diff --git a/src/components/SelectLichessStudy.tsx b/src/components/SelectLichessStudy.tsx
index 2e9de88..2fa2d14 100644
--- a/src/components/SelectLichessStudy.tsx
+++ b/src/components/SelectLichessStudy.tsx
@@ -1,4 +1,5 @@
-import { useEffect, useRef, useState } from "react";
+import { useRef, useState } from "react";
+import { useClickOutside } from "#/hooks/useClickOutside.ts";
import { type IUserStudyChapter, useLichess } from "#/hooks/useLichess.ts";
interface IProps {
@@ -30,24 +31,7 @@ const SelectLichessStudy = ({ setSelectedStudyId }: IProps) => {
setSearch("");
};
- useEffect(() => {
- const handleClickOutside = (event: MouseEvent) => {
- if (
- isOpen &&
- dropdownRef.current &&
- !dropdownRef.current.contains(event.target as Node)
- ) {
- setIsOpen(false);
- setSearch("");
- }
- };
-
- document.addEventListener("mousedown", handleClickOutside);
-
- return () => {
- document.removeEventListener("mousedown", handleClickOutside);
- };
- }, [isOpen]);
+ useClickOutside({ isOpen, setIsOpen, setSearch, ref: dropdownRef });
return (
@@ -74,6 +58,7 @@ const SelectLichessStudy = ({ setSelectedStudyId }: IProps) => {
strokeLinecap="round"
strokeLinejoin="round"
>
+
search
diff --git a/src/components/SelectStudyChapter.tsx b/src/components/SelectStudyChapter.tsx
index 22c3eeb..74e6814 100644
--- a/src/components/SelectStudyChapter.tsx
+++ b/src/components/SelectStudyChapter.tsx
@@ -1,4 +1,5 @@
-import { type Dispatch, useEffect, useRef, useState } from "react";
+import { type Dispatch, useRef, useState } from "react";
+import { useClickOutside } from "#/hooks/useClickOutside.ts";
import { type IUserStudyChapter, useLichess } from "#/hooks/useLichess.ts";
import type { GameAction } from "#/reducers/gameReducer.ts";
@@ -19,24 +20,7 @@ const SelectStudyChapter = ({ selectedStudyId, gameDispatch }: IProps) => {
chapter.name.toLowerCase().includes(search.toLowerCase()),
);
- useEffect(() => {
- const handleClickOutside = (event: MouseEvent) => {
- if (
- isOpen &&
- dropdownRef.current &&
- !dropdownRef.current.contains(event.target as Node)
- ) {
- setIsOpen(false);
- setSearch("");
- }
- };
-
- document.addEventListener("mousedown", handleClickOutside);
-
- return () => {
- document.removeEventListener("mousedown", handleClickOutside);
- };
- }, [isOpen]);
+ useClickOutside({ isOpen, setIsOpen, setSearch, ref: dropdownRef });
const onClickHandler = async () => {
const studies = await getLichessStudyChapters({ studyId: selectedStudyId });
@@ -79,7 +63,7 @@ const SelectStudyChapter = ({ selectedStudyId, gameDispatch }: IProps) => {
strokeLinecap="round"
strokeLinejoin="round"
>
-
link
+
search
diff --git a/src/hooks/useClickOutside.ts b/src/hooks/useClickOutside.ts
index e69de29..78587e0 100644
--- a/src/hooks/useClickOutside.ts
+++ b/src/hooks/useClickOutside.ts
@@ -0,0 +1,34 @@
+import { type RefObject, useEffect } from "react";
+
+interface IProps {
+ isOpen: boolean;
+ setIsOpen: (isOpen: boolean) => void;
+ ref: RefObject
;
+ setSearch: (search: string) => void;
+}
+
+export const useClickOutside = ({
+ isOpen,
+ setIsOpen,
+ setSearch,
+ ref,
+}: IProps) => {
+ useEffect(() => {
+ const handleClickOutside = (event: MouseEvent) => {
+ if (
+ isOpen &&
+ ref.current &&
+ !ref.current.contains(event.target as Node)
+ ) {
+ setIsOpen(false);
+ setSearch("");
+ }
+ };
+
+ document.addEventListener("mousedown", handleClickOutside);
+
+ return () => {
+ document.removeEventListener("mousedown", handleClickOutside);
+ };
+ }, [isOpen, setIsOpen, setSearch, ref]);
+};