@kazee-ds/react 0.6.0 → 0.8.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.
- package/README.md +2 -2
- package/dist/index.js +2077 -179
- package/dist/index.js.map +1 -1
- package/dist/types/Avatar.d.ts +42 -0
- package/dist/types/AvatarGroup.d.ts +18 -0
- package/dist/types/Badge.d.ts +23 -5
- package/dist/types/Button.d.ts +1 -1
- package/dist/types/Calendar.d.ts +60 -0
- package/dist/types/Card.d.ts +30 -8
- package/dist/types/DropdownMenu.d.ts +2 -1
- package/dist/types/Input.d.ts +8 -3
- package/dist/types/OverlayDirection.d.ts +1 -1
- package/dist/types/Select.d.ts +2 -2
- package/dist/types/Switch.d.ts +9 -2
- package/dist/types/Tabs.d.ts +3 -1
- package/dist/types/TemporalField.d.ts +36 -0
- package/dist/types/TemporalPicker.d.ts +137 -0
- package/dist/types/TimeControls.d.ts +14 -0
- package/dist/types/ToggleButton.d.ts +2 -1
- package/dist/types/ToggleButtonGroup.d.ts +2 -0
- package/dist/types/choice-composition.d.ts +5 -2
- package/dist/types/control-composition.d.ts +6 -5
- package/dist/types/date-range-model.d.ts +3 -1
- package/dist/types/index.d.ts +19 -1
- package/dist/types/input-clear.d.ts +24 -0
- package/dist/types/switch-visual.d.ts +21 -0
- package/dist/types/temporal-model.d.ts +44 -0
- package/dist/types/toggle-group-model.d.ts +1 -1
- package/dist/types/visual-slot.d.ts +3 -0
- package/dist/types/visual.d.ts +5 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -27,8 +27,11 @@ import { Tooltip as Tooltip$1, TooltipTrigger } from "react-aria-components/Tool
|
|
|
27
27
|
import { Menu, MenuItem, MenuSection, MenuTrigger, SubmenuTrigger } from "react-aria-components/Menu";
|
|
28
28
|
import { Separator as Separator$1 } from "react-aria-components/Separator";
|
|
29
29
|
import { Button as Button$5, ComboBox, ComboBoxStateContext, Input as Input$3, Label as Label$6, ListBox as ListBox$3, ListBoxItem as ListBoxItem$2, Popover as Popover$3 } from "react-aria-components/ComboBox";
|
|
30
|
-
import { CalendarCell, CalendarGrid, CalendarGridBody, CalendarGridHeader, CalendarHeaderCell,
|
|
31
|
-
import { GregorianCalendar, endOfMonth, getLocalTimeZone, parseDate, startOfMonth, startOfWeek, today } from "@internationalized/date";
|
|
30
|
+
import { CalendarCell, CalendarGrid, CalendarGridBody, CalendarGridHeader, CalendarHeaderCell, RangeCalendar as RangeCalendar$1, RangeCalendarStateContext } from "react-aria-components/RangeCalendar";
|
|
31
|
+
import { CalendarDate, GregorianCalendar, endOfMonth, getLocalTimeZone, now, parseAbsolute, parseDate, parseDateTime, parseTime, parseZonedDateTime, startOfMonth, startOfWeek, toCalendarDateTime, toZoned, today } from "@internationalized/date";
|
|
32
|
+
import { Calendar as Calendar$1, CalendarCell as CalendarCell$1, CalendarGrid as CalendarGrid$1, CalendarGridBody as CalendarGridBody$1, CalendarGridHeader as CalendarGridHeader$1, CalendarHeaderCell as CalendarHeaderCell$1, CalendarStateContext } from "react-aria-components/Calendar";
|
|
33
|
+
import { DateField as DateField$1, DateInput, DateSegment } from "react-aria-components/DateField";
|
|
34
|
+
import { TimeField as TimeField$1 } from "react-aria-components/TimeField";
|
|
32
35
|
//#region src/Button.tsx
|
|
33
36
|
function PendingLabelAnchor() {
|
|
34
37
|
const context = useContext(ProgressBarContext);
|
|
@@ -80,7 +83,7 @@ function ButtonGroupSeparator({ className, style, classNames } = {}) {
|
|
|
80
83
|
"aria-hidden": "true"
|
|
81
84
|
});
|
|
82
85
|
}
|
|
83
|
-
function Root$
|
|
86
|
+
function Root$2({ children, label, variant, size, isDisabled, fullWidth, orientation = "horizontal", dir, className, style, classNames }) {
|
|
84
87
|
function defaults(nodes) {
|
|
85
88
|
return Children.map(nodes, (child) => {
|
|
86
89
|
if (!isValidElement(child)) return child;
|
|
@@ -104,12 +107,14 @@ function Root$1({ children, label, variant, size, isDisabled, fullWidth, orienta
|
|
|
104
107
|
children: defaults(children)
|
|
105
108
|
});
|
|
106
109
|
}
|
|
107
|
-
var ButtonGroup = /* @__PURE__ */ Object.assign(Root$
|
|
110
|
+
var ButtonGroup = /* @__PURE__ */ Object.assign(Root$2, { Separator: ButtonGroupSeparator });
|
|
108
111
|
//#endregion
|
|
109
112
|
//#region src/ToggleButton.tsx
|
|
110
113
|
var ToggleButtonSizeContext = createContext("md");
|
|
111
|
-
|
|
114
|
+
var ToggleButtonVariantContext = createContext("default");
|
|
115
|
+
function ToggleButton({ children, variant, size, isIconOnly, className: consumerClassName, classNames, style, ...props }) {
|
|
112
116
|
const inheritedSize = useContext(ToggleButtonSizeContext);
|
|
117
|
+
const inheritedVariant = useContext(ToggleButtonVariantContext);
|
|
113
118
|
const resolvedSize = size ?? inheritedSize;
|
|
114
119
|
return /* @__PURE__ */ jsx(ToggleButton$1, {
|
|
115
120
|
...props,
|
|
@@ -119,7 +124,7 @@ function ToggleButton({ children, variant = "default", size, isIconOnly, classNa
|
|
|
119
124
|
classNames?.root,
|
|
120
125
|
consumerClassName,
|
|
121
126
|
"toggle-button",
|
|
122
|
-
`toggle-button--${variant}`,
|
|
127
|
+
`toggle-button--${variant ?? inheritedVariant}`,
|
|
123
128
|
resolvedSize !== "md" && `button--${resolvedSize}`,
|
|
124
129
|
isIconOnly && "button--icon-only"
|
|
125
130
|
].filter(Boolean).join(" "),
|
|
@@ -144,41 +149,44 @@ function OverlayDirection({ dir, children }) {
|
|
|
144
149
|
//#endregion
|
|
145
150
|
//#region src/ToggleButtonGroup.tsx
|
|
146
151
|
var keys = (value) => Array.isArray(value) ? value : value ? [value] : [];
|
|
147
|
-
function Root(props) {
|
|
152
|
+
function Root$1(props) {
|
|
148
153
|
return /* @__PURE__ */ jsx(OverlayDirection, {
|
|
149
154
|
dir: props.dir,
|
|
150
155
|
children: /* @__PURE__ */ jsx(ToggleButtonSizeContext.Provider, {
|
|
151
156
|
value: props.size ?? "md",
|
|
152
|
-
children: /* @__PURE__ */ jsx(
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
157
|
+
children: /* @__PURE__ */ jsx(ToggleButtonVariantContext.Provider, {
|
|
158
|
+
value: props.variant ?? "default",
|
|
159
|
+
children: /* @__PURE__ */ jsx(ToggleButtonGroup$1, {
|
|
160
|
+
"aria-label": props.label,
|
|
161
|
+
dir: props.dir,
|
|
162
|
+
className: [
|
|
163
|
+
"button-group",
|
|
164
|
+
props.classNames?.root,
|
|
165
|
+
props.className,
|
|
166
|
+
"toggle-button-group",
|
|
167
|
+
(props.isDetached ?? props.variant === "chip") && "button-group--detached",
|
|
168
|
+
props.fullWidth && "button-group--full-width"
|
|
169
|
+
].filter(Boolean).join(" "),
|
|
170
|
+
style: props.style,
|
|
171
|
+
orientation: props.orientation ?? "horizontal",
|
|
172
|
+
selectionMode: props.selectionMode ?? "single",
|
|
173
|
+
selectedKeys: props.value === void 0 ? void 0 : keys(props.value),
|
|
174
|
+
defaultSelectedKeys: keys(props.defaultValue),
|
|
175
|
+
onSelectionChange: (selected) => {
|
|
176
|
+
if (props.isDisabled) return;
|
|
177
|
+
const next = Array.from(selected, String);
|
|
178
|
+
if (props.selectionMode === "multiple") props.onChange?.(next);
|
|
179
|
+
else props.onChange?.(next[0] ?? null);
|
|
180
|
+
},
|
|
181
|
+
isDisabled: props.isDisabled,
|
|
182
|
+
disallowEmptySelection: props.disallowEmptySelection,
|
|
183
|
+
children: props.children
|
|
184
|
+
})
|
|
177
185
|
})
|
|
178
186
|
})
|
|
179
187
|
});
|
|
180
188
|
}
|
|
181
|
-
var ToggleButtonGroup = /* @__PURE__ */ Object.assign(Root, { Separator: ButtonGroupSeparator });
|
|
189
|
+
var ToggleButtonGroup = /* @__PURE__ */ Object.assign(Root$1, { Separator: ButtonGroupSeparator });
|
|
182
190
|
//#endregion
|
|
183
191
|
//#region src/label-context.ts
|
|
184
192
|
/** Item labels use Text slots rather than introducing native label elements. */
|
|
@@ -227,6 +235,64 @@ function CloseIcon({ className }) {
|
|
|
227
235
|
});
|
|
228
236
|
}
|
|
229
237
|
//#endregion
|
|
238
|
+
//#region src/input-clear.tsx
|
|
239
|
+
var InputClearContext = createContext(null);
|
|
240
|
+
function useClearableInput({ value, defaultValue = "", onChange, isDisabled, isReadOnly }, element) {
|
|
241
|
+
const [local, setLocal] = useState(defaultValue);
|
|
242
|
+
const current = value === void 0 ? local : value;
|
|
243
|
+
const update = (next) => {
|
|
244
|
+
if (!isDisabled && !isReadOnly) {
|
|
245
|
+
if (value === void 0) setLocal(next);
|
|
246
|
+
onChange?.(next);
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
useEffect(() => {
|
|
250
|
+
const form = (element.current instanceof HTMLInputElement || element.current instanceof HTMLTextAreaElement ? element.current : element.current?.querySelector("input,textarea"))?.form;
|
|
251
|
+
const reset = (event) => {
|
|
252
|
+
queueMicrotask(() => {
|
|
253
|
+
if (!event.defaultPrevented && value === void 0) setLocal(defaultValue);
|
|
254
|
+
});
|
|
255
|
+
};
|
|
256
|
+
form?.addEventListener("reset", reset);
|
|
257
|
+
return () => form?.removeEventListener("reset", reset);
|
|
258
|
+
}, [
|
|
259
|
+
element,
|
|
260
|
+
value,
|
|
261
|
+
defaultValue
|
|
262
|
+
]);
|
|
263
|
+
return {
|
|
264
|
+
value: current,
|
|
265
|
+
update,
|
|
266
|
+
context: {
|
|
267
|
+
value: current,
|
|
268
|
+
disabled: isDisabled,
|
|
269
|
+
readOnly: isReadOnly,
|
|
270
|
+
clear: () => {
|
|
271
|
+
if (isDisabled || isReadOnly) return;
|
|
272
|
+
update("");
|
|
273
|
+
(element.current instanceof HTMLInputElement || element.current instanceof HTMLTextAreaElement ? element.current : element.current?.querySelector("input,textarea"))?.focus();
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
function InputClearButton({ className, children, onClick, ...props }) {
|
|
279
|
+
const context = useContext(InputClearContext);
|
|
280
|
+
if (!context) throw new Error("Input.ClearButton requires Input.Root.");
|
|
281
|
+
if (!context.value || context.readOnly) return null;
|
|
282
|
+
return /* @__PURE__ */ jsx("button", {
|
|
283
|
+
"aria-label": "Hapus input / Clear input",
|
|
284
|
+
...props,
|
|
285
|
+
type: "button",
|
|
286
|
+
className: partClass("input__clear", className),
|
|
287
|
+
disabled: context.disabled || props.disabled,
|
|
288
|
+
onClick: (event) => {
|
|
289
|
+
onClick?.(event);
|
|
290
|
+
if (!event.defaultPrevented) context.clear();
|
|
291
|
+
},
|
|
292
|
+
children: children ?? /* @__PURE__ */ jsx(CloseIcon, {})
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
//#endregion
|
|
230
296
|
//#region src/control-composition.tsx
|
|
231
297
|
var SelectPartsContext = createContext({
|
|
232
298
|
clearButtons: 0,
|
|
@@ -418,10 +484,24 @@ function FieldError({ className, ...props }) {
|
|
|
418
484
|
className: partClass(partClass("input__error", fieldClasses.error), className)
|
|
419
485
|
});
|
|
420
486
|
}
|
|
421
|
-
function InputRoot({ className, ...props }) {
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
487
|
+
function InputRoot({ className, size = "md", variant = "primary", hideLabel = false, value, defaultValue, onChange, ...props }) {
|
|
488
|
+
const root = useRef(null);
|
|
489
|
+
const clearable = useClearableInput({
|
|
490
|
+
value,
|
|
491
|
+
defaultValue,
|
|
492
|
+
onChange,
|
|
493
|
+
isDisabled: props.isDisabled,
|
|
494
|
+
isReadOnly: props.isReadOnly
|
|
495
|
+
}, root);
|
|
496
|
+
return /* @__PURE__ */ jsx(InputClearContext.Provider, {
|
|
497
|
+
value: clearable.context,
|
|
498
|
+
children: /* @__PURE__ */ jsx(TextField, {
|
|
499
|
+
...props,
|
|
500
|
+
ref: root,
|
|
501
|
+
value: clearable.value,
|
|
502
|
+
onChange: clearable.update,
|
|
503
|
+
className: partClass(`input input--${size} input--${variant}${hideLabel ? " input--label-hidden" : ""}`, className)
|
|
504
|
+
})
|
|
425
505
|
});
|
|
426
506
|
}
|
|
427
507
|
var InputControlRefContext = createContext(void 0);
|
|
@@ -717,10 +797,17 @@ function SelectGroup({ label, children, size, variant, fullWidth = true, isDisab
|
|
|
717
797
|
}
|
|
718
798
|
//#endregion
|
|
719
799
|
//#region src/Input.tsx
|
|
720
|
-
var CompactInput = /* @__PURE__ */ forwardRef(function Input({ label, value, defaultValue, onChange, description, errorMessage, isInvalid = false, isDisabled = false, isReadOnly = false, isRequired = false, placeholder, type = "text", size = "md", variant = "primary", fullWidth = true, prefix, suffix, name, id, autoComplete, maxLength, minLength, pattern, inputMode, enterKeyHint, autoFocus, spellCheck, form, onFocus, onBlur, onKeyDown, onKeyUp, dir, className, style, classNames }, ref) {
|
|
800
|
+
var CompactInput = /* @__PURE__ */ forwardRef(function Input({ label, value, defaultValue, onChange, description, errorMessage, isInvalid = false, isDisabled = false, isReadOnly = false, isRequired = false, placeholder, type = "text", size = "md", variant = "primary", fullWidth = true, hideLabel = false, isClearable = false, clearLabel, prefix, suffix, name, id, autoComplete, maxLength, minLength, pattern, inputMode, enterKeyHint, autoFocus, spellCheck, form, onFocus, onBlur, onKeyDown, onKeyUp, dir, className, style, classNames }, ref) {
|
|
721
801
|
const control = useRef(null);
|
|
802
|
+
const clearable = useClearableInput({
|
|
803
|
+
value,
|
|
804
|
+
defaultValue,
|
|
805
|
+
onChange,
|
|
806
|
+
isDisabled,
|
|
807
|
+
isReadOnly
|
|
808
|
+
}, control);
|
|
722
809
|
useImperativeHandle(ref, () => control.current);
|
|
723
|
-
const hasAdornment = prefix != null || suffix != null;
|
|
810
|
+
const hasAdornment = prefix != null || suffix != null || isClearable;
|
|
724
811
|
const input = /* @__PURE__ */ jsx(Input$1, {
|
|
725
812
|
ref: control,
|
|
726
813
|
className: partClass(partClass("input__control", classNames?.input), classNames?.control),
|
|
@@ -738,65 +825,71 @@ var CompactInput = /* @__PURE__ */ forwardRef(function Input({ label, value, def
|
|
|
738
825
|
onKeyDown,
|
|
739
826
|
onKeyUp
|
|
740
827
|
});
|
|
741
|
-
return /* @__PURE__ */
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
event.
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
828
|
+
return /* @__PURE__ */ jsx(InputClearContext.Provider, {
|
|
829
|
+
value: clearable.context,
|
|
830
|
+
children: /* @__PURE__ */ jsxs(TextField, {
|
|
831
|
+
className: partClass(partClass(`input input--${size} input--${variant}${fullWidth ? "" : " input--fit"}${hideLabel ? " input--label-hidden" : ""}`, classNames?.root), className),
|
|
832
|
+
style,
|
|
833
|
+
value: clearable.value,
|
|
834
|
+
onChange: clearable.update,
|
|
835
|
+
isInvalid,
|
|
836
|
+
isDisabled,
|
|
837
|
+
isReadOnly,
|
|
838
|
+
isRequired,
|
|
839
|
+
validationBehavior: "aria",
|
|
840
|
+
type,
|
|
841
|
+
name,
|
|
842
|
+
id,
|
|
843
|
+
autoComplete,
|
|
844
|
+
maxLength,
|
|
845
|
+
dir,
|
|
846
|
+
children: [
|
|
847
|
+
/* @__PURE__ */ jsx(Label$2, {
|
|
848
|
+
className: partClass("input__label", classNames?.label),
|
|
849
|
+
children: label
|
|
850
|
+
}),
|
|
851
|
+
/* @__PURE__ */ jsx("fieldset", {
|
|
852
|
+
className: partClass("input__boundary", classNames?.boundary),
|
|
853
|
+
role: "presentation",
|
|
854
|
+
disabled: isDisabled,
|
|
855
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
856
|
+
className: partClass(hasAdornment ? "input__group" : "input__plain", classNames?.group),
|
|
857
|
+
"data-invalid": isInvalid || void 0,
|
|
858
|
+
"data-readonly": isReadOnly || void 0,
|
|
859
|
+
onPointerDown: (event) => {
|
|
860
|
+
if (!isDisabled && !event.target.closest("input,button,a,select,textarea,[tabindex],[contenteditable]")) {
|
|
861
|
+
event.preventDefault();
|
|
862
|
+
control.current?.focus();
|
|
863
|
+
}
|
|
864
|
+
},
|
|
865
|
+
children: [
|
|
866
|
+
prefix != null && /* @__PURE__ */ jsx("span", {
|
|
867
|
+
className: partClass("input__prefix", classNames?.prefix),
|
|
868
|
+
children: prefix
|
|
869
|
+
}),
|
|
870
|
+
input,
|
|
871
|
+
isClearable && /* @__PURE__ */ jsx(InputClearButton, {
|
|
872
|
+
"aria-label": clearLabel ?? "Hapus input / Clear input",
|
|
873
|
+
className: classNames?.clearButton
|
|
874
|
+
}),
|
|
875
|
+
suffix != null && /* @__PURE__ */ jsx("span", {
|
|
876
|
+
className: partClass("input__suffix", classNames?.suffix),
|
|
877
|
+
children: suffix
|
|
878
|
+
})
|
|
879
|
+
]
|
|
880
|
+
})
|
|
881
|
+
}),
|
|
882
|
+
description && /* @__PURE__ */ jsx(Text$1, {
|
|
883
|
+
slot: "description",
|
|
884
|
+
className: partClass("input__description", classNames?.description),
|
|
885
|
+
children: description
|
|
886
|
+
}),
|
|
887
|
+
isInvalid && errorMessage && /* @__PURE__ */ jsx(FieldError$2, {
|
|
888
|
+
className: partClass("input__error", classNames?.error),
|
|
889
|
+
children: errorMessage
|
|
788
890
|
})
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
slot: "description",
|
|
792
|
-
className: partClass("input__description", classNames?.description),
|
|
793
|
-
children: description
|
|
794
|
-
}),
|
|
795
|
-
isInvalid && errorMessage && /* @__PURE__ */ jsx(FieldError$2, {
|
|
796
|
-
className: partClass("input__error", classNames?.error),
|
|
797
|
-
children: errorMessage
|
|
798
|
-
})
|
|
799
|
-
]
|
|
891
|
+
]
|
|
892
|
+
})
|
|
800
893
|
});
|
|
801
894
|
});
|
|
802
895
|
var Input = /* @__PURE__ */ Object.assign(/* @__PURE__ */ forwardRef(function InputWithComposition(props, ref) {
|
|
@@ -813,7 +906,8 @@ var Input = /* @__PURE__ */ Object.assign(/* @__PURE__ */ forwardRef(function In
|
|
|
813
906
|
Control: InputControl,
|
|
814
907
|
Group: InputGroup,
|
|
815
908
|
Prefix: InputPrefix,
|
|
816
|
-
Suffix: InputSuffix
|
|
909
|
+
Suffix: InputSuffix,
|
|
910
|
+
ClearButton: InputClearButton
|
|
817
911
|
});
|
|
818
912
|
//#endregion
|
|
819
913
|
//#region src/Textarea.tsx
|
|
@@ -894,6 +988,36 @@ function Label({ children, htmlFor, id, className, style, classNames }) {
|
|
|
894
988
|
});
|
|
895
989
|
}
|
|
896
990
|
//#endregion
|
|
991
|
+
//#region src/switch-visual.tsx
|
|
992
|
+
var SwitchVisualContext = createContext({});
|
|
993
|
+
function SwitchGroup({ size, tone, variant, isDisabled, orientation = "vertical", className, ...props }) {
|
|
994
|
+
const { label, ...native } = props;
|
|
995
|
+
return /* @__PURE__ */ jsx(SwitchVisualContext.Provider, {
|
|
996
|
+
value: {
|
|
997
|
+
size,
|
|
998
|
+
tone,
|
|
999
|
+
variant,
|
|
1000
|
+
isDisabled
|
|
1001
|
+
},
|
|
1002
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
1003
|
+
...native,
|
|
1004
|
+
role: "group",
|
|
1005
|
+
"aria-label": label ?? props["aria-label"],
|
|
1006
|
+
className: partClass("switch-group", className),
|
|
1007
|
+
"data-orientation": orientation
|
|
1008
|
+
})
|
|
1009
|
+
});
|
|
1010
|
+
}
|
|
1011
|
+
function useSwitchVisual(props) {
|
|
1012
|
+
const inherited = useContext(SwitchVisualContext);
|
|
1013
|
+
return {
|
|
1014
|
+
size: props.size ?? inherited.size ?? "md",
|
|
1015
|
+
tone: props.tone ?? inherited.tone ?? "primary",
|
|
1016
|
+
variant: props.variant ?? inherited.variant ?? "default",
|
|
1017
|
+
disabled: inherited.isDisabled
|
|
1018
|
+
};
|
|
1019
|
+
}
|
|
1020
|
+
//#endregion
|
|
897
1021
|
//#region src/choice-composition.tsx
|
|
898
1022
|
var ChoiceStateContext = createContext({
|
|
899
1023
|
isSelected: false,
|
|
@@ -939,24 +1063,43 @@ function ChoiceContent({ className, ...props }) {
|
|
|
939
1063
|
className: partClass("choice__label", className)
|
|
940
1064
|
});
|
|
941
1065
|
}
|
|
942
|
-
function SwitchComposition({ className, children, ...props }) {
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
1066
|
+
function SwitchComposition({ className, children, size, tone, variant, ...props }) {
|
|
1067
|
+
const visual = useSwitchVisual({
|
|
1068
|
+
size,
|
|
1069
|
+
tone,
|
|
1070
|
+
variant
|
|
1071
|
+
});
|
|
1072
|
+
return /* @__PURE__ */ jsx(SwitchVisualContext.Provider, {
|
|
1073
|
+
value: visual,
|
|
1074
|
+
children: /* @__PURE__ */ jsx(SwitchField, {
|
|
1075
|
+
...props,
|
|
1076
|
+
isDisabled: props.isDisabled ?? visual.disabled,
|
|
1077
|
+
className: partClass("input", className),
|
|
1078
|
+
children: (fieldState) => /* @__PURE__ */ jsx(SwitchButton, {
|
|
1079
|
+
className: "choice",
|
|
1080
|
+
children: (state) => /* @__PURE__ */ jsx(ChoiceStateContext.Provider, {
|
|
1081
|
+
value: state,
|
|
1082
|
+
children: /* @__PURE__ */ jsx(ItemLabelContext.Provider, {
|
|
1083
|
+
value: true,
|
|
1084
|
+
children: typeof children === "function" ? children({
|
|
1085
|
+
...fieldState,
|
|
1086
|
+
...state
|
|
1087
|
+
}) : children
|
|
1088
|
+
})
|
|
1089
|
+
})
|
|
951
1090
|
})
|
|
952
1091
|
})
|
|
953
1092
|
});
|
|
954
1093
|
}
|
|
955
1094
|
function SwitchControl({ className, ...props }) {
|
|
956
1095
|
const state = useContext(ChoiceStateContext);
|
|
1096
|
+
const visual = useSwitchVisual({});
|
|
957
1097
|
return /* @__PURE__ */ jsx("span", {
|
|
958
1098
|
...props,
|
|
959
1099
|
className: partClass("switch__control", className),
|
|
1100
|
+
"data-size": visual.size,
|
|
1101
|
+
"data-tone": visual.tone,
|
|
1102
|
+
"data-variant": visual.variant,
|
|
960
1103
|
"aria-hidden": "true",
|
|
961
1104
|
"data-state": state.isSelected ? "checked" : "unchecked",
|
|
962
1105
|
"data-disabled": state.isDisabled || void 0,
|
|
@@ -971,6 +1114,13 @@ function SwitchThumb({ className, ...props }) {
|
|
|
971
1114
|
"aria-hidden": "true"
|
|
972
1115
|
});
|
|
973
1116
|
}
|
|
1117
|
+
function SwitchIcon({ className, ...props }) {
|
|
1118
|
+
return /* @__PURE__ */ jsx("span", {
|
|
1119
|
+
...props,
|
|
1120
|
+
className: partClass("switch__icon", className),
|
|
1121
|
+
"aria-hidden": "true"
|
|
1122
|
+
});
|
|
1123
|
+
}
|
|
974
1124
|
function RadioGroupComposition({ className, ...props }) {
|
|
975
1125
|
return /* @__PURE__ */ jsx(RadioGroup$1, {
|
|
976
1126
|
...props,
|
|
@@ -1129,7 +1279,12 @@ var RadioGroup = /* @__PURE__ */ Object.assign(RadioGroupRoot, {
|
|
|
1129
1279
|
});
|
|
1130
1280
|
//#endregion
|
|
1131
1281
|
//#region src/Switch.tsx
|
|
1132
|
-
function CompactSwitch({ label, description, errorMessage, isInvalid = false, isSelected, defaultSelected, onChange, isDisabled = false, name, value = "on", id, dir, className, style, classNames }) {
|
|
1282
|
+
function CompactSwitch({ label, description, errorMessage, isInvalid = false, isSelected, defaultSelected, onChange, isDisabled, isReadOnly = false, isRequired = false, validate, validationBehavior = "aria", size, tone, variant, name, value = "on", id, dir, className, style, classNames }) {
|
|
1283
|
+
const visual = useSwitchVisual({
|
|
1284
|
+
size,
|
|
1285
|
+
tone,
|
|
1286
|
+
variant
|
|
1287
|
+
});
|
|
1133
1288
|
return /* @__PURE__ */ jsxs(SwitchField, {
|
|
1134
1289
|
className: partClass(partClass("input", classNames?.root), className),
|
|
1135
1290
|
style,
|
|
@@ -1137,9 +1292,12 @@ function CompactSwitch({ label, description, errorMessage, isInvalid = false, is
|
|
|
1137
1292
|
isSelected,
|
|
1138
1293
|
defaultSelected,
|
|
1139
1294
|
onChange,
|
|
1140
|
-
isDisabled,
|
|
1295
|
+
isDisabled: isDisabled ?? visual.disabled,
|
|
1296
|
+
isReadOnly,
|
|
1297
|
+
isRequired,
|
|
1298
|
+
validate,
|
|
1141
1299
|
isInvalid,
|
|
1142
|
-
validationBehavior
|
|
1300
|
+
validationBehavior,
|
|
1143
1301
|
name,
|
|
1144
1302
|
value,
|
|
1145
1303
|
id,
|
|
@@ -1149,6 +1307,9 @@ function CompactSwitch({ label, description, errorMessage, isInvalid = false, is
|
|
|
1149
1307
|
children: ({ isSelected: selected, isDisabled: disabled, isFocusVisible }) => /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
|
|
1150
1308
|
"aria-hidden": "true",
|
|
1151
1309
|
className: partClass("switch__control", classNames?.control),
|
|
1310
|
+
"data-size": visual.size,
|
|
1311
|
+
"data-tone": visual.tone,
|
|
1312
|
+
"data-variant": visual.variant,
|
|
1152
1313
|
"data-state": selected ? "checked" : "unchecked",
|
|
1153
1314
|
"data-disabled": disabled || void 0,
|
|
1154
1315
|
"data-invalid": isInvalid || void 0,
|
|
@@ -1179,6 +1340,7 @@ var Switch = /* @__PURE__ */ Object.assign(SwitchRoot, {
|
|
|
1179
1340
|
Root: SwitchComposition,
|
|
1180
1341
|
Control: SwitchControl,
|
|
1181
1342
|
Thumb: SwitchThumb,
|
|
1343
|
+
Icon: SwitchIcon,
|
|
1182
1344
|
Content: ChoiceContent
|
|
1183
1345
|
});
|
|
1184
1346
|
//#endregion
|
|
@@ -1561,14 +1723,68 @@ var NumberField = /* @__PURE__ */ Object.assign(NumberFieldRoot, {
|
|
|
1561
1723
|
});
|
|
1562
1724
|
//#endregion
|
|
1563
1725
|
//#region src/Card.tsx
|
|
1564
|
-
/**
|
|
1565
|
-
|
|
1726
|
+
/** Native primary action is a sibling of content, so nested controls remain valid HTML. */
|
|
1727
|
+
var CardTitleIdContext = createContext(void 0);
|
|
1728
|
+
function CardAction({ href, target, rel, onPress, isDisabled, isSelected, actionLabel, actionLabelledBy, actionClassName, renderLink }) {
|
|
1729
|
+
if (!href && !onPress) return null;
|
|
1730
|
+
if (href) {
|
|
1731
|
+
const props = {
|
|
1732
|
+
className: partClass("card__action", actionClassName),
|
|
1733
|
+
href: isDisabled ? void 0 : href,
|
|
1734
|
+
target,
|
|
1735
|
+
rel: rel ?? (target === "_blank" ? "noopener noreferrer" : void 0),
|
|
1736
|
+
"aria-label": actionLabel,
|
|
1737
|
+
"aria-disabled": isDisabled || void 0,
|
|
1738
|
+
"aria-labelledby": actionLabelledBy,
|
|
1739
|
+
role: isDisabled ? "link" : void 0,
|
|
1740
|
+
tabIndex: isDisabled ? -1 : void 0,
|
|
1741
|
+
onClick: (event) => {
|
|
1742
|
+
if (isDisabled) event.preventDefault();
|
|
1743
|
+
else onPress?.();
|
|
1744
|
+
}
|
|
1745
|
+
};
|
|
1746
|
+
return renderLink ? renderLink(props) : /* @__PURE__ */ jsx("a", {
|
|
1747
|
+
...props,
|
|
1748
|
+
"aria-label": actionLabel,
|
|
1749
|
+
"aria-labelledby": actionLabelledBy
|
|
1750
|
+
});
|
|
1751
|
+
}
|
|
1752
|
+
const props = {
|
|
1753
|
+
type: "button",
|
|
1754
|
+
className: partClass("card__action", actionClassName),
|
|
1755
|
+
"aria-label": actionLabel,
|
|
1756
|
+
"aria-labelledby": actionLabelledBy,
|
|
1757
|
+
"aria-pressed": isSelected,
|
|
1758
|
+
disabled: isDisabled,
|
|
1759
|
+
onClick: () => onPress?.()
|
|
1760
|
+
};
|
|
1761
|
+
return /* @__PURE__ */ jsx("button", { ...props });
|
|
1762
|
+
}
|
|
1763
|
+
function CompactCard({ title, description, headingLevel = 3, actions, header, titleExtras, footer, children, className, classNames, density, href, target, rel, onPress, isDisabled, isSelected, actionLabel, actionLabelledBy, actionClassName, renderLink, headerAlign, dividedHeader, flushFooter, ...props }) {
|
|
1566
1764
|
const Heading = `h${headingLevel}`;
|
|
1567
1765
|
return /* @__PURE__ */ jsxs("div", {
|
|
1568
1766
|
...props,
|
|
1767
|
+
"data-density": density,
|
|
1768
|
+
"data-interactive": !!(href || onPress) || void 0,
|
|
1769
|
+
"data-disabled": isDisabled || void 0,
|
|
1770
|
+
"data-selected": isSelected || void 0,
|
|
1569
1771
|
className: partClass(partClass("card", classNames?.root), className),
|
|
1570
1772
|
children: [
|
|
1773
|
+
/* @__PURE__ */ jsx(CardAction, {
|
|
1774
|
+
href,
|
|
1775
|
+
target,
|
|
1776
|
+
rel,
|
|
1777
|
+
onPress,
|
|
1778
|
+
isDisabled,
|
|
1779
|
+
isSelected,
|
|
1780
|
+
renderLink,
|
|
1781
|
+
actionClassName: partClass(classNames?.action ?? "", actionClassName),
|
|
1782
|
+
actionLabelledBy: actionLabelledBy ?? props["aria-labelledby"],
|
|
1783
|
+
actionLabel: actionLabel ?? title ?? props["aria-label"]
|
|
1784
|
+
}),
|
|
1571
1785
|
(title || description || actions || header || titleExtras) && /* @__PURE__ */ jsxs("div", {
|
|
1786
|
+
"data-align": headerAlign,
|
|
1787
|
+
"data-divided": dividedHeader || void 0,
|
|
1572
1788
|
className: partClass("card__header", classNames?.header),
|
|
1573
1789
|
children: [(title || description || header || titleExtras) && /* @__PURE__ */ jsx("div", {
|
|
1574
1790
|
className: partClass("card__heading", classNames?.heading),
|
|
@@ -1595,21 +1811,45 @@ function CompactCard({ title, description, headingLevel = 3, actions, header, ti
|
|
|
1595
1811
|
children
|
|
1596
1812
|
}),
|
|
1597
1813
|
footer && /* @__PURE__ */ jsx("div", {
|
|
1814
|
+
"data-flush": flushFooter || void 0,
|
|
1598
1815
|
className: partClass("card__footer", classNames?.footer),
|
|
1599
1816
|
children: footer
|
|
1600
1817
|
})
|
|
1601
1818
|
]
|
|
1602
1819
|
});
|
|
1603
1820
|
}
|
|
1604
|
-
function CardRoot({ className, ...props }) {
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1821
|
+
function CardRoot({ className, classNames, children, density, href, target, rel, onPress, isDisabled, isSelected, actionLabel, actionLabelledBy, actionClassName, renderLink, ...props }) {
|
|
1822
|
+
const titleId = useId();
|
|
1823
|
+
const label = actionLabel ?? props["aria-label"];
|
|
1824
|
+
return /* @__PURE__ */ jsx(CardTitleIdContext.Provider, {
|
|
1825
|
+
value: titleId,
|
|
1826
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
1827
|
+
...props,
|
|
1828
|
+
"data-density": density,
|
|
1829
|
+
"data-interactive": !!(href || onPress) || void 0,
|
|
1830
|
+
"data-disabled": isDisabled || void 0,
|
|
1831
|
+
"data-selected": isSelected || void 0,
|
|
1832
|
+
className: partClass(partClass("card", classNames?.root), className),
|
|
1833
|
+
children: [/* @__PURE__ */ jsx(CardAction, {
|
|
1834
|
+
href,
|
|
1835
|
+
target,
|
|
1836
|
+
rel,
|
|
1837
|
+
onPress,
|
|
1838
|
+
isDisabled,
|
|
1839
|
+
isSelected,
|
|
1840
|
+
renderLink,
|
|
1841
|
+
actionClassName: partClass(classNames?.action ?? "", actionClassName),
|
|
1842
|
+
actionLabel: label,
|
|
1843
|
+
actionLabelledBy: actionLabelledBy ?? props["aria-labelledby"] ?? (label ? void 0 : titleId)
|
|
1844
|
+
}), children]
|
|
1845
|
+
})
|
|
1608
1846
|
});
|
|
1609
1847
|
}
|
|
1610
|
-
function CardHeader({ className, ...props }) {
|
|
1848
|
+
function CardHeader({ className, align, divided, ...props }) {
|
|
1611
1849
|
return /* @__PURE__ */ jsx("div", {
|
|
1612
1850
|
...props,
|
|
1851
|
+
"data-align": align,
|
|
1852
|
+
"data-divided": divided || void 0,
|
|
1613
1853
|
className: partClass("card__header", className)
|
|
1614
1854
|
});
|
|
1615
1855
|
}
|
|
@@ -1626,8 +1866,10 @@ function CardTitleRow({ className, ...props }) {
|
|
|
1626
1866
|
});
|
|
1627
1867
|
}
|
|
1628
1868
|
function CardTitle({ className, headingLevel = 3, ...props }) {
|
|
1869
|
+
const titleId = useContext(CardTitleIdContext);
|
|
1629
1870
|
const Heading = `h${headingLevel}`;
|
|
1630
1871
|
return /* @__PURE__ */ jsx(Heading, {
|
|
1872
|
+
id: titleId,
|
|
1631
1873
|
...props,
|
|
1632
1874
|
className: partClass("card__title", className)
|
|
1633
1875
|
});
|
|
@@ -1650,9 +1892,10 @@ function CardContent({ className, ...props }) {
|
|
|
1650
1892
|
className: partClass("card__content", className)
|
|
1651
1893
|
});
|
|
1652
1894
|
}
|
|
1653
|
-
function CardFooter({ className, ...props }) {
|
|
1895
|
+
function CardFooter({ className, flush, ...props }) {
|
|
1654
1896
|
return /* @__PURE__ */ jsx("div", {
|
|
1655
1897
|
...props,
|
|
1898
|
+
"data-flush": flush || void 0,
|
|
1656
1899
|
className: partClass("card__footer", className)
|
|
1657
1900
|
});
|
|
1658
1901
|
}
|
|
@@ -1668,15 +1911,261 @@ var Card = /* @__PURE__ */ Object.assign(CompactCard, {
|
|
|
1668
1911
|
Footer: CardFooter
|
|
1669
1912
|
});
|
|
1670
1913
|
//#endregion
|
|
1914
|
+
//#region src/visual-slot.tsx
|
|
1915
|
+
/** Decorate one child while preserving its handlers and ref. */
|
|
1916
|
+
function visualSlot(children, props) {
|
|
1917
|
+
const child = Children.only(children);
|
|
1918
|
+
const merged = {
|
|
1919
|
+
...child.props,
|
|
1920
|
+
...props
|
|
1921
|
+
};
|
|
1922
|
+
merged.className = [props.className, child.props.className].filter(Boolean).join(" ");
|
|
1923
|
+
merged.style = {
|
|
1924
|
+
...props.style,
|
|
1925
|
+
...child.props.style
|
|
1926
|
+
};
|
|
1927
|
+
for (const key of Object.keys(props)) if (/^on[A-Z]/.test(key) && typeof child.props[key] === "function" && typeof props[key] === "function") merged[key] = (...args) => {
|
|
1928
|
+
child.props[key](...args);
|
|
1929
|
+
props[key](...args);
|
|
1930
|
+
};
|
|
1931
|
+
if (child.props.ref && props.ref) merged.ref = (node) => {
|
|
1932
|
+
const cleanups = [];
|
|
1933
|
+
for (const ref of [child.props.ref, props.ref]) if (typeof ref === "function") {
|
|
1934
|
+
const cleanup = ref(node);
|
|
1935
|
+
cleanups.push(typeof cleanup === "function" ? cleanup : () => {
|
|
1936
|
+
ref(null);
|
|
1937
|
+
});
|
|
1938
|
+
} else if (ref) {
|
|
1939
|
+
ref.current = node;
|
|
1940
|
+
cleanups.push(() => {
|
|
1941
|
+
ref.current = null;
|
|
1942
|
+
});
|
|
1943
|
+
}
|
|
1944
|
+
return () => {
|
|
1945
|
+
for (const cleanup of cleanups) cleanup();
|
|
1946
|
+
};
|
|
1947
|
+
};
|
|
1948
|
+
return cloneElement(child, merged);
|
|
1949
|
+
}
|
|
1950
|
+
//#endregion
|
|
1671
1951
|
//#region src/Badge.tsx
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1952
|
+
var AnchorContext = createContext(false);
|
|
1953
|
+
/** Static status text; wrap in Badge.Anchor to position it relative to another element. */
|
|
1954
|
+
function BadgeRoot({ tone = "neutral", size = "md", variant = "default", placement = "top-right", asChild, children, className, classNames, ...props }) {
|
|
1955
|
+
const anchored = useContext(AnchorContext);
|
|
1956
|
+
const attributes = {
|
|
1675
1957
|
...props,
|
|
1676
1958
|
className: partClass(partClass("badge", classNames?.root), className),
|
|
1959
|
+
"data-tone": tone,
|
|
1960
|
+
"data-size": size,
|
|
1961
|
+
"data-variant": variant,
|
|
1962
|
+
"data-placement": anchored ? placement : void 0,
|
|
1963
|
+
"data-anchored": anchored || void 0,
|
|
1964
|
+
"data-dot": anchored && children == null || void 0
|
|
1965
|
+
};
|
|
1966
|
+
return asChild ? visualSlot(children, attributes) : /* @__PURE__ */ jsx("span", {
|
|
1967
|
+
...attributes,
|
|
1968
|
+
children: classNames?.label ? /* @__PURE__ */ jsx("span", {
|
|
1969
|
+
className: partClass("badge__label", classNames.label),
|
|
1970
|
+
children
|
|
1971
|
+
}) : children
|
|
1972
|
+
});
|
|
1973
|
+
}
|
|
1974
|
+
function BadgeAnchor({ className, ...props }) {
|
|
1975
|
+
return /* @__PURE__ */ jsx(AnchorContext.Provider, {
|
|
1976
|
+
value: true,
|
|
1977
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
1978
|
+
...props,
|
|
1979
|
+
className: partClass("badge-anchor badge__anchor", className)
|
|
1980
|
+
})
|
|
1981
|
+
});
|
|
1982
|
+
}
|
|
1983
|
+
function BadgeLabel({ className, ...props }) {
|
|
1984
|
+
return /* @__PURE__ */ jsx("span", {
|
|
1985
|
+
...props,
|
|
1986
|
+
className: partClass("badge__label", className)
|
|
1987
|
+
});
|
|
1988
|
+
}
|
|
1989
|
+
var Badge = /* @__PURE__ */ Object.assign(BadgeRoot, {
|
|
1990
|
+
Root: BadgeRoot,
|
|
1991
|
+
Anchor: BadgeAnchor,
|
|
1992
|
+
Label: BadgeLabel
|
|
1993
|
+
});
|
|
1994
|
+
//#endregion
|
|
1995
|
+
//#region src/Avatar.tsx
|
|
1996
|
+
var AvatarGroupContext = createContext({});
|
|
1997
|
+
var AvatarContext = createContext(null);
|
|
1998
|
+
function AvatarRoot({ size, tone, variant, radius = "full", asChild, children, className, classNames, ...props }) {
|
|
1999
|
+
const group = useContext(AvatarGroupContext);
|
|
2000
|
+
const [status, setStatus] = useState("idle");
|
|
2001
|
+
const actualSize = size ?? group.size ?? "md";
|
|
2002
|
+
const attributes = {
|
|
2003
|
+
...props,
|
|
2004
|
+
className: partClass(partClass("avatar", classNames?.root), className),
|
|
2005
|
+
"data-size": actualSize,
|
|
2006
|
+
"data-tone": tone ?? group.tone ?? "neutral",
|
|
2007
|
+
"data-variant": variant ?? group.variant ?? "default",
|
|
2008
|
+
"data-radius": radius,
|
|
2009
|
+
"data-image-status": status
|
|
2010
|
+
};
|
|
2011
|
+
return /* @__PURE__ */ jsx(AvatarContext.Provider, {
|
|
2012
|
+
value: {
|
|
2013
|
+
status,
|
|
2014
|
+
setStatus,
|
|
2015
|
+
size: actualSize,
|
|
2016
|
+
classNames
|
|
2017
|
+
},
|
|
2018
|
+
children: asChild ? visualSlot(children, attributes) : /* @__PURE__ */ jsx("span", {
|
|
2019
|
+
...attributes,
|
|
2020
|
+
children
|
|
2021
|
+
})
|
|
2022
|
+
});
|
|
2023
|
+
}
|
|
2024
|
+
function AvatarImage(props) {
|
|
2025
|
+
return /* @__PURE__ */ jsx(AvatarImageLoader, { ...props }, `${props.src ?? ""}|${props.srcSet ?? ""}|${props.sizes ?? ""}`);
|
|
2026
|
+
}
|
|
2027
|
+
function AvatarImageLoader({ src, srcSet, sizes, alt, asChild, children, className, onLoad, onError, onLoadingStatusChange, ref, ...props }) {
|
|
2028
|
+
const context = useContext(AvatarContext);
|
|
2029
|
+
const setStatus = context?.setStatus;
|
|
2030
|
+
const imageRef = useRef(null);
|
|
2031
|
+
const [result, setResult] = useState({
|
|
2032
|
+
source: "",
|
|
2033
|
+
status: "idle"
|
|
2034
|
+
});
|
|
2035
|
+
const source = `${src ?? ""}|${srcSet ?? ""}|${sizes ?? ""}`;
|
|
2036
|
+
const status = result.source === source ? result.status : src || srcSet ? "loading" : "error";
|
|
2037
|
+
const statusCallback = useRef(onLoadingStatusChange);
|
|
2038
|
+
useEffect(() => {
|
|
2039
|
+
statusCallback.current = onLoadingStatusChange;
|
|
2040
|
+
});
|
|
2041
|
+
useEffect(() => {
|
|
2042
|
+
setStatus?.(status);
|
|
2043
|
+
statusCallback.current?.(status);
|
|
2044
|
+
}, [status, setStatus]);
|
|
2045
|
+
useEffect(() => () => setStatus?.("idle"), [setStatus]);
|
|
2046
|
+
useEffect(() => {
|
|
2047
|
+
if (imageRef.current?.complete && imageRef.current.naturalWidth > 0) setResult({
|
|
2048
|
+
source,
|
|
2049
|
+
status: "loaded"
|
|
2050
|
+
});
|
|
2051
|
+
}, [source]);
|
|
2052
|
+
const attributes = {
|
|
2053
|
+
...props,
|
|
2054
|
+
src,
|
|
2055
|
+
srcSet,
|
|
2056
|
+
sizes,
|
|
2057
|
+
className: partClass(partClass("avatar__image", context?.classNames?.image), className),
|
|
2058
|
+
"data-status": status,
|
|
2059
|
+
"aria-hidden": status !== "loaded" || void 0,
|
|
2060
|
+
ref: (node) => {
|
|
2061
|
+
imageRef.current = node;
|
|
2062
|
+
if (typeof ref === "function") return ref(node);
|
|
2063
|
+
else if (ref) ref.current = node;
|
|
2064
|
+
},
|
|
2065
|
+
onLoad: (event) => {
|
|
2066
|
+
if (event.currentTarget !== imageRef.current) return;
|
|
2067
|
+
setResult({
|
|
2068
|
+
source,
|
|
2069
|
+
status: "loaded"
|
|
2070
|
+
});
|
|
2071
|
+
onLoad?.(event);
|
|
2072
|
+
},
|
|
2073
|
+
onError: (event) => {
|
|
2074
|
+
if (event.currentTarget !== imageRef.current) return;
|
|
2075
|
+
setResult({
|
|
2076
|
+
source,
|
|
2077
|
+
status: "error"
|
|
2078
|
+
});
|
|
2079
|
+
onError?.(event);
|
|
2080
|
+
}
|
|
2081
|
+
};
|
|
2082
|
+
return asChild ? visualSlot(children, {
|
|
2083
|
+
...attributes,
|
|
2084
|
+
...alt !== void 0 ? { alt } : {}
|
|
2085
|
+
}) : /* @__PURE__ */ jsx("img", {
|
|
2086
|
+
...attributes,
|
|
2087
|
+
alt: alt ?? ""
|
|
2088
|
+
}, source);
|
|
2089
|
+
}
|
|
2090
|
+
function AvatarFallback({ delayMs = 0, tone, className, ...props }) {
|
|
2091
|
+
const context = useContext(AvatarContext);
|
|
2092
|
+
const [ready, setReady] = useState(delayMs <= 0);
|
|
2093
|
+
useEffect(() => {
|
|
2094
|
+
setReady(delayMs <= 0);
|
|
2095
|
+
if (delayMs <= 0) return;
|
|
2096
|
+
const timer = setTimeout(() => setReady(true), delayMs);
|
|
2097
|
+
return () => clearTimeout(timer);
|
|
2098
|
+
}, [delayMs, context?.status]);
|
|
2099
|
+
if (context?.status === "loaded" || !ready) return null;
|
|
2100
|
+
return /* @__PURE__ */ jsx("span", {
|
|
2101
|
+
...props,
|
|
2102
|
+
className: partClass(partClass("avatar__fallback", context?.classNames?.fallback), className),
|
|
1677
2103
|
"data-tone": tone
|
|
1678
2104
|
});
|
|
1679
2105
|
}
|
|
2106
|
+
function AvatarBadge({ size, tone = "primary", placement = "bottom-right", className, children, ...props }) {
|
|
2107
|
+
const context = useContext(AvatarContext);
|
|
2108
|
+
return /* @__PURE__ */ jsx("span", {
|
|
2109
|
+
...props,
|
|
2110
|
+
className: partClass(partClass("avatar__badge", context?.classNames?.badge), className),
|
|
2111
|
+
"data-size": size ?? context?.size ?? "md",
|
|
2112
|
+
"data-tone": tone,
|
|
2113
|
+
"data-placement": placement,
|
|
2114
|
+
"data-dot": children == null || void 0,
|
|
2115
|
+
children
|
|
2116
|
+
});
|
|
2117
|
+
}
|
|
2118
|
+
var Avatar = /* @__PURE__ */ Object.assign(AvatarRoot, {
|
|
2119
|
+
Root: AvatarRoot,
|
|
2120
|
+
Image: AvatarImage,
|
|
2121
|
+
Fallback: AvatarFallback,
|
|
2122
|
+
Badge: AvatarBadge
|
|
2123
|
+
});
|
|
2124
|
+
//#endregion
|
|
2125
|
+
//#region src/AvatarGroup.tsx
|
|
2126
|
+
function flatten(children, prefix = "") {
|
|
2127
|
+
return Children.toArray(children).flatMap((child, index) => {
|
|
2128
|
+
const key = `${prefix}/${isValidElement(child) ? child.key ?? index : index}`;
|
|
2129
|
+
return isValidElement(child) && child.type === Fragment ? flatten(child.props.children, key) : isValidElement(child) ? [cloneElement(child, { key })] : [];
|
|
2130
|
+
});
|
|
2131
|
+
}
|
|
2132
|
+
function AvatarGroupCount({ className, ...props }) {
|
|
2133
|
+
return /* @__PURE__ */ jsx(Avatar, {
|
|
2134
|
+
...props,
|
|
2135
|
+
className: partClass("avatar-group__count", className),
|
|
2136
|
+
children: /* @__PURE__ */ jsx(Avatar.Fallback, { children: props.children })
|
|
2137
|
+
});
|
|
2138
|
+
}
|
|
2139
|
+
function AvatarGroupRoot({ size = "md", tone = "neutral", variant = "default", max, isGrid = false, overlap = "clip", className, classNames, children, ...props }) {
|
|
2140
|
+
const items = flatten(children);
|
|
2141
|
+
const counts = items.filter((item) => isValidElement(item) && item.type === AvatarGroupCount);
|
|
2142
|
+
const avatars = items.filter((item) => !counts.includes(item));
|
|
2143
|
+
const limit = max === void 0 || !Number.isFinite(max) ? avatars.length : Math.max(0, Math.floor(max));
|
|
2144
|
+
const hidden = Math.max(0, avatars.length - limit);
|
|
2145
|
+
return /* @__PURE__ */ jsx(AvatarGroupContext.Provider, {
|
|
2146
|
+
value: {
|
|
2147
|
+
size,
|
|
2148
|
+
tone,
|
|
2149
|
+
variant
|
|
2150
|
+
},
|
|
2151
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
2152
|
+
...props,
|
|
2153
|
+
className: partClass(partClass("avatar-group", classNames?.root), className),
|
|
2154
|
+
"data-size": size,
|
|
2155
|
+
"data-grid": isGrid || void 0,
|
|
2156
|
+
"data-overlap": overlap,
|
|
2157
|
+
children: [avatars.slice(0, limit), counts.length ? counts : hidden > 0 ? /* @__PURE__ */ jsxs(AvatarGroupCount, {
|
|
2158
|
+
className: classNames?.count,
|
|
2159
|
+
"aria-label": `${hidden} more`,
|
|
2160
|
+
children: ["+", hidden]
|
|
2161
|
+
}) : null]
|
|
2162
|
+
})
|
|
2163
|
+
});
|
|
2164
|
+
}
|
|
2165
|
+
var AvatarGroup = /* @__PURE__ */ Object.assign(AvatarGroupRoot, {
|
|
2166
|
+
Root: AvatarGroupRoot,
|
|
2167
|
+
Count: AvatarGroupCount
|
|
2168
|
+
});
|
|
1680
2169
|
//#endregion
|
|
1681
2170
|
//#region src/Skeleton.tsx
|
|
1682
2171
|
/** Decorative placeholder. Set aria-busy and loading text on the surrounding content. */
|
|
@@ -1800,7 +2289,7 @@ function mountTabsIndicator(container) {
|
|
|
1800
2289
|
}
|
|
1801
2290
|
//#endregion
|
|
1802
2291
|
//#region src/Tabs.tsx
|
|
1803
|
-
function CompactTabs({ className, style, classNames, label, variant = "primary", size = "md", orientation = "horizontal", align = "center", fullWidth = false, inset = "default", showSeparators = false, renderIcon, previousLabel = "Tab sebelumnya / Previous tabs", nextLabel = "Tab berikutnya / Next tabs", extras, actions, items, value, defaultValue, onChange, renderPanel, activationMode = "manual", dir, id }) {
|
|
2292
|
+
function CompactTabs({ className, style, classNames, label, variant = "primary", size = "md", indicatorShadow = true, orientation = "horizontal", align = "center", fullWidth = false, inset = "default", showSeparators = false, renderIcon, previousLabel = "Tab sebelumnya / Previous tabs", nextLabel = "Tab berikutnya / Next tabs", extras, actions, items, value, defaultValue, onChange, renderPanel, activationMode = "manual", dir, id }) {
|
|
1804
2293
|
const container = useRef(null);
|
|
1805
2294
|
const hasToolbar = !!(extras || actions);
|
|
1806
2295
|
useEffect(() => container.current ? mountTabsIndicator(container.current) : void 0, [items.length, hasToolbar]);
|
|
@@ -1861,6 +2350,7 @@ function CompactTabs({ className, style, classNames, label, variant = "primary",
|
|
|
1861
2350
|
]
|
|
1862
2351
|
}) : null;
|
|
1863
2352
|
const content = /* @__PURE__ */ jsxs(Tabs$1, {
|
|
2353
|
+
"data-indicator-shadow": indicatorShadow,
|
|
1864
2354
|
className: [
|
|
1865
2355
|
"tabs",
|
|
1866
2356
|
classNames?.root,
|
|
@@ -1908,9 +2398,10 @@ function CompactTabs({ className, style, classNames, label, variant = "primary",
|
|
|
1908
2398
|
children: content
|
|
1909
2399
|
}) : content;
|
|
1910
2400
|
}
|
|
1911
|
-
function TabsRoot({ className, classNames, value, defaultValue, onChange, variant = "primary", size = "md", align = "center", fullWidth, ...props }) {
|
|
2401
|
+
function TabsRoot({ className, classNames, value, defaultValue, onChange, variant = "primary", size = "md", align = "center", fullWidth, indicatorShadow = true, ...props }) {
|
|
1912
2402
|
return /* @__PURE__ */ jsx(Tabs$1, {
|
|
1913
2403
|
...props,
|
|
2404
|
+
"data-indicator-shadow": indicatorShadow,
|
|
1914
2405
|
selectedKey: value,
|
|
1915
2406
|
defaultSelectedKey: defaultValue,
|
|
1916
2407
|
onSelectionChange: onChange ? (key) => onChange(String(key)) : void 0,
|
|
@@ -3259,7 +3750,7 @@ function CompactDropdownMenu(props) {
|
|
|
3259
3750
|
onOpenChange: change,
|
|
3260
3751
|
children: [/* @__PURE__ */ jsx(Button$1, {
|
|
3261
3752
|
style,
|
|
3262
|
-
className: partClass(partClass(partClass(`button button--${props.triggerVariant ?? "secondary"}${props.triggerIconOnly ? " button--icon-only" : ""}`, classNames?.trigger), classNames?.root), className),
|
|
3753
|
+
className: partClass(partClass(partClass(`button button--${props.triggerVariant ?? "secondary"} button--${props.triggerSize ?? "md"}${props.triggerIconOnly ? " button--icon-only" : ""}`, classNames?.trigger), classNames?.root), className),
|
|
3263
3754
|
"aria-label": triggerLabel,
|
|
3264
3755
|
isDisabled: isDisabled || !items.length,
|
|
3265
3756
|
children: props.triggerContent ?? triggerLabel
|
|
@@ -3861,38 +4352,355 @@ function DateRangeCancelButton({ className, onClick, children, ...props }) {
|
|
|
3861
4352
|
});
|
|
3862
4353
|
}
|
|
3863
4354
|
//#endregion
|
|
3864
|
-
//#region src/
|
|
3865
|
-
function
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
4355
|
+
//#region src/Calendar.tsx
|
|
4356
|
+
function date(value) {
|
|
4357
|
+
try {
|
|
4358
|
+
return value ? parseDate(value) : void 0;
|
|
4359
|
+
} catch {
|
|
4360
|
+
return;
|
|
4361
|
+
}
|
|
4362
|
+
}
|
|
4363
|
+
function monthName(year, month, locale) {
|
|
4364
|
+
return new Intl.DateTimeFormat(locale, {
|
|
4365
|
+
month: "long",
|
|
4366
|
+
timeZone: "UTC",
|
|
4367
|
+
calendar: "gregory"
|
|
4368
|
+
}).format(new CalendarDate(year, month, 1).toDate("UTC"));
|
|
4369
|
+
}
|
|
4370
|
+
function MonthPicker({ value, year = today("UTC").year, onChange, locale = "id-ID", minDate, maxDate, isDisabled, className, ...props }) {
|
|
4371
|
+
return /* @__PURE__ */ jsx("div", {
|
|
4372
|
+
...props,
|
|
4373
|
+
className: partClass("calendar__choices", className),
|
|
4374
|
+
role: "group",
|
|
4375
|
+
"aria-label": locale.startsWith("id") ? "Pilih bulan" : "Choose month",
|
|
4376
|
+
children: Array.from({ length: 12 }, (_, i) => i + 1).map((month) => {
|
|
4377
|
+
const start = new CalendarDate(year, month, 1);
|
|
4378
|
+
const end = start.add({ months: 1 }).subtract({ days: 1 });
|
|
4379
|
+
return /* @__PURE__ */ jsx("button", {
|
|
4380
|
+
type: "button",
|
|
4381
|
+
disabled: isDisabled || !!(date(minDate) && end.compare(date(minDate)) < 0) || !!(date(maxDate) && start.compare(date(maxDate)) > 0),
|
|
4382
|
+
"aria-pressed": value === month,
|
|
4383
|
+
onClick: () => onChange?.(month),
|
|
4384
|
+
children: monthName(year, month, locale)
|
|
4385
|
+
}, month);
|
|
4386
|
+
})
|
|
4387
|
+
});
|
|
4388
|
+
}
|
|
4389
|
+
function YearPicker({ value = today("UTC").year, onChange, locale = "id-ID", minDate, maxDate, isDisabled, className, ...props }) {
|
|
4390
|
+
const min = date(minDate)?.year ?? 1, max = date(maxDate)?.year ?? 9999;
|
|
4391
|
+
const [page, setPage] = useState(Math.max(min, Math.min(max, Math.floor((value - 1) / 12) * 12 + 1)));
|
|
4392
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
4393
|
+
...props,
|
|
4394
|
+
className: partClass("calendar__years", className),
|
|
4395
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
4396
|
+
className: "calendar__year-navigation",
|
|
4397
|
+
children: [
|
|
4398
|
+
/* @__PURE__ */ jsx("button", {
|
|
4399
|
+
type: "button",
|
|
4400
|
+
"aria-label": locale.startsWith("id") ? "Tahun sebelumnya" : "Previous years",
|
|
4401
|
+
disabled: isDisabled || page <= min,
|
|
4402
|
+
onClick: () => setPage(Math.max(min, page - 12)),
|
|
4403
|
+
children: "‹"
|
|
4404
|
+
}),
|
|
4405
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
4406
|
+
page,
|
|
4407
|
+
"–",
|
|
4408
|
+
Math.min(page + 11, max)
|
|
4409
|
+
] }),
|
|
4410
|
+
/* @__PURE__ */ jsx("button", {
|
|
4411
|
+
type: "button",
|
|
4412
|
+
"aria-label": locale.startsWith("id") ? "Tahun berikutnya" : "Next years",
|
|
4413
|
+
disabled: isDisabled || page + 11 >= max,
|
|
4414
|
+
onClick: () => setPage(Math.max(min, Math.min(max - 11, page + 12))),
|
|
4415
|
+
children: "›"
|
|
4416
|
+
})
|
|
4417
|
+
]
|
|
4418
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
4419
|
+
className: "calendar__choices",
|
|
4420
|
+
role: "group",
|
|
4421
|
+
"aria-label": locale.startsWith("id") ? "Pilih tahun" : "Choose year",
|
|
4422
|
+
children: Array.from({ length: 12 }, (_, i) => page + i).filter((year) => year <= 9999).map((year) => /* @__PURE__ */ jsx("button", {
|
|
4423
|
+
type: "button",
|
|
4424
|
+
disabled: isDisabled || year < min || year > max,
|
|
4425
|
+
"aria-pressed": value === year,
|
|
4426
|
+
onClick: () => onChange?.(year),
|
|
4427
|
+
children: year
|
|
4428
|
+
}, year))
|
|
4429
|
+
})]
|
|
4430
|
+
});
|
|
4431
|
+
}
|
|
4432
|
+
function MonthYearNavigation({ value, onChange, locale = "id-ID", minDate, maxDate, isDisabled, className, ...props }) {
|
|
4433
|
+
const current = date(value) ?? today("UTC");
|
|
4434
|
+
const [view, setView] = useState(null);
|
|
4435
|
+
const header = useRef(null), lastToggle = useRef("month"), previousView = useRef(null);
|
|
4436
|
+
useEffect(() => {
|
|
4437
|
+
if (view) (header.current?.querySelector(".calendar__view [aria-pressed=\"true\"]:not(:disabled)") ?? header.current?.querySelector(".calendar__view button:not(:disabled)"))?.focus();
|
|
4438
|
+
else if (previousView.current) header.current?.querySelectorAll(".date-range__heading > button")[lastToggle.current === "month" ? 0 : 1]?.focus();
|
|
4439
|
+
previousView.current = view;
|
|
4440
|
+
}, [view]);
|
|
4441
|
+
useEffect(() => {
|
|
4442
|
+
if (!view) return;
|
|
4443
|
+
const grid = header.current?.closest(".date-range__month")?.querySelector(".date-range__grid");
|
|
4444
|
+
if (!grid) return;
|
|
4445
|
+
const inert = grid.hasAttribute("inert"), hidden = grid.getAttribute("aria-hidden");
|
|
4446
|
+
grid.inert = true;
|
|
4447
|
+
grid.setAttribute("inert", "");
|
|
4448
|
+
grid.setAttribute("aria-hidden", "true");
|
|
4449
|
+
return () => {
|
|
4450
|
+
grid.inert = inert;
|
|
4451
|
+
if (!inert) grid.removeAttribute("inert");
|
|
4452
|
+
if (hidden === null) grid.removeAttribute("aria-hidden");
|
|
4453
|
+
else grid.setAttribute("aria-hidden", hidden);
|
|
4454
|
+
};
|
|
4455
|
+
}, [view]);
|
|
4456
|
+
const navigate = (year, month) => {
|
|
4457
|
+
let next = new CalendarDate(year, month, 1);
|
|
4458
|
+
const min = date(minDate), max = date(maxDate);
|
|
4459
|
+
if (min && next.compare(min) < 0) next = min;
|
|
4460
|
+
if (max && next.compare(max) > 0) next = max;
|
|
4461
|
+
onChange(next.toString());
|
|
4462
|
+
};
|
|
4463
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
4464
|
+
...props,
|
|
4465
|
+
ref: header,
|
|
4466
|
+
className: partClass("calendar__header", className),
|
|
4467
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
4468
|
+
className: "date-range__heading",
|
|
4469
|
+
children: [/* @__PURE__ */ jsx("button", {
|
|
4470
|
+
type: "button",
|
|
4471
|
+
disabled: isDisabled,
|
|
4472
|
+
"aria-expanded": view === "month",
|
|
4473
|
+
onClick: () => {
|
|
4474
|
+
lastToggle.current = "month";
|
|
4475
|
+
setView(view === "month" ? null : "month");
|
|
4476
|
+
},
|
|
4477
|
+
children: monthName(current.year, current.month, locale)
|
|
4478
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
4479
|
+
type: "button",
|
|
4480
|
+
disabled: isDisabled,
|
|
4481
|
+
"aria-expanded": view === "year",
|
|
4482
|
+
onClick: () => {
|
|
4483
|
+
lastToggle.current = "year";
|
|
4484
|
+
setView(view === "year" ? null : "year");
|
|
4485
|
+
},
|
|
4486
|
+
children: current.year
|
|
4487
|
+
})]
|
|
4488
|
+
}), view && /* @__PURE__ */ jsxs("div", {
|
|
4489
|
+
className: "calendar__view",
|
|
4490
|
+
role: "group",
|
|
4491
|
+
"aria-label": view === "year" ? locale.startsWith("id") ? "Pilih tahun" : "Choose year" : locale.startsWith("id") ? "Pilih bulan" : "Choose month",
|
|
4492
|
+
onKeyDownCapture: (e) => {
|
|
4493
|
+
if (e.key === "Escape") {
|
|
4494
|
+
e.stopPropagation();
|
|
4495
|
+
setView(null);
|
|
4496
|
+
}
|
|
4497
|
+
},
|
|
4498
|
+
children: [view === "month" ? /* @__PURE__ */ jsx(MonthPicker, {
|
|
4499
|
+
value: current.month,
|
|
4500
|
+
year: current.year,
|
|
4501
|
+
locale,
|
|
4502
|
+
minDate,
|
|
4503
|
+
maxDate,
|
|
4504
|
+
isDisabled,
|
|
4505
|
+
onChange: (month) => {
|
|
4506
|
+
navigate(current.year, month);
|
|
4507
|
+
setView(null);
|
|
4508
|
+
}
|
|
4509
|
+
}) : /* @__PURE__ */ jsx(YearPicker, {
|
|
4510
|
+
value: current.year,
|
|
4511
|
+
locale,
|
|
4512
|
+
minDate,
|
|
4513
|
+
maxDate,
|
|
4514
|
+
isDisabled,
|
|
4515
|
+
onChange: (year) => {
|
|
4516
|
+
navigate(year, current.month);
|
|
4517
|
+
setView("month");
|
|
4518
|
+
}
|
|
4519
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
4520
|
+
type: "button",
|
|
4521
|
+
className: "calendar__back",
|
|
4522
|
+
onClick: () => setView(null),
|
|
4523
|
+
children: locale.startsWith("id") ? "Kembali" : "Back"
|
|
4524
|
+
})]
|
|
4525
|
+
})]
|
|
4526
|
+
});
|
|
4527
|
+
}
|
|
4528
|
+
/** Reads actual visibleRange rather than assuming the focused day is the first panel. */
|
|
4529
|
+
function CalendarViewHeader({ offset = 0, onNavigate, ...props }) {
|
|
4530
|
+
const single = useContext(CalendarStateContext);
|
|
4531
|
+
const visible = (useContext(RangeCalendarStateContext) ?? single)?.visibleRange.start ?? today("UTC");
|
|
4532
|
+
return /* @__PURE__ */ jsx(MonthYearNavigation, {
|
|
4533
|
+
...props,
|
|
4534
|
+
value: visible.add({ months: offset }).toString(),
|
|
4535
|
+
onChange: (value) => onNavigate(parseDate(value).subtract({ months: offset }))
|
|
4536
|
+
});
|
|
4537
|
+
}
|
|
4538
|
+
function CalendarBody({ props, onNavigate }) {
|
|
4539
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("div", {
|
|
4540
|
+
className: "date-range__navigation",
|
|
4541
|
+
children: [/* @__PURE__ */ jsx(Button$1, {
|
|
4542
|
+
slot: "previous",
|
|
4543
|
+
className: "date-range__nav",
|
|
4544
|
+
"aria-label": props.locale?.startsWith("id") ? "Bulan sebelumnya" : "Previous month",
|
|
4545
|
+
children: "‹"
|
|
4546
|
+
}), /* @__PURE__ */ jsx(Button$1, {
|
|
4547
|
+
slot: "next",
|
|
4548
|
+
className: "date-range__nav",
|
|
4549
|
+
"aria-label": props.locale?.startsWith("id") ? "Bulan berikutnya" : "Next month",
|
|
4550
|
+
children: "›"
|
|
4551
|
+
})]
|
|
4552
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
4553
|
+
className: "date-range__months",
|
|
4554
|
+
children: Array.from({ length: props.visibleMonths ?? 1 }, (_, i) => /* @__PURE__ */ jsxs("div", {
|
|
4555
|
+
className: partClass("date-range__month", props.classNames?.month),
|
|
4556
|
+
children: [/* @__PURE__ */ jsx(CalendarViewHeader, {
|
|
4557
|
+
offset: i,
|
|
4558
|
+
onNavigate,
|
|
4559
|
+
locale: props.locale,
|
|
4560
|
+
minDate: props.minDate,
|
|
4561
|
+
maxDate: props.maxDate,
|
|
4562
|
+
isDisabled: props.isDisabled,
|
|
4563
|
+
className: props.classNames?.header
|
|
4564
|
+
}), /* @__PURE__ */ jsxs(CalendarGrid$1, {
|
|
4565
|
+
offset: { months: i },
|
|
4566
|
+
className: partClass("date-range__grid", props.classNames?.grid),
|
|
4567
|
+
weekdayStyle: "short",
|
|
4568
|
+
children: [/* @__PURE__ */ jsx(CalendarGridHeader$1, { children: (day) => /* @__PURE__ */ jsx(CalendarHeaderCell$1, {
|
|
4569
|
+
className: "date-range__weekday",
|
|
4570
|
+
children: day
|
|
4571
|
+
}) }), /* @__PURE__ */ jsx(CalendarGridBody$1, { children: (day) => /* @__PURE__ */ jsx(CalendarCell$1, {
|
|
4572
|
+
date: day,
|
|
4573
|
+
className: partClass("date-range__day", props.classNames?.day)
|
|
4574
|
+
}) })]
|
|
4575
|
+
})]
|
|
4576
|
+
}, i))
|
|
4577
|
+
})] });
|
|
4578
|
+
}
|
|
4579
|
+
function Calendar(props) {
|
|
4580
|
+
const [local, setLocal] = useState(props.defaultValue ?? null);
|
|
4581
|
+
const value = props.value === void 0 ? local : props.value;
|
|
4582
|
+
useEffect(() => {
|
|
4583
|
+
const next = date(value);
|
|
4584
|
+
if (next) setFocused(next);
|
|
4585
|
+
}, [value]);
|
|
4586
|
+
const [focused, setFocused] = useState(() => date(value) ?? date(props.referenceDate) ?? date(props.minDate) ?? today("UTC"));
|
|
4587
|
+
return /* @__PURE__ */ jsx(I18nProvider, {
|
|
4588
|
+
locale: props.locale ?? "id-ID",
|
|
4589
|
+
children: /* @__PURE__ */ jsx(Calendar$1, {
|
|
4590
|
+
className: partClass(partClass("date-range__calendar calendar", props.classNames?.root), props.className),
|
|
4591
|
+
style: props.style,
|
|
4592
|
+
"aria-label": props.label ?? "Calendar",
|
|
4593
|
+
dir: props.dir,
|
|
4594
|
+
value: date(value) ?? null,
|
|
4595
|
+
focusedValue: focused,
|
|
4596
|
+
onFocusChange: setFocused,
|
|
4597
|
+
createCalendar: () => new GregorianCalendar(),
|
|
4598
|
+
visibleDuration: { months: props.visibleMonths ?? 1 },
|
|
4599
|
+
pageBehavior: "single",
|
|
4600
|
+
firstDayOfWeek: props.weekStartsOn === 0 ? "sun" : "mon",
|
|
4601
|
+
minValue: date(props.minDate),
|
|
4602
|
+
maxValue: date(props.maxDate),
|
|
4603
|
+
isDisabled: props.isDisabled,
|
|
4604
|
+
isReadOnly: props.isReadOnly,
|
|
4605
|
+
isDateUnavailable: (v) => props.isDateUnavailable?.(v.toString()) ?? false,
|
|
4606
|
+
onChange: (v) => {
|
|
4607
|
+
const next = v?.toString() ?? null;
|
|
4608
|
+
setLocal(next);
|
|
4609
|
+
props.onChange?.(next);
|
|
4610
|
+
},
|
|
4611
|
+
children: /* @__PURE__ */ jsx(CalendarBody, {
|
|
4612
|
+
props,
|
|
4613
|
+
onNavigate: setFocused
|
|
4614
|
+
})
|
|
4615
|
+
})
|
|
4616
|
+
});
|
|
4617
|
+
}
|
|
4618
|
+
function RangeCalendar(props) {
|
|
4619
|
+
const [local, setLocal] = useState(props.defaultValue ?? null);
|
|
4620
|
+
const value = props.value === void 0 ? local : props.value;
|
|
4621
|
+
const selectedStart = value?.start;
|
|
4622
|
+
useEffect(() => {
|
|
4623
|
+
const next = date(selectedStart);
|
|
4624
|
+
if (next) setFocused(next);
|
|
4625
|
+
}, [selectedStart]);
|
|
4626
|
+
const [focused, setFocused] = useState(() => date(value?.start) ?? date(props.referenceDate) ?? date(props.minDate) ?? today("UTC"));
|
|
4627
|
+
const selected = date(value?.start) && date(value?.end) ? {
|
|
4628
|
+
start: date(value?.start),
|
|
4629
|
+
end: date(value?.end)
|
|
4630
|
+
} : null;
|
|
4631
|
+
return /* @__PURE__ */ jsx(I18nProvider, {
|
|
4632
|
+
locale: props.locale ?? "id-ID",
|
|
4633
|
+
children: /* @__PURE__ */ jsx(RangeCalendar$1, {
|
|
4634
|
+
className: partClass(partClass("date-range__calendar calendar", props.classNames?.root), props.className),
|
|
4635
|
+
style: props.style,
|
|
4636
|
+
"aria-label": props.label ?? "Calendar",
|
|
4637
|
+
dir: props.dir,
|
|
4638
|
+
value: selected,
|
|
4639
|
+
focusedValue: focused,
|
|
4640
|
+
onFocusChange: setFocused,
|
|
4641
|
+
createCalendar: () => new GregorianCalendar(),
|
|
4642
|
+
visibleDuration: { months: props.visibleMonths ?? 2 },
|
|
4643
|
+
pageBehavior: "single",
|
|
4644
|
+
firstDayOfWeek: props.weekStartsOn === 0 ? "sun" : "mon",
|
|
4645
|
+
minValue: date(props.minDate),
|
|
4646
|
+
maxValue: date(props.maxDate),
|
|
4647
|
+
isDisabled: props.isDisabled,
|
|
4648
|
+
isReadOnly: props.isReadOnly,
|
|
4649
|
+
isDateUnavailable: (v) => props.isDateUnavailable?.(v.toString()) ?? false,
|
|
4650
|
+
onChange: (v) => {
|
|
4651
|
+
const next = v ? {
|
|
4652
|
+
start: v.start.toString(),
|
|
4653
|
+
end: v.end.toString()
|
|
4654
|
+
} : null;
|
|
4655
|
+
setLocal(next);
|
|
4656
|
+
props.onChange?.(next);
|
|
4657
|
+
},
|
|
4658
|
+
children: /* @__PURE__ */ jsx(CalendarBody, {
|
|
4659
|
+
props: {
|
|
4660
|
+
...props,
|
|
4661
|
+
visibleMonths: props.visibleMonths ?? 2,
|
|
4662
|
+
value: null,
|
|
4663
|
+
defaultValue: null,
|
|
4664
|
+
onChange: void 0
|
|
4665
|
+
},
|
|
4666
|
+
onNavigate: setFocused
|
|
4667
|
+
})
|
|
4668
|
+
})
|
|
4669
|
+
});
|
|
4670
|
+
}
|
|
4671
|
+
//#endregion
|
|
4672
|
+
//#region src/date-range-model.ts
|
|
4673
|
+
function dateRangeLabels(locale = "id-ID") {
|
|
4674
|
+
return locale.startsWith("id") ? {
|
|
4675
|
+
title: "Pilih rentang tanggal",
|
|
4676
|
+
start: "Tanggal mulai",
|
|
4677
|
+
end: "Tanggal akhir",
|
|
4678
|
+
apply: "Terapkan",
|
|
4679
|
+
cancel: "Batal",
|
|
4680
|
+
clear: "Kosongkan",
|
|
4681
|
+
previousMonth: "Bulan sebelumnya",
|
|
4682
|
+
nextMonth: "Bulan berikutnya",
|
|
4683
|
+
presets: "Pilihan cepat",
|
|
4684
|
+
placeholder: "Pilih tanggal",
|
|
4685
|
+
incomplete: "Lengkapi tanggal mulai dan akhir.",
|
|
4686
|
+
order: "Tanggal akhir harus setelah atau sama dengan tanggal mulai.",
|
|
4687
|
+
bounds: "Tanggal berada di luar batas yang diizinkan.",
|
|
4688
|
+
unavailable: "Rentang memuat tanggal yang tidak tersedia.",
|
|
4689
|
+
length: "Durasi rentang tidak sesuai batas yang diizinkan.",
|
|
4690
|
+
required: "Rentang tanggal wajib diisi."
|
|
4691
|
+
} : {
|
|
4692
|
+
title: "Select date range",
|
|
4693
|
+
start: "Start date",
|
|
4694
|
+
end: "End date",
|
|
4695
|
+
apply: "Apply",
|
|
4696
|
+
cancel: "Cancel",
|
|
4697
|
+
clear: "Clear",
|
|
4698
|
+
previousMonth: "Previous month",
|
|
4699
|
+
nextMonth: "Next month",
|
|
4700
|
+
presets: "Quick selections",
|
|
4701
|
+
placeholder: "Choose dates",
|
|
4702
|
+
incomplete: "Enter both start and end dates.",
|
|
4703
|
+
order: "End date must be on or after start date.",
|
|
3896
4704
|
bounds: "Dates are outside the allowed limits.",
|
|
3897
4705
|
unavailable: "The range includes an unavailable date.",
|
|
3898
4706
|
length: "The range duration is outside the allowed limits.",
|
|
@@ -4011,7 +4819,7 @@ function CalendarContent({ onPending, dir, children }) {
|
|
|
4011
4819
|
});
|
|
4012
4820
|
}
|
|
4013
4821
|
function DateRangePickerRoot(props) {
|
|
4014
|
-
const { label, locale = "id-ID", dir, size = "md", variant = "primary", fullWidth = true, hideLabel = false, visibleMonths = 2, weekStartsOn = 1, display = "
|
|
4822
|
+
const { label, locale = "id-ID", dir, size = "md", variant = "primary", fullWidth = true, hideLabel = false, visibleMonths = 2, weekStartsOn = 1, display = "auto", showInputs = true, presets = [], isDisabled = false, isReadOnly = false, isRequired = false } = props;
|
|
4015
4823
|
const labels = {
|
|
4016
4824
|
...dateRangeLabels(locale),
|
|
4017
4825
|
...props.labels
|
|
@@ -4032,6 +4840,15 @@ function DateRangePickerRoot(props) {
|
|
|
4032
4840
|
const [formError, setFormError] = useState(false);
|
|
4033
4841
|
const [pending, setPending] = useState(false), [calendarKey, setCalendarKey] = useState(0);
|
|
4034
4842
|
const trigger = useRef(null);
|
|
4843
|
+
const [mobile, setMobile] = useState(false);
|
|
4844
|
+
useEffect(() => {
|
|
4845
|
+
const query = window.matchMedia("(max-width: 640px)");
|
|
4846
|
+
const change = () => setMobile(query.matches);
|
|
4847
|
+
change();
|
|
4848
|
+
query.addEventListener("change", change);
|
|
4849
|
+
return () => query.removeEventListener("change", change);
|
|
4850
|
+
}, []);
|
|
4851
|
+
const isDialog = display === "dialog" || display === "auto" && mobile;
|
|
4035
4852
|
const id = useId();
|
|
4036
4853
|
const disclosure = useDisclosure(props.open, props.defaultOpen, props.onOpenChange);
|
|
4037
4854
|
const visible = disclosure.visible && !isDisabled;
|
|
@@ -4044,6 +4861,23 @@ function DateRangePickerRoot(props) {
|
|
|
4044
4861
|
setPending(false);
|
|
4045
4862
|
setCalendarKey((k) => k + 1);
|
|
4046
4863
|
}
|
|
4864
|
+
function updateDraft(next) {
|
|
4865
|
+
if (isDisabled || isReadOnly) return;
|
|
4866
|
+
setDraft(next);
|
|
4867
|
+
const value = next.start || next.end ? next : null;
|
|
4868
|
+
if (props.commitMode === "immediate" && !rangeError(value, props)) {
|
|
4869
|
+
setLocal(value);
|
|
4870
|
+
setFormError(false);
|
|
4871
|
+
props.onChange?.(value);
|
|
4872
|
+
}
|
|
4873
|
+
}
|
|
4874
|
+
function clearDraft() {
|
|
4875
|
+
replaceDraft(empty());
|
|
4876
|
+
if (props.commitMode === "immediate" && !isDisabled && !isReadOnly) {
|
|
4877
|
+
setLocal(null);
|
|
4878
|
+
props.onChange?.(null);
|
|
4879
|
+
}
|
|
4880
|
+
}
|
|
4047
4881
|
function resetDraft() {
|
|
4048
4882
|
replaceDraft({
|
|
4049
4883
|
start,
|
|
@@ -4079,13 +4913,17 @@ function DateRangePickerRoot(props) {
|
|
|
4079
4913
|
...draft,
|
|
4080
4914
|
[part]: value
|
|
4081
4915
|
});
|
|
4916
|
+
updateDraft({
|
|
4917
|
+
...draft,
|
|
4918
|
+
[part]: value
|
|
4919
|
+
});
|
|
4082
4920
|
if (asDate(value)) setFocused(asDate(value));
|
|
4083
4921
|
}
|
|
4084
4922
|
const calendarValue = asDate(draft.start) && asDate(draft.end) && draft.start <= draft.end ? {
|
|
4085
4923
|
start: asDate(draft.start),
|
|
4086
4924
|
end: asDate(draft.end)
|
|
4087
4925
|
} : null;
|
|
4088
|
-
const calendar = /* @__PURE__ */ jsx(RangeCalendar, {
|
|
4926
|
+
const calendar = /* @__PURE__ */ jsx(RangeCalendar$1, {
|
|
4089
4927
|
dir,
|
|
4090
4928
|
className: partClass("date-range__calendar", props.classNames?.calendar),
|
|
4091
4929
|
"aria-label": labels.title,
|
|
@@ -4094,7 +4932,7 @@ function DateRangePickerRoot(props) {
|
|
|
4094
4932
|
onFocusChange: setFocused,
|
|
4095
4933
|
createCalendar: () => new GregorianCalendar(),
|
|
4096
4934
|
onChange: (v) => {
|
|
4097
|
-
if (v)
|
|
4935
|
+
if (v) updateDraft({
|
|
4098
4936
|
start: v.start.toString(),
|
|
4099
4937
|
end: v.end.toString()
|
|
4100
4938
|
});
|
|
@@ -4127,9 +4965,14 @@ function DateRangePickerRoot(props) {
|
|
|
4127
4965
|
className: partClass("date-range__months", props.classNames?.months),
|
|
4128
4966
|
children: Array.from({ length: visibleMonths }, (_, i) => /* @__PURE__ */ jsxs("div", {
|
|
4129
4967
|
className: partClass("date-range__month", props.classNames?.month),
|
|
4130
|
-
children: [/* @__PURE__ */ jsx(
|
|
4131
|
-
offset:
|
|
4132
|
-
|
|
4968
|
+
children: [/* @__PURE__ */ jsx(CalendarViewHeader, {
|
|
4969
|
+
offset: i,
|
|
4970
|
+
onNavigate: setFocused,
|
|
4971
|
+
locale,
|
|
4972
|
+
minDate: props.minDate,
|
|
4973
|
+
maxDate: props.maxDate,
|
|
4974
|
+
isDisabled,
|
|
4975
|
+
className: props.classNames?.heading
|
|
4133
4976
|
}), /* @__PURE__ */ jsxs(CalendarGrid, {
|
|
4134
4977
|
offset: { months: i },
|
|
4135
4978
|
className: partClass("date-range__grid", props.classNames?.grid),
|
|
@@ -4175,6 +5018,7 @@ function DateRangePickerRoot(props) {
|
|
|
4175
5018
|
"aria-pressed": !pending && draft.start === p.value.start && draft.end === p.value.end,
|
|
4176
5019
|
onClick: () => {
|
|
4177
5020
|
replaceDraft({ ...p.value });
|
|
5021
|
+
updateDraft({ ...p.value });
|
|
4178
5022
|
setFocused(asDate(p.value.start));
|
|
4179
5023
|
},
|
|
4180
5024
|
children: p.label
|
|
@@ -4253,26 +5097,46 @@ function DateRangePickerRoot(props) {
|
|
|
4253
5097
|
]
|
|
4254
5098
|
})]
|
|
4255
5099
|
}),
|
|
4256
|
-
/* @__PURE__ */ jsxs("footer", {
|
|
5100
|
+
props.showActions !== false && /* @__PURE__ */ jsxs("footer", {
|
|
4257
5101
|
className: partClass("date-range__footer", props.classNames?.footer),
|
|
4258
5102
|
children: [/* @__PURE__ */ jsx("button", {
|
|
4259
5103
|
type: "button",
|
|
4260
5104
|
className: partClass("button button--ghost button--sm", props.classNames?.clearButton),
|
|
4261
5105
|
disabled: isDisabled || isReadOnly,
|
|
4262
|
-
onClick:
|
|
5106
|
+
onClick: clearDraft,
|
|
4263
5107
|
children: labels.clear
|
|
4264
|
-
}), /* @__PURE__ */ jsxs("div", { children: [
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
|
|
5108
|
+
}), /* @__PURE__ */ jsxs("div", { children: [
|
|
5109
|
+
/* @__PURE__ */ jsx("button", {
|
|
5110
|
+
type: "button",
|
|
5111
|
+
className: "button button--ghost button--sm",
|
|
5112
|
+
disabled: isDisabled || isReadOnly || !!rangeError({
|
|
5113
|
+
start: currentDate(),
|
|
5114
|
+
end: currentDate()
|
|
5115
|
+
}, props),
|
|
5116
|
+
onClick: () => {
|
|
5117
|
+
const next = {
|
|
5118
|
+
start: currentDate(),
|
|
5119
|
+
end: currentDate()
|
|
5120
|
+
};
|
|
5121
|
+
replaceDraft(next);
|
|
5122
|
+
updateDraft(next);
|
|
5123
|
+
},
|
|
5124
|
+
children: locale.startsWith("id") ? "Hari ini" : "Today"
|
|
5125
|
+
}),
|
|
5126
|
+
/* @__PURE__ */ jsx("button", {
|
|
5127
|
+
type: "button",
|
|
5128
|
+
className: partClass("button button--secondary button--sm", props.classNames?.cancelButton),
|
|
5129
|
+
onClick: () => changeOpen(false),
|
|
5130
|
+
children: labels.cancel
|
|
5131
|
+
}),
|
|
5132
|
+
props.commitMode !== "immediate" && /* @__PURE__ */ jsx("button", {
|
|
5133
|
+
type: "button",
|
|
5134
|
+
className: partClass("button button--primary button--sm", props.classNames?.applyButton),
|
|
5135
|
+
disabled: isDisabled || isReadOnly || !!errorCode,
|
|
5136
|
+
onClick: apply,
|
|
5137
|
+
children: labels.apply
|
|
5138
|
+
})
|
|
5139
|
+
] })]
|
|
4276
5140
|
})
|
|
4277
5141
|
]
|
|
4278
5142
|
});
|
|
@@ -4299,7 +5163,7 @@ function DateRangePickerRoot(props) {
|
|
|
4299
5163
|
panel,
|
|
4300
5164
|
edit,
|
|
4301
5165
|
apply,
|
|
4302
|
-
clear:
|
|
5166
|
+
clear: clearDraft,
|
|
4303
5167
|
cancel: () => changeOpen(false)
|
|
4304
5168
|
},
|
|
4305
5169
|
children: /* @__PURE__ */ jsxs("div", {
|
|
@@ -4369,7 +5233,17 @@ function DateRangePickerRoot(props) {
|
|
|
4369
5233
|
}),
|
|
4370
5234
|
/* @__PURE__ */ jsx(ChevronIcon, { className: partClass("date-range__chevron", props.classNames?.chevron) })
|
|
4371
5235
|
]
|
|
4372
|
-
}), /* @__PURE__ */ jsx(
|
|
5236
|
+
}), isDialog ? /* @__PURE__ */ jsx(ModalOverlay, {
|
|
5237
|
+
className: "temporal-picker__overlay",
|
|
5238
|
+
children: /* @__PURE__ */ jsx(Modal, {
|
|
5239
|
+
className: "date-range__panel temporal-picker__modal",
|
|
5240
|
+
children: /* @__PURE__ */ jsx(Dialog$1, {
|
|
5241
|
+
"aria-labelledby": `${id}-title`,
|
|
5242
|
+
className: "date-range__dialog",
|
|
5243
|
+
children: panel
|
|
5244
|
+
})
|
|
5245
|
+
})
|
|
5246
|
+
}) : /* @__PURE__ */ jsx(Popover$2, {
|
|
4373
5247
|
className: partClass("date-range__panel", props.classNames?.panel),
|
|
4374
5248
|
placement: "bottom start",
|
|
4375
5249
|
offset: 8,
|
|
@@ -5272,6 +6146,1030 @@ function ToastRenderer({ composed = false, style, classNames, entry, indicator,
|
|
|
5272
6146
|
});
|
|
5273
6147
|
}
|
|
5274
6148
|
//#endregion
|
|
5275
|
-
|
|
6149
|
+
//#region src/temporal-model.ts
|
|
6150
|
+
/** Wall time is resolved explicitly; DST gaps/overlaps reject by default. */
|
|
6151
|
+
function toZonedValue(value, timeZone = "UTC", disambiguation = "reject") {
|
|
6152
|
+
return toZoned(parseDateTime(value), timeZone, disambiguation).toString();
|
|
6153
|
+
}
|
|
6154
|
+
function toLocalValue(value, timeZone = "UTC", seconds = false) {
|
|
6155
|
+
if (!value) return "";
|
|
6156
|
+
const zoned = value.includes("[") ? parseZonedDateTime(value) : parseAbsolute(value, timeZone);
|
|
6157
|
+
const display = parseAbsolute(zoned.toAbsoluteString(), timeZone);
|
|
6158
|
+
return toCalendarDateTime(display).toString().slice(0, seconds ? 19 : 16);
|
|
6159
|
+
}
|
|
6160
|
+
function orderedValue(value, kind) {
|
|
6161
|
+
if (kind === "datetime") return (value.includes("[") ? parseZonedDateTime(value) : parseAbsolute(value, "UTC")).toDate().getTime();
|
|
6162
|
+
if (kind === "time") {
|
|
6163
|
+
const t = parseTime(value);
|
|
6164
|
+
return t.hour * 3600 + t.minute * 60 + t.second;
|
|
6165
|
+
}
|
|
6166
|
+
return parseDate(value).toDate("UTC").getTime();
|
|
6167
|
+
}
|
|
6168
|
+
function step(value) {
|
|
6169
|
+
if (value !== void 0 && (!Number.isInteger(value) || value <= 0)) throw new RangeError("Time steps must be positive integers.");
|
|
6170
|
+
return value ?? 1;
|
|
6171
|
+
}
|
|
6172
|
+
function temporalError(value, options) {
|
|
6173
|
+
if (!value) return options.isRequired ? "required" : null;
|
|
6174
|
+
let date = "", time = "";
|
|
6175
|
+
try {
|
|
6176
|
+
if (options.kind === "date") {
|
|
6177
|
+
if (!/^(?!0000)\d{4}-\d{2}-\d{2}$/.test(value) || parseDate(value).toString() !== value) return "invalid";
|
|
6178
|
+
date = value;
|
|
6179
|
+
} else if (options.kind === "time") {
|
|
6180
|
+
if (!/^\d{2}:\d{2}(:\d{2})?$/.test(value)) return "invalid";
|
|
6181
|
+
parseTime(value);
|
|
6182
|
+
time = value;
|
|
6183
|
+
} else {
|
|
6184
|
+
orderedValue(value, "datetime");
|
|
6185
|
+
const local = toLocalValue(value, options.timeZone, true);
|
|
6186
|
+
date = local.slice(0, 10);
|
|
6187
|
+
time = local.slice(11);
|
|
6188
|
+
}
|
|
6189
|
+
if (date && (options.minDate && date < options.minDate || options.maxDate && date > options.maxDate)) return "bounds";
|
|
6190
|
+
if (time && (options.minTime && orderedValue(time, "time") < orderedValue(options.minTime, "time") || options.maxTime && orderedValue(time, "time") > orderedValue(options.maxTime, "time"))) return "bounds";
|
|
6191
|
+
if (options.kind === "datetime" && (options.minDateTime && orderedValue(value, "datetime") < orderedValue(options.minDateTime, "datetime") || options.maxDateTime && orderedValue(value, "datetime") > orderedValue(options.maxDateTime, "datetime"))) return "bounds";
|
|
6192
|
+
if (date && options.isDateUnavailable?.(date)) return "unavailable";
|
|
6193
|
+
if (time && options.isTimeUnavailable?.(time)) return "unavailable";
|
|
6194
|
+
if (time) {
|
|
6195
|
+
const t = parseTime(time);
|
|
6196
|
+
if (t.hour % step(options.hourStep) || t.minute % step(options.minuteStep) || t.second % step(options.secondStep)) return "step";
|
|
6197
|
+
}
|
|
6198
|
+
return null;
|
|
6199
|
+
} catch {
|
|
6200
|
+
return "invalid";
|
|
6201
|
+
}
|
|
6202
|
+
}
|
|
6203
|
+
function temporalRangeError(value, options) {
|
|
6204
|
+
if (!value || !value.start && !value.end) return options.isRequired ? "required" : null;
|
|
6205
|
+
if (!value.start || !value.end) return "incomplete";
|
|
6206
|
+
const error = temporalError(value.start, options) ?? temporalError(value.end, options);
|
|
6207
|
+
if (error) return error;
|
|
6208
|
+
if (orderedValue(value.start, options.kind) > orderedValue(value.end, options.kind)) return "order";
|
|
6209
|
+
if (options.kind !== "time" && options.isDateUnavailable) {
|
|
6210
|
+
const first = parseDate(options.kind === "date" ? value.start : toLocalValue(value.start, options.timeZone).slice(0, 10));
|
|
6211
|
+
const last = parseDate(options.kind === "date" ? value.end : toLocalValue(value.end, options.timeZone).slice(0, 10));
|
|
6212
|
+
for (let day = first.add({ days: 1 }); day.compare(last) < 0; day = day.add({ days: 1 })) if (options.isDateUnavailable(day.toString())) return "unavailable";
|
|
6213
|
+
}
|
|
6214
|
+
return null;
|
|
6215
|
+
}
|
|
6216
|
+
/** Project instant boundaries into the selected display zone for disabled calendar/time options. */
|
|
6217
|
+
function temporalDisplayBounds(options, selectedDate) {
|
|
6218
|
+
let minDate = options.minDate, maxDate = options.maxDate, minTime = options.minTime, maxTime = options.maxTime;
|
|
6219
|
+
if (options.kind === "datetime") try {
|
|
6220
|
+
const min = options.minDateTime ? toLocalValue(options.minDateTime, options.timeZone, true) : "", max = options.maxDateTime ? toLocalValue(options.maxDateTime, options.timeZone, true) : "";
|
|
6221
|
+
if (min) {
|
|
6222
|
+
const day = min.slice(0, 10);
|
|
6223
|
+
if (!minDate || day > minDate) minDate = day;
|
|
6224
|
+
if (selectedDate === day && (!minTime || orderedValue(min.slice(11), "time") > orderedValue(minTime, "time"))) minTime = min.slice(11);
|
|
6225
|
+
}
|
|
6226
|
+
if (max) {
|
|
6227
|
+
const day = max.slice(0, 10);
|
|
6228
|
+
if (!maxDate || day < maxDate) maxDate = day;
|
|
6229
|
+
if (selectedDate === day && (!maxTime || orderedValue(max.slice(11), "time") < orderedValue(maxTime, "time"))) maxTime = max.slice(11);
|
|
6230
|
+
}
|
|
6231
|
+
} catch {}
|
|
6232
|
+
return {
|
|
6233
|
+
minDate,
|
|
6234
|
+
maxDate,
|
|
6235
|
+
minTime,
|
|
6236
|
+
maxTime
|
|
6237
|
+
};
|
|
6238
|
+
}
|
|
6239
|
+
/** Minute-granularity list; seconds are edited with TimeField/TimeClock to avoid 86k DOM options. */
|
|
6240
|
+
function timeChoices(options) {
|
|
6241
|
+
const hours = step(options.hourStep), minutes = options.granularity === "hour" ? 60 : step(options.minuteStep ?? 30);
|
|
6242
|
+
const values = [];
|
|
6243
|
+
for (let hour = 0; hour < 24; hour += hours) for (let minute = 0; minute < 60; minute += minutes) {
|
|
6244
|
+
const value = `${String(hour).padStart(2, "0")}:${String(minute).padStart(2, "0")}`;
|
|
6245
|
+
if (!temporalError(value, options)) values.push(value);
|
|
6246
|
+
}
|
|
6247
|
+
return values;
|
|
6248
|
+
}
|
|
6249
|
+
/** User edits zero units hidden by the configured field granularity. */
|
|
6250
|
+
function normalizeTime(value, granularity = "minute") {
|
|
6251
|
+
const time = parseTime(value);
|
|
6252
|
+
return time.set({
|
|
6253
|
+
minute: granularity === "hour" ? 0 : time.minute,
|
|
6254
|
+
second: granularity === "second" ? time.second : 0,
|
|
6255
|
+
millisecond: 0
|
|
6256
|
+
}).toString().slice(0, granularity === "second" ? 8 : 5);
|
|
6257
|
+
}
|
|
6258
|
+
function normalizeWallDateTime(value, granularity = "minute") {
|
|
6259
|
+
const date = parseDateTime(value);
|
|
6260
|
+
return date.toString().slice(0, 10) + "T" + normalizeTime(date.toString().slice(11), granularity);
|
|
6261
|
+
}
|
|
6262
|
+
/** Keep the selected unit and choose the nearest complete valid time for the other units. */
|
|
6263
|
+
function resolveTimeUnit(value, part, selected, options) {
|
|
6264
|
+
let initial;
|
|
6265
|
+
try {
|
|
6266
|
+
initial = parseTime(value || options.minTime || "00:00");
|
|
6267
|
+
} catch {
|
|
6268
|
+
initial = parseTime("00:00");
|
|
6269
|
+
}
|
|
6270
|
+
const desired = initial.set({ [part]: selected });
|
|
6271
|
+
let best = null, distance = Infinity;
|
|
6272
|
+
const hours = step(options.hourStep), minutes = step(options.minuteStep), seconds = step(options.secondStep);
|
|
6273
|
+
for (let hour = 0; hour < 24; hour += hours) {
|
|
6274
|
+
if (part === "hour" && hour !== selected) continue;
|
|
6275
|
+
for (let minute = 0; minute < 60; minute += options.granularity === "hour" ? 60 : minutes) {
|
|
6276
|
+
if (part === "minute" && minute !== selected) continue;
|
|
6277
|
+
for (let second = 0; second < 60; second += options.granularity === "second" ? seconds : 60) {
|
|
6278
|
+
if (part === "second" && second !== selected) continue;
|
|
6279
|
+
const next = normalizeTime(`${String(hour).padStart(2, "0")}:${String(minute).padStart(2, "0")}:${String(second).padStart(2, "0")}`, options.granularity);
|
|
6280
|
+
if (temporalError(next, {
|
|
6281
|
+
...options,
|
|
6282
|
+
kind: "time"
|
|
6283
|
+
})) continue;
|
|
6284
|
+
const delta = Math.abs(orderedValue(next, "time") - (desired.hour * 3600 + desired.minute * 60 + desired.second));
|
|
6285
|
+
if (delta < distance) {
|
|
6286
|
+
best = next;
|
|
6287
|
+
distance = delta;
|
|
6288
|
+
}
|
|
6289
|
+
}
|
|
6290
|
+
}
|
|
6291
|
+
}
|
|
6292
|
+
return best;
|
|
6293
|
+
}
|
|
6294
|
+
function temporalMessages(locale = "id-ID") {
|
|
6295
|
+
return locale.startsWith("id") ? {
|
|
6296
|
+
invalid: "Nilai tanggal atau waktu tidak valid.",
|
|
6297
|
+
required: "Nilai wajib diisi.",
|
|
6298
|
+
incomplete: "Lengkapi nilai mulai dan akhir.",
|
|
6299
|
+
order: "Nilai akhir harus setelah atau sama dengan nilai mulai.",
|
|
6300
|
+
bounds: "Nilai berada di luar batas yang diizinkan.",
|
|
6301
|
+
unavailable: "Nilai tidak tersedia.",
|
|
6302
|
+
step: "Nilai tidak sesuai interval yang diizinkan."
|
|
6303
|
+
} : {
|
|
6304
|
+
invalid: "Invalid date or time.",
|
|
6305
|
+
required: "A value is required.",
|
|
6306
|
+
incomplete: "Enter both start and end values.",
|
|
6307
|
+
order: "End must be on or after start.",
|
|
6308
|
+
bounds: "Value is outside the allowed limits.",
|
|
6309
|
+
unavailable: "Value is unavailable.",
|
|
6310
|
+
step: "Value does not match the allowed interval."
|
|
6311
|
+
};
|
|
6312
|
+
}
|
|
6313
|
+
//#endregion
|
|
6314
|
+
//#region src/TemporalField.tsx
|
|
6315
|
+
function parsed(value, kind, zone) {
|
|
6316
|
+
try {
|
|
6317
|
+
return value ? kind === "time" ? parseTime(value) : kind === "date" ? parseDate(value) : parseDateTime(toLocalValue(value, zone, true)) : null;
|
|
6318
|
+
} catch {
|
|
6319
|
+
return null;
|
|
6320
|
+
}
|
|
6321
|
+
}
|
|
6322
|
+
function TemporalField({ kind, ...props }) {
|
|
6323
|
+
const [local, setLocal] = useState(props.defaultValue ?? null), [editError, setEditError] = useState(null);
|
|
6324
|
+
const value = props.value === void 0 ? local : props.value;
|
|
6325
|
+
const id = useId();
|
|
6326
|
+
const error = editError ?? temporalError(value, {
|
|
6327
|
+
...props,
|
|
6328
|
+
kind
|
|
6329
|
+
});
|
|
6330
|
+
useEffect(() => {
|
|
6331
|
+
setEditError(null);
|
|
6332
|
+
}, [value]);
|
|
6333
|
+
function change(v) {
|
|
6334
|
+
if (props.isDisabled || props.isReadOnly) return;
|
|
6335
|
+
let next;
|
|
6336
|
+
try {
|
|
6337
|
+
next = v ? kind === "datetime" ? toZonedValue(normalizeWallDateTime(v.toString(), props.granularity), props.timeZone, props.disambiguation) : kind === "time" ? normalizeTime(v.toString(), props.granularity) : v.toString().slice(0, 10) : null;
|
|
6338
|
+
} catch {
|
|
6339
|
+
const message = temporalMessages(props.locale).invalid;
|
|
6340
|
+
setEditError(message);
|
|
6341
|
+
props.onError?.(message);
|
|
6342
|
+
return;
|
|
6343
|
+
}
|
|
6344
|
+
setEditError(null);
|
|
6345
|
+
setLocal(next);
|
|
6346
|
+
props.onChange?.(next);
|
|
6347
|
+
props.onError?.(temporalError(next, {
|
|
6348
|
+
...props,
|
|
6349
|
+
kind
|
|
6350
|
+
}));
|
|
6351
|
+
}
|
|
6352
|
+
const fieldContent = /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Label$3, {
|
|
6353
|
+
className: partClass(props.hideLabel ? "temporal__sr-only" : "input__label", props.classNames?.label),
|
|
6354
|
+
children: props.label
|
|
6355
|
+
}), /* @__PURE__ */ jsx(DateInput, {
|
|
6356
|
+
className: partClass("temporal-field__input input__control", props.classNames?.input),
|
|
6357
|
+
children: (segment) => /* @__PURE__ */ jsx(DateSegment, {
|
|
6358
|
+
segment,
|
|
6359
|
+
className: partClass("temporal-field__segment", props.classNames?.segment)
|
|
6360
|
+
})
|
|
6361
|
+
})] });
|
|
6362
|
+
const shared = {
|
|
6363
|
+
id: props.id ?? id,
|
|
6364
|
+
isDisabled: props.isDisabled,
|
|
6365
|
+
isReadOnly: props.isReadOnly,
|
|
6366
|
+
isRequired: props.isRequired,
|
|
6367
|
+
isInvalid: props.isInvalid || !!error,
|
|
6368
|
+
validationBehavior: "aria",
|
|
6369
|
+
"aria-describedby": [props.description ? `${id}-description` : void 0, props.isInvalid || error ? `${id}-error` : void 0].filter(Boolean).join(" ") || void 0
|
|
6370
|
+
};
|
|
6371
|
+
return /* @__PURE__ */ jsx(I18nProvider, {
|
|
6372
|
+
locale: props.locale ?? "id-ID",
|
|
6373
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
6374
|
+
className: partClass(partClass("input temporal-field", props.classNames?.root), props.className),
|
|
6375
|
+
style: props.style,
|
|
6376
|
+
dir: props.dir,
|
|
6377
|
+
children: [
|
|
6378
|
+
kind === "time" ? /* @__PURE__ */ jsx(TimeField$1, {
|
|
6379
|
+
...shared,
|
|
6380
|
+
value: parsed(value, kind, props.timeZone),
|
|
6381
|
+
onChange: change,
|
|
6382
|
+
granularity: props.granularity ?? "minute",
|
|
6383
|
+
hourCycle: props.hourCycle,
|
|
6384
|
+
children: fieldContent
|
|
6385
|
+
}) : /* @__PURE__ */ jsx(DateField$1, {
|
|
6386
|
+
...shared,
|
|
6387
|
+
value: parsed(value, kind, props.timeZone),
|
|
6388
|
+
onChange: change,
|
|
6389
|
+
granularity: kind === "date" ? "day" : props.granularity ?? "minute",
|
|
6390
|
+
hourCycle: props.hourCycle,
|
|
6391
|
+
children: fieldContent
|
|
6392
|
+
}),
|
|
6393
|
+
props.description && /* @__PURE__ */ jsx("span", {
|
|
6394
|
+
id: `${id}-description`,
|
|
6395
|
+
className: partClass("input__description", props.classNames?.description),
|
|
6396
|
+
children: props.description
|
|
6397
|
+
}),
|
|
6398
|
+
(props.isInvalid || error) && /* @__PURE__ */ jsx("span", {
|
|
6399
|
+
id: `${id}-error`,
|
|
6400
|
+
className: partClass("input__error", props.classNames?.error),
|
|
6401
|
+
role: "alert",
|
|
6402
|
+
children: props.errorMessage ?? (error && error in temporalMessages(props.locale) ? temporalMessages(props.locale)[error] : error ?? temporalMessages(props.locale).invalid)
|
|
6403
|
+
}),
|
|
6404
|
+
props.name && /* @__PURE__ */ jsx("input", {
|
|
6405
|
+
type: "hidden",
|
|
6406
|
+
name: props.name,
|
|
6407
|
+
value: value ?? "",
|
|
6408
|
+
disabled: props.isDisabled
|
|
6409
|
+
}),
|
|
6410
|
+
/* @__PURE__ */ jsx(SelectionValidation, {
|
|
6411
|
+
hasValue: !!value && !error,
|
|
6412
|
+
required: props.isRequired || !!error,
|
|
6413
|
+
disabled: props.isDisabled || props.formValidation === false,
|
|
6414
|
+
onInvalid: () => props.onError?.(error ?? "required"),
|
|
6415
|
+
onResetStart: () => {},
|
|
6416
|
+
onReset: (cancelled) => {
|
|
6417
|
+
if (!cancelled && props.value === void 0) {
|
|
6418
|
+
setLocal(props.defaultValue ?? null);
|
|
6419
|
+
setEditError(null);
|
|
6420
|
+
}
|
|
6421
|
+
}
|
|
6422
|
+
})
|
|
6423
|
+
]
|
|
6424
|
+
})
|
|
6425
|
+
});
|
|
6426
|
+
}
|
|
6427
|
+
function DateField(props) {
|
|
6428
|
+
return /* @__PURE__ */ jsx(TemporalField, {
|
|
6429
|
+
...props,
|
|
6430
|
+
kind: "date"
|
|
6431
|
+
});
|
|
6432
|
+
}
|
|
6433
|
+
function TimeField(props) {
|
|
6434
|
+
return /* @__PURE__ */ jsx(TemporalField, {
|
|
6435
|
+
...props,
|
|
6436
|
+
kind: "time"
|
|
6437
|
+
});
|
|
6438
|
+
}
|
|
6439
|
+
function DateTimeField(props) {
|
|
6440
|
+
return /* @__PURE__ */ jsx(TemporalField, {
|
|
6441
|
+
...props,
|
|
6442
|
+
kind: "datetime"
|
|
6443
|
+
});
|
|
6444
|
+
}
|
|
6445
|
+
function TemporalRangeField({ kind, ...props }) {
|
|
6446
|
+
const groupId = useId();
|
|
6447
|
+
const [local, setLocal] = useState(props.defaultValue ?? null);
|
|
6448
|
+
const value = props.value === void 0 ? local : props.value;
|
|
6449
|
+
const error = temporalRangeError(value, {
|
|
6450
|
+
...props,
|
|
6451
|
+
kind
|
|
6452
|
+
});
|
|
6453
|
+
const fields = /* @__PURE__ */ jsx("div", {
|
|
6454
|
+
className: "temporal-picker__fields",
|
|
6455
|
+
children: ["start", "end"].map((part) => /* @__PURE__ */ createElement(TemporalField, {
|
|
6456
|
+
...props,
|
|
6457
|
+
id: props.id ? `${props.id}-${part}` : void 0,
|
|
6458
|
+
className: void 0,
|
|
6459
|
+
style: void 0,
|
|
6460
|
+
classNames: {
|
|
6461
|
+
...props.classNames,
|
|
6462
|
+
root: void 0
|
|
6463
|
+
},
|
|
6464
|
+
kind,
|
|
6465
|
+
key: part,
|
|
6466
|
+
value: value?.[part] ?? null,
|
|
6467
|
+
defaultValue: void 0,
|
|
6468
|
+
formValidation: false,
|
|
6469
|
+
name: props.name ? `${props.name}.${part}` : void 0,
|
|
6470
|
+
label: `${props.label} ${part === "start" ? props.locale?.startsWith("id") ? "Mulai" : "Start" : props.locale?.startsWith("id") ? "Akhir" : "End"}`,
|
|
6471
|
+
onChange: (next) => {
|
|
6472
|
+
const result = {
|
|
6473
|
+
...value ?? {
|
|
6474
|
+
start: "",
|
|
6475
|
+
end: ""
|
|
6476
|
+
},
|
|
6477
|
+
[part]: next ?? ""
|
|
6478
|
+
};
|
|
6479
|
+
setLocal(result);
|
|
6480
|
+
props.onChange?.(result);
|
|
6481
|
+
}
|
|
6482
|
+
}))
|
|
6483
|
+
});
|
|
6484
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
6485
|
+
id: props.id ?? groupId,
|
|
6486
|
+
role: "group",
|
|
6487
|
+
"aria-label": props.label,
|
|
6488
|
+
"aria-describedby": error ? `${groupId}-error` : void 0,
|
|
6489
|
+
className: partClass(partClass("temporal-range-field", props.classNames?.root), props.className),
|
|
6490
|
+
style: props.style,
|
|
6491
|
+
children: [
|
|
6492
|
+
fields,
|
|
6493
|
+
error && /* @__PURE__ */ jsx("span", {
|
|
6494
|
+
id: `${groupId}-error`,
|
|
6495
|
+
role: "alert",
|
|
6496
|
+
className: "input__error",
|
|
6497
|
+
children: props.errorMessage ?? temporalMessages(props.locale)[error]
|
|
6498
|
+
}),
|
|
6499
|
+
/* @__PURE__ */ jsx(SelectionValidation, {
|
|
6500
|
+
hasValue: !!value && !error,
|
|
6501
|
+
required: props.isRequired || !!error,
|
|
6502
|
+
disabled: props.isDisabled || props.formValidation === false,
|
|
6503
|
+
onInvalid: () => props.onError?.(error ?? "required"),
|
|
6504
|
+
onResetStart: () => {},
|
|
6505
|
+
onReset: (cancelled) => {
|
|
6506
|
+
if (!cancelled && props.value === void 0) setLocal(props.defaultValue ?? null);
|
|
6507
|
+
}
|
|
6508
|
+
})
|
|
6509
|
+
]
|
|
6510
|
+
});
|
|
6511
|
+
}
|
|
6512
|
+
function DateRangeField(props) {
|
|
6513
|
+
return /* @__PURE__ */ jsx(TemporalRangeField, {
|
|
6514
|
+
...props,
|
|
6515
|
+
kind: "date"
|
|
6516
|
+
});
|
|
6517
|
+
}
|
|
6518
|
+
function TimeRangeField(props) {
|
|
6519
|
+
return /* @__PURE__ */ jsx(TemporalRangeField, {
|
|
6520
|
+
...props,
|
|
6521
|
+
kind: "time"
|
|
6522
|
+
});
|
|
6523
|
+
}
|
|
6524
|
+
function DateTimeRangeField(props) {
|
|
6525
|
+
return /* @__PURE__ */ jsx(TemporalRangeField, {
|
|
6526
|
+
...props,
|
|
6527
|
+
kind: "datetime"
|
|
6528
|
+
});
|
|
6529
|
+
}
|
|
6530
|
+
//#endregion
|
|
6531
|
+
//#region src/TimeControls.tsx
|
|
6532
|
+
function format(value, locale, hourCycle) {
|
|
6533
|
+
const time = parseTime(value);
|
|
6534
|
+
const date = new Date(Date.UTC(2e3, 0, 1, time.hour, time.minute, time.second));
|
|
6535
|
+
return new Intl.DateTimeFormat(locale, {
|
|
6536
|
+
hour: "2-digit",
|
|
6537
|
+
minute: "2-digit",
|
|
6538
|
+
hourCycle: hourCycle === 12 ? "h12" : "h23",
|
|
6539
|
+
timeZone: "UTC"
|
|
6540
|
+
}).format(date);
|
|
6541
|
+
}
|
|
6542
|
+
function TimeList({ value, defaultValue, onChange, label = "Time", locale = "id-ID", hourCycle, isDisabled, isReadOnly, className, minTime, maxTime, hourStep, minuteStep, secondStep, granularity, isTimeUnavailable, ...props }) {
|
|
6543
|
+
const [local, setLocal] = useState(defaultValue ?? "");
|
|
6544
|
+
const actual = value === void 0 ? local : value ?? "";
|
|
6545
|
+
const options = {
|
|
6546
|
+
kind: "time",
|
|
6547
|
+
minTime,
|
|
6548
|
+
maxTime,
|
|
6549
|
+
hourStep,
|
|
6550
|
+
minuteStep,
|
|
6551
|
+
secondStep,
|
|
6552
|
+
granularity,
|
|
6553
|
+
isTimeUnavailable
|
|
6554
|
+
};
|
|
6555
|
+
return /* @__PURE__ */ jsx("div", {
|
|
6556
|
+
...props,
|
|
6557
|
+
className: partClass("time-list", className),
|
|
6558
|
+
children: /* @__PURE__ */ jsxs("select", {
|
|
6559
|
+
"aria-label": label,
|
|
6560
|
+
size: 6,
|
|
6561
|
+
value: actual,
|
|
6562
|
+
disabled: isDisabled,
|
|
6563
|
+
"aria-readonly": isReadOnly || void 0,
|
|
6564
|
+
onChange: (event) => {
|
|
6565
|
+
if (isReadOnly) {
|
|
6566
|
+
event.currentTarget.value = actual;
|
|
6567
|
+
return;
|
|
6568
|
+
}
|
|
6569
|
+
setLocal(event.target.value);
|
|
6570
|
+
onChange?.(event.target.value);
|
|
6571
|
+
},
|
|
6572
|
+
children: [/* @__PURE__ */ jsx("option", {
|
|
6573
|
+
value: "",
|
|
6574
|
+
disabled: true,
|
|
6575
|
+
children: locale.startsWith("id") ? "Pilih waktu" : "Choose time"
|
|
6576
|
+
}), timeChoices(options).map((time) => /* @__PURE__ */ jsx("option", {
|
|
6577
|
+
value: time,
|
|
6578
|
+
children: format(time, locale, hourCycle)
|
|
6579
|
+
}, time))]
|
|
6580
|
+
})
|
|
6581
|
+
});
|
|
6582
|
+
}
|
|
6583
|
+
function TimeClock({ value, defaultValue, onChange, label = "Time", locale = "id-ID", hourCycle = 24, isDisabled, isReadOnly, className, minTime, maxTime, hourStep = 1, minuteStep = 1, secondStep = 1, granularity = "minute", isTimeUnavailable, ...props }) {
|
|
6584
|
+
const [local, setLocal] = useState(defaultValue ?? minTime ?? "00:00");
|
|
6585
|
+
const actual = value === void 0 ? local : value || minTime || "00:00";
|
|
6586
|
+
let time;
|
|
6587
|
+
try {
|
|
6588
|
+
time = parseTime(actual);
|
|
6589
|
+
} catch {
|
|
6590
|
+
time = parseTime("00:00");
|
|
6591
|
+
}
|
|
6592
|
+
const id = locale.startsWith("id");
|
|
6593
|
+
const parts = granularity === "hour" ? ["hour"] : granularity === "second" ? [
|
|
6594
|
+
"hour",
|
|
6595
|
+
"minute",
|
|
6596
|
+
"second"
|
|
6597
|
+
] : ["hour", "minute"];
|
|
6598
|
+
return /* @__PURE__ */ jsx("div", {
|
|
6599
|
+
...props,
|
|
6600
|
+
role: "group",
|
|
6601
|
+
"aria-label": label,
|
|
6602
|
+
className: partClass("time-clock", className),
|
|
6603
|
+
children: parts.map((part) => {
|
|
6604
|
+
const step = part === "hour" ? hourStep : part === "minute" ? minuteStep : secondStep;
|
|
6605
|
+
const count = part === "hour" ? 24 : 60;
|
|
6606
|
+
const values = Array.from({ length: Math.ceil(count / Math.max(1, step)) }, (_, i) => i * Math.max(1, step)).filter((n) => n < count);
|
|
6607
|
+
return /* @__PURE__ */ jsxs("label", { children: [/* @__PURE__ */ jsx("span", { children: part === "hour" ? id ? "Jam" : "Hours" : part === "minute" ? id ? "Menit" : "Minutes" : id ? "Detik" : "Seconds" }), /* @__PURE__ */ jsx("select", {
|
|
6608
|
+
value: time[part],
|
|
6609
|
+
disabled: isDisabled,
|
|
6610
|
+
"aria-readonly": isReadOnly || void 0,
|
|
6611
|
+
onChange: (event) => {
|
|
6612
|
+
if (isReadOnly) {
|
|
6613
|
+
event.currentTarget.value = String(time[part]);
|
|
6614
|
+
return;
|
|
6615
|
+
}
|
|
6616
|
+
const next = resolveTimeUnit(time.toString(), part, Number(event.target.value), {
|
|
6617
|
+
kind: "time",
|
|
6618
|
+
minTime,
|
|
6619
|
+
maxTime,
|
|
6620
|
+
hourStep,
|
|
6621
|
+
minuteStep,
|
|
6622
|
+
secondStep,
|
|
6623
|
+
granularity,
|
|
6624
|
+
isTimeUnavailable
|
|
6625
|
+
});
|
|
6626
|
+
if (!next) return;
|
|
6627
|
+
setLocal(next);
|
|
6628
|
+
onChange?.(next);
|
|
6629
|
+
},
|
|
6630
|
+
children: values.map((n) => /* @__PURE__ */ jsx("option", {
|
|
6631
|
+
value: n,
|
|
6632
|
+
children: part === "hour" && hourCycle === 12 ? `${n % 12 || 12} ${n < 12 ? "AM" : "PM"}` : String(n).padStart(2, "0")
|
|
6633
|
+
}, n))
|
|
6634
|
+
})] }, part);
|
|
6635
|
+
})
|
|
6636
|
+
});
|
|
6637
|
+
}
|
|
6638
|
+
//#endregion
|
|
6639
|
+
//#region src/TemporalPicker.tsx
|
|
6640
|
+
var PickerContext = createContext(null);
|
|
6641
|
+
function usePicker() {
|
|
6642
|
+
const context = useContext(PickerContext);
|
|
6643
|
+
if (!context) throw new Error("Picker parts must be inside their picker Root.");
|
|
6644
|
+
return context;
|
|
6645
|
+
}
|
|
6646
|
+
function labels(locale = "id-ID") {
|
|
6647
|
+
return locale.startsWith("id") ? {
|
|
6648
|
+
apply: "Terapkan",
|
|
6649
|
+
cancel: "Batal",
|
|
6650
|
+
clear: "Kosongkan",
|
|
6651
|
+
today: "Hari ini",
|
|
6652
|
+
now: "Sekarang",
|
|
6653
|
+
start: "Mulai",
|
|
6654
|
+
end: "Akhir",
|
|
6655
|
+
choose: "Pilih tanggal atau waktu"
|
|
6656
|
+
} : {
|
|
6657
|
+
apply: "Apply",
|
|
6658
|
+
cancel: "Cancel",
|
|
6659
|
+
clear: "Clear",
|
|
6660
|
+
today: "Today",
|
|
6661
|
+
now: "Now",
|
|
6662
|
+
start: "Start",
|
|
6663
|
+
end: "End",
|
|
6664
|
+
choose: "Choose date or time"
|
|
6665
|
+
};
|
|
6666
|
+
}
|
|
6667
|
+
function localValue(value, kind, options) {
|
|
6668
|
+
try {
|
|
6669
|
+
return kind === "datetime" ? toLocalValue(value, options.timeZone, options.granularity === "second") : value;
|
|
6670
|
+
} catch {
|
|
6671
|
+
return "";
|
|
6672
|
+
}
|
|
6673
|
+
}
|
|
6674
|
+
function datePart(value, kind, options) {
|
|
6675
|
+
return localValue(value, kind, options).slice(0, 10);
|
|
6676
|
+
}
|
|
6677
|
+
function combineDate(date, time, options) {
|
|
6678
|
+
try {
|
|
6679
|
+
return toZonedValue(`${date}T${time || "00:00"}`, options.timeZone, options.disambiguation);
|
|
6680
|
+
} catch {
|
|
6681
|
+
return "";
|
|
6682
|
+
}
|
|
6683
|
+
}
|
|
6684
|
+
function displayText(value, kind, options) {
|
|
6685
|
+
if (!value) return labels(options.locale).choose;
|
|
6686
|
+
if (options.formatValue) return options.formatValue(value, options.locale ?? "id-ID");
|
|
6687
|
+
const one = (v) => {
|
|
6688
|
+
if (!v) return "—";
|
|
6689
|
+
try {
|
|
6690
|
+
if (kind === "time") return new Intl.DateTimeFormat(options.locale ?? "id-ID", {
|
|
6691
|
+
hour: "2-digit",
|
|
6692
|
+
minute: "2-digit",
|
|
6693
|
+
second: options.granularity === "second" ? "2-digit" : void 0,
|
|
6694
|
+
hourCycle: options.hourCycle === 12 ? "h12" : "h23",
|
|
6695
|
+
timeZone: "UTC"
|
|
6696
|
+
}).format(/* @__PURE__ */ new Date(`2000-01-01T${v}Z`));
|
|
6697
|
+
if (kind === "date") return new Intl.DateTimeFormat(options.locale ?? "id-ID", {
|
|
6698
|
+
day: "numeric",
|
|
6699
|
+
month: "short",
|
|
6700
|
+
year: "numeric",
|
|
6701
|
+
timeZone: "UTC"
|
|
6702
|
+
}).format(/* @__PURE__ */ new Date(`${v}T12:00:00Z`));
|
|
6703
|
+
return `${localValue(v, kind, options).replace("T", " ")} ${options.timeZone ?? "UTC"}`;
|
|
6704
|
+
} catch {
|
|
6705
|
+
return v;
|
|
6706
|
+
}
|
|
6707
|
+
};
|
|
6708
|
+
return typeof value === "string" ? one(value) : `${one(value.start)} – ${one(value.end)}`;
|
|
6709
|
+
}
|
|
6710
|
+
function TemporalPickerField({ part = "start", ...props }) {
|
|
6711
|
+
const context = usePicker(), o = context.options, l = labels(o.locale);
|
|
6712
|
+
const Field = context.kind === "date" ? DateField : context.kind === "time" ? TimeField : DateTimeField;
|
|
6713
|
+
const value = typeof context.draft === "string" ? context.draft : context.draft?.[part] ?? null;
|
|
6714
|
+
return /* @__PURE__ */ jsx(Field, {
|
|
6715
|
+
...o,
|
|
6716
|
+
...props,
|
|
6717
|
+
className: partClass(o.classNames?.field ?? "", props.className),
|
|
6718
|
+
style: props.style,
|
|
6719
|
+
classNames: void 0,
|
|
6720
|
+
label: props.label ?? (context.range ? `${o.label} ${l[part]}` : o.label),
|
|
6721
|
+
value,
|
|
6722
|
+
name: void 0,
|
|
6723
|
+
formValidation: false,
|
|
6724
|
+
isRequired: false,
|
|
6725
|
+
onError: (error) => context.inputError(part, error),
|
|
6726
|
+
onChange: (next) => context.edit(context.range ? {
|
|
6727
|
+
...typeof context.draft === "object" && context.draft ? context.draft : {
|
|
6728
|
+
start: "",
|
|
6729
|
+
end: ""
|
|
6730
|
+
},
|
|
6731
|
+
[part]: next ?? ""
|
|
6732
|
+
} : next, part)
|
|
6733
|
+
});
|
|
6734
|
+
}
|
|
6735
|
+
function TemporalPickerCalendar(props) {
|
|
6736
|
+
const c = usePicker(), o = c.options;
|
|
6737
|
+
const selected = typeof c.draft === "string" ? c.draft : "";
|
|
6738
|
+
const onSingle = (value) => {
|
|
6739
|
+
if (c.kind === "date") c.edit(value);
|
|
6740
|
+
else {
|
|
6741
|
+
const next = value ? combineDate(value, localValue(selected, c.kind, o).slice(11), o) : null;
|
|
6742
|
+
if (value && !next) {
|
|
6743
|
+
c.inputError("date", "invalid");
|
|
6744
|
+
return;
|
|
6745
|
+
}
|
|
6746
|
+
c.edit(next);
|
|
6747
|
+
}
|
|
6748
|
+
};
|
|
6749
|
+
const bounds = temporalDisplayBounds({
|
|
6750
|
+
...o,
|
|
6751
|
+
kind: c.kind
|
|
6752
|
+
});
|
|
6753
|
+
const range = typeof c.draft === "object" && c.draft ? c.draft : {
|
|
6754
|
+
start: "",
|
|
6755
|
+
end: ""
|
|
6756
|
+
};
|
|
6757
|
+
return /* @__PURE__ */ jsx("div", {
|
|
6758
|
+
...props,
|
|
6759
|
+
className: partClass("temporal-picker__calendar", props.className),
|
|
6760
|
+
children: c.kind !== "time" && (c.range ? /* @__PURE__ */ jsx(RangeCalendar, {
|
|
6761
|
+
...o,
|
|
6762
|
+
minDate: bounds.minDate,
|
|
6763
|
+
maxDate: bounds.maxDate,
|
|
6764
|
+
style: void 0,
|
|
6765
|
+
className: void 0,
|
|
6766
|
+
classNames: void 0,
|
|
6767
|
+
value: {
|
|
6768
|
+
start: datePart(range.start, c.kind, o),
|
|
6769
|
+
end: datePart(range.end, c.kind, o)
|
|
6770
|
+
},
|
|
6771
|
+
onChange: (v) => {
|
|
6772
|
+
if (!v || c.kind === "date") {
|
|
6773
|
+
c.edit(v);
|
|
6774
|
+
return;
|
|
6775
|
+
}
|
|
6776
|
+
const start = v.start ? combineDate(v.start, localValue(range.start, c.kind, o).slice(11), o) : "", end = v.end ? combineDate(v.end, localValue(range.end, c.kind, o).slice(11), o) : "";
|
|
6777
|
+
if (v.start && !start || v.end && !end) {
|
|
6778
|
+
c.inputError("date", "invalid");
|
|
6779
|
+
return;
|
|
6780
|
+
}
|
|
6781
|
+
c.edit({
|
|
6782
|
+
start,
|
|
6783
|
+
end
|
|
6784
|
+
});
|
|
6785
|
+
}
|
|
6786
|
+
}) : /* @__PURE__ */ jsx(Calendar, {
|
|
6787
|
+
...o,
|
|
6788
|
+
minDate: bounds.minDate,
|
|
6789
|
+
maxDate: bounds.maxDate,
|
|
6790
|
+
style: void 0,
|
|
6791
|
+
className: void 0,
|
|
6792
|
+
classNames: void 0,
|
|
6793
|
+
value: datePart(selected, c.kind, o),
|
|
6794
|
+
onChange: onSingle
|
|
6795
|
+
}))
|
|
6796
|
+
});
|
|
6797
|
+
}
|
|
6798
|
+
function TemporalPickerTime({ part = "start", ...props }) {
|
|
6799
|
+
const c = usePicker(), o = c.options, l = labels(o.locale);
|
|
6800
|
+
const wall = localValue(typeof c.draft === "string" ? c.draft : c.draft?.[part] ?? "", c.kind, o);
|
|
6801
|
+
const time = c.kind === "time" ? wall : wall.slice(11);
|
|
6802
|
+
const bounds = temporalDisplayBounds({
|
|
6803
|
+
...o,
|
|
6804
|
+
kind: c.kind
|
|
6805
|
+
}, wall.slice(0, 10));
|
|
6806
|
+
const Control = o.timePresentation === "clock" ? TimeClock : TimeList;
|
|
6807
|
+
return /* @__PURE__ */ jsx("div", {
|
|
6808
|
+
...props,
|
|
6809
|
+
className: partClass("temporal-picker__time", props.className),
|
|
6810
|
+
children: /* @__PURE__ */ jsx(Control, {
|
|
6811
|
+
locale: o.locale,
|
|
6812
|
+
hourCycle: o.hourCycle,
|
|
6813
|
+
minTime: bounds.minTime,
|
|
6814
|
+
maxTime: bounds.maxTime,
|
|
6815
|
+
hourStep: o.hourStep,
|
|
6816
|
+
minuteStep: o.minuteStep,
|
|
6817
|
+
secondStep: o.secondStep,
|
|
6818
|
+
granularity: o.granularity,
|
|
6819
|
+
isTimeUnavailable: o.isTimeUnavailable,
|
|
6820
|
+
isDisabled: o.isDisabled,
|
|
6821
|
+
isReadOnly: o.isReadOnly,
|
|
6822
|
+
label: c.range ? `${o.label} ${l[part]}` : o.label,
|
|
6823
|
+
value: time,
|
|
6824
|
+
onChange: (next) => {
|
|
6825
|
+
const result = c.kind === "time" ? next : combineDate(wall.slice(0, 10) || o.referenceDate || today(o.timeZone ?? "UTC").toString(), next, o);
|
|
6826
|
+
if (!result) {
|
|
6827
|
+
c.inputError(part, "invalid");
|
|
6828
|
+
return;
|
|
6829
|
+
}
|
|
6830
|
+
c.edit(c.range ? {
|
|
6831
|
+
...typeof c.draft === "object" && c.draft ? c.draft : {
|
|
6832
|
+
start: "",
|
|
6833
|
+
end: ""
|
|
6834
|
+
},
|
|
6835
|
+
[part]: result
|
|
6836
|
+
} : result, part);
|
|
6837
|
+
}
|
|
6838
|
+
})
|
|
6839
|
+
});
|
|
6840
|
+
}
|
|
6841
|
+
function TemporalPickerValue({ children, className, ...props }) {
|
|
6842
|
+
const c = usePicker();
|
|
6843
|
+
return /* @__PURE__ */ jsx("span", {
|
|
6844
|
+
...props,
|
|
6845
|
+
id: `${c.id}-value`,
|
|
6846
|
+
className: partClass("date-range__value", className),
|
|
6847
|
+
children: children ?? c.text
|
|
6848
|
+
});
|
|
6849
|
+
}
|
|
6850
|
+
function TemporalPickerTrigger({ children, className, ...props }) {
|
|
6851
|
+
const c = usePicker();
|
|
6852
|
+
return /* @__PURE__ */ jsx(Button$1, {
|
|
6853
|
+
...props,
|
|
6854
|
+
isDisabled: c.options.isDisabled,
|
|
6855
|
+
className: partClass("date-range__trigger", className),
|
|
6856
|
+
"aria-labelledby": `${c.id}-label ${c.id}-value`,
|
|
6857
|
+
"aria-invalid": c.invalid || void 0,
|
|
6858
|
+
"aria-describedby": c.describedBy,
|
|
6859
|
+
children: children ?? /* @__PURE__ */ jsx(TemporalPickerValue, {})
|
|
6860
|
+
});
|
|
6861
|
+
}
|
|
6862
|
+
function TemporalPickerContent({ children, className, ...props }) {
|
|
6863
|
+
const c = usePicker();
|
|
6864
|
+
return /* @__PURE__ */ jsx("div", {
|
|
6865
|
+
...props,
|
|
6866
|
+
className,
|
|
6867
|
+
children: children ?? c.panel
|
|
6868
|
+
});
|
|
6869
|
+
}
|
|
6870
|
+
function TemporalPickerPopover({ children, className, ...props }) {
|
|
6871
|
+
const c = usePicker();
|
|
6872
|
+
return /* @__PURE__ */ jsx(Popover$2, {
|
|
6873
|
+
className: partClass("date-range__panel temporal-picker__panel", className),
|
|
6874
|
+
placement: "bottom start",
|
|
6875
|
+
offset: 8,
|
|
6876
|
+
children: /* @__PURE__ */ jsx(Dialog$1, {
|
|
6877
|
+
"aria-labelledby": `${c.id}-label`,
|
|
6878
|
+
className: "date-range__dialog",
|
|
6879
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
6880
|
+
...props,
|
|
6881
|
+
children: children ?? c.panel
|
|
6882
|
+
})
|
|
6883
|
+
})
|
|
6884
|
+
});
|
|
6885
|
+
}
|
|
6886
|
+
function action(type) {
|
|
6887
|
+
return function PickerAction({ children, className, onClick, ...props }) {
|
|
6888
|
+
const c = usePicker();
|
|
6889
|
+
return /* @__PURE__ */ jsx("button", {
|
|
6890
|
+
type: "button",
|
|
6891
|
+
...props,
|
|
6892
|
+
className: partClass(`button button--${type === "apply" ? "primary" : "ghost"} button--sm`, className),
|
|
6893
|
+
disabled: props.disabled || type !== "cancel" && (c.options.isDisabled || c.options.isReadOnly) || type === "apply" && !!c.error,
|
|
6894
|
+
onClick: (e) => {
|
|
6895
|
+
onClick?.(e);
|
|
6896
|
+
if (!e.defaultPrevented) c[type]();
|
|
6897
|
+
},
|
|
6898
|
+
children: children ?? labels(c.options.locale)[type]
|
|
6899
|
+
});
|
|
6900
|
+
};
|
|
6901
|
+
}
|
|
6902
|
+
var TemporalPickerApplyButton = /* @__PURE__ */ action("apply");
|
|
6903
|
+
var TemporalPickerCancelButton = /* @__PURE__ */ action("cancel");
|
|
6904
|
+
var TemporalPickerClearButton = /* @__PURE__ */ action("clear");
|
|
6905
|
+
function Root({ kind, range, ...props }) {
|
|
6906
|
+
const [local, setLocal] = useState(props.defaultValue ?? null);
|
|
6907
|
+
const committed = props.value === void 0 ? local : props.value;
|
|
6908
|
+
const [draft, setDraft] = useState(committed), [inputErrors, setInputErrors] = useState({}), [formError, setFormError] = useState(false), [mobile, setMobile] = useState(false);
|
|
6909
|
+
const id = useId(), trigger = useRef(null);
|
|
6910
|
+
const disclosure = useDisclosure(props.open, props.defaultOpen, props.onOpenChange);
|
|
6911
|
+
const l = labels(props.locale);
|
|
6912
|
+
const committedKey = JSON.stringify(committed), lastCommitted = useRef(committedKey);
|
|
6913
|
+
useEffect(() => {
|
|
6914
|
+
if (lastCommitted.current === committedKey) return;
|
|
6915
|
+
lastCommitted.current = committedKey;
|
|
6916
|
+
setDraft(committed);
|
|
6917
|
+
setInputErrors({});
|
|
6918
|
+
}, [committed, committedKey]);
|
|
6919
|
+
useEffect(() => {
|
|
6920
|
+
const media = window.matchMedia("(max-width: 640px)");
|
|
6921
|
+
const update = () => setMobile(media.matches);
|
|
6922
|
+
update();
|
|
6923
|
+
media.addEventListener("change", update);
|
|
6924
|
+
return () => media.removeEventListener("change", update);
|
|
6925
|
+
}, []);
|
|
6926
|
+
const constraints = {
|
|
6927
|
+
...props,
|
|
6928
|
+
kind
|
|
6929
|
+
};
|
|
6930
|
+
const validate = (value) => range ? temporalRangeError(typeof value === "object" ? value : null, constraints) : temporalError(typeof value === "string" ? value : null, constraints);
|
|
6931
|
+
const code = Object.values(inputErrors).find(Boolean) ?? validate(draft);
|
|
6932
|
+
const error = code ? code in temporalMessages(props.locale) ? temporalMessages(props.locale)[code] : code : null;
|
|
6933
|
+
const committedError = validate(committed);
|
|
6934
|
+
const errorCallback = useRef(props.onError);
|
|
6935
|
+
useEffect(() => {
|
|
6936
|
+
errorCallback.current = props.onError;
|
|
6937
|
+
}, [props.onError]);
|
|
6938
|
+
useEffect(() => {
|
|
6939
|
+
errorCallback.current?.(error);
|
|
6940
|
+
}, [error]);
|
|
6941
|
+
function changeOpen(next) {
|
|
6942
|
+
if (props.isDisabled && next) return;
|
|
6943
|
+
setDraft(committed);
|
|
6944
|
+
setInputErrors({});
|
|
6945
|
+
disclosure.change(next);
|
|
6946
|
+
}
|
|
6947
|
+
function commit(value, close) {
|
|
6948
|
+
if (props.isDisabled || props.isReadOnly || validate(value)) return;
|
|
6949
|
+
setLocal(value);
|
|
6950
|
+
setFormError(false);
|
|
6951
|
+
props.onChange?.(value);
|
|
6952
|
+
if (close) {
|
|
6953
|
+
props.onApply?.(value);
|
|
6954
|
+
disclosure.change(false);
|
|
6955
|
+
}
|
|
6956
|
+
}
|
|
6957
|
+
function edit(value, part) {
|
|
6958
|
+
if (props.isDisabled || props.isReadOnly) return;
|
|
6959
|
+
setDraft(value);
|
|
6960
|
+
const remaining = part ? {
|
|
6961
|
+
...inputErrors,
|
|
6962
|
+
[part]: null
|
|
6963
|
+
} : {};
|
|
6964
|
+
setInputErrors(remaining);
|
|
6965
|
+
if (props.commitMode === "immediate" && !Object.values(remaining).some(Boolean)) commit(value, false);
|
|
6966
|
+
}
|
|
6967
|
+
function clear() {
|
|
6968
|
+
if (props.isDisabled || props.isReadOnly) return;
|
|
6969
|
+
setDraft(null);
|
|
6970
|
+
setInputErrors({});
|
|
6971
|
+
if (props.commitMode === "immediate") {
|
|
6972
|
+
setLocal(null);
|
|
6973
|
+
props.onChange?.(null);
|
|
6974
|
+
}
|
|
6975
|
+
}
|
|
6976
|
+
const context = {
|
|
6977
|
+
options: props,
|
|
6978
|
+
kind,
|
|
6979
|
+
range,
|
|
6980
|
+
draft,
|
|
6981
|
+
error,
|
|
6982
|
+
id,
|
|
6983
|
+
invalid: props.isInvalid || !!committedError || formError,
|
|
6984
|
+
describedBy: [props.description ? `${id}-description` : void 0, props.isInvalid || committedError || formError ? `${id}-error` : void 0].filter(Boolean).join(" ") || void 0,
|
|
6985
|
+
text: displayText(committed, kind, props),
|
|
6986
|
+
edit,
|
|
6987
|
+
inputError: (part, error) => setInputErrors((current) => current[part] === error ? current : {
|
|
6988
|
+
...current,
|
|
6989
|
+
[part]: error
|
|
6990
|
+
}),
|
|
6991
|
+
apply: () => {
|
|
6992
|
+
if (!error) commit(draft, true);
|
|
6993
|
+
},
|
|
6994
|
+
cancel: () => changeOpen(false),
|
|
6995
|
+
clear,
|
|
6996
|
+
panel: null
|
|
6997
|
+
};
|
|
6998
|
+
const current = kind === "date" ? today(props.timeZone ?? "UTC").toString() : kind === "time" ? now(props.timeZone ?? "UTC").toString().slice(11, props.granularity === "second" ? 19 : 16) : now(props.timeZone ?? "UTC").toString();
|
|
6999
|
+
const panel = /* @__PURE__ */ jsxs("div", {
|
|
7000
|
+
className: partClass("temporal-picker__content", props.classNames?.content),
|
|
7001
|
+
children: [
|
|
7002
|
+
/* @__PURE__ */ jsx("h2", {
|
|
7003
|
+
className: "temporal-picker__title",
|
|
7004
|
+
children: props.label
|
|
7005
|
+
}),
|
|
7006
|
+
!!props.presets?.length && /* @__PURE__ */ jsx("div", {
|
|
7007
|
+
className: "temporal-picker__presets",
|
|
7008
|
+
children: props.presets.map((p) => /* @__PURE__ */ jsx("button", {
|
|
7009
|
+
type: "button",
|
|
7010
|
+
className: partClass("date-range__preset", props.classNames?.preset),
|
|
7011
|
+
disabled: props.isDisabled || props.isReadOnly || !!validate(p.value),
|
|
7012
|
+
onClick: () => edit(p.value),
|
|
7013
|
+
children: p.label
|
|
7014
|
+
}, p.id))
|
|
7015
|
+
}),
|
|
7016
|
+
props.showInputs !== false && /* @__PURE__ */ jsxs("div", {
|
|
7017
|
+
className: "temporal-picker__fields",
|
|
7018
|
+
children: [/* @__PURE__ */ jsx(TemporalPickerField, {}), range && /* @__PURE__ */ jsx(TemporalPickerField, { part: "end" })]
|
|
7019
|
+
}),
|
|
7020
|
+
/* @__PURE__ */ jsxs("div", {
|
|
7021
|
+
className: "temporal-picker__views",
|
|
7022
|
+
children: [
|
|
7023
|
+
kind !== "time" && /* @__PURE__ */ jsx(TemporalPickerCalendar, { className: props.classNames?.calendar }),
|
|
7024
|
+
" ",
|
|
7025
|
+
kind !== "date" && /* @__PURE__ */ jsxs("div", {
|
|
7026
|
+
className: "temporal-picker__times",
|
|
7027
|
+
children: [/* @__PURE__ */ jsx(TemporalPickerTime, { className: props.classNames?.time }), range && /* @__PURE__ */ jsx(TemporalPickerTime, {
|
|
7028
|
+
part: "end",
|
|
7029
|
+
className: props.classNames?.time
|
|
7030
|
+
})]
|
|
7031
|
+
})
|
|
7032
|
+
]
|
|
7033
|
+
}),
|
|
7034
|
+
error && /* @__PURE__ */ jsx("span", {
|
|
7035
|
+
className: "input__error",
|
|
7036
|
+
role: "alert",
|
|
7037
|
+
children: error
|
|
7038
|
+
}),
|
|
7039
|
+
/* @__PURE__ */ jsx("button", {
|
|
7040
|
+
type: "button",
|
|
7041
|
+
className: "button button--ghost button--sm",
|
|
7042
|
+
disabled: props.isDisabled || props.isReadOnly || !!temporalError(current, constraints),
|
|
7043
|
+
onClick: () => edit(range ? {
|
|
7044
|
+
start: current,
|
|
7045
|
+
end: current
|
|
7046
|
+
} : current),
|
|
7047
|
+
children: kind === "date" ? l.today : l.now
|
|
7048
|
+
}),
|
|
7049
|
+
props.showActions !== false && /* @__PURE__ */ jsxs("footer", {
|
|
7050
|
+
className: partClass("date-range__footer", props.classNames?.footer),
|
|
7051
|
+
children: [/* @__PURE__ */ jsx(TemporalPickerClearButton, { className: props.classNames?.clearButton }), /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(TemporalPickerCancelButton, { className: props.classNames?.cancelButton }), props.commitMode !== "immediate" && /* @__PURE__ */ jsx(TemporalPickerApplyButton, { className: props.classNames?.applyButton })] })]
|
|
7052
|
+
})
|
|
7053
|
+
]
|
|
7054
|
+
});
|
|
7055
|
+
context.panel = panel;
|
|
7056
|
+
const dialog = props.display === "dialog" || props.display !== "inline" && props.display !== "popover" && mobile;
|
|
7057
|
+
return /* @__PURE__ */ jsx(PickerContext.Provider, {
|
|
7058
|
+
value: context,
|
|
7059
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
7060
|
+
className: partClass(partClass(`date-range temporal-picker date-range--${props.size ?? "md"}`, props.classNames?.root), props.className),
|
|
7061
|
+
style: props.style,
|
|
7062
|
+
dir: props.dir,
|
|
7063
|
+
children: [
|
|
7064
|
+
/* @__PURE__ */ jsx("span", {
|
|
7065
|
+
id: `${id}-label`,
|
|
7066
|
+
className: partClass(props.hideLabel ? "temporal__sr-only" : "date-range__label", props.classNames?.label),
|
|
7067
|
+
children: props.label
|
|
7068
|
+
}),
|
|
7069
|
+
props.display === "inline" ? /* @__PURE__ */ jsx("section", {
|
|
7070
|
+
className: partClass("date-range__panel date-range__inline", props.classNames?.panel),
|
|
7071
|
+
"aria-labelledby": `${id}-label`,
|
|
7072
|
+
children: props.children ?? panel
|
|
7073
|
+
}) : /* @__PURE__ */ jsx(DialogTrigger, {
|
|
7074
|
+
isOpen: disclosure.visible && !props.isDisabled,
|
|
7075
|
+
onOpenChange: changeOpen,
|
|
7076
|
+
children: props.children ?? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Button$1, {
|
|
7077
|
+
ref: trigger,
|
|
7078
|
+
className: partClass("date-range__trigger", props.classNames?.trigger),
|
|
7079
|
+
isDisabled: props.isDisabled,
|
|
7080
|
+
"aria-labelledby": `${id}-label ${id}-value`,
|
|
7081
|
+
"aria-invalid": context.invalid || void 0,
|
|
7082
|
+
"aria-describedby": context.describedBy,
|
|
7083
|
+
children: /* @__PURE__ */ jsx(TemporalPickerValue, { className: props.classNames?.value })
|
|
7084
|
+
}), dialog ? /* @__PURE__ */ jsx(ModalOverlay, {
|
|
7085
|
+
className: "temporal-picker__overlay",
|
|
7086
|
+
children: /* @__PURE__ */ jsx(Modal, {
|
|
7087
|
+
className: "date-range__panel temporal-picker__modal",
|
|
7088
|
+
children: /* @__PURE__ */ jsx(Dialog$1, {
|
|
7089
|
+
"aria-labelledby": `${id}-label`,
|
|
7090
|
+
children: panel
|
|
7091
|
+
})
|
|
7092
|
+
})
|
|
7093
|
+
}) : /* @__PURE__ */ jsx(TemporalPickerPopover, { className: props.classNames?.panel })] })
|
|
7094
|
+
}),
|
|
7095
|
+
props.description && /* @__PURE__ */ jsx("span", {
|
|
7096
|
+
id: `${id}-description`,
|
|
7097
|
+
className: partClass("input__description", props.classNames?.description),
|
|
7098
|
+
children: props.description
|
|
7099
|
+
}),
|
|
7100
|
+
(props.isInvalid || committedError || formError) && /* @__PURE__ */ jsx("span", {
|
|
7101
|
+
id: `${id}-error`,
|
|
7102
|
+
role: "alert",
|
|
7103
|
+
className: partClass("input__error", props.classNames?.error),
|
|
7104
|
+
children: props.errorMessage ?? temporalMessages(props.locale)[committedError ?? (props.isInvalid ? "invalid" : "required")]
|
|
7105
|
+
}),
|
|
7106
|
+
props.name && (range ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("input", {
|
|
7107
|
+
type: "hidden",
|
|
7108
|
+
name: `${props.name}.start`,
|
|
7109
|
+
value: typeof committed === "object" && committed ? committed.start : "",
|
|
7110
|
+
disabled: props.isDisabled
|
|
7111
|
+
}), /* @__PURE__ */ jsx("input", {
|
|
7112
|
+
type: "hidden",
|
|
7113
|
+
name: `${props.name}.end`,
|
|
7114
|
+
value: typeof committed === "object" && committed ? committed.end : "",
|
|
7115
|
+
disabled: props.isDisabled
|
|
7116
|
+
})] }) : /* @__PURE__ */ jsx("input", {
|
|
7117
|
+
type: "hidden",
|
|
7118
|
+
name: props.name,
|
|
7119
|
+
value: typeof committed === "string" ? committed : "",
|
|
7120
|
+
disabled: props.isDisabled
|
|
7121
|
+
})),
|
|
7122
|
+
/* @__PURE__ */ jsx(SelectionValidation, {
|
|
7123
|
+
hasValue: !!committed && !committedError,
|
|
7124
|
+
required: props.isRequired || !!committedError,
|
|
7125
|
+
disabled: props.isDisabled,
|
|
7126
|
+
onInvalid: () => {
|
|
7127
|
+
setFormError(true);
|
|
7128
|
+
trigger.current?.focus();
|
|
7129
|
+
},
|
|
7130
|
+
onResetStart: () => {},
|
|
7131
|
+
onReset: (cancelled) => {
|
|
7132
|
+
if (!cancelled) {
|
|
7133
|
+
if (props.value === void 0) setLocal(props.defaultValue ?? null);
|
|
7134
|
+
setDraft(props.value === void 0 ? props.defaultValue ?? null : committed);
|
|
7135
|
+
setInputErrors({});
|
|
7136
|
+
setFormError(false);
|
|
7137
|
+
disclosure.change(false);
|
|
7138
|
+
}
|
|
7139
|
+
}
|
|
7140
|
+
})
|
|
7141
|
+
]
|
|
7142
|
+
})
|
|
7143
|
+
});
|
|
7144
|
+
}
|
|
7145
|
+
function picker(kind, range) {
|
|
7146
|
+
const Component = (props) => /* @__PURE__ */ jsx(Root, {
|
|
7147
|
+
...props,
|
|
7148
|
+
kind,
|
|
7149
|
+
range
|
|
7150
|
+
});
|
|
7151
|
+
return Object.assign(Component, {
|
|
7152
|
+
Root: Component,
|
|
7153
|
+
Trigger: TemporalPickerTrigger,
|
|
7154
|
+
Value: TemporalPickerValue,
|
|
7155
|
+
Popover: TemporalPickerPopover,
|
|
7156
|
+
Content: TemporalPickerContent,
|
|
7157
|
+
Field: TemporalPickerField,
|
|
7158
|
+
Calendar: TemporalPickerCalendar,
|
|
7159
|
+
Time: TemporalPickerTime,
|
|
7160
|
+
MonthPicker,
|
|
7161
|
+
YearPicker,
|
|
7162
|
+
ApplyButton: TemporalPickerApplyButton,
|
|
7163
|
+
CancelButton: TemporalPickerCancelButton,
|
|
7164
|
+
ClearButton: TemporalPickerClearButton
|
|
7165
|
+
});
|
|
7166
|
+
}
|
|
7167
|
+
var DatePicker = /* @__PURE__ */ picker("date", false);
|
|
7168
|
+
var TimePicker = /* @__PURE__ */ picker("time", false);
|
|
7169
|
+
var TimeRangePicker = /* @__PURE__ */ picker("time", true);
|
|
7170
|
+
var DateTimePicker = /* @__PURE__ */ picker("datetime", false);
|
|
7171
|
+
var DateTimeRangePicker = /* @__PURE__ */ picker("datetime", true);
|
|
7172
|
+
//#endregion
|
|
7173
|
+
export { Alert, AlertActions, AlertContent, AlertDescription, AlertIndicator, AlertTitle, Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarGroupRoot, AvatarImage, AvatarRoot, Badge, Breadcrumb, BreadcrumbCurrent, BreadcrumbItemPart, BreadcrumbLink, BreadcrumbList, BreadcrumbRoot, BreadcrumbSeparator, Button, ButtonGroup, ButtonGroupSeparator, Calendar, Card, CardActions, CardContent, CardDescription, CardFooter, CardHeader, CardHeading, CardRoot, CardTitle, CardTitleRow, Chart, ChartDescription, ChartPlot, ChartRoot, ChartTitle, Checkbox, Combobox, DataTable, DataTableColumn as DataTableColumnPart, DataTableEmpty, DataTableError, DataTableRoot, DataTableSortButton, DataTableStatus, DateField, DatePicker, DateRangeField, DateRangePicker, DateTimeField, DateTimePicker, DateTimeRangeField, DateTimeRangePicker, Description, Dialog, DialogBackdrop as DialogBackdropPart, DialogCloseButton, DialogContent, DialogPanel, DialogRoot, DialogTriggerPart, DropdownHeading, DropdownItem, DropdownItemIndicator, DropdownList, DropdownMenu, DropdownPopover, DropdownRoot, DropdownSection, DropdownSeparator, DropdownSubmenuIndicator, DropdownSubmenuTrigger, DropdownTrigger, Empty, EmptyActions, EmptyDescription, EmptyRoot, EmptyTitle, Field, FieldError, Form, Header, Input, InputClearButton, Label, ListBox, Listbox, MonthPicker, MonthYearNavigation, NumberField, OverlayBody, OverlayDescription, OverlayFooter, OverlayHeader, OverlayHeading, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationNext, PaginationPageButton, PaginationPrevious, PaginationRoot, PaginationSummary, Popover, PopoverCloseButton, PopoverContent, PopoverDialog, PopoverTrigger, RadioGroup, RangeCalendar, Select, SelectGroup, Separator, Sidebar, SidebarHeader, SidebarItem, SidebarLink, SidebarList, SidebarNavigation, SidebarRoot, SidebarTitle, SidebarToggle, Skeleton, Spinner, Switch, SwitchGroup, Table, TableBody, TableCaption, TableCell, TableColumn, TableFooter, TableHeader, TableRoot, TableRow, TableScrollContainer, Tabs, TabsIndicator, TabsList, TabsListContainer, TabsPanel, TabsRoot, TabsSeparator, TabsTab, Textarea, TimeClock, TimeField, TimeList, TimePicker, TimeRangeField, TimeRangePicker, Toast, ToastActionButton, ToastActions, ToastBody, ToastCloseButton, ToastDescription, ToastIndicator, ToastProgress, ToastProvider, ToastRoot, ToastTitle, ToggleButton, ToggleButtonGroup, ToggleGroup, Tooltip, TooltipContent, TooltipRoot, TooltipTriggerPart, YearPicker, createDateRangePresets, createToastManager, rangeText as formatDateRange, useToast };
|
|
5276
7174
|
|
|
5277
7175
|
//# sourceMappingURL=index.js.map
|