@letar/forms 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +57 -0
- package/README.md +79 -4
- package/README.ru.md +304 -0
- package/{chunk-G3HYXHCZ.js → chunk-4V6WBJ76.js} +14 -14
- package/chunk-4V6WBJ76.js.map +1 -0
- package/chunk-6QOPSQ3Z.js +78 -0
- package/chunk-6QOPSQ3Z.js.map +1 -0
- package/{chunk-GIBNEYK3.js → chunk-7FEQFDJ7.js} +5 -4
- package/chunk-7FEQFDJ7.js.map +1 -0
- package/chunk-GOELIS6T.js +849 -0
- package/chunk-GOELIS6T.js.map +1 -0
- package/chunk-HWVOFWAT.js +846 -0
- package/chunk-HWVOFWAT.js.map +1 -0
- package/chunk-KUNT5MSU.js +709 -0
- package/chunk-KUNT5MSU.js.map +1 -0
- package/chunk-M2PNAAIR.js +971 -0
- package/chunk-M2PNAAIR.js.map +1 -0
- package/chunk-PJETA6YN.js +821 -0
- package/chunk-PJETA6YN.js.map +1 -0
- package/chunk-XKKJKYWZ.js +299 -0
- package/chunk-XKKJKYWZ.js.map +1 -0
- package/fields/boolean.js +5 -0
- package/fields/boolean.js.map +1 -0
- package/fields/datetime.js +5 -0
- package/fields/datetime.js.map +1 -0
- package/fields/number.js +5 -0
- package/fields/number.js.map +1 -0
- package/fields/selection.js +5 -0
- package/fields/selection.js.map +1 -0
- package/fields/specialized.js +5 -0
- package/fields/specialized.js.map +1 -0
- package/fields/text.js +5 -0
- package/fields/text.js.map +1 -0
- package/i18n.js +1 -1
- package/index.js +261 -4540
- package/index.js.map +1 -1
- package/offline.js +1 -1
- package/package.json +33 -2
- package/chunk-G3HYXHCZ.js.map +0 -1
- package/chunk-GIBNEYK3.js.map +0 -1
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { createField, FieldTooltip, FieldError } from './chunk-HWVOFWAT.js';
|
|
2
|
+
import { Field, Checkbox, HStack, Switch } from '@chakra-ui/react';
|
|
3
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
var FieldCheckbox = createField({
|
|
6
|
+
displayName: "FieldCheckbox",
|
|
7
|
+
render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps }) => /* @__PURE__ */ jsxs(
|
|
8
|
+
Field.Root,
|
|
9
|
+
{
|
|
10
|
+
invalid: hasError,
|
|
11
|
+
required: resolved.required,
|
|
12
|
+
disabled: resolved.disabled,
|
|
13
|
+
readOnly: resolved.readOnly,
|
|
14
|
+
children: [
|
|
15
|
+
/* @__PURE__ */ jsxs(
|
|
16
|
+
Checkbox.Root,
|
|
17
|
+
{
|
|
18
|
+
checked: !!field.state.value,
|
|
19
|
+
onCheckedChange: (e) => field.handleChange(!!e.checked),
|
|
20
|
+
colorPalette: componentProps.colorPalette ?? "brand",
|
|
21
|
+
size: componentProps.size ?? "md",
|
|
22
|
+
disabled: resolved.disabled,
|
|
23
|
+
readOnly: resolved.readOnly,
|
|
24
|
+
"data-field-name": fullPath,
|
|
25
|
+
children: [
|
|
26
|
+
/* @__PURE__ */ jsx(Checkbox.HiddenInput, { onBlur: field.handleBlur }),
|
|
27
|
+
/* @__PURE__ */ jsx(Checkbox.Control, {}),
|
|
28
|
+
resolved.label && /* @__PURE__ */ jsx(Checkbox.Label, { children: resolved.tooltip ? /* @__PURE__ */ jsxs(HStack, { gap: 1, children: [
|
|
29
|
+
/* @__PURE__ */ jsx("span", { children: resolved.label }),
|
|
30
|
+
/* @__PURE__ */ jsx(FieldTooltip, { ...resolved.tooltip })
|
|
31
|
+
] }) : resolved.label })
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
),
|
|
35
|
+
/* @__PURE__ */ jsx(FieldError, { hasError, errorMessage, helperText: resolved.helperText })
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
)
|
|
39
|
+
});
|
|
40
|
+
var FieldSwitch = createField({
|
|
41
|
+
displayName: "FieldSwitch",
|
|
42
|
+
render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps }) => /* @__PURE__ */ jsxs(
|
|
43
|
+
Field.Root,
|
|
44
|
+
{
|
|
45
|
+
invalid: hasError,
|
|
46
|
+
required: resolved.required,
|
|
47
|
+
disabled: resolved.disabled,
|
|
48
|
+
readOnly: resolved.readOnly,
|
|
49
|
+
children: [
|
|
50
|
+
/* @__PURE__ */ jsxs(
|
|
51
|
+
Switch.Root,
|
|
52
|
+
{
|
|
53
|
+
checked: !!field.state.value,
|
|
54
|
+
onCheckedChange: (e) => field.handleChange(e.checked),
|
|
55
|
+
colorPalette: componentProps.colorPalette ?? "brand",
|
|
56
|
+
size: componentProps.size ?? "md",
|
|
57
|
+
disabled: resolved.disabled,
|
|
58
|
+
readOnly: resolved.readOnly,
|
|
59
|
+
"data-field-name": fullPath,
|
|
60
|
+
children: [
|
|
61
|
+
/* @__PURE__ */ jsx(Switch.HiddenInput, { onBlur: field.handleBlur }),
|
|
62
|
+
/* @__PURE__ */ jsx(Switch.Control, { children: /* @__PURE__ */ jsx(Switch.Thumb, {}) }),
|
|
63
|
+
resolved.label && /* @__PURE__ */ jsx(Switch.Label, { children: resolved.tooltip ? /* @__PURE__ */ jsxs(HStack, { gap: 1, children: [
|
|
64
|
+
/* @__PURE__ */ jsx("span", { children: resolved.label }),
|
|
65
|
+
/* @__PURE__ */ jsx(FieldTooltip, { ...resolved.tooltip })
|
|
66
|
+
] }) : resolved.label })
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
),
|
|
70
|
+
/* @__PURE__ */ jsx(FieldError, { hasError, errorMessage, helperText: resolved.helperText })
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
)
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
export { FieldCheckbox, FieldSwitch };
|
|
77
|
+
//# sourceMappingURL=chunk-6QOPSQ3Z.js.map
|
|
78
|
+
//# sourceMappingURL=chunk-6QOPSQ3Z.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/declarative/form-fields/boolean/field-checkbox.tsx","../src/lib/declarative/form-fields/boolean/field-switch.tsx"],"names":["jsxs","Field","jsx","HStack"],"mappings":"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","file":"chunk-6QOPSQ3Z.js","sourcesContent":["'use client'\n\nimport { Checkbox, Field, HStack } from '@chakra-ui/react'\nimport type { ReactElement } from 'react'\nimport type { CheckboxFieldProps } from '../../types'\nimport { createField, FieldError } from '../base'\nimport { FieldTooltip } from '../base/field-tooltip'\n\n/**\n * Form.Field.Checkbox - Boolean checkbox field\n *\n * Renders a Chakra Checkbox with automatic form integration and error display.\n *\n * @example\n * ```tsx\n * <Form.Field.Checkbox name=\"active\" label=\"Active\" />\n * ```\n *\n * @example With color palette\n * ```tsx\n * <Form.Field.Checkbox name=\"terms\" label=\"Accept terms\" colorPalette=\"green\" />\n * ```\n */\nexport const FieldCheckbox = createField<CheckboxFieldProps, boolean>({\n displayName: 'FieldCheckbox',\n render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps }): ReactElement => (\n <Field.Root\n invalid={hasError}\n required={resolved.required}\n disabled={resolved.disabled}\n readOnly={resolved.readOnly}\n >\n <Checkbox.Root\n checked={!!field.state.value}\n onCheckedChange={(e) => field.handleChange(!!e.checked)}\n colorPalette={componentProps.colorPalette ?? 'brand'}\n size={componentProps.size ?? 'md'}\n disabled={resolved.disabled}\n readOnly={resolved.readOnly}\n data-field-name={fullPath}\n >\n <Checkbox.HiddenInput onBlur={field.handleBlur} />\n <Checkbox.Control />\n {resolved.label && (\n <Checkbox.Label>\n {resolved.tooltip ? (\n <HStack gap={1}>\n <span>{resolved.label}</span>\n <FieldTooltip {...resolved.tooltip} />\n </HStack>\n ) : (\n resolved.label\n )}\n </Checkbox.Label>\n )}\n </Checkbox.Root>\n <FieldError hasError={hasError} errorMessage={errorMessage} helperText={resolved.helperText} />\n </Field.Root>\n ),\n})\n","'use client'\n\nimport { Field, HStack, Switch } from '@chakra-ui/react'\nimport type { ReactElement } from 'react'\nimport type { SwitchFieldProps } from '../../types'\nimport { createField, FieldError } from '../base'\nimport { FieldTooltip } from '../base/field-tooltip'\n\n/**\n * Form.Field.Switch - Boolean switch/toggle field\n *\n * Renders a Chakra Switch with automatic form integration and error display.\n *\n * @example\n * ```tsx\n * <Form.Field.Switch name=\"notifications\" label=\"Enable notifications\" />\n * ```\n *\n * @example With color palette and size\n * ```tsx\n * <Form.Field.Switch name=\"darkMode\" label=\"Dark mode\" colorPalette=\"purple\" size=\"lg\" />\n * ```\n */\nexport const FieldSwitch = createField<SwitchFieldProps, boolean>({\n displayName: 'FieldSwitch',\n render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps }): ReactElement => (\n <Field.Root\n invalid={hasError}\n required={resolved.required}\n disabled={resolved.disabled}\n readOnly={resolved.readOnly}\n >\n <Switch.Root\n checked={!!field.state.value}\n onCheckedChange={(e) => field.handleChange(e.checked)}\n colorPalette={componentProps.colorPalette ?? 'brand'}\n size={componentProps.size ?? 'md'}\n disabled={resolved.disabled}\n readOnly={resolved.readOnly}\n data-field-name={fullPath}\n >\n <Switch.HiddenInput onBlur={field.handleBlur} />\n <Switch.Control>\n <Switch.Thumb />\n </Switch.Control>\n {resolved.label && (\n <Switch.Label>\n {resolved.tooltip ? (\n <HStack gap={1}>\n <span>{resolved.label}</span>\n <FieldTooltip {...resolved.tooltip} />\n </HStack>\n ) : (\n resolved.label\n )}\n </Switch.Label>\n )}\n </Switch.Root>\n <FieldError hasError={hasError} errorMessage={errorMessage} helperText={resolved.helperText} />\n </Field.Root>\n ),\n})\n"]}
|
|
@@ -133,13 +133,14 @@ var STRING_FORMATS = [
|
|
|
133
133
|
];
|
|
134
134
|
var FormI18nContext = createContext(null);
|
|
135
135
|
function FormI18nProvider({ t, locale, children, setupZodErrorMap = false }) {
|
|
136
|
+
const resolvedT = t ?? ((key) => key);
|
|
136
137
|
useEffect(() => {
|
|
137
|
-
if (setupZodErrorMap) {
|
|
138
|
+
if (setupZodErrorMap && t) {
|
|
138
139
|
const errorMap = createFormErrorMap({ t });
|
|
139
140
|
z.config({ customError: errorMap });
|
|
140
141
|
}
|
|
141
142
|
}, [setupZodErrorMap, t]);
|
|
142
|
-
return /* @__PURE__ */ jsx(FormI18nContext.Provider, { value: { t, locale, enabled:
|
|
143
|
+
return /* @__PURE__ */ jsx(FormI18nContext.Provider, { value: { t: resolvedT, locale, enabled: !!t }, children });
|
|
143
144
|
}
|
|
144
145
|
function useFormI18n() {
|
|
145
146
|
return useContext(FormI18nContext);
|
|
@@ -187,5 +188,5 @@ function useLocalizedOptions(options) {
|
|
|
187
188
|
}
|
|
188
189
|
|
|
189
190
|
export { FormI18nProvider, SIZE_ORIGINS, STRING_FORMATS, ZOD_ERROR_CODES, createFormErrorMap, getLocalizedValue, useFormI18n, useLocalizedOptions };
|
|
190
|
-
//# sourceMappingURL=chunk-
|
|
191
|
-
//# sourceMappingURL=chunk-
|
|
191
|
+
//# sourceMappingURL=chunk-7FEQFDJ7.js.map
|
|
192
|
+
//# sourceMappingURL=chunk-7FEQFDJ7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/i18n/create-form-error-map.ts","../src/lib/i18n/form-i18n-provider.tsx","../src/lib/i18n/use-localized-options.ts"],"names":[],"mappings":"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","file":"chunk-7FEQFDJ7.js","sourcesContent":["import type { TranslateFunction, TranslateParams } from './form-i18n-provider'\n\n/**\n * Zod v4 issue type (упрощённый тип для работы с error map)\n * Полный тип: z.core.$ZodIssue (discriminated union)\n */\ninterface ZodIssue {\n readonly code: string\n readonly path: PropertyKey[]\n readonly message: string\n readonly input?: unknown\n readonly expected?: string\n readonly minimum?: number\n readonly maximum?: number\n readonly inclusive?: boolean\n readonly origin?: string\n readonly format?: string\n readonly options?: unknown[]\n readonly keys?: string[]\n readonly multipleOf?: number\n}\n\n/**\n * Конфигурация для создания error map\n */\nexport interface FormErrorMapConfig {\n /** Функция перевода (совместима с next-intl) */\n t: TranslateFunction\n /** Префикс для ключей валидации (по умолчанию 'validation') */\n prefix?: string\n}\n\n/**\n * Извлекает параметры из Zod issue для интерполяции в сообщение\n */\nfunction extractParams(issue: ZodIssue): TranslateParams {\n const params: TranslateParams = {}\n\n // Общие параметры\n if (issue.input !== undefined) {\n params.received = typeof issue.input === 'object' ? 'object' : String(issue.input)\n }\n\n // too_small / too_big\n if (issue.minimum !== undefined) {\n params.minimum = issue.minimum\n }\n if (issue.maximum !== undefined) {\n params.maximum = issue.maximum\n }\n if (issue.inclusive !== undefined) {\n params.inclusive = issue.inclusive\n }\n\n // invalid_type\n if (issue.expected !== undefined) {\n params.expected = issue.expected\n }\n\n // invalid_value (объединяет invalid_enum_value + invalid_literal в Zod v4)\n if (issue.options && Array.isArray(issue.options)) {\n params.options = issue.options.join(', ')\n }\n\n // unrecognized_keys\n if (issue.keys && Array.isArray(issue.keys)) {\n params.keys = issue.keys.join(', ')\n }\n\n // not_multiple_of\n if (issue.multipleOf !== undefined) {\n params.multipleOf = issue.multipleOf\n }\n\n // custom — сообщение из .refine()\n if (issue.message) {\n params.message = issue.message\n }\n\n return params\n}\n\n/**\n * Определяет origin (тип данных) для issue\n * Используется для построения ключа: validation.too_small.string\n */\nfunction getIssueOrigin(issue: ZodIssue): string | undefined {\n // Для too_small / too_big определяем origin по типу input или expected\n if (issue.code === 'too_small' || issue.code === 'too_big') {\n if (issue.origin) {\n return issue.origin\n }\n // Fallback по типу input\n const input = issue.input\n if (typeof input === 'string') {\n return 'string'\n }\n if (typeof input === 'number') {\n return 'number'\n }\n if (Array.isArray(input)) {\n return 'array'\n }\n if (input instanceof Date) {\n return 'date'\n }\n }\n\n // Для invalid_format (Zod v4, ранее invalid_string) определяем format\n if (issue.code === 'invalid_format') {\n if (issue.format) {\n return issue.format\n }\n }\n\n return undefined\n}\n\n/**\n * Пытается получить перевод по ключу\n * @returns переведённая строка или undefined если перевод не найден\n */\nfunction tryTranslate(t: TranslateFunction, key: string, params: TranslateParams): string | undefined {\n try {\n const result = t(key, params)\n // next-intl возвращает ключ при отсутствии перевода\n if (!result || result === key || result.startsWith(key)) {\n return undefined\n }\n return result\n } catch {\n return undefined\n }\n}\n\n/**\n * Создаёт Zod error map с поддержкой i18n\n *\n * Error map преобразует Zod ошибки в переведённые сообщения.\n * Ключи строятся по формату: `{prefix}.{code}.{origin?}`\n *\n * @example\n * ```tsx\n * import { createFormErrorMap } from '@lena/form-components'\n * import { z } from 'zod/v4'\n * import { useTranslations } from 'next-intl'\n *\n * // В провайдере приложения\n * const t = useTranslations('formSchemas')\n * z.config({ customError: createFormErrorMap({ t }) })\n *\n * // Или через FormI18nProvider\n * <FormI18nProvider t={t} locale={locale} setupZodErrorMap>\n * {children}\n * </FormI18nProvider>\n * ```\n *\n * @example Структура ключей в JSON\n * ```json\n * {\n * \"validation\": {\n * \"required\": \"Обязательное поле\",\n * \"too_small\": {\n * \"string\": \"Минимум {minimum} символов\",\n * \"number\": \"Минимум {minimum}\"\n * },\n * \"invalid_format\": {\n * \"email\": \"Некорректный email\"\n * }\n * }\n * }\n * ```\n */\nexport function createFormErrorMap(config: FormErrorMapConfig) {\n const { t, prefix = 'validation' } = config\n\n return (issue: ZodIssue): string | undefined => {\n const params = extractParams(issue)\n const origin = getIssueOrigin(issue)\n\n // Строим ключи для поиска перевода\n const baseKey = `${prefix}.${issue.code}`\n const originKey = origin ? `${baseKey}.${origin}` : null\n\n // Пробуем с origin, затем без\n let translated: string | undefined\n\n if (originKey) {\n translated = tryTranslate(t, originKey, params)\n }\n\n if (!translated) {\n translated = tryTranslate(t, baseKey, params)\n }\n\n // Возвращаем undefined чтобы Zod использовал дефолтное сообщение\n return translated\n }\n}\n\n/**\n * Список всех кодов ошибок Zod v4 для генерации ключей\n */\nexport const ZOD_ERROR_CODES = [\n 'invalid_type',\n 'too_small',\n 'too_big',\n 'invalid_format', // Zod v4: ранее invalid_string\n 'not_multiple_of',\n 'unrecognized_keys',\n 'invalid_value', // Zod v4: объединяет invalid_enum_value + invalid_literal\n 'invalid_union',\n 'invalid_key',\n 'invalid_element',\n 'custom',\n] as const\n\nexport type ZodErrorCode = (typeof ZOD_ERROR_CODES)[number]\n\n/**\n * Origins для ошибок too_small / too_big\n */\nexport const SIZE_ORIGINS = ['string', 'number', 'array', 'date', 'set', 'file'] as const\n\n/**\n * Formats для ошибок invalid_format (Zod v4, ранее invalid_string)\n */\nexport const STRING_FORMATS = [\n 'email',\n 'url',\n 'uuid',\n 'cuid',\n 'cuid2',\n 'ulid',\n 'regex',\n 'datetime',\n 'date',\n 'time',\n 'duration',\n 'ip',\n 'cidr',\n 'base64',\n 'base64url',\n 'json_string',\n 'e164',\n 'jwt',\n 'emoji',\n 'nanoid',\n 'guid',\n 'lowercase',\n 'uppercase',\n] as const\n","'use client'\n\nimport { createContext, type ReactNode, useContext, useEffect } from 'react'\nimport { z } from 'zod/v4'\nimport { createFormErrorMap } from './create-form-error-map'\n\n/**\n * Параметры для интерполяции в сообщениях об ошибках\n * @example { minimum: 5, maximum: 100 }\n */\nexport type TranslateParams = Record<string, string | number | boolean | undefined>\n\n/**\n * Функция перевода (совместима с next-intl useTranslations)\n * @param key - Ключ перевода в формате \"ModelName.fieldName.property\"\n * @param params - Опциональные параметры для интерполяции\n * @returns Переведённая строка или fallback\n */\nexport type TranslateFunction = (key: string, params?: TranslateParams) => string\n\n/**\n * Контекст для i18n в формах\n */\ninterface FormI18nContextValue {\n /** Функция перевода */\n t: TranslateFunction\n /** Текущая локаль */\n locale: string\n /** Включен ли i18n */\n enabled: boolean\n}\n\nconst FormI18nContext = createContext<FormI18nContextValue | null>(null)\n\n/**\n * Props для FormI18nProvider\n */\ninterface FormI18nProviderProps {\n /**\n * Функция перевода из next-intl или другой i18n библиотеки.\n * Если не задана, переводы полей (title, placeholder) не применяются,\n * но locale используется для constraint hints.\n * @example useTranslations('formSchemas')\n */\n t?: TranslateFunction\n /** Текущая локаль (default: 'en') */\n locale: string\n children: ReactNode\n /**\n * Автоматически настроить глобальный Zod error map для i18n\n *\n * При включении, Zod ошибки будут переводиться через функцию t()\n * с ключами вида `validation.{code}.{origin?}`\n *\n * @example\n * ```json\n * {\n * \"validation\": {\n * \"too_small\": { \"string\": \"Минимум {minimum} символов\" },\n * \"invalid_string\": { \"email\": \"Некорректный email\" }\n * }\n * }\n * ```\n *\n * @default false\n */\n setupZodErrorMap?: boolean\n}\n\n/**\n * Провайдер i18n для форм\n *\n * Оборачивает формы и предоставляет доступ к переводам через useFormI18n.\n * При наличии провайдера, компоненты форм будут использовать переводы\n * по ключам из i18nKey в схемах.\n *\n * @example Базовое использование\n * ```tsx\n * import { FormI18nProvider } from '@lena/form-components'\n * import { useTranslations, useLocale } from 'next-intl'\n *\n * function App({ children }) {\n * const t = useTranslations('formSchemas')\n * const locale = useLocale()\n *\n * return (\n * <FormI18nProvider t={t} locale={locale}>\n * {children}\n * </FormI18nProvider>\n * )\n * }\n * ```\n *\n * @example С автоматической настройкой Zod error map\n * ```tsx\n * <FormI18nProvider t={t} locale={locale} setupZodErrorMap>\n * {children}\n * </FormI18nProvider>\n * ```\n */\nexport function FormI18nProvider({ t, locale, children, setupZodErrorMap = false }: FormI18nProviderProps) {\n // Fallback t-функция: возвращает ключ как есть (без перевода)\n const resolvedT: TranslateFunction = t ?? ((key: string) => key)\n\n // Настраиваем глобальный Zod error map при включённом флаге\n useEffect(() => {\n if (setupZodErrorMap && t) {\n const errorMap = createFormErrorMap({ t })\n // Type assertion: наш error map совместим с Zod v4 API,\n // но TypeScript не может вывести это автоматически\n z.config({ customError: errorMap as z.core.$ZodErrorMap<z.core.$ZodIssue> })\n }\n }, [setupZodErrorMap, t])\n\n return <FormI18nContext.Provider value={{ t: resolvedT, locale, enabled: !!t }}>{children}</FormI18nContext.Provider>\n}\n\n/**\n * Хук для доступа к i18n в формах\n *\n * Возвращает функцию перевода и информацию о локали.\n * Если FormI18nProvider не найден, возвращает null.\n *\n * @example\n * ```tsx\n * function MyField() {\n * const i18n = useFormI18n()\n *\n * if (i18n) {\n * const label = i18n.t('Product.name.title')\n * }\n * }\n * ```\n */\nexport function useFormI18n(): FormI18nContextValue | null {\n return useContext(FormI18nContext)\n}\n\n/**\n * Получить переведённое значение с fallback\n *\n * Пытается получить перевод по ключу. Если перевод пустой или\n * i18n не настроен, возвращает fallback значение.\n *\n * @param i18n - Контекст i18n (может быть null)\n * @param i18nKey - Базовый ключ (например, \"Product.name\")\n * @param property - Свойство (например, \"title\", \"placeholder\")\n * @param fallback - Значение по умолчанию\n * @returns Переведённая строка или fallback\n */\nexport function getLocalizedValue(\n i18n: FormI18nContextValue | null,\n i18nKey: string | undefined,\n property: 'title' | 'placeholder' | 'description' | 'label',\n fallback: string | undefined,\n): string | undefined {\n if (!i18n || !i18nKey) {\n return fallback\n }\n\n try {\n const fullKey = `${i18nKey}.${property}`\n const translated = i18n.t(fullKey)\n\n // Если перевод пустой или равен ключу (next-intl возвращает ключ при отсутствии перевода)\n if (!translated || translated === fullKey) {\n return fallback\n }\n\n return translated\n } catch {\n // При ошибке возвращаем fallback\n return fallback\n }\n}\n","'use client'\n\nimport { useMemo } from 'react'\nimport { useFormI18n } from './form-i18n-provider'\n\n/**\n * Опция для select/radio/checkbox с поддержкой i18n\n */\nexport interface LocalizableOption {\n value: string | number\n label: string\n /** Опция отключена */\n disabled?: boolean\n /** Ключ i18n для перевода label (например, \"RecipeType.SWEET\") */\n i18nKey?: string\n}\n\n/**\n * Хук для локализации опций select/radio/checkbox\n *\n * Принимает массив опций с i18nKey и возвращает массив с переведёнными label.\n * Если i18n не настроен или перевод отсутствует, используется оригинальный label.\n *\n * @param options - Массив опций с возможными i18nKey\n * @returns Массив опций с переведёнными label\n *\n * @example\n * ```tsx\n * // Опции из Zod схемы\n * const rawOptions = [\n * { value: 'SWEET', label: 'Сладкое', i18nKey: 'RecipeType.SWEET' },\n * { value: 'SALTY', label: 'Солёное', i18nKey: 'RecipeType.SALTY' },\n * ]\n *\n * function MySelect() {\n * const options = useLocalizedOptions(rawOptions)\n * // options[0].label будет переведён если есть FormI18nProvider\n * }\n * ```\n */\nexport function useLocalizedOptions(\n options: LocalizableOption[] | undefined\n): { value: string | number; label: string; disabled?: boolean }[] {\n const i18n = useFormI18n()\n\n return useMemo(() => {\n if (!options) {\n return []\n }\n\n if (!i18n) {\n // i18n не настроен — возвращаем оригинальные label\n return options.map(({ value, label, disabled }) => ({ value, label, disabled }))\n }\n\n return options.map(({ value, label, disabled, i18nKey }) => {\n if (!i18nKey) {\n return { value, label, disabled }\n }\n\n try {\n // Ключ для enum option: \"EnumName.VALUE.label\"\n const fullKey = `${i18nKey}.label`\n const translated = i18n.t(fullKey)\n\n // Если перевод пустой или равен ключу — используем fallback\n if (!translated || translated === fullKey) {\n return { value, label, disabled }\n }\n\n return { value, label: translated, disabled }\n } catch {\n return { value, label, disabled }\n }\n })\n }, [options, i18n])\n}\n"]}
|