@kazee-ds/react 0.6.0 → 0.7.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 +2072 -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 +28 -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,65 @@ 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, 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
|
+
disabled: isDisabled,
|
|
1758
|
+
onClick: () => onPress?.()
|
|
1759
|
+
};
|
|
1760
|
+
return /* @__PURE__ */ jsx("button", { ...props });
|
|
1761
|
+
}
|
|
1762
|
+
function CompactCard({ title, description, headingLevel = 3, actions, header, titleExtras, footer, children, className, classNames, density, href, target, rel, onPress, isDisabled, actionLabel, actionLabelledBy, actionClassName, renderLink, headerAlign, dividedHeader, flushFooter, ...props }) {
|
|
1566
1763
|
const Heading = `h${headingLevel}`;
|
|
1567
1764
|
return /* @__PURE__ */ jsxs("div", {
|
|
1568
1765
|
...props,
|
|
1766
|
+
"data-density": density,
|
|
1767
|
+
"data-interactive": !!(href || onPress) || void 0,
|
|
1768
|
+
"data-disabled": isDisabled || void 0,
|
|
1569
1769
|
className: partClass(partClass("card", classNames?.root), className),
|
|
1570
1770
|
children: [
|
|
1771
|
+
/* @__PURE__ */ jsx(CardAction, {
|
|
1772
|
+
href,
|
|
1773
|
+
target,
|
|
1774
|
+
rel,
|
|
1775
|
+
onPress,
|
|
1776
|
+
isDisabled,
|
|
1777
|
+
renderLink,
|
|
1778
|
+
actionClassName: partClass(classNames?.action ?? "", actionClassName),
|
|
1779
|
+
actionLabelledBy: actionLabelledBy ?? props["aria-labelledby"],
|
|
1780
|
+
actionLabel: actionLabel ?? title ?? props["aria-label"]
|
|
1781
|
+
}),
|
|
1571
1782
|
(title || description || actions || header || titleExtras) && /* @__PURE__ */ jsxs("div", {
|
|
1783
|
+
"data-align": headerAlign,
|
|
1784
|
+
"data-divided": dividedHeader || void 0,
|
|
1572
1785
|
className: partClass("card__header", classNames?.header),
|
|
1573
1786
|
children: [(title || description || header || titleExtras) && /* @__PURE__ */ jsx("div", {
|
|
1574
1787
|
className: partClass("card__heading", classNames?.heading),
|
|
@@ -1595,21 +1808,43 @@ function CompactCard({ title, description, headingLevel = 3, actions, header, ti
|
|
|
1595
1808
|
children
|
|
1596
1809
|
}),
|
|
1597
1810
|
footer && /* @__PURE__ */ jsx("div", {
|
|
1811
|
+
"data-flush": flushFooter || void 0,
|
|
1598
1812
|
className: partClass("card__footer", classNames?.footer),
|
|
1599
1813
|
children: footer
|
|
1600
1814
|
})
|
|
1601
1815
|
]
|
|
1602
1816
|
});
|
|
1603
1817
|
}
|
|
1604
|
-
function CardRoot({ className, ...props }) {
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1818
|
+
function CardRoot({ className, classNames, children, density, href, target, rel, onPress, isDisabled, actionLabel, actionLabelledBy, actionClassName, renderLink, ...props }) {
|
|
1819
|
+
const titleId = useId();
|
|
1820
|
+
const label = actionLabel ?? props["aria-label"];
|
|
1821
|
+
return /* @__PURE__ */ jsx(CardTitleIdContext.Provider, {
|
|
1822
|
+
value: titleId,
|
|
1823
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
1824
|
+
...props,
|
|
1825
|
+
"data-density": density,
|
|
1826
|
+
"data-interactive": !!(href || onPress) || void 0,
|
|
1827
|
+
"data-disabled": isDisabled || void 0,
|
|
1828
|
+
className: partClass(partClass("card", classNames?.root), className),
|
|
1829
|
+
children: [/* @__PURE__ */ jsx(CardAction, {
|
|
1830
|
+
href,
|
|
1831
|
+
target,
|
|
1832
|
+
rel,
|
|
1833
|
+
onPress,
|
|
1834
|
+
isDisabled,
|
|
1835
|
+
renderLink,
|
|
1836
|
+
actionClassName: partClass(classNames?.action ?? "", actionClassName),
|
|
1837
|
+
actionLabel: label,
|
|
1838
|
+
actionLabelledBy: actionLabelledBy ?? props["aria-labelledby"] ?? (label ? void 0 : titleId)
|
|
1839
|
+
}), children]
|
|
1840
|
+
})
|
|
1608
1841
|
});
|
|
1609
1842
|
}
|
|
1610
|
-
function CardHeader({ className, ...props }) {
|
|
1843
|
+
function CardHeader({ className, align, divided, ...props }) {
|
|
1611
1844
|
return /* @__PURE__ */ jsx("div", {
|
|
1612
1845
|
...props,
|
|
1846
|
+
"data-align": align,
|
|
1847
|
+
"data-divided": divided || void 0,
|
|
1613
1848
|
className: partClass("card__header", className)
|
|
1614
1849
|
});
|
|
1615
1850
|
}
|
|
@@ -1626,8 +1861,10 @@ function CardTitleRow({ className, ...props }) {
|
|
|
1626
1861
|
});
|
|
1627
1862
|
}
|
|
1628
1863
|
function CardTitle({ className, headingLevel = 3, ...props }) {
|
|
1864
|
+
const titleId = useContext(CardTitleIdContext);
|
|
1629
1865
|
const Heading = `h${headingLevel}`;
|
|
1630
1866
|
return /* @__PURE__ */ jsx(Heading, {
|
|
1867
|
+
id: titleId,
|
|
1631
1868
|
...props,
|
|
1632
1869
|
className: partClass("card__title", className)
|
|
1633
1870
|
});
|
|
@@ -1650,9 +1887,10 @@ function CardContent({ className, ...props }) {
|
|
|
1650
1887
|
className: partClass("card__content", className)
|
|
1651
1888
|
});
|
|
1652
1889
|
}
|
|
1653
|
-
function CardFooter({ className, ...props }) {
|
|
1890
|
+
function CardFooter({ className, flush, ...props }) {
|
|
1654
1891
|
return /* @__PURE__ */ jsx("div", {
|
|
1655
1892
|
...props,
|
|
1893
|
+
"data-flush": flush || void 0,
|
|
1656
1894
|
className: partClass("card__footer", className)
|
|
1657
1895
|
});
|
|
1658
1896
|
}
|
|
@@ -1668,15 +1906,261 @@ var Card = /* @__PURE__ */ Object.assign(CompactCard, {
|
|
|
1668
1906
|
Footer: CardFooter
|
|
1669
1907
|
});
|
|
1670
1908
|
//#endregion
|
|
1909
|
+
//#region src/visual-slot.tsx
|
|
1910
|
+
/** Decorate one child while preserving its handlers and ref. */
|
|
1911
|
+
function visualSlot(children, props) {
|
|
1912
|
+
const child = Children.only(children);
|
|
1913
|
+
const merged = {
|
|
1914
|
+
...child.props,
|
|
1915
|
+
...props
|
|
1916
|
+
};
|
|
1917
|
+
merged.className = [props.className, child.props.className].filter(Boolean).join(" ");
|
|
1918
|
+
merged.style = {
|
|
1919
|
+
...props.style,
|
|
1920
|
+
...child.props.style
|
|
1921
|
+
};
|
|
1922
|
+
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) => {
|
|
1923
|
+
child.props[key](...args);
|
|
1924
|
+
props[key](...args);
|
|
1925
|
+
};
|
|
1926
|
+
if (child.props.ref && props.ref) merged.ref = (node) => {
|
|
1927
|
+
const cleanups = [];
|
|
1928
|
+
for (const ref of [child.props.ref, props.ref]) if (typeof ref === "function") {
|
|
1929
|
+
const cleanup = ref(node);
|
|
1930
|
+
cleanups.push(typeof cleanup === "function" ? cleanup : () => {
|
|
1931
|
+
ref(null);
|
|
1932
|
+
});
|
|
1933
|
+
} else if (ref) {
|
|
1934
|
+
ref.current = node;
|
|
1935
|
+
cleanups.push(() => {
|
|
1936
|
+
ref.current = null;
|
|
1937
|
+
});
|
|
1938
|
+
}
|
|
1939
|
+
return () => {
|
|
1940
|
+
for (const cleanup of cleanups) cleanup();
|
|
1941
|
+
};
|
|
1942
|
+
};
|
|
1943
|
+
return cloneElement(child, merged);
|
|
1944
|
+
}
|
|
1945
|
+
//#endregion
|
|
1671
1946
|
//#region src/Badge.tsx
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1947
|
+
var AnchorContext = createContext(false);
|
|
1948
|
+
/** Static status text; wrap in Badge.Anchor to position it relative to another element. */
|
|
1949
|
+
function BadgeRoot({ tone = "neutral", size = "md", variant = "default", placement = "top-right", asChild, children, className, classNames, ...props }) {
|
|
1950
|
+
const anchored = useContext(AnchorContext);
|
|
1951
|
+
const attributes = {
|
|
1675
1952
|
...props,
|
|
1676
1953
|
className: partClass(partClass("badge", classNames?.root), className),
|
|
1954
|
+
"data-tone": tone,
|
|
1955
|
+
"data-size": size,
|
|
1956
|
+
"data-variant": variant,
|
|
1957
|
+
"data-placement": anchored ? placement : void 0,
|
|
1958
|
+
"data-anchored": anchored || void 0,
|
|
1959
|
+
"data-dot": anchored && children == null || void 0
|
|
1960
|
+
};
|
|
1961
|
+
return asChild ? visualSlot(children, attributes) : /* @__PURE__ */ jsx("span", {
|
|
1962
|
+
...attributes,
|
|
1963
|
+
children: classNames?.label ? /* @__PURE__ */ jsx("span", {
|
|
1964
|
+
className: partClass("badge__label", classNames.label),
|
|
1965
|
+
children
|
|
1966
|
+
}) : children
|
|
1967
|
+
});
|
|
1968
|
+
}
|
|
1969
|
+
function BadgeAnchor({ className, ...props }) {
|
|
1970
|
+
return /* @__PURE__ */ jsx(AnchorContext.Provider, {
|
|
1971
|
+
value: true,
|
|
1972
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
1973
|
+
...props,
|
|
1974
|
+
className: partClass("badge-anchor badge__anchor", className)
|
|
1975
|
+
})
|
|
1976
|
+
});
|
|
1977
|
+
}
|
|
1978
|
+
function BadgeLabel({ className, ...props }) {
|
|
1979
|
+
return /* @__PURE__ */ jsx("span", {
|
|
1980
|
+
...props,
|
|
1981
|
+
className: partClass("badge__label", className)
|
|
1982
|
+
});
|
|
1983
|
+
}
|
|
1984
|
+
var Badge = /* @__PURE__ */ Object.assign(BadgeRoot, {
|
|
1985
|
+
Root: BadgeRoot,
|
|
1986
|
+
Anchor: BadgeAnchor,
|
|
1987
|
+
Label: BadgeLabel
|
|
1988
|
+
});
|
|
1989
|
+
//#endregion
|
|
1990
|
+
//#region src/Avatar.tsx
|
|
1991
|
+
var AvatarGroupContext = createContext({});
|
|
1992
|
+
var AvatarContext = createContext(null);
|
|
1993
|
+
function AvatarRoot({ size, tone, variant, radius = "full", asChild, children, className, classNames, ...props }) {
|
|
1994
|
+
const group = useContext(AvatarGroupContext);
|
|
1995
|
+
const [status, setStatus] = useState("idle");
|
|
1996
|
+
const actualSize = size ?? group.size ?? "md";
|
|
1997
|
+
const attributes = {
|
|
1998
|
+
...props,
|
|
1999
|
+
className: partClass(partClass("avatar", classNames?.root), className),
|
|
2000
|
+
"data-size": actualSize,
|
|
2001
|
+
"data-tone": tone ?? group.tone ?? "neutral",
|
|
2002
|
+
"data-variant": variant ?? group.variant ?? "default",
|
|
2003
|
+
"data-radius": radius,
|
|
2004
|
+
"data-image-status": status
|
|
2005
|
+
};
|
|
2006
|
+
return /* @__PURE__ */ jsx(AvatarContext.Provider, {
|
|
2007
|
+
value: {
|
|
2008
|
+
status,
|
|
2009
|
+
setStatus,
|
|
2010
|
+
size: actualSize,
|
|
2011
|
+
classNames
|
|
2012
|
+
},
|
|
2013
|
+
children: asChild ? visualSlot(children, attributes) : /* @__PURE__ */ jsx("span", {
|
|
2014
|
+
...attributes,
|
|
2015
|
+
children
|
|
2016
|
+
})
|
|
2017
|
+
});
|
|
2018
|
+
}
|
|
2019
|
+
function AvatarImage(props) {
|
|
2020
|
+
return /* @__PURE__ */ jsx(AvatarImageLoader, { ...props }, `${props.src ?? ""}|${props.srcSet ?? ""}|${props.sizes ?? ""}`);
|
|
2021
|
+
}
|
|
2022
|
+
function AvatarImageLoader({ src, srcSet, sizes, alt, asChild, children, className, onLoad, onError, onLoadingStatusChange, ref, ...props }) {
|
|
2023
|
+
const context = useContext(AvatarContext);
|
|
2024
|
+
const setStatus = context?.setStatus;
|
|
2025
|
+
const imageRef = useRef(null);
|
|
2026
|
+
const [result, setResult] = useState({
|
|
2027
|
+
source: "",
|
|
2028
|
+
status: "idle"
|
|
2029
|
+
});
|
|
2030
|
+
const source = `${src ?? ""}|${srcSet ?? ""}|${sizes ?? ""}`;
|
|
2031
|
+
const status = result.source === source ? result.status : src || srcSet ? "loading" : "error";
|
|
2032
|
+
const statusCallback = useRef(onLoadingStatusChange);
|
|
2033
|
+
useEffect(() => {
|
|
2034
|
+
statusCallback.current = onLoadingStatusChange;
|
|
2035
|
+
});
|
|
2036
|
+
useEffect(() => {
|
|
2037
|
+
setStatus?.(status);
|
|
2038
|
+
statusCallback.current?.(status);
|
|
2039
|
+
}, [status, setStatus]);
|
|
2040
|
+
useEffect(() => () => setStatus?.("idle"), [setStatus]);
|
|
2041
|
+
useEffect(() => {
|
|
2042
|
+
if (imageRef.current?.complete && imageRef.current.naturalWidth > 0) setResult({
|
|
2043
|
+
source,
|
|
2044
|
+
status: "loaded"
|
|
2045
|
+
});
|
|
2046
|
+
}, [source]);
|
|
2047
|
+
const attributes = {
|
|
2048
|
+
...props,
|
|
2049
|
+
src,
|
|
2050
|
+
srcSet,
|
|
2051
|
+
sizes,
|
|
2052
|
+
className: partClass(partClass("avatar__image", context?.classNames?.image), className),
|
|
2053
|
+
"data-status": status,
|
|
2054
|
+
"aria-hidden": status !== "loaded" || void 0,
|
|
2055
|
+
ref: (node) => {
|
|
2056
|
+
imageRef.current = node;
|
|
2057
|
+
if (typeof ref === "function") return ref(node);
|
|
2058
|
+
else if (ref) ref.current = node;
|
|
2059
|
+
},
|
|
2060
|
+
onLoad: (event) => {
|
|
2061
|
+
if (event.currentTarget !== imageRef.current) return;
|
|
2062
|
+
setResult({
|
|
2063
|
+
source,
|
|
2064
|
+
status: "loaded"
|
|
2065
|
+
});
|
|
2066
|
+
onLoad?.(event);
|
|
2067
|
+
},
|
|
2068
|
+
onError: (event) => {
|
|
2069
|
+
if (event.currentTarget !== imageRef.current) return;
|
|
2070
|
+
setResult({
|
|
2071
|
+
source,
|
|
2072
|
+
status: "error"
|
|
2073
|
+
});
|
|
2074
|
+
onError?.(event);
|
|
2075
|
+
}
|
|
2076
|
+
};
|
|
2077
|
+
return asChild ? visualSlot(children, {
|
|
2078
|
+
...attributes,
|
|
2079
|
+
...alt !== void 0 ? { alt } : {}
|
|
2080
|
+
}) : /* @__PURE__ */ jsx("img", {
|
|
2081
|
+
...attributes,
|
|
2082
|
+
alt: alt ?? ""
|
|
2083
|
+
}, source);
|
|
2084
|
+
}
|
|
2085
|
+
function AvatarFallback({ delayMs = 0, tone, className, ...props }) {
|
|
2086
|
+
const context = useContext(AvatarContext);
|
|
2087
|
+
const [ready, setReady] = useState(delayMs <= 0);
|
|
2088
|
+
useEffect(() => {
|
|
2089
|
+
setReady(delayMs <= 0);
|
|
2090
|
+
if (delayMs <= 0) return;
|
|
2091
|
+
const timer = setTimeout(() => setReady(true), delayMs);
|
|
2092
|
+
return () => clearTimeout(timer);
|
|
2093
|
+
}, [delayMs, context?.status]);
|
|
2094
|
+
if (context?.status === "loaded" || !ready) return null;
|
|
2095
|
+
return /* @__PURE__ */ jsx("span", {
|
|
2096
|
+
...props,
|
|
2097
|
+
className: partClass(partClass("avatar__fallback", context?.classNames?.fallback), className),
|
|
1677
2098
|
"data-tone": tone
|
|
1678
2099
|
});
|
|
1679
2100
|
}
|
|
2101
|
+
function AvatarBadge({ size, tone = "primary", placement = "bottom-right", className, children, ...props }) {
|
|
2102
|
+
const context = useContext(AvatarContext);
|
|
2103
|
+
return /* @__PURE__ */ jsx("span", {
|
|
2104
|
+
...props,
|
|
2105
|
+
className: partClass(partClass("avatar__badge", context?.classNames?.badge), className),
|
|
2106
|
+
"data-size": size ?? context?.size ?? "md",
|
|
2107
|
+
"data-tone": tone,
|
|
2108
|
+
"data-placement": placement,
|
|
2109
|
+
"data-dot": children == null || void 0,
|
|
2110
|
+
children
|
|
2111
|
+
});
|
|
2112
|
+
}
|
|
2113
|
+
var Avatar = /* @__PURE__ */ Object.assign(AvatarRoot, {
|
|
2114
|
+
Root: AvatarRoot,
|
|
2115
|
+
Image: AvatarImage,
|
|
2116
|
+
Fallback: AvatarFallback,
|
|
2117
|
+
Badge: AvatarBadge
|
|
2118
|
+
});
|
|
2119
|
+
//#endregion
|
|
2120
|
+
//#region src/AvatarGroup.tsx
|
|
2121
|
+
function flatten(children, prefix = "") {
|
|
2122
|
+
return Children.toArray(children).flatMap((child, index) => {
|
|
2123
|
+
const key = `${prefix}/${isValidElement(child) ? child.key ?? index : index}`;
|
|
2124
|
+
return isValidElement(child) && child.type === Fragment ? flatten(child.props.children, key) : isValidElement(child) ? [cloneElement(child, { key })] : [];
|
|
2125
|
+
});
|
|
2126
|
+
}
|
|
2127
|
+
function AvatarGroupCount({ className, ...props }) {
|
|
2128
|
+
return /* @__PURE__ */ jsx(Avatar, {
|
|
2129
|
+
...props,
|
|
2130
|
+
className: partClass("avatar-group__count", className),
|
|
2131
|
+
children: /* @__PURE__ */ jsx(Avatar.Fallback, { children: props.children })
|
|
2132
|
+
});
|
|
2133
|
+
}
|
|
2134
|
+
function AvatarGroupRoot({ size = "md", tone = "neutral", variant = "default", max, isGrid = false, overlap = "clip", className, classNames, children, ...props }) {
|
|
2135
|
+
const items = flatten(children);
|
|
2136
|
+
const counts = items.filter((item) => isValidElement(item) && item.type === AvatarGroupCount);
|
|
2137
|
+
const avatars = items.filter((item) => !counts.includes(item));
|
|
2138
|
+
const limit = max === void 0 || !Number.isFinite(max) ? avatars.length : Math.max(0, Math.floor(max));
|
|
2139
|
+
const hidden = Math.max(0, avatars.length - limit);
|
|
2140
|
+
return /* @__PURE__ */ jsx(AvatarGroupContext.Provider, {
|
|
2141
|
+
value: {
|
|
2142
|
+
size,
|
|
2143
|
+
tone,
|
|
2144
|
+
variant
|
|
2145
|
+
},
|
|
2146
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
2147
|
+
...props,
|
|
2148
|
+
className: partClass(partClass("avatar-group", classNames?.root), className),
|
|
2149
|
+
"data-size": size,
|
|
2150
|
+
"data-grid": isGrid || void 0,
|
|
2151
|
+
"data-overlap": overlap,
|
|
2152
|
+
children: [avatars.slice(0, limit), counts.length ? counts : hidden > 0 ? /* @__PURE__ */ jsxs(AvatarGroupCount, {
|
|
2153
|
+
className: classNames?.count,
|
|
2154
|
+
"aria-label": `${hidden} more`,
|
|
2155
|
+
children: ["+", hidden]
|
|
2156
|
+
}) : null]
|
|
2157
|
+
})
|
|
2158
|
+
});
|
|
2159
|
+
}
|
|
2160
|
+
var AvatarGroup = /* @__PURE__ */ Object.assign(AvatarGroupRoot, {
|
|
2161
|
+
Root: AvatarGroupRoot,
|
|
2162
|
+
Count: AvatarGroupCount
|
|
2163
|
+
});
|
|
1680
2164
|
//#endregion
|
|
1681
2165
|
//#region src/Skeleton.tsx
|
|
1682
2166
|
/** Decorative placeholder. Set aria-busy and loading text on the surrounding content. */
|
|
@@ -1800,7 +2284,7 @@ function mountTabsIndicator(container) {
|
|
|
1800
2284
|
}
|
|
1801
2285
|
//#endregion
|
|
1802
2286
|
//#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 }) {
|
|
2287
|
+
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
2288
|
const container = useRef(null);
|
|
1805
2289
|
const hasToolbar = !!(extras || actions);
|
|
1806
2290
|
useEffect(() => container.current ? mountTabsIndicator(container.current) : void 0, [items.length, hasToolbar]);
|
|
@@ -1861,6 +2345,7 @@ function CompactTabs({ className, style, classNames, label, variant = "primary",
|
|
|
1861
2345
|
]
|
|
1862
2346
|
}) : null;
|
|
1863
2347
|
const content = /* @__PURE__ */ jsxs(Tabs$1, {
|
|
2348
|
+
"data-indicator-shadow": indicatorShadow,
|
|
1864
2349
|
className: [
|
|
1865
2350
|
"tabs",
|
|
1866
2351
|
classNames?.root,
|
|
@@ -1908,9 +2393,10 @@ function CompactTabs({ className, style, classNames, label, variant = "primary",
|
|
|
1908
2393
|
children: content
|
|
1909
2394
|
}) : content;
|
|
1910
2395
|
}
|
|
1911
|
-
function TabsRoot({ className, classNames, value, defaultValue, onChange, variant = "primary", size = "md", align = "center", fullWidth, ...props }) {
|
|
2396
|
+
function TabsRoot({ className, classNames, value, defaultValue, onChange, variant = "primary", size = "md", align = "center", fullWidth, indicatorShadow = true, ...props }) {
|
|
1912
2397
|
return /* @__PURE__ */ jsx(Tabs$1, {
|
|
1913
2398
|
...props,
|
|
2399
|
+
"data-indicator-shadow": indicatorShadow,
|
|
1914
2400
|
selectedKey: value,
|
|
1915
2401
|
defaultSelectedKey: defaultValue,
|
|
1916
2402
|
onSelectionChange: onChange ? (key) => onChange(String(key)) : void 0,
|
|
@@ -3259,7 +3745,7 @@ function CompactDropdownMenu(props) {
|
|
|
3259
3745
|
onOpenChange: change,
|
|
3260
3746
|
children: [/* @__PURE__ */ jsx(Button$1, {
|
|
3261
3747
|
style,
|
|
3262
|
-
className: partClass(partClass(partClass(`button button--${props.triggerVariant ?? "secondary"}${props.triggerIconOnly ? " button--icon-only" : ""}`, classNames?.trigger), classNames?.root), className),
|
|
3748
|
+
className: partClass(partClass(partClass(`button button--${props.triggerVariant ?? "secondary"} button--${props.triggerSize ?? "md"}${props.triggerIconOnly ? " button--icon-only" : ""}`, classNames?.trigger), classNames?.root), className),
|
|
3263
3749
|
"aria-label": triggerLabel,
|
|
3264
3750
|
isDisabled: isDisabled || !items.length,
|
|
3265
3751
|
children: props.triggerContent ?? triggerLabel
|
|
@@ -3861,38 +4347,355 @@ function DateRangeCancelButton({ className, onClick, children, ...props }) {
|
|
|
3861
4347
|
});
|
|
3862
4348
|
}
|
|
3863
4349
|
//#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
|
-
|
|
4350
|
+
//#region src/Calendar.tsx
|
|
4351
|
+
function date(value) {
|
|
4352
|
+
try {
|
|
4353
|
+
return value ? parseDate(value) : void 0;
|
|
4354
|
+
} catch {
|
|
4355
|
+
return;
|
|
4356
|
+
}
|
|
4357
|
+
}
|
|
4358
|
+
function monthName(year, month, locale) {
|
|
4359
|
+
return new Intl.DateTimeFormat(locale, {
|
|
4360
|
+
month: "long",
|
|
4361
|
+
timeZone: "UTC",
|
|
4362
|
+
calendar: "gregory"
|
|
4363
|
+
}).format(new CalendarDate(year, month, 1).toDate("UTC"));
|
|
4364
|
+
}
|
|
4365
|
+
function MonthPicker({ value, year = today("UTC").year, onChange, locale = "id-ID", minDate, maxDate, isDisabled, className, ...props }) {
|
|
4366
|
+
return /* @__PURE__ */ jsx("div", {
|
|
4367
|
+
...props,
|
|
4368
|
+
className: partClass("calendar__choices", className),
|
|
4369
|
+
role: "group",
|
|
4370
|
+
"aria-label": locale.startsWith("id") ? "Pilih bulan" : "Choose month",
|
|
4371
|
+
children: Array.from({ length: 12 }, (_, i) => i + 1).map((month) => {
|
|
4372
|
+
const start = new CalendarDate(year, month, 1);
|
|
4373
|
+
const end = start.add({ months: 1 }).subtract({ days: 1 });
|
|
4374
|
+
return /* @__PURE__ */ jsx("button", {
|
|
4375
|
+
type: "button",
|
|
4376
|
+
disabled: isDisabled || !!(date(minDate) && end.compare(date(minDate)) < 0) || !!(date(maxDate) && start.compare(date(maxDate)) > 0),
|
|
4377
|
+
"aria-pressed": value === month,
|
|
4378
|
+
onClick: () => onChange?.(month),
|
|
4379
|
+
children: monthName(year, month, locale)
|
|
4380
|
+
}, month);
|
|
4381
|
+
})
|
|
4382
|
+
});
|
|
4383
|
+
}
|
|
4384
|
+
function YearPicker({ value = today("UTC").year, onChange, locale = "id-ID", minDate, maxDate, isDisabled, className, ...props }) {
|
|
4385
|
+
const min = date(minDate)?.year ?? 1, max = date(maxDate)?.year ?? 9999;
|
|
4386
|
+
const [page, setPage] = useState(Math.max(min, Math.min(max, Math.floor((value - 1) / 12) * 12 + 1)));
|
|
4387
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
4388
|
+
...props,
|
|
4389
|
+
className: partClass("calendar__years", className),
|
|
4390
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
4391
|
+
className: "calendar__year-navigation",
|
|
4392
|
+
children: [
|
|
4393
|
+
/* @__PURE__ */ jsx("button", {
|
|
4394
|
+
type: "button",
|
|
4395
|
+
"aria-label": locale.startsWith("id") ? "Tahun sebelumnya" : "Previous years",
|
|
4396
|
+
disabled: isDisabled || page <= min,
|
|
4397
|
+
onClick: () => setPage(Math.max(min, page - 12)),
|
|
4398
|
+
children: "‹"
|
|
4399
|
+
}),
|
|
4400
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
4401
|
+
page,
|
|
4402
|
+
"–",
|
|
4403
|
+
Math.min(page + 11, max)
|
|
4404
|
+
] }),
|
|
4405
|
+
/* @__PURE__ */ jsx("button", {
|
|
4406
|
+
type: "button",
|
|
4407
|
+
"aria-label": locale.startsWith("id") ? "Tahun berikutnya" : "Next years",
|
|
4408
|
+
disabled: isDisabled || page + 11 >= max,
|
|
4409
|
+
onClick: () => setPage(Math.max(min, Math.min(max - 11, page + 12))),
|
|
4410
|
+
children: "›"
|
|
4411
|
+
})
|
|
4412
|
+
]
|
|
4413
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
4414
|
+
className: "calendar__choices",
|
|
4415
|
+
role: "group",
|
|
4416
|
+
"aria-label": locale.startsWith("id") ? "Pilih tahun" : "Choose year",
|
|
4417
|
+
children: Array.from({ length: 12 }, (_, i) => page + i).filter((year) => year <= 9999).map((year) => /* @__PURE__ */ jsx("button", {
|
|
4418
|
+
type: "button",
|
|
4419
|
+
disabled: isDisabled || year < min || year > max,
|
|
4420
|
+
"aria-pressed": value === year,
|
|
4421
|
+
onClick: () => onChange?.(year),
|
|
4422
|
+
children: year
|
|
4423
|
+
}, year))
|
|
4424
|
+
})]
|
|
4425
|
+
});
|
|
4426
|
+
}
|
|
4427
|
+
function MonthYearNavigation({ value, onChange, locale = "id-ID", minDate, maxDate, isDisabled, className, ...props }) {
|
|
4428
|
+
const current = date(value) ?? today("UTC");
|
|
4429
|
+
const [view, setView] = useState(null);
|
|
4430
|
+
const header = useRef(null), lastToggle = useRef("month"), previousView = useRef(null);
|
|
4431
|
+
useEffect(() => {
|
|
4432
|
+
if (view) (header.current?.querySelector(".calendar__view [aria-pressed=\"true\"]:not(:disabled)") ?? header.current?.querySelector(".calendar__view button:not(:disabled)"))?.focus();
|
|
4433
|
+
else if (previousView.current) header.current?.querySelectorAll(".date-range__heading > button")[lastToggle.current === "month" ? 0 : 1]?.focus();
|
|
4434
|
+
previousView.current = view;
|
|
4435
|
+
}, [view]);
|
|
4436
|
+
useEffect(() => {
|
|
4437
|
+
if (!view) return;
|
|
4438
|
+
const grid = header.current?.closest(".date-range__month")?.querySelector(".date-range__grid");
|
|
4439
|
+
if (!grid) return;
|
|
4440
|
+
const inert = grid.hasAttribute("inert"), hidden = grid.getAttribute("aria-hidden");
|
|
4441
|
+
grid.inert = true;
|
|
4442
|
+
grid.setAttribute("inert", "");
|
|
4443
|
+
grid.setAttribute("aria-hidden", "true");
|
|
4444
|
+
return () => {
|
|
4445
|
+
grid.inert = inert;
|
|
4446
|
+
if (!inert) grid.removeAttribute("inert");
|
|
4447
|
+
if (hidden === null) grid.removeAttribute("aria-hidden");
|
|
4448
|
+
else grid.setAttribute("aria-hidden", hidden);
|
|
4449
|
+
};
|
|
4450
|
+
}, [view]);
|
|
4451
|
+
const navigate = (year, month) => {
|
|
4452
|
+
let next = new CalendarDate(year, month, 1);
|
|
4453
|
+
const min = date(minDate), max = date(maxDate);
|
|
4454
|
+
if (min && next.compare(min) < 0) next = min;
|
|
4455
|
+
if (max && next.compare(max) > 0) next = max;
|
|
4456
|
+
onChange(next.toString());
|
|
4457
|
+
};
|
|
4458
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
4459
|
+
...props,
|
|
4460
|
+
ref: header,
|
|
4461
|
+
className: partClass("calendar__header", className),
|
|
4462
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
4463
|
+
className: "date-range__heading",
|
|
4464
|
+
children: [/* @__PURE__ */ jsx("button", {
|
|
4465
|
+
type: "button",
|
|
4466
|
+
disabled: isDisabled,
|
|
4467
|
+
"aria-expanded": view === "month",
|
|
4468
|
+
onClick: () => {
|
|
4469
|
+
lastToggle.current = "month";
|
|
4470
|
+
setView(view === "month" ? null : "month");
|
|
4471
|
+
},
|
|
4472
|
+
children: monthName(current.year, current.month, locale)
|
|
4473
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
4474
|
+
type: "button",
|
|
4475
|
+
disabled: isDisabled,
|
|
4476
|
+
"aria-expanded": view === "year",
|
|
4477
|
+
onClick: () => {
|
|
4478
|
+
lastToggle.current = "year";
|
|
4479
|
+
setView(view === "year" ? null : "year");
|
|
4480
|
+
},
|
|
4481
|
+
children: current.year
|
|
4482
|
+
})]
|
|
4483
|
+
}), view && /* @__PURE__ */ jsxs("div", {
|
|
4484
|
+
className: "calendar__view",
|
|
4485
|
+
role: "group",
|
|
4486
|
+
"aria-label": view === "year" ? locale.startsWith("id") ? "Pilih tahun" : "Choose year" : locale.startsWith("id") ? "Pilih bulan" : "Choose month",
|
|
4487
|
+
onKeyDownCapture: (e) => {
|
|
4488
|
+
if (e.key === "Escape") {
|
|
4489
|
+
e.stopPropagation();
|
|
4490
|
+
setView(null);
|
|
4491
|
+
}
|
|
4492
|
+
},
|
|
4493
|
+
children: [view === "month" ? /* @__PURE__ */ jsx(MonthPicker, {
|
|
4494
|
+
value: current.month,
|
|
4495
|
+
year: current.year,
|
|
4496
|
+
locale,
|
|
4497
|
+
minDate,
|
|
4498
|
+
maxDate,
|
|
4499
|
+
isDisabled,
|
|
4500
|
+
onChange: (month) => {
|
|
4501
|
+
navigate(current.year, month);
|
|
4502
|
+
setView(null);
|
|
4503
|
+
}
|
|
4504
|
+
}) : /* @__PURE__ */ jsx(YearPicker, {
|
|
4505
|
+
value: current.year,
|
|
4506
|
+
locale,
|
|
4507
|
+
minDate,
|
|
4508
|
+
maxDate,
|
|
4509
|
+
isDisabled,
|
|
4510
|
+
onChange: (year) => {
|
|
4511
|
+
navigate(year, current.month);
|
|
4512
|
+
setView("month");
|
|
4513
|
+
}
|
|
4514
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
4515
|
+
type: "button",
|
|
4516
|
+
className: "calendar__back",
|
|
4517
|
+
onClick: () => setView(null),
|
|
4518
|
+
children: locale.startsWith("id") ? "Kembali" : "Back"
|
|
4519
|
+
})]
|
|
4520
|
+
})]
|
|
4521
|
+
});
|
|
4522
|
+
}
|
|
4523
|
+
/** Reads actual visibleRange rather than assuming the focused day is the first panel. */
|
|
4524
|
+
function CalendarViewHeader({ offset = 0, onNavigate, ...props }) {
|
|
4525
|
+
const single = useContext(CalendarStateContext);
|
|
4526
|
+
const visible = (useContext(RangeCalendarStateContext) ?? single)?.visibleRange.start ?? today("UTC");
|
|
4527
|
+
return /* @__PURE__ */ jsx(MonthYearNavigation, {
|
|
4528
|
+
...props,
|
|
4529
|
+
value: visible.add({ months: offset }).toString(),
|
|
4530
|
+
onChange: (value) => onNavigate(parseDate(value).subtract({ months: offset }))
|
|
4531
|
+
});
|
|
4532
|
+
}
|
|
4533
|
+
function CalendarBody({ props, onNavigate }) {
|
|
4534
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("div", {
|
|
4535
|
+
className: "date-range__navigation",
|
|
4536
|
+
children: [/* @__PURE__ */ jsx(Button$1, {
|
|
4537
|
+
slot: "previous",
|
|
4538
|
+
className: "date-range__nav",
|
|
4539
|
+
"aria-label": props.locale?.startsWith("id") ? "Bulan sebelumnya" : "Previous month",
|
|
4540
|
+
children: "‹"
|
|
4541
|
+
}), /* @__PURE__ */ jsx(Button$1, {
|
|
4542
|
+
slot: "next",
|
|
4543
|
+
className: "date-range__nav",
|
|
4544
|
+
"aria-label": props.locale?.startsWith("id") ? "Bulan berikutnya" : "Next month",
|
|
4545
|
+
children: "›"
|
|
4546
|
+
})]
|
|
4547
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
4548
|
+
className: "date-range__months",
|
|
4549
|
+
children: Array.from({ length: props.visibleMonths ?? 1 }, (_, i) => /* @__PURE__ */ jsxs("div", {
|
|
4550
|
+
className: partClass("date-range__month", props.classNames?.month),
|
|
4551
|
+
children: [/* @__PURE__ */ jsx(CalendarViewHeader, {
|
|
4552
|
+
offset: i,
|
|
4553
|
+
onNavigate,
|
|
4554
|
+
locale: props.locale,
|
|
4555
|
+
minDate: props.minDate,
|
|
4556
|
+
maxDate: props.maxDate,
|
|
4557
|
+
isDisabled: props.isDisabled,
|
|
4558
|
+
className: props.classNames?.header
|
|
4559
|
+
}), /* @__PURE__ */ jsxs(CalendarGrid$1, {
|
|
4560
|
+
offset: { months: i },
|
|
4561
|
+
className: partClass("date-range__grid", props.classNames?.grid),
|
|
4562
|
+
weekdayStyle: "short",
|
|
4563
|
+
children: [/* @__PURE__ */ jsx(CalendarGridHeader$1, { children: (day) => /* @__PURE__ */ jsx(CalendarHeaderCell$1, {
|
|
4564
|
+
className: "date-range__weekday",
|
|
4565
|
+
children: day
|
|
4566
|
+
}) }), /* @__PURE__ */ jsx(CalendarGridBody$1, { children: (day) => /* @__PURE__ */ jsx(CalendarCell$1, {
|
|
4567
|
+
date: day,
|
|
4568
|
+
className: partClass("date-range__day", props.classNames?.day)
|
|
4569
|
+
}) })]
|
|
4570
|
+
})]
|
|
4571
|
+
}, i))
|
|
4572
|
+
})] });
|
|
4573
|
+
}
|
|
4574
|
+
function Calendar(props) {
|
|
4575
|
+
const [local, setLocal] = useState(props.defaultValue ?? null);
|
|
4576
|
+
const value = props.value === void 0 ? local : props.value;
|
|
4577
|
+
useEffect(() => {
|
|
4578
|
+
const next = date(value);
|
|
4579
|
+
if (next) setFocused(next);
|
|
4580
|
+
}, [value]);
|
|
4581
|
+
const [focused, setFocused] = useState(() => date(value) ?? date(props.referenceDate) ?? date(props.minDate) ?? today("UTC"));
|
|
4582
|
+
return /* @__PURE__ */ jsx(I18nProvider, {
|
|
4583
|
+
locale: props.locale ?? "id-ID",
|
|
4584
|
+
children: /* @__PURE__ */ jsx(Calendar$1, {
|
|
4585
|
+
className: partClass(partClass("date-range__calendar calendar", props.classNames?.root), props.className),
|
|
4586
|
+
style: props.style,
|
|
4587
|
+
"aria-label": props.label ?? "Calendar",
|
|
4588
|
+
dir: props.dir,
|
|
4589
|
+
value: date(value) ?? null,
|
|
4590
|
+
focusedValue: focused,
|
|
4591
|
+
onFocusChange: setFocused,
|
|
4592
|
+
createCalendar: () => new GregorianCalendar(),
|
|
4593
|
+
visibleDuration: { months: props.visibleMonths ?? 1 },
|
|
4594
|
+
pageBehavior: "single",
|
|
4595
|
+
firstDayOfWeek: props.weekStartsOn === 0 ? "sun" : "mon",
|
|
4596
|
+
minValue: date(props.minDate),
|
|
4597
|
+
maxValue: date(props.maxDate),
|
|
4598
|
+
isDisabled: props.isDisabled,
|
|
4599
|
+
isReadOnly: props.isReadOnly,
|
|
4600
|
+
isDateUnavailable: (v) => props.isDateUnavailable?.(v.toString()) ?? false,
|
|
4601
|
+
onChange: (v) => {
|
|
4602
|
+
const next = v?.toString() ?? null;
|
|
4603
|
+
setLocal(next);
|
|
4604
|
+
props.onChange?.(next);
|
|
4605
|
+
},
|
|
4606
|
+
children: /* @__PURE__ */ jsx(CalendarBody, {
|
|
4607
|
+
props,
|
|
4608
|
+
onNavigate: setFocused
|
|
4609
|
+
})
|
|
4610
|
+
})
|
|
4611
|
+
});
|
|
4612
|
+
}
|
|
4613
|
+
function RangeCalendar(props) {
|
|
4614
|
+
const [local, setLocal] = useState(props.defaultValue ?? null);
|
|
4615
|
+
const value = props.value === void 0 ? local : props.value;
|
|
4616
|
+
const selectedStart = value?.start;
|
|
4617
|
+
useEffect(() => {
|
|
4618
|
+
const next = date(selectedStart);
|
|
4619
|
+
if (next) setFocused(next);
|
|
4620
|
+
}, [selectedStart]);
|
|
4621
|
+
const [focused, setFocused] = useState(() => date(value?.start) ?? date(props.referenceDate) ?? date(props.minDate) ?? today("UTC"));
|
|
4622
|
+
const selected = date(value?.start) && date(value?.end) ? {
|
|
4623
|
+
start: date(value?.start),
|
|
4624
|
+
end: date(value?.end)
|
|
4625
|
+
} : null;
|
|
4626
|
+
return /* @__PURE__ */ jsx(I18nProvider, {
|
|
4627
|
+
locale: props.locale ?? "id-ID",
|
|
4628
|
+
children: /* @__PURE__ */ jsx(RangeCalendar$1, {
|
|
4629
|
+
className: partClass(partClass("date-range__calendar calendar", props.classNames?.root), props.className),
|
|
4630
|
+
style: props.style,
|
|
4631
|
+
"aria-label": props.label ?? "Calendar",
|
|
4632
|
+
dir: props.dir,
|
|
4633
|
+
value: selected,
|
|
4634
|
+
focusedValue: focused,
|
|
4635
|
+
onFocusChange: setFocused,
|
|
4636
|
+
createCalendar: () => new GregorianCalendar(),
|
|
4637
|
+
visibleDuration: { months: props.visibleMonths ?? 2 },
|
|
4638
|
+
pageBehavior: "single",
|
|
4639
|
+
firstDayOfWeek: props.weekStartsOn === 0 ? "sun" : "mon",
|
|
4640
|
+
minValue: date(props.minDate),
|
|
4641
|
+
maxValue: date(props.maxDate),
|
|
4642
|
+
isDisabled: props.isDisabled,
|
|
4643
|
+
isReadOnly: props.isReadOnly,
|
|
4644
|
+
isDateUnavailable: (v) => props.isDateUnavailable?.(v.toString()) ?? false,
|
|
4645
|
+
onChange: (v) => {
|
|
4646
|
+
const next = v ? {
|
|
4647
|
+
start: v.start.toString(),
|
|
4648
|
+
end: v.end.toString()
|
|
4649
|
+
} : null;
|
|
4650
|
+
setLocal(next);
|
|
4651
|
+
props.onChange?.(next);
|
|
4652
|
+
},
|
|
4653
|
+
children: /* @__PURE__ */ jsx(CalendarBody, {
|
|
4654
|
+
props: {
|
|
4655
|
+
...props,
|
|
4656
|
+
visibleMonths: props.visibleMonths ?? 2,
|
|
4657
|
+
value: null,
|
|
4658
|
+
defaultValue: null,
|
|
4659
|
+
onChange: void 0
|
|
4660
|
+
},
|
|
4661
|
+
onNavigate: setFocused
|
|
4662
|
+
})
|
|
4663
|
+
})
|
|
4664
|
+
});
|
|
4665
|
+
}
|
|
4666
|
+
//#endregion
|
|
4667
|
+
//#region src/date-range-model.ts
|
|
4668
|
+
function dateRangeLabels(locale = "id-ID") {
|
|
4669
|
+
return locale.startsWith("id") ? {
|
|
4670
|
+
title: "Pilih rentang tanggal",
|
|
4671
|
+
start: "Tanggal mulai",
|
|
4672
|
+
end: "Tanggal akhir",
|
|
4673
|
+
apply: "Terapkan",
|
|
4674
|
+
cancel: "Batal",
|
|
4675
|
+
clear: "Kosongkan",
|
|
4676
|
+
previousMonth: "Bulan sebelumnya",
|
|
4677
|
+
nextMonth: "Bulan berikutnya",
|
|
4678
|
+
presets: "Pilihan cepat",
|
|
4679
|
+
placeholder: "Pilih tanggal",
|
|
4680
|
+
incomplete: "Lengkapi tanggal mulai dan akhir.",
|
|
4681
|
+
order: "Tanggal akhir harus setelah atau sama dengan tanggal mulai.",
|
|
4682
|
+
bounds: "Tanggal berada di luar batas yang diizinkan.",
|
|
4683
|
+
unavailable: "Rentang memuat tanggal yang tidak tersedia.",
|
|
4684
|
+
length: "Durasi rentang tidak sesuai batas yang diizinkan.",
|
|
4685
|
+
required: "Rentang tanggal wajib diisi."
|
|
4686
|
+
} : {
|
|
4687
|
+
title: "Select date range",
|
|
4688
|
+
start: "Start date",
|
|
4689
|
+
end: "End date",
|
|
4690
|
+
apply: "Apply",
|
|
4691
|
+
cancel: "Cancel",
|
|
4692
|
+
clear: "Clear",
|
|
4693
|
+
previousMonth: "Previous month",
|
|
4694
|
+
nextMonth: "Next month",
|
|
4695
|
+
presets: "Quick selections",
|
|
4696
|
+
placeholder: "Choose dates",
|
|
4697
|
+
incomplete: "Enter both start and end dates.",
|
|
4698
|
+
order: "End date must be on or after start date.",
|
|
3896
4699
|
bounds: "Dates are outside the allowed limits.",
|
|
3897
4700
|
unavailable: "The range includes an unavailable date.",
|
|
3898
4701
|
length: "The range duration is outside the allowed limits.",
|
|
@@ -4011,7 +4814,7 @@ function CalendarContent({ onPending, dir, children }) {
|
|
|
4011
4814
|
});
|
|
4012
4815
|
}
|
|
4013
4816
|
function DateRangePickerRoot(props) {
|
|
4014
|
-
const { label, locale = "id-ID", dir, size = "md", variant = "primary", fullWidth = true, hideLabel = false, visibleMonths = 2, weekStartsOn = 1, display = "
|
|
4817
|
+
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
4818
|
const labels = {
|
|
4016
4819
|
...dateRangeLabels(locale),
|
|
4017
4820
|
...props.labels
|
|
@@ -4032,6 +4835,15 @@ function DateRangePickerRoot(props) {
|
|
|
4032
4835
|
const [formError, setFormError] = useState(false);
|
|
4033
4836
|
const [pending, setPending] = useState(false), [calendarKey, setCalendarKey] = useState(0);
|
|
4034
4837
|
const trigger = useRef(null);
|
|
4838
|
+
const [mobile, setMobile] = useState(false);
|
|
4839
|
+
useEffect(() => {
|
|
4840
|
+
const query = window.matchMedia("(max-width: 640px)");
|
|
4841
|
+
const change = () => setMobile(query.matches);
|
|
4842
|
+
change();
|
|
4843
|
+
query.addEventListener("change", change);
|
|
4844
|
+
return () => query.removeEventListener("change", change);
|
|
4845
|
+
}, []);
|
|
4846
|
+
const isDialog = display === "dialog" || display === "auto" && mobile;
|
|
4035
4847
|
const id = useId();
|
|
4036
4848
|
const disclosure = useDisclosure(props.open, props.defaultOpen, props.onOpenChange);
|
|
4037
4849
|
const visible = disclosure.visible && !isDisabled;
|
|
@@ -4044,6 +4856,23 @@ function DateRangePickerRoot(props) {
|
|
|
4044
4856
|
setPending(false);
|
|
4045
4857
|
setCalendarKey((k) => k + 1);
|
|
4046
4858
|
}
|
|
4859
|
+
function updateDraft(next) {
|
|
4860
|
+
if (isDisabled || isReadOnly) return;
|
|
4861
|
+
setDraft(next);
|
|
4862
|
+
const value = next.start || next.end ? next : null;
|
|
4863
|
+
if (props.commitMode === "immediate" && !rangeError(value, props)) {
|
|
4864
|
+
setLocal(value);
|
|
4865
|
+
setFormError(false);
|
|
4866
|
+
props.onChange?.(value);
|
|
4867
|
+
}
|
|
4868
|
+
}
|
|
4869
|
+
function clearDraft() {
|
|
4870
|
+
replaceDraft(empty());
|
|
4871
|
+
if (props.commitMode === "immediate" && !isDisabled && !isReadOnly) {
|
|
4872
|
+
setLocal(null);
|
|
4873
|
+
props.onChange?.(null);
|
|
4874
|
+
}
|
|
4875
|
+
}
|
|
4047
4876
|
function resetDraft() {
|
|
4048
4877
|
replaceDraft({
|
|
4049
4878
|
start,
|
|
@@ -4079,13 +4908,17 @@ function DateRangePickerRoot(props) {
|
|
|
4079
4908
|
...draft,
|
|
4080
4909
|
[part]: value
|
|
4081
4910
|
});
|
|
4911
|
+
updateDraft({
|
|
4912
|
+
...draft,
|
|
4913
|
+
[part]: value
|
|
4914
|
+
});
|
|
4082
4915
|
if (asDate(value)) setFocused(asDate(value));
|
|
4083
4916
|
}
|
|
4084
4917
|
const calendarValue = asDate(draft.start) && asDate(draft.end) && draft.start <= draft.end ? {
|
|
4085
4918
|
start: asDate(draft.start),
|
|
4086
4919
|
end: asDate(draft.end)
|
|
4087
4920
|
} : null;
|
|
4088
|
-
const calendar = /* @__PURE__ */ jsx(RangeCalendar, {
|
|
4921
|
+
const calendar = /* @__PURE__ */ jsx(RangeCalendar$1, {
|
|
4089
4922
|
dir,
|
|
4090
4923
|
className: partClass("date-range__calendar", props.classNames?.calendar),
|
|
4091
4924
|
"aria-label": labels.title,
|
|
@@ -4094,7 +4927,7 @@ function DateRangePickerRoot(props) {
|
|
|
4094
4927
|
onFocusChange: setFocused,
|
|
4095
4928
|
createCalendar: () => new GregorianCalendar(),
|
|
4096
4929
|
onChange: (v) => {
|
|
4097
|
-
if (v)
|
|
4930
|
+
if (v) updateDraft({
|
|
4098
4931
|
start: v.start.toString(),
|
|
4099
4932
|
end: v.end.toString()
|
|
4100
4933
|
});
|
|
@@ -4127,9 +4960,14 @@ function DateRangePickerRoot(props) {
|
|
|
4127
4960
|
className: partClass("date-range__months", props.classNames?.months),
|
|
4128
4961
|
children: Array.from({ length: visibleMonths }, (_, i) => /* @__PURE__ */ jsxs("div", {
|
|
4129
4962
|
className: partClass("date-range__month", props.classNames?.month),
|
|
4130
|
-
children: [/* @__PURE__ */ jsx(
|
|
4131
|
-
offset:
|
|
4132
|
-
|
|
4963
|
+
children: [/* @__PURE__ */ jsx(CalendarViewHeader, {
|
|
4964
|
+
offset: i,
|
|
4965
|
+
onNavigate: setFocused,
|
|
4966
|
+
locale,
|
|
4967
|
+
minDate: props.minDate,
|
|
4968
|
+
maxDate: props.maxDate,
|
|
4969
|
+
isDisabled,
|
|
4970
|
+
className: props.classNames?.heading
|
|
4133
4971
|
}), /* @__PURE__ */ jsxs(CalendarGrid, {
|
|
4134
4972
|
offset: { months: i },
|
|
4135
4973
|
className: partClass("date-range__grid", props.classNames?.grid),
|
|
@@ -4175,6 +5013,7 @@ function DateRangePickerRoot(props) {
|
|
|
4175
5013
|
"aria-pressed": !pending && draft.start === p.value.start && draft.end === p.value.end,
|
|
4176
5014
|
onClick: () => {
|
|
4177
5015
|
replaceDraft({ ...p.value });
|
|
5016
|
+
updateDraft({ ...p.value });
|
|
4178
5017
|
setFocused(asDate(p.value.start));
|
|
4179
5018
|
},
|
|
4180
5019
|
children: p.label
|
|
@@ -4253,26 +5092,46 @@ function DateRangePickerRoot(props) {
|
|
|
4253
5092
|
]
|
|
4254
5093
|
})]
|
|
4255
5094
|
}),
|
|
4256
|
-
/* @__PURE__ */ jsxs("footer", {
|
|
5095
|
+
props.showActions !== false && /* @__PURE__ */ jsxs("footer", {
|
|
4257
5096
|
className: partClass("date-range__footer", props.classNames?.footer),
|
|
4258
5097
|
children: [/* @__PURE__ */ jsx("button", {
|
|
4259
5098
|
type: "button",
|
|
4260
5099
|
className: partClass("button button--ghost button--sm", props.classNames?.clearButton),
|
|
4261
5100
|
disabled: isDisabled || isReadOnly,
|
|
4262
|
-
onClick:
|
|
5101
|
+
onClick: clearDraft,
|
|
4263
5102
|
children: labels.clear
|
|
4264
|
-
}), /* @__PURE__ */ jsxs("div", { children: [
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
|
|
5103
|
+
}), /* @__PURE__ */ jsxs("div", { children: [
|
|
5104
|
+
/* @__PURE__ */ jsx("button", {
|
|
5105
|
+
type: "button",
|
|
5106
|
+
className: "button button--ghost button--sm",
|
|
5107
|
+
disabled: isDisabled || isReadOnly || !!rangeError({
|
|
5108
|
+
start: currentDate(),
|
|
5109
|
+
end: currentDate()
|
|
5110
|
+
}, props),
|
|
5111
|
+
onClick: () => {
|
|
5112
|
+
const next = {
|
|
5113
|
+
start: currentDate(),
|
|
5114
|
+
end: currentDate()
|
|
5115
|
+
};
|
|
5116
|
+
replaceDraft(next);
|
|
5117
|
+
updateDraft(next);
|
|
5118
|
+
},
|
|
5119
|
+
children: locale.startsWith("id") ? "Hari ini" : "Today"
|
|
5120
|
+
}),
|
|
5121
|
+
/* @__PURE__ */ jsx("button", {
|
|
5122
|
+
type: "button",
|
|
5123
|
+
className: partClass("button button--secondary button--sm", props.classNames?.cancelButton),
|
|
5124
|
+
onClick: () => changeOpen(false),
|
|
5125
|
+
children: labels.cancel
|
|
5126
|
+
}),
|
|
5127
|
+
props.commitMode !== "immediate" && /* @__PURE__ */ jsx("button", {
|
|
5128
|
+
type: "button",
|
|
5129
|
+
className: partClass("button button--primary button--sm", props.classNames?.applyButton),
|
|
5130
|
+
disabled: isDisabled || isReadOnly || !!errorCode,
|
|
5131
|
+
onClick: apply,
|
|
5132
|
+
children: labels.apply
|
|
5133
|
+
})
|
|
5134
|
+
] })]
|
|
4276
5135
|
})
|
|
4277
5136
|
]
|
|
4278
5137
|
});
|
|
@@ -4299,7 +5158,7 @@ function DateRangePickerRoot(props) {
|
|
|
4299
5158
|
panel,
|
|
4300
5159
|
edit,
|
|
4301
5160
|
apply,
|
|
4302
|
-
clear:
|
|
5161
|
+
clear: clearDraft,
|
|
4303
5162
|
cancel: () => changeOpen(false)
|
|
4304
5163
|
},
|
|
4305
5164
|
children: /* @__PURE__ */ jsxs("div", {
|
|
@@ -4369,7 +5228,17 @@ function DateRangePickerRoot(props) {
|
|
|
4369
5228
|
}),
|
|
4370
5229
|
/* @__PURE__ */ jsx(ChevronIcon, { className: partClass("date-range__chevron", props.classNames?.chevron) })
|
|
4371
5230
|
]
|
|
4372
|
-
}), /* @__PURE__ */ jsx(
|
|
5231
|
+
}), isDialog ? /* @__PURE__ */ jsx(ModalOverlay, {
|
|
5232
|
+
className: "temporal-picker__overlay",
|
|
5233
|
+
children: /* @__PURE__ */ jsx(Modal, {
|
|
5234
|
+
className: "date-range__panel temporal-picker__modal",
|
|
5235
|
+
children: /* @__PURE__ */ jsx(Dialog$1, {
|
|
5236
|
+
"aria-labelledby": `${id}-title`,
|
|
5237
|
+
className: "date-range__dialog",
|
|
5238
|
+
children: panel
|
|
5239
|
+
})
|
|
5240
|
+
})
|
|
5241
|
+
}) : /* @__PURE__ */ jsx(Popover$2, {
|
|
4373
5242
|
className: partClass("date-range__panel", props.classNames?.panel),
|
|
4374
5243
|
placement: "bottom start",
|
|
4375
5244
|
offset: 8,
|
|
@@ -5272,6 +6141,1030 @@ function ToastRenderer({ composed = false, style, classNames, entry, indicator,
|
|
|
5272
6141
|
});
|
|
5273
6142
|
}
|
|
5274
6143
|
//#endregion
|
|
5275
|
-
|
|
6144
|
+
//#region src/temporal-model.ts
|
|
6145
|
+
/** Wall time is resolved explicitly; DST gaps/overlaps reject by default. */
|
|
6146
|
+
function toZonedValue(value, timeZone = "UTC", disambiguation = "reject") {
|
|
6147
|
+
return toZoned(parseDateTime(value), timeZone, disambiguation).toString();
|
|
6148
|
+
}
|
|
6149
|
+
function toLocalValue(value, timeZone = "UTC", seconds = false) {
|
|
6150
|
+
if (!value) return "";
|
|
6151
|
+
const zoned = value.includes("[") ? parseZonedDateTime(value) : parseAbsolute(value, timeZone);
|
|
6152
|
+
const display = parseAbsolute(zoned.toAbsoluteString(), timeZone);
|
|
6153
|
+
return toCalendarDateTime(display).toString().slice(0, seconds ? 19 : 16);
|
|
6154
|
+
}
|
|
6155
|
+
function orderedValue(value, kind) {
|
|
6156
|
+
if (kind === "datetime") return (value.includes("[") ? parseZonedDateTime(value) : parseAbsolute(value, "UTC")).toDate().getTime();
|
|
6157
|
+
if (kind === "time") {
|
|
6158
|
+
const t = parseTime(value);
|
|
6159
|
+
return t.hour * 3600 + t.minute * 60 + t.second;
|
|
6160
|
+
}
|
|
6161
|
+
return parseDate(value).toDate("UTC").getTime();
|
|
6162
|
+
}
|
|
6163
|
+
function step(value) {
|
|
6164
|
+
if (value !== void 0 && (!Number.isInteger(value) || value <= 0)) throw new RangeError("Time steps must be positive integers.");
|
|
6165
|
+
return value ?? 1;
|
|
6166
|
+
}
|
|
6167
|
+
function temporalError(value, options) {
|
|
6168
|
+
if (!value) return options.isRequired ? "required" : null;
|
|
6169
|
+
let date = "", time = "";
|
|
6170
|
+
try {
|
|
6171
|
+
if (options.kind === "date") {
|
|
6172
|
+
if (!/^(?!0000)\d{4}-\d{2}-\d{2}$/.test(value) || parseDate(value).toString() !== value) return "invalid";
|
|
6173
|
+
date = value;
|
|
6174
|
+
} else if (options.kind === "time") {
|
|
6175
|
+
if (!/^\d{2}:\d{2}(:\d{2})?$/.test(value)) return "invalid";
|
|
6176
|
+
parseTime(value);
|
|
6177
|
+
time = value;
|
|
6178
|
+
} else {
|
|
6179
|
+
orderedValue(value, "datetime");
|
|
6180
|
+
const local = toLocalValue(value, options.timeZone, true);
|
|
6181
|
+
date = local.slice(0, 10);
|
|
6182
|
+
time = local.slice(11);
|
|
6183
|
+
}
|
|
6184
|
+
if (date && (options.minDate && date < options.minDate || options.maxDate && date > options.maxDate)) return "bounds";
|
|
6185
|
+
if (time && (options.minTime && orderedValue(time, "time") < orderedValue(options.minTime, "time") || options.maxTime && orderedValue(time, "time") > orderedValue(options.maxTime, "time"))) return "bounds";
|
|
6186
|
+
if (options.kind === "datetime" && (options.minDateTime && orderedValue(value, "datetime") < orderedValue(options.minDateTime, "datetime") || options.maxDateTime && orderedValue(value, "datetime") > orderedValue(options.maxDateTime, "datetime"))) return "bounds";
|
|
6187
|
+
if (date && options.isDateUnavailable?.(date)) return "unavailable";
|
|
6188
|
+
if (time && options.isTimeUnavailable?.(time)) return "unavailable";
|
|
6189
|
+
if (time) {
|
|
6190
|
+
const t = parseTime(time);
|
|
6191
|
+
if (t.hour % step(options.hourStep) || t.minute % step(options.minuteStep) || t.second % step(options.secondStep)) return "step";
|
|
6192
|
+
}
|
|
6193
|
+
return null;
|
|
6194
|
+
} catch {
|
|
6195
|
+
return "invalid";
|
|
6196
|
+
}
|
|
6197
|
+
}
|
|
6198
|
+
function temporalRangeError(value, options) {
|
|
6199
|
+
if (!value || !value.start && !value.end) return options.isRequired ? "required" : null;
|
|
6200
|
+
if (!value.start || !value.end) return "incomplete";
|
|
6201
|
+
const error = temporalError(value.start, options) ?? temporalError(value.end, options);
|
|
6202
|
+
if (error) return error;
|
|
6203
|
+
if (orderedValue(value.start, options.kind) > orderedValue(value.end, options.kind)) return "order";
|
|
6204
|
+
if (options.kind !== "time" && options.isDateUnavailable) {
|
|
6205
|
+
const first = parseDate(options.kind === "date" ? value.start : toLocalValue(value.start, options.timeZone).slice(0, 10));
|
|
6206
|
+
const last = parseDate(options.kind === "date" ? value.end : toLocalValue(value.end, options.timeZone).slice(0, 10));
|
|
6207
|
+
for (let day = first.add({ days: 1 }); day.compare(last) < 0; day = day.add({ days: 1 })) if (options.isDateUnavailable(day.toString())) return "unavailable";
|
|
6208
|
+
}
|
|
6209
|
+
return null;
|
|
6210
|
+
}
|
|
6211
|
+
/** Project instant boundaries into the selected display zone for disabled calendar/time options. */
|
|
6212
|
+
function temporalDisplayBounds(options, selectedDate) {
|
|
6213
|
+
let minDate = options.minDate, maxDate = options.maxDate, minTime = options.minTime, maxTime = options.maxTime;
|
|
6214
|
+
if (options.kind === "datetime") try {
|
|
6215
|
+
const min = options.minDateTime ? toLocalValue(options.minDateTime, options.timeZone, true) : "", max = options.maxDateTime ? toLocalValue(options.maxDateTime, options.timeZone, true) : "";
|
|
6216
|
+
if (min) {
|
|
6217
|
+
const day = min.slice(0, 10);
|
|
6218
|
+
if (!minDate || day > minDate) minDate = day;
|
|
6219
|
+
if (selectedDate === day && (!minTime || orderedValue(min.slice(11), "time") > orderedValue(minTime, "time"))) minTime = min.slice(11);
|
|
6220
|
+
}
|
|
6221
|
+
if (max) {
|
|
6222
|
+
const day = max.slice(0, 10);
|
|
6223
|
+
if (!maxDate || day < maxDate) maxDate = day;
|
|
6224
|
+
if (selectedDate === day && (!maxTime || orderedValue(max.slice(11), "time") < orderedValue(maxTime, "time"))) maxTime = max.slice(11);
|
|
6225
|
+
}
|
|
6226
|
+
} catch {}
|
|
6227
|
+
return {
|
|
6228
|
+
minDate,
|
|
6229
|
+
maxDate,
|
|
6230
|
+
minTime,
|
|
6231
|
+
maxTime
|
|
6232
|
+
};
|
|
6233
|
+
}
|
|
6234
|
+
/** Minute-granularity list; seconds are edited with TimeField/TimeClock to avoid 86k DOM options. */
|
|
6235
|
+
function timeChoices(options) {
|
|
6236
|
+
const hours = step(options.hourStep), minutes = options.granularity === "hour" ? 60 : step(options.minuteStep ?? 30);
|
|
6237
|
+
const values = [];
|
|
6238
|
+
for (let hour = 0; hour < 24; hour += hours) for (let minute = 0; minute < 60; minute += minutes) {
|
|
6239
|
+
const value = `${String(hour).padStart(2, "0")}:${String(minute).padStart(2, "0")}`;
|
|
6240
|
+
if (!temporalError(value, options)) values.push(value);
|
|
6241
|
+
}
|
|
6242
|
+
return values;
|
|
6243
|
+
}
|
|
6244
|
+
/** User edits zero units hidden by the configured field granularity. */
|
|
6245
|
+
function normalizeTime(value, granularity = "minute") {
|
|
6246
|
+
const time = parseTime(value);
|
|
6247
|
+
return time.set({
|
|
6248
|
+
minute: granularity === "hour" ? 0 : time.minute,
|
|
6249
|
+
second: granularity === "second" ? time.second : 0,
|
|
6250
|
+
millisecond: 0
|
|
6251
|
+
}).toString().slice(0, granularity === "second" ? 8 : 5);
|
|
6252
|
+
}
|
|
6253
|
+
function normalizeWallDateTime(value, granularity = "minute") {
|
|
6254
|
+
const date = parseDateTime(value);
|
|
6255
|
+
return date.toString().slice(0, 10) + "T" + normalizeTime(date.toString().slice(11), granularity);
|
|
6256
|
+
}
|
|
6257
|
+
/** Keep the selected unit and choose the nearest complete valid time for the other units. */
|
|
6258
|
+
function resolveTimeUnit(value, part, selected, options) {
|
|
6259
|
+
let initial;
|
|
6260
|
+
try {
|
|
6261
|
+
initial = parseTime(value || options.minTime || "00:00");
|
|
6262
|
+
} catch {
|
|
6263
|
+
initial = parseTime("00:00");
|
|
6264
|
+
}
|
|
6265
|
+
const desired = initial.set({ [part]: selected });
|
|
6266
|
+
let best = null, distance = Infinity;
|
|
6267
|
+
const hours = step(options.hourStep), minutes = step(options.minuteStep), seconds = step(options.secondStep);
|
|
6268
|
+
for (let hour = 0; hour < 24; hour += hours) {
|
|
6269
|
+
if (part === "hour" && hour !== selected) continue;
|
|
6270
|
+
for (let minute = 0; minute < 60; minute += options.granularity === "hour" ? 60 : minutes) {
|
|
6271
|
+
if (part === "minute" && minute !== selected) continue;
|
|
6272
|
+
for (let second = 0; second < 60; second += options.granularity === "second" ? seconds : 60) {
|
|
6273
|
+
if (part === "second" && second !== selected) continue;
|
|
6274
|
+
const next = normalizeTime(`${String(hour).padStart(2, "0")}:${String(minute).padStart(2, "0")}:${String(second).padStart(2, "0")}`, options.granularity);
|
|
6275
|
+
if (temporalError(next, {
|
|
6276
|
+
...options,
|
|
6277
|
+
kind: "time"
|
|
6278
|
+
})) continue;
|
|
6279
|
+
const delta = Math.abs(orderedValue(next, "time") - (desired.hour * 3600 + desired.minute * 60 + desired.second));
|
|
6280
|
+
if (delta < distance) {
|
|
6281
|
+
best = next;
|
|
6282
|
+
distance = delta;
|
|
6283
|
+
}
|
|
6284
|
+
}
|
|
6285
|
+
}
|
|
6286
|
+
}
|
|
6287
|
+
return best;
|
|
6288
|
+
}
|
|
6289
|
+
function temporalMessages(locale = "id-ID") {
|
|
6290
|
+
return locale.startsWith("id") ? {
|
|
6291
|
+
invalid: "Nilai tanggal atau waktu tidak valid.",
|
|
6292
|
+
required: "Nilai wajib diisi.",
|
|
6293
|
+
incomplete: "Lengkapi nilai mulai dan akhir.",
|
|
6294
|
+
order: "Nilai akhir harus setelah atau sama dengan nilai mulai.",
|
|
6295
|
+
bounds: "Nilai berada di luar batas yang diizinkan.",
|
|
6296
|
+
unavailable: "Nilai tidak tersedia.",
|
|
6297
|
+
step: "Nilai tidak sesuai interval yang diizinkan."
|
|
6298
|
+
} : {
|
|
6299
|
+
invalid: "Invalid date or time.",
|
|
6300
|
+
required: "A value is required.",
|
|
6301
|
+
incomplete: "Enter both start and end values.",
|
|
6302
|
+
order: "End must be on or after start.",
|
|
6303
|
+
bounds: "Value is outside the allowed limits.",
|
|
6304
|
+
unavailable: "Value is unavailable.",
|
|
6305
|
+
step: "Value does not match the allowed interval."
|
|
6306
|
+
};
|
|
6307
|
+
}
|
|
6308
|
+
//#endregion
|
|
6309
|
+
//#region src/TemporalField.tsx
|
|
6310
|
+
function parsed(value, kind, zone) {
|
|
6311
|
+
try {
|
|
6312
|
+
return value ? kind === "time" ? parseTime(value) : kind === "date" ? parseDate(value) : parseDateTime(toLocalValue(value, zone, true)) : null;
|
|
6313
|
+
} catch {
|
|
6314
|
+
return null;
|
|
6315
|
+
}
|
|
6316
|
+
}
|
|
6317
|
+
function TemporalField({ kind, ...props }) {
|
|
6318
|
+
const [local, setLocal] = useState(props.defaultValue ?? null), [editError, setEditError] = useState(null);
|
|
6319
|
+
const value = props.value === void 0 ? local : props.value;
|
|
6320
|
+
const id = useId();
|
|
6321
|
+
const error = editError ?? temporalError(value, {
|
|
6322
|
+
...props,
|
|
6323
|
+
kind
|
|
6324
|
+
});
|
|
6325
|
+
useEffect(() => {
|
|
6326
|
+
setEditError(null);
|
|
6327
|
+
}, [value]);
|
|
6328
|
+
function change(v) {
|
|
6329
|
+
if (props.isDisabled || props.isReadOnly) return;
|
|
6330
|
+
let next;
|
|
6331
|
+
try {
|
|
6332
|
+
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;
|
|
6333
|
+
} catch {
|
|
6334
|
+
const message = temporalMessages(props.locale).invalid;
|
|
6335
|
+
setEditError(message);
|
|
6336
|
+
props.onError?.(message);
|
|
6337
|
+
return;
|
|
6338
|
+
}
|
|
6339
|
+
setEditError(null);
|
|
6340
|
+
setLocal(next);
|
|
6341
|
+
props.onChange?.(next);
|
|
6342
|
+
props.onError?.(temporalError(next, {
|
|
6343
|
+
...props,
|
|
6344
|
+
kind
|
|
6345
|
+
}));
|
|
6346
|
+
}
|
|
6347
|
+
const fieldContent = /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Label$3, {
|
|
6348
|
+
className: partClass(props.hideLabel ? "temporal__sr-only" : "input__label", props.classNames?.label),
|
|
6349
|
+
children: props.label
|
|
6350
|
+
}), /* @__PURE__ */ jsx(DateInput, {
|
|
6351
|
+
className: partClass("temporal-field__input input__control", props.classNames?.input),
|
|
6352
|
+
children: (segment) => /* @__PURE__ */ jsx(DateSegment, {
|
|
6353
|
+
segment,
|
|
6354
|
+
className: partClass("temporal-field__segment", props.classNames?.segment)
|
|
6355
|
+
})
|
|
6356
|
+
})] });
|
|
6357
|
+
const shared = {
|
|
6358
|
+
id: props.id ?? id,
|
|
6359
|
+
isDisabled: props.isDisabled,
|
|
6360
|
+
isReadOnly: props.isReadOnly,
|
|
6361
|
+
isRequired: props.isRequired,
|
|
6362
|
+
isInvalid: props.isInvalid || !!error,
|
|
6363
|
+
validationBehavior: "aria",
|
|
6364
|
+
"aria-describedby": [props.description ? `${id}-description` : void 0, props.isInvalid || error ? `${id}-error` : void 0].filter(Boolean).join(" ") || void 0
|
|
6365
|
+
};
|
|
6366
|
+
return /* @__PURE__ */ jsx(I18nProvider, {
|
|
6367
|
+
locale: props.locale ?? "id-ID",
|
|
6368
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
6369
|
+
className: partClass(partClass("input temporal-field", props.classNames?.root), props.className),
|
|
6370
|
+
style: props.style,
|
|
6371
|
+
dir: props.dir,
|
|
6372
|
+
children: [
|
|
6373
|
+
kind === "time" ? /* @__PURE__ */ jsx(TimeField$1, {
|
|
6374
|
+
...shared,
|
|
6375
|
+
value: parsed(value, kind, props.timeZone),
|
|
6376
|
+
onChange: change,
|
|
6377
|
+
granularity: props.granularity ?? "minute",
|
|
6378
|
+
hourCycle: props.hourCycle,
|
|
6379
|
+
children: fieldContent
|
|
6380
|
+
}) : /* @__PURE__ */ jsx(DateField$1, {
|
|
6381
|
+
...shared,
|
|
6382
|
+
value: parsed(value, kind, props.timeZone),
|
|
6383
|
+
onChange: change,
|
|
6384
|
+
granularity: kind === "date" ? "day" : props.granularity ?? "minute",
|
|
6385
|
+
hourCycle: props.hourCycle,
|
|
6386
|
+
children: fieldContent
|
|
6387
|
+
}),
|
|
6388
|
+
props.description && /* @__PURE__ */ jsx("span", {
|
|
6389
|
+
id: `${id}-description`,
|
|
6390
|
+
className: partClass("input__description", props.classNames?.description),
|
|
6391
|
+
children: props.description
|
|
6392
|
+
}),
|
|
6393
|
+
(props.isInvalid || error) && /* @__PURE__ */ jsx("span", {
|
|
6394
|
+
id: `${id}-error`,
|
|
6395
|
+
className: partClass("input__error", props.classNames?.error),
|
|
6396
|
+
role: "alert",
|
|
6397
|
+
children: props.errorMessage ?? (error && error in temporalMessages(props.locale) ? temporalMessages(props.locale)[error] : error ?? temporalMessages(props.locale).invalid)
|
|
6398
|
+
}),
|
|
6399
|
+
props.name && /* @__PURE__ */ jsx("input", {
|
|
6400
|
+
type: "hidden",
|
|
6401
|
+
name: props.name,
|
|
6402
|
+
value: value ?? "",
|
|
6403
|
+
disabled: props.isDisabled
|
|
6404
|
+
}),
|
|
6405
|
+
/* @__PURE__ */ jsx(SelectionValidation, {
|
|
6406
|
+
hasValue: !!value && !error,
|
|
6407
|
+
required: props.isRequired || !!error,
|
|
6408
|
+
disabled: props.isDisabled || props.formValidation === false,
|
|
6409
|
+
onInvalid: () => props.onError?.(error ?? "required"),
|
|
6410
|
+
onResetStart: () => {},
|
|
6411
|
+
onReset: (cancelled) => {
|
|
6412
|
+
if (!cancelled && props.value === void 0) {
|
|
6413
|
+
setLocal(props.defaultValue ?? null);
|
|
6414
|
+
setEditError(null);
|
|
6415
|
+
}
|
|
6416
|
+
}
|
|
6417
|
+
})
|
|
6418
|
+
]
|
|
6419
|
+
})
|
|
6420
|
+
});
|
|
6421
|
+
}
|
|
6422
|
+
function DateField(props) {
|
|
6423
|
+
return /* @__PURE__ */ jsx(TemporalField, {
|
|
6424
|
+
...props,
|
|
6425
|
+
kind: "date"
|
|
6426
|
+
});
|
|
6427
|
+
}
|
|
6428
|
+
function TimeField(props) {
|
|
6429
|
+
return /* @__PURE__ */ jsx(TemporalField, {
|
|
6430
|
+
...props,
|
|
6431
|
+
kind: "time"
|
|
6432
|
+
});
|
|
6433
|
+
}
|
|
6434
|
+
function DateTimeField(props) {
|
|
6435
|
+
return /* @__PURE__ */ jsx(TemporalField, {
|
|
6436
|
+
...props,
|
|
6437
|
+
kind: "datetime"
|
|
6438
|
+
});
|
|
6439
|
+
}
|
|
6440
|
+
function TemporalRangeField({ kind, ...props }) {
|
|
6441
|
+
const groupId = useId();
|
|
6442
|
+
const [local, setLocal] = useState(props.defaultValue ?? null);
|
|
6443
|
+
const value = props.value === void 0 ? local : props.value;
|
|
6444
|
+
const error = temporalRangeError(value, {
|
|
6445
|
+
...props,
|
|
6446
|
+
kind
|
|
6447
|
+
});
|
|
6448
|
+
const fields = /* @__PURE__ */ jsx("div", {
|
|
6449
|
+
className: "temporal-picker__fields",
|
|
6450
|
+
children: ["start", "end"].map((part) => /* @__PURE__ */ createElement(TemporalField, {
|
|
6451
|
+
...props,
|
|
6452
|
+
id: props.id ? `${props.id}-${part}` : void 0,
|
|
6453
|
+
className: void 0,
|
|
6454
|
+
style: void 0,
|
|
6455
|
+
classNames: {
|
|
6456
|
+
...props.classNames,
|
|
6457
|
+
root: void 0
|
|
6458
|
+
},
|
|
6459
|
+
kind,
|
|
6460
|
+
key: part,
|
|
6461
|
+
value: value?.[part] ?? null,
|
|
6462
|
+
defaultValue: void 0,
|
|
6463
|
+
formValidation: false,
|
|
6464
|
+
name: props.name ? `${props.name}.${part}` : void 0,
|
|
6465
|
+
label: `${props.label} ${part === "start" ? props.locale?.startsWith("id") ? "Mulai" : "Start" : props.locale?.startsWith("id") ? "Akhir" : "End"}`,
|
|
6466
|
+
onChange: (next) => {
|
|
6467
|
+
const result = {
|
|
6468
|
+
...value ?? {
|
|
6469
|
+
start: "",
|
|
6470
|
+
end: ""
|
|
6471
|
+
},
|
|
6472
|
+
[part]: next ?? ""
|
|
6473
|
+
};
|
|
6474
|
+
setLocal(result);
|
|
6475
|
+
props.onChange?.(result);
|
|
6476
|
+
}
|
|
6477
|
+
}))
|
|
6478
|
+
});
|
|
6479
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
6480
|
+
id: props.id ?? groupId,
|
|
6481
|
+
role: "group",
|
|
6482
|
+
"aria-label": props.label,
|
|
6483
|
+
"aria-describedby": error ? `${groupId}-error` : void 0,
|
|
6484
|
+
className: partClass(partClass("temporal-range-field", props.classNames?.root), props.className),
|
|
6485
|
+
style: props.style,
|
|
6486
|
+
children: [
|
|
6487
|
+
fields,
|
|
6488
|
+
error && /* @__PURE__ */ jsx("span", {
|
|
6489
|
+
id: `${groupId}-error`,
|
|
6490
|
+
role: "alert",
|
|
6491
|
+
className: "input__error",
|
|
6492
|
+
children: props.errorMessage ?? temporalMessages(props.locale)[error]
|
|
6493
|
+
}),
|
|
6494
|
+
/* @__PURE__ */ jsx(SelectionValidation, {
|
|
6495
|
+
hasValue: !!value && !error,
|
|
6496
|
+
required: props.isRequired || !!error,
|
|
6497
|
+
disabled: props.isDisabled || props.formValidation === false,
|
|
6498
|
+
onInvalid: () => props.onError?.(error ?? "required"),
|
|
6499
|
+
onResetStart: () => {},
|
|
6500
|
+
onReset: (cancelled) => {
|
|
6501
|
+
if (!cancelled && props.value === void 0) setLocal(props.defaultValue ?? null);
|
|
6502
|
+
}
|
|
6503
|
+
})
|
|
6504
|
+
]
|
|
6505
|
+
});
|
|
6506
|
+
}
|
|
6507
|
+
function DateRangeField(props) {
|
|
6508
|
+
return /* @__PURE__ */ jsx(TemporalRangeField, {
|
|
6509
|
+
...props,
|
|
6510
|
+
kind: "date"
|
|
6511
|
+
});
|
|
6512
|
+
}
|
|
6513
|
+
function TimeRangeField(props) {
|
|
6514
|
+
return /* @__PURE__ */ jsx(TemporalRangeField, {
|
|
6515
|
+
...props,
|
|
6516
|
+
kind: "time"
|
|
6517
|
+
});
|
|
6518
|
+
}
|
|
6519
|
+
function DateTimeRangeField(props) {
|
|
6520
|
+
return /* @__PURE__ */ jsx(TemporalRangeField, {
|
|
6521
|
+
...props,
|
|
6522
|
+
kind: "datetime"
|
|
6523
|
+
});
|
|
6524
|
+
}
|
|
6525
|
+
//#endregion
|
|
6526
|
+
//#region src/TimeControls.tsx
|
|
6527
|
+
function format(value, locale, hourCycle) {
|
|
6528
|
+
const time = parseTime(value);
|
|
6529
|
+
const date = new Date(Date.UTC(2e3, 0, 1, time.hour, time.minute, time.second));
|
|
6530
|
+
return new Intl.DateTimeFormat(locale, {
|
|
6531
|
+
hour: "2-digit",
|
|
6532
|
+
minute: "2-digit",
|
|
6533
|
+
hourCycle: hourCycle === 12 ? "h12" : "h23",
|
|
6534
|
+
timeZone: "UTC"
|
|
6535
|
+
}).format(date);
|
|
6536
|
+
}
|
|
6537
|
+
function TimeList({ value, defaultValue, onChange, label = "Time", locale = "id-ID", hourCycle, isDisabled, isReadOnly, className, minTime, maxTime, hourStep, minuteStep, secondStep, granularity, isTimeUnavailable, ...props }) {
|
|
6538
|
+
const [local, setLocal] = useState(defaultValue ?? "");
|
|
6539
|
+
const actual = value === void 0 ? local : value ?? "";
|
|
6540
|
+
const options = {
|
|
6541
|
+
kind: "time",
|
|
6542
|
+
minTime,
|
|
6543
|
+
maxTime,
|
|
6544
|
+
hourStep,
|
|
6545
|
+
minuteStep,
|
|
6546
|
+
secondStep,
|
|
6547
|
+
granularity,
|
|
6548
|
+
isTimeUnavailable
|
|
6549
|
+
};
|
|
6550
|
+
return /* @__PURE__ */ jsx("div", {
|
|
6551
|
+
...props,
|
|
6552
|
+
className: partClass("time-list", className),
|
|
6553
|
+
children: /* @__PURE__ */ jsxs("select", {
|
|
6554
|
+
"aria-label": label,
|
|
6555
|
+
size: 6,
|
|
6556
|
+
value: actual,
|
|
6557
|
+
disabled: isDisabled,
|
|
6558
|
+
"aria-readonly": isReadOnly || void 0,
|
|
6559
|
+
onChange: (event) => {
|
|
6560
|
+
if (isReadOnly) {
|
|
6561
|
+
event.currentTarget.value = actual;
|
|
6562
|
+
return;
|
|
6563
|
+
}
|
|
6564
|
+
setLocal(event.target.value);
|
|
6565
|
+
onChange?.(event.target.value);
|
|
6566
|
+
},
|
|
6567
|
+
children: [/* @__PURE__ */ jsx("option", {
|
|
6568
|
+
value: "",
|
|
6569
|
+
disabled: true,
|
|
6570
|
+
children: locale.startsWith("id") ? "Pilih waktu" : "Choose time"
|
|
6571
|
+
}), timeChoices(options).map((time) => /* @__PURE__ */ jsx("option", {
|
|
6572
|
+
value: time,
|
|
6573
|
+
children: format(time, locale, hourCycle)
|
|
6574
|
+
}, time))]
|
|
6575
|
+
})
|
|
6576
|
+
});
|
|
6577
|
+
}
|
|
6578
|
+
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 }) {
|
|
6579
|
+
const [local, setLocal] = useState(defaultValue ?? minTime ?? "00:00");
|
|
6580
|
+
const actual = value === void 0 ? local : value || minTime || "00:00";
|
|
6581
|
+
let time;
|
|
6582
|
+
try {
|
|
6583
|
+
time = parseTime(actual);
|
|
6584
|
+
} catch {
|
|
6585
|
+
time = parseTime("00:00");
|
|
6586
|
+
}
|
|
6587
|
+
const id = locale.startsWith("id");
|
|
6588
|
+
const parts = granularity === "hour" ? ["hour"] : granularity === "second" ? [
|
|
6589
|
+
"hour",
|
|
6590
|
+
"minute",
|
|
6591
|
+
"second"
|
|
6592
|
+
] : ["hour", "minute"];
|
|
6593
|
+
return /* @__PURE__ */ jsx("div", {
|
|
6594
|
+
...props,
|
|
6595
|
+
role: "group",
|
|
6596
|
+
"aria-label": label,
|
|
6597
|
+
className: partClass("time-clock", className),
|
|
6598
|
+
children: parts.map((part) => {
|
|
6599
|
+
const step = part === "hour" ? hourStep : part === "minute" ? minuteStep : secondStep;
|
|
6600
|
+
const count = part === "hour" ? 24 : 60;
|
|
6601
|
+
const values = Array.from({ length: Math.ceil(count / Math.max(1, step)) }, (_, i) => i * Math.max(1, step)).filter((n) => n < count);
|
|
6602
|
+
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", {
|
|
6603
|
+
value: time[part],
|
|
6604
|
+
disabled: isDisabled,
|
|
6605
|
+
"aria-readonly": isReadOnly || void 0,
|
|
6606
|
+
onChange: (event) => {
|
|
6607
|
+
if (isReadOnly) {
|
|
6608
|
+
event.currentTarget.value = String(time[part]);
|
|
6609
|
+
return;
|
|
6610
|
+
}
|
|
6611
|
+
const next = resolveTimeUnit(time.toString(), part, Number(event.target.value), {
|
|
6612
|
+
kind: "time",
|
|
6613
|
+
minTime,
|
|
6614
|
+
maxTime,
|
|
6615
|
+
hourStep,
|
|
6616
|
+
minuteStep,
|
|
6617
|
+
secondStep,
|
|
6618
|
+
granularity,
|
|
6619
|
+
isTimeUnavailable
|
|
6620
|
+
});
|
|
6621
|
+
if (!next) return;
|
|
6622
|
+
setLocal(next);
|
|
6623
|
+
onChange?.(next);
|
|
6624
|
+
},
|
|
6625
|
+
children: values.map((n) => /* @__PURE__ */ jsx("option", {
|
|
6626
|
+
value: n,
|
|
6627
|
+
children: part === "hour" && hourCycle === 12 ? `${n % 12 || 12} ${n < 12 ? "AM" : "PM"}` : String(n).padStart(2, "0")
|
|
6628
|
+
}, n))
|
|
6629
|
+
})] }, part);
|
|
6630
|
+
})
|
|
6631
|
+
});
|
|
6632
|
+
}
|
|
6633
|
+
//#endregion
|
|
6634
|
+
//#region src/TemporalPicker.tsx
|
|
6635
|
+
var PickerContext = createContext(null);
|
|
6636
|
+
function usePicker() {
|
|
6637
|
+
const context = useContext(PickerContext);
|
|
6638
|
+
if (!context) throw new Error("Picker parts must be inside their picker Root.");
|
|
6639
|
+
return context;
|
|
6640
|
+
}
|
|
6641
|
+
function labels(locale = "id-ID") {
|
|
6642
|
+
return locale.startsWith("id") ? {
|
|
6643
|
+
apply: "Terapkan",
|
|
6644
|
+
cancel: "Batal",
|
|
6645
|
+
clear: "Kosongkan",
|
|
6646
|
+
today: "Hari ini",
|
|
6647
|
+
now: "Sekarang",
|
|
6648
|
+
start: "Mulai",
|
|
6649
|
+
end: "Akhir",
|
|
6650
|
+
choose: "Pilih tanggal atau waktu"
|
|
6651
|
+
} : {
|
|
6652
|
+
apply: "Apply",
|
|
6653
|
+
cancel: "Cancel",
|
|
6654
|
+
clear: "Clear",
|
|
6655
|
+
today: "Today",
|
|
6656
|
+
now: "Now",
|
|
6657
|
+
start: "Start",
|
|
6658
|
+
end: "End",
|
|
6659
|
+
choose: "Choose date or time"
|
|
6660
|
+
};
|
|
6661
|
+
}
|
|
6662
|
+
function localValue(value, kind, options) {
|
|
6663
|
+
try {
|
|
6664
|
+
return kind === "datetime" ? toLocalValue(value, options.timeZone, options.granularity === "second") : value;
|
|
6665
|
+
} catch {
|
|
6666
|
+
return "";
|
|
6667
|
+
}
|
|
6668
|
+
}
|
|
6669
|
+
function datePart(value, kind, options) {
|
|
6670
|
+
return localValue(value, kind, options).slice(0, 10);
|
|
6671
|
+
}
|
|
6672
|
+
function combineDate(date, time, options) {
|
|
6673
|
+
try {
|
|
6674
|
+
return toZonedValue(`${date}T${time || "00:00"}`, options.timeZone, options.disambiguation);
|
|
6675
|
+
} catch {
|
|
6676
|
+
return "";
|
|
6677
|
+
}
|
|
6678
|
+
}
|
|
6679
|
+
function displayText(value, kind, options) {
|
|
6680
|
+
if (!value) return labels(options.locale).choose;
|
|
6681
|
+
if (options.formatValue) return options.formatValue(value, options.locale ?? "id-ID");
|
|
6682
|
+
const one = (v) => {
|
|
6683
|
+
if (!v) return "—";
|
|
6684
|
+
try {
|
|
6685
|
+
if (kind === "time") return new Intl.DateTimeFormat(options.locale ?? "id-ID", {
|
|
6686
|
+
hour: "2-digit",
|
|
6687
|
+
minute: "2-digit",
|
|
6688
|
+
second: options.granularity === "second" ? "2-digit" : void 0,
|
|
6689
|
+
hourCycle: options.hourCycle === 12 ? "h12" : "h23",
|
|
6690
|
+
timeZone: "UTC"
|
|
6691
|
+
}).format(/* @__PURE__ */ new Date(`2000-01-01T${v}Z`));
|
|
6692
|
+
if (kind === "date") return new Intl.DateTimeFormat(options.locale ?? "id-ID", {
|
|
6693
|
+
day: "numeric",
|
|
6694
|
+
month: "short",
|
|
6695
|
+
year: "numeric",
|
|
6696
|
+
timeZone: "UTC"
|
|
6697
|
+
}).format(/* @__PURE__ */ new Date(`${v}T12:00:00Z`));
|
|
6698
|
+
return `${localValue(v, kind, options).replace("T", " ")} ${options.timeZone ?? "UTC"}`;
|
|
6699
|
+
} catch {
|
|
6700
|
+
return v;
|
|
6701
|
+
}
|
|
6702
|
+
};
|
|
6703
|
+
return typeof value === "string" ? one(value) : `${one(value.start)} – ${one(value.end)}`;
|
|
6704
|
+
}
|
|
6705
|
+
function TemporalPickerField({ part = "start", ...props }) {
|
|
6706
|
+
const context = usePicker(), o = context.options, l = labels(o.locale);
|
|
6707
|
+
const Field = context.kind === "date" ? DateField : context.kind === "time" ? TimeField : DateTimeField;
|
|
6708
|
+
const value = typeof context.draft === "string" ? context.draft : context.draft?.[part] ?? null;
|
|
6709
|
+
return /* @__PURE__ */ jsx(Field, {
|
|
6710
|
+
...o,
|
|
6711
|
+
...props,
|
|
6712
|
+
className: partClass(o.classNames?.field ?? "", props.className),
|
|
6713
|
+
style: props.style,
|
|
6714
|
+
classNames: void 0,
|
|
6715
|
+
label: props.label ?? (context.range ? `${o.label} ${l[part]}` : o.label),
|
|
6716
|
+
value,
|
|
6717
|
+
name: void 0,
|
|
6718
|
+
formValidation: false,
|
|
6719
|
+
isRequired: false,
|
|
6720
|
+
onError: (error) => context.inputError(part, error),
|
|
6721
|
+
onChange: (next) => context.edit(context.range ? {
|
|
6722
|
+
...typeof context.draft === "object" && context.draft ? context.draft : {
|
|
6723
|
+
start: "",
|
|
6724
|
+
end: ""
|
|
6725
|
+
},
|
|
6726
|
+
[part]: next ?? ""
|
|
6727
|
+
} : next, part)
|
|
6728
|
+
});
|
|
6729
|
+
}
|
|
6730
|
+
function TemporalPickerCalendar(props) {
|
|
6731
|
+
const c = usePicker(), o = c.options;
|
|
6732
|
+
const selected = typeof c.draft === "string" ? c.draft : "";
|
|
6733
|
+
const onSingle = (value) => {
|
|
6734
|
+
if (c.kind === "date") c.edit(value);
|
|
6735
|
+
else {
|
|
6736
|
+
const next = value ? combineDate(value, localValue(selected, c.kind, o).slice(11), o) : null;
|
|
6737
|
+
if (value && !next) {
|
|
6738
|
+
c.inputError("date", "invalid");
|
|
6739
|
+
return;
|
|
6740
|
+
}
|
|
6741
|
+
c.edit(next);
|
|
6742
|
+
}
|
|
6743
|
+
};
|
|
6744
|
+
const bounds = temporalDisplayBounds({
|
|
6745
|
+
...o,
|
|
6746
|
+
kind: c.kind
|
|
6747
|
+
});
|
|
6748
|
+
const range = typeof c.draft === "object" && c.draft ? c.draft : {
|
|
6749
|
+
start: "",
|
|
6750
|
+
end: ""
|
|
6751
|
+
};
|
|
6752
|
+
return /* @__PURE__ */ jsx("div", {
|
|
6753
|
+
...props,
|
|
6754
|
+
className: partClass("temporal-picker__calendar", props.className),
|
|
6755
|
+
children: c.kind !== "time" && (c.range ? /* @__PURE__ */ jsx(RangeCalendar, {
|
|
6756
|
+
...o,
|
|
6757
|
+
minDate: bounds.minDate,
|
|
6758
|
+
maxDate: bounds.maxDate,
|
|
6759
|
+
style: void 0,
|
|
6760
|
+
className: void 0,
|
|
6761
|
+
classNames: void 0,
|
|
6762
|
+
value: {
|
|
6763
|
+
start: datePart(range.start, c.kind, o),
|
|
6764
|
+
end: datePart(range.end, c.kind, o)
|
|
6765
|
+
},
|
|
6766
|
+
onChange: (v) => {
|
|
6767
|
+
if (!v || c.kind === "date") {
|
|
6768
|
+
c.edit(v);
|
|
6769
|
+
return;
|
|
6770
|
+
}
|
|
6771
|
+
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) : "";
|
|
6772
|
+
if (v.start && !start || v.end && !end) {
|
|
6773
|
+
c.inputError("date", "invalid");
|
|
6774
|
+
return;
|
|
6775
|
+
}
|
|
6776
|
+
c.edit({
|
|
6777
|
+
start,
|
|
6778
|
+
end
|
|
6779
|
+
});
|
|
6780
|
+
}
|
|
6781
|
+
}) : /* @__PURE__ */ jsx(Calendar, {
|
|
6782
|
+
...o,
|
|
6783
|
+
minDate: bounds.minDate,
|
|
6784
|
+
maxDate: bounds.maxDate,
|
|
6785
|
+
style: void 0,
|
|
6786
|
+
className: void 0,
|
|
6787
|
+
classNames: void 0,
|
|
6788
|
+
value: datePart(selected, c.kind, o),
|
|
6789
|
+
onChange: onSingle
|
|
6790
|
+
}))
|
|
6791
|
+
});
|
|
6792
|
+
}
|
|
6793
|
+
function TemporalPickerTime({ part = "start", ...props }) {
|
|
6794
|
+
const c = usePicker(), o = c.options, l = labels(o.locale);
|
|
6795
|
+
const wall = localValue(typeof c.draft === "string" ? c.draft : c.draft?.[part] ?? "", c.kind, o);
|
|
6796
|
+
const time = c.kind === "time" ? wall : wall.slice(11);
|
|
6797
|
+
const bounds = temporalDisplayBounds({
|
|
6798
|
+
...o,
|
|
6799
|
+
kind: c.kind
|
|
6800
|
+
}, wall.slice(0, 10));
|
|
6801
|
+
const Control = o.timePresentation === "clock" ? TimeClock : TimeList;
|
|
6802
|
+
return /* @__PURE__ */ jsx("div", {
|
|
6803
|
+
...props,
|
|
6804
|
+
className: partClass("temporal-picker__time", props.className),
|
|
6805
|
+
children: /* @__PURE__ */ jsx(Control, {
|
|
6806
|
+
locale: o.locale,
|
|
6807
|
+
hourCycle: o.hourCycle,
|
|
6808
|
+
minTime: bounds.minTime,
|
|
6809
|
+
maxTime: bounds.maxTime,
|
|
6810
|
+
hourStep: o.hourStep,
|
|
6811
|
+
minuteStep: o.minuteStep,
|
|
6812
|
+
secondStep: o.secondStep,
|
|
6813
|
+
granularity: o.granularity,
|
|
6814
|
+
isTimeUnavailable: o.isTimeUnavailable,
|
|
6815
|
+
isDisabled: o.isDisabled,
|
|
6816
|
+
isReadOnly: o.isReadOnly,
|
|
6817
|
+
label: c.range ? `${o.label} ${l[part]}` : o.label,
|
|
6818
|
+
value: time,
|
|
6819
|
+
onChange: (next) => {
|
|
6820
|
+
const result = c.kind === "time" ? next : combineDate(wall.slice(0, 10) || o.referenceDate || today(o.timeZone ?? "UTC").toString(), next, o);
|
|
6821
|
+
if (!result) {
|
|
6822
|
+
c.inputError(part, "invalid");
|
|
6823
|
+
return;
|
|
6824
|
+
}
|
|
6825
|
+
c.edit(c.range ? {
|
|
6826
|
+
...typeof c.draft === "object" && c.draft ? c.draft : {
|
|
6827
|
+
start: "",
|
|
6828
|
+
end: ""
|
|
6829
|
+
},
|
|
6830
|
+
[part]: result
|
|
6831
|
+
} : result, part);
|
|
6832
|
+
}
|
|
6833
|
+
})
|
|
6834
|
+
});
|
|
6835
|
+
}
|
|
6836
|
+
function TemporalPickerValue({ children, className, ...props }) {
|
|
6837
|
+
const c = usePicker();
|
|
6838
|
+
return /* @__PURE__ */ jsx("span", {
|
|
6839
|
+
...props,
|
|
6840
|
+
id: `${c.id}-value`,
|
|
6841
|
+
className: partClass("date-range__value", className),
|
|
6842
|
+
children: children ?? c.text
|
|
6843
|
+
});
|
|
6844
|
+
}
|
|
6845
|
+
function TemporalPickerTrigger({ children, className, ...props }) {
|
|
6846
|
+
const c = usePicker();
|
|
6847
|
+
return /* @__PURE__ */ jsx(Button$1, {
|
|
6848
|
+
...props,
|
|
6849
|
+
isDisabled: c.options.isDisabled,
|
|
6850
|
+
className: partClass("date-range__trigger", className),
|
|
6851
|
+
"aria-labelledby": `${c.id}-label ${c.id}-value`,
|
|
6852
|
+
"aria-invalid": c.invalid || void 0,
|
|
6853
|
+
"aria-describedby": c.describedBy,
|
|
6854
|
+
children: children ?? /* @__PURE__ */ jsx(TemporalPickerValue, {})
|
|
6855
|
+
});
|
|
6856
|
+
}
|
|
6857
|
+
function TemporalPickerContent({ children, className, ...props }) {
|
|
6858
|
+
const c = usePicker();
|
|
6859
|
+
return /* @__PURE__ */ jsx("div", {
|
|
6860
|
+
...props,
|
|
6861
|
+
className,
|
|
6862
|
+
children: children ?? c.panel
|
|
6863
|
+
});
|
|
6864
|
+
}
|
|
6865
|
+
function TemporalPickerPopover({ children, className, ...props }) {
|
|
6866
|
+
const c = usePicker();
|
|
6867
|
+
return /* @__PURE__ */ jsx(Popover$2, {
|
|
6868
|
+
className: partClass("date-range__panel temporal-picker__panel", className),
|
|
6869
|
+
placement: "bottom start",
|
|
6870
|
+
offset: 8,
|
|
6871
|
+
children: /* @__PURE__ */ jsx(Dialog$1, {
|
|
6872
|
+
"aria-labelledby": `${c.id}-label`,
|
|
6873
|
+
className: "date-range__dialog",
|
|
6874
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
6875
|
+
...props,
|
|
6876
|
+
children: children ?? c.panel
|
|
6877
|
+
})
|
|
6878
|
+
})
|
|
6879
|
+
});
|
|
6880
|
+
}
|
|
6881
|
+
function action(type) {
|
|
6882
|
+
return function PickerAction({ children, className, onClick, ...props }) {
|
|
6883
|
+
const c = usePicker();
|
|
6884
|
+
return /* @__PURE__ */ jsx("button", {
|
|
6885
|
+
type: "button",
|
|
6886
|
+
...props,
|
|
6887
|
+
className: partClass(`button button--${type === "apply" ? "primary" : "ghost"} button--sm`, className),
|
|
6888
|
+
disabled: props.disabled || type !== "cancel" && (c.options.isDisabled || c.options.isReadOnly) || type === "apply" && !!c.error,
|
|
6889
|
+
onClick: (e) => {
|
|
6890
|
+
onClick?.(e);
|
|
6891
|
+
if (!e.defaultPrevented) c[type]();
|
|
6892
|
+
},
|
|
6893
|
+
children: children ?? labels(c.options.locale)[type]
|
|
6894
|
+
});
|
|
6895
|
+
};
|
|
6896
|
+
}
|
|
6897
|
+
var TemporalPickerApplyButton = /* @__PURE__ */ action("apply");
|
|
6898
|
+
var TemporalPickerCancelButton = /* @__PURE__ */ action("cancel");
|
|
6899
|
+
var TemporalPickerClearButton = /* @__PURE__ */ action("clear");
|
|
6900
|
+
function Root({ kind, range, ...props }) {
|
|
6901
|
+
const [local, setLocal] = useState(props.defaultValue ?? null);
|
|
6902
|
+
const committed = props.value === void 0 ? local : props.value;
|
|
6903
|
+
const [draft, setDraft] = useState(committed), [inputErrors, setInputErrors] = useState({}), [formError, setFormError] = useState(false), [mobile, setMobile] = useState(false);
|
|
6904
|
+
const id = useId(), trigger = useRef(null);
|
|
6905
|
+
const disclosure = useDisclosure(props.open, props.defaultOpen, props.onOpenChange);
|
|
6906
|
+
const l = labels(props.locale);
|
|
6907
|
+
const committedKey = JSON.stringify(committed), lastCommitted = useRef(committedKey);
|
|
6908
|
+
useEffect(() => {
|
|
6909
|
+
if (lastCommitted.current === committedKey) return;
|
|
6910
|
+
lastCommitted.current = committedKey;
|
|
6911
|
+
setDraft(committed);
|
|
6912
|
+
setInputErrors({});
|
|
6913
|
+
}, [committed, committedKey]);
|
|
6914
|
+
useEffect(() => {
|
|
6915
|
+
const media = window.matchMedia("(max-width: 640px)");
|
|
6916
|
+
const update = () => setMobile(media.matches);
|
|
6917
|
+
update();
|
|
6918
|
+
media.addEventListener("change", update);
|
|
6919
|
+
return () => media.removeEventListener("change", update);
|
|
6920
|
+
}, []);
|
|
6921
|
+
const constraints = {
|
|
6922
|
+
...props,
|
|
6923
|
+
kind
|
|
6924
|
+
};
|
|
6925
|
+
const validate = (value) => range ? temporalRangeError(typeof value === "object" ? value : null, constraints) : temporalError(typeof value === "string" ? value : null, constraints);
|
|
6926
|
+
const code = Object.values(inputErrors).find(Boolean) ?? validate(draft);
|
|
6927
|
+
const error = code ? code in temporalMessages(props.locale) ? temporalMessages(props.locale)[code] : code : null;
|
|
6928
|
+
const committedError = validate(committed);
|
|
6929
|
+
const errorCallback = useRef(props.onError);
|
|
6930
|
+
useEffect(() => {
|
|
6931
|
+
errorCallback.current = props.onError;
|
|
6932
|
+
}, [props.onError]);
|
|
6933
|
+
useEffect(() => {
|
|
6934
|
+
errorCallback.current?.(error);
|
|
6935
|
+
}, [error]);
|
|
6936
|
+
function changeOpen(next) {
|
|
6937
|
+
if (props.isDisabled && next) return;
|
|
6938
|
+
setDraft(committed);
|
|
6939
|
+
setInputErrors({});
|
|
6940
|
+
disclosure.change(next);
|
|
6941
|
+
}
|
|
6942
|
+
function commit(value, close) {
|
|
6943
|
+
if (props.isDisabled || props.isReadOnly || validate(value)) return;
|
|
6944
|
+
setLocal(value);
|
|
6945
|
+
setFormError(false);
|
|
6946
|
+
props.onChange?.(value);
|
|
6947
|
+
if (close) {
|
|
6948
|
+
props.onApply?.(value);
|
|
6949
|
+
disclosure.change(false);
|
|
6950
|
+
}
|
|
6951
|
+
}
|
|
6952
|
+
function edit(value, part) {
|
|
6953
|
+
if (props.isDisabled || props.isReadOnly) return;
|
|
6954
|
+
setDraft(value);
|
|
6955
|
+
const remaining = part ? {
|
|
6956
|
+
...inputErrors,
|
|
6957
|
+
[part]: null
|
|
6958
|
+
} : {};
|
|
6959
|
+
setInputErrors(remaining);
|
|
6960
|
+
if (props.commitMode === "immediate" && !Object.values(remaining).some(Boolean)) commit(value, false);
|
|
6961
|
+
}
|
|
6962
|
+
function clear() {
|
|
6963
|
+
if (props.isDisabled || props.isReadOnly) return;
|
|
6964
|
+
setDraft(null);
|
|
6965
|
+
setInputErrors({});
|
|
6966
|
+
if (props.commitMode === "immediate") {
|
|
6967
|
+
setLocal(null);
|
|
6968
|
+
props.onChange?.(null);
|
|
6969
|
+
}
|
|
6970
|
+
}
|
|
6971
|
+
const context = {
|
|
6972
|
+
options: props,
|
|
6973
|
+
kind,
|
|
6974
|
+
range,
|
|
6975
|
+
draft,
|
|
6976
|
+
error,
|
|
6977
|
+
id,
|
|
6978
|
+
invalid: props.isInvalid || !!committedError || formError,
|
|
6979
|
+
describedBy: [props.description ? `${id}-description` : void 0, props.isInvalid || committedError || formError ? `${id}-error` : void 0].filter(Boolean).join(" ") || void 0,
|
|
6980
|
+
text: displayText(committed, kind, props),
|
|
6981
|
+
edit,
|
|
6982
|
+
inputError: (part, error) => setInputErrors((current) => current[part] === error ? current : {
|
|
6983
|
+
...current,
|
|
6984
|
+
[part]: error
|
|
6985
|
+
}),
|
|
6986
|
+
apply: () => {
|
|
6987
|
+
if (!error) commit(draft, true);
|
|
6988
|
+
},
|
|
6989
|
+
cancel: () => changeOpen(false),
|
|
6990
|
+
clear,
|
|
6991
|
+
panel: null
|
|
6992
|
+
};
|
|
6993
|
+
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();
|
|
6994
|
+
const panel = /* @__PURE__ */ jsxs("div", {
|
|
6995
|
+
className: partClass("temporal-picker__content", props.classNames?.content),
|
|
6996
|
+
children: [
|
|
6997
|
+
/* @__PURE__ */ jsx("h2", {
|
|
6998
|
+
className: "temporal-picker__title",
|
|
6999
|
+
children: props.label
|
|
7000
|
+
}),
|
|
7001
|
+
!!props.presets?.length && /* @__PURE__ */ jsx("div", {
|
|
7002
|
+
className: "temporal-picker__presets",
|
|
7003
|
+
children: props.presets.map((p) => /* @__PURE__ */ jsx("button", {
|
|
7004
|
+
type: "button",
|
|
7005
|
+
className: partClass("date-range__preset", props.classNames?.preset),
|
|
7006
|
+
disabled: props.isDisabled || props.isReadOnly || !!validate(p.value),
|
|
7007
|
+
onClick: () => edit(p.value),
|
|
7008
|
+
children: p.label
|
|
7009
|
+
}, p.id))
|
|
7010
|
+
}),
|
|
7011
|
+
props.showInputs !== false && /* @__PURE__ */ jsxs("div", {
|
|
7012
|
+
className: "temporal-picker__fields",
|
|
7013
|
+
children: [/* @__PURE__ */ jsx(TemporalPickerField, {}), range && /* @__PURE__ */ jsx(TemporalPickerField, { part: "end" })]
|
|
7014
|
+
}),
|
|
7015
|
+
/* @__PURE__ */ jsxs("div", {
|
|
7016
|
+
className: "temporal-picker__views",
|
|
7017
|
+
children: [
|
|
7018
|
+
kind !== "time" && /* @__PURE__ */ jsx(TemporalPickerCalendar, { className: props.classNames?.calendar }),
|
|
7019
|
+
" ",
|
|
7020
|
+
kind !== "date" && /* @__PURE__ */ jsxs("div", {
|
|
7021
|
+
className: "temporal-picker__times",
|
|
7022
|
+
children: [/* @__PURE__ */ jsx(TemporalPickerTime, { className: props.classNames?.time }), range && /* @__PURE__ */ jsx(TemporalPickerTime, {
|
|
7023
|
+
part: "end",
|
|
7024
|
+
className: props.classNames?.time
|
|
7025
|
+
})]
|
|
7026
|
+
})
|
|
7027
|
+
]
|
|
7028
|
+
}),
|
|
7029
|
+
error && /* @__PURE__ */ jsx("span", {
|
|
7030
|
+
className: "input__error",
|
|
7031
|
+
role: "alert",
|
|
7032
|
+
children: error
|
|
7033
|
+
}),
|
|
7034
|
+
/* @__PURE__ */ jsx("button", {
|
|
7035
|
+
type: "button",
|
|
7036
|
+
className: "button button--ghost button--sm",
|
|
7037
|
+
disabled: props.isDisabled || props.isReadOnly || !!temporalError(current, constraints),
|
|
7038
|
+
onClick: () => edit(range ? {
|
|
7039
|
+
start: current,
|
|
7040
|
+
end: current
|
|
7041
|
+
} : current),
|
|
7042
|
+
children: kind === "date" ? l.today : l.now
|
|
7043
|
+
}),
|
|
7044
|
+
props.showActions !== false && /* @__PURE__ */ jsxs("footer", {
|
|
7045
|
+
className: partClass("date-range__footer", props.classNames?.footer),
|
|
7046
|
+
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 })] })]
|
|
7047
|
+
})
|
|
7048
|
+
]
|
|
7049
|
+
});
|
|
7050
|
+
context.panel = panel;
|
|
7051
|
+
const dialog = props.display === "dialog" || props.display !== "inline" && props.display !== "popover" && mobile;
|
|
7052
|
+
return /* @__PURE__ */ jsx(PickerContext.Provider, {
|
|
7053
|
+
value: context,
|
|
7054
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
7055
|
+
className: partClass(partClass(`date-range temporal-picker date-range--${props.size ?? "md"}`, props.classNames?.root), props.className),
|
|
7056
|
+
style: props.style,
|
|
7057
|
+
dir: props.dir,
|
|
7058
|
+
children: [
|
|
7059
|
+
/* @__PURE__ */ jsx("span", {
|
|
7060
|
+
id: `${id}-label`,
|
|
7061
|
+
className: partClass(props.hideLabel ? "temporal__sr-only" : "date-range__label", props.classNames?.label),
|
|
7062
|
+
children: props.label
|
|
7063
|
+
}),
|
|
7064
|
+
props.display === "inline" ? /* @__PURE__ */ jsx("section", {
|
|
7065
|
+
className: partClass("date-range__panel date-range__inline", props.classNames?.panel),
|
|
7066
|
+
"aria-labelledby": `${id}-label`,
|
|
7067
|
+
children: props.children ?? panel
|
|
7068
|
+
}) : /* @__PURE__ */ jsx(DialogTrigger, {
|
|
7069
|
+
isOpen: disclosure.visible && !props.isDisabled,
|
|
7070
|
+
onOpenChange: changeOpen,
|
|
7071
|
+
children: props.children ?? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Button$1, {
|
|
7072
|
+
ref: trigger,
|
|
7073
|
+
className: partClass("date-range__trigger", props.classNames?.trigger),
|
|
7074
|
+
isDisabled: props.isDisabled,
|
|
7075
|
+
"aria-labelledby": `${id}-label ${id}-value`,
|
|
7076
|
+
"aria-invalid": context.invalid || void 0,
|
|
7077
|
+
"aria-describedby": context.describedBy,
|
|
7078
|
+
children: /* @__PURE__ */ jsx(TemporalPickerValue, { className: props.classNames?.value })
|
|
7079
|
+
}), dialog ? /* @__PURE__ */ jsx(ModalOverlay, {
|
|
7080
|
+
className: "temporal-picker__overlay",
|
|
7081
|
+
children: /* @__PURE__ */ jsx(Modal, {
|
|
7082
|
+
className: "date-range__panel temporal-picker__modal",
|
|
7083
|
+
children: /* @__PURE__ */ jsx(Dialog$1, {
|
|
7084
|
+
"aria-labelledby": `${id}-label`,
|
|
7085
|
+
children: panel
|
|
7086
|
+
})
|
|
7087
|
+
})
|
|
7088
|
+
}) : /* @__PURE__ */ jsx(TemporalPickerPopover, { className: props.classNames?.panel })] })
|
|
7089
|
+
}),
|
|
7090
|
+
props.description && /* @__PURE__ */ jsx("span", {
|
|
7091
|
+
id: `${id}-description`,
|
|
7092
|
+
className: partClass("input__description", props.classNames?.description),
|
|
7093
|
+
children: props.description
|
|
7094
|
+
}),
|
|
7095
|
+
(props.isInvalid || committedError || formError) && /* @__PURE__ */ jsx("span", {
|
|
7096
|
+
id: `${id}-error`,
|
|
7097
|
+
role: "alert",
|
|
7098
|
+
className: partClass("input__error", props.classNames?.error),
|
|
7099
|
+
children: props.errorMessage ?? temporalMessages(props.locale)[committedError ?? (props.isInvalid ? "invalid" : "required")]
|
|
7100
|
+
}),
|
|
7101
|
+
props.name && (range ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("input", {
|
|
7102
|
+
type: "hidden",
|
|
7103
|
+
name: `${props.name}.start`,
|
|
7104
|
+
value: typeof committed === "object" && committed ? committed.start : "",
|
|
7105
|
+
disabled: props.isDisabled
|
|
7106
|
+
}), /* @__PURE__ */ jsx("input", {
|
|
7107
|
+
type: "hidden",
|
|
7108
|
+
name: `${props.name}.end`,
|
|
7109
|
+
value: typeof committed === "object" && committed ? committed.end : "",
|
|
7110
|
+
disabled: props.isDisabled
|
|
7111
|
+
})] }) : /* @__PURE__ */ jsx("input", {
|
|
7112
|
+
type: "hidden",
|
|
7113
|
+
name: props.name,
|
|
7114
|
+
value: typeof committed === "string" ? committed : "",
|
|
7115
|
+
disabled: props.isDisabled
|
|
7116
|
+
})),
|
|
7117
|
+
/* @__PURE__ */ jsx(SelectionValidation, {
|
|
7118
|
+
hasValue: !!committed && !committedError,
|
|
7119
|
+
required: props.isRequired || !!committedError,
|
|
7120
|
+
disabled: props.isDisabled,
|
|
7121
|
+
onInvalid: () => {
|
|
7122
|
+
setFormError(true);
|
|
7123
|
+
trigger.current?.focus();
|
|
7124
|
+
},
|
|
7125
|
+
onResetStart: () => {},
|
|
7126
|
+
onReset: (cancelled) => {
|
|
7127
|
+
if (!cancelled) {
|
|
7128
|
+
if (props.value === void 0) setLocal(props.defaultValue ?? null);
|
|
7129
|
+
setDraft(props.value === void 0 ? props.defaultValue ?? null : committed);
|
|
7130
|
+
setInputErrors({});
|
|
7131
|
+
setFormError(false);
|
|
7132
|
+
disclosure.change(false);
|
|
7133
|
+
}
|
|
7134
|
+
}
|
|
7135
|
+
})
|
|
7136
|
+
]
|
|
7137
|
+
})
|
|
7138
|
+
});
|
|
7139
|
+
}
|
|
7140
|
+
function picker(kind, range) {
|
|
7141
|
+
const Component = (props) => /* @__PURE__ */ jsx(Root, {
|
|
7142
|
+
...props,
|
|
7143
|
+
kind,
|
|
7144
|
+
range
|
|
7145
|
+
});
|
|
7146
|
+
return Object.assign(Component, {
|
|
7147
|
+
Root: Component,
|
|
7148
|
+
Trigger: TemporalPickerTrigger,
|
|
7149
|
+
Value: TemporalPickerValue,
|
|
7150
|
+
Popover: TemporalPickerPopover,
|
|
7151
|
+
Content: TemporalPickerContent,
|
|
7152
|
+
Field: TemporalPickerField,
|
|
7153
|
+
Calendar: TemporalPickerCalendar,
|
|
7154
|
+
Time: TemporalPickerTime,
|
|
7155
|
+
MonthPicker,
|
|
7156
|
+
YearPicker,
|
|
7157
|
+
ApplyButton: TemporalPickerApplyButton,
|
|
7158
|
+
CancelButton: TemporalPickerCancelButton,
|
|
7159
|
+
ClearButton: TemporalPickerClearButton
|
|
7160
|
+
});
|
|
7161
|
+
}
|
|
7162
|
+
var DatePicker = /* @__PURE__ */ picker("date", false);
|
|
7163
|
+
var TimePicker = /* @__PURE__ */ picker("time", false);
|
|
7164
|
+
var TimeRangePicker = /* @__PURE__ */ picker("time", true);
|
|
7165
|
+
var DateTimePicker = /* @__PURE__ */ picker("datetime", false);
|
|
7166
|
+
var DateTimeRangePicker = /* @__PURE__ */ picker("datetime", true);
|
|
7167
|
+
//#endregion
|
|
7168
|
+
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
7169
|
|
|
5277
7170
|
//# sourceMappingURL=index.js.map
|