@letar/forms 1.0.3 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,709 @@
1
+ import { createField, FieldWrapper, FieldLabel, FieldError, getFieldErrors, useResolvedFieldProps } from './chunk-HWVOFWAT.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-KUNT5MSU.js.map
709
+ //# sourceMappingURL=chunk-KUNT5MSU.js.map