From c3430c4633ee29e0733d5ef2f9c905c2e85c96a6 Mon Sep 17 00:00:00 2001
From: "Mikal S." <7761729+revam@users.noreply.github.com>
Date: Tue, 3 Sep 2024 20:45:40 +0200
Subject: [PATCH] fix: fix auto focus for inputs (#1040)
just don't look at the internals and you'll be good.
---
.../Collection/Tmdb/EpisodeSelect.tsx | 1 +
src/components/Input/Input.tsx | 13 ++++-------
src/hooks/useAutoFocusRef.ts | 23 +++++++++++++++++++
3 files changed, 28 insertions(+), 9 deletions(-)
create mode 100644 src/hooks/useAutoFocusRef.ts
diff --git a/src/components/Collection/Tmdb/EpisodeSelect.tsx b/src/components/Collection/Tmdb/EpisodeSelect.tsx
index 636434e4d..8a8c09d3a 100644
--- a/src/components/Collection/Tmdb/EpisodeSelect.tsx
+++ b/src/components/Collection/Tmdb/EpisodeSelect.tsx
@@ -123,6 +123,7 @@ const EpisodeSelect = React.memo((props: Props) => {
className="z-[110] w-[var(--button-width)] rounded-lg bg-panel-background focus:outline-none"
>
{
const {
- autoFocus,
+ autoFocus = false,
center,
className,
disabled,
@@ -64,15 +65,9 @@ const Input = React.memo((props: Props) => {
} = props;
const bodyVisible = useContext(BodyVisibleContext);
- const inputRef = useRef(null);
+ const inputRef = useAutoFocusRef(autoFocus, bodyVisible);
const [isShow, setIsShow] = React.useState(false);
- useEffect(() => {
- if (autoFocus && bodyVisible && inputRef.current) {
- inputRef.current?.focus();
- }
- }, [autoFocus, bodyVisible]);
-
useEffect(() => {
if (isOverlay) return;
setIsShow(_ => false);
diff --git a/src/hooks/useAutoFocusRef.ts b/src/hooks/useAutoFocusRef.ts
new file mode 100644
index 000000000..015db10c8
--- /dev/null
+++ b/src/hooks/useAutoFocusRef.ts
@@ -0,0 +1,23 @@
+import type React from 'react';
+
+import useEventCallback from './useEventCallback';
+
+function useAutoFocusRef(autoFocus: boolean, bodyVisible: boolean): React.MutableRefObject {
+ // eslint-disable-next-line no-undef
+ const ref: React.MutableRefObject & { timeout?: NodeJS.Timeout } = useEventCallback(
+ (element: HTMLInputElement | null) => {
+ ref.current = element;
+ if (autoFocus && bodyVisible && element) {
+ if (ref.timeout) clearTimeout(ref.timeout);
+ ref.timeout = setTimeout(() => {
+ if (ref.timeout) delete ref.timeout;
+ element.focus();
+ }, 0);
+ }
+ },
+ // eslint-disable-next-line no-undef
+ ) as unknown as React.MutableRefObject & { timeout?: NodeJS.Timeout };
+ return ref;
+}
+
+export default useAutoFocusRef;