Extract custom hooks for reusable logic

This commit is contained in:
adilallo
2026-01-26 12:51:27 -07:00
parent f513aecacc
commit 86d7cff5d4
21 changed files with 1590 additions and 141 deletions
+71
View File
@@ -0,0 +1,71 @@
import { useCallback } from "react";
/**
* Hook for managing form field event handlers with disabled state handling
* Ensures handlers respect disabled state and provides consistent behavior
*
* @param disabled - Whether the field is disabled
* @param handlers - Object containing onChange, onFocus, onBlur handlers
*
* @returns Object with wrapped handlers that respect disabled state
*
* @example
* ```tsx
* const { handleChange, handleFocus, handleBlur } = useFormField(disabled, {
* onChange: (e) => setValue(e.target.value),
* onFocus: (e) => setFocused(true),
* onBlur: (e) => setFocused(false),
* });
* ```
*/
interface FormFieldHandlers<T = HTMLElement> {
onChange?: (e: React.ChangeEvent<T>) => void;
onFocus?: (e: React.FocusEvent<T>) => void;
onBlur?: (e: React.FocusEvent<T>) => void;
}
interface UseFormFieldReturn<T = HTMLElement> {
handleChange: (e: React.ChangeEvent<T>) => void;
handleFocus: (e: React.FocusEvent<T>) => void;
handleBlur: (e: React.FocusEvent<T>) => void;
}
export function useFormField<T extends HTMLElement = HTMLElement>(
disabled: boolean,
handlers: FormFieldHandlers<T>,
): UseFormFieldReturn<T> {
const { onChange, onFocus, onBlur } = handlers;
const handleChange = useCallback(
(e: React.ChangeEvent<T>) => {
if (!disabled && onChange) {
onChange(e);
}
},
[disabled, onChange],
);
const handleFocus = useCallback(
(e: React.FocusEvent<T>) => {
if (!disabled && onFocus) {
onFocus(e);
}
},
[disabled, onFocus],
);
const handleBlur = useCallback(
(e: React.FocusEvent<T>) => {
if (!disabled && onBlur) {
onBlur(e);
}
},
[disabled, onBlur],
);
return {
handleChange,
handleFocus,
handleBlur,
};
}