47 lines
1.1 KiB
TypeScript
47 lines
1.1 KiB
TypeScript
/* eslint-disable promise/prefer-await-to-then */
|
|
'use client';
|
|
import { useEffect, useRef, useState } from 'react';
|
|
import { useDebouncedCallback } from 'use-debounce';
|
|
|
|
export function useDebouncedOnChangeCallback<T>(
|
|
callback: ((value: T) => Promise<void> | void) | undefined,
|
|
) {
|
|
const [isPending, setIsPending] = useState(false);
|
|
|
|
const debouncedCallback = useDebouncedCallback((newValue: T) => {
|
|
if (!callback) return;
|
|
|
|
setIsPending(true);
|
|
const result = callback(newValue);
|
|
|
|
if (result instanceof Promise) {
|
|
result.finally(() => setIsPending(false));
|
|
} else {
|
|
setIsPending(false);
|
|
}
|
|
}, 300);
|
|
|
|
return {
|
|
debouncedCallback,
|
|
isPending,
|
|
};
|
|
}
|
|
|
|
export function useFocus(isPending: boolean) {
|
|
const inputRef = useRef<HTMLInputElement | null>(null);
|
|
const [isInitialRender, setIsInitialRender] = useState(true);
|
|
|
|
useEffect(() => {
|
|
if (isInitialRender) {
|
|
setIsInitialRender(false);
|
|
return;
|
|
}
|
|
|
|
if (inputRef.current && isPending) {
|
|
inputRef.current.focus();
|
|
}
|
|
}, [isInitialRender, isPending]);
|
|
|
|
return inputRef;
|
|
}
|