@letar/forms 1.0.3 → 1.2.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.
Files changed (56) hide show
  1. package/CHANGELOG.md +331 -0
  2. package/README.md +9 -9
  3. package/README.ru.md +389 -0
  4. package/analytics.js +3 -0
  5. package/analytics.js.map +1 -0
  6. package/chunk-2PSXYC3I.js +1782 -0
  7. package/chunk-2PSXYC3I.js.map +1 -0
  8. package/chunk-5D6S6EGF.js +206 -0
  9. package/chunk-5D6S6EGF.js.map +1 -0
  10. package/chunk-6E7VJAJT.js +78 -0
  11. package/chunk-6E7VJAJT.js.map +1 -0
  12. package/chunk-CGXKRCSM.js +117 -0
  13. package/chunk-CGXKRCSM.js.map +1 -0
  14. package/chunk-DQUVUMCX.js +982 -0
  15. package/chunk-DQUVUMCX.js.map +1 -0
  16. package/chunk-K3J4L26K.js +345 -0
  17. package/chunk-K3J4L26K.js.map +1 -0
  18. package/chunk-MAYUFA5K.js +822 -0
  19. package/chunk-MAYUFA5K.js.map +1 -0
  20. package/{chunk-4V6WBJ76.js → chunk-MVGXZNHP.js} +2 -2
  21. package/{chunk-4V6WBJ76.js.map → chunk-MVGXZNHP.js.map} +1 -1
  22. package/chunk-MZDTJSF7.js +299 -0
  23. package/chunk-MZDTJSF7.js.map +1 -0
  24. package/chunk-Q5EOF36Y.js +709 -0
  25. package/chunk-Q5EOF36Y.js.map +1 -0
  26. package/{chunk-7FEQFDJ7.js → chunk-R2RTCKXY.js} +2 -2
  27. package/{chunk-7FEQFDJ7.js.map → chunk-R2RTCKXY.js.map} +1 -1
  28. package/chunk-XFWLD5EO.js +1045 -0
  29. package/chunk-XFWLD5EO.js.map +1 -0
  30. package/fields/boolean.js +5 -0
  31. package/fields/boolean.js.map +1 -0
  32. package/fields/datetime.js +5 -0
  33. package/fields/datetime.js.map +1 -0
  34. package/fields/number.js +5 -0
  35. package/fields/number.js.map +1 -0
  36. package/fields/selection.js +5 -0
  37. package/fields/selection.js.map +1 -0
  38. package/fields/specialized.js +5 -0
  39. package/fields/specialized.js.map +1 -0
  40. package/fields/text.js +5 -0
  41. package/fields/text.js.map +1 -0
  42. package/hcaptcha-U4XIT3HS.js +64 -0
  43. package/hcaptcha-U4XIT3HS.js.map +1 -0
  44. package/i18n.js +1 -1
  45. package/index.js +3736 -4962
  46. package/index.js.map +1 -1
  47. package/offline.js +1 -1
  48. package/package.json +59 -4
  49. package/recaptcha-PKAUAY2S.js +56 -0
  50. package/recaptcha-PKAUAY2S.js.map +1 -0
  51. package/server-errors.js +3 -0
  52. package/server-errors.js.map +1 -0
  53. package/turnstile-7FXTBSLW.js +36 -0
  54. package/turnstile-7FXTBSLW.js.map +1 -0
  55. package/validators/ru.js +73 -0
  56. package/validators/ru.js.map +1 -0
@@ -0,0 +1,299 @@
1
+ import { createField, FieldWrapper, FieldTooltip, FieldError } from './chunk-XFWLD5EO.js';
2
+ import { NumberInput, Field, RatingGroup, HStack, Slider, For } from '@chakra-ui/react';
3
+ import { useMemo } from 'react';
4
+ import { jsx, jsxs } from 'react/jsx-runtime';
5
+
6
+ var FieldCurrency = createField({
7
+ displayName: "FieldCurrency",
8
+ useFieldState: (props) => {
9
+ const { currency = "RUB", currencyDisplay = "symbol", decimalScale = 2 } = props;
10
+ const formatOptions = useMemo(
11
+ () => ({
12
+ style: "currency",
13
+ currency,
14
+ currencyDisplay,
15
+ minimumFractionDigits: decimalScale,
16
+ maximumFractionDigits: decimalScale
17
+ }),
18
+ [currency, currencyDisplay, decimalScale]
19
+ );
20
+ return { formatOptions };
21
+ },
22
+ render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps, fieldState }) => {
23
+ const value = field.state.value;
24
+ const { min, max, step = 0.01, size } = componentProps;
25
+ const { formatOptions } = fieldState;
26
+ return /* @__PURE__ */ jsx(FieldWrapper, { resolved, hasError, errorMessage, fullPath, children: /* @__PURE__ */ jsxs(
27
+ NumberInput.Root,
28
+ {
29
+ value: value?.toString() ?? "",
30
+ onValueChange: (details) => {
31
+ const num = details.valueAsNumber;
32
+ field.handleChange(Number.isNaN(num) ? void 0 : num);
33
+ },
34
+ onBlur: field.handleBlur,
35
+ min,
36
+ max,
37
+ step,
38
+ formatOptions,
39
+ clampValueOnBlur: true,
40
+ size,
41
+ children: [
42
+ /* @__PURE__ */ jsxs(NumberInput.Control, { children: [
43
+ /* @__PURE__ */ jsx(NumberInput.IncrementTrigger, {}),
44
+ /* @__PURE__ */ jsx(NumberInput.DecrementTrigger, {})
45
+ ] }),
46
+ /* @__PURE__ */ jsx(NumberInput.Input, { placeholder: resolved.placeholder, "data-field-name": fullPath })
47
+ ]
48
+ }
49
+ ) });
50
+ }
51
+ });
52
+ var FieldNumber = createField({
53
+ displayName: "FieldNumber",
54
+ render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps }) => {
55
+ const value = field.state.value;
56
+ const { constraints } = resolved;
57
+ const min = componentProps.min ?? constraints.number?.min;
58
+ const max = componentProps.max ?? constraints.number?.max;
59
+ const step = componentProps.step ?? constraints.number?.step;
60
+ const isOptional = resolved.required === false;
61
+ const isEmpty = value === void 0 || value === null;
62
+ const shouldApplyMinMax = !isOptional || !isEmpty;
63
+ return /* @__PURE__ */ jsx(FieldWrapper, { resolved, hasError, errorMessage, fullPath, children: /* @__PURE__ */ jsxs(
64
+ NumberInput.Root,
65
+ {
66
+ value: value?.toString() ?? "",
67
+ onValueChange: (details) => {
68
+ const num = details.valueAsNumber;
69
+ field.handleChange(Number.isNaN(num) ? void 0 : num);
70
+ },
71
+ onBlur: field.handleBlur,
72
+ min: shouldApplyMinMax ? min : void 0,
73
+ max: shouldApplyMinMax ? max : void 0,
74
+ step,
75
+ children: [
76
+ /* @__PURE__ */ jsxs(NumberInput.Control, { children: [
77
+ /* @__PURE__ */ jsx(NumberInput.IncrementTrigger, {}),
78
+ /* @__PURE__ */ jsx(NumberInput.DecrementTrigger, {})
79
+ ] }),
80
+ /* @__PURE__ */ jsx(NumberInput.Input, { placeholder: resolved.placeholder, "data-field-name": fullPath, inputMode: "decimal" })
81
+ ]
82
+ }
83
+ ) });
84
+ }
85
+ });
86
+ var FieldNumberInput = createField({
87
+ displayName: "FieldNumberInput",
88
+ render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps }) => {
89
+ const value = field.state.value;
90
+ return /* @__PURE__ */ jsx(FieldWrapper, { resolved, hasError, errorMessage, fullPath, children: /* @__PURE__ */ jsxs(
91
+ NumberInput.Root,
92
+ {
93
+ value: value?.toString() ?? "",
94
+ onValueChange: (details) => {
95
+ const num = details.valueAsNumber;
96
+ field.handleChange(Number.isNaN(num) ? void 0 : num);
97
+ },
98
+ onBlur: field.handleBlur,
99
+ min: componentProps.min,
100
+ max: componentProps.max,
101
+ step: componentProps.step,
102
+ formatOptions: componentProps.formatOptions,
103
+ allowMouseWheel: componentProps.allowMouseWheel,
104
+ clampValueOnBlur: componentProps.clampValueOnBlur ?? true,
105
+ spinOnPress: componentProps.spinOnPress ?? true,
106
+ size: componentProps.size,
107
+ children: [
108
+ /* @__PURE__ */ jsxs(NumberInput.Control, { children: [
109
+ /* @__PURE__ */ jsx(NumberInput.IncrementTrigger, {}),
110
+ /* @__PURE__ */ jsx(NumberInput.DecrementTrigger, {})
111
+ ] }),
112
+ /* @__PURE__ */ jsx(NumberInput.Input, { placeholder: resolved.placeholder, "data-field-name": fullPath, inputMode: "decimal" })
113
+ ]
114
+ }
115
+ ) });
116
+ }
117
+ });
118
+ var FieldPercentage = createField({
119
+ displayName: "FieldPercentage",
120
+ useFieldState: (props) => {
121
+ const { decimalScale = 0 } = props;
122
+ const formatOptions = useMemo(
123
+ () => ({
124
+ style: "unit",
125
+ unit: "percent",
126
+ unitDisplay: "short",
127
+ minimumFractionDigits: decimalScale,
128
+ maximumFractionDigits: decimalScale
129
+ }),
130
+ [decimalScale]
131
+ );
132
+ return { formatOptions };
133
+ },
134
+ render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps, fieldState }) => {
135
+ const value = field.state.value;
136
+ const { min = 0, max = 100, step = 1, size } = componentProps;
137
+ const { formatOptions } = fieldState;
138
+ return /* @__PURE__ */ jsx(FieldWrapper, { resolved, hasError, errorMessage, fullPath, children: /* @__PURE__ */ jsxs(
139
+ NumberInput.Root,
140
+ {
141
+ value: value?.toString() ?? "",
142
+ onValueChange: (details) => {
143
+ const num = details.valueAsNumber;
144
+ field.handleChange(Number.isNaN(num) ? void 0 : num);
145
+ },
146
+ onBlur: field.handleBlur,
147
+ min,
148
+ max,
149
+ step,
150
+ formatOptions,
151
+ clampValueOnBlur: true,
152
+ size,
153
+ children: [
154
+ /* @__PURE__ */ jsxs(NumberInput.Control, { children: [
155
+ /* @__PURE__ */ jsx(NumberInput.IncrementTrigger, {}),
156
+ /* @__PURE__ */ jsx(NumberInput.DecrementTrigger, {})
157
+ ] }),
158
+ /* @__PURE__ */ jsx(NumberInput.Input, { placeholder: resolved.placeholder, "data-field-name": fullPath })
159
+ ]
160
+ }
161
+ ) });
162
+ }
163
+ });
164
+ var FieldRating = createField({
165
+ displayName: "FieldRating",
166
+ render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps }) => {
167
+ const { count = 5, allowHalf = false, size = "md", colorPalette, icon, onValueChange } = componentProps;
168
+ const value = field.state.value ?? 0;
169
+ const handleValueChange = (details) => {
170
+ field.handleChange(details.value);
171
+ onValueChange?.(details.value);
172
+ };
173
+ return /* @__PURE__ */ jsxs(
174
+ Field.Root,
175
+ {
176
+ invalid: hasError,
177
+ required: resolved.required,
178
+ disabled: resolved.disabled,
179
+ readOnly: resolved.readOnly,
180
+ children: [
181
+ /* @__PURE__ */ jsxs(
182
+ RatingGroup.Root,
183
+ {
184
+ value,
185
+ onValueChange: handleValueChange,
186
+ count,
187
+ allowHalf,
188
+ size,
189
+ colorPalette,
190
+ disabled: resolved.disabled,
191
+ readOnly: resolved.readOnly,
192
+ "data-field-name": fullPath,
193
+ children: [
194
+ resolved.label && /* @__PURE__ */ jsx(RatingGroup.Label, { children: resolved.tooltip ? /* @__PURE__ */ jsxs(HStack, { gap: 1, children: [
195
+ /* @__PURE__ */ jsx("span", { children: resolved.label }),
196
+ /* @__PURE__ */ jsx(FieldTooltip, { ...resolved.tooltip })
197
+ ] }) : resolved.label }),
198
+ /* @__PURE__ */ jsx(RatingGroup.HiddenInput, { onBlur: field.handleBlur }),
199
+ /* @__PURE__ */ jsx(RatingGroup.Control, { children: Array.from({ length: count }).map((_, index) => /* @__PURE__ */ jsx(RatingGroup.Item, { index: index + 1, children: /* @__PURE__ */ jsx(RatingGroup.ItemIndicator, { icon }) }, index)) })
200
+ ]
201
+ }
202
+ ),
203
+ /* @__PURE__ */ jsx(FieldError, { hasError, errorMessage, helperText: resolved.helperText })
204
+ ]
205
+ }
206
+ );
207
+ }
208
+ });
209
+ var FieldSlider = createField({
210
+ displayName: "FieldSlider",
211
+ render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps }) => {
212
+ const { constraints } = resolved;
213
+ const min = componentProps.min ?? constraints.number?.min ?? 0;
214
+ const max = componentProps.max ?? constraints.number?.max ?? 100;
215
+ const step = componentProps.step ?? constraints.number?.step ?? 1;
216
+ const {
217
+ showValue,
218
+ orientation = "horizontal",
219
+ size = "md",
220
+ variant = "outline",
221
+ colorPalette,
222
+ marks,
223
+ origin,
224
+ onValueChange,
225
+ onValueChangeEnd
226
+ } = componentProps;
227
+ const normalizedMarks = marks?.map((mark) => typeof mark === "number" ? { value: mark, label: void 0 } : mark);
228
+ const numValue = field.state.value ?? min;
229
+ const arrayValue = [numValue];
230
+ const handleValueChange = (details) => {
231
+ const newValue = details.value[0] ?? min;
232
+ field.handleChange(newValue);
233
+ onValueChange?.(newValue);
234
+ };
235
+ const handleValueChangeEnd = (details) => {
236
+ const newValue = details.value[0] ?? min;
237
+ onValueChangeEnd?.(newValue);
238
+ };
239
+ return /* @__PURE__ */ jsxs(
240
+ Field.Root,
241
+ {
242
+ invalid: hasError,
243
+ required: resolved.required,
244
+ disabled: resolved.disabled,
245
+ readOnly: resolved.readOnly,
246
+ children: [
247
+ /* @__PURE__ */ jsxs(
248
+ Slider.Root,
249
+ {
250
+ value: arrayValue,
251
+ onValueChange: handleValueChange,
252
+ onValueChangeEnd: handleValueChangeEnd,
253
+ min,
254
+ max,
255
+ step,
256
+ orientation,
257
+ size,
258
+ variant,
259
+ colorPalette,
260
+ origin,
261
+ disabled: resolved.disabled,
262
+ readOnly: resolved.readOnly,
263
+ invalid: hasError,
264
+ thumbAlignment: "center",
265
+ onBlur: field.handleBlur,
266
+ "data-field-name": fullPath,
267
+ children: [
268
+ resolved.label && !showValue && /* @__PURE__ */ jsx(Slider.Label, { children: resolved.tooltip ? /* @__PURE__ */ jsxs(HStack, { gap: 1, children: [
269
+ /* @__PURE__ */ jsx("span", { children: resolved.label }),
270
+ /* @__PURE__ */ jsx(FieldTooltip, { ...resolved.tooltip })
271
+ ] }) : resolved.label }),
272
+ resolved.label && showValue && /* @__PURE__ */ jsxs(HStack, { justify: "space-between", children: [
273
+ /* @__PURE__ */ jsx(Slider.Label, { children: resolved.tooltip ? /* @__PURE__ */ jsxs(HStack, { gap: 1, children: [
274
+ /* @__PURE__ */ jsx("span", { children: resolved.label }),
275
+ /* @__PURE__ */ jsx(FieldTooltip, { ...resolved.tooltip })
276
+ ] }) : resolved.label }),
277
+ /* @__PURE__ */ jsx(Slider.ValueText, {})
278
+ ] }),
279
+ /* @__PURE__ */ jsxs(Slider.Control, { children: [
280
+ /* @__PURE__ */ jsx(Slider.Track, { children: /* @__PURE__ */ jsx(Slider.Range, {}) }),
281
+ /* @__PURE__ */ jsx(For, { each: arrayValue, children: (_, index) => /* @__PURE__ */ jsx(Slider.Thumb, { index, children: /* @__PURE__ */ jsx(Slider.HiddenInput, {}) }, index) }),
282
+ normalizedMarks && normalizedMarks.length > 0 && /* @__PURE__ */ jsx(Slider.MarkerGroup, { children: normalizedMarks.map((mark, index) => /* @__PURE__ */ jsxs(Slider.Marker, { value: mark.value, children: [
283
+ /* @__PURE__ */ jsx(Slider.MarkerIndicator, {}),
284
+ mark.label
285
+ ] }, index)) })
286
+ ] })
287
+ ]
288
+ }
289
+ ),
290
+ /* @__PURE__ */ jsx(FieldError, { hasError, errorMessage, helperText: resolved.helperText })
291
+ ]
292
+ }
293
+ );
294
+ }
295
+ });
296
+
297
+ export { FieldCurrency, FieldNumber, FieldNumberInput, FieldPercentage, FieldRating, FieldSlider };
298
+ //# sourceMappingURL=chunk-MZDTJSF7.js.map
299
+ //# sourceMappingURL=chunk-MZDTJSF7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/declarative/form-fields/number/field-currency.tsx","../src/lib/declarative/form-fields/number/field-number.tsx","../src/lib/declarative/form-fields/number/field-number-input.tsx","../src/lib/declarative/form-fields/number/field-percentage.tsx","../src/lib/declarative/form-fields/number/field-rating.tsx","../src/lib/declarative/form-fields/number/field-slider.tsx"],"names":["jsx","jsxs","NumberInput","useMemo","Field","HStack"],"mappings":";;;;;AAsCO,IAAM,gBAAgB,WAAA,CAAwE;AAAA,EACnG,WAAA,EAAa,eAAA;AAAA,EAEb,aAAA,EAAe,CAAC,KAAA,KAAU;AACxB,IAAA,MAAM,EAAE,QAAA,GAAW,KAAA,EAAO,kBAAkB,QAAA,EAAU,YAAA,GAAe,GAAE,GAAI,KAAA;AAG3E,IAAA,MAAM,aAAA,GAAgB,OAAA;AAAA,MACpB,OAAO;AAAA,QACL,KAAA,EAAO,UAAA;AAAA,QACP,QAAA;AAAA,QACA,eAAA;AAAA,QACA,qBAAA,EAAuB,YAAA;AAAA,QACvB,qBAAA,EAAuB;AAAA,OACzB,CAAA;AAAA,MACA,CAAC,QAAA,EAAU,eAAA,EAAiB,YAAY;AAAA,KAC1C;AAEA,IAAA,OAAO,EAAE,aAAA,EAAc;AAAA,EACzB,CAAA;AAAA,EAEA,MAAA,EAAQ,CAAC,EAAE,KAAA,EAAO,QAAA,EAAU,UAAU,QAAA,EAAU,YAAA,EAAc,cAAA,EAAgB,UAAA,EAAW,KAAoB;AAC3G,IAAA,MAAM,KAAA,GAAQ,MAAM,KAAA,CAAM,KAAA;AAE1B,IAAA,MAAM,EAAE,GAAA,EAAK,GAAA,EAAK,IAAA,GAAO,IAAA,EAAM,MAAK,GAAI,cAAA;AAExC,IAAA,MAAM,EAAE,eAAc,GAAI,UAAA;AAE1B,IAAA,uBACE,GAAA,CAAC,YAAA,EAAA,EAAa,QAAA,EAAoB,QAAA,EAAoB,cAA4B,QAAA,EAChF,QAAA,kBAAA,IAAA;AAAA,MAAC,WAAA,CAAY,IAAA;AAAA,MAAZ;AAAA,QACC,KAAA,EAAO,KAAA,EAAO,QAAA,EAAS,IAAK,EAAA;AAAA,QAC5B,aAAA,EAAe,CAAC,OAAA,KAAuC;AACrD,UAAA,MAAM,MAAM,OAAA,CAAQ,aAAA;AACpB,UAAA,KAAA,CAAM,aAAa,MAAA,CAAO,KAAA,CAAM,GAAG,CAAA,GAAI,SAAY,GAAG,CAAA;AAAA,QACxD,CAAA;AAAA,QACA,QAAQ,KAAA,CAAM,UAAA;AAAA,QACd,GAAA;AAAA,QACA,GAAA;AAAA,QACA,IAAA;AAAA,QACA,aAAA;AAAA,QACA,gBAAA,EAAgB,IAAA;AAAA,QAChB,IAAA;AAAA,QAEA,QAAA,EAAA;AAAA,0BAAA,IAAA,CAAC,WAAA,CAAY,SAAZ,EACC,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,WAAA,CAAY,kBAAZ,EAA6B,CAAA;AAAA,4BAC9B,GAAA,CAAC,WAAA,CAAY,gBAAA,EAAZ,EAA6B;AAAA,WAAA,EAChC,CAAA;AAAA,0BACA,GAAA,CAAC,YAAY,KAAA,EAAZ,EAAkB,aAAa,QAAA,CAAS,WAAA,EAAa,mBAAiB,QAAA,EAAU;AAAA;AAAA;AAAA,KACnF,EACF,CAAA;AAAA,EAEJ;AACF,CAAC;ACjEM,IAAM,cAAc,WAAA,CAAkD;AAAA,EAC3E,WAAA,EAAa,aAAA;AAAA,EACb,MAAA,EAAQ,CAAC,EAAE,KAAA,EAAO,UAAU,QAAA,EAAU,QAAA,EAAU,YAAA,EAAc,cAAA,EAAe,KAAoB;AAC/F,IAAA,MAAM,KAAA,GAAQ,MAAM,KAAA,CAAM,KAAA;AAC1B,IAAA,MAAM,EAAE,aAAY,GAAI,QAAA;AAGxB,IAAA,MAAM,GAAA,GAAM,cAAA,CAAe,GAAA,IAAO,WAAA,CAAY,MAAA,EAAQ,GAAA;AACtD,IAAA,MAAM,GAAA,GAAM,cAAA,CAAe,GAAA,IAAO,WAAA,CAAY,MAAA,EAAQ,GAAA;AACtD,IAAA,MAAM,IAAA,GAAO,cAAA,CAAe,IAAA,IAAQ,WAAA,CAAY,MAAA,EAAQ,IAAA;AAIxD,IAAA,MAAM,UAAA,GAAa,SAAS,QAAA,KAAa,KAAA;AACzC,IAAA,MAAM,OAAA,GAAU,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA;AACjD,IAAA,MAAM,iBAAA,GAAoB,CAAC,UAAA,IAAc,CAAC,OAAA;AAE1C,IAAA,uBACEA,GAAAA,CAAC,YAAA,EAAA,EAAa,UAAoB,QAAA,EAAoB,YAAA,EAA4B,UAChF,QAAA,kBAAAC,IAAAA;AAAA,MAACC,WAAAA,CAAY,IAAA;AAAA,MAAZ;AAAA,QACC,KAAA,EAAO,KAAA,EAAO,QAAA,EAAS,IAAK,EAAA;AAAA,QAC5B,aAAA,EAAe,CAAC,OAAA,KAAuC;AACrD,UAAA,MAAM,MAAM,OAAA,CAAQ,aAAA;AACpB,UAAA,KAAA,CAAM,aAAa,MAAA,CAAO,KAAA,CAAM,GAAG,CAAA,GAAI,SAAY,GAAG,CAAA;AAAA,QACxD,CAAA;AAAA,QACA,QAAQ,KAAA,CAAM,UAAA;AAAA,QACd,GAAA,EAAK,oBAAoB,GAAA,GAAM,MAAA;AAAA,QAC/B,GAAA,EAAK,oBAAoB,GAAA,GAAM,MAAA;AAAA,QAC/B,IAAA;AAAA,QAEA,QAAA,EAAA;AAAA,0BAAAD,IAAAA,CAACC,WAAAA,CAAY,OAAA,EAAZ,EACC,QAAA,EAAA;AAAA,4BAAAF,GAAAA,CAACE,WAAAA,CAAY,gBAAA,EAAZ,EAA6B,CAAA;AAAA,4BAC9BF,GAAAA,CAACE,WAAAA,CAAY,gBAAA,EAAZ,EAA6B;AAAA,WAAA,EAChC,CAAA;AAAA,0BACAF,GAAAA,CAACE,WAAAA,CAAY,KAAA,EAAZ,EAAkB,WAAA,EAAa,QAAA,CAAS,WAAA,EAAa,iBAAA,EAAiB,QAAA,EAAU,SAAA,EAAU,SAAA,EAAU;AAAA;AAAA;AAAA,KACvG,EACF,CAAA;AAAA,EAEJ;AACF,CAAC;AClCM,IAAM,mBAAmB,WAAA,CAAuD;AAAA,EACrF,WAAA,EAAa,kBAAA;AAAA,EAEb,MAAA,EAAQ,CAAC,EAAE,KAAA,EAAO,UAAU,QAAA,EAAU,QAAA,EAAU,YAAA,EAAc,cAAA,EAAe,KAAoB;AAC/F,IAAA,MAAM,KAAA,GAAQ,MAAM,KAAA,CAAM,KAAA;AAE1B,IAAA,uBACEF,GAAAA,CAAC,YAAA,EAAA,EAAa,UAAoB,QAAA,EAAoB,YAAA,EAA4B,UAChF,QAAA,kBAAAC,IAAAA;AAAA,MAACC,WAAAA,CAAY,IAAA;AAAA,MAAZ;AAAA,QACC,KAAA,EAAO,KAAA,EAAO,QAAA,EAAS,IAAK,EAAA;AAAA,QAC5B,aAAA,EAAe,CAAC,OAAA,KAAuC;AACrD,UAAA,MAAM,MAAM,OAAA,CAAQ,aAAA;AACpB,UAAA,KAAA,CAAM,aAAa,MAAA,CAAO,KAAA,CAAM,GAAG,CAAA,GAAI,SAAY,GAAG,CAAA;AAAA,QACxD,CAAA;AAAA,QACA,QAAQ,KAAA,CAAM,UAAA;AAAA,QACd,KAAK,cAAA,CAAe,GAAA;AAAA,QACpB,KAAK,cAAA,CAAe,GAAA;AAAA,QACpB,MAAM,cAAA,CAAe,IAAA;AAAA,QACrB,eAAe,cAAA,CAAe,aAAA;AAAA,QAC9B,iBAAiB,cAAA,CAAe,eAAA;AAAA,QAChC,gBAAA,EAAkB,eAAe,gBAAA,IAAoB,IAAA;AAAA,QACrD,WAAA,EAAa,eAAe,WAAA,IAAe,IAAA;AAAA,QAC3C,MAAM,cAAA,CAAe,IAAA;AAAA,QAErB,QAAA,EAAA;AAAA,0BAAAD,IAAAA,CAACC,WAAAA,CAAY,OAAA,EAAZ,EACC,QAAA,EAAA;AAAA,4BAAAF,GAAAA,CAACE,WAAAA,CAAY,gBAAA,EAAZ,EAA6B,CAAA;AAAA,4BAC9BF,GAAAA,CAACE,WAAAA,CAAY,gBAAA,EAAZ,EAA6B;AAAA,WAAA,EAChC,CAAA;AAAA,0BACAF,GAAAA,CAACE,WAAAA,CAAY,KAAA,EAAZ,EAAkB,WAAA,EAAa,QAAA,CAAS,WAAA,EAAa,iBAAA,EAAiB,QAAA,EAAU,SAAA,EAAU,SAAA,EAAU;AAAA;AAAA;AAAA,KACvG,EACF,CAAA;AAAA,EAEJ;AACF,CAAC;AC9BM,IAAM,kBAAkB,WAAA,CAA4E;AAAA,EACzG,WAAA,EAAa,iBAAA;AAAA,EAEb,aAAA,EAAe,CAAC,KAAA,KAAU;AACxB,IAAA,MAAM,EAAE,YAAA,GAAe,CAAA,EAAE,GAAI,KAAA;AAI7B,IAAA,MAAM,aAAA,GAAgBC,OAAAA;AAAA,MACpB,OAAO;AAAA,QACL,KAAA,EAAO,MAAA;AAAA,QACP,IAAA,EAAM,SAAA;AAAA,QACN,WAAA,EAAa,OAAA;AAAA,QACb,qBAAA,EAAuB,YAAA;AAAA,QACvB,qBAAA,EAAuB;AAAA,OACzB,CAAA;AAAA,MACA,CAAC,YAAY;AAAA,KACf;AAEA,IAAA,OAAO,EAAE,aAAA,EAAc;AAAA,EACzB,CAAA;AAAA,EAEA,MAAA,EAAQ,CAAC,EAAE,KAAA,EAAO,QAAA,EAAU,UAAU,QAAA,EAAU,YAAA,EAAc,cAAA,EAAgB,UAAA,EAAW,KAAoB;AAC3G,IAAA,MAAM,KAAA,GAAQ,MAAM,KAAA,CAAM,KAAA;AAE1B,IAAA,MAAM,EAAE,MAAM,CAAA,EAAG,GAAA,GAAM,KAAK,IAAA,GAAO,CAAA,EAAG,MAAK,GAAI,cAAA;AAE/C,IAAA,MAAM,EAAE,eAAc,GAAI,UAAA;AAE1B,IAAA,uBACEH,GAAAA,CAAC,YAAA,EAAA,EAAa,UAAoB,QAAA,EAAoB,YAAA,EAA4B,UAChF,QAAA,kBAAAC,IAAAA;AAAA,MAACC,WAAAA,CAAY,IAAA;AAAA,MAAZ;AAAA,QACC,KAAA,EAAO,KAAA,EAAO,QAAA,EAAS,IAAK,EAAA;AAAA,QAC5B,aAAA,EAAe,CAAC,OAAA,KAAuC;AACrD,UAAA,MAAM,MAAM,OAAA,CAAQ,aAAA;AACpB,UAAA,KAAA,CAAM,aAAa,MAAA,CAAO,KAAA,CAAM,GAAG,CAAA,GAAI,SAAY,GAAG,CAAA;AAAA,QACxD,CAAA;AAAA,QACA,QAAQ,KAAA,CAAM,UAAA;AAAA,QACd,GAAA;AAAA,QACA,GAAA;AAAA,QACA,IAAA;AAAA,QACA,aAAA;AAAA,QACA,gBAAA,EAAgB,IAAA;AAAA,QAChB,IAAA;AAAA,QAEA,QAAA,EAAA;AAAA,0BAAAD,IAAAA,CAACC,WAAAA,CAAY,OAAA,EAAZ,EACC,QAAA,EAAA;AAAA,4BAAAF,GAAAA,CAACE,WAAAA,CAAY,gBAAA,EAAZ,EAA6B,CAAA;AAAA,4BAC9BF,GAAAA,CAACE,WAAAA,CAAY,gBAAA,EAAZ,EAA6B;AAAA,WAAA,EAChC,CAAA;AAAA,0BACAF,IAACE,WAAAA,CAAY,KAAA,EAAZ,EAAkB,WAAA,EAAa,QAAA,CAAS,WAAA,EAAa,iBAAA,EAAiB,QAAA,EAAU;AAAA;AAAA;AAAA,KACnF,EACF,CAAA;AAAA,EAEJ;AACF,CAAC;AC9BM,IAAM,cAAc,WAAA,CAAsC;AAAA,EAC/D,WAAA,EAAa,aAAA;AAAA,EAEb,MAAA,EAAQ,CAAC,EAAE,KAAA,EAAO,UAAU,QAAA,EAAU,QAAA,EAAU,YAAA,EAAc,cAAA,EAAe,KAAoB;AAC/F,IAAA,MAAM,EAAE,KAAA,GAAQ,CAAA,EAAG,SAAA,GAAY,KAAA,EAAO,OAAO,IAAA,EAAM,YAAA,EAAc,IAAA,EAAM,aAAA,EAAc,GAAI,cAAA;AAEzF,IAAA,MAAM,KAAA,GAAS,KAAA,CAAM,KAAA,CAAM,KAAA,IAAoB,CAAA;AAE/C,IAAA,MAAM,iBAAA,GAAoB,CAAC,OAAA,KAA+B;AACxD,MAAA,KAAA,CAAM,YAAA,CAAa,QAAQ,KAAK,CAAA;AAChC,MAAA,aAAA,GAAgB,QAAQ,KAAK,CAAA;AAAA,IAC/B,CAAA;AAEA,IAAA,uBACED,IAAAA;AAAA,MAAC,KAAA,CAAM,IAAA;AAAA,MAAN;AAAA,QACC,OAAA,EAAS,QAAA;AAAA,QACT,UAAU,QAAA,CAAS,QAAA;AAAA,QACnB,UAAU,QAAA,CAAS,QAAA;AAAA,QACnB,UAAU,QAAA,CAAS,QAAA;AAAA,QAEnB,QAAA,EAAA;AAAA,0BAAAA,IAAAA;AAAA,YAAC,WAAA,CAAY,IAAA;AAAA,YAAZ;AAAA,cACC,KAAA;AAAA,cACA,aAAA,EAAe,iBAAA;AAAA,cACf,KAAA;AAAA,cACA,SAAA;AAAA,cACA,IAAA;AAAA,cACA,YAAA;AAAA,cACA,UAAU,QAAA,CAAS,QAAA;AAAA,cACnB,UAAU,QAAA,CAAS,QAAA;AAAA,cACnB,iBAAA,EAAiB,QAAA;AAAA,cAEhB,QAAA,EAAA;AAAA,gBAAA,QAAA,CAAS,KAAA,oBACRD,GAAAA,CAAC,WAAA,CAAY,KAAA,EAAZ,EACE,QAAA,EAAA,QAAA,CAAS,OAAA,mBACRC,IAAAA,CAAC,MAAA,EAAA,EAAO,GAAA,EAAK,CAAA,EACX,QAAA,EAAA;AAAA,kCAAAD,GAAAA,CAAC,MAAA,EAAA,EAAM,QAAA,EAAA,QAAA,CAAS,KAAA,EAAM,CAAA;AAAA,kCACtBA,GAAAA,CAAC,YAAA,EAAA,EAAc,GAAG,SAAS,OAAA,EAAS;AAAA,iBAAA,EACtC,CAAA,GAEA,SAAS,KAAA,EAEb,CAAA;AAAA,gCAEFA,GAAAA,CAAC,WAAA,CAAY,aAAZ,EAAwB,MAAA,EAAQ,MAAM,UAAA,EAAY,CAAA;AAAA,gCACnDA,GAAAA,CAAC,WAAA,CAAY,OAAA,EAAZ,EACE,QAAA,EAAA,KAAA,CAAM,IAAA,CAAK,EAAE,MAAA,EAAQ,KAAA,EAAO,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,EAAG,KAAA,qBACrCA,GAAAA,CAAC,WAAA,CAAY,IAAA,EAAZ,EAA6B,KAAA,EAAO,QAAQ,CAAA,EAC3C,QAAA,kBAAAA,GAAAA,CAAC,WAAA,CAAY,eAAZ,EAA0B,IAAA,EAA8C,CAAA,EAAA,EADpD,KAEvB,CACD,CAAA,EACH;AAAA;AAAA;AAAA,WACF;AAAA,0BACAA,GAAAA,CAAC,UAAA,EAAA,EAAW,UAAoB,YAAA,EAA4B,UAAA,EAAY,SAAS,UAAA,EAAY;AAAA;AAAA;AAAA,KAC/F;AAAA,EAEJ;AACF,CAAC;AC3BM,IAAM,cAAc,WAAA,CAAsC;AAAA,EAC/D,WAAA,EAAa,aAAA;AAAA,EAEb,MAAA,EAAQ,CAAC,EAAE,KAAA,EAAO,UAAU,QAAA,EAAU,QAAA,EAAU,YAAA,EAAc,cAAA,EAAe,KAAoB;AAC/F,IAAA,MAAM,EAAE,aAAY,GAAI,QAAA;AAGxB,IAAA,MAAM,GAAA,GAAM,cAAA,CAAe,GAAA,IAAO,WAAA,CAAY,QAAQ,GAAA,IAAO,CAAA;AAC7D,IAAA,MAAM,GAAA,GAAM,cAAA,CAAe,GAAA,IAAO,WAAA,CAAY,QAAQ,GAAA,IAAO,GAAA;AAC7D,IAAA,MAAM,IAAA,GAAO,cAAA,CAAe,IAAA,IAAQ,WAAA,CAAY,QAAQ,IAAA,IAAQ,CAAA;AAEhE,IAAA,MAAM;AAAA,MACJ,SAAA;AAAA,MACA,WAAA,GAAc,YAAA;AAAA,MACd,IAAA,GAAO,IAAA;AAAA,MACP,OAAA,GAAU,SAAA;AAAA,MACV,YAAA;AAAA,MACA,KAAA;AAAA,MACA,MAAA;AAAA,MACA,aAAA;AAAA,MACA;AAAA,KACF,GAAI,cAAA;AAGJ,IAAA,MAAM,eAAA,GAAkB,KAAA,EAAO,GAAA,CAAI,CAAC,SAAU,OAAO,IAAA,KAAS,QAAA,GAAW,EAAE,KAAA,EAAO,IAAA,EAAM,KAAA,EAAO,MAAA,KAAc,IAAK,CAAA;AAGlH,IAAA,MAAM,QAAA,GAAY,KAAA,CAAM,KAAA,CAAM,KAAA,IAAoB,GAAA;AAClD,IAAA,MAAM,UAAA,GAAa,CAAC,QAAQ,CAAA;AAE5B,IAAA,MAAM,iBAAA,GAAoB,CAAC,OAAA,KAAiC;AAC1D,MAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,KAAA,CAAM,CAAC,CAAA,IAAK,GAAA;AACrC,MAAA,KAAA,CAAM,aAAa,QAAQ,CAAA;AAC3B,MAAA,aAAA,GAAgB,QAAQ,CAAA;AAAA,IAC1B,CAAA;AAEA,IAAA,MAAM,oBAAA,GAAuB,CAAC,OAAA,KAAiC;AAC7D,MAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,KAAA,CAAM,CAAC,CAAA,IAAK,GAAA;AACrC,MAAA,gBAAA,GAAmB,QAAQ,CAAA;AAAA,IAC7B,CAAA;AAEA,IAAA,uBACEC,IAAAA;AAAA,MAACG,KAAAA,CAAM,IAAA;AAAA,MAAN;AAAA,QACC,OAAA,EAAS,QAAA;AAAA,QACT,UAAU,QAAA,CAAS,QAAA;AAAA,QACnB,UAAU,QAAA,CAAS,QAAA;AAAA,QACnB,UAAU,QAAA,CAAS,QAAA;AAAA,QAEnB,QAAA,EAAA;AAAA,0BAAAH,IAAAA;AAAA,YAAC,MAAA,CAAO,IAAA;AAAA,YAAP;AAAA,cACC,KAAA,EAAO,UAAA;AAAA,cACP,aAAA,EAAe,iBAAA;AAAA,cACf,gBAAA,EAAkB,oBAAA;AAAA,cAClB,GAAA;AAAA,cACA,GAAA;AAAA,cACA,IAAA;AAAA,cACA,WAAA;AAAA,cACA,IAAA;AAAA,cACA,OAAA;AAAA,cACA,YAAA;AAAA,cACA,MAAA;AAAA,cACA,UAAU,QAAA,CAAS,QAAA;AAAA,cACnB,UAAU,QAAA,CAAS,QAAA;AAAA,cACnB,OAAA,EAAS,QAAA;AAAA,cACT,cAAA,EAAe,QAAA;AAAA,cACf,QAAQ,KAAA,CAAM,UAAA;AAAA,cACd,iBAAA,EAAiB,QAAA;AAAA,cAEhB,QAAA,EAAA;AAAA,gBAAA,QAAA,CAAS,KAAA,IAAS,CAAC,SAAA,oBAClBD,IAAC,MAAA,CAAO,KAAA,EAAP,EACE,QAAA,EAAA,QAAA,CAAS,0BACRC,IAAAA,CAACI,MAAAA,EAAA,EAAO,KAAK,CAAA,EACX,QAAA,EAAA;AAAA,kCAAAL,GAAAA,CAAC,MAAA,EAAA,EAAM,QAAA,EAAA,QAAA,CAAS,KAAA,EAAM,CAAA;AAAA,kCACtBA,GAAAA,CAAC,YAAA,EAAA,EAAc,GAAG,SAAS,OAAA,EAAS;AAAA,iBAAA,EACtC,CAAA,GAEA,SAAS,KAAA,EAEb,CAAA;AAAA,gBAED,QAAA,CAAS,SAAS,SAAA,oBACjBC,KAACI,MAAAA,EAAA,EAAO,SAAQ,eAAA,EACd,QAAA,EAAA;AAAA,kCAAAL,GAAAA,CAAC,MAAA,CAAO,KAAA,EAAP,EACE,QAAA,EAAA,QAAA,CAAS,OAAA,mBACRC,IAAAA,CAACI,MAAAA,EAAA,EAAO,GAAA,EAAK,CAAA,EACX,QAAA,EAAA;AAAA,oCAAAL,GAAAA,CAAC,MAAA,EAAA,EAAM,QAAA,EAAA,QAAA,CAAS,KAAA,EAAM,CAAA;AAAA,oCACtBA,GAAAA,CAAC,YAAA,EAAA,EAAc,GAAG,SAAS,OAAA,EAAS;AAAA,mBAAA,EACtC,CAAA,GAEA,SAAS,KAAA,EAEb,CAAA;AAAA,kCACAA,GAAAA,CAAC,MAAA,CAAO,SAAA,EAAP,EAAiB;AAAA,iBAAA,EACpB,CAAA;AAAA,gCAEFC,IAAAA,CAAC,MAAA,CAAO,OAAA,EAAP,EACC,QAAA,EAAA;AAAA,kCAAAD,GAAAA,CAAC,OAAO,KAAA,EAAP,EACC,0BAAAA,GAAAA,CAAC,MAAA,CAAO,KAAA,EAAP,EAAa,CAAA,EAChB,CAAA;AAAA,kCACAA,IAAC,GAAA,EAAA,EAAI,IAAA,EAAM,YACR,QAAA,EAAA,CAAC,CAAA,EAAG,0BACHA,GAAAA,CAAC,OAAO,KAAA,EAAP,EAAyB,OACxB,QAAA,kBAAAA,GAAAA,CAAC,OAAO,WAAA,EAAP,EAAmB,CAAA,EAAA,EADH,KAEnB,CAAA,EAEJ,CAAA;AAAA,kBACC,eAAA,IAAmB,gBAAgB,MAAA,GAAS,CAAA,oBAC3CA,GAAAA,CAAC,MAAA,CAAO,aAAP,EACE,QAAA,EAAA,eAAA,CAAgB,IAAI,CAAC,IAAA,EAAM,0BAC1BC,IAAAA,CAAC,OAAO,MAAA,EAAP,EAA0B,KAAA,EAAO,IAAA,CAAK,KAAA,EACrC,QAAA,EAAA;AAAA,oCAAAD,GAAAA,CAAC,MAAA,CAAO,eAAA,EAAP,EAAuB,CAAA;AAAA,oBACvB,IAAA,CAAK;AAAA,mBAAA,EAAA,EAFY,KAGpB,CACD,CAAA,EACH;AAAA,iBAAA,EAEJ;AAAA;AAAA;AAAA,WACF;AAAA,0BACAA,GAAAA,CAAC,UAAA,EAAA,EAAW,UAAoB,YAAA,EAA4B,UAAA,EAAY,SAAS,UAAA,EAAY;AAAA;AAAA;AAAA,KAC/F;AAAA,EAEJ;AACF,CAAC","file":"chunk-MZDTJSF7.js","sourcesContent":["'use client'\n\nimport { NumberInput } from '@chakra-ui/react'\nimport { type ReactElement, useMemo } from 'react'\nimport type { CurrencyFieldProps } from '../../types'\nimport { createField, FieldWrapper } from '../base'\n\n/**\n * Form.Field.Currency - Currency input field\n *\n * Renders NumberInput with currency formatting (symbol and decimal part).\n *\n * @example Russian rubles (by default)\n * ```tsx\n * <Form.Field.Currency name=\"price\" label=\"Price\" />\n * ```\n *\n * @example US Dollars\n * ```tsx\n * <Form.Field.Currency name=\"amount\" label=\"Amount\" currency=\"USD\" />\n * ```\n *\n * @example Euro with currency code\n * ```tsx\n * <Form.Field.Currency\n * name=\"total\"\n * label=\"Total\"\n * currency=\"EUR\"\n * currencyDisplay=\"code\"\n * />\n * ```\n */\n/** Currency field state */\ninterface CurrencyFieldState {\n /** Memoized format options */\n formatOptions: Intl.NumberFormatOptions\n}\n\nexport const FieldCurrency = createField<CurrencyFieldProps, number | undefined, CurrencyFieldState>({\n displayName: 'FieldCurrency',\n\n useFieldState: (props) => {\n const { currency = 'RUB', currencyDisplay = 'symbol', decimalScale = 2 } = props\n\n // Memoize formatOptions at component top level\n const formatOptions = useMemo(\n () => ({\n style: 'currency' as const,\n currency,\n currencyDisplay,\n minimumFractionDigits: decimalScale,\n maximumFractionDigits: decimalScale,\n }),\n [currency, currencyDisplay, decimalScale]\n )\n\n return { formatOptions }\n },\n\n render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps, fieldState }): ReactElement => {\n const value = field.state.value as number | undefined\n\n const { min, max, step = 0.01, size } = componentProps\n\n const { formatOptions } = fieldState\n\n return (\n <FieldWrapper resolved={resolved} hasError={hasError} errorMessage={errorMessage} fullPath={fullPath}>\n <NumberInput.Root\n value={value?.toString() ?? ''}\n onValueChange={(details: { valueAsNumber: number }) => {\n const num = details.valueAsNumber\n field.handleChange(Number.isNaN(num) ? undefined : num)\n }}\n onBlur={field.handleBlur}\n min={min}\n max={max}\n step={step}\n formatOptions={formatOptions}\n clampValueOnBlur\n size={size}\n >\n <NumberInput.Control>\n <NumberInput.IncrementTrigger />\n <NumberInput.DecrementTrigger />\n </NumberInput.Control>\n <NumberInput.Input placeholder={resolved.placeholder} data-field-name={fullPath} />\n </NumberInput.Root>\n </FieldWrapper>\n )\n },\n})\n","'use client'\n\nimport { NumberInput } from '@chakra-ui/react'\nimport type { ReactElement } from 'react'\nimport type { NumberFieldProps } from '../../types'\nimport { createField, FieldWrapper } from '../base'\n\n/**\n * Form.Field.Number - Number input field\n *\n * Renders a Chakra NumberInput with automatic form integration and error display.\n *\n * Automatically extracts from Zod schema:\n * - `min` from `z.number().min(1)` → min={1}\n * - `max` from `z.number().max(100)` → max={100}\n * - `step` from `z.number().int()` → step={1}, or `z.number().multipleOf(0.5)` → step={0.5}\n * - `helperText` automatically generated from constraints (\"From 1 to 100\")\n *\n * Props always take priority over automatic values from schema.\n *\n * @example\n * ```tsx\n * <Form.Field.Number name=\"portions\" label=\"Portions\" />\n * // With z.number().min(1).max(100) automatically: min={1} max={100} helperText=\"From 1 to 100\"\n * ```\n */\nexport const FieldNumber = createField<NumberFieldProps, number | undefined>({\n displayName: 'FieldNumber',\n render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps }): ReactElement => {\n const value = field.state.value as number | undefined\n const { constraints } = resolved\n\n // Props take priority over constraints\n const min = componentProps.min ?? constraints.number?.min\n const max = componentProps.max ?? constraints.number?.max\n const step = componentProps.step ?? constraints.number?.step\n\n // For optional fields do not pass min/max to NumberInput when value is empty,\n // otherwise Chakra will show invalid state for empty value\n const isOptional = resolved.required === false\n const isEmpty = value === undefined || value === null\n const shouldApplyMinMax = !isOptional || !isEmpty\n\n return (\n <FieldWrapper resolved={resolved} hasError={hasError} errorMessage={errorMessage} fullPath={fullPath}>\n <NumberInput.Root\n value={value?.toString() ?? ''}\n onValueChange={(details: { valueAsNumber: number }) => {\n const num = details.valueAsNumber\n field.handleChange(Number.isNaN(num) ? undefined : num)\n }}\n onBlur={field.handleBlur}\n min={shouldApplyMinMax ? min : undefined}\n max={shouldApplyMinMax ? max : undefined}\n step={step}\n >\n <NumberInput.Control>\n <NumberInput.IncrementTrigger />\n <NumberInput.DecrementTrigger />\n </NumberInput.Control>\n <NumberInput.Input placeholder={resolved.placeholder} data-field-name={fullPath} inputMode=\"decimal\" />\n </NumberInput.Root>\n </FieldWrapper>\n )\n },\n})\n","'use client'\n\nimport { NumberInput } from '@chakra-ui/react'\nimport type { ReactElement } from 'react'\nimport type { NumberInputFieldProps } from '../../types'\nimport { createField, FieldWrapper } from '../base'\n\n/**\n * Form.Field.NumberInput - Number field with extended options\n *\n * Extends base Number field with formatting, mouse wheel support, etc.\n *\n * @example Basic usage\n * ```tsx\n * <Form.Field.NumberInput name=\"quantity\" label=\"Quantity\" min={1} max={100} />\n * ```\n *\n * @example With currency formatting\n * ```tsx\n * <Form.Field.NumberInput\n * name=\"price\"\n * label=\"Price\"\n * formatOptions={{ style: 'currency', currency: 'RUB' }}\n * />\n * ```\n *\n * @example With mouse wheel\n * ```tsx\n * <Form.Field.NumberInput name=\"count\" allowMouseWheel />\n * ```\n */\nexport const FieldNumberInput = createField<NumberInputFieldProps, number | undefined>({\n displayName: 'FieldNumberInput',\n\n render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps }): ReactElement => {\n const value = field.state.value as number | undefined\n\n return (\n <FieldWrapper resolved={resolved} hasError={hasError} errorMessage={errorMessage} fullPath={fullPath}>\n <NumberInput.Root\n value={value?.toString() ?? ''}\n onValueChange={(details: { valueAsNumber: number }) => {\n const num = details.valueAsNumber\n field.handleChange(Number.isNaN(num) ? undefined : num)\n }}\n onBlur={field.handleBlur}\n min={componentProps.min}\n max={componentProps.max}\n step={componentProps.step}\n formatOptions={componentProps.formatOptions}\n allowMouseWheel={componentProps.allowMouseWheel}\n clampValueOnBlur={componentProps.clampValueOnBlur ?? true}\n spinOnPress={componentProps.spinOnPress ?? true}\n size={componentProps.size}\n >\n <NumberInput.Control>\n <NumberInput.IncrementTrigger />\n <NumberInput.DecrementTrigger />\n </NumberInput.Control>\n <NumberInput.Input placeholder={resolved.placeholder} data-field-name={fullPath} inputMode=\"decimal\" />\n </NumberInput.Root>\n </FieldWrapper>\n )\n },\n})\n","'use client'\n\nimport { NumberInput } from '@chakra-ui/react'\nimport { type ReactElement, useMemo } from 'react'\nimport type { PercentageFieldProps } from '../../types'\nimport { createField, FieldWrapper } from '../base'\n\n/**\n * Form.Field.Percentage - Percentage input field\n *\n * Renders NumberInput with percentage formatting and % symbol.\n * Value is stored as-is (50 = 50%), not as decimal fraction (0.5).\n *\n * @example Basic usage (0-100%)\n * ```tsx\n * <Form.Field.Percentage name=\"discount\" label=\"Discount\" />\n * ```\n *\n * @example With custom range\n * ```tsx\n * <Form.Field.Percentage name=\"margin\" label=\"Margin\" min={0} max={50} />\n * ```\n *\n * @example With decimals\n * ```tsx\n * <Form.Field.Percentage name=\"rate\" label=\"Rate\" decimalScale={2} step={0.1} />\n * ```\n */\n/** Percentage field state */\ninterface PercentageFieldState {\n /** Memoized format options */\n formatOptions: Intl.NumberFormatOptions\n}\n\nexport const FieldPercentage = createField<PercentageFieldProps, number | undefined, PercentageFieldState>({\n displayName: 'FieldPercentage',\n\n useFieldState: (props) => {\n const { decimalScale = 0 } = props\n\n // Use 'unit' style with percent to store whole numbers (50 = 50%)\n // Chakra's 'percent' style expects decimals (0.5 = 50%)\n const formatOptions = useMemo(\n () => ({\n style: 'unit' as const,\n unit: 'percent',\n unitDisplay: 'short' as const,\n minimumFractionDigits: decimalScale,\n maximumFractionDigits: decimalScale,\n }),\n [decimalScale]\n )\n\n return { formatOptions }\n },\n\n render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps, fieldState }): ReactElement => {\n const value = field.state.value as number | undefined\n\n const { min = 0, max = 100, step = 1, size } = componentProps\n\n const { formatOptions } = fieldState\n\n return (\n <FieldWrapper resolved={resolved} hasError={hasError} errorMessage={errorMessage} fullPath={fullPath}>\n <NumberInput.Root\n value={value?.toString() ?? ''}\n onValueChange={(details: { valueAsNumber: number }) => {\n const num = details.valueAsNumber\n field.handleChange(Number.isNaN(num) ? undefined : num)\n }}\n onBlur={field.handleBlur}\n min={min}\n max={max}\n step={step}\n formatOptions={formatOptions}\n clampValueOnBlur\n size={size}\n >\n <NumberInput.Control>\n <NumberInput.IncrementTrigger />\n <NumberInput.DecrementTrigger />\n </NumberInput.Control>\n <NumberInput.Input placeholder={resolved.placeholder} data-field-name={fullPath} />\n </NumberInput.Root>\n </FieldWrapper>\n )\n },\n})\n","'use client'\n\nimport { Field, HStack, RatingGroup } from '@chakra-ui/react'\nimport type React from 'react'\nimport type { ReactElement, ReactNode } from 'react'\nimport type { BaseFieldProps } from '../../types'\nimport { createField, FieldError } from '../base'\nimport { FieldTooltip } from '../base/field-tooltip'\n\n/**\n * Props for Rating field\n */\nexport interface RatingFieldProps extends Omit<BaseFieldProps, 'placeholder'> {\n /** Number of rating elements (by default: 5) */\n count?: number\n /** Allow half values (by default: false) */\n allowHalf?: boolean\n /** Size: xs, sm, md, lg (by default: md) */\n size?: 'xs' | 'sm' | 'md' | 'lg'\n /** Color palette (by default: gray) */\n colorPalette?: 'gray' | 'red' | 'orange' | 'yellow' | 'green' | 'teal' | 'blue' | 'cyan' | 'purple' | 'pink'\n /** Custom icon (by default: star) */\n icon?: ReactNode\n /** Callback on value change */\n onValueChange?: (value: number) => void\n}\n\n/**\n * Form.Field.Rating - Star rating input field\n *\n * Renders Chakra RatingGroup with automatic form integration.\n * Form value is stored as number.\n *\n * @example Basic usage\n * ```tsx\n * <Form.Field.Rating name=\"rating\" label=\"Rating\" />\n * ```\n *\n * @example With custom count and color\n * ```tsx\n * <Form.Field.Rating\n * name=\"quality\"\n * label=\"Quality\"\n * count={10}\n * colorPalette=\"orange\"\n * />\n * ```\n *\n * @example With half values\n * ```tsx\n * <Form.Field.Rating\n * name=\"score\"\n * label=\"Score\"\n * allowHalf\n * size=\"lg\"\n * />\n * ```\n */\nexport const FieldRating = createField<RatingFieldProps, number>({\n displayName: 'FieldRating',\n\n render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps }): ReactElement => {\n const { count = 5, allowHalf = false, size = 'md', colorPalette, icon, onValueChange } = componentProps\n\n const value = (field.state.value as number) ?? 0\n\n const handleValueChange = (details: { value: number }) => {\n field.handleChange(details.value)\n onValueChange?.(details.value)\n }\n\n return (\n <Field.Root\n invalid={hasError}\n required={resolved.required}\n disabled={resolved.disabled}\n readOnly={resolved.readOnly}\n >\n <RatingGroup.Root\n value={value}\n onValueChange={handleValueChange}\n count={count}\n allowHalf={allowHalf}\n size={size}\n colorPalette={colorPalette}\n disabled={resolved.disabled}\n readOnly={resolved.readOnly}\n data-field-name={fullPath}\n >\n {resolved.label && (\n <RatingGroup.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 </RatingGroup.Label>\n )}\n <RatingGroup.HiddenInput onBlur={field.handleBlur} />\n <RatingGroup.Control>\n {Array.from({ length: count }).map((_, index) => (\n <RatingGroup.Item key={index} index={index + 1}>\n <RatingGroup.ItemIndicator icon={icon as React.ReactElement | undefined} />\n </RatingGroup.Item>\n ))}\n </RatingGroup.Control>\n </RatingGroup.Root>\n <FieldError hasError={hasError} errorMessage={errorMessage} helperText={resolved.helperText} />\n </Field.Root>\n )\n },\n})\n","'use client'\n\nimport { Field, For, HStack, Slider } from '@chakra-ui/react'\nimport type { ReactElement, ReactNode } from 'react'\nimport type { BaseFieldProps, FieldTooltipMeta } from '../../types'\nimport { createField, FieldError } from '../base'\nimport { FieldTooltip } from '../base/field-tooltip'\n\n/**\n * Slider mark definition\n */\nexport interface SliderMark {\n /** Value on the scale */\n value: number\n /** Mark text */\n label?: ReactNode\n}\n\n/**\n * Props for Slider field\n */\nexport interface SliderFieldProps extends Omit<BaseFieldProps, 'placeholder'> {\n /** Tooltip for field label */\n tooltip?: FieldTooltipMeta\n /** Minimum value (by default: 0) */\n min?: number\n /** Maximum value (by default: 100) */\n max?: number\n /** Step (by default: 1) */\n step?: number\n /** Show current value next to label */\n showValue?: boolean\n /** Orientation (by default: horizontal) */\n orientation?: 'horizontal' | 'vertical'\n /** Size (by default: md) */\n size?: 'sm' | 'md' | 'lg'\n /** Variant (by default: outline) */\n variant?: 'outline' | 'solid'\n /** Color palette */\n colorPalette?: 'gray' | 'red' | 'orange' | 'yellow' | 'green' | 'teal' | 'blue' | 'cyan' | 'purple' | 'pink'\n /** Marks on slider track */\n marks?: (number | SliderMark)[]\n /** Fill origin point (by default: start) */\n origin?: 'start' | 'center' | 'end'\n /** Callback on value change */\n onValueChange?: (value: number) => void\n /** Callback when drag ends */\n onValueChangeEnd?: (value: number) => void\n}\n\n/**\n * Form.Field.Slider - Slider field\n *\n * Renders Chakra Slider with automatic form integration.\n * Form value is stored as number.\n *\n * Automatically extracts from Zod schema:\n * - `min` from `z.number().min(1)` → min={1}\n * - `max` from `z.number().max(100)` → max={100}\n * - `step` from `z.number().int()` → step={1}, or `z.number().multipleOf(0.5)` → step={0.5}\n * - `helperText` automatically is generated from constraints (\"From 1 to 100\")\n *\n * Props always take priority over automatic values from schema.\n *\n * @example Basic usage\n * ```tsx\n * <Form.Field.Slider name=\"volume\" label=\"Volume\" />\n * ```\n *\n * @example With automatic constraints from Zod\n * ```tsx\n * // In schema: z.object({ rating: z.number().min(1).max(10) })\n * <Form.Field.Slider name=\"rating\" label=\"Rating\" showValue />\n * // Automatically: min={1} max={10} helperText=\"From 1 to 10\"\n * ```\n *\n * @example With marks\n * ```tsx\n * <Form.Field.Slider\n * name=\"rating\"\n * label=\"Rating\"\n * min={0}\n * max={100}\n * marks={[0, 25, 50, 75, 100]}\n * />\n * ```\n */\nexport const FieldSlider = createField<SliderFieldProps, number>({\n displayName: 'FieldSlider',\n\n render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps }): ReactElement => {\n const { constraints } = resolved\n\n // Props take priority over constraints, then defaults\n const min = componentProps.min ?? constraints.number?.min ?? 0\n const max = componentProps.max ?? constraints.number?.max ?? 100\n const step = componentProps.step ?? constraints.number?.step ?? 1\n\n const {\n showValue,\n orientation = 'horizontal',\n size = 'md',\n variant = 'outline',\n colorPalette,\n marks,\n origin,\n onValueChange,\n onValueChangeEnd,\n } = componentProps\n\n // Normalize marks to array of objects\n const normalizedMarks = marks?.map((mark) => (typeof mark === 'number' ? { value: mark, label: undefined } : mark))\n\n // Convert number to array for Slider\n const numValue = (field.state.value as number) ?? min\n const arrayValue = [numValue]\n\n const handleValueChange = (details: { value: number[] }) => {\n const newValue = details.value[0] ?? min\n field.handleChange(newValue)\n onValueChange?.(newValue)\n }\n\n const handleValueChangeEnd = (details: { value: number[] }) => {\n const newValue = details.value[0] ?? min\n onValueChangeEnd?.(newValue)\n }\n\n return (\n <Field.Root\n invalid={hasError}\n required={resolved.required}\n disabled={resolved.disabled}\n readOnly={resolved.readOnly}\n >\n <Slider.Root\n value={arrayValue}\n onValueChange={handleValueChange}\n onValueChangeEnd={handleValueChangeEnd}\n min={min}\n max={max}\n step={step}\n orientation={orientation}\n size={size}\n variant={variant}\n colorPalette={colorPalette}\n origin={origin}\n disabled={resolved.disabled}\n readOnly={resolved.readOnly}\n invalid={hasError}\n thumbAlignment=\"center\"\n onBlur={field.handleBlur}\n data-field-name={fullPath}\n >\n {resolved.label && !showValue && (\n <Slider.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 </Slider.Label>\n )}\n {resolved.label && showValue && (\n <HStack justify=\"space-between\">\n <Slider.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 </Slider.Label>\n <Slider.ValueText />\n </HStack>\n )}\n <Slider.Control>\n <Slider.Track>\n <Slider.Range />\n </Slider.Track>\n <For each={arrayValue}>\n {(_, index) => (\n <Slider.Thumb key={index} index={index}>\n <Slider.HiddenInput />\n </Slider.Thumb>\n )}\n </For>\n {normalizedMarks && normalizedMarks.length > 0 && (\n <Slider.MarkerGroup>\n {normalizedMarks.map((mark, index) => (\n <Slider.Marker key={index} value={mark.value}>\n <Slider.MarkerIndicator />\n {mark.label}\n </Slider.Marker>\n ))}\n </Slider.MarkerGroup>\n )}\n </Slider.Control>\n </Slider.Root>\n <FieldError hasError={hasError} errorMessage={errorMessage} helperText={resolved.helperText} />\n </Field.Root>\n )\n },\n})\n"]}