From 5983a4431103512f1fa23a75a23218872e1a6277 Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Sat, 4 Oct 2025 11:18:08 +0700 Subject: [PATCH] chore(FE-40): add DebouncedTextInput component --- src/components/input/DebouncedTextInput.tsx | 42 +++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/components/input/DebouncedTextInput.tsx diff --git a/src/components/input/DebouncedTextInput.tsx b/src/components/input/DebouncedTextInput.tsx new file mode 100644 index 00000000..61dbf61c --- /dev/null +++ b/src/components/input/DebouncedTextInput.tsx @@ -0,0 +1,42 @@ +'use client'; + +import { ChangeEvent, ChangeEventHandler, useEffect, useState } from 'react'; +import { useDebounce } from 'use-debounce'; + +import TextInput, { TextInputProps } from '@/components/input/TextInput'; + +interface DebouncedTextInputProps extends TextInputProps { + delay?: number; +} + +const DebouncedTextInput = (props: DebouncedTextInputProps) => { + const { delay, onChange } = props; + + const [internalChangeEvent, setInternalChangeEvent] = + useState>(); + const [internalValue, setInternalValue] = useState(props.value); + + const [debouncedChangeEvent] = useDebounce(internalChangeEvent, delay ?? 300); + const [debouncedValue] = useDebounce(internalValue, delay ?? 300); + + const internalChangeHandler: ChangeEventHandler = (e) => { + setInternalValue(e.target.value); + setInternalChangeEvent(e); + }; + + useEffect(() => { + if (debouncedChangeEvent) { + onChange?.(debouncedChangeEvent); + } + }, [debouncedValue, debouncedChangeEvent, onChange]); + + return ( + + ); +}; + +export default DebouncedTextInput;