feat: add internationalization message platform

This commit is contained in:
donghyeon-ka
2026-07-26 16:17:39 +09:00
parent b8c0444217
commit 668bf05b48
57 changed files with 1711 additions and 201 deletions
+13 -4
View File
@@ -8,6 +8,10 @@ import {
type FormEvent,
} from "react";
import type { ZodType, ZodIssue } from "zod";
import {
useLocale,
type ParameterlessMessageKey,
} from "../i18n/index.js";
import {
mapValidationFailureToFields,
@@ -37,6 +41,7 @@ export function useAppForm<
Command,
Output,
>(options: AppFormOptions<Values, Command, Output>) {
const { message } = useLocale();
const {
schema,
defaultValues,
@@ -142,13 +147,14 @@ export function useAppForm<
const errors = issuesToFieldErrors<Values>(
parsed.error.issues,
allowedServerFields,
message,
);
setFieldErrors(errors);
setFormErrors(
parsed.error.issues.some(
(issue) => !allowedServerFields.includes(issue.path[0] as FieldName<Values>),
)
? ["입력 구성을 다시 확인해 주세요."]
? [message("form.validation.configuration")]
: [],
);
setTouched(new Set(allowedServerFields));
@@ -178,6 +184,7 @@ export function useAppForm<
const mapped = mapValidationFailureToFields<Values>(
outcome.error,
allowedServerFields,
message,
);
setFieldErrors(mapped.fieldErrors);
setFormErrors(mapped.formErrors);
@@ -185,11 +192,11 @@ export function useAppForm<
focusFirstError(mapped.fieldErrors);
} else if (outcome.error.kind === "CONFLICT") {
setFormErrors([
"다른 변경과 충돌했습니다. 입력은 유지되었으니 최신 상태를 확인해 주세요.",
message("form.conflict"),
]);
setResult("conflict");
} else {
setFormErrors(["저장하지 못했습니다. 잠시 후 다시 시도해 주세요."]);
setFormErrors([message("form.unavailable")]);
setResult("unavailable");
}
return outcome;
@@ -203,6 +210,7 @@ export function useAppForm<
defaultValues,
focusFirstError,
mapToCommand,
message,
resetOnSuccess,
schema,
submit,
@@ -231,6 +239,7 @@ export function useAppForm<
function issuesToFieldErrors<Values extends FormValues>(
issues: readonly ZodIssue[],
allowedFields: readonly FieldName<Values>[],
message: (key: ParameterlessMessageKey) => string,
): FieldErrors<Values> {
const allowed = new Set<PropertyKey>(allowedFields);
const errors: Partial<Record<FieldName<Values>, string>> = {};
@@ -238,7 +247,7 @@ function issuesToFieldErrors<Values extends FormValues>(
const field = issue.path[0];
if (!allowed.has(field)) continue;
const name = field as FieldName<Values>;
errors[name] ??= validationMessage(issue.code);
errors[name] ??= validationMessage(issue.code, message);
}
return Object.freeze(errors);
}