90 lines
2.4 KiB
TypeScript
90 lines
2.4 KiB
TypeScript
|
|
import { useState } from "react";
|
||
|
|
|
||
|
|
export interface ValidationState {
|
||
|
|
enabled: boolean;
|
||
|
|
value: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface ValidationStates {
|
||
|
|
[fieldName: string]: ValidationState;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface UseFormValidationProps {
|
||
|
|
fields: string[];
|
||
|
|
initialStates?: Partial<ValidationStates>;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useFormValidation({ fields, initialStates = {} }: UseFormValidationProps) {
|
||
|
|
// 검증 상태 초기화
|
||
|
|
const initValidationStates = (): ValidationStates => {
|
||
|
|
const states: ValidationStates = {};
|
||
|
|
fields.forEach((field) => {
|
||
|
|
states[field] = initialStates[field] || { enabled: false, value: "" };
|
||
|
|
});
|
||
|
|
return states;
|
||
|
|
};
|
||
|
|
|
||
|
|
const [validationStates, setValidationStates] = useState<ValidationStates>(initValidationStates);
|
||
|
|
|
||
|
|
// 특정 필드의 검증 상태 업데이트
|
||
|
|
const updateFieldValidation = (fieldName: string, value: string) => {
|
||
|
|
setValidationStates((prev) => ({
|
||
|
|
...prev,
|
||
|
|
[fieldName]: { enabled: true, value: value.trim() },
|
||
|
|
}));
|
||
|
|
};
|
||
|
|
|
||
|
|
// onBlur 핸들러 생성
|
||
|
|
const createBlurHandler =
|
||
|
|
(fieldName: string) => (event: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
||
|
|
const value = event.target.value.trim();
|
||
|
|
if (value) {
|
||
|
|
updateFieldValidation(fieldName, value);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// 모든 필수 필드가 검증되었는지 확인
|
||
|
|
const areAllFieldsValidated = (requiredFields?: string[]) => {
|
||
|
|
const fieldsToCheck = requiredFields || fields;
|
||
|
|
return fieldsToCheck.every((field) => validationStates[field]?.enabled);
|
||
|
|
};
|
||
|
|
|
||
|
|
// 검증 상태 초기화
|
||
|
|
const resetValidation = (newStates?: Partial<ValidationStates>) => {
|
||
|
|
if (newStates) {
|
||
|
|
setValidationStates((prev) => {
|
||
|
|
const updated = { ...prev };
|
||
|
|
Object.entries(newStates).forEach(([key, value]) => {
|
||
|
|
if (value !== undefined) {
|
||
|
|
updated[key] = value;
|
||
|
|
}
|
||
|
|
});
|
||
|
|
return updated;
|
||
|
|
});
|
||
|
|
} else {
|
||
|
|
setValidationStates(initValidationStates());
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// 특정 필드 검증 상태 확인
|
||
|
|
const isFieldValidated = (fieldName: string) => validationStates[fieldName]?.enabled || false;
|
||
|
|
|
||
|
|
// 필드 값 가져오기
|
||
|
|
const getFieldValue = (fieldName: string) => validationStates[fieldName]?.value || "";
|
||
|
|
|
||
|
|
return {
|
||
|
|
// 상태
|
||
|
|
validationStates,
|
||
|
|
|
||
|
|
// 액션
|
||
|
|
updateFieldValidation,
|
||
|
|
resetValidation,
|
||
|
|
|
||
|
|
// 유틸리티
|
||
|
|
createBlurHandler,
|
||
|
|
areAllFieldsValidated,
|
||
|
|
isFieldValidated,
|
||
|
|
getFieldValue,
|
||
|
|
};
|
||
|
|
}
|