@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,709 @@
1
+ import { createField, FieldWrapper, FieldLabel, FieldError, getFieldErrors, useResolvedFieldProps } from './chunk-XFWLD5EO.js';
2
+ import { Input, Field, Flex, HStack, Box, Menu, Button, Portal, NumberInput, Text, Stack } from '@chakra-ui/react';
3
+ import { jsx, jsxs } from 'react/jsx-runtime';
4
+ import { LuCalendar, LuChevronDown } from 'react-icons/lu';
5
+ import { memo, useMemo, useCallback } from 'react';
6
+
7
+ var FieldDate = createField({
8
+ displayName: "FieldDate",
9
+ render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps }) => {
10
+ const { constraints } = resolved;
11
+ const rawValue = field.state.value;
12
+ let stringValue = "";
13
+ if (rawValue instanceof Date) {
14
+ stringValue = rawValue.toISOString().split("T")[0];
15
+ } else if (typeof rawValue === "string") {
16
+ stringValue = rawValue;
17
+ }
18
+ const min = componentProps.min ?? constraints.date?.min;
19
+ const max = componentProps.max ?? constraints.date?.max;
20
+ return /* @__PURE__ */ jsx(FieldWrapper, { resolved, hasError, errorMessage, fullPath, children: /* @__PURE__ */ jsx(
21
+ Input,
22
+ {
23
+ type: "date",
24
+ value: stringValue,
25
+ onChange: (e) => field.handleChange(e.target.value),
26
+ onBlur: field.handleBlur,
27
+ placeholder: resolved.placeholder,
28
+ min,
29
+ max,
30
+ "data-field-name": fullPath
31
+ }
32
+ ) });
33
+ }
34
+ });
35
+ function getPresetRange(preset) {
36
+ const today = /* @__PURE__ */ new Date();
37
+ const formatDate = (d) => d.toISOString().split("T")[0];
38
+ switch (preset) {
39
+ case "today":
40
+ return { start: formatDate(today), end: formatDate(today) };
41
+ case "yesterday": {
42
+ const yesterday = new Date(today);
43
+ yesterday.setDate(today.getDate() - 1);
44
+ return { start: formatDate(yesterday), end: formatDate(yesterday) };
45
+ }
46
+ case "thisWeek": {
47
+ const startOfWeek = new Date(today);
48
+ startOfWeek.setDate(today.getDate() - today.getDay() + 1);
49
+ const endOfWeek = new Date(startOfWeek);
50
+ endOfWeek.setDate(startOfWeek.getDate() + 6);
51
+ return { start: formatDate(startOfWeek), end: formatDate(endOfWeek) };
52
+ }
53
+ case "lastWeek": {
54
+ const startOfLastWeek = new Date(today);
55
+ startOfLastWeek.setDate(today.getDate() - today.getDay() - 6);
56
+ const endOfLastWeek = new Date(startOfLastWeek);
57
+ endOfLastWeek.setDate(startOfLastWeek.getDate() + 6);
58
+ return { start: formatDate(startOfLastWeek), end: formatDate(endOfLastWeek) };
59
+ }
60
+ case "thisMonth": {
61
+ const startOfMonth = new Date(today.getFullYear(), today.getMonth(), 1);
62
+ const endOfMonth = new Date(today.getFullYear(), today.getMonth() + 1, 0);
63
+ return { start: formatDate(startOfMonth), end: formatDate(endOfMonth) };
64
+ }
65
+ case "lastMonth": {
66
+ const startOfLastMonth = new Date(today.getFullYear(), today.getMonth() - 1, 1);
67
+ const endOfLastMonth = new Date(today.getFullYear(), today.getMonth(), 0);
68
+ return { start: formatDate(startOfLastMonth), end: formatDate(endOfLastMonth) };
69
+ }
70
+ case "thisYear": {
71
+ const startOfYear = new Date(today.getFullYear(), 0, 1);
72
+ const endOfYear = new Date(today.getFullYear(), 11, 31);
73
+ return { start: formatDate(startOfYear), end: formatDate(endOfYear) };
74
+ }
75
+ }
76
+ }
77
+ function getPresetLabel(preset) {
78
+ switch (preset) {
79
+ case "today":
80
+ return "Today";
81
+ case "yesterday":
82
+ return "Yesterday";
83
+ case "thisWeek":
84
+ return "This week";
85
+ case "lastWeek":
86
+ return "Last week";
87
+ case "thisMonth":
88
+ return "This month";
89
+ case "lastMonth":
90
+ return "Last month";
91
+ case "thisYear":
92
+ return "This year";
93
+ }
94
+ }
95
+ var FieldDateRange = createField({
96
+ displayName: "FieldDateRange",
97
+ render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps }) => {
98
+ const {
99
+ startLabel = "Start",
100
+ endLabel = "End",
101
+ startPlaceholder,
102
+ endPlaceholder,
103
+ min,
104
+ max,
105
+ presets,
106
+ orientation = "horizontal",
107
+ size = "md"
108
+ } = componentProps;
109
+ const value = field.state.value ?? { start: "", end: "" };
110
+ const handleStartChange = (newStart) => {
111
+ field.handleChange({ ...value, start: newStart });
112
+ };
113
+ const handleEndChange = (newEnd) => {
114
+ field.handleChange({ ...value, end: newEnd });
115
+ };
116
+ const handlePreset = (preset) => {
117
+ field.handleChange(getPresetRange(preset));
118
+ };
119
+ const Container = orientation === "horizontal" ? HStack : Box;
120
+ return /* @__PURE__ */ jsxs(
121
+ Field.Root,
122
+ {
123
+ invalid: hasError,
124
+ required: resolved.required,
125
+ disabled: resolved.disabled,
126
+ readOnly: resolved.readOnly,
127
+ children: [
128
+ /* @__PURE__ */ jsx(FieldLabel, { label: resolved.label, tooltip: resolved.tooltip, required: resolved.required }),
129
+ /* @__PURE__ */ jsxs(Flex, { gap: 2, direction: orientation === "horizontal" ? "row" : "column", align: "stretch", width: "full", children: [
130
+ /* @__PURE__ */ jsxs(Container, { gap: 2, flex: 1, alignItems: "flex-end", children: [
131
+ /* @__PURE__ */ jsx(Box, { flex: 1, children: /* @__PURE__ */ jsxs(Field.Root, { disabled: resolved.disabled, readOnly: resolved.readOnly, children: [
132
+ /* @__PURE__ */ jsx(Field.Label, { fontSize: "sm", color: "fg.muted", children: startLabel }),
133
+ /* @__PURE__ */ jsx(
134
+ Input,
135
+ {
136
+ type: "date",
137
+ value: value.start,
138
+ onChange: (e) => handleStartChange(e.target.value),
139
+ onBlur: field.handleBlur,
140
+ placeholder: startPlaceholder,
141
+ min,
142
+ max: value.end || max,
143
+ size,
144
+ "data-field-name": `${fullPath}.start`
145
+ }
146
+ )
147
+ ] }) }),
148
+ /* @__PURE__ */ jsx(Box, { flex: 1, children: /* @__PURE__ */ jsxs(Field.Root, { disabled: resolved.disabled, readOnly: resolved.readOnly, children: [
149
+ /* @__PURE__ */ jsx(Field.Label, { fontSize: "sm", color: "fg.muted", children: endLabel }),
150
+ /* @__PURE__ */ jsx(
151
+ Input,
152
+ {
153
+ type: "date",
154
+ value: value.end,
155
+ onChange: (e) => handleEndChange(e.target.value),
156
+ onBlur: field.handleBlur,
157
+ placeholder: endPlaceholder,
158
+ min: value.start || min,
159
+ max,
160
+ size,
161
+ "data-field-name": `${fullPath}.end`
162
+ }
163
+ )
164
+ ] }) })
165
+ ] }),
166
+ presets && presets.length > 0 && !resolved.readOnly && /* @__PURE__ */ jsxs(Menu.Root, { children: [
167
+ /* @__PURE__ */ jsx(Menu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { variant: "outline", size, disabled: resolved.disabled, children: [
168
+ /* @__PURE__ */ jsx(LuCalendar, {}),
169
+ "Presets",
170
+ /* @__PURE__ */ jsx(LuChevronDown, {})
171
+ ] }) }),
172
+ /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(Menu.Positioner, { children: /* @__PURE__ */ jsx(Menu.Content, { children: presets.map((preset) => /* @__PURE__ */ jsx(Menu.Item, { value: preset, onClick: () => handlePreset(preset), children: getPresetLabel(preset) }, preset)) }) }) })
173
+ ] })
174
+ ] }),
175
+ /* @__PURE__ */ jsx(FieldError, { hasError, errorMessage, helperText: resolved.helperText })
176
+ ]
177
+ }
178
+ );
179
+ }
180
+ });
181
+ function parseDateTime(value) {
182
+ if (!value) {
183
+ return { date: "", time: "" };
184
+ }
185
+ const match = value.match(/^(\d{4}-\d{2}-\d{2})(?:T(\d{2}:\d{2}))?/);
186
+ if (match) {
187
+ return { date: match[1], time: match[2] || "" };
188
+ }
189
+ return { date: "", time: "" };
190
+ }
191
+ function combineDateTime(date, time) {
192
+ if (!date) {
193
+ return "";
194
+ }
195
+ if (!time) {
196
+ return date;
197
+ }
198
+ return `${date}T${time}:00`;
199
+ }
200
+ var FieldDateTimePicker = createField({
201
+ displayName: "FieldDateTimePicker",
202
+ render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps }) => {
203
+ const { minDateTime, maxDateTime, timeStep = 15 } = componentProps;
204
+ const minDateTimeStr = minDateTime instanceof Date ? minDateTime.toISOString().slice(0, 16) : minDateTime?.slice(0, 16);
205
+ const maxDateTimeStr = maxDateTime instanceof Date ? maxDateTime.toISOString().slice(0, 16) : maxDateTime?.slice(0, 16);
206
+ const minDate = minDateTimeStr?.slice(0, 10);
207
+ const maxDate = maxDateTimeStr?.slice(0, 10);
208
+ const value = field.state.value;
209
+ const { date, time } = parseDateTime(value);
210
+ const handleDateChange = (newDate) => {
211
+ const combined = combineDateTime(newDate, time);
212
+ field.handleChange(combined || void 0);
213
+ };
214
+ const handleTimeChange = (newTime) => {
215
+ const combined = combineDateTime(date, newTime);
216
+ field.handleChange(combined || void 0);
217
+ };
218
+ return /* @__PURE__ */ jsxs(
219
+ Field.Root,
220
+ {
221
+ invalid: hasError,
222
+ required: resolved.required,
223
+ disabled: resolved.disabled,
224
+ readOnly: resolved.readOnly,
225
+ children: [
226
+ /* @__PURE__ */ jsx(FieldLabel, { label: resolved.label, tooltip: resolved.tooltip, required: resolved.required }),
227
+ /* @__PURE__ */ jsxs(HStack, { gap: 2, children: [
228
+ /* @__PURE__ */ jsx(
229
+ Input,
230
+ {
231
+ type: "date",
232
+ value: date,
233
+ onChange: (e) => handleDateChange(e.target.value),
234
+ onBlur: field.handleBlur,
235
+ min: minDate,
236
+ max: maxDate,
237
+ "data-field-name": `${fullPath}-date`,
238
+ flex: 1
239
+ }
240
+ ),
241
+ /* @__PURE__ */ jsx(
242
+ Input,
243
+ {
244
+ type: "time",
245
+ value: time,
246
+ onChange: (e) => handleTimeChange(e.target.value),
247
+ onBlur: field.handleBlur,
248
+ step: timeStep * 60,
249
+ "data-field-name": `${fullPath}-time`,
250
+ width: "150px"
251
+ }
252
+ )
253
+ ] }),
254
+ /* @__PURE__ */ jsx(FieldError, { hasError, errorMessage, helperText: resolved.helperText })
255
+ ]
256
+ }
257
+ );
258
+ }
259
+ });
260
+ function minutesToHHMM(minutes) {
261
+ return {
262
+ hours: Math.floor(minutes / 60),
263
+ mins: minutes % 60
264
+ };
265
+ }
266
+ function hhmmToMinutes(hours, mins) {
267
+ return hours * 60 + mins;
268
+ }
269
+ var FieldDuration = createField({
270
+ displayName: "FieldDuration",
271
+ render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps }) => {
272
+ const { format = "HH:MM", min = 0, max = 1440, step = 15 } = componentProps;
273
+ const value = field.state.value ?? 0;
274
+ const { hours, mins } = minutesToHHMM(value);
275
+ const handleHoursChange = (newHours) => {
276
+ const newValue = hhmmToMinutes(newHours, mins);
277
+ const clampedValue = Math.max(min, Math.min(max, newValue));
278
+ field.handleChange(clampedValue);
279
+ };
280
+ const handleMinsChange = (newMins) => {
281
+ const newValue = hhmmToMinutes(hours, newMins);
282
+ const clampedValue = Math.max(min, Math.min(max, newValue));
283
+ field.handleChange(clampedValue);
284
+ };
285
+ const handleMinutesChange = (newValue) => {
286
+ const clampedValue = Math.max(min, Math.min(max, newValue));
287
+ field.handleChange(clampedValue);
288
+ };
289
+ if (format === "minutes") {
290
+ return /* @__PURE__ */ jsxs(
291
+ Field.Root,
292
+ {
293
+ invalid: hasError,
294
+ required: resolved.required,
295
+ disabled: resolved.disabled,
296
+ readOnly: resolved.readOnly,
297
+ children: [
298
+ /* @__PURE__ */ jsx(FieldLabel, { label: resolved.label, tooltip: resolved.tooltip, required: resolved.required }),
299
+ /* @__PURE__ */ jsxs(
300
+ NumberInput.Root,
301
+ {
302
+ value: value.toString(),
303
+ onValueChange: (details) => {
304
+ const num = details.valueAsNumber;
305
+ if (!Number.isNaN(num)) {
306
+ handleMinutesChange(num);
307
+ }
308
+ },
309
+ onBlur: field.handleBlur,
310
+ min,
311
+ max,
312
+ step,
313
+ children: [
314
+ /* @__PURE__ */ jsxs(NumberInput.Control, { children: [
315
+ /* @__PURE__ */ jsx(NumberInput.IncrementTrigger, {}),
316
+ /* @__PURE__ */ jsx(NumberInput.DecrementTrigger, {})
317
+ ] }),
318
+ /* @__PURE__ */ jsx(NumberInput.Input, { placeholder: resolved.placeholder ?? "min", "data-field-name": fullPath })
319
+ ]
320
+ }
321
+ ),
322
+ /* @__PURE__ */ jsx(FieldError, { hasError, errorMessage, helperText: resolved.helperText })
323
+ ]
324
+ }
325
+ );
326
+ }
327
+ return /* @__PURE__ */ jsxs(
328
+ Field.Root,
329
+ {
330
+ invalid: hasError,
331
+ required: resolved.required,
332
+ disabled: resolved.disabled,
333
+ readOnly: resolved.readOnly,
334
+ children: [
335
+ /* @__PURE__ */ jsx(FieldLabel, { label: resolved.label, tooltip: resolved.tooltip, required: resolved.required }),
336
+ /* @__PURE__ */ jsxs(HStack, { gap: 2, children: [
337
+ /* @__PURE__ */ jsxs(
338
+ NumberInput.Root,
339
+ {
340
+ value: hours.toString(),
341
+ onValueChange: (details) => {
342
+ const num = details.valueAsNumber;
343
+ if (!Number.isNaN(num)) {
344
+ handleHoursChange(num);
345
+ }
346
+ },
347
+ onBlur: field.handleBlur,
348
+ min: 0,
349
+ max: Math.floor(max / 60),
350
+ width: "80px",
351
+ children: [
352
+ /* @__PURE__ */ jsxs(NumberInput.Control, { children: [
353
+ /* @__PURE__ */ jsx(NumberInput.IncrementTrigger, {}),
354
+ /* @__PURE__ */ jsx(NumberInput.DecrementTrigger, {})
355
+ ] }),
356
+ /* @__PURE__ */ jsx(NumberInput.Input, { "data-field-name": `${fullPath}-hours` })
357
+ ]
358
+ }
359
+ ),
360
+ /* @__PURE__ */ jsx(Text, { fontWeight: "bold", children: ":" }),
361
+ /* @__PURE__ */ jsxs(
362
+ NumberInput.Root,
363
+ {
364
+ value: mins.toString().padStart(2, "0"),
365
+ onValueChange: (details) => {
366
+ const num = details.valueAsNumber;
367
+ if (!Number.isNaN(num)) {
368
+ handleMinsChange(num);
369
+ }
370
+ },
371
+ onBlur: field.handleBlur,
372
+ min: 0,
373
+ max: 59,
374
+ step,
375
+ width: "80px",
376
+ children: [
377
+ /* @__PURE__ */ jsxs(NumberInput.Control, { children: [
378
+ /* @__PURE__ */ jsx(NumberInput.IncrementTrigger, {}),
379
+ /* @__PURE__ */ jsx(NumberInput.DecrementTrigger, {})
380
+ ] }),
381
+ /* @__PURE__ */ jsx(NumberInput.Input, { "data-field-name": `${fullPath}-mins` })
382
+ ]
383
+ }
384
+ )
385
+ ] }),
386
+ /* @__PURE__ */ jsx(FieldError, { hasError, errorMessage, helperText: resolved.helperText })
387
+ ]
388
+ }
389
+ );
390
+ }
391
+ });
392
+ var DAYS_OF_WEEK = ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"];
393
+ var DEFAULT_DAY_NAMES = {
394
+ monday: "Monday",
395
+ tuesday: "Tuesday",
396
+ wednesday: "Wednesday",
397
+ thursday: "Thursday",
398
+ friday: "Friday",
399
+ saturday: "Saturday",
400
+ sunday: "Sunday"
401
+ };
402
+ var DEFAULT_WORKING_HOURS = {
403
+ monday: { open: "09:00", close: "18:00" },
404
+ tuesday: { open: "09:00", close: "18:00" },
405
+ wednesday: { open: "09:00", close: "18:00" },
406
+ thursday: { open: "09:00", close: "18:00" },
407
+ friday: { open: "09:00", close: "18:00" },
408
+ saturday: null,
409
+ sunday: null
410
+ };
411
+ var SWITCH_STYLES = {
412
+ /** Switch track width */
413
+ trackWidth: "36px",
414
+ /** Switch track height */
415
+ trackHeight: "20px",
416
+ /** Round indicator (thumb) size */
417
+ thumbSize: "16px",
418
+ /** Thumb offset from edge (2px each side for centering in 20px track) */
419
+ thumbOffset: "2px",
420
+ /** Thumb position in enabled state (trackWidth - thumbSize - thumbOffset = 36 - 16 - 2 = 18) */
421
+ thumbEnabledLeft: "18px"
422
+ };
423
+ function isValidTimeRange(open, close) {
424
+ const [openH, openM] = open.split(":").map(Number);
425
+ const [closeH, closeM] = close.split(":").map(Number);
426
+ const openMinutes = openH * 60 + openM;
427
+ const closeMinutes = closeH * 60 + closeM;
428
+ return closeMinutes > openMinutes;
429
+ }
430
+ var ScheduleContent = memo(function ScheduleContent2({
431
+ field,
432
+ schedule,
433
+ days,
434
+ mergedDayNames,
435
+ showCopyToWeekdays,
436
+ offLabel,
437
+ copyToWeekdaysLabel,
438
+ defaultOpenTime,
439
+ defaultCloseTime,
440
+ disabled,
441
+ readOnly,
442
+ resolvedLabel,
443
+ resolvedHelperText,
444
+ resolvedRequired,
445
+ resolvedTooltip,
446
+ fullPath
447
+ }) {
448
+ const { hasError, errorMessage } = getFieldErrors(field);
449
+ const invalidDays = useMemo(() => {
450
+ const invalid = [];
451
+ for (const day of days) {
452
+ const daySchedule = schedule[day];
453
+ if (daySchedule && !isValidTimeRange(daySchedule.open, daySchedule.close)) {
454
+ invalid.push(day);
455
+ }
456
+ }
457
+ return invalid;
458
+ }, [schedule, days]);
459
+ const handleDayToggle = useCallback(
460
+ (day, enabled) => {
461
+ const newSchedule = {
462
+ ...schedule,
463
+ [day]: enabled ? { open: defaultOpenTime, close: defaultCloseTime } : null
464
+ };
465
+ field.handleChange(newSchedule);
466
+ },
467
+ [schedule, field, defaultOpenTime, defaultCloseTime]
468
+ );
469
+ const handleTimeChange = useCallback(
470
+ (day, timeField, value) => {
471
+ const current = schedule[day];
472
+ if (!current) {
473
+ return;
474
+ }
475
+ const newSchedule = {
476
+ ...schedule,
477
+ [day]: { ...current, [timeField]: value }
478
+ };
479
+ field.handleChange(newSchedule);
480
+ },
481
+ [schedule, field]
482
+ );
483
+ const handleCopyToWeekdays = useCallback(() => {
484
+ const mondaySchedule = schedule.monday;
485
+ if (!mondaySchedule) {
486
+ return;
487
+ }
488
+ const newSchedule = {
489
+ ...schedule,
490
+ monday: mondaySchedule,
491
+ tuesday: mondaySchedule,
492
+ wednesday: mondaySchedule,
493
+ thursday: mondaySchedule,
494
+ friday: mondaySchedule
495
+ };
496
+ field.handleChange(newSchedule);
497
+ }, [schedule, field]);
498
+ return /* @__PURE__ */ jsxs(
499
+ Field.Root,
500
+ {
501
+ invalid: hasError,
502
+ required: resolvedRequired,
503
+ disabled,
504
+ readOnly,
505
+ "data-field-name": fullPath,
506
+ children: [
507
+ /* @__PURE__ */ jsx(FieldLabel, { label: resolvedLabel, tooltip: resolvedTooltip, required: resolvedRequired }),
508
+ /* @__PURE__ */ jsxs(Stack, { gap: 3, children: [
509
+ invalidDays.length > 0 && /* @__PURE__ */ jsx(Box, { p: 3, bg: "red.50", borderWidth: "1px", borderColor: "red.200", borderRadius: "md", children: /* @__PURE__ */ jsxs(Text, { color: "red.600", fontSize: "sm", fontWeight: "medium", children: [
510
+ "End time must be after start time: ",
511
+ invalidDays.map((d) => mergedDayNames[d]).join(", ")
512
+ ] }) }),
513
+ showCopyToWeekdays && days.includes("monday") && /* @__PURE__ */ jsxs(HStack, { gap: 2, flexWrap: "wrap", children: [
514
+ /* @__PURE__ */ jsx(Text, { fontSize: "sm", color: "fg.muted", children: "Quick actions:" }),
515
+ /* @__PURE__ */ jsx(
516
+ Button,
517
+ {
518
+ type: "button",
519
+ size: "xs",
520
+ variant: "ghost",
521
+ colorPalette: "blue",
522
+ onClick: handleCopyToWeekdays,
523
+ disabled: disabled || readOnly || !schedule.monday,
524
+ children: copyToWeekdaysLabel
525
+ }
526
+ )
527
+ ] }),
528
+ days.map((day) => {
529
+ const daySchedule = schedule[day];
530
+ const isEnabled = daySchedule !== null && daySchedule !== void 0;
531
+ const dayHasError = invalidDays.includes(day);
532
+ return /* @__PURE__ */ jsx(
533
+ Box,
534
+ {
535
+ "data-day": day,
536
+ p: 3,
537
+ bg: dayHasError ? "red.50" : isEnabled ? "bg.panel" : "bg.muted",
538
+ borderRadius: "md",
539
+ borderWidth: dayHasError ? "2px" : "1px",
540
+ borderColor: dayHasError ? "red.300" : "border.muted",
541
+ children: /* @__PURE__ */ jsxs(HStack, { justify: "space-between", flexWrap: "wrap", gap: 3, children: [
542
+ /* @__PURE__ */ jsxs(HStack, { gap: 3, minW: "140px", children: [
543
+ /* @__PURE__ */ jsxs(
544
+ Box,
545
+ {
546
+ as: "label",
547
+ display: "inline-flex",
548
+ alignItems: "center",
549
+ cursor: disabled || readOnly ? "not-allowed" : "pointer",
550
+ position: "relative",
551
+ opacity: disabled || readOnly ? 0.4 : 1,
552
+ children: [
553
+ /* @__PURE__ */ jsx(
554
+ "input",
555
+ {
556
+ type: "checkbox",
557
+ checked: isEnabled,
558
+ onChange: (e) => handleDayToggle(day, e.target.checked),
559
+ disabled: disabled || readOnly,
560
+ "data-switch": day,
561
+ style: {
562
+ position: "absolute",
563
+ opacity: 0,
564
+ width: 0,
565
+ height: 0
566
+ }
567
+ }
568
+ ),
569
+ /* @__PURE__ */ jsx(
570
+ Box,
571
+ {
572
+ w: SWITCH_STYLES.trackWidth,
573
+ h: SWITCH_STYLES.trackHeight,
574
+ bg: isEnabled ? "green.500" : "gray.300",
575
+ borderRadius: "full",
576
+ position: "relative",
577
+ transition: "background 0.2s",
578
+ children: /* @__PURE__ */ jsx(
579
+ Box,
580
+ {
581
+ position: "absolute",
582
+ top: SWITCH_STYLES.thumbOffset,
583
+ left: isEnabled ? SWITCH_STYLES.thumbEnabledLeft : SWITCH_STYLES.thumbOffset,
584
+ w: SWITCH_STYLES.thumbSize,
585
+ h: SWITCH_STYLES.thumbSize,
586
+ bg: "white",
587
+ borderRadius: "full",
588
+ transition: "left 0.2s",
589
+ boxShadow: "sm"
590
+ }
591
+ )
592
+ }
593
+ )
594
+ ]
595
+ }
596
+ ),
597
+ /* @__PURE__ */ jsx(Text, { fontWeight: "medium", color: isEnabled ? "fg" : "fg.muted", children: mergedDayNames[day] })
598
+ ] }),
599
+ isEnabled ? /* @__PURE__ */ jsxs(HStack, { gap: 2, children: [
600
+ /* @__PURE__ */ jsx(
601
+ Input,
602
+ {
603
+ type: "time",
604
+ size: "sm",
605
+ width: "120px",
606
+ value: daySchedule?.open || defaultOpenTime,
607
+ onChange: (e) => handleTimeChange(day, "open", e.target.value),
608
+ disabled: disabled || readOnly
609
+ }
610
+ ),
611
+ /* @__PURE__ */ jsx(Text, { color: "fg.muted", children: "\u2014" }),
612
+ /* @__PURE__ */ jsx(
613
+ Input,
614
+ {
615
+ type: "time",
616
+ size: "sm",
617
+ width: "120px",
618
+ value: daySchedule?.close || defaultCloseTime,
619
+ onChange: (e) => handleTimeChange(day, "close", e.target.value),
620
+ disabled: disabled || readOnly
621
+ }
622
+ )
623
+ ] }) : /* @__PURE__ */ jsx(Text, { fontSize: "sm", color: "fg.muted", children: offLabel })
624
+ ] })
625
+ },
626
+ day
627
+ );
628
+ })
629
+ ] }),
630
+ /* @__PURE__ */ jsx(FieldError, { hasError, errorMessage, helperText: resolvedHelperText })
631
+ ]
632
+ }
633
+ );
634
+ });
635
+ function FieldSchedule({
636
+ name,
637
+ label,
638
+ helperText,
639
+ required,
640
+ disabled,
641
+ readOnly,
642
+ tooltip,
643
+ dayNames = {},
644
+ defaultSchedule = DEFAULT_WORKING_HOURS,
645
+ days = DAYS_OF_WEEK,
646
+ showCopyToWeekdays = true,
647
+ offLabel = "Day off",
648
+ copyToWeekdaysLabel = "Copy Mon to weekdays",
649
+ defaultOpenTime = "09:00",
650
+ defaultCloseTime = "18:00"
651
+ }) {
652
+ const {
653
+ form,
654
+ fullPath,
655
+ label: resolvedLabel,
656
+ helperText: resolvedHelperText,
657
+ tooltip: resolvedTooltip,
658
+ required: resolvedRequired,
659
+ disabled: resolvedDisabled,
660
+ readOnly: resolvedReadOnly
661
+ } = useResolvedFieldProps(name, { label, helperText, required, disabled, readOnly, tooltip });
662
+ const mergedDayNames = { ...DEFAULT_DAY_NAMES, ...dayNames };
663
+ return /* @__PURE__ */ jsx(form.Field, { name: fullPath, children: (field) => {
664
+ const schedule = field.state.value || defaultSchedule;
665
+ return /* @__PURE__ */ jsx(
666
+ ScheduleContent,
667
+ {
668
+ field,
669
+ schedule,
670
+ defaultSchedule,
671
+ days,
672
+ mergedDayNames,
673
+ showCopyToWeekdays,
674
+ offLabel,
675
+ copyToWeekdaysLabel,
676
+ defaultOpenTime,
677
+ defaultCloseTime,
678
+ disabled: resolvedDisabled,
679
+ readOnly: resolvedReadOnly,
680
+ resolvedLabel,
681
+ resolvedHelperText,
682
+ resolvedRequired,
683
+ resolvedTooltip,
684
+ fullPath
685
+ }
686
+ );
687
+ } });
688
+ }
689
+ var FieldTime = createField({
690
+ displayName: "FieldTime",
691
+ render: ({ field, fullPath, resolved, hasError, errorMessage, componentProps }) => /* @__PURE__ */ jsx(FieldWrapper, { resolved, hasError, errorMessage, fullPath, children: /* @__PURE__ */ jsx(
692
+ Input,
693
+ {
694
+ type: "time",
695
+ value: field.state.value ?? "",
696
+ onChange: (e) => field.handleChange(e.target.value),
697
+ onBlur: field.handleBlur,
698
+ placeholder: resolved.placeholder,
699
+ min: componentProps.min,
700
+ max: componentProps.max,
701
+ step: componentProps.step,
702
+ "data-field-name": fullPath
703
+ }
704
+ ) })
705
+ });
706
+
707
+ export { FieldDate, FieldDateRange, FieldDateTimePicker, FieldDuration, FieldSchedule, FieldTime };
708
+ //# sourceMappingURL=chunk-Q5EOF36Y.js.map
709
+ //# sourceMappingURL=chunk-Q5EOF36Y.js.map