aboutsummaryrefslogtreecommitdiffstats
path: root/src/utils/hooks/use-autofocus/use-autofocus.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils/hooks/use-autofocus/use-autofocus.ts')
-rw-r--r--src/utils/hooks/use-autofocus/use-autofocus.ts40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/utils/hooks/use-autofocus/use-autofocus.ts b/src/utils/hooks/use-autofocus/use-autofocus.ts
new file mode 100644
index 0000000..0d21a59
--- /dev/null
+++ b/src/utils/hooks/use-autofocus/use-autofocus.ts
@@ -0,0 +1,40 @@
+import { useCallback, useRef, type MutableRefObject } from 'react';
+import { useTimeout } from '../use-timeout';
+
+export type UseAutofocusCondition = () => boolean;
+
+export type UseAutofocusConfig = {
+ /**
+ * A condition to met before giving focus to the element.
+ */
+ condition?: UseAutofocusCondition;
+ /**
+ * A delay in ms before giving focus to the element.
+ */
+ delay?: number;
+};
+
+/**
+ * React hook to give focus to an element automatically.
+ *
+ * @param {UseAutofocusConfig} [config] - A configuration object.
+ * @returns {RefObject<T>} The element reference.
+ */
+export const useAutofocus = <T extends HTMLElement>(
+ config?: UseAutofocusConfig
+): MutableRefObject<T | null> => {
+ const { condition, delay } = config ?? {};
+ const ref = useRef<T | null>(null);
+
+ const setFocus = useCallback(() => {
+ const shouldFocus = condition ? condition() : true;
+
+ if (ref.current && shouldFocus) {
+ ref.current.focus();
+ }
+ }, [condition]);
+
+ useTimeout(setFocus, delay);
+
+ return ref;
+};