@techsio/ui-kit 0.43.0 → 0.44.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.
@@ -0,0 +1,1374 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { Fragment as external_react_Fragment, createContext, createElement, useContext, useEffect, useId, useReducer, useRef, useState } from "react";
3
+ import { connect, machine } from "@zag-js/date-input";
4
+ import { connect as date_picker_connect, machine as date_picker_machine } from "@zag-js/date-picker";
5
+ import { Portal, mergeProps, normalizeProps, useMachine } from "@zag-js/react";
6
+ import { Button } from "../atoms/button.js";
7
+ import { Input } from "../atoms/input.js";
8
+ import { Label } from "../atoms/label.js";
9
+ import { canConfirmDatePickerDraft, createDatePickerCoordinatorState, datePickerCoordinatorReducer, getDatePickerDraftTimeParts } from "../internal/date-picker-coordinator.js";
10
+ import { tv } from "../utils.js";
11
+ const datePickerVariants = tv({
12
+ slots: {
13
+ root: "relative flex w-full flex-col gap-date-picker-root",
14
+ label: "text-date-picker-label-fg",
15
+ control: "w-full",
16
+ inputControl: [
17
+ "form-control-base flex w-full items-center gap-date-picker-control",
18
+ "border-(length:--border-width-date-picker-control)",
19
+ "border-date-picker-control-border bg-date-picker-control-bg text-date-picker-control-fg",
20
+ "hover:border-date-picker-control-border-hover hover:bg-date-picker-control-bg-hover",
21
+ "data-focus:border-date-picker-control-border-focus data-focus:bg-date-picker-control-bg-focus",
22
+ "has-focus-visible:outline-(style:--default-ring-style) has-focus-visible:outline-(length:--default-ring-width)",
23
+ "has-focus-visible:outline-date-picker-control-ring",
24
+ "has-focus-visible:outline-offset-(length:--default-ring-offset)",
25
+ "data-[validation=error]:border-(length:--border-width-validation)",
26
+ "data-[validation=error]:border-date-picker-control-border-error",
27
+ "data-[validation=error]:hover:border-date-picker-control-border-error-hover",
28
+ "data-focus:data-[validation=error]:border-date-picker-control-border-error-focus",
29
+ "data-disabled:cursor-not-allowed data-disabled:border-date-picker-control-border-disabled",
30
+ "data-disabled:bg-date-picker-control-bg-disabled data-disabled:text-date-picker-control-fg-disabled",
31
+ "data-readonly:bg-date-picker-control-bg-readonly",
32
+ "transition-colors duration-200 motion-reduce:transition-none"
33
+ ],
34
+ segments: [
35
+ "date-picker-scrollbar-hidden flex min-w-0 flex-1 items-center overflow-x-auto overflow-y-hidden outline-none",
36
+ "data-disabled:overflow-hidden"
37
+ ],
38
+ segmentGroup: "flex min-w-0 items-center",
39
+ rangeSeparator: "shrink-0 px-date-picker-range-separator text-date-picker-range-separator-fg",
40
+ segment: [
41
+ "date-picker-segment-size inline-flex shrink-0 items-center justify-center rounded-date-picker-day px-date-picker-segment tabular-nums outline-none",
42
+ "data-placeholder-shown:text-date-picker-segment-fg-placeholder",
43
+ "focus:bg-date-picker-segment-bg-focus",
44
+ "data-[type=literal]:min-h-0 data-[type=literal]:min-w-0 data-[type=literal]:px-0 data-[type=literal]:text-date-picker-control-fg",
45
+ "data-disabled:cursor-not-allowed data-readonly:cursor-default"
46
+ ],
47
+ indicatorGroup: "flex shrink-0 items-center gap-date-picker-indicator",
48
+ trigger: [
49
+ "inline-flex shrink-0 items-center justify-center rounded-date-picker-day border-0 p-0",
50
+ "bg-date-picker-trigger-bg text-date-picker-trigger-fg",
51
+ "hover:bg-date-picker-trigger-bg-hover",
52
+ "active:bg-date-picker-trigger-bg-active",
53
+ "focus-visible:outline-(style:--default-ring-style) focus-visible:outline-(length:--default-ring-width)",
54
+ "focus-visible:outline-date-picker-trigger-ring",
55
+ "focus-visible:outline-offset-(length:--default-ring-offset)",
56
+ "data-disabled:cursor-not-allowed data-disabled:text-date-picker-trigger-fg-disabled",
57
+ "disabled:cursor-not-allowed disabled:bg-date-picker-control-bg-disabled disabled:text-date-picker-trigger-fg-disabled",
58
+ "transition-colors duration-200 motion-reduce:transition-none"
59
+ ],
60
+ clearTrigger: [
61
+ "inline-flex shrink-0 items-center justify-center rounded-date-picker-day p-0",
62
+ "text-date-picker-trigger-fg hover:bg-date-picker-trigger-bg-hover active:bg-date-picker-trigger-bg-active",
63
+ "focus-visible:outline-(style:--default-ring-style) focus-visible:outline-(length:--default-ring-width)",
64
+ "focus-visible:outline-date-picker-trigger-ring",
65
+ "focus-visible:outline-offset-(length:--default-ring-offset)",
66
+ "data-disabled:cursor-not-allowed data-disabled:text-date-picker-trigger-fg-disabled",
67
+ "data-readonly:hidden",
68
+ "disabled:cursor-not-allowed disabled:text-date-picker-trigger-fg-disabled",
69
+ "transition-colors duration-200 motion-reduce:transition-none"
70
+ ],
71
+ positioner: "isolate z-(--z-index)",
72
+ content: [
73
+ "flex max-h-(--available-height) w-date-picker-content max-w-date-picker-viewport flex-col overflow-hidden",
74
+ "data-[selection-mode=range]:w-date-picker-content-range",
75
+ "border-(length:--border-width-date-picker-content) border-date-picker-content-border",
76
+ "rounded-date-picker-content bg-date-picker-content-bg text-date-picker-content-fg shadow-date-picker-content",
77
+ "outline-none duration-200 ease-out",
78
+ "motion-safe:transition motion-reduce:transition-none",
79
+ "starting:-translate-y-date-picker-enter-offset starting:opacity-0"
80
+ ],
81
+ calendar: [
82
+ "grid min-h-0 grid-cols-1 gap-date-picker-calendar overflow-y-auto p-date-picker-content",
83
+ "sm:data-[selection-mode=range]:grid-cols-2"
84
+ ],
85
+ monthPanel: [
86
+ "grid min-w-0 content-start gap-date-picker-calendar",
87
+ "sm:data-[index=1]:border-date-picker-month-divider-border sm:data-[index=1]:border-l sm:data-[index=1]:pl-date-picker-content"
88
+ ],
89
+ view: "min-w-0",
90
+ viewControl: "flex min-w-0 items-center justify-between gap-date-picker-calendar",
91
+ navigationTrigger: [
92
+ "size-date-picker-navigation shrink-0 rounded-date-picker-day p-0",
93
+ "text-date-picker-navigation-fg hover:bg-date-picker-navigation-bg-hover",
94
+ "focus-visible:outline-(style:--default-ring-style) focus-visible:outline-(length:--default-ring-width)",
95
+ "focus-visible:outline-date-picker-navigation-ring",
96
+ "focus-visible:outline-offset-(length:--default-ring-offset)",
97
+ "disabled:cursor-not-allowed disabled:text-date-picker-navigation-fg-disabled"
98
+ ],
99
+ viewTrigger: [
100
+ "min-w-0 flex-1 truncate rounded-date-picker-day px-date-picker-calendar-cell",
101
+ "font-date-picker-view text-date-picker-navigation-fg hover:bg-date-picker-navigation-bg-hover",
102
+ "focus-visible:outline-(style:--default-ring-style) focus-visible:outline-(length:--default-ring-width)",
103
+ "focus-visible:outline-date-picker-navigation-ring",
104
+ "focus-visible:outline-offset-(length:--default-ring-offset)"
105
+ ],
106
+ viewHeading: "min-w-0 flex-1 truncate px-date-picker-calendar-cell text-center font-date-picker-view text-date-picker-navigation-fg",
107
+ table: "w-full table-fixed border-separate border-spacing-0",
108
+ tableHeader: [
109
+ "text-center align-middle",
110
+ "font-date-picker-weekday text-date-picker-weekday text-date-picker-weekday-fg"
111
+ ],
112
+ tableCell: "p-0 text-center align-middle",
113
+ dayTrigger: [
114
+ "border-(length:--border-width-date-picker-day) flex w-full items-center justify-center",
115
+ "rounded-date-picker-day border-date-picker-day-border bg-date-picker-day-bg text-date-picker-day-fg",
116
+ "hover:bg-date-picker-day-bg-hover",
117
+ "focus-visible:outline-(style:--default-ring-style) focus-visible:outline-(length:--default-ring-width)",
118
+ "focus-visible:outline-date-picker-day-ring",
119
+ "focus-visible:outline-offset-(length:--default-ring-offset)",
120
+ "data-today:border-date-picker-day-today-border",
121
+ "data-in-range:rounded-none data-in-range:bg-date-picker-day-bg-range",
122
+ "data-in-hover-range:rounded-none data-in-hover-range:bg-date-picker-day-bg-range-hover",
123
+ "data-range-start:rounded-date-picker-day data-range-start:rounded-r-none",
124
+ "data-range-end:rounded-date-picker-day data-range-end:rounded-l-none",
125
+ "data-range-start:bg-date-picker-day-bg-selected data-range-end:bg-date-picker-day-bg-selected",
126
+ "data-range-start:text-date-picker-day-fg-selected data-range-end:text-date-picker-day-fg-selected",
127
+ "data-selected:bg-date-picker-day-bg-selected data-selected:text-date-picker-day-fg-selected",
128
+ "data-selected:hover:bg-date-picker-day-bg-selected-hover",
129
+ "data-unavailable:text-date-picker-day-fg-unavailable data-unavailable:line-through",
130
+ "data-outside-range:opacity-date-picker-outside",
131
+ "data-disabled:pointer-events-none data-disabled:cursor-not-allowed data-disabled:opacity-date-picker-disabled",
132
+ "forced-colors:data-selected:outline-2",
133
+ "forced-colors:data-disabled:opacity-date-picker-disabled",
134
+ "transition-colors duration-200 motion-reduce:transition-none"
135
+ ],
136
+ periodTrigger: [
137
+ "w-full rounded-date-picker-day p-date-picker-calendar-cell",
138
+ "text-date-picker-day-fg hover:bg-date-picker-day-bg-hover",
139
+ "focus-visible:outline-(style:--default-ring-style) focus-visible:outline-(length:--default-ring-width)",
140
+ "focus-visible:outline-date-picker-day-ring",
141
+ "focus-visible:outline-offset-(length:--default-ring-offset)",
142
+ "data-selected:bg-date-picker-day-bg-selected data-selected:text-date-picker-day-fg-selected",
143
+ "data-disabled:pointer-events-none data-disabled:cursor-not-allowed data-disabled:opacity-date-picker-disabled"
144
+ ],
145
+ timeControl: [
146
+ "grid shrink-0 grid-cols-1 gap-date-picker-time border-date-picker-time-border border-t",
147
+ "bg-date-picker-time-bg p-date-picker-time text-date-picker-time-fg",
148
+ "sm:data-[selection-mode=range]:grid-cols-2"
149
+ ],
150
+ timeGroup: [
151
+ "flex min-w-0 items-center gap-date-picker-time",
152
+ "data-[index=1]:border-date-picker-time-border data-[index=1]:border-t data-[index=1]:pt-date-picker-time",
153
+ "sm:data-[index=1]:border-l sm:data-[index=1]:border-t-0 sm:data-[index=1]:pt-0 sm:data-[index=1]:pl-date-picker-time"
154
+ ],
155
+ timeGroupLabel: "shrink-0 font-date-picker-view text-date-picker-time-label-fg text-date-picker-time-label",
156
+ timeFields: "flex min-w-0 items-center gap-date-picker-indicator",
157
+ timeField: "w-date-picker-time-field shrink-0",
158
+ timeLabel: "sr-only",
159
+ timeSeparator: "shrink-0 text-date-picker-time-label-fg tabular-nums",
160
+ timeInput: "token-date-picker-time-input px-date-picker-time-input text-center tabular-nums",
161
+ dayPeriod: [
162
+ "h-date-picker-time-field border-(length:--border-width-date-picker-time) rounded-date-picker-time text-date-picker-sm",
163
+ "border-date-picker-time-border bg-date-picker-time-bg px-date-picker-calendar-cell text-date-picker-time-fg",
164
+ "focus-visible:outline-(style:--default-ring-style) focus-visible:outline-(length:--default-ring-width)",
165
+ "focus-visible:outline-date-picker-time-ring",
166
+ "focus-visible:outline-offset-(length:--default-ring-offset)",
167
+ "disabled:cursor-not-allowed disabled:opacity-date-picker-disabled"
168
+ ],
169
+ timeZone: "ms-auto self-center truncate text-date-picker-time-label text-date-picker-time-label-fg",
170
+ footer: [
171
+ "flex shrink-0 items-center justify-end gap-date-picker-footer border-date-picker-footer-border border-t",
172
+ "p-date-picker-footer"
173
+ ],
174
+ cancelTrigger: "shrink-0 text-date-picker-content-fg",
175
+ confirmTrigger: "shrink-0"
176
+ },
177
+ variants: {
178
+ size: {
179
+ sm: {
180
+ inputControl: "h-date-picker-control-sm rounded-date-picker-control-sm p-date-picker-segments-sm text-date-picker-sm",
181
+ trigger: "size-icon-control-sm text-icon-control-sm",
182
+ clearTrigger: "size-icon-control-sm text-icon-control-sm",
183
+ content: "text-date-picker-content-sm",
184
+ dayTrigger: "size-date-picker-day-sm",
185
+ tableHeader: "h-date-picker-day-sm"
186
+ },
187
+ md: {
188
+ inputControl: "h-date-picker-control-md rounded-date-picker-control-md p-date-picker-segments-md text-date-picker-md",
189
+ trigger: "size-icon-control-md text-icon-control-md",
190
+ clearTrigger: "size-icon-control-md text-icon-control-md",
191
+ content: "text-date-picker-content-md",
192
+ dayTrigger: "size-date-picker-day-md",
193
+ tableHeader: "h-date-picker-day-md"
194
+ },
195
+ lg: {
196
+ inputControl: "h-date-picker-control-lg rounded-date-picker-control-lg p-date-picker-segments-lg text-date-picker-lg",
197
+ trigger: "size-icon-control-lg text-icon-control-lg",
198
+ clearTrigger: "size-icon-control-lg text-icon-control-lg",
199
+ content: "text-date-picker-content-lg",
200
+ dayTrigger: "size-date-picker-day-lg",
201
+ tableHeader: "h-date-picker-day-lg"
202
+ }
203
+ },
204
+ timed: {
205
+ true: {
206
+ calendar: "p-date-picker-content-timed",
207
+ dayTrigger: "h-date-picker-day-timed",
208
+ tableHeader: "h-date-picker-day-timed"
209
+ }
210
+ }
211
+ },
212
+ defaultVariants: {
213
+ size: "md"
214
+ }
215
+ });
216
+ const DatePickerContext = /*#__PURE__*/ createContext(null);
217
+ function useDatePickerContext() {
218
+ const context = useContext(DatePickerContext);
219
+ if (!context) throw new Error("DatePicker components must be used within DatePicker.Root");
220
+ return context;
221
+ }
222
+ function setRefValue(ref, value) {
223
+ if ("function" == typeof ref) return void ref(value);
224
+ if (ref) ref.current = value;
225
+ }
226
+ function toCompleteDatePickerRange(value) {
227
+ const start = value[0];
228
+ const end = value[1];
229
+ if (!(start && end && start.compare(end) <= 0)) return null;
230
+ return [
231
+ start,
232
+ end
233
+ ];
234
+ }
235
+ function toDateValues(value) {
236
+ if (isDateValueArray(value)) return [
237
+ ...value
238
+ ];
239
+ return value ? [
240
+ value
241
+ ] : [];
242
+ }
243
+ function isDateValueArray(value) {
244
+ return Array.isArray(value);
245
+ }
246
+ function serializeDatePickerValue(value) {
247
+ if (Array.isArray(value)) {
248
+ const range = toCompleteDatePickerRange(value);
249
+ return range ? [
250
+ range[0].toString(),
251
+ range[1].toString()
252
+ ] : [
253
+ "",
254
+ ""
255
+ ];
256
+ }
257
+ return value?.toString() ?? "";
258
+ }
259
+ function DatePicker({ children, className, defaultOpen = false, defaultValue, disabled, endName, flip = true, form, granularity = "day", gutter = 8, hideTimeZone = false, hourCycle, id, invalid, isDateUnavailable, isTimeUnavailable, locale = "en-US", max, min, name, numOfMonths, offset = {
260
+ mainAxis: 8,
261
+ crossAxis: 0
262
+ }, onOpenChange, onValueChange, open, overflowPadding = 8, placement = "bottom-start", readOnly, ref, required, sameWidth = false, selectionMode = "single", shouldForceLeadingZeros = false, size = "md", slide = true, startOfWeek, startName, timeZone = "UTC", value, ...htmlProps }) {
263
+ const generatedId = useId();
264
+ const uniqueId = id ?? generatedId;
265
+ const isTimed = "day" !== granularity;
266
+ const resolvedHourCycle = hourCycle ?? (new Intl.DateTimeFormat(locale, {
267
+ hour: "numeric"
268
+ }).resolvedOptions().hour12 ? 12 : 24);
269
+ const [uncontrolledValue, setUncontrolledValue] = useState(()=>defaultValue ?? null);
270
+ const acceptedValue = void 0 === value ? uncontrolledValue : value;
271
+ const acceptedValues = toDateValues(acceptedValue);
272
+ const acceptedScalarValue = acceptedValues[0] ?? null;
273
+ const acceptedCandidate = "range" === selectionMode ? acceptedValues : acceptedScalarValue;
274
+ const [rangeInputDraft, setRangeInputDraft] = useState(null);
275
+ const usesPopupDraft = isTimed || "range" === selectionMode;
276
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);
277
+ const resolvedOpen = void 0 === open ? uncontrolledOpen : open;
278
+ const isTimedRangePopupOpen = isTimed && "range" === selectionMode && resolvedOpen;
279
+ const [coordinator, dispatch] = useReducer(datePickerCoordinatorReducer, void 0, ()=>usesPopupDraft && resolvedOpen ? {
280
+ draft: {
281
+ baseline: acceptedCandidate,
282
+ candidate: acceptedCandidate
283
+ }
284
+ } : createDatePickerCoordinatorState());
285
+ const acceptedValueAsString = serializeDatePickerValue(acceptedValue);
286
+ const acceptedValuesAsString = acceptedValues.map((item)=>item.toString());
287
+ const acceptedValueKey = JSON.stringify(acceptedValueAsString);
288
+ const previousAcceptedValue = useRef(acceptedValueKey);
289
+ const previousOpen = useRef(resolvedOpen);
290
+ const triggerElementRef = useRef(null);
291
+ const styles = datePickerVariants({
292
+ size,
293
+ timed: isTimed
294
+ });
295
+ useEffect(()=>{
296
+ if (previousOpen.current === resolvedOpen) return;
297
+ previousOpen.current = resolvedOpen;
298
+ const pendingTimedRange = resolvedOpen && isTimed && "range" === selectionMode && rangeInputDraft ? toCompleteDatePickerRange(rangeInputDraft) : null;
299
+ if ("range" === selectionMode) setRangeInputDraft(null);
300
+ if (!(resolvedOpen && usesPopupDraft)) return void dispatch({
301
+ type: "discard"
302
+ });
303
+ dispatch({
304
+ type: "open",
305
+ value: acceptedCandidate
306
+ });
307
+ if (pendingTimedRange) dispatch({
308
+ type: "edit",
309
+ value: pendingTimedRange
310
+ });
311
+ }, [
312
+ acceptedCandidate,
313
+ isTimed,
314
+ rangeInputDraft,
315
+ resolvedOpen,
316
+ selectionMode,
317
+ usesPopupDraft
318
+ ]);
319
+ useEffect(()=>{
320
+ if (previousAcceptedValue.current === acceptedValueKey) return;
321
+ previousAcceptedValue.current = acceptedValueKey;
322
+ setRangeInputDraft(null);
323
+ if (usesPopupDraft && resolvedOpen) dispatch({
324
+ type: "resync",
325
+ value: acceptedCandidate
326
+ });
327
+ }, [
328
+ acceptedCandidate,
329
+ acceptedValueKey,
330
+ resolvedOpen,
331
+ usesPopupDraft
332
+ ]);
333
+ const commitValue = (nextValue)=>{
334
+ if (void 0 === value) setUncontrolledValue(nextValue);
335
+ onValueChange?.({
336
+ value: nextValue,
337
+ valueAsString: serializeDatePickerValue(nextValue)
338
+ });
339
+ };
340
+ const requestOpen = (nextOpen)=>{
341
+ if (nextOpen === resolvedOpen) return;
342
+ const activeElement = nextOpen || "u" < typeof document ? null : document.activeElement;
343
+ const shouldRestoreFocus = activeElement instanceof HTMLElement && Boolean(activeElement.closest('[data-scope="date-picker"][data-part="content"]'));
344
+ if (void 0 === open) setUncontrolledOpen(nextOpen);
345
+ onOpenChange?.({
346
+ open: nextOpen
347
+ });
348
+ if (shouldRestoreFocus) requestAnimationFrame(()=>{
349
+ if (document.activeElement === document.body) triggerElementRef.current?.focus({
350
+ preventScroll: true
351
+ });
352
+ });
353
+ };
354
+ const draftValue = coordinator.draft ? coordinator.draft.candidate : acceptedCandidate;
355
+ const pickerValues = usesPopupDraft && resolvedOpen ? toDateValues(draftValue) : acceptedValues;
356
+ const dateInputValues = "range" !== selectionMode || isTimedRangePopupOpen ? acceptedValues : rangeInputDraft ?? acceptedValues;
357
+ const resolvedNumOfMonths = numOfMonths ?? ("range" === selectionMode ? 2 : 1);
358
+ const pickerService = useMachine(date_picker_machine, {
359
+ closeOnSelect: !isTimed,
360
+ disabled,
361
+ id: `${uniqueId}-calendar`,
362
+ ids: {
363
+ label: ()=>`${uniqueId}-label`
364
+ },
365
+ invalid,
366
+ isDateUnavailable,
367
+ locale,
368
+ max,
369
+ min,
370
+ fixedWeeks: resolvedNumOfMonths > 1,
371
+ numOfMonths: 1,
372
+ onOpenChange: (details)=>requestOpen(details.open),
373
+ onValueChange: (details)=>{
374
+ const nextValue = details.value[0] ?? null;
375
+ if ("range" === selectionMode) {
376
+ dispatch({
377
+ type: "edit",
378
+ value: details.value
379
+ });
380
+ const nextRange = toCompleteDatePickerRange(details.value);
381
+ if (isTimed || !nextRange) return;
382
+ commitValue(nextRange);
383
+ requestOpen(false);
384
+ return;
385
+ }
386
+ if (isTimed) return void dispatch({
387
+ type: "edit",
388
+ value: nextValue
389
+ });
390
+ commitValue(nextValue);
391
+ requestOpen(false);
392
+ },
393
+ open: resolvedOpen,
394
+ openOnClick: false,
395
+ positioning: {
396
+ flip,
397
+ gutter,
398
+ offset,
399
+ overflowPadding,
400
+ placement,
401
+ sameWidth,
402
+ slide
403
+ },
404
+ readOnly,
405
+ required,
406
+ selectionMode,
407
+ startOfWeek,
408
+ timeZone,
409
+ value: pickerValues
410
+ });
411
+ const pickerApi = date_picker_connect(pickerService, normalizeProps);
412
+ const dateInputService = useMachine(machine, {
413
+ disabled,
414
+ granularity,
415
+ hideTimeZone,
416
+ hourCycle,
417
+ id: `${uniqueId}-input`,
418
+ ids: {
419
+ label: ()=>`${uniqueId}-label`
420
+ },
421
+ invalid,
422
+ isDateUnavailable,
423
+ locale,
424
+ max,
425
+ min,
426
+ onValueChange: (details)=>{
427
+ if ("range" === selectionMode) {
428
+ dispatch({
429
+ type: "edit",
430
+ value: details.value
431
+ });
432
+ if (isTimedRangePopupOpen) return;
433
+ setRangeInputDraft(details.value);
434
+ const nextRange = toCompleteDatePickerRange(details.value);
435
+ if (nextRange) {
436
+ if (isTimed) return void requestOpen(true);
437
+ setRangeInputDraft(null);
438
+ commitValue(nextRange);
439
+ requestOpen(false);
440
+ }
441
+ return;
442
+ }
443
+ commitValue(details.value[0] ?? null);
444
+ },
445
+ readOnly: readOnly || isTimed && resolvedOpen,
446
+ required,
447
+ selectionMode,
448
+ shouldForceLeadingZeros,
449
+ timeZone,
450
+ value: dateInputValues
451
+ });
452
+ const dateInputApi = connect(dateInputService, normalizeProps);
453
+ const canConfirm = canConfirmDatePickerDraft(coordinator, isTimeUnavailable);
454
+ const submitDraft = ()=>{
455
+ if (!(canConfirm && coordinator.draft)) return;
456
+ const candidate = coordinator.draft.candidate;
457
+ if ("range" === selectionMode) if (null === candidate) commitValue(null);
458
+ else {
459
+ const nextRange = toCompleteDatePickerRange(toDateValues(candidate));
460
+ if (!nextRange) return;
461
+ commitValue(nextRange);
462
+ }
463
+ else if (!isDateValueArray(candidate)) commitValue(candidate);
464
+ requestOpen(false);
465
+ };
466
+ const clearValue = ()=>{
467
+ if (disabled || readOnly) return;
468
+ setRangeInputDraft(null);
469
+ if (isTimed && resolvedOpen) return void dispatch({
470
+ type: "edit",
471
+ value: null
472
+ });
473
+ commitValue(null);
474
+ };
475
+ const rootProps = mergeProps(htmlProps, pickerApi.getRootProps());
476
+ return /*#__PURE__*/ jsx(DatePickerContext.Provider, {
477
+ value: {
478
+ acceptedValue,
479
+ canConfirm,
480
+ clearValue,
481
+ coordinator,
482
+ dateInputApi,
483
+ granularity,
484
+ hideTimeZone,
485
+ hourCycle: resolvedHourCycle,
486
+ isTimed,
487
+ max,
488
+ min,
489
+ numOfMonths: resolvedNumOfMonths,
490
+ pickerApi,
491
+ requestOpen,
492
+ required: Boolean(required),
493
+ selectionMode,
494
+ setDraftTimePart: (part, nextValue, index = 0)=>{
495
+ if ("day" !== granularity) dispatch({
496
+ type: "edit-time",
497
+ granularity,
498
+ hourCycle: resolvedHourCycle,
499
+ index,
500
+ part,
501
+ value: nextValue
502
+ });
503
+ },
504
+ setDraftValue: (nextValue)=>dispatch({
505
+ type: "edit",
506
+ value: nextValue
507
+ }),
508
+ size,
509
+ styles,
510
+ submitDraft,
511
+ triggerElementRef
512
+ },
513
+ children: /*#__PURE__*/ jsxs("div", {
514
+ ...rootProps,
515
+ className: styles.root({
516
+ className
517
+ }),
518
+ "data-granularity": granularity,
519
+ "data-selection-mode": selectionMode,
520
+ ref: ref,
521
+ children: [
522
+ children,
523
+ "range" === selectionMode ? /*#__PURE__*/ jsxs(Fragment, {
524
+ children: [
525
+ /*#__PURE__*/ jsx("input", {
526
+ disabled: disabled,
527
+ form: form,
528
+ name: startName,
529
+ type: "hidden",
530
+ value: acceptedValuesAsString[0] ?? ""
531
+ }),
532
+ /*#__PURE__*/ jsx("input", {
533
+ disabled: disabled,
534
+ form: form,
535
+ name: endName,
536
+ type: "hidden",
537
+ value: acceptedValuesAsString[1] ?? ""
538
+ })
539
+ ]
540
+ }) : /*#__PURE__*/ jsx("input", {
541
+ disabled: disabled,
542
+ form: form,
543
+ name: name,
544
+ type: "hidden",
545
+ value: acceptedValuesAsString[0] ?? ""
546
+ })
547
+ ]
548
+ })
549
+ });
550
+ }
551
+ DatePicker.Label = function({ children, className, ref, ...props }) {
552
+ const { dateInputApi, pickerApi, required, size, styles } = useDatePickerContext();
553
+ const labelProps = mergeProps({
554
+ ...props,
555
+ ref
556
+ }, pickerApi.getLabelProps(), dateInputApi.getLabelProps());
557
+ return /*#__PURE__*/ jsx(Label, {
558
+ ...labelProps,
559
+ className: styles.label({
560
+ className
561
+ }),
562
+ disabled: dateInputApi.disabled,
563
+ required: required,
564
+ size: size,
565
+ children: children
566
+ });
567
+ };
568
+ DatePicker.Control = function({ children, className, ref, ...props }) {
569
+ const { dateInputApi, pickerApi, styles } = useDatePickerContext();
570
+ const controlProps = mergeProps(props, pickerApi.getControlProps());
571
+ const { "data-invalid": _dataInvalid, ...dateInputControlProps } = dateInputApi.getControlProps();
572
+ return /*#__PURE__*/ jsx("div", {
573
+ ...controlProps,
574
+ className: styles.control({
575
+ className
576
+ }),
577
+ ref: ref,
578
+ children: /*#__PURE__*/ jsx("div", {
579
+ ...dateInputControlProps,
580
+ className: styles.inputControl(),
581
+ "data-disabled": dateInputApi.disabled || void 0,
582
+ "data-readonly": pickerApi.readOnly || void 0,
583
+ "data-validation": dateInputApi.invalid ? "error" : void 0,
584
+ children: children
585
+ })
586
+ });
587
+ };
588
+ DatePicker.Segments = function({ className, endLabel = "End", ref, separator = "–", startLabel = "Start", ...props }) {
589
+ const { dateInputApi, required, selectionMode, styles } = useDatePickerContext();
590
+ const startDescriptorId = useId();
591
+ const endDescriptorId = useId();
592
+ const renderSegments = (index)=>dateInputApi.getSegments({
593
+ index
594
+ }).map((segment, segmentIndex)=>/*#__PURE__*/ createElement("span", {
595
+ ...dateInputApi.getSegmentProps({
596
+ index,
597
+ segment
598
+ }),
599
+ "aria-required": required && "literal" !== segment.type ? true : void 0,
600
+ className: styles.segment(),
601
+ key: `${segment.type}-${segmentIndex}`
602
+ }, segment.text));
603
+ if ("range" === selectionMode) {
604
+ const visibleLabel = props["aria-label"];
605
+ const baseLabelId = dateInputApi.getLabelProps().id;
606
+ const getRangeGroupLabelProps = (index, descriptorId, label)=>({
607
+ ...visibleLabel ? {
608
+ "aria-label": `${visibleLabel} ${label}`
609
+ } : {
610
+ "aria-labelledby": `${baseLabelId} ${descriptorId}`
611
+ },
612
+ ...dateInputApi.getSegmentGroupProps({
613
+ index
614
+ }),
615
+ ...visibleLabel ? {
616
+ "aria-label": `${visibleLabel} ${label}`,
617
+ "aria-labelledby": void 0
618
+ } : {
619
+ "aria-labelledby": `${baseLabelId} ${descriptorId}`
620
+ }
621
+ });
622
+ return /*#__PURE__*/ jsxs("div", {
623
+ ...props,
624
+ "aria-label": void 0,
625
+ className: styles.segments({
626
+ className
627
+ }),
628
+ "data-part": "segments",
629
+ "data-scope": "date-picker",
630
+ ref: ref,
631
+ children: [
632
+ /*#__PURE__*/ jsx("span", {
633
+ className: "sr-only",
634
+ id: startDescriptorId,
635
+ children: startLabel
636
+ }),
637
+ /*#__PURE__*/ jsx("div", {
638
+ ...getRangeGroupLabelProps(0, startDescriptorId, startLabel),
639
+ className: styles.segmentGroup(),
640
+ children: renderSegments(0)
641
+ }),
642
+ /*#__PURE__*/ jsx("span", {
643
+ "aria-hidden": "true",
644
+ className: styles.rangeSeparator(),
645
+ children: separator
646
+ }),
647
+ /*#__PURE__*/ jsx("span", {
648
+ className: "sr-only",
649
+ id: endDescriptorId,
650
+ children: endLabel
651
+ }),
652
+ /*#__PURE__*/ jsx("div", {
653
+ ...getRangeGroupLabelProps(1, endDescriptorId, endLabel),
654
+ className: styles.segmentGroup(),
655
+ children: renderSegments(1)
656
+ })
657
+ ]
658
+ });
659
+ }
660
+ const groupProps = mergeProps(props, dateInputApi.getSegmentGroupProps());
661
+ return /*#__PURE__*/ jsx("div", {
662
+ ...groupProps,
663
+ className: styles.segments({
664
+ className
665
+ }),
666
+ ref: ref,
667
+ children: renderSegments(0)
668
+ });
669
+ };
670
+ DatePicker.IndicatorGroup = function({ className, ref, ...props }) {
671
+ const { styles } = useDatePickerContext();
672
+ return /*#__PURE__*/ jsx("div", {
673
+ ...props,
674
+ className: styles.indicatorGroup({
675
+ className
676
+ }),
677
+ "data-part": "indicator-group",
678
+ "data-scope": "date-picker",
679
+ ref: ref
680
+ });
681
+ };
682
+ DatePicker.Trigger = function({ children, className, icon, iconSize = "current", ref, size = "current", theme = "unstyled", type = "button", ...props }) {
683
+ const { dateInputApi, pickerApi, styles, triggerElementRef } = useDatePickerContext();
684
+ const triggerProps = mergeProps(props, pickerApi.getTriggerProps());
685
+ return /*#__PURE__*/ jsx(Button, {
686
+ ...triggerProps,
687
+ "aria-invalid": dateInputApi.invalid || void 0,
688
+ className: styles.trigger({
689
+ className
690
+ }),
691
+ icon: icon ?? (children ? void 0 : "token-icon-date-picker-calendar"),
692
+ iconSize: iconSize,
693
+ ref: (node)=>{
694
+ triggerElementRef.current = node;
695
+ setRefValue(ref, node);
696
+ },
697
+ size: size,
698
+ theme: theme,
699
+ type: type,
700
+ children: children
701
+ });
702
+ };
703
+ DatePicker.ClearTrigger = function({ children, className, icon, iconSize = "current", onClick, ref, size = "current", theme = "unstyled", type = "button", ...props }) {
704
+ const { clearValue, pickerApi, styles } = useDatePickerContext();
705
+ const { onClick: _onMachineClick, ...machineClearProps } = pickerApi.getClearTriggerProps();
706
+ const clearProps = mergeProps(props, machineClearProps);
707
+ const isClearDisabled = Boolean(clearProps.disabled || pickerApi.disabled || pickerApi.readOnly);
708
+ const handleClick = (event)=>{
709
+ onClick?.(event);
710
+ if (!(event.defaultPrevented || isClearDisabled)) clearValue();
711
+ };
712
+ return /*#__PURE__*/ jsx(Button, {
713
+ ...clearProps,
714
+ className: styles.clearTrigger({
715
+ className
716
+ }),
717
+ "data-readonly": pickerApi.readOnly || void 0,
718
+ disabled: isClearDisabled,
719
+ icon: icon ?? (children ? void 0 : "token-icon-date-picker-clear"),
720
+ iconSize: iconSize,
721
+ onClick: handleClick,
722
+ ref: ref,
723
+ size: size,
724
+ theme: theme,
725
+ type: type,
726
+ children: children
727
+ });
728
+ };
729
+ DatePicker.Positioner = function({ children, className, forceMount = false, ref, ...props }) {
730
+ const { pickerApi, styles } = useDatePickerContext();
731
+ if (!(pickerApi.open || forceMount)) return null;
732
+ const positionerProps = mergeProps(props, pickerApi.getPositionerProps());
733
+ const node = /*#__PURE__*/ jsx("div", {
734
+ ...positionerProps,
735
+ className: styles.positioner({
736
+ className
737
+ }),
738
+ ref: ref,
739
+ children: children
740
+ });
741
+ return /*#__PURE__*/ jsx(Portal, {
742
+ children: node
743
+ });
744
+ };
745
+ DatePicker.Content = function({ className, ref, ...props }) {
746
+ const { isTimed, pickerApi, selectionMode, styles } = useDatePickerContext();
747
+ const contentProps = mergeProps(props, pickerApi.getContentProps());
748
+ return /*#__PURE__*/ jsx("div", {
749
+ ...contentProps,
750
+ className: styles.content({
751
+ className
752
+ }),
753
+ "data-selection-mode": selectionMode,
754
+ "data-timed": isTimed || void 0,
755
+ ref: ref
756
+ });
757
+ };
758
+ DatePicker.Calendar = function({ className, ref, ...props }) {
759
+ const { acceptedValue, max, min, numOfMonths, pickerApi, selectionMode, styles } = useDatePickerContext();
760
+ const createPanelMonths = ()=>Array.from({
761
+ length: numOfMonths
762
+ }, (_, index)=>pickerApi.visibleRange.start.add({
763
+ months: index
764
+ }).set({
765
+ day: 1
766
+ }));
767
+ const [panelMonths, setPanelMonths] = useState(createPanelMonths);
768
+ const [activePanelIndex, setActivePanelIndex] = useState(null);
769
+ const acceptedValueKey = JSON.stringify(serializeDatePickerValue(acceptedValue));
770
+ const previousAcceptedValue = useRef(acceptedValueKey);
771
+ const previousNumOfMonths = useRef(numOfMonths);
772
+ const previousView = useRef(pickerApi.view);
773
+ const focusedMonthKey = `${pickerApi.focusedValue.year}-${pickerApi.focusedValue.month}`;
774
+ const visibleRangeStartKey = pickerApi.visibleRange.start.toString();
775
+ useEffect(()=>{
776
+ if ("single" !== selectionMode) return;
777
+ setPanelMonths(createPanelMonths());
778
+ }, [
779
+ numOfMonths,
780
+ selectionMode,
781
+ visibleRangeStartKey
782
+ ]);
783
+ useEffect(()=>{
784
+ if (previousAcceptedValue.current === acceptedValueKey && previousNumOfMonths.current === numOfMonths) return;
785
+ previousAcceptedValue.current = acceptedValueKey;
786
+ previousNumOfMonths.current = numOfMonths;
787
+ setPanelMonths(createPanelMonths());
788
+ setActivePanelIndex(null);
789
+ pickerApi.setView("day");
790
+ }, [
791
+ acceptedValueKey,
792
+ numOfMonths
793
+ ]);
794
+ useEffect(()=>{
795
+ const returnedToDay = "day" !== previousView.current && "day" === pickerApi.view;
796
+ previousView.current = pickerApi.view;
797
+ if (!(returnedToDay && null !== activePanelIndex)) return;
798
+ const selectedMonth = pickerApi.focusedValue.set({
799
+ day: 1
800
+ });
801
+ setPanelMonths((current)=>current.map((month, index)=>index === activePanelIndex ? selectedMonth : month));
802
+ setActivePanelIndex(null);
803
+ }, [
804
+ activePanelIndex,
805
+ focusedMonthKey,
806
+ pickerApi.view
807
+ ]);
808
+ const canShowPanelMonth = (index, value)=>{
809
+ const monthStart = value.set({
810
+ day: 1
811
+ });
812
+ const monthEnd = monthStart.add({
813
+ months: 1
814
+ }).subtract({
815
+ days: 1
816
+ });
817
+ const previousMonth = panelMonths[index - 1];
818
+ const nextMonth = panelMonths[index + 1];
819
+ if (min && monthEnd.compare(min) < 0) return false;
820
+ if (max && monthStart.compare(max) > 0) return false;
821
+ if (previousMonth && monthStart.compare(previousMonth) <= 0) return false;
822
+ if (nextMonth && monthStart.compare(nextMonth) >= 0) return false;
823
+ return true;
824
+ };
825
+ const movePanel = (index, months)=>{
826
+ const currentMonth = panelMonths[index];
827
+ if (!currentMonth) return;
828
+ const nextMonth = currentMonth.add({
829
+ months
830
+ }).set({
831
+ day: 1
832
+ });
833
+ if (!canShowPanelMonth(index, nextMonth)) return;
834
+ setPanelMonths((current)=>current.map((month, panelIndex)=>panelIndex === index ? nextMonth : month));
835
+ setActivePanelIndex(null);
836
+ pickerApi.setView("day");
837
+ pickerApi.setFocusedValue(nextMonth);
838
+ };
839
+ const openPeriodChooser = (index)=>{
840
+ const panelMonth = panelMonths[index];
841
+ if (!panelMonth) return;
842
+ setActivePanelIndex(index);
843
+ pickerApi.setFocusedValue(panelMonth);
844
+ pickerApi.setView("month");
845
+ };
846
+ const renderPanelNavigationTrigger = (index, months, view)=>{
847
+ const isPrevious = months < 0;
848
+ const machineProps = isPrevious ? pickerApi.getPrevTriggerProps({
849
+ view
850
+ }) : pickerApi.getNextTriggerProps({
851
+ view
852
+ });
853
+ const panelMonth = panelMonths[index];
854
+ const nextMonth = panelMonth?.add({
855
+ months
856
+ }).set({
857
+ day: 1
858
+ });
859
+ const disabled = pickerApi.disabled || !nextMonth || !canShowPanelMonth(index, nextMonth);
860
+ const isYearJump = 12 === Math.abs(months);
861
+ return /*#__PURE__*/ jsx(Button, {
862
+ ...machineProps,
863
+ className: styles.navigationTrigger(),
864
+ disabled: disabled,
865
+ icon: isYearJump ? isPrevious ? "token-icon-date-picker-previous-year" : "token-icon-date-picker-next-year" : isPrevious ? "token-icon-date-picker-previous" : "token-icon-date-picker-next",
866
+ iconSize: "current",
867
+ id: `${machineProps.id}-${index}-${Math.abs(months)}`,
868
+ onClick: ()=>movePanel(index, months),
869
+ size: "current",
870
+ theme: "unstyled",
871
+ type: "button"
872
+ });
873
+ };
874
+ const renderDayView = (month, index)=>{
875
+ const visibleRange = {
876
+ end: month.add({
877
+ months: 1
878
+ }).subtract({
879
+ days: 1
880
+ }),
881
+ start: month
882
+ };
883
+ const viewProps = pickerApi.getViewProps({
884
+ view: "day"
885
+ });
886
+ return /*#__PURE__*/ jsx("div", {
887
+ ...viewProps,
888
+ className: styles.view(),
889
+ hidden: false,
890
+ children: /*#__PURE__*/ jsxs("table", {
891
+ ...pickerApi.getTableProps({
892
+ id: `panel-${index}`,
893
+ view: "day"
894
+ }),
895
+ className: styles.table(),
896
+ children: [
897
+ /*#__PURE__*/ jsx("thead", {
898
+ ...pickerApi.getTableHeadProps({
899
+ view: "day"
900
+ }),
901
+ children: /*#__PURE__*/ jsx("tr", {
902
+ ...pickerApi.getTableRowProps({
903
+ view: "day"
904
+ }),
905
+ children: pickerApi.weekDays.map((weekDay)=>/*#__PURE__*/ createElement("th", {
906
+ ...pickerApi.getTableHeaderProps({
907
+ view: "day"
908
+ }),
909
+ className: styles.tableHeader(),
910
+ key: weekDay.value.toString(),
911
+ scope: "col"
912
+ }, /*#__PURE__*/ jsx("abbr", {
913
+ title: weekDay.long,
914
+ children: weekDay.short
915
+ })))
916
+ })
917
+ }),
918
+ /*#__PURE__*/ jsx("tbody", {
919
+ ...pickerApi.getTableBodyProps({
920
+ view: "day"
921
+ }),
922
+ children: pickerApi.getMonthWeeks(month).map((week)=>/*#__PURE__*/ createElement("tr", {
923
+ ...pickerApi.getTableRowProps({
924
+ view: "day"
925
+ }),
926
+ key: week[0]?.toString()
927
+ }, week.map((day)=>/*#__PURE__*/ createElement("td", {
928
+ ...pickerApi.getDayTableCellProps({
929
+ value: day,
930
+ visibleRange
931
+ }),
932
+ className: styles.tableCell(),
933
+ key: day.toString()
934
+ }, /*#__PURE__*/ jsx(Button, {
935
+ ...pickerApi.getDayTableCellTriggerProps({
936
+ value: day,
937
+ visibleRange
938
+ }),
939
+ className: styles.dayTrigger(),
940
+ size: "current",
941
+ theme: "unstyled",
942
+ type: "button",
943
+ children: pickerApi.format(day, {
944
+ day: "numeric"
945
+ })
946
+ })))))
947
+ })
948
+ ]
949
+ })
950
+ });
951
+ };
952
+ const renderMonthView = (index)=>/*#__PURE__*/ jsx("div", {
953
+ ...pickerApi.getViewProps({
954
+ view: "month"
955
+ }),
956
+ className: styles.view(),
957
+ children: /*#__PURE__*/ jsx("table", {
958
+ ...pickerApi.getTableProps({
959
+ columns: 3,
960
+ view: "month"
961
+ }),
962
+ className: styles.table(),
963
+ children: /*#__PURE__*/ jsx("tbody", {
964
+ ...pickerApi.getTableBodyProps({
965
+ view: "month"
966
+ }),
967
+ children: pickerApi.getMonthsGrid({
968
+ columns: 3
969
+ }).map((row)=>/*#__PURE__*/ createElement("tr", {
970
+ ...pickerApi.getTableRowProps({
971
+ view: "month"
972
+ }),
973
+ key: row[0]?.value
974
+ }, row.map((month)=>{
975
+ const candidate = pickerApi.focusedValue.set({
976
+ month: month.value
977
+ }).set({
978
+ day: 1
979
+ });
980
+ const machineProps = pickerApi.getMonthTableCellTriggerProps({
981
+ columns: 3,
982
+ value: month.value
983
+ });
984
+ const disabled = Boolean(machineProps.disabled) || !canShowPanelMonth(index, candidate);
985
+ return /*#__PURE__*/ createElement("td", {
986
+ ...pickerApi.getMonthTableCellProps({
987
+ columns: 3,
988
+ value: month.value
989
+ }),
990
+ "aria-disabled": disabled || void 0,
991
+ className: styles.tableCell(),
992
+ key: month.value
993
+ }, /*#__PURE__*/ jsx(Button, {
994
+ ...machineProps,
995
+ "aria-disabled": disabled || void 0,
996
+ className: styles.periodTrigger(),
997
+ "data-disabled": disabled || void 0,
998
+ disabled: disabled,
999
+ size: "current",
1000
+ theme: "unstyled",
1001
+ type: "button",
1002
+ children: month.label
1003
+ }));
1004
+ })))
1005
+ })
1006
+ })
1007
+ });
1008
+ const renderYearView = ()=>/*#__PURE__*/ jsx("div", {
1009
+ ...pickerApi.getViewProps({
1010
+ view: "year"
1011
+ }),
1012
+ className: styles.view(),
1013
+ children: /*#__PURE__*/ jsx("table", {
1014
+ ...pickerApi.getTableProps({
1015
+ columns: 4,
1016
+ view: "year"
1017
+ }),
1018
+ className: styles.table(),
1019
+ children: /*#__PURE__*/ jsx("tbody", {
1020
+ ...pickerApi.getTableBodyProps({
1021
+ view: "year"
1022
+ }),
1023
+ children: pickerApi.getYearsGrid({
1024
+ columns: 4
1025
+ }).map((row)=>/*#__PURE__*/ createElement("tr", {
1026
+ ...pickerApi.getTableRowProps({
1027
+ view: "year"
1028
+ }),
1029
+ key: row[0]?.value
1030
+ }, row.map((year)=>/*#__PURE__*/ createElement("td", {
1031
+ ...pickerApi.getYearTableCellProps({
1032
+ columns: 4,
1033
+ value: year.value
1034
+ }),
1035
+ className: styles.tableCell(),
1036
+ key: year.value
1037
+ }, /*#__PURE__*/ jsx(Button, {
1038
+ ...pickerApi.getYearTableCellTriggerProps({
1039
+ columns: 4,
1040
+ value: year.value
1041
+ }),
1042
+ className: styles.periodTrigger(),
1043
+ size: "current",
1044
+ theme: "unstyled",
1045
+ type: "button",
1046
+ children: year.label
1047
+ })))))
1048
+ })
1049
+ })
1050
+ });
1051
+ const renderPeriodPanel = (index)=>/*#__PURE__*/ jsxs(Fragment, {
1052
+ children: [
1053
+ /*#__PURE__*/ jsxs("div", {
1054
+ ...pickerApi.getViewControlProps({
1055
+ view: pickerApi.view
1056
+ }),
1057
+ className: styles.viewControl(),
1058
+ children: [
1059
+ /*#__PURE__*/ jsx(Button, {
1060
+ ...pickerApi.getPrevTriggerProps({
1061
+ view: pickerApi.view
1062
+ }),
1063
+ className: styles.navigationTrigger(),
1064
+ icon: "token-icon-date-picker-previous",
1065
+ iconSize: "current",
1066
+ size: "current",
1067
+ theme: "unstyled",
1068
+ type: "button"
1069
+ }),
1070
+ "month" === pickerApi.view ? /*#__PURE__*/ jsx(Button, {
1071
+ ...pickerApi.getViewTriggerProps({
1072
+ view: "month"
1073
+ }),
1074
+ className: styles.viewTrigger(),
1075
+ size: "current",
1076
+ theme: "unstyled",
1077
+ type: "button",
1078
+ children: pickerApi.focusedValue.year
1079
+ }) : /*#__PURE__*/ jsxs("span", {
1080
+ className: styles.viewHeading(),
1081
+ children: [
1082
+ pickerApi.getDecade().start,
1083
+ "–",
1084
+ pickerApi.getDecade().end
1085
+ ]
1086
+ }),
1087
+ /*#__PURE__*/ jsx(Button, {
1088
+ ...pickerApi.getNextTriggerProps({
1089
+ view: pickerApi.view
1090
+ }),
1091
+ className: styles.navigationTrigger(),
1092
+ icon: "token-icon-date-picker-next",
1093
+ iconSize: "current",
1094
+ size: "current",
1095
+ theme: "unstyled",
1096
+ type: "button"
1097
+ })
1098
+ ]
1099
+ }),
1100
+ "month" === pickerApi.view ? renderMonthView(index) : null,
1101
+ "year" === pickerApi.view ? renderYearView() : null
1102
+ ]
1103
+ });
1104
+ const renderDayPanel = (month, index)=>{
1105
+ const monthText = pickerApi.format(month, {
1106
+ month: "short",
1107
+ year: "numeric"
1108
+ });
1109
+ const monthLabel = pickerApi.format(month, {
1110
+ month: "long",
1111
+ year: "numeric"
1112
+ });
1113
+ const viewTriggerProps = pickerApi.getViewTriggerProps({
1114
+ view: "day"
1115
+ });
1116
+ const isPeriodPanel = activePanelIndex === index && "day" !== pickerApi.view;
1117
+ const isInactivePanel = null !== activePanelIndex && activePanelIndex !== index;
1118
+ return /*#__PURE__*/ jsx("div", {
1119
+ className: styles.monthPanel(),
1120
+ "data-index": index,
1121
+ "data-view": isPeriodPanel ? pickerApi.view : "day",
1122
+ inert: isInactivePanel || void 0,
1123
+ children: isPeriodPanel ? renderPeriodPanel(index) : /*#__PURE__*/ jsxs(Fragment, {
1124
+ children: [
1125
+ /*#__PURE__*/ jsxs("div", {
1126
+ ...pickerApi.getViewControlProps({
1127
+ view: "day"
1128
+ }),
1129
+ className: styles.viewControl(),
1130
+ children: [
1131
+ renderPanelNavigationTrigger(index, -12, "month"),
1132
+ renderPanelNavigationTrigger(index, -1, "day"),
1133
+ /*#__PURE__*/ jsx(Button, {
1134
+ ...viewTriggerProps,
1135
+ "aria-label": `${viewTriggerProps["aria-label"]}: ${monthLabel}`,
1136
+ className: styles.viewTrigger(),
1137
+ id: `${viewTriggerProps.id}-${index}`,
1138
+ onClick: ()=>openPeriodChooser(index),
1139
+ size: "current",
1140
+ theme: "unstyled",
1141
+ title: monthLabel,
1142
+ type: "button",
1143
+ children: monthText
1144
+ }),
1145
+ renderPanelNavigationTrigger(index, 1, "day"),
1146
+ renderPanelNavigationTrigger(index, 12, "month")
1147
+ ]
1148
+ }),
1149
+ renderDayView(month, index)
1150
+ ]
1151
+ })
1152
+ }, index);
1153
+ };
1154
+ return /*#__PURE__*/ jsx("div", {
1155
+ ...props,
1156
+ className: styles.calendar({
1157
+ className
1158
+ }),
1159
+ "data-part": "calendar",
1160
+ "data-scope": "date-picker",
1161
+ "data-selection-mode": selectionMode,
1162
+ "data-view": null === activePanelIndex ? "day" : pickerApi.view,
1163
+ ref: ref,
1164
+ children: panelMonths.map(renderDayPanel)
1165
+ });
1166
+ };
1167
+ DatePicker.TimeControl = function({ className, endLabel = "End time", ref, startLabel = "Start time", ...props }) {
1168
+ const { coordinator, granularity, hideTimeZone, hourCycle, isTimed, pickerApi, selectionMode, setDraftTimePart, styles } = useDatePickerContext();
1169
+ if (!isTimed) return null;
1170
+ const visibleParts = [
1171
+ {
1172
+ label: "Hour",
1173
+ part: "hour"
1174
+ },
1175
+ ..."minute" === granularity || "second" === granularity ? [
1176
+ {
1177
+ label: "Minute",
1178
+ part: "minute"
1179
+ }
1180
+ ] : [],
1181
+ ..."second" === granularity ? [
1182
+ {
1183
+ label: "Second",
1184
+ part: "second"
1185
+ }
1186
+ ] : []
1187
+ ];
1188
+ const draftValues = toDateValues(coordinator.draft?.candidate);
1189
+ const renderTimeGroup = (index, accessibleLabel)=>{
1190
+ const candidate = draftValues[index];
1191
+ const timeParts = getDatePickerDraftTimeParts(coordinator, hourCycle, index);
1192
+ const isDisabled = pickerApi.disabled || pickerApi.readOnly || !candidate;
1193
+ const candidateTimeZone = !hideTimeZone && candidate && "timeZone" in candidate ? candidate.timeZone : null;
1194
+ return /*#__PURE__*/ jsxs("div", {
1195
+ "aria-label": accessibleLabel,
1196
+ className: styles.timeGroup(),
1197
+ "data-index": index,
1198
+ role: "group",
1199
+ children: [
1200
+ /*#__PURE__*/ jsx("span", {
1201
+ "aria-hidden": "true",
1202
+ className: styles.timeGroupLabel(),
1203
+ children: accessibleLabel
1204
+ }),
1205
+ /*#__PURE__*/ jsxs("div", {
1206
+ className: styles.timeFields(),
1207
+ children: [
1208
+ visibleParts.map(({ label, part }, partIndex)=>{
1209
+ const hourMaximum = 12 === hourCycle ? 12 : 23;
1210
+ const max = "hour" === part ? hourMaximum : 59;
1211
+ const min = "hour" === part && 12 === hourCycle ? 1 : 0;
1212
+ return /*#__PURE__*/ jsxs(external_react_Fragment, {
1213
+ children: [
1214
+ partIndex > 0 ? /*#__PURE__*/ jsx("span", {
1215
+ "aria-hidden": "true",
1216
+ className: styles.timeSeparator(),
1217
+ children: ":"
1218
+ }) : null,
1219
+ /*#__PURE__*/ jsxs("div", {
1220
+ className: styles.timeField(),
1221
+ children: [
1222
+ /*#__PURE__*/ jsx("span", {
1223
+ className: styles.timeLabel(),
1224
+ children: label
1225
+ }),
1226
+ /*#__PURE__*/ jsx(Input, {
1227
+ "aria-label": "range" === selectionMode ? `${accessibleLabel} ${label.toLowerCase()}` : label,
1228
+ className: styles.timeInput(),
1229
+ disabled: isDisabled,
1230
+ inputMode: "numeric",
1231
+ max: max,
1232
+ min: min,
1233
+ onChange: (event)=>{
1234
+ const nextValue = event.currentTarget.value;
1235
+ if ("" === nextValue) return void setDraftTimePart(part, null, index);
1236
+ const parsedValue = Number(nextValue);
1237
+ if (Number.isInteger(parsedValue) && parsedValue >= min && parsedValue <= max) setDraftTimePart(part, parsedValue, index);
1238
+ },
1239
+ placeholder: "--",
1240
+ readOnly: pickerApi.readOnly,
1241
+ size: "sm",
1242
+ step: 1,
1243
+ type: "number",
1244
+ value: timeParts[part] ?? ""
1245
+ })
1246
+ ]
1247
+ })
1248
+ ]
1249
+ }, part);
1250
+ }),
1251
+ 12 === hourCycle ? /*#__PURE__*/ jsxs("div", {
1252
+ className: styles.timeField(),
1253
+ children: [
1254
+ /*#__PURE__*/ jsx("span", {
1255
+ className: styles.timeLabel(),
1256
+ children: "Day period"
1257
+ }),
1258
+ /*#__PURE__*/ jsxs("select", {
1259
+ "aria-label": "range" === selectionMode ? `${accessibleLabel} day period` : "Day period",
1260
+ className: styles.dayPeriod(),
1261
+ disabled: isDisabled,
1262
+ onChange: (event)=>{
1263
+ const nextValue = event.currentTarget.value;
1264
+ setDraftTimePart("dayPeriod", "" === nextValue ? null : Number(nextValue), index);
1265
+ },
1266
+ value: timeParts.dayPeriod ?? "",
1267
+ children: [
1268
+ /*#__PURE__*/ jsx("option", {
1269
+ value: "",
1270
+ children: "--"
1271
+ }),
1272
+ /*#__PURE__*/ jsx("option", {
1273
+ value: "0",
1274
+ children: "AM"
1275
+ }),
1276
+ /*#__PURE__*/ jsx("option", {
1277
+ value: "12",
1278
+ children: "PM"
1279
+ })
1280
+ ]
1281
+ })
1282
+ ]
1283
+ }) : null,
1284
+ candidateTimeZone ? /*#__PURE__*/ jsx("span", {
1285
+ className: styles.timeZone(),
1286
+ title: candidateTimeZone,
1287
+ children: candidateTimeZone
1288
+ }) : null
1289
+ ]
1290
+ })
1291
+ ]
1292
+ });
1293
+ };
1294
+ return /*#__PURE__*/ jsxs("div", {
1295
+ ...props,
1296
+ "aria-label": "single" === selectionMode ? props["aria-label"] ?? "Time" : void 0,
1297
+ className: styles.timeControl({
1298
+ className
1299
+ }),
1300
+ "data-granularity": granularity,
1301
+ "data-hour-cycle": hourCycle,
1302
+ "data-part": "time-control",
1303
+ "data-scope": "date-picker",
1304
+ "data-selection-mode": selectionMode,
1305
+ ref: ref,
1306
+ role: "single" === selectionMode ? "group" : void 0,
1307
+ children: [
1308
+ renderTimeGroup(0, "range" === selectionMode ? startLabel : "Time"),
1309
+ "range" === selectionMode ? renderTimeGroup(1, endLabel) : null
1310
+ ]
1311
+ });
1312
+ };
1313
+ DatePicker.Footer = function({ className, ref, ...props }) {
1314
+ const { styles } = useDatePickerContext();
1315
+ return /*#__PURE__*/ jsx("div", {
1316
+ ...props,
1317
+ className: styles.footer({
1318
+ className
1319
+ }),
1320
+ "data-part": "footer",
1321
+ "data-scope": "date-picker",
1322
+ ref: ref
1323
+ });
1324
+ };
1325
+ DatePicker.CancelTrigger = function({ children = "Cancel", className, onClick, ref, size: sizeProp, theme = "borderless", type = "button", variant = "primary", ...props }) {
1326
+ const { requestOpen, size, styles } = useDatePickerContext();
1327
+ const actionSize = sizeProp ?? ("lg" === size ? "md" : "sm");
1328
+ const handleClick = (event)=>{
1329
+ onClick?.(event);
1330
+ if (!event.defaultPrevented) requestOpen(false);
1331
+ };
1332
+ return /*#__PURE__*/ jsx(Button, {
1333
+ ...props,
1334
+ className: styles.cancelTrigger({
1335
+ className
1336
+ }),
1337
+ "data-part": "cancel-trigger",
1338
+ "data-scope": "date-picker",
1339
+ onClick: handleClick,
1340
+ ref: ref,
1341
+ size: actionSize,
1342
+ theme: theme,
1343
+ type: type,
1344
+ variant: variant,
1345
+ children: children
1346
+ });
1347
+ };
1348
+ DatePicker.ConfirmTrigger = function({ children = "Confirm", className, disabled, onClick, ref, size: sizeProp, theme = "solid", type = "button", variant = "primary", ...props }) {
1349
+ const { canConfirm, size, styles, submitDraft } = useDatePickerContext();
1350
+ const actionSize = sizeProp ?? ("lg" === size ? "md" : "sm");
1351
+ const handleClick = (event)=>{
1352
+ onClick?.(event);
1353
+ if (!event.defaultPrevented) submitDraft();
1354
+ };
1355
+ return /*#__PURE__*/ jsx(Button, {
1356
+ ...props,
1357
+ className: styles.confirmTrigger({
1358
+ className
1359
+ }),
1360
+ "data-part": "confirm-trigger",
1361
+ "data-scope": "date-picker",
1362
+ disabled: disabled || !canConfirm,
1363
+ onClick: handleClick,
1364
+ ref: ref,
1365
+ size: actionSize,
1366
+ theme: theme,
1367
+ type: type,
1368
+ variant: variant,
1369
+ children: children
1370
+ });
1371
+ };
1372
+ DatePicker.Root = DatePicker;
1373
+ DatePicker.displayName = "DatePicker";
1374
+ export { DatePicker };