@omnitron-dev/prism 0.1.1

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 (83) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +44 -0
  3. package/bin/prism.js +13 -0
  4. package/dist/accessibility/index.d.ts +157 -0
  5. package/dist/accessibility/index.js +186 -0
  6. package/dist/accessibility/index.js.map +1 -0
  7. package/dist/blocks/index.d.ts +1239 -0
  8. package/dist/blocks/index.js +1712 -0
  9. package/dist/blocks/index.js.map +1 -0
  10. package/dist/chunk-77KIJLPP.js +37 -0
  11. package/dist/chunk-77KIJLPP.js.map +1 -0
  12. package/dist/chunk-BTIT7WYH.js +339 -0
  13. package/dist/chunk-BTIT7WYH.js.map +1 -0
  14. package/dist/chunk-BV32OJ2A.js +1409 -0
  15. package/dist/chunk-BV32OJ2A.js.map +1 -0
  16. package/dist/chunk-DDY7TLUI.js +139 -0
  17. package/dist/chunk-DDY7TLUI.js.map +1 -0
  18. package/dist/chunk-DXXZ3ITR.js +4227 -0
  19. package/dist/chunk-DXXZ3ITR.js.map +1 -0
  20. package/dist/chunk-E3XANPTO.js +2319 -0
  21. package/dist/chunk-E3XANPTO.js.map +1 -0
  22. package/dist/chunk-FU52GL2E.js +3 -0
  23. package/dist/chunk-FU52GL2E.js.map +1 -0
  24. package/dist/chunk-GYDT5EKX.js +16505 -0
  25. package/dist/chunk-GYDT5EKX.js.map +1 -0
  26. package/dist/chunk-HO2GKTWJ.js +28 -0
  27. package/dist/chunk-HO2GKTWJ.js.map +1 -0
  28. package/dist/chunk-JDTC2SBY.js +140 -0
  29. package/dist/chunk-JDTC2SBY.js.map +1 -0
  30. package/dist/chunk-JNU4QHJK.js +6 -0
  31. package/dist/chunk-JNU4QHJK.js.map +1 -0
  32. package/dist/chunk-LAEY5USO.js +2621 -0
  33. package/dist/chunk-LAEY5USO.js.map +1 -0
  34. package/dist/chunk-UR6X3W5I.js +530 -0
  35. package/dist/chunk-UR6X3W5I.js.map +1 -0
  36. package/dist/chunk-WC2WM2JD.js +883 -0
  37. package/dist/chunk-WC2WM2JD.js.map +1 -0
  38. package/dist/chunk-XWL6J6IO.js +40 -0
  39. package/dist/chunk-XWL6J6IO.js.map +1 -0
  40. package/dist/cli/index.js +2695 -0
  41. package/dist/cli/index.js.map +1 -0
  42. package/dist/config-BA6IeTq9.d.ts +100 -0
  43. package/dist/core/index.d.ts +454 -0
  44. package/dist/core/index.js +9 -0
  45. package/dist/core/index.js.map +1 -0
  46. package/dist/forms/index.d.ts +562 -0
  47. package/dist/forms/index.js +545 -0
  48. package/dist/forms/index.js.map +1 -0
  49. package/dist/hooks/index.d.ts +7 -0
  50. package/dist/hooks/index.js +10 -0
  51. package/dist/hooks/index.js.map +1 -0
  52. package/dist/http/index.d.ts +233 -0
  53. package/dist/http/index.js +282 -0
  54. package/dist/http/index.js.map +1 -0
  55. package/dist/index-odhPSv9I.d.ts +2491 -0
  56. package/dist/index.css +131 -0
  57. package/dist/index.css.map +1 -0
  58. package/dist/index.d.ts +9109 -0
  59. package/dist/index.js +13280 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/layouts/index.d.ts +854 -0
  62. package/dist/layouts/index.js +6 -0
  63. package/dist/layouts/index.js.map +1 -0
  64. package/dist/netron/index.d.ts +4 -0
  65. package/dist/netron/index.js +4 -0
  66. package/dist/netron/index.js.map +1 -0
  67. package/dist/registry/index.d.ts +352 -0
  68. package/dist/registry/index.js +4 -0
  69. package/dist/registry/index.js.map +1 -0
  70. package/dist/registry-BrDNftd5.d.ts +574 -0
  71. package/dist/settings-plpR26Xk.d.ts +455 -0
  72. package/dist/state/index.d.ts +981 -0
  73. package/dist/state/index.js +5 -0
  74. package/dist/state/index.js.map +1 -0
  75. package/dist/theme/index.d.ts +1049 -0
  76. package/dist/theme/index.js +5 -0
  77. package/dist/theme/index.js.map +1 -0
  78. package/dist/theme-CrXLfP1c.d.ts +389 -0
  79. package/dist/types/index.d.ts +146 -0
  80. package/dist/types/index.js +5 -0
  81. package/dist/types/index.js.map +1 -0
  82. package/dist/use-timeout-D7U3EAtH.d.ts +808 -0
  83. package/package.json +194 -0
@@ -0,0 +1,2621 @@
1
+ import { forwardRef, useState, useRef, useEffect, useId, useCallback, useMemo } from 'react';
2
+ import InputBase from '@mui/material/InputBase';
3
+ import InputAdornment from '@mui/material/InputAdornment';
4
+ import Tooltip from '@mui/material/Tooltip';
5
+ import Box7 from '@mui/material/Box';
6
+ import { useTheme, alpha } from '@mui/material/styles';
7
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
8
+ import { useFormContext, Controller } from 'react-hook-form';
9
+ import TextField from '@mui/material/TextField';
10
+ import MenuItem from '@mui/material/MenuItem';
11
+ import Checkbox from '@mui/material/Checkbox';
12
+ import FormControlLabel from '@mui/material/FormControlLabel';
13
+ import FormControl8 from '@mui/material/FormControl';
14
+ import FormHelperText9 from '@mui/material/FormHelperText';
15
+ import Switch from '@mui/material/Switch';
16
+ import FormLabel6 from '@mui/material/FormLabel';
17
+ import Radio from '@mui/material/Radio';
18
+ import RadioGroup from '@mui/material/RadioGroup';
19
+ import Autocomplete from '@mui/material/Autocomplete';
20
+ import Chip from '@mui/material/Chip';
21
+ import Rating from '@mui/material/Rating';
22
+ import Slider from '@mui/material/Slider';
23
+ import Typography2 from '@mui/material/Typography';
24
+ import { DatePicker } from '@mui/x-date-pickers/DatePicker';
25
+ import dayjs from 'dayjs';
26
+ import { TimePicker } from '@mui/x-date-pickers/TimePicker';
27
+ import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker';
28
+ import FormGroup from '@mui/material/FormGroup';
29
+ import { useDropzone } from 'react-dropzone';
30
+ import Stack from '@mui/material/Stack';
31
+ import IconButton from '@mui/material/IconButton';
32
+ import Avatar from '@mui/material/Avatar';
33
+ import Menu from '@mui/material/Menu';
34
+ import ListItemIcon from '@mui/material/ListItemIcon';
35
+ import ListItemText from '@mui/material/ListItemText';
36
+
37
+ function SearchIcon({ size = 18 }) {
38
+ return /* @__PURE__ */ jsxs(
39
+ "svg",
40
+ {
41
+ width: size,
42
+ height: size,
43
+ viewBox: "0 0 24 24",
44
+ fill: "none",
45
+ stroke: "currentColor",
46
+ strokeWidth: "2",
47
+ strokeLinecap: "round",
48
+ strokeLinejoin: "round",
49
+ children: [
50
+ /* @__PURE__ */ jsx("circle", { cx: "11", cy: "11", r: "8" }),
51
+ /* @__PURE__ */ jsx("line", { x1: "21", y1: "21", x2: "16.65", y2: "16.65" })
52
+ ]
53
+ }
54
+ );
55
+ }
56
+ function ClearIcon() {
57
+ return /* @__PURE__ */ jsxs(
58
+ "svg",
59
+ {
60
+ width: "14",
61
+ height: "14",
62
+ viewBox: "0 0 24 24",
63
+ fill: "none",
64
+ stroke: "currentColor",
65
+ strokeWidth: "2.5",
66
+ strokeLinecap: "round",
67
+ strokeLinejoin: "round",
68
+ children: [
69
+ /* @__PURE__ */ jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
70
+ /* @__PURE__ */ jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
71
+ ]
72
+ }
73
+ );
74
+ }
75
+ var SearchInput = forwardRef(function SearchInput2({
76
+ value: controlledValue,
77
+ onChange,
78
+ placeholder = "Search...",
79
+ debounce = 0,
80
+ compact = false,
81
+ fullWidth = true,
82
+ width,
83
+ minWidth,
84
+ clearTooltip = "Clear",
85
+ autoFocus,
86
+ onFocus,
87
+ onBlur,
88
+ onKeyDown,
89
+ sx
90
+ }, ref) {
91
+ const theme = useTheme();
92
+ const [localValue, setLocalValue] = useState(controlledValue ?? "");
93
+ const timerRef = useRef(void 0);
94
+ useEffect(() => {
95
+ if (controlledValue !== void 0) {
96
+ setLocalValue(controlledValue);
97
+ }
98
+ }, [controlledValue]);
99
+ const displayValue = controlledValue !== void 0 && debounce === 0 ? controlledValue : localValue;
100
+ const handleChange = (e) => {
101
+ const val = e.target.value;
102
+ setLocalValue(val);
103
+ if (debounce > 0) {
104
+ clearTimeout(timerRef.current);
105
+ timerRef.current = setTimeout(() => onChange?.(val), debounce);
106
+ } else {
107
+ onChange?.(val);
108
+ }
109
+ };
110
+ const handleClear = () => {
111
+ setLocalValue("");
112
+ clearTimeout(timerRef.current);
113
+ onChange?.("");
114
+ };
115
+ useEffect(() => () => clearTimeout(timerRef.current), []);
116
+ const py = compact ? 0.625 : 0.75;
117
+ const px = compact ? 1.25 : 1.5;
118
+ const inputPy = compact ? "3px" : "4px";
119
+ return /* @__PURE__ */ jsx(
120
+ InputBase,
121
+ {
122
+ ref,
123
+ fullWidth,
124
+ placeholder,
125
+ value: displayValue,
126
+ onChange: handleChange,
127
+ autoFocus,
128
+ onFocus,
129
+ onBlur,
130
+ onKeyDown,
131
+ startAdornment: /* @__PURE__ */ jsx(InputAdornment, { position: "start", sx: { color: "text.disabled", mr: compact ? 0.75 : 1 }, children: /* @__PURE__ */ jsx(SearchIcon, { size: compact ? 16 : 18 }) }),
132
+ endAdornment: displayValue ? /* @__PURE__ */ jsx(InputAdornment, { position: "end", children: /* @__PURE__ */ jsx(Tooltip, { title: clearTooltip, children: /* @__PURE__ */ jsx(
133
+ Box7,
134
+ {
135
+ component: "button",
136
+ type: "button",
137
+ onClick: handleClear,
138
+ sx: {
139
+ p: 0.25,
140
+ border: "none",
141
+ background: "none",
142
+ cursor: "pointer",
143
+ color: "text.disabled",
144
+ display: "flex",
145
+ alignItems: "center",
146
+ borderRadius: "50%",
147
+ "&:hover": { color: "text.secondary" }
148
+ },
149
+ children: /* @__PURE__ */ jsx(ClearIcon, {})
150
+ }
151
+ ) }) }) : null,
152
+ sx: {
153
+ px,
154
+ py,
155
+ borderRadius: 1,
156
+ fontSize: "0.875rem",
157
+ bgcolor: alpha(theme.palette.grey[500], 0.08),
158
+ transition: theme.transitions.create(["background-color"], {
159
+ duration: theme.transitions.duration.shorter
160
+ }),
161
+ "&:hover": {
162
+ bgcolor: alpha(theme.palette.grey[500], 0.12)
163
+ },
164
+ "&.Mui-focused": {
165
+ bgcolor: alpha(theme.palette.grey[500], 0.16)
166
+ },
167
+ "& .MuiInputBase-input": {
168
+ py: inputPy,
169
+ px: 0,
170
+ overflow: "visible",
171
+ "&::placeholder": {
172
+ opacity: 0.64
173
+ }
174
+ },
175
+ ...width != null && { width },
176
+ ...minWidth != null && { minWidth },
177
+ ...!fullWidth && { width: width ?? "auto" },
178
+ ...Array.isArray(sx) ? Object.assign({}, ...sx) : sx
179
+ }
180
+ }
181
+ );
182
+ });
183
+ function FieldText({
184
+ name,
185
+ helperText,
186
+ rules,
187
+ required,
188
+ slotProps,
189
+ multiline,
190
+ ...other
191
+ }) {
192
+ const { control } = useFormContext();
193
+ const id = useId();
194
+ const inputId = `field-text-${id}`;
195
+ const helperId = `field-text-helper-${id}`;
196
+ return /* @__PURE__ */ jsx(
197
+ Controller,
198
+ {
199
+ name,
200
+ control,
201
+ rules,
202
+ render: ({ field, fieldState: { error } }) => /* @__PURE__ */ jsx(
203
+ TextField,
204
+ {
205
+ ...field,
206
+ id: inputId,
207
+ fullWidth: true,
208
+ multiline,
209
+ value: field.value ?? "",
210
+ error: !!error,
211
+ helperText: error?.message ?? helperText,
212
+ required,
213
+ slotProps: {
214
+ formHelperText: {
215
+ id: helperId
216
+ },
217
+ htmlInput: {
218
+ "aria-describedby": error?.message || helperText ? helperId : void 0,
219
+ "aria-invalid": !!error,
220
+ "aria-required": required
221
+ },
222
+ // Shrink label for multiline fields to prevent overlap with textarea content
223
+ ...multiline ? { inputLabel: { shrink: true } } : {},
224
+ ...slotProps
225
+ },
226
+ ...other
227
+ }
228
+ )
229
+ }
230
+ );
231
+ }
232
+ function FieldSelect({
233
+ name,
234
+ options,
235
+ helperText,
236
+ placeholder,
237
+ rules,
238
+ required,
239
+ slotProps,
240
+ ...other
241
+ }) {
242
+ const { control } = useFormContext();
243
+ const id = useId();
244
+ const inputId = `field-select-${id}`;
245
+ const helperId = `field-select-helper-${id}`;
246
+ return /* @__PURE__ */ jsx(
247
+ Controller,
248
+ {
249
+ name,
250
+ control,
251
+ rules,
252
+ render: ({ field, fieldState: { error } }) => /* @__PURE__ */ jsxs(
253
+ TextField,
254
+ {
255
+ ...field,
256
+ id: inputId,
257
+ select: true,
258
+ fullWidth: true,
259
+ value: field.value ?? "",
260
+ error: !!error,
261
+ helperText: error?.message ?? helperText,
262
+ required,
263
+ slotProps: {
264
+ formHelperText: {
265
+ id: helperId
266
+ },
267
+ select: {
268
+ "aria-describedby": error?.message || helperText ? helperId : void 0,
269
+ "aria-invalid": !!error,
270
+ "aria-required": required
271
+ },
272
+ ...slotProps
273
+ },
274
+ ...other,
275
+ children: [
276
+ placeholder && /* @__PURE__ */ jsx(MenuItem, { value: "", disabled: true, "aria-hidden": "true", children: placeholder }),
277
+ options.map((option) => /* @__PURE__ */ jsx(
278
+ MenuItem,
279
+ {
280
+ value: option.value,
281
+ disabled: option.disabled,
282
+ "aria-disabled": option.disabled,
283
+ children: option.label
284
+ },
285
+ option.value
286
+ ))
287
+ ]
288
+ }
289
+ )
290
+ }
291
+ );
292
+ }
293
+ function FieldCheckbox({
294
+ name,
295
+ label,
296
+ helperText,
297
+ rules,
298
+ required,
299
+ indeterminate,
300
+ ...other
301
+ }) {
302
+ const { control } = useFormContext();
303
+ const id = useId();
304
+ const inputId = `field-checkbox-${id}`;
305
+ const helperId = `field-checkbox-helper-${id}`;
306
+ return /* @__PURE__ */ jsx(
307
+ Controller,
308
+ {
309
+ name,
310
+ control,
311
+ rules,
312
+ render: ({ field, fieldState: { error } }) => /* @__PURE__ */ jsxs(FormControl8, { error: !!error, required, children: [
313
+ /* @__PURE__ */ jsx(
314
+ FormControlLabel,
315
+ {
316
+ control: /* @__PURE__ */ jsx(
317
+ Checkbox,
318
+ {
319
+ ...field,
320
+ id: inputId,
321
+ checked: !!field.value,
322
+ indeterminate,
323
+ inputProps: {
324
+ "aria-describedby": error?.message || helperText ? helperId : void 0,
325
+ "aria-invalid": !!error,
326
+ "aria-required": required,
327
+ ...indeterminate && { "aria-checked": "mixed" }
328
+ },
329
+ ...other
330
+ }
331
+ ),
332
+ label,
333
+ htmlFor: inputId
334
+ }
335
+ ),
336
+ (error?.message || helperText) && /* @__PURE__ */ jsx(FormHelperText9, { id: helperId, children: error?.message ?? helperText })
337
+ ] })
338
+ }
339
+ );
340
+ }
341
+ function FieldSwitch({
342
+ name,
343
+ label,
344
+ helperText,
345
+ labelPlacement = "end",
346
+ rules,
347
+ required,
348
+ ...other
349
+ }) {
350
+ const { control } = useFormContext();
351
+ const id = useId();
352
+ const inputId = `field-switch-${id}`;
353
+ const helperId = `field-switch-helper-${id}`;
354
+ return /* @__PURE__ */ jsx(
355
+ Controller,
356
+ {
357
+ name,
358
+ control,
359
+ rules,
360
+ render: ({ field, fieldState: { error } }) => /* @__PURE__ */ jsxs(FormControl8, { error: !!error, required, children: [
361
+ /* @__PURE__ */ jsx(
362
+ FormControlLabel,
363
+ {
364
+ control: /* @__PURE__ */ jsx(
365
+ Switch,
366
+ {
367
+ ...field,
368
+ id: inputId,
369
+ checked: !!field.value,
370
+ inputProps: {
371
+ "aria-describedby": error?.message || helperText ? helperId : void 0,
372
+ "aria-invalid": !!error,
373
+ "aria-required": required
374
+ },
375
+ ...other
376
+ }
377
+ ),
378
+ label,
379
+ labelPlacement,
380
+ htmlFor: inputId
381
+ }
382
+ ),
383
+ (error?.message || helperText) && /* @__PURE__ */ jsx(FormHelperText9, { id: helperId, children: error?.message ?? helperText })
384
+ ] })
385
+ }
386
+ );
387
+ }
388
+
389
+ // src/utils/transform-number.ts
390
+ function parseNumber(value, options = {}) {
391
+ const { allowNegative = true } = options;
392
+ const trimmed = value.trim();
393
+ if (trimmed === "" || trimmed === "-" || trimmed === ".") {
394
+ return void 0;
395
+ }
396
+ if (!allowNegative && trimmed.startsWith("-")) {
397
+ return void 0;
398
+ }
399
+ const num = parseFloat(trimmed);
400
+ return Number.isNaN(num) ? void 0 : num;
401
+ }
402
+ function clampNumber(value, options = {}) {
403
+ const { min, max } = options;
404
+ let result = value;
405
+ if (min !== void 0 && result < min) {
406
+ result = min;
407
+ }
408
+ if (max !== void 0 && result > max) {
409
+ result = max;
410
+ }
411
+ return result;
412
+ }
413
+ function roundToDecimals(value, decimals) {
414
+ const factor = Math.pow(10, decimals);
415
+ return Math.round(value * factor) / factor;
416
+ }
417
+ function transformOnChange(value, options = {}) {
418
+ const { allowNegative = true, decimals } = options;
419
+ if (value === "") return "";
420
+ if (allowNegative && value === "-") return "-";
421
+ if (value.endsWith(".") && decimals !== 0) {
422
+ const withoutDot = value.slice(0, -1);
423
+ const num2 = parseNumber(withoutDot, options);
424
+ if (num2 !== void 0) return value;
425
+ }
426
+ if (decimals !== 0 && value.includes(".")) {
427
+ const parts = value.split(".");
428
+ if (parts.length === 2 && /^0*$/.test(parts[1])) {
429
+ const num2 = parseNumber(parts[0], options);
430
+ if (num2 !== void 0) return value;
431
+ }
432
+ }
433
+ const num = parseNumber(value, options);
434
+ if (num === void 0) {
435
+ return "";
436
+ }
437
+ return value;
438
+ }
439
+ function transformOnBlur(value, options = {}) {
440
+ const { min, max, decimals, defaultValue = 0 } = options;
441
+ const num = parseNumber(value, options);
442
+ if (num === void 0) {
443
+ return defaultValue;
444
+ }
445
+ let result = num;
446
+ if (decimals !== void 0) {
447
+ result = roundToDecimals(result, decimals);
448
+ }
449
+ result = clampNumber(result, { min, max });
450
+ return result;
451
+ }
452
+ function transformForDisplay(value, options = {}) {
453
+ if (value === null || value === void 0) {
454
+ return "";
455
+ }
456
+ const { decimals } = options;
457
+ if (decimals !== void 0) {
458
+ return value.toFixed(decimals);
459
+ }
460
+ return String(value);
461
+ }
462
+ function createNumberInputHandlers(config) {
463
+ const { value, onChange, options = {} } = config;
464
+ let intermediateValue = null;
465
+ return {
466
+ displayValue: intermediateValue ?? transformForDisplay(value, options),
467
+ handleChange: (newValue) => {
468
+ const transformed = transformOnChange(newValue, options);
469
+ intermediateValue = transformed;
470
+ const num = parseNumber(transformed, options);
471
+ if (num !== void 0) {
472
+ onChange(num);
473
+ }
474
+ },
475
+ handleBlur: () => {
476
+ const finalValue = transformOnBlur(intermediateValue ?? String(value), options);
477
+ intermediateValue = null;
478
+ onChange(finalValue);
479
+ }
480
+ };
481
+ }
482
+ function NumberInput({
483
+ field,
484
+ error,
485
+ options,
486
+ helperText,
487
+ inputId,
488
+ helperId,
489
+ required,
490
+ slotProps,
491
+ ...other
492
+ }) {
493
+ const [displayValue, setDisplayValue] = useState(
494
+ () => transformForDisplay(field.value ?? options.defaultValue ?? 0, options)
495
+ );
496
+ useEffect(() => {
497
+ const formatted = transformForDisplay(field.value ?? options.defaultValue ?? 0, options);
498
+ setDisplayValue(formatted);
499
+ }, [field.value, options]);
500
+ const handleChange = useCallback(
501
+ (e) => {
502
+ const transformed = transformOnChange(e.target.value, options);
503
+ setDisplayValue(transformed);
504
+ const num = parseFloat(transformed);
505
+ if (!isNaN(num)) {
506
+ field.onChange(num);
507
+ } else if (transformed === "" || transformed === "-") {
508
+ field.onChange(options.defaultValue ?? 0);
509
+ }
510
+ },
511
+ [field, options]
512
+ );
513
+ const handleBlur = useCallback(() => {
514
+ const finalValue = transformOnBlur(displayValue || String(field.value ?? options.defaultValue ?? 0), options);
515
+ field.onChange(finalValue);
516
+ setDisplayValue(transformForDisplay(finalValue, options));
517
+ field.onBlur();
518
+ }, [displayValue, field, options]);
519
+ return /* @__PURE__ */ jsx(
520
+ TextField,
521
+ {
522
+ ...other,
523
+ id: inputId,
524
+ fullWidth: true,
525
+ value: displayValue,
526
+ onChange: handleChange,
527
+ onBlur: handleBlur,
528
+ error: !!error,
529
+ helperText: error?.message ?? helperText,
530
+ required,
531
+ slotProps: {
532
+ formHelperText: {
533
+ id: helperId
534
+ },
535
+ htmlInput: {
536
+ inputMode: options.decimals === 0 ? "numeric" : "decimal",
537
+ "aria-describedby": error?.message || helperText ? helperId : void 0,
538
+ "aria-invalid": !!error,
539
+ "aria-required": required,
540
+ "aria-valuemin": options.min,
541
+ "aria-valuemax": options.max,
542
+ "aria-valuenow": field.value ?? options.defaultValue ?? 0
543
+ },
544
+ ...slotProps
545
+ }
546
+ }
547
+ );
548
+ }
549
+ function FieldNumber({
550
+ name,
551
+ min,
552
+ max,
553
+ decimals,
554
+ allowNegative = true,
555
+ defaultValue = 0,
556
+ rules,
557
+ error: _error,
558
+ ...other
559
+ }) {
560
+ const { control } = useFormContext();
561
+ const id = useId();
562
+ const inputId = `field-number-${id}`;
563
+ const helperId = `field-number-helper-${id}`;
564
+ const options = {
565
+ min,
566
+ max,
567
+ decimals,
568
+ allowNegative,
569
+ defaultValue
570
+ };
571
+ return /* @__PURE__ */ jsx(
572
+ Controller,
573
+ {
574
+ name,
575
+ control,
576
+ rules,
577
+ render: ({ field, fieldState: { error } }) => /* @__PURE__ */ jsx(NumberInput, { field, error, options, inputId, helperId, ...other })
578
+ }
579
+ );
580
+ }
581
+ function FieldRadio({
582
+ name,
583
+ options,
584
+ label,
585
+ helperText,
586
+ row = false,
587
+ rules,
588
+ required,
589
+ ...other
590
+ }) {
591
+ const { control } = useFormContext();
592
+ const id = useId();
593
+ const groupId = `field-radio-${id}`;
594
+ const labelId = `field-radio-label-${id}`;
595
+ const helperId = `field-radio-helper-${id}`;
596
+ return /* @__PURE__ */ jsx(
597
+ Controller,
598
+ {
599
+ name,
600
+ control,
601
+ rules,
602
+ render: ({ field, fieldState: { error } }) => /* @__PURE__ */ jsxs(FormControl8, { error: !!error, required, ...other, children: [
603
+ label && /* @__PURE__ */ jsx(FormLabel6, { id: labelId, htmlFor: groupId, children: label }),
604
+ /* @__PURE__ */ jsx(
605
+ RadioGroup,
606
+ {
607
+ ...field,
608
+ id: groupId,
609
+ row,
610
+ value: field.value ?? "",
611
+ "aria-labelledby": label ? labelId : void 0,
612
+ "aria-describedby": error?.message || helperText ? helperId : void 0,
613
+ "aria-invalid": !!error,
614
+ "aria-required": required,
615
+ children: options.map((option, index) => /* @__PURE__ */ jsx(
616
+ FormControlLabel,
617
+ {
618
+ value: option.value,
619
+ control: /* @__PURE__ */ jsx(
620
+ Radio,
621
+ {
622
+ id: `${groupId}-option-${index}`,
623
+ inputProps: {
624
+ "aria-label": option.label
625
+ }
626
+ }
627
+ ),
628
+ label: option.label,
629
+ disabled: option.disabled
630
+ },
631
+ String(option.value)
632
+ ))
633
+ }
634
+ ),
635
+ (error?.message || helperText) && /* @__PURE__ */ jsx(FormHelperText9, { id: helperId, children: error?.message ?? helperText })
636
+ ] })
637
+ }
638
+ );
639
+ }
640
+ function FieldAutocomplete({
641
+ name,
642
+ options,
643
+ label,
644
+ placeholder,
645
+ helperText,
646
+ textFieldProps,
647
+ disableClearable,
648
+ disableCloseOnSelect,
649
+ loading,
650
+ loadingText,
651
+ noOptionsText,
652
+ disabled,
653
+ readOnly,
654
+ fullWidth = true,
655
+ size
656
+ }) {
657
+ const { control, setValue } = useFormContext();
658
+ return /* @__PURE__ */ jsx(
659
+ Controller,
660
+ {
661
+ name,
662
+ control,
663
+ render: ({ field, fieldState: { error } }) => {
664
+ const selectedOption = options.find((opt) => opt.value === field.value) ?? null;
665
+ return /* @__PURE__ */ jsx(
666
+ Autocomplete,
667
+ {
668
+ options,
669
+ value: selectedOption,
670
+ disableClearable,
671
+ disableCloseOnSelect,
672
+ loading,
673
+ loadingText,
674
+ noOptionsText,
675
+ disabled,
676
+ readOnly,
677
+ fullWidth,
678
+ size,
679
+ getOptionLabel: (option) => option.label,
680
+ getOptionDisabled: (option) => !!option.disabled,
681
+ isOptionEqualToValue: (option, value) => option.value === value.value,
682
+ groupBy: options.some((opt) => opt.group) ? (option) => option.group ?? "" : void 0,
683
+ onChange: (_event, newValue) => {
684
+ setValue(name, newValue?.value ?? "", { shouldValidate: true });
685
+ },
686
+ renderInput: (params) => /* @__PURE__ */ jsx(
687
+ TextField,
688
+ {
689
+ ...params,
690
+ label,
691
+ placeholder,
692
+ error: !!error,
693
+ helperText: error?.message ?? helperText,
694
+ ...textFieldProps
695
+ }
696
+ )
697
+ }
698
+ );
699
+ }
700
+ }
701
+ );
702
+ }
703
+ function FieldMultiSelect({
704
+ name,
705
+ options,
706
+ label,
707
+ placeholder,
708
+ helperText,
709
+ textFieldProps,
710
+ maxSelections,
711
+ chipVariant = "filled",
712
+ chipColor = "primary",
713
+ disableClearable,
714
+ disableCloseOnSelect,
715
+ loading,
716
+ loadingText,
717
+ noOptionsText,
718
+ disabled,
719
+ readOnly,
720
+ fullWidth = true,
721
+ size,
722
+ limitTags
723
+ }) {
724
+ const { control, setValue } = useFormContext();
725
+ return /* @__PURE__ */ jsx(
726
+ Controller,
727
+ {
728
+ name,
729
+ control,
730
+ render: ({ field, fieldState: { error } }) => {
731
+ const values = field.value ?? [];
732
+ const selectedOptions = values.map((val) => options.find((opt) => opt.value === val)).filter((opt) => opt !== void 0);
733
+ const isMaxReached = maxSelections !== void 0 && selectedOptions.length >= maxSelections;
734
+ return /* @__PURE__ */ jsx(
735
+ Autocomplete,
736
+ {
737
+ multiple: true,
738
+ options,
739
+ value: selectedOptions,
740
+ disableClearable,
741
+ disableCloseOnSelect,
742
+ loading,
743
+ loadingText,
744
+ noOptionsText,
745
+ disabled,
746
+ readOnly,
747
+ fullWidth,
748
+ size,
749
+ limitTags,
750
+ getOptionLabel: (option) => option.label,
751
+ getOptionDisabled: (option) => {
752
+ if (option.disabled) return true;
753
+ if (isMaxReached) {
754
+ const isSelected = selectedOptions.some((sel) => sel.value === option.value);
755
+ return !isSelected;
756
+ }
757
+ return false;
758
+ },
759
+ isOptionEqualToValue: (option, value) => option.value === value.value,
760
+ groupBy: options.some((opt) => opt.group) ? (option) => option.group ?? "" : void 0,
761
+ onChange: (_event, newValue) => {
762
+ const newValues = newValue.map((item) => item.value);
763
+ setValue(name, newValues, { shouldValidate: true });
764
+ },
765
+ renderTags: (value, getTagProps) => value.map((option, index) => {
766
+ const { key, ...tagProps } = getTagProps({ index });
767
+ return /* @__PURE__ */ jsx(
768
+ Chip,
769
+ {
770
+ label: option.label,
771
+ variant: chipVariant,
772
+ color: chipColor,
773
+ size: "small",
774
+ ...tagProps
775
+ },
776
+ key
777
+ );
778
+ }),
779
+ renderInput: (params) => /* @__PURE__ */ jsx(
780
+ TextField,
781
+ {
782
+ ...params,
783
+ label,
784
+ placeholder: selectedOptions.length === 0 ? placeholder : void 0,
785
+ error: !!error,
786
+ helperText: error?.message ?? (maxSelections ? `${selectedOptions.length}/${maxSelections} selected${helperText ? ` - ${helperText}` : ""}` : helperText),
787
+ ...textFieldProps
788
+ }
789
+ )
790
+ }
791
+ );
792
+ }
793
+ }
794
+ );
795
+ }
796
+ function FieldRating({
797
+ name,
798
+ label,
799
+ helperText,
800
+ formControlProps,
801
+ showValue = false,
802
+ max = 5,
803
+ precision = 1,
804
+ size = "medium",
805
+ ...other
806
+ }) {
807
+ const { control } = useFormContext();
808
+ const id = useId();
809
+ const helperId = `field-rating-helper-${id}`;
810
+ const labelId = `field-rating-label-${id}`;
811
+ return /* @__PURE__ */ jsx(
812
+ Controller,
813
+ {
814
+ name,
815
+ control,
816
+ render: ({ field, fieldState: { error } }) => {
817
+ const hasHelper = !!(error?.message || helperText);
818
+ return /* @__PURE__ */ jsxs(FormControl8, { error: !!error, ...formControlProps, children: [
819
+ label && /* @__PURE__ */ jsx(FormLabel6, { id: labelId, sx: { mb: 1 }, children: label }),
820
+ /* @__PURE__ */ jsxs(Box7, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
821
+ /* @__PURE__ */ jsx(
822
+ Rating,
823
+ {
824
+ ...other,
825
+ ...field,
826
+ value: field.value ?? 0,
827
+ max,
828
+ precision,
829
+ size,
830
+ onChange: (_event, newValue) => {
831
+ field.onChange(newValue);
832
+ },
833
+ "aria-labelledby": label ? labelId : void 0,
834
+ "aria-describedby": hasHelper ? helperId : void 0,
835
+ "aria-invalid": !!error
836
+ }
837
+ ),
838
+ showValue && /* @__PURE__ */ jsxs(
839
+ Box7,
840
+ {
841
+ component: "span",
842
+ sx: {
843
+ color: "text.secondary",
844
+ fontSize: size === "small" ? "0.75rem" : size === "large" ? "1rem" : "0.875rem"
845
+ },
846
+ children: [
847
+ field.value ?? 0,
848
+ "/",
849
+ max
850
+ ]
851
+ }
852
+ )
853
+ ] }),
854
+ hasHelper && /* @__PURE__ */ jsx(FormHelperText9, { id: helperId, children: error?.message ?? helperText })
855
+ ] });
856
+ }
857
+ }
858
+ );
859
+ }
860
+ function FieldSlider({
861
+ name,
862
+ label,
863
+ helperText,
864
+ formControlProps,
865
+ showValue = false,
866
+ formatValue,
867
+ unit,
868
+ min = 0,
869
+ max = 100,
870
+ step = 1,
871
+ ...other
872
+ }) {
873
+ const { control } = useFormContext();
874
+ const id = useId();
875
+ const helperId = `field-slider-helper-${id}`;
876
+ const labelId = `field-slider-label-${id}`;
877
+ const defaultFormatValue = (value) => {
878
+ if (Array.isArray(value)) {
879
+ return `${value[0]}${unit ?? ""} - ${value[1]}${unit ?? ""}`;
880
+ }
881
+ return `${value}${unit ?? ""}`;
882
+ };
883
+ const displayValue = formatValue ?? defaultFormatValue;
884
+ return /* @__PURE__ */ jsx(
885
+ Controller,
886
+ {
887
+ name,
888
+ control,
889
+ render: ({ field, fieldState: { error } }) => {
890
+ const hasHelper = !!(error?.message || helperText);
891
+ return /* @__PURE__ */ jsxs(FormControl8, { error: !!error, fullWidth: true, ...formControlProps, children: [
892
+ (label || showValue) && /* @__PURE__ */ jsxs(Box7, { sx: { display: "flex", justifyContent: "space-between", alignItems: "center", mb: 1 }, children: [
893
+ label && /* @__PURE__ */ jsx(FormLabel6, { id: labelId, children: label }),
894
+ showValue && /* @__PURE__ */ jsx(Typography2, { variant: "body2", color: "text.secondary", children: displayValue(field.value ?? (Array.isArray(other.defaultValue) ? [min, max] : min)) })
895
+ ] }),
896
+ /* @__PURE__ */ jsx(
897
+ Slider,
898
+ {
899
+ ...other,
900
+ ...field,
901
+ value: field.value ?? (Array.isArray(other.defaultValue) ? [min, max] : min),
902
+ min,
903
+ max,
904
+ step,
905
+ onChange: (_event, newValue) => {
906
+ field.onChange(newValue);
907
+ },
908
+ valueLabelDisplay: other.valueLabelDisplay ?? "auto",
909
+ valueLabelFormat: (value) => `${value}${unit ?? ""}`,
910
+ "aria-labelledby": label ? labelId : void 0,
911
+ "aria-describedby": hasHelper ? helperId : void 0,
912
+ "aria-invalid": !!error
913
+ }
914
+ ),
915
+ hasHelper && /* @__PURE__ */ jsx(FormHelperText9, { id: helperId, children: error?.message ?? helperText })
916
+ ] });
917
+ }
918
+ }
919
+ );
920
+ }
921
+ function normalizeValue(value) {
922
+ if (value === null || value === void 0 || value === "") return null;
923
+ if (dayjs.isDayjs(value)) return value.isValid() ? value : null;
924
+ if (value instanceof Date) {
925
+ const parsed2 = dayjs(value);
926
+ return parsed2.isValid() ? parsed2 : null;
927
+ }
928
+ const parsed = dayjs(value);
929
+ return parsed.isValid() ? parsed : null;
930
+ }
931
+ function FieldDatePicker({
932
+ name,
933
+ label,
934
+ helperText,
935
+ textFieldProps,
936
+ disabled,
937
+ readOnly,
938
+ minDate,
939
+ maxDate,
940
+ disablePast,
941
+ disableFuture,
942
+ views,
943
+ openTo,
944
+ format
945
+ }) {
946
+ const { control } = useFormContext();
947
+ return /* @__PURE__ */ jsx(
948
+ Controller,
949
+ {
950
+ name,
951
+ control,
952
+ render: ({ field, fieldState: { error } }) => {
953
+ const normalizedValue = normalizeValue(field.value);
954
+ return /* @__PURE__ */ jsx(
955
+ DatePicker,
956
+ {
957
+ label,
958
+ value: normalizedValue,
959
+ onChange: (newValue) => {
960
+ field.onChange(newValue?.toISOString() ?? null);
961
+ },
962
+ disabled,
963
+ readOnly,
964
+ minDate,
965
+ maxDate,
966
+ disablePast,
967
+ disableFuture,
968
+ views,
969
+ openTo,
970
+ format,
971
+ slotProps: {
972
+ textField: {
973
+ fullWidth: true,
974
+ error: !!error,
975
+ helperText: error?.message ?? helperText,
976
+ ...textFieldProps
977
+ }
978
+ }
979
+ }
980
+ );
981
+ }
982
+ }
983
+ );
984
+ }
985
+ function normalizeValue2(value) {
986
+ if (value === null || value === void 0 || value === "") {
987
+ return null;
988
+ }
989
+ if (dayjs.isDayjs(value)) {
990
+ return value.isValid() ? value : null;
991
+ }
992
+ if (value instanceof Date) {
993
+ const parsed2 = dayjs(value);
994
+ return parsed2.isValid() ? parsed2 : null;
995
+ }
996
+ const parsed = dayjs(value);
997
+ return parsed.isValid() ? parsed : null;
998
+ }
999
+ function FieldTimePicker({
1000
+ name,
1001
+ label,
1002
+ helperText,
1003
+ textFieldProps,
1004
+ disabled,
1005
+ readOnly,
1006
+ minutesStep,
1007
+ ampm,
1008
+ minTime,
1009
+ maxTime,
1010
+ views,
1011
+ openTo,
1012
+ format
1013
+ }) {
1014
+ const { control } = useFormContext();
1015
+ return /* @__PURE__ */ jsx(
1016
+ Controller,
1017
+ {
1018
+ name,
1019
+ control,
1020
+ render: ({ field, fieldState: { error } }) => {
1021
+ const normalizedValue = normalizeValue2(field.value);
1022
+ return /* @__PURE__ */ jsx(
1023
+ TimePicker,
1024
+ {
1025
+ label,
1026
+ value: normalizedValue,
1027
+ onChange: (newValue) => {
1028
+ field.onChange(newValue?.toISOString() ?? null);
1029
+ },
1030
+ disabled,
1031
+ readOnly,
1032
+ minutesStep,
1033
+ ampm,
1034
+ minTime,
1035
+ maxTime,
1036
+ views,
1037
+ openTo,
1038
+ format,
1039
+ slotProps: {
1040
+ textField: {
1041
+ fullWidth: true,
1042
+ error: !!error,
1043
+ helperText: error?.message ?? helperText,
1044
+ ...textFieldProps
1045
+ }
1046
+ }
1047
+ }
1048
+ );
1049
+ }
1050
+ }
1051
+ );
1052
+ }
1053
+ function normalizeValue3(value) {
1054
+ if (value === null || value === void 0 || value === "") {
1055
+ return null;
1056
+ }
1057
+ if (dayjs.isDayjs(value)) {
1058
+ return value.isValid() ? value : null;
1059
+ }
1060
+ if (value instanceof Date) {
1061
+ const parsed2 = dayjs(value);
1062
+ return parsed2.isValid() ? parsed2 : null;
1063
+ }
1064
+ const parsed = dayjs(value);
1065
+ return parsed.isValid() ? parsed : null;
1066
+ }
1067
+ function FieldDateTimePicker({
1068
+ name,
1069
+ label,
1070
+ helperText,
1071
+ textFieldProps,
1072
+ disabled,
1073
+ readOnly,
1074
+ minutesStep,
1075
+ ampm,
1076
+ minDateTime,
1077
+ maxDateTime,
1078
+ disablePast,
1079
+ disableFuture,
1080
+ views,
1081
+ openTo,
1082
+ format
1083
+ }) {
1084
+ const { control } = useFormContext();
1085
+ return /* @__PURE__ */ jsx(
1086
+ Controller,
1087
+ {
1088
+ name,
1089
+ control,
1090
+ render: ({ field, fieldState: { error } }) => {
1091
+ const normalizedValue = normalizeValue3(field.value);
1092
+ return /* @__PURE__ */ jsx(
1093
+ DateTimePicker,
1094
+ {
1095
+ label,
1096
+ value: normalizedValue,
1097
+ onChange: (newValue) => {
1098
+ field.onChange(newValue?.toISOString() ?? null);
1099
+ },
1100
+ disabled,
1101
+ readOnly,
1102
+ minutesStep,
1103
+ ampm,
1104
+ minDateTime,
1105
+ maxDateTime,
1106
+ disablePast,
1107
+ disableFuture,
1108
+ views,
1109
+ openTo,
1110
+ format,
1111
+ slotProps: {
1112
+ textField: {
1113
+ fullWidth: true,
1114
+ error: !!error,
1115
+ helperText: error?.message ?? helperText,
1116
+ ...textFieldProps
1117
+ }
1118
+ }
1119
+ }
1120
+ );
1121
+ }
1122
+ }
1123
+ );
1124
+ }
1125
+ function FieldMultiCheckbox({
1126
+ name,
1127
+ label,
1128
+ options,
1129
+ helperText,
1130
+ slotProps,
1131
+ row,
1132
+ ...other
1133
+ }) {
1134
+ const { control } = useFormContext();
1135
+ const id = useId();
1136
+ const helperId = `field-multi-checkbox-helper-${id}`;
1137
+ return /* @__PURE__ */ jsx(
1138
+ Controller,
1139
+ {
1140
+ name,
1141
+ control,
1142
+ render: ({ field, fieldState: { error } }) => {
1143
+ const selectedValues = Array.isArray(field.value) ? field.value : [];
1144
+ const hasHelper = !!(error?.message || helperText);
1145
+ const handleToggle = (optionValue) => {
1146
+ const isSelected = selectedValues.includes(optionValue);
1147
+ const newValues = isSelected ? selectedValues.filter((v) => v !== optionValue) : [...selectedValues, optionValue];
1148
+ field.onChange(newValues);
1149
+ };
1150
+ return /* @__PURE__ */ jsxs(
1151
+ FormControl8,
1152
+ {
1153
+ component: "fieldset",
1154
+ error: !!error,
1155
+ "aria-describedby": hasHelper ? helperId : void 0,
1156
+ ...slotProps?.wrapper,
1157
+ children: [
1158
+ label && /* @__PURE__ */ jsx(
1159
+ FormLabel6,
1160
+ {
1161
+ component: "legend",
1162
+ ...slotProps?.formLabel,
1163
+ sx: {
1164
+ mb: 1,
1165
+ ...slotProps?.formLabel?.sx
1166
+ },
1167
+ children: label
1168
+ }
1169
+ ),
1170
+ /* @__PURE__ */ jsx(Box7, { ...slotProps?.container, children: /* @__PURE__ */ jsx(FormGroup, { row, ...other, children: options.map((option) => /* @__PURE__ */ jsx(
1171
+ FormControlLabel,
1172
+ {
1173
+ label: option.label,
1174
+ disabled: option.disabled,
1175
+ control: /* @__PURE__ */ jsx(
1176
+ Checkbox,
1177
+ {
1178
+ checked: selectedValues.includes(option.value),
1179
+ onChange: () => handleToggle(option.value),
1180
+ ...slotProps?.checkbox
1181
+ }
1182
+ )
1183
+ },
1184
+ option.value
1185
+ )) }) }),
1186
+ hasHelper && /* @__PURE__ */ jsx(FormHelperText9, { id: helperId, error: !!error, ...slotProps?.helperText, children: error?.message ?? helperText })
1187
+ ]
1188
+ }
1189
+ );
1190
+ }
1191
+ }
1192
+ );
1193
+ }
1194
+ function FieldMultiSwitch({
1195
+ name,
1196
+ label,
1197
+ options,
1198
+ helperText,
1199
+ slotProps,
1200
+ row,
1201
+ ...other
1202
+ }) {
1203
+ const { control } = useFormContext();
1204
+ const id = useId();
1205
+ const helperId = `field-multi-switch-helper-${id}`;
1206
+ return /* @__PURE__ */ jsx(
1207
+ Controller,
1208
+ {
1209
+ name,
1210
+ control,
1211
+ render: ({ field, fieldState: { error } }) => {
1212
+ const selectedValues = Array.isArray(field.value) ? field.value : [];
1213
+ const hasHelper = !!(error?.message || helperText);
1214
+ const handleToggle = (optionValue) => {
1215
+ const isSelected = selectedValues.includes(optionValue);
1216
+ const newValues = isSelected ? selectedValues.filter((v) => v !== optionValue) : [...selectedValues, optionValue];
1217
+ field.onChange(newValues);
1218
+ };
1219
+ return /* @__PURE__ */ jsxs(
1220
+ FormControl8,
1221
+ {
1222
+ component: "fieldset",
1223
+ error: !!error,
1224
+ "aria-describedby": hasHelper ? helperId : void 0,
1225
+ ...slotProps?.wrapper,
1226
+ children: [
1227
+ label && /* @__PURE__ */ jsx(
1228
+ FormLabel6,
1229
+ {
1230
+ component: "legend",
1231
+ ...slotProps?.formLabel,
1232
+ sx: {
1233
+ mb: 1,
1234
+ ...slotProps?.formLabel?.sx
1235
+ },
1236
+ children: label
1237
+ }
1238
+ ),
1239
+ /* @__PURE__ */ jsx(Box7, { ...slotProps?.container, children: /* @__PURE__ */ jsx(FormGroup, { row, ...other, children: options.map((option) => /* @__PURE__ */ jsx(
1240
+ FormControlLabel,
1241
+ {
1242
+ label: option.label,
1243
+ disabled: option.disabled,
1244
+ control: /* @__PURE__ */ jsx(
1245
+ Switch,
1246
+ {
1247
+ checked: selectedValues.includes(option.value),
1248
+ onChange: () => handleToggle(option.value),
1249
+ ...slotProps?.switch
1250
+ }
1251
+ )
1252
+ },
1253
+ option.value
1254
+ )) }) }),
1255
+ hasHelper && /* @__PURE__ */ jsx(FormHelperText9, { id: helperId, error: !!error, ...slotProps?.helperText, children: error?.message ?? helperText })
1256
+ ]
1257
+ }
1258
+ );
1259
+ }
1260
+ }
1261
+ );
1262
+ }
1263
+ function FieldCode({
1264
+ name,
1265
+ length = 6,
1266
+ placeholder = "-",
1267
+ helperText,
1268
+ autoFocus = false,
1269
+ disabled = false,
1270
+ type = "text",
1271
+ gap = 1.5,
1272
+ inputWidth = 48,
1273
+ slotProps
1274
+ }) {
1275
+ const { control } = useFormContext();
1276
+ const inputRefs = useRef([]);
1277
+ const id = useId();
1278
+ const helperId = `field-code-helper-${id}`;
1279
+ const focusInput = useCallback((index) => {
1280
+ const input = inputRefs.current[index];
1281
+ if (input) {
1282
+ input.focus();
1283
+ input.select();
1284
+ }
1285
+ }, []);
1286
+ return /* @__PURE__ */ jsx(
1287
+ Controller,
1288
+ {
1289
+ name,
1290
+ control,
1291
+ render: ({ field, fieldState: { error } }) => {
1292
+ const valueString = String(field.value ?? "").slice(0, length);
1293
+ const digits = Array.from({ length }, (_, i) => valueString[i] ?? "");
1294
+ const updateValue = (newDigits) => {
1295
+ const newValue = newDigits.join("");
1296
+ field.onChange(newValue);
1297
+ };
1298
+ const handleChange = (index) => (e) => {
1299
+ const inputValue = e.target.value;
1300
+ if (inputValue.length <= 1) {
1301
+ const newDigits = [...digits];
1302
+ newDigits[index] = inputValue;
1303
+ updateValue(newDigits);
1304
+ if (inputValue && index < length - 1) {
1305
+ focusInput(index + 1);
1306
+ }
1307
+ }
1308
+ };
1309
+ const handleKeyDown = (index) => (e) => {
1310
+ const key = e.key;
1311
+ if (key === "Backspace") {
1312
+ e.preventDefault();
1313
+ const newDigits = [...digits];
1314
+ if (digits[index]) {
1315
+ newDigits[index] = "";
1316
+ updateValue(newDigits);
1317
+ } else if (index > 0) {
1318
+ newDigits[index - 1] = "";
1319
+ updateValue(newDigits);
1320
+ focusInput(index - 1);
1321
+ }
1322
+ }
1323
+ if (key === "ArrowLeft" && index > 0) {
1324
+ e.preventDefault();
1325
+ focusInput(index - 1);
1326
+ }
1327
+ if (key === "ArrowRight" && index < length - 1) {
1328
+ e.preventDefault();
1329
+ focusInput(index + 1);
1330
+ }
1331
+ if (key === "Delete") {
1332
+ e.preventDefault();
1333
+ const newDigits = [...digits];
1334
+ newDigits[index] = "";
1335
+ updateValue(newDigits);
1336
+ }
1337
+ };
1338
+ const handlePaste = (e) => {
1339
+ e.preventDefault();
1340
+ const pastedData = e.clipboardData.getData("text").slice(0, length);
1341
+ const validChars = type === "number" ? pastedData.replace(/\D/g, "") : pastedData;
1342
+ if (validChars) {
1343
+ const newDigits = Array.from({ length }, (_, i) => validChars[i] ?? "");
1344
+ updateValue(newDigits);
1345
+ const focusIndex = Math.min(validChars.length, length - 1);
1346
+ focusInput(focusIndex);
1347
+ }
1348
+ };
1349
+ const hasHelper = !!(error?.message || helperText);
1350
+ return /* @__PURE__ */ jsxs(Box7, { role: "group", "aria-label": `${name} code input`, ...slotProps?.wrapper, children: [
1351
+ /* @__PURE__ */ jsx(
1352
+ Box7,
1353
+ {
1354
+ sx: {
1355
+ display: "flex",
1356
+ gap,
1357
+ justifyContent: "center"
1358
+ },
1359
+ children: digits.map((digit, index) => /* @__PURE__ */ jsx(
1360
+ TextField,
1361
+ {
1362
+ inputRef: (el) => {
1363
+ inputRefs.current[index] = el;
1364
+ },
1365
+ value: digit,
1366
+ onChange: handleChange(index),
1367
+ onKeyDown: handleKeyDown(index),
1368
+ onPaste: handlePaste,
1369
+ onFocus: (e) => e.target.select(),
1370
+ disabled,
1371
+ error: !!error,
1372
+ autoFocus: autoFocus && index === 0,
1373
+ placeholder,
1374
+ slotProps: {
1375
+ htmlInput: {
1376
+ maxLength: 1,
1377
+ "aria-label": `Digit ${index + 1} of ${length}`,
1378
+ "aria-describedby": hasHelper ? helperId : void 0,
1379
+ "aria-invalid": !!error,
1380
+ style: {
1381
+ textAlign: "center",
1382
+ fontSize: "1.25rem",
1383
+ fontWeight: 600,
1384
+ padding: "12px 0"
1385
+ },
1386
+ inputMode: type === "number" ? "numeric" : "text",
1387
+ autoComplete: "one-time-code"
1388
+ }
1389
+ },
1390
+ sx: {
1391
+ width: inputWidth,
1392
+ "& .MuiInputBase-input": {
1393
+ p: 0,
1394
+ height: inputWidth
1395
+ }
1396
+ },
1397
+ ...slotProps?.textField
1398
+ },
1399
+ index
1400
+ ))
1401
+ }
1402
+ ),
1403
+ hasHelper && /* @__PURE__ */ jsx(
1404
+ FormHelperText9,
1405
+ {
1406
+ id: helperId,
1407
+ error: !!error,
1408
+ sx: { textAlign: "center", mt: 1 },
1409
+ ...slotProps?.helperText,
1410
+ children: error?.message ?? helperText
1411
+ }
1412
+ )
1413
+ ] });
1414
+ }
1415
+ }
1416
+ );
1417
+ }
1418
+ function formatFileSize(bytes) {
1419
+ if (bytes === 0) return "0 Bytes";
1420
+ const k = 1024;
1421
+ const sizes = ["Bytes", "KB", "MB", "GB"];
1422
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
1423
+ return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
1424
+ }
1425
+ function getPreviewUrl(file) {
1426
+ if (typeof file === "string") return file;
1427
+ if (file instanceof File && file.type.startsWith("image/")) {
1428
+ return URL.createObjectURL(file);
1429
+ }
1430
+ return null;
1431
+ }
1432
+ function getFileName(file) {
1433
+ if (typeof file === "string") {
1434
+ return file.split("/").pop() ?? "file";
1435
+ }
1436
+ return file.name;
1437
+ }
1438
+ function UploadPlaceholder({ isDragActive, disabled }) {
1439
+ const theme = useTheme();
1440
+ return /* @__PURE__ */ jsxs(
1441
+ Stack,
1442
+ {
1443
+ spacing: 1,
1444
+ alignItems: "center",
1445
+ justifyContent: "center",
1446
+ sx: {
1447
+ p: 3,
1448
+ textAlign: "center",
1449
+ color: disabled ? "text.disabled" : "text.secondary"
1450
+ },
1451
+ children: [
1452
+ /* @__PURE__ */ jsx(
1453
+ Box7,
1454
+ {
1455
+ component: "span",
1456
+ sx: {
1457
+ width: 48,
1458
+ height: 48,
1459
+ display: "flex",
1460
+ alignItems: "center",
1461
+ justifyContent: "center",
1462
+ borderRadius: "50%",
1463
+ bgcolor: alpha(theme.palette.primary.main, 0.08),
1464
+ color: "primary.main",
1465
+ fontSize: 24
1466
+ },
1467
+ children: "\u{1F4C1}"
1468
+ }
1469
+ ),
1470
+ /* @__PURE__ */ jsx(Typography2, { variant: "body2", component: "span", children: isDragActive ? "Drop files here" : /* @__PURE__ */ jsxs(Fragment, { children: [
1471
+ "Drag & drop files here, or",
1472
+ " ",
1473
+ /* @__PURE__ */ jsx(Typography2, { component: "span", variant: "body2", sx: { color: "primary.main", textDecoration: "underline" }, children: "browse" })
1474
+ ] }) })
1475
+ ]
1476
+ }
1477
+ );
1478
+ }
1479
+ function FilePreview({ files, thumbnail, onRemove }) {
1480
+ if (files.length === 0) return null;
1481
+ return /* @__PURE__ */ jsx(Stack, { spacing: 1, sx: { mt: 2 }, children: files.map((file, index) => {
1482
+ const previewUrl = thumbnail ? getPreviewUrl(file) : null;
1483
+ const fileName = getFileName(file);
1484
+ const fileSize = file instanceof File ? formatFileSize(file.size) : "";
1485
+ return /* @__PURE__ */ jsxs(
1486
+ Box7,
1487
+ {
1488
+ sx: {
1489
+ p: 1,
1490
+ display: "flex",
1491
+ alignItems: "center",
1492
+ gap: 1.5,
1493
+ borderRadius: 1,
1494
+ bgcolor: "background.neutral",
1495
+ border: "1px solid",
1496
+ borderColor: "divider"
1497
+ },
1498
+ children: [
1499
+ previewUrl && /* @__PURE__ */ jsx(
1500
+ Box7,
1501
+ {
1502
+ component: "img",
1503
+ src: previewUrl,
1504
+ alt: fileName,
1505
+ sx: {
1506
+ width: 40,
1507
+ height: 40,
1508
+ borderRadius: 0.5,
1509
+ objectFit: "cover",
1510
+ flexShrink: 0
1511
+ }
1512
+ }
1513
+ ),
1514
+ /* @__PURE__ */ jsxs(Box7, { sx: { flexGrow: 1, minWidth: 0 }, children: [
1515
+ /* @__PURE__ */ jsx(Typography2, { variant: "body2", noWrap: true, children: fileName }),
1516
+ fileSize && /* @__PURE__ */ jsx(Typography2, { variant: "caption", color: "text.secondary", children: fileSize })
1517
+ ] }),
1518
+ onRemove && /* @__PURE__ */ jsx(IconButton, { size: "small", onClick: () => onRemove(file), sx: { flexShrink: 0 }, children: "\u2715" })
1519
+ ]
1520
+ },
1521
+ `${fileName}-${index}`
1522
+ );
1523
+ }) });
1524
+ }
1525
+ function RejectionFiles({ rejections }) {
1526
+ if (rejections.length === 0) return null;
1527
+ return /* @__PURE__ */ jsx(Box7, { sx: { mt: 2 }, children: rejections.map(({ file, errors }) => /* @__PURE__ */ jsxs(
1528
+ Box7,
1529
+ {
1530
+ sx: {
1531
+ p: 1,
1532
+ mb: 1,
1533
+ borderRadius: 1,
1534
+ bgcolor: "error.lighter",
1535
+ border: "1px solid",
1536
+ borderColor: "error.light"
1537
+ },
1538
+ children: [
1539
+ /* @__PURE__ */ jsx(Typography2, { variant: "body2", color: "error", children: file.name }),
1540
+ errors.map((error) => /* @__PURE__ */ jsx(Typography2, { variant: "caption", color: "error", children: error.message }, error.code))
1541
+ ]
1542
+ },
1543
+ file.name
1544
+ )) });
1545
+ }
1546
+ function FieldUploadInner({
1547
+ value,
1548
+ error,
1549
+ multiple,
1550
+ thumbnail,
1551
+ disabled,
1552
+ helperText,
1553
+ placeholder,
1554
+ onRemove,
1555
+ onRemoveAll,
1556
+ slotProps,
1557
+ sx,
1558
+ dropzoneOptions,
1559
+ setValue,
1560
+ name
1561
+ }) {
1562
+ const theme = useTheme();
1563
+ const [rejections, setRejections] = useState([]);
1564
+ const files = useMemo(() => {
1565
+ if (!value) return [];
1566
+ return Array.isArray(value) ? value : [value];
1567
+ }, [value]);
1568
+ const onDrop = useCallback(
1569
+ (acceptedFiles, fileRejections) => {
1570
+ setRejections(fileRejections);
1571
+ if (acceptedFiles.length === 0) return;
1572
+ if (multiple) {
1573
+ setValue(name, [...files, ...acceptedFiles], { shouldValidate: true });
1574
+ } else {
1575
+ setValue(name, acceptedFiles[0], { shouldValidate: true });
1576
+ }
1577
+ },
1578
+ [files, multiple, name, setValue]
1579
+ );
1580
+ const handleRemove = useCallback(
1581
+ (file) => {
1582
+ const newFiles = files.filter((f) => f !== file);
1583
+ setValue(name, multiple ? newFiles : null, { shouldValidate: true });
1584
+ onRemove?.(file);
1585
+ },
1586
+ [files, multiple, name, onRemove, setValue]
1587
+ );
1588
+ const handleRemoveAll = useCallback(() => {
1589
+ setValue(name, multiple ? [] : null, { shouldValidate: true });
1590
+ onRemoveAll?.();
1591
+ }, [multiple, name, onRemoveAll, setValue]);
1592
+ const { getRootProps, getInputProps, isDragActive } = useDropzone({
1593
+ ...dropzoneOptions,
1594
+ multiple,
1595
+ disabled,
1596
+ onDrop
1597
+ });
1598
+ const hasError = !!error;
1599
+ const hasFiles = files.length > 0;
1600
+ return /* @__PURE__ */ jsxs(Box7, { ...slotProps?.wrapper, children: [
1601
+ /* @__PURE__ */ jsxs(
1602
+ Box7,
1603
+ {
1604
+ ...getRootProps(),
1605
+ sx: {
1606
+ p: 0,
1607
+ outline: "none",
1608
+ borderRadius: 1,
1609
+ cursor: disabled ? "default" : "pointer",
1610
+ overflow: "hidden",
1611
+ border: "1px dashed",
1612
+ borderColor: hasError ? "error.main" : isDragActive ? "primary.main" : "divider",
1613
+ bgcolor: isDragActive ? alpha(theme.palette.primary.main, 0.08) : "background.paper",
1614
+ transition: theme.transitions.create(["border-color", "background-color"]),
1615
+ "&:hover": {
1616
+ borderColor: disabled ? "divider" : "primary.main",
1617
+ bgcolor: disabled ? "background.paper" : alpha(theme.palette.primary.main, 0.04)
1618
+ },
1619
+ ...sx
1620
+ },
1621
+ children: [
1622
+ /* @__PURE__ */ jsx("input", { ...getInputProps() }),
1623
+ placeholder ?? /* @__PURE__ */ jsx(UploadPlaceholder, { isDragActive, disabled })
1624
+ ]
1625
+ }
1626
+ ),
1627
+ /* @__PURE__ */ jsx(RejectionFiles, { rejections }),
1628
+ /* @__PURE__ */ jsx(FilePreview, { files, thumbnail, onRemove: handleRemove }),
1629
+ hasFiles && multiple && onRemoveAll && /* @__PURE__ */ jsx(Box7, { sx: { mt: 1, textAlign: "right" }, children: /* @__PURE__ */ jsx(
1630
+ Typography2,
1631
+ {
1632
+ component: "button",
1633
+ variant: "caption",
1634
+ onClick: handleRemoveAll,
1635
+ sx: {
1636
+ color: "error.main",
1637
+ cursor: "pointer",
1638
+ border: "none",
1639
+ bgcolor: "transparent",
1640
+ "&:hover": { textDecoration: "underline" }
1641
+ },
1642
+ children: "Remove all"
1643
+ }
1644
+ ) }),
1645
+ (error?.message || helperText) && /* @__PURE__ */ jsx(FormHelperText9, { error: hasError, sx: { mt: 1 }, children: error?.message ?? helperText })
1646
+ ] });
1647
+ }
1648
+ function FieldUpload({
1649
+ name,
1650
+ multiple = false,
1651
+ thumbnail = false,
1652
+ disabled,
1653
+ helperText,
1654
+ placeholder,
1655
+ onRemove,
1656
+ onRemoveAll,
1657
+ slotProps,
1658
+ sx,
1659
+ ...dropzoneOptions
1660
+ }) {
1661
+ const { control, setValue } = useFormContext();
1662
+ return /* @__PURE__ */ jsx(
1663
+ Controller,
1664
+ {
1665
+ name,
1666
+ control,
1667
+ render: ({ field, fieldState: { error } }) => /* @__PURE__ */ jsx(
1668
+ FieldUploadInner,
1669
+ {
1670
+ value: field.value,
1671
+ error,
1672
+ multiple,
1673
+ thumbnail,
1674
+ disabled,
1675
+ helperText,
1676
+ placeholder,
1677
+ onRemove,
1678
+ onRemoveAll,
1679
+ slotProps,
1680
+ sx,
1681
+ dropzoneOptions,
1682
+ setValue,
1683
+ name
1684
+ }
1685
+ )
1686
+ }
1687
+ );
1688
+ }
1689
+ function FieldUploadBoxInner({
1690
+ value,
1691
+ error,
1692
+ size,
1693
+ disabled,
1694
+ helperText,
1695
+ sx,
1696
+ dropzoneOptions,
1697
+ setValue,
1698
+ name
1699
+ }) {
1700
+ const theme = useTheme();
1701
+ const onDrop = useCallback(
1702
+ (acceptedFiles) => {
1703
+ if (acceptedFiles.length > 0) {
1704
+ setValue(name, acceptedFiles[0], { shouldValidate: true });
1705
+ }
1706
+ },
1707
+ [name, setValue]
1708
+ );
1709
+ const { getRootProps, getInputProps, isDragActive } = useDropzone({
1710
+ ...dropzoneOptions,
1711
+ multiple: false,
1712
+ disabled,
1713
+ onDrop
1714
+ });
1715
+ const previewUrl = value ? getPreviewUrl(value) : null;
1716
+ const hasError = !!error;
1717
+ return /* @__PURE__ */ jsxs(Box7, { children: [
1718
+ /* @__PURE__ */ jsxs(
1719
+ Box7,
1720
+ {
1721
+ ...getRootProps(),
1722
+ sx: {
1723
+ width: size,
1724
+ height: size,
1725
+ display: "flex",
1726
+ alignItems: "center",
1727
+ justifyContent: "center",
1728
+ borderRadius: 1,
1729
+ cursor: disabled ? "default" : "pointer",
1730
+ border: "1px dashed",
1731
+ borderColor: hasError ? "error.main" : isDragActive ? "primary.main" : "divider",
1732
+ bgcolor: isDragActive ? alpha(theme.palette.primary.main, 0.08) : "background.paper",
1733
+ backgroundImage: previewUrl ? `url(${previewUrl})` : "none",
1734
+ backgroundSize: "cover",
1735
+ backgroundPosition: "center",
1736
+ transition: theme.transitions.create(["border-color", "background-color"]),
1737
+ "&:hover": {
1738
+ borderColor: disabled ? "divider" : "primary.main"
1739
+ },
1740
+ ...sx
1741
+ },
1742
+ children: [
1743
+ /* @__PURE__ */ jsx("input", { ...getInputProps() }),
1744
+ !previewUrl && /* @__PURE__ */ jsx(
1745
+ Typography2,
1746
+ {
1747
+ sx: {
1748
+ fontSize: size / 3,
1749
+ color: isDragActive ? "primary.main" : "text.disabled"
1750
+ },
1751
+ children: "+"
1752
+ }
1753
+ )
1754
+ ]
1755
+ }
1756
+ ),
1757
+ (error?.message || helperText) && /* @__PURE__ */ jsx(FormHelperText9, { error: hasError, sx: { mt: 0.5 }, children: error?.message ?? helperText })
1758
+ ] });
1759
+ }
1760
+ function FieldUploadBox({
1761
+ name,
1762
+ size = 64,
1763
+ disabled,
1764
+ helperText,
1765
+ sx,
1766
+ ...dropzoneOptions
1767
+ }) {
1768
+ const { control, setValue } = useFormContext();
1769
+ return /* @__PURE__ */ jsx(
1770
+ Controller,
1771
+ {
1772
+ name,
1773
+ control,
1774
+ render: ({ field, fieldState: { error } }) => /* @__PURE__ */ jsx(
1775
+ FieldUploadBoxInner,
1776
+ {
1777
+ value: field.value,
1778
+ error,
1779
+ size,
1780
+ disabled,
1781
+ helperText,
1782
+ sx,
1783
+ dropzoneOptions,
1784
+ setValue,
1785
+ name
1786
+ }
1787
+ )
1788
+ }
1789
+ );
1790
+ }
1791
+ function FieldUploadAvatarInner({
1792
+ value,
1793
+ error,
1794
+ size,
1795
+ disabled,
1796
+ helperText,
1797
+ sx,
1798
+ dropzoneOptions,
1799
+ setValue,
1800
+ name
1801
+ }) {
1802
+ const theme = useTheme();
1803
+ const onDrop = useCallback(
1804
+ (acceptedFiles) => {
1805
+ if (acceptedFiles.length > 0) {
1806
+ setValue(name, acceptedFiles[0], { shouldValidate: true });
1807
+ }
1808
+ },
1809
+ [name, setValue]
1810
+ );
1811
+ const { getRootProps, getInputProps, isDragActive } = useDropzone({
1812
+ ...dropzoneOptions,
1813
+ multiple: false,
1814
+ disabled,
1815
+ accept: dropzoneOptions.accept ?? { "image/*": [] },
1816
+ onDrop
1817
+ });
1818
+ const previewUrl = value ? getPreviewUrl(value) : null;
1819
+ const hasError = !!error;
1820
+ return /* @__PURE__ */ jsxs(Box7, { sx: { display: "inline-flex", flexDirection: "column", alignItems: "center" }, children: [
1821
+ /* @__PURE__ */ jsxs(
1822
+ Box7,
1823
+ {
1824
+ ...getRootProps(),
1825
+ sx: {
1826
+ width: size,
1827
+ height: size,
1828
+ borderRadius: "50%",
1829
+ cursor: disabled ? "default" : "pointer",
1830
+ position: "relative",
1831
+ overflow: "hidden",
1832
+ border: "1px dashed",
1833
+ borderColor: hasError ? "error.main" : isDragActive ? "primary.main" : "divider",
1834
+ transition: theme.transitions.create(["border-color"]),
1835
+ "&:hover .upload-overlay": {
1836
+ opacity: disabled ? 0 : 1
1837
+ },
1838
+ ...sx
1839
+ },
1840
+ children: [
1841
+ /* @__PURE__ */ jsx("input", { ...getInputProps() }),
1842
+ /* @__PURE__ */ jsx(
1843
+ Avatar,
1844
+ {
1845
+ src: previewUrl ?? void 0,
1846
+ sx: {
1847
+ width: "100%",
1848
+ height: "100%",
1849
+ bgcolor: "background.neutral"
1850
+ },
1851
+ children: !previewUrl && /* @__PURE__ */ jsx(Typography2, { sx: { fontSize: size / 4, color: "text.disabled" }, children: "\u{1F4F7}" })
1852
+ }
1853
+ ),
1854
+ /* @__PURE__ */ jsxs(
1855
+ Box7,
1856
+ {
1857
+ className: "upload-overlay",
1858
+ sx: {
1859
+ position: "absolute",
1860
+ inset: 0,
1861
+ display: "flex",
1862
+ flexDirection: "column",
1863
+ alignItems: "center",
1864
+ justifyContent: "center",
1865
+ bgcolor: alpha(theme.palette.grey[900], 0.64),
1866
+ color: "common.white",
1867
+ opacity: isDragActive ? 1 : 0,
1868
+ transition: theme.transitions.create("opacity")
1869
+ },
1870
+ children: [
1871
+ /* @__PURE__ */ jsx(Typography2, { sx: { fontSize: size / 6 }, children: "\u{1F4F7}" }),
1872
+ /* @__PURE__ */ jsx(Typography2, { variant: "caption", children: previewUrl ? "Update" : "Upload" })
1873
+ ]
1874
+ }
1875
+ )
1876
+ ]
1877
+ }
1878
+ ),
1879
+ (error?.message || helperText) && /* @__PURE__ */ jsx(FormHelperText9, { error: hasError, sx: { mt: 1, textAlign: "center" }, children: error?.message ?? helperText })
1880
+ ] });
1881
+ }
1882
+ function FieldUploadAvatar({
1883
+ name,
1884
+ size = 144,
1885
+ disabled,
1886
+ helperText,
1887
+ sx,
1888
+ ...dropzoneOptions
1889
+ }) {
1890
+ const { control, setValue } = useFormContext();
1891
+ return /* @__PURE__ */ jsx(
1892
+ Controller,
1893
+ {
1894
+ name,
1895
+ control,
1896
+ render: ({ field, fieldState: { error } }) => /* @__PURE__ */ jsx(
1897
+ FieldUploadAvatarInner,
1898
+ {
1899
+ value: field.value,
1900
+ error,
1901
+ size,
1902
+ disabled,
1903
+ helperText,
1904
+ sx,
1905
+ dropzoneOptions,
1906
+ setValue,
1907
+ name
1908
+ }
1909
+ )
1910
+ }
1911
+ );
1912
+ }
1913
+ var DEFAULT_COUNTRIES = [
1914
+ { code: "US", name: "United States", dialCode: "+1", flag: "\u{1F1FA}\u{1F1F8}" },
1915
+ { code: "GB", name: "United Kingdom", dialCode: "+44", flag: "\u{1F1EC}\u{1F1E7}" },
1916
+ { code: "CA", name: "Canada", dialCode: "+1", flag: "\u{1F1E8}\u{1F1E6}" },
1917
+ { code: "AU", name: "Australia", dialCode: "+61", flag: "\u{1F1E6}\u{1F1FA}" },
1918
+ { code: "DE", name: "Germany", dialCode: "+49", flag: "\u{1F1E9}\u{1F1EA}" },
1919
+ { code: "FR", name: "France", dialCode: "+33", flag: "\u{1F1EB}\u{1F1F7}" },
1920
+ { code: "IT", name: "Italy", dialCode: "+39", flag: "\u{1F1EE}\u{1F1F9}" },
1921
+ { code: "ES", name: "Spain", dialCode: "+34", flag: "\u{1F1EA}\u{1F1F8}" },
1922
+ { code: "JP", name: "Japan", dialCode: "+81", flag: "\u{1F1EF}\u{1F1F5}" },
1923
+ { code: "CN", name: "China", dialCode: "+86", flag: "\u{1F1E8}\u{1F1F3}" },
1924
+ { code: "KR", name: "South Korea", dialCode: "+82", flag: "\u{1F1F0}\u{1F1F7}" },
1925
+ { code: "IN", name: "India", dialCode: "+91", flag: "\u{1F1EE}\u{1F1F3}" },
1926
+ { code: "BR", name: "Brazil", dialCode: "+55", flag: "\u{1F1E7}\u{1F1F7}" },
1927
+ { code: "MX", name: "Mexico", dialCode: "+52", flag: "\u{1F1F2}\u{1F1FD}" },
1928
+ { code: "RU", name: "Russia", dialCode: "+7", flag: "\u{1F1F7}\u{1F1FA}" },
1929
+ { code: "NL", name: "Netherlands", dialCode: "+31", flag: "\u{1F1F3}\u{1F1F1}" },
1930
+ { code: "BE", name: "Belgium", dialCode: "+32", flag: "\u{1F1E7}\u{1F1EA}" },
1931
+ { code: "CH", name: "Switzerland", dialCode: "+41", flag: "\u{1F1E8}\u{1F1ED}" },
1932
+ { code: "AT", name: "Austria", dialCode: "+43", flag: "\u{1F1E6}\u{1F1F9}" },
1933
+ { code: "SE", name: "Sweden", dialCode: "+46", flag: "\u{1F1F8}\u{1F1EA}" },
1934
+ { code: "NO", name: "Norway", dialCode: "+47", flag: "\u{1F1F3}\u{1F1F4}" },
1935
+ { code: "DK", name: "Denmark", dialCode: "+45", flag: "\u{1F1E9}\u{1F1F0}" },
1936
+ { code: "FI", name: "Finland", dialCode: "+358", flag: "\u{1F1EB}\u{1F1EE}" },
1937
+ { code: "PL", name: "Poland", dialCode: "+48", flag: "\u{1F1F5}\u{1F1F1}" },
1938
+ { code: "PT", name: "Portugal", dialCode: "+351", flag: "\u{1F1F5}\u{1F1F9}" },
1939
+ { code: "GR", name: "Greece", dialCode: "+30", flag: "\u{1F1EC}\u{1F1F7}" },
1940
+ { code: "IE", name: "Ireland", dialCode: "+353", flag: "\u{1F1EE}\u{1F1EA}" },
1941
+ { code: "NZ", name: "New Zealand", dialCode: "+64", flag: "\u{1F1F3}\u{1F1FF}" },
1942
+ { code: "SG", name: "Singapore", dialCode: "+65", flag: "\u{1F1F8}\u{1F1EC}" },
1943
+ { code: "HK", name: "Hong Kong", dialCode: "+852", flag: "\u{1F1ED}\u{1F1F0}" },
1944
+ { code: "AE", name: "UAE", dialCode: "+971", flag: "\u{1F1E6}\u{1F1EA}" },
1945
+ { code: "SA", name: "Saudi Arabia", dialCode: "+966", flag: "\u{1F1F8}\u{1F1E6}" },
1946
+ { code: "IL", name: "Israel", dialCode: "+972", flag: "\u{1F1EE}\u{1F1F1}" },
1947
+ { code: "TR", name: "Turkey", dialCode: "+90", flag: "\u{1F1F9}\u{1F1F7}" },
1948
+ { code: "ZA", name: "South Africa", dialCode: "+27", flag: "\u{1F1FF}\u{1F1E6}" },
1949
+ { code: "EG", name: "Egypt", dialCode: "+20", flag: "\u{1F1EA}\u{1F1EC}" },
1950
+ { code: "NG", name: "Nigeria", dialCode: "+234", flag: "\u{1F1F3}\u{1F1EC}" },
1951
+ { code: "KE", name: "Kenya", dialCode: "+254", flag: "\u{1F1F0}\u{1F1EA}" },
1952
+ { code: "AR", name: "Argentina", dialCode: "+54", flag: "\u{1F1E6}\u{1F1F7}" },
1953
+ { code: "CL", name: "Chile", dialCode: "+56", flag: "\u{1F1E8}\u{1F1F1}" },
1954
+ { code: "CO", name: "Colombia", dialCode: "+57", flag: "\u{1F1E8}\u{1F1F4}" },
1955
+ { code: "PE", name: "Peru", dialCode: "+51", flag: "\u{1F1F5}\u{1F1EA}" },
1956
+ { code: "VE", name: "Venezuela", dialCode: "+58", flag: "\u{1F1FB}\u{1F1EA}" },
1957
+ { code: "TH", name: "Thailand", dialCode: "+66", flag: "\u{1F1F9}\u{1F1ED}" },
1958
+ { code: "VN", name: "Vietnam", dialCode: "+84", flag: "\u{1F1FB}\u{1F1F3}" },
1959
+ { code: "MY", name: "Malaysia", dialCode: "+60", flag: "\u{1F1F2}\u{1F1FE}" },
1960
+ { code: "ID", name: "Indonesia", dialCode: "+62", flag: "\u{1F1EE}\u{1F1E9}" },
1961
+ { code: "PH", name: "Philippines", dialCode: "+63", flag: "\u{1F1F5}\u{1F1ED}" },
1962
+ { code: "PK", name: "Pakistan", dialCode: "+92", flag: "\u{1F1F5}\u{1F1F0}" },
1963
+ { code: "BD", name: "Bangladesh", dialCode: "+880", flag: "\u{1F1E7}\u{1F1E9}" },
1964
+ { code: "UA", name: "Ukraine", dialCode: "+380", flag: "\u{1F1FA}\u{1F1E6}" },
1965
+ { code: "CZ", name: "Czech Republic", dialCode: "+420", flag: "\u{1F1E8}\u{1F1FF}" },
1966
+ { code: "RO", name: "Romania", dialCode: "+40", flag: "\u{1F1F7}\u{1F1F4}" },
1967
+ { code: "HU", name: "Hungary", dialCode: "+36", flag: "\u{1F1ED}\u{1F1FA}" }
1968
+ ];
1969
+ function formatPhoneNumber(value) {
1970
+ return value.replace(/[^\d+]/g, "");
1971
+ }
1972
+ function detectCountryFromNumber(phoneNumber, countries) {
1973
+ if (!phoneNumber.startsWith("+")) return null;
1974
+ const sortedCountries = [...countries].sort((a, b) => b.dialCode.length - a.dialCode.length);
1975
+ for (const country of sortedCountries) {
1976
+ if (phoneNumber.startsWith(country.dialCode)) {
1977
+ return country;
1978
+ }
1979
+ }
1980
+ return null;
1981
+ }
1982
+ function FieldPhone({
1983
+ name,
1984
+ label,
1985
+ helperText,
1986
+ defaultCountry = "US",
1987
+ preferredCountries = [],
1988
+ hideCountrySelect = false,
1989
+ countries: customCountries,
1990
+ disabled,
1991
+ ...other
1992
+ }) {
1993
+ const { control } = useFormContext();
1994
+ const countries = customCountries ?? DEFAULT_COUNTRIES;
1995
+ const anchorRef = useRef(null);
1996
+ const [menuOpen, setMenuOpen] = useState(false);
1997
+ const defaultCountryData = useMemo(
1998
+ () => countries.find((c) => c.code === defaultCountry) ?? countries[0],
1999
+ [countries, defaultCountry]
2000
+ );
2001
+ const sortedCountries = useMemo(() => {
2002
+ if (preferredCountries.length === 0) return countries;
2003
+ const preferred = preferredCountries.map((code) => countries.find((c) => c.code === code)).filter(Boolean);
2004
+ const rest = countries.filter((c) => !preferredCountries.includes(c.code));
2005
+ return [...preferred, ...rest];
2006
+ }, [countries, preferredCountries]);
2007
+ const handleOpenMenu = useCallback(() => {
2008
+ if (!disabled) {
2009
+ setMenuOpen(true);
2010
+ }
2011
+ }, [disabled]);
2012
+ const handleCloseMenu = useCallback(() => {
2013
+ setMenuOpen(false);
2014
+ }, []);
2015
+ return /* @__PURE__ */ jsx(
2016
+ Controller,
2017
+ {
2018
+ name,
2019
+ control,
2020
+ render: ({ field, fieldState: { error } }) => {
2021
+ const detectedCountry = field.value ? detectCountryFromNumber(field.value, countries) : null;
2022
+ const selectedCountry = detectedCountry ?? defaultCountryData;
2023
+ const handleCountrySelect = (country) => {
2024
+ const currentNumber = field.value ?? "";
2025
+ const numberWithoutCode = currentNumber.replace(/^\+\d+\s*/, "");
2026
+ field.onChange(`${country.dialCode}${numberWithoutCode}`);
2027
+ handleCloseMenu();
2028
+ };
2029
+ const handleInputChange = (e) => {
2030
+ const rawValue = e.target.value;
2031
+ const formatted = formatPhoneNumber(rawValue);
2032
+ if (formatted && !formatted.startsWith("+")) {
2033
+ field.onChange(`${selectedCountry.dialCode}${formatted}`);
2034
+ } else {
2035
+ field.onChange(formatted);
2036
+ }
2037
+ };
2038
+ const displayValue = field.value ?? "";
2039
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
2040
+ /* @__PURE__ */ jsx(
2041
+ TextField,
2042
+ {
2043
+ ...other,
2044
+ label,
2045
+ value: displayValue,
2046
+ onChange: handleInputChange,
2047
+ disabled,
2048
+ error: !!error,
2049
+ helperText: error?.message ?? helperText,
2050
+ fullWidth: true,
2051
+ slotProps: {
2052
+ input: {
2053
+ startAdornment: !hideCountrySelect && /* @__PURE__ */ jsxs(InputAdornment, { position: "start", children: [
2054
+ /* @__PURE__ */ jsx(
2055
+ IconButton,
2056
+ {
2057
+ ref: anchorRef,
2058
+ onClick: handleOpenMenu,
2059
+ disabled,
2060
+ size: "small",
2061
+ edge: "start",
2062
+ "aria-label": `Select country, current: ${selectedCountry.name}`,
2063
+ "aria-haspopup": "listbox",
2064
+ "aria-expanded": menuOpen,
2065
+ sx: { mr: -0.5 },
2066
+ children: /* @__PURE__ */ jsx(
2067
+ Box7,
2068
+ {
2069
+ component: "span",
2070
+ sx: {
2071
+ fontSize: "1.25rem",
2072
+ lineHeight: 1,
2073
+ display: "flex",
2074
+ alignItems: "center"
2075
+ },
2076
+ children: selectedCountry.flag
2077
+ }
2078
+ )
2079
+ }
2080
+ ),
2081
+ /* @__PURE__ */ jsx(Typography2, { variant: "body2", color: "text.secondary", sx: { mr: 0.5, minWidth: 40 }, children: selectedCountry.dialCode })
2082
+ ] })
2083
+ },
2084
+ htmlInput: {
2085
+ inputMode: "tel",
2086
+ autoComplete: "tel"
2087
+ }
2088
+ }
2089
+ }
2090
+ ),
2091
+ /* @__PURE__ */ jsx(
2092
+ Menu,
2093
+ {
2094
+ anchorEl: anchorRef.current,
2095
+ open: menuOpen,
2096
+ onClose: handleCloseMenu,
2097
+ slotProps: {
2098
+ paper: {
2099
+ sx: {
2100
+ maxHeight: 300,
2101
+ minWidth: 280
2102
+ }
2103
+ }
2104
+ },
2105
+ children: sortedCountries.map((country, index) => /* @__PURE__ */ jsxs(
2106
+ MenuItem,
2107
+ {
2108
+ selected: country.code === selectedCountry.code,
2109
+ onClick: () => handleCountrySelect(country),
2110
+ divider: preferredCountries.length > 0 && index === preferredCountries.length - 1,
2111
+ children: [
2112
+ /* @__PURE__ */ jsx(ListItemIcon, { sx: { fontSize: "1.25rem", minWidth: 36 }, children: country.flag }),
2113
+ /* @__PURE__ */ jsx(ListItemText, { primary: country.name, secondary: country.dialCode })
2114
+ ]
2115
+ },
2116
+ country.code
2117
+ ))
2118
+ }
2119
+ )
2120
+ ] });
2121
+ }
2122
+ }
2123
+ );
2124
+ }
2125
+ var DEFAULT_COUNTRIES2 = [
2126
+ { code: "AD", label: "Andorra", phone: "+376", flag: "\u{1F1E6}\u{1F1E9}" },
2127
+ { code: "AE", label: "United Arab Emirates", phone: "+971", flag: "\u{1F1E6}\u{1F1EA}" },
2128
+ { code: "AF", label: "Afghanistan", phone: "+93", flag: "\u{1F1E6}\u{1F1EB}" },
2129
+ { code: "AG", label: "Antigua and Barbuda", phone: "+1-268", flag: "\u{1F1E6}\u{1F1EC}" },
2130
+ { code: "AI", label: "Anguilla", phone: "+1-264", flag: "\u{1F1E6}\u{1F1EE}" },
2131
+ { code: "AL", label: "Albania", phone: "+355", flag: "\u{1F1E6}\u{1F1F1}" },
2132
+ { code: "AM", label: "Armenia", phone: "+374", flag: "\u{1F1E6}\u{1F1F2}" },
2133
+ { code: "AO", label: "Angola", phone: "+244", flag: "\u{1F1E6}\u{1F1F4}" },
2134
+ { code: "AR", label: "Argentina", phone: "+54", flag: "\u{1F1E6}\u{1F1F7}" },
2135
+ { code: "AT", label: "Austria", phone: "+43", flag: "\u{1F1E6}\u{1F1F9}" },
2136
+ { code: "AU", label: "Australia", phone: "+61", flag: "\u{1F1E6}\u{1F1FA}" },
2137
+ { code: "AZ", label: "Azerbaijan", phone: "+994", flag: "\u{1F1E6}\u{1F1FF}" },
2138
+ { code: "BA", label: "Bosnia and Herzegovina", phone: "+387", flag: "\u{1F1E7}\u{1F1E6}" },
2139
+ { code: "BB", label: "Barbados", phone: "+1-246", flag: "\u{1F1E7}\u{1F1E7}" },
2140
+ { code: "BD", label: "Bangladesh", phone: "+880", flag: "\u{1F1E7}\u{1F1E9}" },
2141
+ { code: "BE", label: "Belgium", phone: "+32", flag: "\u{1F1E7}\u{1F1EA}" },
2142
+ { code: "BF", label: "Burkina Faso", phone: "+226", flag: "\u{1F1E7}\u{1F1EB}" },
2143
+ { code: "BG", label: "Bulgaria", phone: "+359", flag: "\u{1F1E7}\u{1F1EC}" },
2144
+ { code: "BH", label: "Bahrain", phone: "+973", flag: "\u{1F1E7}\u{1F1ED}" },
2145
+ { code: "BI", label: "Burundi", phone: "+257", flag: "\u{1F1E7}\u{1F1EE}" },
2146
+ { code: "BJ", label: "Benin", phone: "+229", flag: "\u{1F1E7}\u{1F1EF}" },
2147
+ { code: "BN", label: "Brunei", phone: "+673", flag: "\u{1F1E7}\u{1F1F3}" },
2148
+ { code: "BO", label: "Bolivia", phone: "+591", flag: "\u{1F1E7}\u{1F1F4}" },
2149
+ { code: "BR", label: "Brazil", phone: "+55", flag: "\u{1F1E7}\u{1F1F7}" },
2150
+ { code: "BS", label: "Bahamas", phone: "+1-242", flag: "\u{1F1E7}\u{1F1F8}" },
2151
+ { code: "BT", label: "Bhutan", phone: "+975", flag: "\u{1F1E7}\u{1F1F9}" },
2152
+ { code: "BW", label: "Botswana", phone: "+267", flag: "\u{1F1E7}\u{1F1FC}" },
2153
+ { code: "BY", label: "Belarus", phone: "+375", flag: "\u{1F1E7}\u{1F1FE}" },
2154
+ { code: "BZ", label: "Belize", phone: "+501", flag: "\u{1F1E7}\u{1F1FF}" },
2155
+ { code: "CA", label: "Canada", phone: "+1", flag: "\u{1F1E8}\u{1F1E6}" },
2156
+ { code: "CH", label: "Switzerland", phone: "+41", flag: "\u{1F1E8}\u{1F1ED}" },
2157
+ { code: "CL", label: "Chile", phone: "+56", flag: "\u{1F1E8}\u{1F1F1}" },
2158
+ { code: "CN", label: "China", phone: "+86", flag: "\u{1F1E8}\u{1F1F3}" },
2159
+ { code: "CO", label: "Colombia", phone: "+57", flag: "\u{1F1E8}\u{1F1F4}" },
2160
+ { code: "CR", label: "Costa Rica", phone: "+506", flag: "\u{1F1E8}\u{1F1F7}" },
2161
+ { code: "CU", label: "Cuba", phone: "+53", flag: "\u{1F1E8}\u{1F1FA}" },
2162
+ { code: "CY", label: "Cyprus", phone: "+357", flag: "\u{1F1E8}\u{1F1FE}" },
2163
+ { code: "CZ", label: "Czech Republic", phone: "+420", flag: "\u{1F1E8}\u{1F1FF}" },
2164
+ { code: "DE", label: "Germany", phone: "+49", flag: "\u{1F1E9}\u{1F1EA}" },
2165
+ { code: "DJ", label: "Djibouti", phone: "+253", flag: "\u{1F1E9}\u{1F1EF}" },
2166
+ { code: "DK", label: "Denmark", phone: "+45", flag: "\u{1F1E9}\u{1F1F0}" },
2167
+ { code: "DM", label: "Dominica", phone: "+1-767", flag: "\u{1F1E9}\u{1F1F2}" },
2168
+ { code: "DO", label: "Dominican Republic", phone: "+1-809", flag: "\u{1F1E9}\u{1F1F4}" },
2169
+ { code: "DZ", label: "Algeria", phone: "+213", flag: "\u{1F1E9}\u{1F1FF}" },
2170
+ { code: "EC", label: "Ecuador", phone: "+593", flag: "\u{1F1EA}\u{1F1E8}" },
2171
+ { code: "EE", label: "Estonia", phone: "+372", flag: "\u{1F1EA}\u{1F1EA}" },
2172
+ { code: "EG", label: "Egypt", phone: "+20", flag: "\u{1F1EA}\u{1F1EC}" },
2173
+ { code: "ES", label: "Spain", phone: "+34", flag: "\u{1F1EA}\u{1F1F8}" },
2174
+ { code: "ET", label: "Ethiopia", phone: "+251", flag: "\u{1F1EA}\u{1F1F9}" },
2175
+ { code: "FI", label: "Finland", phone: "+358", flag: "\u{1F1EB}\u{1F1EE}" },
2176
+ { code: "FJ", label: "Fiji", phone: "+679", flag: "\u{1F1EB}\u{1F1EF}" },
2177
+ { code: "FR", label: "France", phone: "+33", flag: "\u{1F1EB}\u{1F1F7}" },
2178
+ { code: "GA", label: "Gabon", phone: "+241", flag: "\u{1F1EC}\u{1F1E6}" },
2179
+ { code: "GB", label: "United Kingdom", phone: "+44", flag: "\u{1F1EC}\u{1F1E7}" },
2180
+ { code: "GE", label: "Georgia", phone: "+995", flag: "\u{1F1EC}\u{1F1EA}" },
2181
+ { code: "GH", label: "Ghana", phone: "+233", flag: "\u{1F1EC}\u{1F1ED}" },
2182
+ { code: "GR", label: "Greece", phone: "+30", flag: "\u{1F1EC}\u{1F1F7}" },
2183
+ { code: "GT", label: "Guatemala", phone: "+502", flag: "\u{1F1EC}\u{1F1F9}" },
2184
+ { code: "GY", label: "Guyana", phone: "+592", flag: "\u{1F1EC}\u{1F1FE}" },
2185
+ { code: "HK", label: "Hong Kong", phone: "+852", flag: "\u{1F1ED}\u{1F1F0}" },
2186
+ { code: "HN", label: "Honduras", phone: "+504", flag: "\u{1F1ED}\u{1F1F3}" },
2187
+ { code: "HR", label: "Croatia", phone: "+385", flag: "\u{1F1ED}\u{1F1F7}" },
2188
+ { code: "HT", label: "Haiti", phone: "+509", flag: "\u{1F1ED}\u{1F1F9}" },
2189
+ { code: "HU", label: "Hungary", phone: "+36", flag: "\u{1F1ED}\u{1F1FA}" },
2190
+ { code: "ID", label: "Indonesia", phone: "+62", flag: "\u{1F1EE}\u{1F1E9}" },
2191
+ { code: "IE", label: "Ireland", phone: "+353", flag: "\u{1F1EE}\u{1F1EA}" },
2192
+ { code: "IL", label: "Israel", phone: "+972", flag: "\u{1F1EE}\u{1F1F1}" },
2193
+ { code: "IN", label: "India", phone: "+91", flag: "\u{1F1EE}\u{1F1F3}" },
2194
+ { code: "IQ", label: "Iraq", phone: "+964", flag: "\u{1F1EE}\u{1F1F6}" },
2195
+ { code: "IR", label: "Iran", phone: "+98", flag: "\u{1F1EE}\u{1F1F7}" },
2196
+ { code: "IS", label: "Iceland", phone: "+354", flag: "\u{1F1EE}\u{1F1F8}" },
2197
+ { code: "IT", label: "Italy", phone: "+39", flag: "\u{1F1EE}\u{1F1F9}" },
2198
+ { code: "JM", label: "Jamaica", phone: "+1-876", flag: "\u{1F1EF}\u{1F1F2}" },
2199
+ { code: "JO", label: "Jordan", phone: "+962", flag: "\u{1F1EF}\u{1F1F4}" },
2200
+ { code: "JP", label: "Japan", phone: "+81", flag: "\u{1F1EF}\u{1F1F5}" },
2201
+ { code: "KE", label: "Kenya", phone: "+254", flag: "\u{1F1F0}\u{1F1EA}" },
2202
+ { code: "KG", label: "Kyrgyzstan", phone: "+996", flag: "\u{1F1F0}\u{1F1EC}" },
2203
+ { code: "KH", label: "Cambodia", phone: "+855", flag: "\u{1F1F0}\u{1F1ED}" },
2204
+ { code: "KR", label: "South Korea", phone: "+82", flag: "\u{1F1F0}\u{1F1F7}" },
2205
+ { code: "KW", label: "Kuwait", phone: "+965", flag: "\u{1F1F0}\u{1F1FC}" },
2206
+ { code: "KZ", label: "Kazakhstan", phone: "+7", flag: "\u{1F1F0}\u{1F1FF}" },
2207
+ { code: "LA", label: "Laos", phone: "+856", flag: "\u{1F1F1}\u{1F1E6}" },
2208
+ { code: "LB", label: "Lebanon", phone: "+961", flag: "\u{1F1F1}\u{1F1E7}" },
2209
+ { code: "LK", label: "Sri Lanka", phone: "+94", flag: "\u{1F1F1}\u{1F1F0}" },
2210
+ { code: "LR", label: "Liberia", phone: "+231", flag: "\u{1F1F1}\u{1F1F7}" },
2211
+ { code: "LT", label: "Lithuania", phone: "+370", flag: "\u{1F1F1}\u{1F1F9}" },
2212
+ { code: "LU", label: "Luxembourg", phone: "+352", flag: "\u{1F1F1}\u{1F1FA}" },
2213
+ { code: "LV", label: "Latvia", phone: "+371", flag: "\u{1F1F1}\u{1F1FB}" },
2214
+ { code: "LY", label: "Libya", phone: "+218", flag: "\u{1F1F1}\u{1F1FE}" },
2215
+ { code: "MA", label: "Morocco", phone: "+212", flag: "\u{1F1F2}\u{1F1E6}" },
2216
+ { code: "MC", label: "Monaco", phone: "+377", flag: "\u{1F1F2}\u{1F1E8}" },
2217
+ { code: "MD", label: "Moldova", phone: "+373", flag: "\u{1F1F2}\u{1F1E9}" },
2218
+ { code: "ME", label: "Montenegro", phone: "+382", flag: "\u{1F1F2}\u{1F1EA}" },
2219
+ { code: "MG", label: "Madagascar", phone: "+261", flag: "\u{1F1F2}\u{1F1EC}" },
2220
+ { code: "MK", label: "North Macedonia", phone: "+389", flag: "\u{1F1F2}\u{1F1F0}" },
2221
+ { code: "ML", label: "Mali", phone: "+223", flag: "\u{1F1F2}\u{1F1F1}" },
2222
+ { code: "MM", label: "Myanmar", phone: "+95", flag: "\u{1F1F2}\u{1F1F2}" },
2223
+ { code: "MN", label: "Mongolia", phone: "+976", flag: "\u{1F1F2}\u{1F1F3}" },
2224
+ { code: "MO", label: "Macau", phone: "+853", flag: "\u{1F1F2}\u{1F1F4}" },
2225
+ { code: "MT", label: "Malta", phone: "+356", flag: "\u{1F1F2}\u{1F1F9}" },
2226
+ { code: "MU", label: "Mauritius", phone: "+230", flag: "\u{1F1F2}\u{1F1FA}" },
2227
+ { code: "MV", label: "Maldives", phone: "+960", flag: "\u{1F1F2}\u{1F1FB}" },
2228
+ { code: "MW", label: "Malawi", phone: "+265", flag: "\u{1F1F2}\u{1F1FC}" },
2229
+ { code: "MX", label: "Mexico", phone: "+52", flag: "\u{1F1F2}\u{1F1FD}" },
2230
+ { code: "MY", label: "Malaysia", phone: "+60", flag: "\u{1F1F2}\u{1F1FE}" },
2231
+ { code: "MZ", label: "Mozambique", phone: "+258", flag: "\u{1F1F2}\u{1F1FF}" },
2232
+ { code: "NA", label: "Namibia", phone: "+264", flag: "\u{1F1F3}\u{1F1E6}" },
2233
+ { code: "NE", label: "Niger", phone: "+227", flag: "\u{1F1F3}\u{1F1EA}" },
2234
+ { code: "NG", label: "Nigeria", phone: "+234", flag: "\u{1F1F3}\u{1F1EC}" },
2235
+ { code: "NI", label: "Nicaragua", phone: "+505", flag: "\u{1F1F3}\u{1F1EE}" },
2236
+ { code: "NL", label: "Netherlands", phone: "+31", flag: "\u{1F1F3}\u{1F1F1}" },
2237
+ { code: "NO", label: "Norway", phone: "+47", flag: "\u{1F1F3}\u{1F1F4}" },
2238
+ { code: "NP", label: "Nepal", phone: "+977", flag: "\u{1F1F3}\u{1F1F5}" },
2239
+ { code: "NZ", label: "New Zealand", phone: "+64", flag: "\u{1F1F3}\u{1F1FF}" },
2240
+ { code: "OM", label: "Oman", phone: "+968", flag: "\u{1F1F4}\u{1F1F2}" },
2241
+ { code: "PA", label: "Panama", phone: "+507", flag: "\u{1F1F5}\u{1F1E6}" },
2242
+ { code: "PE", label: "Peru", phone: "+51", flag: "\u{1F1F5}\u{1F1EA}" },
2243
+ { code: "PG", label: "Papua New Guinea", phone: "+675", flag: "\u{1F1F5}\u{1F1EC}" },
2244
+ { code: "PH", label: "Philippines", phone: "+63", flag: "\u{1F1F5}\u{1F1ED}" },
2245
+ { code: "PK", label: "Pakistan", phone: "+92", flag: "\u{1F1F5}\u{1F1F0}" },
2246
+ { code: "PL", label: "Poland", phone: "+48", flag: "\u{1F1F5}\u{1F1F1}" },
2247
+ { code: "PT", label: "Portugal", phone: "+351", flag: "\u{1F1F5}\u{1F1F9}" },
2248
+ { code: "PY", label: "Paraguay", phone: "+595", flag: "\u{1F1F5}\u{1F1FE}" },
2249
+ { code: "QA", label: "Qatar", phone: "+974", flag: "\u{1F1F6}\u{1F1E6}" },
2250
+ { code: "RO", label: "Romania", phone: "+40", flag: "\u{1F1F7}\u{1F1F4}" },
2251
+ { code: "RS", label: "Serbia", phone: "+381", flag: "\u{1F1F7}\u{1F1F8}" },
2252
+ { code: "RU", label: "Russia", phone: "+7", flag: "\u{1F1F7}\u{1F1FA}" },
2253
+ { code: "RW", label: "Rwanda", phone: "+250", flag: "\u{1F1F7}\u{1F1FC}" },
2254
+ { code: "SA", label: "Saudi Arabia", phone: "+966", flag: "\u{1F1F8}\u{1F1E6}" },
2255
+ { code: "SD", label: "Sudan", phone: "+249", flag: "\u{1F1F8}\u{1F1E9}" },
2256
+ { code: "SE", label: "Sweden", phone: "+46", flag: "\u{1F1F8}\u{1F1EA}" },
2257
+ { code: "SG", label: "Singapore", phone: "+65", flag: "\u{1F1F8}\u{1F1EC}" },
2258
+ { code: "SI", label: "Slovenia", phone: "+386", flag: "\u{1F1F8}\u{1F1EE}" },
2259
+ { code: "SK", label: "Slovakia", phone: "+421", flag: "\u{1F1F8}\u{1F1F0}" },
2260
+ { code: "SL", label: "Sierra Leone", phone: "+232", flag: "\u{1F1F8}\u{1F1F1}" },
2261
+ { code: "SN", label: "Senegal", phone: "+221", flag: "\u{1F1F8}\u{1F1F3}" },
2262
+ { code: "SO", label: "Somalia", phone: "+252", flag: "\u{1F1F8}\u{1F1F4}" },
2263
+ { code: "SR", label: "Suriname", phone: "+597", flag: "\u{1F1F8}\u{1F1F7}" },
2264
+ { code: "SV", label: "El Salvador", phone: "+503", flag: "\u{1F1F8}\u{1F1FB}" },
2265
+ { code: "SY", label: "Syria", phone: "+963", flag: "\u{1F1F8}\u{1F1FE}" },
2266
+ { code: "TH", label: "Thailand", phone: "+66", flag: "\u{1F1F9}\u{1F1ED}" },
2267
+ { code: "TJ", label: "Tajikistan", phone: "+992", flag: "\u{1F1F9}\u{1F1EF}" },
2268
+ { code: "TM", label: "Turkmenistan", phone: "+993", flag: "\u{1F1F9}\u{1F1F2}" },
2269
+ { code: "TN", label: "Tunisia", phone: "+216", flag: "\u{1F1F9}\u{1F1F3}" },
2270
+ { code: "TR", label: "Turkey", phone: "+90", flag: "\u{1F1F9}\u{1F1F7}" },
2271
+ { code: "TT", label: "Trinidad and Tobago", phone: "+1-868", flag: "\u{1F1F9}\u{1F1F9}" },
2272
+ { code: "TW", label: "Taiwan", phone: "+886", flag: "\u{1F1F9}\u{1F1FC}" },
2273
+ { code: "TZ", label: "Tanzania", phone: "+255", flag: "\u{1F1F9}\u{1F1FF}" },
2274
+ { code: "UA", label: "Ukraine", phone: "+380", flag: "\u{1F1FA}\u{1F1E6}" },
2275
+ { code: "UG", label: "Uganda", phone: "+256", flag: "\u{1F1FA}\u{1F1EC}" },
2276
+ { code: "US", label: "United States", phone: "+1", flag: "\u{1F1FA}\u{1F1F8}" },
2277
+ { code: "UY", label: "Uruguay", phone: "+598", flag: "\u{1F1FA}\u{1F1FE}" },
2278
+ { code: "UZ", label: "Uzbekistan", phone: "+998", flag: "\u{1F1FA}\u{1F1FF}" },
2279
+ { code: "VE", label: "Venezuela", phone: "+58", flag: "\u{1F1FB}\u{1F1EA}" },
2280
+ { code: "VN", label: "Vietnam", phone: "+84", flag: "\u{1F1FB}\u{1F1F3}" },
2281
+ { code: "YE", label: "Yemen", phone: "+967", flag: "\u{1F1FE}\u{1F1EA}" },
2282
+ { code: "ZA", label: "South Africa", phone: "+27", flag: "\u{1F1FF}\u{1F1E6}" },
2283
+ { code: "ZM", label: "Zambia", phone: "+260", flag: "\u{1F1FF}\u{1F1F2}" },
2284
+ { code: "ZW", label: "Zimbabwe", phone: "+263", flag: "\u{1F1FF}\u{1F1FC}" }
2285
+ ];
2286
+ function FieldCountrySelect({
2287
+ name,
2288
+ label,
2289
+ placeholder,
2290
+ helperText,
2291
+ getValue = "full",
2292
+ countries: customCountries,
2293
+ textFieldProps,
2294
+ multiple,
2295
+ disabled,
2296
+ ...other
2297
+ }) {
2298
+ const { control } = useFormContext();
2299
+ const countries = customCountries ?? DEFAULT_COUNTRIES2;
2300
+ const countryMap = useMemo(() => {
2301
+ const byCode = /* @__PURE__ */ new Map();
2302
+ const byLabel = /* @__PURE__ */ new Map();
2303
+ for (const country of countries) {
2304
+ byCode.set(country.code, country);
2305
+ byLabel.set(country.label, country);
2306
+ }
2307
+ return { byCode, byLabel };
2308
+ }, [countries]);
2309
+ const findCountry = (v) => {
2310
+ if (v === null || v === void 0) return null;
2311
+ if (typeof v === "object" && v !== null && "code" in v) {
2312
+ return v;
2313
+ }
2314
+ if (typeof v === "string") {
2315
+ return countryMap.byCode.get(v) ?? countryMap.byLabel.get(v) ?? null;
2316
+ }
2317
+ return null;
2318
+ };
2319
+ const valueToCountry = (value) => {
2320
+ if (value === null || value === void 0) {
2321
+ return multiple ? [] : null;
2322
+ }
2323
+ if (multiple) {
2324
+ const values = Array.isArray(value) ? value : [value];
2325
+ return values.map(findCountry).filter((c) => c !== null);
2326
+ }
2327
+ return findCountry(value);
2328
+ };
2329
+ const countryToValue = (country) => {
2330
+ if (country === null) {
2331
+ return multiple ? [] : null;
2332
+ }
2333
+ if (multiple && Array.isArray(country)) {
2334
+ if (getValue === "code") return country.map((c) => c.code);
2335
+ if (getValue === "label") return country.map((c) => c.label);
2336
+ return country;
2337
+ }
2338
+ if (!Array.isArray(country)) {
2339
+ if (getValue === "code") return country.code;
2340
+ if (getValue === "label") return country.label;
2341
+ return country;
2342
+ }
2343
+ return null;
2344
+ };
2345
+ return /* @__PURE__ */ jsx(
2346
+ Controller,
2347
+ {
2348
+ name,
2349
+ control,
2350
+ render: ({ field, fieldState: { error } }) => {
2351
+ const currentValue = valueToCountry(field.value);
2352
+ return /* @__PURE__ */ jsx(
2353
+ Autocomplete,
2354
+ {
2355
+ ...other,
2356
+ multiple,
2357
+ disabled,
2358
+ options: countries,
2359
+ value: currentValue,
2360
+ onChange: (_event, newValue) => {
2361
+ field.onChange(countryToValue(newValue));
2362
+ },
2363
+ getOptionLabel: (option) => option.label,
2364
+ isOptionEqualToValue: (option, value) => option.code === value.code,
2365
+ renderOption: (props, option) => {
2366
+ const { key, ...optionProps } = props;
2367
+ return /* @__PURE__ */ jsxs(Box7, { component: "li", sx: { "& > span": { mr: 1.5, flexShrink: 0 } }, ...optionProps, children: [
2368
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "1.25rem" }, children: option.flag }),
2369
+ option.label,
2370
+ " (",
2371
+ option.code,
2372
+ ")"
2373
+ ] }, key);
2374
+ },
2375
+ renderInput: (params) => /* @__PURE__ */ jsx(
2376
+ TextField,
2377
+ {
2378
+ ...params,
2379
+ ...textFieldProps,
2380
+ label,
2381
+ placeholder,
2382
+ error: !!error,
2383
+ helperText: error?.message ?? helperText,
2384
+ slotProps: {
2385
+ ...textFieldProps?.slotProps,
2386
+ htmlInput: {
2387
+ ...params.inputProps,
2388
+ autoComplete: "country-name"
2389
+ }
2390
+ }
2391
+ }
2392
+ )
2393
+ }
2394
+ );
2395
+ }
2396
+ }
2397
+ );
2398
+ }
2399
+ var DEFAULT_EDITOR_TOOLBAR = {
2400
+ bold: true,
2401
+ italic: true,
2402
+ underline: true,
2403
+ headings: [1, 2, 3],
2404
+ bulletList: true,
2405
+ orderedList: true,
2406
+ link: true,
2407
+ history: true
2408
+ };
2409
+ function BasicEditor({
2410
+ value,
2411
+ onChange,
2412
+ onBlur,
2413
+ error,
2414
+ name,
2415
+ disabled,
2416
+ readOnly,
2417
+ placeholder,
2418
+ minHeight = 200,
2419
+ maxHeight,
2420
+ "aria-label": ariaLabel,
2421
+ "aria-describedby": ariaDescribedBy
2422
+ }) {
2423
+ return /* @__PURE__ */ jsx(
2424
+ TextField,
2425
+ {
2426
+ multiline: true,
2427
+ fullWidth: true,
2428
+ minRows: 6,
2429
+ maxRows: maxHeight ? 20 : void 0,
2430
+ value,
2431
+ onChange: (e) => onChange(e.target.value),
2432
+ onBlur,
2433
+ error,
2434
+ disabled,
2435
+ slotProps: {
2436
+ input: {
2437
+ readOnly
2438
+ },
2439
+ htmlInput: {
2440
+ "aria-label": ariaLabel || name,
2441
+ "aria-describedby": ariaDescribedBy
2442
+ }
2443
+ },
2444
+ placeholder,
2445
+ sx: {
2446
+ "& .MuiOutlinedInput-root": {
2447
+ minHeight,
2448
+ maxHeight,
2449
+ alignItems: "flex-start"
2450
+ },
2451
+ "& .MuiInputBase-input": {
2452
+ resize: "vertical"
2453
+ }
2454
+ }
2455
+ }
2456
+ );
2457
+ }
2458
+ function FieldEditor({
2459
+ name,
2460
+ label,
2461
+ helperText,
2462
+ rules,
2463
+ placeholder,
2464
+ disabled,
2465
+ readOnly,
2466
+ toolbar = DEFAULT_EDITOR_TOOLBAR,
2467
+ minHeight = 200,
2468
+ maxHeight,
2469
+ required,
2470
+ fullWidth = true,
2471
+ renderEditor,
2472
+ sx,
2473
+ "aria-label": ariaLabel
2474
+ }) {
2475
+ const { control } = useFormContext();
2476
+ const errorId = `${name}-error`;
2477
+ const helperId = `${name}-helper`;
2478
+ const describedBy = [helperText ? helperId : null, errorId].filter(Boolean).join(" ") || void 0;
2479
+ return /* @__PURE__ */ jsx(
2480
+ Controller,
2481
+ {
2482
+ name,
2483
+ control,
2484
+ rules,
2485
+ render: ({ field, fieldState: { error } }) => /* @__PURE__ */ jsxs(FormControl8, { fullWidth, error: !!error, disabled, required, sx, children: [
2486
+ label && /* @__PURE__ */ jsx(FormLabel6, { htmlFor: name, sx: { mb: 1, fontWeight: 500 }, children: label }),
2487
+ renderEditor ? (
2488
+ // Custom editor implementation
2489
+ renderEditor({
2490
+ value: field.value ?? "",
2491
+ onChange: field.onChange,
2492
+ onBlur: field.onBlur,
2493
+ error: !!error,
2494
+ name,
2495
+ disabled,
2496
+ readOnly,
2497
+ placeholder,
2498
+ toolbar,
2499
+ minHeight,
2500
+ maxHeight,
2501
+ "aria-label": ariaLabel || label || name,
2502
+ "aria-describedby": describedBy
2503
+ })
2504
+ ) : (
2505
+ // Basic textarea fallback
2506
+ /* @__PURE__ */ jsx(
2507
+ BasicEditor,
2508
+ {
2509
+ value: field.value ?? "",
2510
+ onChange: field.onChange,
2511
+ onBlur: field.onBlur,
2512
+ error: !!error,
2513
+ name,
2514
+ disabled,
2515
+ readOnly,
2516
+ placeholder,
2517
+ toolbar,
2518
+ minHeight,
2519
+ maxHeight,
2520
+ "aria-label": ariaLabel || label || name,
2521
+ "aria-describedby": describedBy
2522
+ }
2523
+ )
2524
+ ),
2525
+ (error?.message || helperText) && /* @__PURE__ */ jsx(FormHelperText9, { id: error ? errorId : helperId, error: !!error, children: error?.message ?? helperText })
2526
+ ] })
2527
+ }
2528
+ );
2529
+ }
2530
+ function FieldCustomEditor({
2531
+ name,
2532
+ label,
2533
+ helperText,
2534
+ rules,
2535
+ required,
2536
+ fullWidth = true,
2537
+ disabled,
2538
+ sx,
2539
+ children
2540
+ }) {
2541
+ const { control } = useFormContext();
2542
+ const errorId = `${name}-error`;
2543
+ return /* @__PURE__ */ jsx(
2544
+ Controller,
2545
+ {
2546
+ name,
2547
+ control,
2548
+ rules,
2549
+ render: ({ field, fieldState: { error } }) => /* @__PURE__ */ jsxs(FormControl8, { fullWidth, error: !!error, disabled, required, sx, children: [
2550
+ label && /* @__PURE__ */ jsx(FormLabel6, { htmlFor: name, sx: { mb: 1, fontWeight: 500 }, children: label }),
2551
+ children({
2552
+ value: field.value ?? "",
2553
+ onChange: field.onChange,
2554
+ onBlur: field.onBlur,
2555
+ error: !!error,
2556
+ errorMessage: error?.message,
2557
+ name,
2558
+ disabled
2559
+ }),
2560
+ (error?.message || helperText) && /* @__PURE__ */ jsx(FormHelperText9, { id: errorId, error: !!error, children: error?.message ?? helperText })
2561
+ ] })
2562
+ }
2563
+ );
2564
+ }
2565
+
2566
+ // src/components/field/index.ts
2567
+ var Field = {
2568
+ // Base fields
2569
+ /** Text input field */
2570
+ Text: FieldText,
2571
+ /** Select dropdown field */
2572
+ Select: FieldSelect,
2573
+ /** Checkbox field */
2574
+ Checkbox: FieldCheckbox,
2575
+ /** Switch toggle field */
2576
+ Switch: FieldSwitch,
2577
+ /** Number input field */
2578
+ Number: FieldNumber,
2579
+ /** Radio button group field */
2580
+ Radio: FieldRadio,
2581
+ /** Autocomplete with search field */
2582
+ Autocomplete: FieldAutocomplete,
2583
+ /** Multiple selection with chips field */
2584
+ MultiSelect: FieldMultiSelect,
2585
+ /** Star rating field */
2586
+ Rating: FieldRating,
2587
+ /** Range slider field */
2588
+ Slider: FieldSlider,
2589
+ /** Date picker field (MUI X) */
2590
+ DatePicker: FieldDatePicker,
2591
+ // New fields (v0.4.0)
2592
+ /** Time picker field (MUI X) */
2593
+ TimePicker: FieldTimePicker,
2594
+ /** Combined date-time picker field (MUI X) */
2595
+ DateTimePicker: FieldDateTimePicker,
2596
+ /** Multiple checkbox group field */
2597
+ MultiCheckbox: FieldMultiCheckbox,
2598
+ /** Multiple switch group field */
2599
+ MultiSwitch: FieldMultiSwitch,
2600
+ /** OTP/PIN code input field */
2601
+ Code: FieldCode,
2602
+ /** File upload with dropzone */
2603
+ Upload: FieldUpload,
2604
+ /** Compact file upload box */
2605
+ UploadBox: FieldUploadBox,
2606
+ /** Circular avatar upload */
2607
+ UploadAvatar: FieldUploadAvatar,
2608
+ /** International phone input */
2609
+ Phone: FieldPhone,
2610
+ /** Country selector with flags */
2611
+ CountrySelect: FieldCountrySelect,
2612
+ // Editor fields (v0.4.0)
2613
+ /** Rich text editor (with textarea fallback or custom editor) */
2614
+ Editor: FieldEditor,
2615
+ /** Headless editor field with render prop */
2616
+ CustomEditor: FieldCustomEditor
2617
+ };
2618
+
2619
+ export { Field, FieldAutocomplete, FieldCheckbox, FieldCode, FieldCountrySelect, FieldCustomEditor, FieldDatePicker, FieldDateTimePicker, FieldEditor, FieldMultiCheckbox, FieldMultiSelect, FieldMultiSwitch, FieldNumber, FieldPhone, FieldRadio, FieldRating, FieldSelect, FieldSlider, FieldSwitch, FieldText, FieldTimePicker, FieldUpload, FieldUploadAvatar, FieldUploadBox, SearchInput, clampNumber, createNumberInputHandlers, parseNumber, roundToDecimals, transformForDisplay, transformOnBlur, transformOnChange };
2620
+ //# sourceMappingURL=chunk-LAEY5USO.js.map
2621
+ //# sourceMappingURL=chunk-LAEY5USO.js.map