gridsmith-ui 0.19.0 → 0.21.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/dist/{chunk-5PDTHKW3.js → chunk-GGVASDXT.js} +119 -12
- package/dist/chunk-GGVASDXT.js.map +1 -0
- package/dist/{chunk-JXANCXK6.js → chunk-RT7RYGC3.js} +39 -4
- package/dist/chunk-RT7RYGC3.js.map +1 -0
- package/dist/editor.d.ts +39 -2
- package/dist/editor.js +120 -8
- package/dist/editor.js.map +1 -1
- package/dist/index.d.ts +216 -57
- package/dist/index.js +1272 -527
- package/dist/index.js.map +1 -1
- package/dist/resizable.js +6 -6
- package/dist/resizable.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-5PDTHKW3.js.map +0 -1
- package/dist/chunk-JXANCXK6.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Button, useAppShell, REACT_VERSION_PROBLEM, ControlSizeContext, useDirtyGuard, OverlayCloseCtx, DiscardConfirm, Spinner, DrawerFooterCtx, useCompact, useElementWidth, Sheet, useCloseSettle, Drawer, useRememberedWidth, pxOf, ResizeEdge, defaultMaxWidth } from './chunk-
|
|
2
|
-
export { AppShell, Button, ButtonSizeContext, ControlSizeContext, Drawer, Sheet, SkipLink, Spinner, useAppShell, useUnsavedChanges } from './chunk-
|
|
1
|
+
import { Button, useAppShell, REACT_VERSION_PROBLEM, ControlSizeContext, triggerType, useOverlayMark, useDirtyGuard, OverlayMarkScope, OverlayCloseCtx, DiscardConfirm, OVERLAY_ROOT_ATTR, Spinner, OverlayMarkCtx, DrawerFooterCtx, useCompact, useElementWidth, Sheet, useCloseSettle, Drawer, useRememberedWidth, pxOf, ResizeEdge, defaultMaxWidth } from './chunk-GGVASDXT.js';
|
|
2
|
+
export { AppShell, Button, ButtonSizeContext, ControlSizeContext, Drawer, Sheet, SkipLink, Spinner, useAppShell, useUnsavedChanges } from './chunk-GGVASDXT.js';
|
|
3
3
|
import { Skeleton, TITLE_TEXT } from './chunk-NCIZQYXQ.js';
|
|
4
4
|
export { Skeleton } from './chunk-NCIZQYXQ.js';
|
|
5
|
-
import { FOCUSABLE, usePopupFocus, FIELD, ZOOM_KEYS, useOverlayLayer, useFocusTrap, useFocusBeforeOpen, rememberFocus, focusInitial, OVERLAY_CLOSE_ATTR, focusAfterRemoval, rovingTabStop, useGridKeyboard, useNonModalDialog, usePressMarks, useReturnFocus, useCloseOnFocusOut } from './chunk-
|
|
6
|
-
export { useGridKeyboard } from './chunk-
|
|
5
|
+
import { FOCUSABLE, usePopupFocus, FIELD, ZOOM_KEYS, FormChangeCtx, useOverlayLayer, useFocusTrap, useFocusBeforeOpen, rememberFocus, focusInitial, OVERLAY_CLOSE_ATTR, useReportedChange, focusAfterRemoval, useOptionalFormContext, rovingTabStop, useGridKeyboard, FormCtx, useNonModalDialog, usePressMarks, useReturnFocus, useCloseOnFocusOut } from './chunk-RT7RYGC3.js';
|
|
6
|
+
export { useFormContext, useGridKeyboard } from './chunk-RT7RYGC3.js';
|
|
7
7
|
import { Link } from './chunk-EQDR57AM.js';
|
|
8
8
|
export { CodeBlock, Divider, Link } from './chunk-EQDR57AM.js';
|
|
9
9
|
import { Badge } from './chunk-XYDIBW3J.js';
|
|
@@ -82,6 +82,7 @@ function DropdownMenu({ trigger, items, align = "end", className, container }) {
|
|
|
82
82
|
/* @__PURE__ */ jsx(
|
|
83
83
|
Slot,
|
|
84
84
|
{
|
|
85
|
+
...triggerType(trigger),
|
|
85
86
|
ref: triggerRef,
|
|
86
87
|
onClick: () => {
|
|
87
88
|
setOpen(!open);
|
|
@@ -115,6 +116,7 @@ function DropdownMenu({ trigger, items, align = "end", className, container }) {
|
|
|
115
116
|
return /* @__PURE__ */ jsxs(
|
|
116
117
|
"button",
|
|
117
118
|
{
|
|
119
|
+
type: "button",
|
|
118
120
|
"data-index": i,
|
|
119
121
|
role: "menuitem",
|
|
120
122
|
disabled: item.disabled,
|
|
@@ -177,13 +179,14 @@ function BulkActionBar({ selectedCount, actions, onClearSelection, className })
|
|
|
177
179
|
isMobile ? /* @__PURE__ */ jsx(
|
|
178
180
|
DropdownMenu,
|
|
179
181
|
{
|
|
180
|
-
trigger: /* @__PURE__ */ jsx(Button, { variant: "secondary", size: "sm", iconLeft: /* @__PURE__ */ jsx(Icon, { name: "more-vertical", size: 14 }), children: "Actions" }),
|
|
182
|
+
trigger: /* @__PURE__ */ jsx(Button, { type: "button", variant: "secondary", size: "sm", iconLeft: /* @__PURE__ */ jsx(Icon, { name: "more-vertical", size: 14 }), children: "Actions" }),
|
|
181
183
|
items: dropdownItems,
|
|
182
184
|
align: "start"
|
|
183
185
|
}
|
|
184
186
|
) : /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-2", children: actions.map((action, i) => /* @__PURE__ */ jsx(
|
|
185
187
|
Button,
|
|
186
188
|
{
|
|
189
|
+
type: "button",
|
|
187
190
|
variant: "secondary",
|
|
188
191
|
size: "sm",
|
|
189
192
|
onClick: action.onClick,
|
|
@@ -194,6 +197,7 @@ function BulkActionBar({ selectedCount, actions, onClearSelection, className })
|
|
|
194
197
|
/* @__PURE__ */ jsx(
|
|
195
198
|
"button",
|
|
196
199
|
{
|
|
200
|
+
type: "button",
|
|
197
201
|
onClick: onClearSelection,
|
|
198
202
|
className: "ml-auto text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)] transition-colors cursor-pointer",
|
|
199
203
|
"aria-label": "Clear selection",
|
|
@@ -204,6 +208,12 @@ function BulkActionBar({ selectedCount, actions, onClearSelection, className })
|
|
|
204
208
|
}
|
|
205
209
|
);
|
|
206
210
|
}
|
|
211
|
+
var UNCONTROLLED = /* @__PURE__ */ Symbol("uncontrolled");
|
|
212
|
+
var valueOf = (e) => {
|
|
213
|
+
const t = e.target;
|
|
214
|
+
if (!t) return void 0;
|
|
215
|
+
return t instanceof HTMLInputElement && (t.type === "checkbox" || t.type === "radio") ? t.checked : t.value;
|
|
216
|
+
};
|
|
207
217
|
var INPUT_HEIGHT = {
|
|
208
218
|
sm: "h-[var(--ds-control-height-sm)]",
|
|
209
219
|
md: "h-[var(--ds-control-height-md)]",
|
|
@@ -217,6 +227,7 @@ var INPUT_TEXT = {
|
|
|
217
227
|
function Input({ className, size: sizeProp, error = false, prefix, suffix, ...props }) {
|
|
218
228
|
const contextSize = useContext(ControlSizeContext);
|
|
219
229
|
const size = sizeProp ?? contextSize ?? "md";
|
|
230
|
+
const onChange = useReportedChange(props.onChange, props.value === void 0 ? UNCONTROLLED : props.value, valueOf);
|
|
220
231
|
const borderColor = error ? "border-[var(--ds-status-error)]" : "border-[var(--ds-input-border)]";
|
|
221
232
|
const hoverBorder = !error && !props.disabled && !props.readOnly ? "hover:border-[var(--ds-input-border-hover)]" : "";
|
|
222
233
|
if (prefix || suffix) {
|
|
@@ -252,7 +263,8 @@ function Input({ className, size: sizeProp, error = false, prefix, suffix, ...pr
|
|
|
252
263
|
"disabled:cursor-not-allowed",
|
|
253
264
|
"read-only:text-[var(--ds-text-secondary)] read-only:cursor-default"
|
|
254
265
|
),
|
|
255
|
-
...props
|
|
266
|
+
...props,
|
|
267
|
+
onChange: props.onChange || props.value === void 0 ? onChange : void 0
|
|
256
268
|
}
|
|
257
269
|
),
|
|
258
270
|
suffix && /* @__PURE__ */ jsx("span", { className: "shrink-0 pr-ds-3 text-[var(--ds-text-muted)] flex items-center", children: suffix })
|
|
@@ -281,11 +293,13 @@ function Input({ className, size: sizeProp, error = false, prefix, suffix, ...pr
|
|
|
281
293
|
"transition-colors duration-[var(--ds-transition-speed)]",
|
|
282
294
|
className
|
|
283
295
|
),
|
|
284
|
-
...props
|
|
296
|
+
...props,
|
|
297
|
+
onChange: props.onChange || props.value === void 0 ? onChange : void 0
|
|
285
298
|
}
|
|
286
299
|
);
|
|
287
300
|
}
|
|
288
301
|
function Textarea({ className, autoResize, maxRows, error = false, ref, ...props }) {
|
|
302
|
+
const onChange = useReportedChange(props.onChange, props.value === void 0 ? UNCONTROLLED : props.value, valueOf);
|
|
289
303
|
const internalRef = useRef(null);
|
|
290
304
|
const textareaRef = ref ?? internalRef;
|
|
291
305
|
const resize = useCallback(() => {
|
|
@@ -324,7 +338,8 @@ function Textarea({ className, autoResize, maxRows, error = false, ref, ...props
|
|
|
324
338
|
className
|
|
325
339
|
),
|
|
326
340
|
onInput: autoResize ? resize : void 0,
|
|
327
|
-
...props
|
|
341
|
+
...props,
|
|
342
|
+
onChange: props.onChange || props.value === void 0 ? onChange : void 0
|
|
328
343
|
}
|
|
329
344
|
);
|
|
330
345
|
}
|
|
@@ -347,18 +362,20 @@ var TOGGLE_SIZES = {
|
|
|
347
362
|
md: { w: 44, h: 24, thumb: 16 }
|
|
348
363
|
};
|
|
349
364
|
function Toggle({ checked, onChange, label, disabled, error = false, layout = "full", size = "md", "aria-labelledby": ariaLabelledBy, ...rest }) {
|
|
365
|
+
const change = useReportedChange(onChange, checked);
|
|
350
366
|
const dims = TOGGLE_SIZES[size];
|
|
351
367
|
const travel = dims.w - dims.thumb - 3;
|
|
352
368
|
const switchButton = /* @__PURE__ */ jsx(
|
|
353
369
|
"button",
|
|
354
370
|
{
|
|
371
|
+
type: "button",
|
|
355
372
|
role: "switch",
|
|
356
373
|
"aria-checked": checked,
|
|
357
374
|
"aria-label": !label && !ariaLabelledBy ? "Toggle" : void 0,
|
|
358
375
|
"aria-labelledby": ariaLabelledBy,
|
|
359
376
|
"aria-invalid": error || void 0,
|
|
360
377
|
disabled,
|
|
361
|
-
onClick: () => !disabled &&
|
|
378
|
+
onClick: () => !disabled && change(!checked),
|
|
362
379
|
...rest,
|
|
363
380
|
className: cn(
|
|
364
381
|
"relative inline-flex shrink-0 items-center overflow-hidden",
|
|
@@ -407,15 +424,6 @@ function Toggle({ checked, onChange, label, disabled, error = false, layout = "f
|
|
|
407
424
|
}
|
|
408
425
|
);
|
|
409
426
|
}
|
|
410
|
-
var FormCtx = createContext(null);
|
|
411
|
-
function useFormContext() {
|
|
412
|
-
const ctx = useContext(FormCtx);
|
|
413
|
-
if (!ctx) throw new Error("useFormContext must be used within FormWrapper");
|
|
414
|
-
return ctx;
|
|
415
|
-
}
|
|
416
|
-
function useOptionalFormContext() {
|
|
417
|
-
return useContext(FormCtx);
|
|
418
|
-
}
|
|
419
427
|
function InlineFieldError({ message, id, className }) {
|
|
420
428
|
return /* @__PURE__ */ jsxs(
|
|
421
429
|
"p",
|
|
@@ -454,7 +462,9 @@ function useFieldControl(own, options = {}) {
|
|
|
454
462
|
requiredNote: noteId ? /* @__PURE__ */ jsx("span", { id: noteId, hidden: true, children: "Required" }) : null
|
|
455
463
|
};
|
|
456
464
|
}
|
|
457
|
-
|
|
465
|
+
var AddAnotherRowCtx = createContext(false);
|
|
466
|
+
function Field({ label, children, hint, error, required, labelAction, hideLabel = false, id: idProp, validate, className }) {
|
|
467
|
+
const inGroupRow = useContext(AddAnotherRowCtx);
|
|
458
468
|
const generated = useId();
|
|
459
469
|
const id = idProp ?? `field-${generated}`;
|
|
460
470
|
const hintId = `${id}-hint`;
|
|
@@ -533,6 +543,10 @@ function Field({ label, children, hint, error, required, labelAction, id: idProp
|
|
|
533
543
|
} } : {};
|
|
534
544
|
control = cloneElement(child, isNative ? ariaOnly : { ...ariaOnly, ...errorFlag ? { error: true } : {}, ...onChange });
|
|
535
545
|
}
|
|
546
|
+
const labelNode = /* @__PURE__ */ jsxs(Label, { id: labelId, htmlFor: id, className: cn(hideLabel && "sr-only", hideLabel && inGroupRow && "@max-[30rem]:not-sr-only"), children: [
|
|
547
|
+
label,
|
|
548
|
+
required && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "ml-ds-0.5 text-[var(--ds-status-error)]", children: "*" })
|
|
549
|
+
] });
|
|
536
550
|
return (
|
|
537
551
|
// In a settings panel a field keeps the narrow reading width however wide the page is (--ds-form-max, Sprint 25.9 A4)
|
|
538
552
|
/* @__PURE__ */ jsxs(
|
|
@@ -541,11 +555,8 @@ function Field({ label, children, hint, error, required, labelAction, id: idProp
|
|
|
541
555
|
className: cn("flex flex-col gap-ds-1.5 max-w-[var(--ds-form-max,none)]", className),
|
|
542
556
|
...validate ? { onFocusCapture, onBlurCapture, onInputCapture: recheck } : {},
|
|
543
557
|
children: [
|
|
544
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-ds-2", children: [
|
|
545
|
-
|
|
546
|
-
label,
|
|
547
|
-
required && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "ml-ds-0.5 text-[var(--ds-status-error)]", children: "*" })
|
|
548
|
-
] }),
|
|
558
|
+
hideLabel && !labelAction ? labelNode : /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-ds-2", children: [
|
|
559
|
+
labelNode,
|
|
549
560
|
labelAction
|
|
550
561
|
] }),
|
|
551
562
|
/* @__PURE__ */ jsx(FieldContext.Provider, { value: fieldContext, children: control }),
|
|
@@ -564,7 +575,7 @@ var DROPDOWN_HEIGHT = {
|
|
|
564
575
|
function Dropdown({
|
|
565
576
|
options,
|
|
566
577
|
value,
|
|
567
|
-
onChange,
|
|
578
|
+
onChange: onChangeProp,
|
|
568
579
|
label,
|
|
569
580
|
disabled,
|
|
570
581
|
placeholder = "Select...",
|
|
@@ -579,6 +590,7 @@ function Dropdown({
|
|
|
579
590
|
"aria-label": ariaLabel,
|
|
580
591
|
...wiring
|
|
581
592
|
}) {
|
|
593
|
+
const onChange = useReportedChange(onChangeProp, value);
|
|
582
594
|
const contextSize = useContext(ControlSizeContext);
|
|
583
595
|
const generatedId = useId();
|
|
584
596
|
const control = useFieldControl({ ...wiring, error: error || void 0 }, { requiredInDescription: true });
|
|
@@ -865,6 +877,7 @@ function Dropdown({
|
|
|
865
877
|
/* @__PURE__ */ jsx(
|
|
866
878
|
"button",
|
|
867
879
|
{
|
|
880
|
+
type: "button",
|
|
868
881
|
"data-chip-remove": "",
|
|
869
882
|
onClick: () => {
|
|
870
883
|
pendingChipFocus.current = { index: i, value: v };
|
|
@@ -932,7 +945,8 @@ var TEXT_SIZE = {
|
|
|
932
945
|
md: "text-sm",
|
|
933
946
|
lg: "text-base"
|
|
934
947
|
};
|
|
935
|
-
function Combobox({ value, onChange, options, placeholder = "Search\u2026", disabled, loading = false, className, ref, container, error = false, size: sizeProp, ...wiring }) {
|
|
948
|
+
function Combobox({ value, onChange: onChangeProp, options, placeholder = "Search\u2026", disabled, loading = false, className, ref, container, error = false, size: sizeProp, ...wiring }) {
|
|
949
|
+
const onChange = useReportedChange(onChangeProp, value);
|
|
936
950
|
const contextSize = useContext(ControlSizeContext);
|
|
937
951
|
const control = useFieldControl({ ...wiring, error: error || void 0 });
|
|
938
952
|
const size = sizeProp ?? contextSize ?? "md";
|
|
@@ -1130,6 +1144,7 @@ function Combobox({ value, onChange, options, placeholder = "Search\u2026", disa
|
|
|
1130
1144
|
children: /* @__PURE__ */ jsx("div", { style: { padding: "var(--ds-space-1)" }, children: loading ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-ds-4", children: /* @__PURE__ */ jsx(Spinner, { size: "sm", label: "Loading options" }) }) : filtered.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-ds-2 py-ds-3 text-sm text-[var(--ds-text-muted)] text-center", children: "No results" }) : filtered.map((opt, i) => /* @__PURE__ */ jsxs(
|
|
1131
1145
|
"button",
|
|
1132
1146
|
{
|
|
1147
|
+
type: "button",
|
|
1133
1148
|
id: `${listboxId}-opt-${i}`,
|
|
1134
1149
|
role: "option",
|
|
1135
1150
|
tabIndex: -1,
|
|
@@ -1161,9 +1176,11 @@ var CHECKBOX_SIZES = {
|
|
|
1161
1176
|
sm: { box: "h-[16px] w-[16px]", glyph: 10, label: "text-xs" },
|
|
1162
1177
|
md: { box: "h-[18px] w-[18px]", glyph: 12, label: "text-sm" }
|
|
1163
1178
|
};
|
|
1164
|
-
function Checkbox({ checked, onChange, label, size = "md", disabled = false, indeterminate = false, className, ref }) {
|
|
1179
|
+
function Checkbox({ checked, onChange: onChangeProp, label, size = "md", disabled = false, indeterminate = false, className, ref, ...wiring }) {
|
|
1180
|
+
const onChange = useReportedChange(onChangeProp, checked);
|
|
1165
1181
|
const internalRef = useRef(null);
|
|
1166
1182
|
const dims = CHECKBOX_SIZES[size];
|
|
1183
|
+
const control = useFieldControl(wiring);
|
|
1167
1184
|
const mergedRef = useCallback(
|
|
1168
1185
|
(node) => {
|
|
1169
1186
|
internalRef.current = node;
|
|
@@ -1191,6 +1208,11 @@ function Checkbox({ checked, onChange, label, size = "md", disabled = false, ind
|
|
|
1191
1208
|
{
|
|
1192
1209
|
ref: mergedRef,
|
|
1193
1210
|
type: "checkbox",
|
|
1211
|
+
id: control.id,
|
|
1212
|
+
"aria-labelledby": wiring["aria-labelledby"],
|
|
1213
|
+
"aria-describedby": control.describedBy,
|
|
1214
|
+
"aria-invalid": control.invalid || void 0,
|
|
1215
|
+
required: control.required || void 0,
|
|
1194
1216
|
checked,
|
|
1195
1217
|
disabled,
|
|
1196
1218
|
onChange: (e) => onChange(e.target.checked),
|
|
@@ -1253,9 +1275,11 @@ function CheckboxGroupItem({ value, label, disabled, groupValue, onGroupChange }
|
|
|
1253
1275
|
}
|
|
1254
1276
|
);
|
|
1255
1277
|
}
|
|
1256
|
-
function RadioGroup({ value, onChange, options, orientation = "vertical", className, label }) {
|
|
1278
|
+
function RadioGroup({ value, onChange: onChangeProp, options, orientation = "vertical", className, label, ...wiring }) {
|
|
1279
|
+
const onChange = useReportedChange(onChangeProp, value);
|
|
1257
1280
|
const groupRef = useRef(null);
|
|
1258
1281
|
const groupId = useId();
|
|
1282
|
+
const control = useFieldControl(wiring);
|
|
1259
1283
|
const enabledOptions = options.filter((o) => !o.disabled);
|
|
1260
1284
|
const tabStop = rovingTabStop(options, (o) => o.value === value, (o) => !!o.disabled);
|
|
1261
1285
|
function handleKeyDown(e) {
|
|
@@ -1285,7 +1309,11 @@ function RadioGroup({ value, onChange, options, orientation = "vertical", classN
|
|
|
1285
1309
|
{
|
|
1286
1310
|
ref: groupRef,
|
|
1287
1311
|
role: "radiogroup",
|
|
1288
|
-
|
|
1312
|
+
id: control.id,
|
|
1313
|
+
"aria-labelledby": label ? groupId : control.labelId,
|
|
1314
|
+
"aria-describedby": control.describedBy,
|
|
1315
|
+
"aria-invalid": control.invalid || void 0,
|
|
1316
|
+
"aria-required": control.required || void 0,
|
|
1289
1317
|
className: cn(
|
|
1290
1318
|
"flex",
|
|
1291
1319
|
orientation === "vertical" ? "flex-col gap-ds-2" : "flex-row flex-wrap gap-ds-3"
|
|
@@ -1478,7 +1506,8 @@ function parseTypedDate(text, dayFirst = localeDayFirst()) {
|
|
|
1478
1506
|
}
|
|
1479
1507
|
return null;
|
|
1480
1508
|
}
|
|
1481
|
-
function DatePicker({ value, onChange, placeholder = "Pick a date", disabled, className, ref, container, error = false, label, id, size: sizeProp, min, max, range: range2, ...wiring }) {
|
|
1509
|
+
function DatePicker({ value, onChange: onChangeProp, placeholder = "Pick a date", disabled, className, ref, container, error = false, label, id, size: sizeProp, min, max, range: range2, ...wiring }) {
|
|
1510
|
+
const onChange = useReportedChange(onChangeProp, value);
|
|
1482
1511
|
const contextSize = useContext(ControlSizeContext);
|
|
1483
1512
|
const size = sizeProp ?? contextSize ?? "md";
|
|
1484
1513
|
const [open, setOpen] = useState(false);
|
|
@@ -1779,13 +1808,13 @@ function DatePicker({ value, onChange, placeholder = "Pick a date", disabled, cl
|
|
|
1779
1808
|
className: "flex items-center justify-between bg-[var(--ds-bg-muted)] rounded-t-[var(--ds-radius-md)]",
|
|
1780
1809
|
style: { padding: "var(--ds-space-2) var(--ds-space-3)" },
|
|
1781
1810
|
children: [
|
|
1782
|
-
/* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon-sm", onClick: prevMonth, "aria-label": "Previous month", children: /* @__PURE__ */ jsx(Icon, { name: "chevron-right", size: 14, className: "rotate-180" }) }),
|
|
1811
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", onClick: prevMonth, "aria-label": "Previous month", children: /* @__PURE__ */ jsx(Icon, { name: "chevron-right", size: 14, className: "rotate-180" }) }),
|
|
1783
1812
|
/* @__PURE__ */ jsxs("span", { className: "text-sm font-medium text-[var(--ds-text-primary)]", children: [
|
|
1784
1813
|
MONTHS[month],
|
|
1785
1814
|
" ",
|
|
1786
1815
|
year
|
|
1787
1816
|
] }),
|
|
1788
|
-
/* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon-sm", onClick: nextMonth, "aria-label": "Next month", children: /* @__PURE__ */ jsx(Icon, { name: "chevron-right", size: 14 }) })
|
|
1817
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", onClick: nextMonth, "aria-label": "Next month", children: /* @__PURE__ */ jsx(Icon, { name: "chevron-right", size: 14 }) })
|
|
1789
1818
|
]
|
|
1790
1819
|
}
|
|
1791
1820
|
),
|
|
@@ -1848,6 +1877,7 @@ function DatePicker({ value, onChange, placeholder = "Pick a date", disabled, cl
|
|
|
1848
1877
|
/* @__PURE__ */ jsx(
|
|
1849
1878
|
Button,
|
|
1850
1879
|
{
|
|
1880
|
+
type: "button",
|
|
1851
1881
|
variant: "ghost",
|
|
1852
1882
|
size: "sm",
|
|
1853
1883
|
onClick: () => {
|
|
@@ -1861,6 +1891,7 @@ function DatePicker({ value, onChange, placeholder = "Pick a date", disabled, cl
|
|
|
1861
1891
|
value && /* @__PURE__ */ jsx(
|
|
1862
1892
|
Button,
|
|
1863
1893
|
{
|
|
1894
|
+
type: "button",
|
|
1864
1895
|
variant: "ghost",
|
|
1865
1896
|
size: "sm",
|
|
1866
1897
|
onClick: () => choose(null),
|
|
@@ -2083,7 +2114,7 @@ var DEFAULT_DATE_RANGE_PRESETS = [
|
|
|
2083
2114
|
];
|
|
2084
2115
|
function DateRangePicker({
|
|
2085
2116
|
value,
|
|
2086
|
-
onChange,
|
|
2117
|
+
onChange: onChangeProp,
|
|
2087
2118
|
placeholder = "Pick a date range",
|
|
2088
2119
|
disabled,
|
|
2089
2120
|
error = false,
|
|
@@ -2099,6 +2130,7 @@ function DateRangePicker({
|
|
|
2099
2130
|
size: sizeProp,
|
|
2100
2131
|
...wiring
|
|
2101
2132
|
}) {
|
|
2133
|
+
const onChange = useReportedChange(onChangeProp, value);
|
|
2102
2134
|
const contextSize = useContext(ControlSizeContext);
|
|
2103
2135
|
const size = sizeProp ?? contextSize ?? "md";
|
|
2104
2136
|
const [open, setOpen] = useState(false);
|
|
@@ -2246,7 +2278,7 @@ function DateRangePicker({
|
|
|
2246
2278
|
),
|
|
2247
2279
|
style: { top: pos.top, left: pos.left },
|
|
2248
2280
|
children: [
|
|
2249
|
-
presets.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-ds-0.5 p-ds-2 border-r-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)] min-w-[140px]", children: presets.map((p) => /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", className: "justify-start", onClick: () => {
|
|
2281
|
+
presets.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-ds-0.5 p-ds-2 border-r-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)] min-w-[140px]", children: presets.map((p) => /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", className: "justify-start", onClick: () => {
|
|
2250
2282
|
const r = p.range();
|
|
2251
2283
|
returnFocus();
|
|
2252
2284
|
onChange(r);
|
|
@@ -2255,7 +2287,7 @@ function DateRangePicker({
|
|
|
2255
2287
|
}, children: p.label }, p.label)) }),
|
|
2256
2288
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
2257
2289
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between bg-[var(--ds-bg-muted)] rounded-tr-[var(--ds-radius-md)] px-ds-3 py-ds-2", children: [
|
|
2258
|
-
/* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon-sm", onClick: () => pageMonths(-1), "aria-label": "Previous month", children: /* @__PURE__ */ jsx(Icon, { name: "chevron-right", size: 14, className: "rotate-180" }) }),
|
|
2290
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", onClick: () => pageMonths(-1), "aria-label": "Previous month", children: /* @__PURE__ */ jsx(Icon, { name: "chevron-right", size: 14, className: "rotate-180" }) }),
|
|
2259
2291
|
/* @__PURE__ */ jsxs("span", { className: "text-sm font-medium text-[var(--ds-text-primary)]", children: [
|
|
2260
2292
|
MONTHS2[months[0].getMonth()],
|
|
2261
2293
|
" ",
|
|
@@ -2265,7 +2297,7 @@ function DateRangePicker({
|
|
|
2265
2297
|
" ",
|
|
2266
2298
|
months[1].getFullYear()
|
|
2267
2299
|
] }),
|
|
2268
|
-
/* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon-sm", onClick: () => pageMonths(1), "aria-label": "Next month", children: /* @__PURE__ */ jsx(Icon, { name: "chevron-right", size: 14 }) })
|
|
2300
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", onClick: () => pageMonths(1), "aria-label": "Next month", children: /* @__PURE__ */ jsx(Icon, { name: "chevron-right", size: 14 }) })
|
|
2269
2301
|
] }),
|
|
2270
2302
|
/* @__PURE__ */ jsx("div", { ref: gridRef, onKeyDown: grid.onKeyDown, className: "flex gap-ds-4 px-ds-3 py-ds-2", onMouseLeave: () => setHover(null), children: months.map((m) => /* @__PURE__ */ jsxs("div", { role: "grid", "aria-label": `${MONTHS2[m.getMonth()]} ${m.getFullYear()}`, className: "w-[224px] flex flex-col gap-ds-0.5", children: [
|
|
2271
2303
|
/* @__PURE__ */ jsx("div", { role: "row", className: "grid grid-cols-7 gap-ds-0.5 mb-ds-0.5", children: dayNames.map((d) => /* @__PURE__ */ jsx("div", { role: "columnheader", className: "text-center text-2xs font-medium text-[var(--ds-text-muted)] py-ds-1", children: d }, d)) }),
|
|
@@ -2306,7 +2338,7 @@ function DateRangePicker({
|
|
|
2306
2338
|
] }, `${m.getFullYear()}-${m.getMonth()}`)) }),
|
|
2307
2339
|
/* @__PURE__ */ jsxs("div", { className: "flex justify-between items-center bg-[var(--ds-bg-muted)] border-t-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)] rounded-br-[var(--ds-radius-md)] px-ds-3 py-ds-2", children: [
|
|
2308
2340
|
/* @__PURE__ */ jsx("span", { className: "text-xs text-[var(--ds-text-muted)]", children: value.start && !value.end ? "Now pick an end date" : summary ?? "Pick a start date" }),
|
|
2309
|
-
(value.start || value.end) && /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: () => {
|
|
2341
|
+
(value.start || value.end) && /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => {
|
|
2310
2342
|
onChange({ start: null, end: null });
|
|
2311
2343
|
setHover(null);
|
|
2312
2344
|
}, children: "Clear" })
|
|
@@ -2456,28 +2488,50 @@ function Progress({ value, max = 100, variant = "default", size = "md", indeterm
|
|
|
2456
2488
|
] })
|
|
2457
2489
|
] });
|
|
2458
2490
|
}
|
|
2491
|
+
|
|
2492
|
+
// ../../showcase/src/lib/dev-warn.ts
|
|
2493
|
+
var warned = /* @__PURE__ */ new Set();
|
|
2494
|
+
function warnOnce(component, message) {
|
|
2495
|
+
let dev = false;
|
|
2496
|
+
try {
|
|
2497
|
+
dev = process.env.NODE_ENV !== "production";
|
|
2498
|
+
} catch {
|
|
2499
|
+
dev = false;
|
|
2500
|
+
}
|
|
2501
|
+
const text = `${component}: ${message}`;
|
|
2502
|
+
if (!dev || warned.has(text)) return;
|
|
2503
|
+
warned.add(text);
|
|
2504
|
+
console.warn(text);
|
|
2505
|
+
}
|
|
2459
2506
|
function TruncFileName({ children, className }) {
|
|
2460
2507
|
const { ref, isTruncated } = useTextOverflow({ lines: 1 });
|
|
2461
2508
|
const el = /* @__PURE__ */ jsx("p", { ref, className: cn("truncate", className), children });
|
|
2462
2509
|
if (!isTruncated) return el;
|
|
2463
2510
|
return /* @__PURE__ */ jsx(Tooltip, { content: children, children: el });
|
|
2464
2511
|
}
|
|
2512
|
+
var PARALLEL = 3;
|
|
2465
2513
|
function formatSize(bytes) {
|
|
2466
2514
|
if (bytes < 1024) return `${bytes} B`;
|
|
2467
2515
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
2468
2516
|
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
2469
2517
|
}
|
|
2470
|
-
|
|
2471
|
-
|
|
2518
|
+
var running = (item) => item.status === "queued" || item.status === "uploading";
|
|
2519
|
+
var failureOf = (err) => err instanceof Error && err.message ? err.message : "The upload didn't work.";
|
|
2520
|
+
var percentOf = (value) => typeof value === "number" && Number.isFinite(value) ? Math.max(0, Math.min(100, value)) : 0;
|
|
2521
|
+
var STILL_UPLOADING = "Wait for your files to finish uploading";
|
|
2522
|
+
function FileUpload({ onFiles, files, upload, onCancel, onRetry, onRemove, accept, multiple = true, maxSize, className, error = false, label, id }) {
|
|
2523
|
+
const controlled = files !== void 0;
|
|
2524
|
+
const [own, setOwn] = useState([]);
|
|
2525
|
+
const shown = controlled ? files : own;
|
|
2472
2526
|
const [dragOver, setDragOver] = useState(false);
|
|
2473
2527
|
const [rejected, setRejected] = useState(null);
|
|
2474
2528
|
const inputRef = useRef(null);
|
|
2529
|
+
const listRef = useRef(null);
|
|
2475
2530
|
const nextEntryId = useRef(0);
|
|
2476
|
-
const
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
}, []);
|
|
2531
|
+
const controllers = useRef(/* @__PURE__ */ new Map());
|
|
2532
|
+
const uploadRef = useLatest(upload);
|
|
2533
|
+
const overlayMark = useContext(OverlayMarkCtx);
|
|
2534
|
+
const reportChange = useContext(FormChangeCtx);
|
|
2481
2535
|
const field = useField();
|
|
2482
2536
|
const ownId = useId();
|
|
2483
2537
|
const inputId = id ?? `${ownId}-input`;
|
|
@@ -2485,39 +2539,141 @@ function FileUpload({ onFiles, accept, multiple = true, maxSize, className, erro
|
|
|
2485
2539
|
const rejectedId = `${ownId}-rejected`;
|
|
2486
2540
|
const showLabel = label != null && !field;
|
|
2487
2541
|
const constraints = fileConstraints(accept, maxSize, multiple);
|
|
2488
|
-
const
|
|
2489
|
-
const
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2542
|
+
const patch = (itemId, change) => setOwn((prev) => prev.map((i) => i.id === itemId ? { ...i, ...change } : i));
|
|
2543
|
+
const stop = (itemId) => {
|
|
2544
|
+
controllers.current.get(itemId)?.abort();
|
|
2545
|
+
controllers.current.delete(itemId);
|
|
2546
|
+
};
|
|
2547
|
+
const start = (item) => {
|
|
2548
|
+
const run = uploadRef.current;
|
|
2549
|
+
if (!run || !item.file) return;
|
|
2550
|
+
const controller = new AbortController();
|
|
2551
|
+
controllers.current.set(item.id, controller);
|
|
2552
|
+
patch(item.id, { status: "uploading", progress: 0, error: void 0 });
|
|
2553
|
+
const settle = (change) => {
|
|
2554
|
+
if (controller.signal.aborted) return;
|
|
2555
|
+
controllers.current.delete(item.id);
|
|
2556
|
+
patch(item.id, change);
|
|
2557
|
+
};
|
|
2558
|
+
let attempt;
|
|
2559
|
+
try {
|
|
2560
|
+
attempt = Promise.resolve(run(item.file, {
|
|
2561
|
+
signal: controller.signal,
|
|
2562
|
+
onProgress: (percent) => {
|
|
2563
|
+
if (!controller.signal.aborted) patch(item.id, { progress: percentOf(percent) });
|
|
2564
|
+
}
|
|
2565
|
+
}));
|
|
2566
|
+
} catch (err) {
|
|
2567
|
+
attempt = Promise.reject(err);
|
|
2568
|
+
}
|
|
2569
|
+
attempt.then(() => settle({ status: "done", progress: 100 }), (err) => settle({ status: "error", error: failureOf(err) }));
|
|
2493
2570
|
};
|
|
2571
|
+
const [hadUpload, setHadUpload] = useState(!!upload);
|
|
2572
|
+
if (!controlled && !!upload !== hadUpload) {
|
|
2573
|
+
setHadUpload(!!upload);
|
|
2574
|
+
setOwn((prev) => prev.map((i) => upload ? i.status === "added" && i.file ? { ...i, status: "queued" } : i : i.status === "queued" ? { ...i, status: "error", error: "The upload couldn't start." } : i));
|
|
2575
|
+
}
|
|
2576
|
+
useEffect(() => {
|
|
2577
|
+
if (controlled || !upload) return;
|
|
2578
|
+
let active = own.filter((i) => i.status === "uploading" && controllers.current.has(i.id)).length;
|
|
2579
|
+
for (const item of own) {
|
|
2580
|
+
if (active >= PARALLEL) break;
|
|
2581
|
+
if (item.status === "queued" || item.status === "uploading" && !controllers.current.has(item.id)) {
|
|
2582
|
+
start(item);
|
|
2583
|
+
active++;
|
|
2584
|
+
}
|
|
2585
|
+
}
|
|
2586
|
+
}, [own, controlled, upload]);
|
|
2587
|
+
const stopAll = useCallback(() => {
|
|
2588
|
+
controllers.current.forEach((c) => c.abort());
|
|
2589
|
+
controllers.current.clear();
|
|
2590
|
+
}, []);
|
|
2591
|
+
useEffect(() => stopAll, [stopAll]);
|
|
2592
|
+
const overlayOpen = overlayMark?.open ?? true;
|
|
2593
|
+
const [wasOpen, setWasOpen] = useState(overlayOpen);
|
|
2594
|
+
if (overlayOpen !== wasOpen) {
|
|
2595
|
+
setWasOpen(overlayOpen);
|
|
2596
|
+
if (!overlayOpen && !controlled) setOwn((prev) => prev.filter((i) => !running(i)));
|
|
2597
|
+
}
|
|
2598
|
+
useEffect(() => {
|
|
2599
|
+
if (!overlayOpen && !controlled) stopAll();
|
|
2600
|
+
}, [overlayOpen, controlled, stopAll]);
|
|
2601
|
+
const busy = shown.some((i) => i.status === "uploading" || i.status === "queued" && (controlled || !!upload));
|
|
2602
|
+
useEffect(() => {
|
|
2603
|
+
if (!busy || !overlayMark) return;
|
|
2604
|
+
return overlayMark.hold();
|
|
2605
|
+
}, [busy, overlayMark]);
|
|
2606
|
+
const form = useOptionalFormContext();
|
|
2607
|
+
const waitingKey = `${inputId}-uploads`;
|
|
2608
|
+
const waitingId = `${ownId}-waiting`;
|
|
2609
|
+
const busyRef = useLatest(busy);
|
|
2610
|
+
const registerCheck = form?.register;
|
|
2611
|
+
useEffect(() => registerCheck?.(waitingKey, () => busyRef.current ? STILL_UPLOADING : void 0), [registerCheck, waitingKey, busyRef]);
|
|
2612
|
+
const waiting = form?.errors[waitingKey];
|
|
2613
|
+
const clearWaiting = form?.setError;
|
|
2614
|
+
useEffect(() => {
|
|
2615
|
+
if (!busy && waiting) clearWaiting?.(waitingKey, void 0);
|
|
2616
|
+
}, [busy, waiting, clearWaiting, waitingKey]);
|
|
2617
|
+
useEffect(() => {
|
|
2618
|
+
const owner = inputRef.current?.form;
|
|
2619
|
+
if (!owner) return;
|
|
2620
|
+
const clear = () => setRejected(null);
|
|
2621
|
+
owner.addEventListener("submit", clear);
|
|
2622
|
+
return () => owner.removeEventListener("submit", clear);
|
|
2623
|
+
}, []);
|
|
2624
|
+
const invalid = error || rejected != null || !!waiting;
|
|
2625
|
+
const describedBy = [constraints ? constraintsId : null, field?.describedBy, rejected ? rejectedId : null, waiting ? waitingId : null].filter(Boolean).join(" ") || void 0;
|
|
2626
|
+
useEffect(() => {
|
|
2627
|
+
if (controlled && !onFiles) warnOnce("FileUpload", "`files` without `onFiles`: the page's list never gets the files the user picks. Add them in onFiles.");
|
|
2628
|
+
if (controlled && upload) warnOnce("FileUpload", "pass `files` or `upload`, not both: with `files` the page runs the uploads and FileUpload shows them.");
|
|
2629
|
+
if (!onRemove) warnOnce("FileUpload", "no `onRemove`: Remove shows only on a failed file, since the page would still have a file the user removed.");
|
|
2630
|
+
const ids = shown.map((i) => i.id);
|
|
2631
|
+
if (new Set(ids).size !== ids.length) warnOnce("FileUpload", "two files in the list share an id: give each file its own (the same file picked twice is two files).");
|
|
2632
|
+
}, [controlled, onFiles, upload, onRemove, shown]);
|
|
2633
|
+
const [heard, setHeard] = useState({ text: "", n: 0 });
|
|
2634
|
+
const signature2 = shown.map((i) => `${i.id}\0${i.status}`).join("");
|
|
2635
|
+
const [seen, setSeen] = useState(() => ({ signature: signature2, statuses: new Map(shown.map((i) => [i.id, i.status])) }));
|
|
2636
|
+
if (signature2 !== seen.signature) {
|
|
2637
|
+
const said = [];
|
|
2638
|
+
for (const item of shown) {
|
|
2639
|
+
const before = seen.statuses.get(item.id);
|
|
2640
|
+
if (!before || before === item.status) continue;
|
|
2641
|
+
if (item.status === "done") said.push(`${item.name} uploaded`);
|
|
2642
|
+
else if (item.status === "error") said.push(`${item.name} didn't upload: ${item.error ?? "the upload failed"}`);
|
|
2643
|
+
}
|
|
2644
|
+
setSeen({ signature: signature2, statuses: new Map(shown.map((i) => [i.id, i.status])) });
|
|
2645
|
+
if (said.length) setHeard((h) => ({ text: said.join(". "), n: h.n + 1 }));
|
|
2646
|
+
}
|
|
2647
|
+
const pendingFocus = useRef(null);
|
|
2648
|
+
const lastAction = useRef(null);
|
|
2649
|
+
useEffect(() => {
|
|
2650
|
+
const gone = pendingFocus.current;
|
|
2651
|
+
if (gone && !shown.some((i) => i.id === gone.id)) {
|
|
2652
|
+
pendingFocus.current = null;
|
|
2653
|
+
const rows = Array.from(listRef.current?.querySelectorAll(":scope > li") ?? []).map((row2) => row2.querySelector("button")).filter((b) => !!b);
|
|
2654
|
+
focusAfterRemoval(rows, gone.index, inputRef.current);
|
|
2655
|
+
return;
|
|
2656
|
+
}
|
|
2657
|
+
const last = lastAction.current;
|
|
2658
|
+
const active = document.activeElement;
|
|
2659
|
+
if (!last || last.el.isConnected || active && active !== document.body) return;
|
|
2660
|
+
const row = Array.from(listRef.current?.querySelectorAll(":scope > li") ?? []).find((li) => li.dataset.uploadId === last.id);
|
|
2661
|
+
row?.querySelector("button")?.focus();
|
|
2662
|
+
}, [shown]);
|
|
2494
2663
|
const addFiles = useCallback(
|
|
2495
2664
|
(fileList) => {
|
|
2496
2665
|
const { accepted, message } = checkFiles(Array.from(fileList), { accept, maxSize, multiple });
|
|
2497
2666
|
setRejected(message);
|
|
2498
2667
|
if (accepted.length === 0) return;
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
}
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
for (const { id: id2 } of entries) {
|
|
2507
|
-
let progress = 0;
|
|
2508
|
-
const timer = setInterval(() => {
|
|
2509
|
-
progress = Math.min(100, progress + Math.random() * 30 + 10);
|
|
2510
|
-
const done = progress >= 100;
|
|
2511
|
-
if (done) {
|
|
2512
|
-
clearInterval(timer);
|
|
2513
|
-
timers.current.delete(id2);
|
|
2514
|
-
}
|
|
2515
|
-
setFiles((prev) => prev.map((f) => f.id === id2 ? { ...f, progress, status: done ? "complete" : "uploading" } : f));
|
|
2516
|
-
}, 300);
|
|
2517
|
-
timers.current.set(id2, timer);
|
|
2518
|
-
}
|
|
2668
|
+
reportChange?.();
|
|
2669
|
+
onFiles?.(accepted);
|
|
2670
|
+
if (controlled) return;
|
|
2671
|
+
const status = uploadRef.current ? "queued" : "added";
|
|
2672
|
+
const entries = accepted.map((file) => ({ id: `${ownId}-file-${nextEntryId.current++}`, name: file.name, size: file.size, status, file }));
|
|
2673
|
+
if (!multiple) stopAll();
|
|
2674
|
+
setOwn((prev) => multiple ? [...prev, ...entries] : entries);
|
|
2519
2675
|
},
|
|
2520
|
-
[accept, maxSize, multiple, onFiles]
|
|
2676
|
+
[accept, maxSize, multiple, onFiles, controlled, ownId, reportChange, stopAll, uploadRef]
|
|
2521
2677
|
);
|
|
2522
2678
|
const handleDrop = useCallback(
|
|
2523
2679
|
(e) => {
|
|
@@ -2527,10 +2683,31 @@ function FileUpload({ onFiles, accept, multiple = true, maxSize, className, erro
|
|
|
2527
2683
|
},
|
|
2528
2684
|
[addFiles]
|
|
2529
2685
|
);
|
|
2530
|
-
const
|
|
2531
|
-
|
|
2532
|
-
|
|
2686
|
+
const indexOf = (item) => shown.findIndex((i) => i.id === item.id);
|
|
2687
|
+
const cancel = (item) => {
|
|
2688
|
+
pendingFocus.current = { id: item.id, index: indexOf(item) };
|
|
2689
|
+
if (!controlled) {
|
|
2690
|
+
stop(item.id);
|
|
2691
|
+
setOwn((prev) => prev.filter((i) => i.id !== item.id));
|
|
2692
|
+
}
|
|
2693
|
+
onCancel?.(item);
|
|
2533
2694
|
};
|
|
2695
|
+
const retry = (item) => {
|
|
2696
|
+
if (!controlled) patch(item.id, { status: "queued", progress: 0, error: void 0 });
|
|
2697
|
+
onRetry?.(item);
|
|
2698
|
+
};
|
|
2699
|
+
const remove = (item) => {
|
|
2700
|
+
pendingFocus.current = { id: item.id, index: indexOf(item) };
|
|
2701
|
+
reportChange?.();
|
|
2702
|
+
if (!controlled) {
|
|
2703
|
+
stop(item.id);
|
|
2704
|
+
setOwn((prev) => prev.filter((i) => i.id !== item.id));
|
|
2705
|
+
}
|
|
2706
|
+
onRemove?.(item);
|
|
2707
|
+
};
|
|
2708
|
+
const canCancel = !controlled || !!onCancel;
|
|
2709
|
+
const canRetry = !controlled || !!onRetry;
|
|
2710
|
+
const canRemove = (item) => !!onRemove || !controlled && item.status === "error";
|
|
2534
2711
|
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-ds-3", className), children: [
|
|
2535
2712
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-ds-1.5", children: [
|
|
2536
2713
|
showLabel && /* @__PURE__ */ jsx(Label, { htmlFor: inputId, children: label }),
|
|
@@ -2584,35 +2761,51 @@ function FileUpload({ onFiles, accept, multiple = true, maxSize, className, erro
|
|
|
2584
2761
|
]
|
|
2585
2762
|
}
|
|
2586
2763
|
),
|
|
2587
|
-
rejected && /* @__PURE__ */ jsx(InlineFieldError, { id: rejectedId, message: rejected, className: "mt-0" })
|
|
2764
|
+
rejected && /* @__PURE__ */ jsx(InlineFieldError, { id: rejectedId, message: rejected, className: "mt-0" }),
|
|
2765
|
+
waiting && /* @__PURE__ */ jsx(InlineFieldError, { id: waitingId, message: waiting, className: "mt-0" })
|
|
2588
2766
|
] }),
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
{
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
"
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2767
|
+
shown.length > 0 && /* @__PURE__ */ jsx("ul", { ref: listRef, className: "space-y-ds-2", children: shown.map((item) => {
|
|
2768
|
+
const progress = percentOf(item.progress);
|
|
2769
|
+
const words = item.status === "queued" ? "Waiting" : item.status === "uploading" ? `${Math.round(progress)}%` : item.status === "done" ? "Uploaded" : item.status === "error" ? "Failed" : null;
|
|
2770
|
+
return /* @__PURE__ */ jsxs(
|
|
2771
|
+
"li",
|
|
2772
|
+
{
|
|
2773
|
+
"data-upload-id": item.id,
|
|
2774
|
+
"data-upload-status": item.status,
|
|
2775
|
+
onFocus: (e) => {
|
|
2776
|
+
if (e.target instanceof HTMLButtonElement) lastAction.current = { id: item.id, el: e.target };
|
|
2777
|
+
},
|
|
2778
|
+
className: cn(
|
|
2779
|
+
"flex items-center gap-ds-3 text-sm",
|
|
2780
|
+
"border-[length:var(--ds-border-width)]",
|
|
2781
|
+
item.status === "error" ? "border-[var(--ds-status-error)]" : "border-[var(--ds-border-subtle)]",
|
|
2782
|
+
"rounded-[var(--ds-radius-md)] bg-[var(--ds-bg-surface)]"
|
|
2783
|
+
),
|
|
2784
|
+
style: { padding: "var(--ds-space-3)" },
|
|
2785
|
+
children: [
|
|
2786
|
+
/* @__PURE__ */ jsx(Icon, { name: "folder", size: 16, className: "text-[var(--ds-text-muted)] shrink-0" }),
|
|
2787
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
2788
|
+
/* @__PURE__ */ jsx(TruncFileName, { className: "text-[var(--ds-text-primary)]", children: item.name }),
|
|
2789
|
+
(item.size != null || words) && /* @__PURE__ */ jsx("p", { className: "text-xs text-[var(--ds-text-muted)]", children: [item.size != null ? formatSize(item.size) : null, words].filter(Boolean).join(" \xB7 ") }),
|
|
2790
|
+
item.status === "uploading" && /* @__PURE__ */ jsx(Progress, { value: progress, size: "sm", label: `Uploading ${item.name}`, className: "mt-ds-1" }),
|
|
2791
|
+
item.status === "error" && /* @__PURE__ */ jsx("p", { className: "mt-ds-1 text-xs text-[var(--ds-status-error)]", children: item.error ?? "The upload didn't work." })
|
|
2792
|
+
] }),
|
|
2793
|
+
item.status === "done" && /* @__PURE__ */ jsx(Icon, { name: "check", size: 16, className: "text-[var(--ds-status-success)] shrink-0", "aria-hidden": "true" }),
|
|
2794
|
+
running(item) && canCancel && // the visible word starts the name, which says which file (WCAG 2.5.3)
|
|
2795
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => cancel(item), "aria-label": `Cancel ${item.name}`, children: "Cancel" }),
|
|
2796
|
+
item.status === "error" && canRetry && /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => retry(item), "aria-label": `Retry ${item.name}`, children: "Retry" }),
|
|
2797
|
+
!running(item) && canRemove(item) && /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", onClick: () => remove(item), "aria-label": `Remove ${item.name}`, children: /* @__PURE__ */ jsx(Icon, { name: "close", size: 14 }) })
|
|
2798
|
+
]
|
|
2799
|
+
},
|
|
2800
|
+
item.id
|
|
2801
|
+
);
|
|
2802
|
+
}) }),
|
|
2803
|
+
/* @__PURE__ */ jsx("div", { role: "status", className: "sr-only", children: /* @__PURE__ */ jsx("span", { children: heard.text }, heard.n) })
|
|
2611
2804
|
] });
|
|
2612
2805
|
}
|
|
2613
2806
|
function SliderRange({
|
|
2614
2807
|
value,
|
|
2615
|
-
onChange,
|
|
2808
|
+
onChange: onChangeProp,
|
|
2616
2809
|
min = 0,
|
|
2617
2810
|
max = 100,
|
|
2618
2811
|
step = 1,
|
|
@@ -2627,6 +2820,7 @@ function SliderRange({
|
|
|
2627
2820
|
trackStyle,
|
|
2628
2821
|
formatValue
|
|
2629
2822
|
}) {
|
|
2823
|
+
const onChange = useReportedChange(onChangeProp, value);
|
|
2630
2824
|
const field = useField();
|
|
2631
2825
|
const ownId = useId();
|
|
2632
2826
|
const showLabel = label != null && !field;
|
|
@@ -2832,7 +3026,7 @@ function parseTime(value) {
|
|
|
2832
3026
|
}
|
|
2833
3027
|
function TimePicker({
|
|
2834
3028
|
value,
|
|
2835
|
-
onChange,
|
|
3029
|
+
onChange: onChangeProp,
|
|
2836
3030
|
use24Hour = false,
|
|
2837
3031
|
minuteStep = 15,
|
|
2838
3032
|
disabled,
|
|
@@ -2844,6 +3038,7 @@ function TimePicker({
|
|
|
2844
3038
|
size: sizeProp,
|
|
2845
3039
|
...wiring
|
|
2846
3040
|
}) {
|
|
3041
|
+
const onChange = useReportedChange(onChangeProp, value);
|
|
2847
3042
|
const contextSize = useContext(ControlSizeContext);
|
|
2848
3043
|
const control = useFieldControl({ ...wiring, id, error: error || void 0 }, { requiredInDescription: true });
|
|
2849
3044
|
const size = sizeProp ?? contextSize ?? "md";
|
|
@@ -3222,7 +3417,7 @@ var sizes = {
|
|
|
3222
3417
|
};
|
|
3223
3418
|
function NumberInput({
|
|
3224
3419
|
value,
|
|
3225
|
-
onChange,
|
|
3420
|
+
onChange: onChangeProp,
|
|
3226
3421
|
min = -Infinity,
|
|
3227
3422
|
max = Infinity,
|
|
3228
3423
|
step = 1,
|
|
@@ -3236,6 +3431,7 @@ function NumberInput({
|
|
|
3236
3431
|
allowDecimals,
|
|
3237
3432
|
id
|
|
3238
3433
|
}) {
|
|
3434
|
+
const onChange = useReportedChange(onChangeProp, value);
|
|
3239
3435
|
const contextSize = useContext(ControlSizeContext);
|
|
3240
3436
|
const size = sizeProp ?? contextSize ?? "md";
|
|
3241
3437
|
const intervalRef = useRef(void 0);
|
|
@@ -3254,13 +3450,13 @@ function NumberInput({
|
|
|
3254
3450
|
[min, max]
|
|
3255
3451
|
);
|
|
3256
3452
|
const valueRef = useLatest(value);
|
|
3257
|
-
const commitValue = useCallback((v) => {
|
|
3453
|
+
const commitValue = useCallback((v, own = false) => {
|
|
3258
3454
|
const clamped = clamp(v);
|
|
3259
3455
|
valueRef.current = clamped;
|
|
3260
3456
|
setDraft(String(clamped));
|
|
3261
|
-
onChange(clamped);
|
|
3457
|
+
(own ? onChangeProp : onChange)(clamped);
|
|
3262
3458
|
return clamped;
|
|
3263
|
-
}, [onChange, clamp, valueRef]);
|
|
3459
|
+
}, [onChange, onChangeProp, clamp, valueRef]);
|
|
3264
3460
|
const increment = useCallback(() => commitValue(valueRef.current + step), [commitValue, step, valueRef]);
|
|
3265
3461
|
const decrement = useCallback(() => commitValue(valueRef.current - step), [commitValue, step, valueRef]);
|
|
3266
3462
|
const startRepeat = useCallback(
|
|
@@ -3298,11 +3494,11 @@ function NumberInput({
|
|
|
3298
3494
|
setFocused(false);
|
|
3299
3495
|
const parsed = parseFloat(draft);
|
|
3300
3496
|
if (!isNaN(parsed) && isFinite(parsed)) {
|
|
3301
|
-
const committed = commitValue(parsed);
|
|
3497
|
+
const committed = commitValue(parsed, draft === String(value));
|
|
3302
3498
|
setDraft(String(committed));
|
|
3303
3499
|
} else {
|
|
3304
3500
|
const fallback = isFinite(min) ? min : 0;
|
|
3305
|
-
const committed = commitValue(value !== void 0 ? value : fallback);
|
|
3501
|
+
const committed = commitValue(value !== void 0 ? value : fallback, true);
|
|
3306
3502
|
setDraft(String(committed));
|
|
3307
3503
|
}
|
|
3308
3504
|
}, [draft, commitValue, min, value]);
|
|
@@ -3543,7 +3739,7 @@ var Tag = forwardRef(function Tag2({
|
|
|
3543
3739
|
});
|
|
3544
3740
|
function TagInput({
|
|
3545
3741
|
value,
|
|
3546
|
-
onChange,
|
|
3742
|
+
onChange: onChangeProp,
|
|
3547
3743
|
placeholder = "Add a tag...",
|
|
3548
3744
|
maxTags = Infinity,
|
|
3549
3745
|
disabled = false,
|
|
@@ -3552,6 +3748,7 @@ function TagInput({
|
|
|
3552
3748
|
id,
|
|
3553
3749
|
"aria-label": ariaLabel
|
|
3554
3750
|
}) {
|
|
3751
|
+
const onChange = useReportedChange(onChangeProp, value);
|
|
3555
3752
|
const [input, setInput] = useState("");
|
|
3556
3753
|
const inputRef = useRef(null);
|
|
3557
3754
|
const addTag = useCallback(
|
|
@@ -3677,7 +3874,7 @@ var sizes2 = {
|
|
|
3677
3874
|
};
|
|
3678
3875
|
function PinInput({
|
|
3679
3876
|
value,
|
|
3680
|
-
onChange,
|
|
3877
|
+
onChange: onChangeProp,
|
|
3681
3878
|
length = 6,
|
|
3682
3879
|
mask = false,
|
|
3683
3880
|
disabled = false,
|
|
@@ -3686,6 +3883,7 @@ function PinInput({
|
|
|
3686
3883
|
error = false,
|
|
3687
3884
|
id
|
|
3688
3885
|
}) {
|
|
3886
|
+
const onChange = useReportedChange(onChangeProp, value);
|
|
3689
3887
|
const contextSize = useContext(ControlSizeContext);
|
|
3690
3888
|
const size = sizeProp ?? contextSize ?? "md";
|
|
3691
3889
|
const inputsRef = useRef([]);
|
|
@@ -3821,23 +4019,26 @@ function StarIcon({ filled, half, size }) {
|
|
|
3821
4019
|
}
|
|
3822
4020
|
function Rating({
|
|
3823
4021
|
value,
|
|
3824
|
-
onChange,
|
|
4022
|
+
onChange: onChangeProp,
|
|
3825
4023
|
max = 5,
|
|
3826
4024
|
allowHalf = false,
|
|
3827
4025
|
readOnly = false,
|
|
3828
4026
|
size = "md",
|
|
3829
4027
|
className,
|
|
3830
|
-
error = false
|
|
4028
|
+
error = false,
|
|
4029
|
+
...wiring
|
|
3831
4030
|
}) {
|
|
4031
|
+
const onChange = useReportedChange(onChangeProp, value);
|
|
3832
4032
|
const [hoverValue, setHoverValue] = useState(null);
|
|
3833
4033
|
const displayValue = hoverValue ?? value;
|
|
4034
|
+
const control = useFieldControl({ ...wiring, error: error || void 0 });
|
|
3834
4035
|
const handleClick = useCallback(
|
|
3835
4036
|
(starIdx, isLeftHalf) => {
|
|
3836
|
-
if (readOnly || !
|
|
4037
|
+
if (readOnly || !onChangeProp) return;
|
|
3837
4038
|
const newValue = allowHalf && isLeftHalf ? starIdx + 0.5 : starIdx + 1;
|
|
3838
4039
|
onChange(newValue === value ? 0 : newValue);
|
|
3839
4040
|
},
|
|
3840
|
-
[readOnly, onChange, allowHalf, value]
|
|
4041
|
+
[readOnly, onChangeProp, onChange, allowHalf, value]
|
|
3841
4042
|
);
|
|
3842
4043
|
const handleMouseMove = useCallback(
|
|
3843
4044
|
(starIdx, e) => {
|
|
@@ -3851,7 +4052,7 @@ function Rating({
|
|
|
3851
4052
|
const iconSize = iconSizes[size];
|
|
3852
4053
|
const step = allowHalf ? 0.5 : 1;
|
|
3853
4054
|
const handleKeyDown = (e) => {
|
|
3854
|
-
if (readOnly || !
|
|
4055
|
+
if (readOnly || !onChangeProp) return;
|
|
3855
4056
|
let next = null;
|
|
3856
4057
|
if (e.key === "ArrowRight" || e.key === "ArrowUp") next = Math.min(max, value + step);
|
|
3857
4058
|
else if (e.key === "ArrowLeft" || e.key === "ArrowDown") next = Math.max(0, value - step);
|
|
@@ -3897,8 +4098,12 @@ function Rating({
|
|
|
3897
4098
|
"div",
|
|
3898
4099
|
{
|
|
3899
4100
|
role: readOnly ? "img" : "radiogroup",
|
|
3900
|
-
|
|
3901
|
-
"aria-
|
|
4101
|
+
id: control.id,
|
|
4102
|
+
"aria-label": readOnly || !control.labelId ? `Rating: ${value} out of ${max}` : void 0,
|
|
4103
|
+
"aria-labelledby": readOnly ? void 0 : control.labelId,
|
|
4104
|
+
"aria-describedby": control.describedBy,
|
|
4105
|
+
"aria-invalid": readOnly ? void 0 : control.invalid || void 0,
|
|
4106
|
+
"aria-required": readOnly ? void 0 : control.required || void 0,
|
|
3902
4107
|
onKeyDown: readOnly ? void 0 : handleKeyDown,
|
|
3903
4108
|
className: cn(
|
|
3904
4109
|
"inline-flex items-center gap-ds-0.5",
|
|
@@ -3975,13 +4180,14 @@ var DEFAULT_SWATCHES = [
|
|
|
3975
4180
|
];
|
|
3976
4181
|
function ColorPicker({
|
|
3977
4182
|
value,
|
|
3978
|
-
onChange,
|
|
4183
|
+
onChange: onChangeProp,
|
|
3979
4184
|
showAlpha = false,
|
|
3980
4185
|
swatches = DEFAULT_SWATCHES,
|
|
3981
4186
|
disabled = false,
|
|
3982
4187
|
className,
|
|
3983
4188
|
error = false
|
|
3984
4189
|
}) {
|
|
4190
|
+
const onChange = useReportedChange(onChangeProp, value);
|
|
3985
4191
|
const [hsl, setHsl] = useState(() => hexToHsl(value));
|
|
3986
4192
|
const [hexInput, setHexInput] = useState(value);
|
|
3987
4193
|
const satLightRef = useRef(null);
|
|
@@ -4222,6 +4428,7 @@ var Alert = forwardRef(function Alert2({
|
|
|
4222
4428
|
trigger: /* @__PURE__ */ jsx(
|
|
4223
4429
|
"button",
|
|
4224
4430
|
{
|
|
4431
|
+
type: "button",
|
|
4225
4432
|
className: cn(
|
|
4226
4433
|
"shrink-0 text-xs font-medium px-ds-2.5 py-ds-1 rounded-[var(--ds-radius-sm)]",
|
|
4227
4434
|
"transition-colors cursor-pointer",
|
|
@@ -4246,6 +4453,7 @@ var Alert = forwardRef(function Alert2({
|
|
|
4246
4453
|
return /* @__PURE__ */ jsxs(
|
|
4247
4454
|
"button",
|
|
4248
4455
|
{
|
|
4456
|
+
type: "button",
|
|
4249
4457
|
onClick: a.onClick,
|
|
4250
4458
|
className: cn(
|
|
4251
4459
|
"shrink-0 text-xs font-medium px-ds-2.5 py-ds-1 rounded-[var(--ds-radius-sm)]",
|
|
@@ -4266,6 +4474,7 @@ var Alert = forwardRef(function Alert2({
|
|
|
4266
4474
|
/* @__PURE__ */ jsxs(
|
|
4267
4475
|
"button",
|
|
4268
4476
|
{
|
|
4477
|
+
type: "button",
|
|
4269
4478
|
onClick: () => setDetailsExpanded(!detailsExpanded),
|
|
4270
4479
|
"aria-expanded": detailsExpanded,
|
|
4271
4480
|
className: cn(
|
|
@@ -4293,6 +4502,7 @@ var Alert = forwardRef(function Alert2({
|
|
|
4293
4502
|
dismissible && /* @__PURE__ */ jsx(
|
|
4294
4503
|
"button",
|
|
4295
4504
|
{
|
|
4505
|
+
type: "button",
|
|
4296
4506
|
onClick: onDismiss,
|
|
4297
4507
|
className: "shrink-0 text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)] transition-colors cursor-pointer",
|
|
4298
4508
|
"aria-label": "Dismiss",
|
|
@@ -4303,6 +4513,7 @@ var Alert = forwardRef(function Alert2({
|
|
|
4303
4513
|
}
|
|
4304
4514
|
);
|
|
4305
4515
|
});
|
|
4516
|
+
var isThenable = (value) => !!value && typeof value.then === "function";
|
|
4306
4517
|
function stampFormId(node, formId) {
|
|
4307
4518
|
return Children.map(node, (child) => {
|
|
4308
4519
|
if (!isValidElement(child)) return child;
|
|
@@ -4359,12 +4570,19 @@ function FormWrapper({ onSubmit, validationMode: validationModeProp, children, a
|
|
|
4359
4570
|
const pendingSubmit = useRef(false);
|
|
4360
4571
|
const pendingFocus = useRef(false);
|
|
4361
4572
|
const onSubmitRef = useLatest(onSubmit);
|
|
4573
|
+
const overlayMark = useContext(OverlayMarkCtx);
|
|
4574
|
+
const reportChange = useMemo(() => overlayMark ? () => overlayMark.report(formId) : null, [overlayMark, formId]);
|
|
4575
|
+
useEffect(() => overlayMark?.attach(formId), [overlayMark, formId]);
|
|
4362
4576
|
useEffect(() => {
|
|
4363
4577
|
if (pendingSubmit.current && submitted) {
|
|
4364
4578
|
pendingSubmit.current = false;
|
|
4365
|
-
|
|
4579
|
+
const answer = overlayMark?.submit(formId, { element: () => formRef.current, failing: () => Object.keys(errorsRef.current).length > 0 });
|
|
4580
|
+
const result = onSubmitRef.current(errorsRef.current);
|
|
4581
|
+
if (!answer) return;
|
|
4582
|
+
if (isThenable(result)) void result.then(() => answer.settle("resolved"));
|
|
4583
|
+
else answer.settle("returned");
|
|
4366
4584
|
}
|
|
4367
|
-
}, [submitted, submitCount, errors, errorsRef, onSubmitRef]);
|
|
4585
|
+
}, [submitted, submitCount, errors, errorsRef, onSubmitRef, overlayMark, formId]);
|
|
4368
4586
|
const submittedRef = useLatest(submitted);
|
|
4369
4587
|
const errorSummaryRef = useLatest(errorSummary);
|
|
4370
4588
|
const summaryRef = useRef(null);
|
|
@@ -4418,7 +4636,15 @@ function FormWrapper({ onSubmit, validationMode: validationModeProp, children, a
|
|
|
4418
4636
|
pendingFocus.current = false;
|
|
4419
4637
|
}, []);
|
|
4420
4638
|
const setError = useCallback((field, message) => {
|
|
4421
|
-
setErrors((prev) =>
|
|
4639
|
+
setErrors((prev) => {
|
|
4640
|
+
if (!message) {
|
|
4641
|
+
if (!(field in prev)) return prev;
|
|
4642
|
+
const next = { ...prev };
|
|
4643
|
+
delete next[field];
|
|
4644
|
+
return next;
|
|
4645
|
+
}
|
|
4646
|
+
return prev[field] === message ? prev : { ...prev, [field]: message };
|
|
4647
|
+
});
|
|
4422
4648
|
}, []);
|
|
4423
4649
|
const checks = useRef(/* @__PURE__ */ new Map());
|
|
4424
4650
|
const register = useCallback((field, check) => {
|
|
@@ -4441,11 +4667,20 @@ function FormWrapper({ onSubmit, validationMode: validationModeProp, children, a
|
|
|
4441
4667
|
}, []);
|
|
4442
4668
|
const handleSubmit = useCallback(
|
|
4443
4669
|
(e) => {
|
|
4670
|
+
if (e.target !== e.currentTarget) return;
|
|
4444
4671
|
e.preventDefault();
|
|
4672
|
+
e.stopPropagation();
|
|
4445
4673
|
if (checks.current.size > 0) {
|
|
4446
|
-
const found =
|
|
4447
|
-
for (const [field, check] of checks.current) found
|
|
4448
|
-
setErrors((prev) =>
|
|
4674
|
+
const found = /* @__PURE__ */ new Map();
|
|
4675
|
+
for (const [field, check] of checks.current) found.set(field, check());
|
|
4676
|
+
setErrors((prev) => {
|
|
4677
|
+
const next = { ...prev };
|
|
4678
|
+
for (const [field, message] of found) {
|
|
4679
|
+
if (message) next[field] = message;
|
|
4680
|
+
else delete next[field];
|
|
4681
|
+
}
|
|
4682
|
+
return next;
|
|
4683
|
+
});
|
|
4449
4684
|
}
|
|
4450
4685
|
pendingSubmit.current = true;
|
|
4451
4686
|
pendingFocus.current = focusFirstError;
|
|
@@ -4468,22 +4703,79 @@ function FormWrapper({ onSubmit, validationMode: validationModeProp, children, a
|
|
|
4468
4703
|
f.message
|
|
4469
4704
|
] }, f.id || f.label)) }) }) : null;
|
|
4470
4705
|
const actionsNode = actions && !drawerFooter ? /* @__PURE__ */ jsx("div", { "data-form-actions": "", className: cn("flex flex-wrap items-center gap-ds-2 pt-ds-2", actionsAlign === "end" ? "justify-end" : "justify-start"), children: actions }) : null;
|
|
4471
|
-
return /* @__PURE__ */ jsx(FormCtx.Provider, { value: { errors, setError, clearErrors, validationMode, submitted, register }, children: /* @__PURE__ */ jsxs("form", { ref: setRefs, id: drawerFooter ? formId : void 0, onSubmit: handleSubmit, onFocusCapture: userActed, onInputCapture: userActed, className: cn("flex flex-col gap-ds-5 max-w-[var(--ds-form-max,none)]", className), noValidate: true, children: [
|
|
4706
|
+
return /* @__PURE__ */ jsx(FormCtx.Provider, { value: { errors, setError, clearErrors, validationMode, submitted, register }, children: /* @__PURE__ */ jsx(FormChangeCtx.Provider, { value: reportChange, children: /* @__PURE__ */ jsxs("form", { ref: setRefs, id: drawerFooter ? formId : void 0, onSubmit: handleSubmit, onFocusCapture: userActed, onInputCapture: userActed, className: cn("flex flex-col gap-ds-5 max-w-[var(--ds-form-max,none)]", className), noValidate: true, children: [
|
|
4472
4707
|
summaryNode && /* @__PURE__ */ jsx("div", { ref: summaryRef, "data-form-error-summary": "", tabIndex: -1, className: "rounded-[var(--ds-radius-md)] outline-none focus-visible:shadow-[var(--ds-shadow-focus)]", children: summaryNode }),
|
|
4473
4708
|
children,
|
|
4474
4709
|
actionsNode
|
|
4475
|
-
] }) });
|
|
4710
|
+
] }) }) });
|
|
4711
|
+
}
|
|
4712
|
+
var FOCUSABLE2 = "input:not([disabled]):not([type='hidden']), select:not([disabled]), textarea:not([disabled]), [role='combobox'], [role='switch'], [role='radio'], [tabindex]:not([tabindex='-1'])";
|
|
4713
|
+
function AddAnother({ items, getId, itemName, columns, renderRow, onAdd, onRemove, addLabel = "Add another", label, minItems = 1, maxItems, className }) {
|
|
4714
|
+
const listRef = useRef(null);
|
|
4715
|
+
const addRef = useRef(null);
|
|
4716
|
+
const reportChange = useContext(FormChangeCtx);
|
|
4717
|
+
const getIdRef = useLatest(getId);
|
|
4718
|
+
const pending = useRef(null);
|
|
4719
|
+
useEffect(() => {
|
|
4720
|
+
const next = pending.current;
|
|
4721
|
+
if (!next) return;
|
|
4722
|
+
const rows = () => Array.from(listRef.current?.querySelectorAll(":scope > li") ?? []);
|
|
4723
|
+
const firstFields = () => rows().map((row) => row.querySelector(FOCUSABLE2)).filter((el) => !!el);
|
|
4724
|
+
const ids = items.map((item) => getIdRef.current(item));
|
|
4725
|
+
if (next.kind === "remove") {
|
|
4726
|
+
if (ids.includes(next.id)) return;
|
|
4727
|
+
pending.current = null;
|
|
4728
|
+
focusAfterRemoval(firstFields(), next.index, addRef.current);
|
|
4729
|
+
return;
|
|
4730
|
+
}
|
|
4731
|
+
const added = ids.findIndex((id) => !next.before.has(id));
|
|
4732
|
+
if (added === -1) return;
|
|
4733
|
+
pending.current = null;
|
|
4734
|
+
rows()[added]?.querySelector(FOCUSABLE2)?.focus();
|
|
4735
|
+
}, [items, getIdRef]);
|
|
4736
|
+
const canRemove = items.length > minItems;
|
|
4737
|
+
const canAdd = maxItems === void 0 || items.length < maxItems;
|
|
4738
|
+
const grid = { "--gs-add-another-cols": `repeat(${columns.length}, minmax(0, 1fr)) max-content` };
|
|
4739
|
+
const body = /* @__PURE__ */ jsxs("div", { "data-add-another": "", className: cn("@container flex flex-col gap-ds-3", className), style: grid, children: [
|
|
4740
|
+
/* @__PURE__ */ jsxs("div", { "aria-hidden": "true", className: "hidden gap-ds-3 text-sm font-medium text-[var(--ds-text-secondary)] @min-[30rem]:grid @min-[30rem]:grid-cols-[var(--gs-add-another-cols)]", children: [
|
|
4741
|
+
columns.map((column) => /* @__PURE__ */ jsx("span", { children: column }, column)),
|
|
4742
|
+
canRemove && /* @__PURE__ */ jsx("span", { className: "invisible inline-flex items-center whitespace-nowrap px-ds-4 text-xs font-medium", children: "Remove" })
|
|
4743
|
+
] }),
|
|
4744
|
+
/* @__PURE__ */ jsx("ul", { ref: listRef, className: "flex flex-col gap-ds-4 @min-[30rem]:gap-ds-3", children: items.map((item, index) => {
|
|
4745
|
+
const id = getId(item);
|
|
4746
|
+
return /* @__PURE__ */ jsxs("li", { "data-add-another-row": "", className: "grid grid-cols-1 items-start gap-ds-3 @min-[30rem]:grid-cols-[var(--gs-add-another-cols)]", children: [
|
|
4747
|
+
/* @__PURE__ */ jsx(AddAnotherRowCtx.Provider, { value: true, children: renderRow(item, index, (column) => `${column}, ${itemName(index)}`) }),
|
|
4748
|
+
canRemove && // the visible "Remove" starts its name, which says whose row it removes (WCAG 2.5.3 label in name)
|
|
4749
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", "aria-label": `Remove ${itemName(index)}`, className: "justify-self-start @min-[30rem]:mt-[calc((var(--ds-control-height-md)-var(--ds-control-height-sm))/2)]", onClick: () => {
|
|
4750
|
+
pending.current = { kind: "remove", id, index };
|
|
4751
|
+
reportChange?.();
|
|
4752
|
+
onRemove(id);
|
|
4753
|
+
}, children: "Remove" })
|
|
4754
|
+
] }, id);
|
|
4755
|
+
}) }),
|
|
4756
|
+
canAdd && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, { ref: addRef, type: "button", variant: "secondary", onClick: () => {
|
|
4757
|
+
pending.current = { kind: "add", before: new Set(items.map(getId)) };
|
|
4758
|
+
reportChange?.();
|
|
4759
|
+
onAdd();
|
|
4760
|
+
}, children: addLabel }) })
|
|
4761
|
+
] });
|
|
4762
|
+
if (!label) return body;
|
|
4763
|
+
return /* @__PURE__ */ jsxs("fieldset", { className: "min-w-0", children: [
|
|
4764
|
+
/* @__PURE__ */ jsx("legend", { className: "mb-ds-2 text-sm font-medium text-[var(--ds-text-primary)]", children: label }),
|
|
4765
|
+
body
|
|
4766
|
+
] });
|
|
4476
4767
|
}
|
|
4477
4768
|
function TransferList({
|
|
4478
4769
|
available,
|
|
4479
4770
|
selected,
|
|
4480
|
-
onChange,
|
|
4771
|
+
onChange: onChangeProp,
|
|
4481
4772
|
availableTitle = "Available",
|
|
4482
4773
|
selectedTitle = "Selected",
|
|
4483
4774
|
searchable = true,
|
|
4484
4775
|
className,
|
|
4485
4776
|
ref
|
|
4486
4777
|
}) {
|
|
4778
|
+
const onChange = useReportedChange(onChangeProp, selected, (_available, chosen) => chosen);
|
|
4487
4779
|
const [checkedAvailable, setCheckedAvailable] = useState(/* @__PURE__ */ new Set());
|
|
4488
4780
|
const [checkedSelected, setCheckedSelected] = useState(/* @__PURE__ */ new Set());
|
|
4489
4781
|
const [searchLeft, setSearchLeft] = useState("");
|
|
@@ -4565,6 +4857,7 @@ function TransferList({
|
|
|
4565
4857
|
/* @__PURE__ */ jsx(
|
|
4566
4858
|
"button",
|
|
4567
4859
|
{
|
|
4860
|
+
type: "button",
|
|
4568
4861
|
onClick: moveAllRight,
|
|
4569
4862
|
disabled: !available.filter((i) => !i.disabled).length,
|
|
4570
4863
|
"aria-label": isStacked ? "Move all down" : "Move all right",
|
|
@@ -4575,6 +4868,7 @@ function TransferList({
|
|
|
4575
4868
|
/* @__PURE__ */ jsx(
|
|
4576
4869
|
"button",
|
|
4577
4870
|
{
|
|
4871
|
+
type: "button",
|
|
4578
4872
|
onClick: moveRight,
|
|
4579
4873
|
disabled: !checkedAvailable.size,
|
|
4580
4874
|
"aria-label": isStacked ? "Move selected down" : "Move selected right",
|
|
@@ -4585,6 +4879,7 @@ function TransferList({
|
|
|
4585
4879
|
/* @__PURE__ */ jsx(
|
|
4586
4880
|
"button",
|
|
4587
4881
|
{
|
|
4882
|
+
type: "button",
|
|
4588
4883
|
onClick: moveLeft,
|
|
4589
4884
|
disabled: !checkedSelected.size,
|
|
4590
4885
|
"aria-label": isStacked ? "Move selected up" : "Move selected left",
|
|
@@ -4595,6 +4890,7 @@ function TransferList({
|
|
|
4595
4890
|
/* @__PURE__ */ jsx(
|
|
4596
4891
|
"button",
|
|
4597
4892
|
{
|
|
4893
|
+
type: "button",
|
|
4598
4894
|
onClick: moveAllLeft,
|
|
4599
4895
|
disabled: !selected.filter((i) => !i.disabled).length,
|
|
4600
4896
|
"aria-label": isStacked ? "Move all up" : "Move all left",
|
|
@@ -4726,62 +5022,6 @@ function toInitials(value) {
|
|
|
4726
5022
|
if (!/\s/.test(s) && Array.from(s).length <= 3) return s;
|
|
4727
5023
|
return initialsOf(s);
|
|
4728
5024
|
}
|
|
4729
|
-
var variantColors = {
|
|
4730
|
-
success: "bg-[var(--ds-status-success)]",
|
|
4731
|
-
warning: "bg-[var(--ds-status-warning)]",
|
|
4732
|
-
error: "bg-[var(--ds-status-error)]",
|
|
4733
|
-
info: "bg-[var(--ds-accent-primary)]",
|
|
4734
|
-
neutral: "bg-[var(--ds-text-muted)]",
|
|
4735
|
-
offline: "bg-[var(--ds-text-muted)] opacity-disabled"
|
|
4736
|
-
};
|
|
4737
|
-
var pulseRingColors = {
|
|
4738
|
-
success: "bg-[color-mix(in_oklch,var(--ds-status-success)_30%,transparent)]",
|
|
4739
|
-
warning: "bg-[color-mix(in_oklch,var(--ds-status-warning)_30%,transparent)]",
|
|
4740
|
-
error: "bg-[color-mix(in_oklch,var(--ds-status-error)_30%,transparent)]",
|
|
4741
|
-
info: "bg-[var(--ds-accent-soft)]",
|
|
4742
|
-
neutral: "bg-[color-mix(in_oklch,var(--ds-text-muted)_20%,transparent)]",
|
|
4743
|
-
offline: "bg-[color-mix(in_oklch,var(--ds-text-muted)_10%,transparent)]"
|
|
4744
|
-
};
|
|
4745
|
-
var StatusDot = forwardRef(function StatusDot2({
|
|
4746
|
-
variant = "neutral",
|
|
4747
|
-
label,
|
|
4748
|
-
pulse = false,
|
|
4749
|
-
className
|
|
4750
|
-
}, ref) {
|
|
4751
|
-
return /* @__PURE__ */ jsxs(
|
|
4752
|
-
"span",
|
|
4753
|
-
{
|
|
4754
|
-
ref,
|
|
4755
|
-
className: cn("inline-flex items-center gap-ds-1.5", className),
|
|
4756
|
-
role: "status",
|
|
4757
|
-
"aria-label": label ?? variant,
|
|
4758
|
-
children: [
|
|
4759
|
-
/* @__PURE__ */ jsxs("span", { className: "relative inline-flex shrink-0", children: [
|
|
4760
|
-
/* @__PURE__ */ jsx(
|
|
4761
|
-
"span",
|
|
4762
|
-
{
|
|
4763
|
-
className: cn(
|
|
4764
|
-
"rounded-[var(--ds-radius-full)] h-2.5 w-2.5",
|
|
4765
|
-
variantColors[variant]
|
|
4766
|
-
)
|
|
4767
|
-
}
|
|
4768
|
-
),
|
|
4769
|
-
pulse && variant !== "offline" && /* @__PURE__ */ jsx(
|
|
4770
|
-
"span",
|
|
4771
|
-
{
|
|
4772
|
-
className: cn(
|
|
4773
|
-
"absolute inset-0 rounded-[var(--ds-radius-full)]",
|
|
4774
|
-
"animate-ping motion-reduce:animate-none",
|
|
4775
|
-
pulseRingColors[variant]
|
|
4776
|
-
)
|
|
4777
|
-
}
|
|
4778
|
-
)
|
|
4779
|
-
] }),
|
|
4780
|
-
label && /* @__PURE__ */ jsx("span", { className: "font-normal text-[var(--ds-text-primary)] text-[length:var(--ds-font-size-xs)]", children: label })
|
|
4781
|
-
]
|
|
4782
|
-
}
|
|
4783
|
-
);
|
|
4784
|
-
});
|
|
4785
5025
|
var sizeStyles2 = {
|
|
4786
5026
|
sm: "h-8 w-8 text-xs",
|
|
4787
5027
|
md: "h-10 w-10 text-sm",
|
|
@@ -4804,13 +5044,23 @@ function colorStyles(color, seed) {
|
|
|
4804
5044
|
if (color === "neutral") return "bg-[var(--ds-bg-muted)] text-[var(--ds-text-secondary)]";
|
|
4805
5045
|
return paletteStyles[color === "auto" ? paletteFor(seed) : color];
|
|
4806
5046
|
}
|
|
4807
|
-
|
|
4808
|
-
|
|
4809
|
-
|
|
4810
|
-
|
|
4811
|
-
|
|
4812
|
-
}
|
|
5047
|
+
function PresenceMark({ status }) {
|
|
5048
|
+
return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 10 10", width: "10", height: "10", "aria-hidden": "true", focusable: "false", "data-presence": status, className: "block", children: [
|
|
5049
|
+
status === "online" && /* @__PURE__ */ jsx("circle", { cx: "5", cy: "5", r: "5", className: "fill-[var(--ds-status-success)]" }),
|
|
5050
|
+
status === "away" && /* @__PURE__ */ jsx("circle", { cx: "5", cy: "5", r: "4", fill: "none", strokeWidth: "2", className: "stroke-[var(--ds-status-warning)]" }),
|
|
5051
|
+
status === "busy" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5052
|
+
/* @__PURE__ */ jsx("circle", { cx: "5", cy: "5", r: "5", className: "fill-[var(--ds-status-error)]" }),
|
|
5053
|
+
/* @__PURE__ */ jsx("rect", { x: "2.5", y: "4.1", width: "5", height: "1.8", rx: "0.9", className: "fill-[var(--ds-bg-canvas)]" })
|
|
5054
|
+
] }),
|
|
5055
|
+
status === "offline" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5056
|
+
/* @__PURE__ */ jsx("circle", { cx: "5", cy: "5", r: "4", fill: "none", strokeWidth: "2", className: "stroke-[var(--ds-text-muted)]" }),
|
|
5057
|
+
/* @__PURE__ */ jsx("line", { x1: "3.1", y1: "6.9", x2: "6.9", y2: "3.1", strokeWidth: "1.5", strokeLinecap: "round", className: "stroke-[var(--ds-text-muted)]" })
|
|
5058
|
+
] })
|
|
5059
|
+
] });
|
|
5060
|
+
}
|
|
4813
5061
|
function Avatar({ initials, src, alt, size = "md", status, color = "auto", className }) {
|
|
5062
|
+
const who = alt ?? initials ?? "";
|
|
5063
|
+
const named = status ? [who, status].filter(Boolean).join(", ") : void 0;
|
|
4814
5064
|
const base = cn(
|
|
4815
5065
|
"inline-flex items-center justify-center font-medium shrink-0",
|
|
4816
5066
|
"rounded-[var(--ds-radius-full)]",
|
|
@@ -4822,13 +5072,15 @@ function Avatar({ initials, src, alt, size = "md", status, color = "auto", class
|
|
|
4822
5072
|
{
|
|
4823
5073
|
"data-avatar": "",
|
|
4824
5074
|
src,
|
|
4825
|
-
alt: alt ?? initials ?? "",
|
|
5075
|
+
alt: named ?? alt ?? initials ?? "",
|
|
4826
5076
|
className: cn(base, "object-cover")
|
|
4827
5077
|
}
|
|
4828
5078
|
) : /* @__PURE__ */ jsx(
|
|
4829
5079
|
"div",
|
|
4830
5080
|
{
|
|
4831
5081
|
"data-avatar": "",
|
|
5082
|
+
role: named ? "img" : void 0,
|
|
5083
|
+
"aria-label": named,
|
|
4832
5084
|
className: cn(
|
|
4833
5085
|
base,
|
|
4834
5086
|
colorStyles(color, alt ?? initials ?? ""),
|
|
@@ -4850,20 +5102,14 @@ function Avatar({ initials, src, alt, size = "md", status, color = "auto", class
|
|
|
4850
5102
|
size === "lg" && "bottom-[0px] right-[0px]"
|
|
4851
5103
|
),
|
|
4852
5104
|
"aria-hidden": "true",
|
|
4853
|
-
children: /* @__PURE__ */ jsx(
|
|
4854
|
-
StatusDot,
|
|
4855
|
-
{
|
|
4856
|
-
variant: statusVariantMap[status],
|
|
4857
|
-
className: "rounded-[var(--ds-radius-full)] shadow-[0_0_0_2px_var(--ds-bg-canvas)]"
|
|
4858
|
-
}
|
|
4859
|
-
)
|
|
5105
|
+
children: /* @__PURE__ */ jsx("span", { className: "block rounded-[var(--ds-radius-full)] bg-[var(--ds-bg-canvas)] shadow-[0_0_0_2px_var(--ds-bg-canvas)]", children: /* @__PURE__ */ jsx(PresenceMark, { status }) })
|
|
4860
5106
|
}
|
|
4861
5107
|
)
|
|
4862
5108
|
] });
|
|
4863
5109
|
}
|
|
4864
5110
|
function MentionInput({
|
|
4865
5111
|
value: controlledValue,
|
|
4866
|
-
onChange,
|
|
5112
|
+
onChange: onChangeProp,
|
|
4867
5113
|
suggestions,
|
|
4868
5114
|
trigger = "@",
|
|
4869
5115
|
placeholder,
|
|
@@ -4872,6 +5118,7 @@ function MentionInput({
|
|
|
4872
5118
|
}) {
|
|
4873
5119
|
const [internalValue, setInternalValue] = useState("");
|
|
4874
5120
|
const value = controlledValue ?? internalValue;
|
|
5121
|
+
const onChange = useReportedChange(onChangeProp, value);
|
|
4875
5122
|
const [query, setQuery] = useState("");
|
|
4876
5123
|
const [showPopup, setShowPopup] = useState(false);
|
|
4877
5124
|
const [activeIndex, setActiveIndex] = useState(0);
|
|
@@ -5777,6 +6024,57 @@ var DescriptionList = forwardRef(function DescriptionList2({
|
|
|
5777
6024
|
}
|
|
5778
6025
|
);
|
|
5779
6026
|
});
|
|
6027
|
+
var variantColors = {
|
|
6028
|
+
success: "bg-[var(--ds-status-success)]",
|
|
6029
|
+
warning: "bg-[var(--ds-status-warning)]",
|
|
6030
|
+
error: "bg-[var(--ds-status-error)]",
|
|
6031
|
+
info: "bg-[var(--ds-accent-primary)]",
|
|
6032
|
+
neutral: "bg-[var(--ds-text-muted)]",
|
|
6033
|
+
offline: "bg-[var(--ds-text-muted)] opacity-disabled"
|
|
6034
|
+
};
|
|
6035
|
+
var pulseRingColors = {
|
|
6036
|
+
success: "bg-[color-mix(in_oklch,var(--ds-status-success)_30%,transparent)]",
|
|
6037
|
+
warning: "bg-[color-mix(in_oklch,var(--ds-status-warning)_30%,transparent)]",
|
|
6038
|
+
error: "bg-[color-mix(in_oklch,var(--ds-status-error)_30%,transparent)]",
|
|
6039
|
+
info: "bg-[var(--ds-accent-soft)]",
|
|
6040
|
+
neutral: "bg-[color-mix(in_oklch,var(--ds-text-muted)_20%,transparent)]",
|
|
6041
|
+
offline: "bg-[color-mix(in_oklch,var(--ds-text-muted)_10%,transparent)]"
|
|
6042
|
+
};
|
|
6043
|
+
var StatusDot = forwardRef(function StatusDot2({
|
|
6044
|
+
variant = "neutral",
|
|
6045
|
+
label,
|
|
6046
|
+
pulse = false,
|
|
6047
|
+
className
|
|
6048
|
+
}, ref) {
|
|
6049
|
+
return (
|
|
6050
|
+
// No live region (A48): the dot is read as its words where it sits; telling the user about a change as it happens
|
|
6051
|
+
// is the toasts' job (WCAG 4.1.3). The dot itself is hidden from assistive technology.
|
|
6052
|
+
/* @__PURE__ */ jsxs("span", { ref, "data-status-dot": variant, className: cn("inline-flex items-center gap-ds-1.5", className), children: [
|
|
6053
|
+
/* @__PURE__ */ jsxs("span", { "aria-hidden": "true", className: "relative inline-flex shrink-0", children: [
|
|
6054
|
+
/* @__PURE__ */ jsx(
|
|
6055
|
+
"span",
|
|
6056
|
+
{
|
|
6057
|
+
className: cn(
|
|
6058
|
+
"rounded-[var(--ds-radius-full)] h-2.5 w-2.5",
|
|
6059
|
+
variantColors[variant]
|
|
6060
|
+
)
|
|
6061
|
+
}
|
|
6062
|
+
),
|
|
6063
|
+
pulse && variant !== "offline" && /* @__PURE__ */ jsx(
|
|
6064
|
+
"span",
|
|
6065
|
+
{
|
|
6066
|
+
className: cn(
|
|
6067
|
+
"absolute inset-0 rounded-[var(--ds-radius-full)]",
|
|
6068
|
+
"animate-ping motion-reduce:animate-none",
|
|
6069
|
+
pulseRingColors[variant]
|
|
6070
|
+
)
|
|
6071
|
+
}
|
|
6072
|
+
)
|
|
6073
|
+
] }),
|
|
6074
|
+
/* @__PURE__ */ jsx("span", { className: "font-normal text-[var(--ds-text-primary)] text-[length:var(--ds-font-size-xs)]", children: label })
|
|
6075
|
+
] })
|
|
6076
|
+
);
|
|
6077
|
+
});
|
|
5780
6078
|
function Accordion({ items, type = "single", defaultOpen = [], open: controlledOpen, onOpenChange, className }) {
|
|
5781
6079
|
const [internalOpen, setInternalOpen] = useState(new Set(defaultOpen));
|
|
5782
6080
|
const baseId = useId();
|
|
@@ -5811,6 +6109,7 @@ function Accordion({ items, type = "single", defaultOpen = [], open: controlledO
|
|
|
5811
6109
|
/* @__PURE__ */ jsxs(
|
|
5812
6110
|
"button",
|
|
5813
6111
|
{
|
|
6112
|
+
type: "button",
|
|
5814
6113
|
id: triggerId,
|
|
5815
6114
|
"aria-expanded": isOpen,
|
|
5816
6115
|
"aria-controls": panelId,
|
|
@@ -6196,6 +6495,7 @@ function Table({
|
|
|
6196
6495
|
expandable && /* @__PURE__ */ jsx("td", { className: cn("w-8", density === "compact" ? "px-ds-1 py-ds-2" : "px-ds-2 py-ds-3"), children: /* @__PURE__ */ jsx(
|
|
6197
6496
|
"button",
|
|
6198
6497
|
{
|
|
6498
|
+
type: "button",
|
|
6199
6499
|
onClick: () => toggleExpand(i),
|
|
6200
6500
|
className: "text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)] cursor-pointer",
|
|
6201
6501
|
"aria-expanded": isExpanded,
|
|
@@ -6312,7 +6612,7 @@ var indicatorInset = {
|
|
|
6312
6612
|
};
|
|
6313
6613
|
function SegmentedControl({
|
|
6314
6614
|
value,
|
|
6315
|
-
onChange,
|
|
6615
|
+
onChange: onChangeProp,
|
|
6316
6616
|
options,
|
|
6317
6617
|
size: sizeProp,
|
|
6318
6618
|
variant = "default",
|
|
@@ -6323,6 +6623,7 @@ function SegmentedControl({
|
|
|
6323
6623
|
maxOptions = 6,
|
|
6324
6624
|
...wiring
|
|
6325
6625
|
}) {
|
|
6626
|
+
const onChange = useReportedChange(onChangeProp, value);
|
|
6326
6627
|
const contextSize = useContext(ControlSizeContext);
|
|
6327
6628
|
const control = useFieldControl(wiring);
|
|
6328
6629
|
const named = !ariaLabel && control.labelId ? { "aria-labelledby": control.labelId } : {};
|
|
@@ -8212,74 +8513,78 @@ function TableToolbar({
|
|
|
8212
8513
|
const paged = total !== void 0 && !!pagination && pagination.pageSize > 0 && total > pagination.pageSize;
|
|
8213
8514
|
const countText = total === void 0 ? null : grows ? shown < total ? `Showing ${shown} of ${total} ${noun(total)}` : resultCount !== void 0 ? `${total} ${noun(total)}` : null : paged ? `Showing ${Math.min((pagination.page - 1) * pagination.pageSize + 1, total)}\u2013${Math.min(pagination.page * pagination.pageSize, total)} of ${total} ${noun(total)}` : resultCount !== void 0 ? `${total} ${noun(total)}` : null;
|
|
8214
8515
|
if (!hasControls && countText === null && !hasChips) return null;
|
|
8215
|
-
return
|
|
8216
|
-
|
|
8217
|
-
|
|
8218
|
-
|
|
8219
|
-
|
|
8220
|
-
|
|
8221
|
-
placeholder: search.placeholder ?? search.label,
|
|
8222
|
-
value: search.value,
|
|
8223
|
-
size,
|
|
8224
|
-
onChange: (e) => search.onChange(e.target.value),
|
|
8225
|
-
className: cn("flex-1 min-w-[160px]", !searchFills && "max-w-[280px]")
|
|
8226
|
-
}
|
|
8227
|
-
),
|
|
8228
|
-
primaryFilter && (compact ? /* @__PURE__ */ jsx(
|
|
8229
|
-
Dropdown,
|
|
8230
|
-
{
|
|
8231
|
-
"aria-label": primaryFilter.label,
|
|
8232
|
-
options: primaryFilter.options.map((o) => ({ id: o.value, label: o.label })),
|
|
8233
|
-
value: primaryFilter.value,
|
|
8234
|
-
onChange: (v) => primaryFilter.onChange(v),
|
|
8235
|
-
size,
|
|
8236
|
-
className: "w-[150px]"
|
|
8237
|
-
}
|
|
8238
|
-
) : /* @__PURE__ */ jsx(
|
|
8239
|
-
SegmentedControl,
|
|
8240
|
-
{
|
|
8241
|
-
"aria-label": primaryFilter.label,
|
|
8242
|
-
options: primaryFilter.options,
|
|
8243
|
-
value: primaryFilter.value,
|
|
8244
|
-
size,
|
|
8245
|
-
onChange: primaryFilter.onChange
|
|
8246
|
-
}
|
|
8247
|
-
)),
|
|
8248
|
-
(filters || actions) && /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-ds-2 justify-end", inPane ? "flex-none" : "flex-1"), children: [
|
|
8249
|
-
filters && /* @__PURE__ */ jsxs(
|
|
8250
|
-
Button,
|
|
8516
|
+
return (
|
|
8517
|
+
// a list's search and filters are how it's viewed, not a form's data: they never mark an overlay's form (0.21.0)
|
|
8518
|
+
/* @__PURE__ */ jsx(FormChangeCtx, { value: null, children: /* @__PURE__ */ jsx(ControlSizeContext.Provider, { value: size, children: /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-ds-3 min-w-0 mb-ds-3 last:mb-0", className), "data-table-toolbar": "", children: [
|
|
8519
|
+
hasControls && /* @__PURE__ */ jsxs("div", { ref: rowRef, className: "flex items-center gap-ds-2 flex-wrap", children: [
|
|
8520
|
+
search && /* @__PURE__ */ jsx(
|
|
8521
|
+
Input,
|
|
8251
8522
|
{
|
|
8252
|
-
|
|
8523
|
+
"aria-label": search.label,
|
|
8524
|
+
placeholder: search.placeholder ?? search.label,
|
|
8525
|
+
value: search.value,
|
|
8253
8526
|
size,
|
|
8254
|
-
|
|
8255
|
-
|
|
8256
|
-
"aria-expanded": open,
|
|
8257
|
-
"aria-controls": filterRowId,
|
|
8258
|
-
className: "mr-auto",
|
|
8259
|
-
children: [
|
|
8260
|
-
"Filters",
|
|
8261
|
-
count > 0 && !open && /* @__PURE__ */ jsx(Badge, { variant: "default", size: "xs", className: "ml-ds-1", children: count })
|
|
8262
|
-
]
|
|
8527
|
+
onChange: (e) => search.onChange(e.target.value),
|
|
8528
|
+
className: cn("flex-1 min-w-[160px]", !searchFills && "max-w-[280px]")
|
|
8263
8529
|
}
|
|
8264
8530
|
),
|
|
8265
|
-
|
|
8266
|
-
|
|
8267
|
-
|
|
8268
|
-
|
|
8269
|
-
|
|
8270
|
-
|
|
8271
|
-
|
|
8272
|
-
|
|
8273
|
-
|
|
8274
|
-
|
|
8275
|
-
|
|
8276
|
-
|
|
8277
|
-
|
|
8278
|
-
|
|
8279
|
-
|
|
8280
|
-
|
|
8281
|
-
|
|
8282
|
-
|
|
8531
|
+
primaryFilter && (compact ? /* @__PURE__ */ jsx(
|
|
8532
|
+
Dropdown,
|
|
8533
|
+
{
|
|
8534
|
+
"aria-label": primaryFilter.label,
|
|
8535
|
+
options: primaryFilter.options.map((o) => ({ id: o.value, label: o.label })),
|
|
8536
|
+
value: primaryFilter.value,
|
|
8537
|
+
onChange: (v) => primaryFilter.onChange(v),
|
|
8538
|
+
size,
|
|
8539
|
+
className: "w-[150px]"
|
|
8540
|
+
}
|
|
8541
|
+
) : /* @__PURE__ */ jsx(
|
|
8542
|
+
SegmentedControl,
|
|
8543
|
+
{
|
|
8544
|
+
"aria-label": primaryFilter.label,
|
|
8545
|
+
options: primaryFilter.options,
|
|
8546
|
+
value: primaryFilter.value,
|
|
8547
|
+
size,
|
|
8548
|
+
onChange: primaryFilter.onChange
|
|
8549
|
+
}
|
|
8550
|
+
)),
|
|
8551
|
+
(filters || actions) && /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-ds-2 justify-end", inPane ? "flex-none" : "flex-1"), children: [
|
|
8552
|
+
filters && /* @__PURE__ */ jsxs(
|
|
8553
|
+
Button,
|
|
8554
|
+
{
|
|
8555
|
+
type: "button",
|
|
8556
|
+
variant: open ? "secondary" : "outline",
|
|
8557
|
+
size,
|
|
8558
|
+
iconLeft: /* @__PURE__ */ jsx(Icon, { name: "filter", size: iconSize }),
|
|
8559
|
+
onClick: () => setOpen(!open),
|
|
8560
|
+
"aria-expanded": open,
|
|
8561
|
+
"aria-controls": filterRowId,
|
|
8562
|
+
className: "mr-auto",
|
|
8563
|
+
children: [
|
|
8564
|
+
"Filters",
|
|
8565
|
+
count > 0 && !open && /* @__PURE__ */ jsx(Badge, { variant: "default", size: "xs", className: "ml-ds-1", children: count })
|
|
8566
|
+
]
|
|
8567
|
+
}
|
|
8568
|
+
),
|
|
8569
|
+
actions
|
|
8570
|
+
] })
|
|
8571
|
+
] }),
|
|
8572
|
+
filters && open && /* @__PURE__ */ jsx("div", { id: filterRowId, className: "flex items-center gap-ds-3 flex-wrap", children: filters }),
|
|
8573
|
+
(countText !== null || hasChips) && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-2 flex-wrap", children: [
|
|
8574
|
+
countText !== null && /* @__PURE__ */ jsx("span", { className: "text-xs text-[var(--ds-text-muted)]", "aria-live": "polite", "data-result-count": "", children: countText }),
|
|
8575
|
+
activeFilters?.map((f) => /* @__PURE__ */ jsx(Tag, { size: "sm", variant: "subtle", onRemove: f.onRemove, children: f.label }, f.id)),
|
|
8576
|
+
hasChips && onClearAll && /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: onClearAll, children: "Clear all" })
|
|
8577
|
+
] })
|
|
8578
|
+
] }) }) })
|
|
8579
|
+
);
|
|
8580
|
+
}
|
|
8581
|
+
var ICON_TEXT_OFFSET = "calc((2rem - 1.25rem) / 2)";
|
|
8582
|
+
function Marker({ item, vertical }) {
|
|
8583
|
+
if (item.icon) {
|
|
8584
|
+
return /* @__PURE__ */ jsx("div", { "data-timeline-icon": "", className: "shrink-0 w-8 h-8 flex items-center justify-center *:max-w-8 *:max-h-8", children: item.icon });
|
|
8585
|
+
}
|
|
8586
|
+
return /* @__PURE__ */ jsx(
|
|
8587
|
+
"div",
|
|
8283
8588
|
{
|
|
8284
8589
|
className: cn(
|
|
8285
8590
|
"shrink-0 w-3 h-3 rounded-[var(--ds-radius-full)]",
|
|
@@ -8436,6 +8741,8 @@ function CollapsibleTrigger({ children, className }) {
|
|
|
8436
8741
|
if (isValidElement(children)) {
|
|
8437
8742
|
const child = children;
|
|
8438
8743
|
return cloneElement(child, {
|
|
8744
|
+
// a Button trigger in a form toggles; it never submits the form (0.21.0)
|
|
8745
|
+
...triggerType(child),
|
|
8439
8746
|
"aria-expanded": isOpen,
|
|
8440
8747
|
className: cn(child.props.className, className),
|
|
8441
8748
|
onClick: (e) => {
|
|
@@ -8864,6 +9171,7 @@ function Carousel({
|
|
|
8864
9171
|
/* @__PURE__ */ jsx(
|
|
8865
9172
|
"button",
|
|
8866
9173
|
{
|
|
9174
|
+
type: "button",
|
|
8867
9175
|
onClick: prev,
|
|
8868
9176
|
disabled: !canPrev,
|
|
8869
9177
|
"aria-label": "Previous slide",
|
|
@@ -8883,6 +9191,7 @@ function Carousel({
|
|
|
8883
9191
|
/* @__PURE__ */ jsx(
|
|
8884
9192
|
"button",
|
|
8885
9193
|
{
|
|
9194
|
+
type: "button",
|
|
8886
9195
|
onClick: next,
|
|
8887
9196
|
disabled: !canNext,
|
|
8888
9197
|
"aria-label": "Next slide",
|
|
@@ -8903,6 +9212,7 @@ function Carousel({
|
|
|
8903
9212
|
showIndicators && count > 1 && /* @__PURE__ */ jsx("div", { className: "absolute bottom-ds-3 left-1/2 -translate-x-1/2 flex gap-ds-1.5 z-10", children: children.map((_, i) => /* @__PURE__ */ jsx(
|
|
8904
9213
|
"button",
|
|
8905
9214
|
{
|
|
9215
|
+
type: "button",
|
|
8906
9216
|
onClick: () => goTo(i),
|
|
8907
9217
|
"aria-label": `Go to slide ${i + 1}`,
|
|
8908
9218
|
className: cn(
|
|
@@ -8982,7 +9292,7 @@ function ActionsRow({ message, onAction }) {
|
|
|
8982
9292
|
),
|
|
8983
9293
|
children: message.actions.map((a) => {
|
|
8984
9294
|
const { id, label, icon } = resolveAction(a);
|
|
8985
|
-
return /* @__PURE__ */ jsx(Tooltip, { content: label, children: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon-xs", "aria-label": label, onClick: () => run(id), children: /* @__PURE__ */ jsx(Icon, { name: icon, size: 14 }) }) }, id);
|
|
9295
|
+
return /* @__PURE__ */ jsx(Tooltip, { content: label, children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon-xs", "aria-label": label, onClick: () => run(id), children: /* @__PURE__ */ jsx(Icon, { name: icon, size: 14 }) }) }, id);
|
|
8986
9296
|
})
|
|
8987
9297
|
}
|
|
8988
9298
|
);
|
|
@@ -9119,12 +9429,13 @@ function ChatInputBar({ onSend, busy, onStop, onAttach, onVoice, placeholder })
|
|
|
9119
9429
|
),
|
|
9120
9430
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-ds-2 pb-ds-1.5", children: [
|
|
9121
9431
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-0.5", children: [
|
|
9122
|
-
onAttach && /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon-sm", "aria-label": "Add attachment", onClick: onAttach, className: compact, children: /* @__PURE__ */ jsx(Icon, { name: "paperclip", size: glyph }) }),
|
|
9123
|
-
onVoice && /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon-sm", "aria-label": "Voice message", onClick: onVoice, className: compact, children: /* @__PURE__ */ jsx(Icon, { name: "mic", size: glyph }) })
|
|
9432
|
+
onAttach && /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", "aria-label": "Add attachment", onClick: onAttach, className: compact, children: /* @__PURE__ */ jsx(Icon, { name: "paperclip", size: glyph }) }),
|
|
9433
|
+
onVoice && /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", "aria-label": "Voice message", onClick: onVoice, className: compact, children: /* @__PURE__ */ jsx(Icon, { name: "mic", size: glyph }) })
|
|
9124
9434
|
] }),
|
|
9125
|
-
busy ? /* @__PURE__ */ jsx(Button, { variant: "tertiary", size: "icon-sm", "aria-label": "Stop generating", onClick: onStop, className: compact, children: /* @__PURE__ */ jsx(Icon, { name: "square", size: glyph }) }) : /* @__PURE__ */ jsx(
|
|
9435
|
+
busy ? /* @__PURE__ */ jsx(Button, { type: "button", variant: "tertiary", size: "icon-sm", "aria-label": "Stop generating", onClick: onStop, className: compact, children: /* @__PURE__ */ jsx(Icon, { name: "square", size: glyph }) }) : /* @__PURE__ */ jsx(
|
|
9126
9436
|
Button,
|
|
9127
9437
|
{
|
|
9438
|
+
type: "button",
|
|
9128
9439
|
variant: text.trim() ? "default" : "ghost",
|
|
9129
9440
|
size: "icon-sm",
|
|
9130
9441
|
"aria-label": "Send message",
|
|
@@ -9238,7 +9549,7 @@ function ChatMessageList({
|
|
|
9238
9549
|
}),
|
|
9239
9550
|
typingUser && /* @__PURE__ */ jsx(TypingIndicator, { name: typingUser })
|
|
9240
9551
|
] }) }),
|
|
9241
|
-
showJump && !empty && /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-0 bottom-ds-2 flex justify-center", children: /* @__PURE__ */ jsxs(Button, { variant: "secondary", size: "xs", className: "pointer-events-auto rounded-[var(--ds-radius-full)]", onClick: scrollToBottom, children: [
|
|
9552
|
+
showJump && !empty && /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-0 bottom-ds-2 flex justify-center", children: /* @__PURE__ */ jsxs(Button, { type: "button", variant: "secondary", size: "xs", className: "pointer-events-auto rounded-[var(--ds-radius-full)]", onClick: scrollToBottom, children: [
|
|
9242
9553
|
/* @__PURE__ */ jsx(Icon, { name: "chevron-down", size: 14 }),
|
|
9243
9554
|
"Jump to latest"
|
|
9244
9555
|
] }) })
|
|
@@ -9293,10 +9604,11 @@ function ChatPanel({
|
|
|
9293
9604
|
] }),
|
|
9294
9605
|
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-ds-1", children: [
|
|
9295
9606
|
actions,
|
|
9296
|
-
onNewConversation && /* @__PURE__ */ jsx(Tooltip, { content: "New conversation", children: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon-sm", "aria-label": "New conversation", onClick: onNewConversation, children: /* @__PURE__ */ jsx(Icon, { name: "plus", size: 16 }) }) }),
|
|
9607
|
+
onNewConversation && /* @__PURE__ */ jsx(Tooltip, { content: "New conversation", children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", "aria-label": "New conversation", onClick: onNewConversation, children: /* @__PURE__ */ jsx(Icon, { name: "plus", size: 16 }) }) }),
|
|
9297
9608
|
onExpandedChange && /* @__PURE__ */ jsx(Tooltip, { content: expanded ? "Collapse" : "Expand", children: /* @__PURE__ */ jsx(
|
|
9298
9609
|
Button,
|
|
9299
9610
|
{
|
|
9611
|
+
type: "button",
|
|
9300
9612
|
variant: "ghost",
|
|
9301
9613
|
size: "icon-sm",
|
|
9302
9614
|
"aria-label": expanded ? "Collapse" : "Expand",
|
|
@@ -9305,7 +9617,7 @@ function ChatPanel({
|
|
|
9305
9617
|
children: /* @__PURE__ */ jsx(Icon, { name: expanded ? "minimize-2" : "maximize-2", size: 16 })
|
|
9306
9618
|
}
|
|
9307
9619
|
) }),
|
|
9308
|
-
/* @__PURE__ */ jsx(Tooltip, { content: "Close", children: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon-sm", "aria-label": "Close", onClick: onClose, ...{ [OVERLAY_CLOSE_ATTR]: "" }, children: /* @__PURE__ */ jsx(Icon, { name: "close", size: 16 }) }) })
|
|
9620
|
+
/* @__PURE__ */ jsx(Tooltip, { content: "Close", children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", "aria-label": "Close", onClick: onClose, ...{ [OVERLAY_CLOSE_ATTR]: "" }, children: /* @__PURE__ */ jsx(Icon, { name: "close", size: 16 }) }) })
|
|
9309
9621
|
] })
|
|
9310
9622
|
]
|
|
9311
9623
|
}
|
|
@@ -10542,15 +10854,15 @@ var TimeViewport = forwardRef(function TimeViewport2({
|
|
|
10542
10854
|
const hasHeader = headerNode != null || labelHeader != null;
|
|
10543
10855
|
const bar = toolbar === false ? null : /* @__PURE__ */ jsxs("div", { className: cn("flex shrink-0 flex-wrap items-center gap-ds-1 px-ds-2 py-ds-1.5 border-b-[length:var(--ds-border-width)]", border), children: [
|
|
10544
10856
|
onZoomChange && levels.length > 1 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
10545
|
-
/* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon-sm", "aria-label": "Zoom out", "aria-disabled": !canZoomOut || void 0, className: "aria-disabled:opacity-disabled aria-disabled:cursor-not-allowed", onClick: () => zoom(1), children: /* @__PURE__ */ jsx(Icon, { name: "minus", size: 14 }) }),
|
|
10857
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", "aria-label": "Zoom out", "aria-disabled": !canZoomOut || void 0, className: "aria-disabled:opacity-disabled aria-disabled:cursor-not-allowed", onClick: () => zoom(1), children: /* @__PURE__ */ jsx(Icon, { name: "minus", size: 14 }) }),
|
|
10546
10858
|
/* @__PURE__ */ jsx("span", { "aria-live": "polite", className: "min-w-[4.5rem] text-center text-xs text-[var(--ds-text-secondary)]", children: ZOOM_NAMES[scale.zoom] }),
|
|
10547
|
-
/* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon-sm", "aria-label": "Zoom in", "aria-disabled": !canZoomIn || void 0, className: "aria-disabled:opacity-disabled aria-disabled:cursor-not-allowed", onClick: () => zoom(-1), children: /* @__PURE__ */ jsx(Icon, { name: "plus", size: 14 }) })
|
|
10859
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", "aria-label": "Zoom in", "aria-disabled": !canZoomIn || void 0, className: "aria-disabled:opacity-disabled aria-disabled:cursor-not-allowed", onClick: () => zoom(-1), children: /* @__PURE__ */ jsx(Icon, { name: "plus", size: 14 }) })
|
|
10548
10860
|
] }),
|
|
10549
|
-
/* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon-sm", "aria-label": "Previous period", onClick: () => api.page(-1), children: /* @__PURE__ */ jsx(Icon, { name: "chevron-left", size: 14 }) }),
|
|
10550
|
-
/* @__PURE__ */ jsx(Button, { variant: "secondary", size: "sm", disabled: todayAtX === null, onClick: () => {
|
|
10861
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", "aria-label": "Previous period", onClick: () => api.page(-1), children: /* @__PURE__ */ jsx(Icon, { name: "chevron-left", size: 14 }) }),
|
|
10862
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "secondary", size: "sm", disabled: todayAtX === null, onClick: () => {
|
|
10551
10863
|
if (todayAtX !== null) setLeft(todayAtX - visibleWidth / 2);
|
|
10552
10864
|
}, children: "Today" }),
|
|
10553
|
-
/* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon-sm", "aria-label": "Next period", onClick: () => api.page(1), children: /* @__PURE__ */ jsx(Icon, { name: "chevron-right", size: 14 }) }),
|
|
10865
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", "aria-label": "Next period", onClick: () => api.page(1), children: /* @__PURE__ */ jsx(Icon, { name: "chevron-right", size: 14 }) }),
|
|
10554
10866
|
toolbar
|
|
10555
10867
|
] });
|
|
10556
10868
|
return (
|
|
@@ -10807,16 +11119,16 @@ var SELECTED = "outline-solid outline-2 outline-offset-2 outline-[var(--ds-text-
|
|
|
10807
11119
|
var UNDATED_INSET = 16;
|
|
10808
11120
|
var NO_GROUPS = [];
|
|
10809
11121
|
var NO_STATUSES = {};
|
|
10810
|
-
var
|
|
10811
|
-
function
|
|
11122
|
+
var warned2 = /* @__PURE__ */ new Set();
|
|
11123
|
+
function warnOnce2(message) {
|
|
10812
11124
|
let dev = false;
|
|
10813
11125
|
try {
|
|
10814
11126
|
dev = process.env.NODE_ENV !== "production";
|
|
10815
11127
|
} catch {
|
|
10816
11128
|
dev = false;
|
|
10817
11129
|
}
|
|
10818
|
-
if (!dev ||
|
|
10819
|
-
|
|
11130
|
+
if (!dev || warned2.has(message)) return;
|
|
11131
|
+
warned2.add(message);
|
|
10820
11132
|
console.warn(`Gantt: ${message}`);
|
|
10821
11133
|
}
|
|
10822
11134
|
function GanttArrows({ arrows, width, height }) {
|
|
@@ -10898,7 +11210,7 @@ function Gantt({
|
|
|
10898
11210
|
const selected = isControlled ? selectedId ?? null : selectedState;
|
|
10899
11211
|
useEffect(() => {
|
|
10900
11212
|
if (overridden !== null) {
|
|
10901
|
-
|
|
11213
|
+
warnOnce2("selectedId was given a value after the Gantt had kept a selection of its own. To control the selection, pass selectedId from the first render (null for none); to let the Gantt keep it, leave selectedId out.");
|
|
10902
11214
|
}
|
|
10903
11215
|
}, [overridden]);
|
|
10904
11216
|
const select = (item) => {
|
|
@@ -10910,8 +11222,8 @@ function Gantt({
|
|
|
10910
11222
|
const phases = useMemo(() => uniqueById(groups), [groups]);
|
|
10911
11223
|
useEffect(() => {
|
|
10912
11224
|
const quoted = (ids) => ids.map((id) => `"${id}"`).join(", ");
|
|
10913
|
-
if (plan.repeated.length)
|
|
10914
|
-
if (phases.repeated.length)
|
|
11225
|
+
if (plan.repeated.length) warnOnce2(`more than one item has the id ${quoted(plan.repeated)}; only the first of each is shown.`);
|
|
11226
|
+
if (phases.repeated.length) warnOnce2(`more than one group has the id ${quoted(phases.repeated)}; only the first of each is shown.`);
|
|
10915
11227
|
}, [plan, phases]);
|
|
10916
11228
|
const tasks = plan.unique;
|
|
10917
11229
|
const extent = useMemo(() => itemsExtent(tasks), [tasks]);
|
|
@@ -11651,6 +11963,7 @@ function TabButton({
|
|
|
11651
11963
|
const btn2 = /* @__PURE__ */ jsxs(
|
|
11652
11964
|
"button",
|
|
11653
11965
|
{
|
|
11966
|
+
type: "button",
|
|
11654
11967
|
id: tabId,
|
|
11655
11968
|
role: "tab",
|
|
11656
11969
|
"aria-selected": isActive,
|
|
@@ -11686,6 +11999,7 @@ function TabButton({
|
|
|
11686
11999
|
const btn = /* @__PURE__ */ jsx(
|
|
11687
12000
|
"button",
|
|
11688
12001
|
{
|
|
12002
|
+
type: "button",
|
|
11689
12003
|
id: tabId,
|
|
11690
12004
|
role: "tab",
|
|
11691
12005
|
"aria-selected": isActive,
|
|
@@ -11806,14 +12120,17 @@ function TabsRoot(props) {
|
|
|
11806
12120
|
const { tabs, mobile = "scroll" } = props;
|
|
11807
12121
|
const collapseToDropdown = isMobile && (orientation === "responsive" || mobile === "dropdown");
|
|
11808
12122
|
if (collapseToDropdown) {
|
|
11809
|
-
return
|
|
11810
|
-
|
|
11811
|
-
{
|
|
11812
|
-
|
|
11813
|
-
|
|
11814
|
-
|
|
11815
|
-
|
|
11816
|
-
|
|
12123
|
+
return (
|
|
12124
|
+
// choosing a tab is navigation, never a change to a form around it (0.21.0)
|
|
12125
|
+
/* @__PURE__ */ jsx(FormChangeCtx, { value: null, children: /* @__PURE__ */ jsx(
|
|
12126
|
+
Dropdown,
|
|
12127
|
+
{
|
|
12128
|
+
options: tabs.filter((t) => !t.disabled).map((t) => ({ id: t.id, label: t.label, group: t.group })),
|
|
12129
|
+
value: activeTab,
|
|
12130
|
+
onChange: (v) => onTabChange(v),
|
|
12131
|
+
className
|
|
12132
|
+
}
|
|
12133
|
+
) })
|
|
11817
12134
|
);
|
|
11818
12135
|
}
|
|
11819
12136
|
if (effectiveOrientation === "vertical") {
|
|
@@ -11915,7 +12232,7 @@ function SettingsLayout({
|
|
|
11915
12232
|
return (
|
|
11916
12233
|
// gap-x-ds-8 is the rail's gap, unused in one column: the threshold reads the same gap as the row (useColumnGap)
|
|
11917
12234
|
/* @__PURE__ */ jsxs("div", { ref: rootRef, "data-settings-layout": "sidebar", "data-collapsed": "true", className: cn("flex flex-col gap-y-ds-6 gap-x-ds-8", className), children: [
|
|
11918
|
-
/* @__PURE__ */ jsx(
|
|
12235
|
+
/* @__PURE__ */ jsx(FormChangeCtx, { value: null, children: /* @__PURE__ */ jsx(
|
|
11919
12236
|
Dropdown,
|
|
11920
12237
|
{
|
|
11921
12238
|
"aria-label": ariaLabel,
|
|
@@ -11923,7 +12240,7 @@ function SettingsLayout({
|
|
|
11923
12240
|
value,
|
|
11924
12241
|
onChange: (v) => onChange(v)
|
|
11925
12242
|
}
|
|
11926
|
-
),
|
|
12243
|
+
) }),
|
|
11927
12244
|
/* @__PURE__ */ jsx("div", { "data-settings-panel": "", className: PANEL_CLASSES, style: PANEL_STYLE, children })
|
|
11928
12245
|
] })
|
|
11929
12246
|
);
|
|
@@ -12059,6 +12376,7 @@ var Breadcrumbs = forwardRef(function Breadcrumbs2({
|
|
|
12059
12376
|
/* @__PURE__ */ jsx(
|
|
12060
12377
|
"button",
|
|
12061
12378
|
{
|
|
12379
|
+
type: "button",
|
|
12062
12380
|
ref: ellipsisBtnRef,
|
|
12063
12381
|
onClick: () => {
|
|
12064
12382
|
if (!dropdownOpen) setActiveIdx(0);
|
|
@@ -12109,6 +12427,7 @@ var Breadcrumbs = forwardRef(function Breadcrumbs2({
|
|
|
12109
12427
|
children: collapsedItems.map((ci, idx) => /* @__PURE__ */ jsxs(
|
|
12110
12428
|
"button",
|
|
12111
12429
|
{
|
|
12430
|
+
type: "button",
|
|
12112
12431
|
"data-index": idx,
|
|
12113
12432
|
role: "menuitem",
|
|
12114
12433
|
tabIndex: idx === activeIdx ? 0 : -1,
|
|
@@ -12207,6 +12526,7 @@ function Popover({ open, onOpenChange, trigger, children, side = "bottom", align
|
|
|
12207
12526
|
/* @__PURE__ */ jsx(
|
|
12208
12527
|
Slot,
|
|
12209
12528
|
{
|
|
12529
|
+
...triggerType(trigger),
|
|
12210
12530
|
ref: setTriggerNode,
|
|
12211
12531
|
onClick: () => {
|
|
12212
12532
|
setTriggerWidth(triggerRef.current?.offsetWidth);
|
|
@@ -12279,7 +12599,7 @@ function LoadMore({ hasMore, onLoadMore, loadMoreLabel, currentPage, scroll, cla
|
|
|
12279
12599
|
if (!hasMore) return null;
|
|
12280
12600
|
return /* @__PURE__ */ jsxs("div", { "data-ds-pager": "", "data-pagination-mode": scroll ? "infinite-scroll" : "load-more", className: cn("flex flex-col items-center", className), children: [
|
|
12281
12601
|
scroll && /* @__PURE__ */ jsx("div", { ref: marker, "data-load-more-trigger": "", "aria-hidden": "true", className: "h-px w-full" }),
|
|
12282
|
-
/* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: onLoadMore, children: loadMoreLabel ?? "Load more" })
|
|
12602
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "secondary", onClick: onLoadMore, children: loadMoreLabel ?? "Load more" })
|
|
12283
12603
|
] });
|
|
12284
12604
|
}
|
|
12285
12605
|
function PageNumbers({ currentPage, totalPages, onPageChange, pageSize: pageSizeProp, pageSizeOptions, onPageSizeChange, className }) {
|
|
@@ -12289,7 +12609,7 @@ function PageNumbers({ currentPage, totalPages, onPageChange, pageSize: pageSize
|
|
|
12289
12609
|
return /* @__PURE__ */ jsxs("nav", { "aria-label": "Pagination", "data-ds-pager": "", className: cn("flex flex-wrap items-center gap-ds-3", className), children: [
|
|
12290
12610
|
pageSizeOptions && pageSize != null && onPageSizeChange && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-2", children: [
|
|
12291
12611
|
/* @__PURE__ */ jsx("span", { className: "text-sm text-[var(--ds-text-muted)] whitespace-nowrap", children: "Rows per page" }),
|
|
12292
|
-
/* @__PURE__ */ jsx(
|
|
12612
|
+
/* @__PURE__ */ jsx(FormChangeCtx, { value: null, children: /* @__PURE__ */ jsx(
|
|
12293
12613
|
Dropdown,
|
|
12294
12614
|
{
|
|
12295
12615
|
options: pageSizeOptions.map((n) => ({ id: String(n), label: String(n) })),
|
|
@@ -12298,12 +12618,13 @@ function PageNumbers({ currentPage, totalPages, onPageChange, pageSize: pageSize
|
|
|
12298
12618
|
size: "sm",
|
|
12299
12619
|
className: "w-[4.5rem]"
|
|
12300
12620
|
}
|
|
12301
|
-
)
|
|
12621
|
+
) })
|
|
12302
12622
|
] }),
|
|
12303
12623
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-1", children: [
|
|
12304
12624
|
/* @__PURE__ */ jsx(
|
|
12305
12625
|
"button",
|
|
12306
12626
|
{
|
|
12627
|
+
type: "button",
|
|
12307
12628
|
onClick: () => onPageChange(currentPage - 1),
|
|
12308
12629
|
disabled: currentPage <= 1,
|
|
12309
12630
|
"aria-label": "Previous page",
|
|
@@ -12323,6 +12644,7 @@ function PageNumbers({ currentPage, totalPages, onPageChange, pageSize: pageSize
|
|
|
12323
12644
|
(p, i) => p === "..." ? /* @__PURE__ */ jsx(EllipsisJumper, { totalPages, onPageChange }, `ellipsis-${i}`) : /* @__PURE__ */ jsx(
|
|
12324
12645
|
"button",
|
|
12325
12646
|
{
|
|
12647
|
+
type: "button",
|
|
12326
12648
|
onClick: () => onPageChange(p),
|
|
12327
12649
|
"aria-current": p === currentPage ? "page" : void 0,
|
|
12328
12650
|
className: cn(
|
|
@@ -12340,6 +12662,7 @@ function PageNumbers({ currentPage, totalPages, onPageChange, pageSize: pageSize
|
|
|
12340
12662
|
/* @__PURE__ */ jsx(
|
|
12341
12663
|
"button",
|
|
12342
12664
|
{
|
|
12665
|
+
type: "button",
|
|
12343
12666
|
onClick: () => onPageChange(currentPage + 1),
|
|
12344
12667
|
disabled: currentPage >= totalPages,
|
|
12345
12668
|
"aria-label": "Next page",
|
|
@@ -12602,6 +12925,7 @@ function StepCircle({ status, index, onClick, clickable }) {
|
|
|
12602
12925
|
return /* @__PURE__ */ jsx(
|
|
12603
12926
|
"button",
|
|
12604
12927
|
{
|
|
12928
|
+
type: "button",
|
|
12605
12929
|
onClick,
|
|
12606
12930
|
disabled: !clickable,
|
|
12607
12931
|
"aria-current": status === "current" ? "step" : void 0,
|
|
@@ -12796,7 +13120,7 @@ var Sidebar = forwardRef(function Sidebar2({
|
|
|
12796
13120
|
position = "flush",
|
|
12797
13121
|
navbarFloating: navbarFloatingProp,
|
|
12798
13122
|
navSize = "md",
|
|
12799
|
-
fill = false,
|
|
13123
|
+
fill: fill2 = false,
|
|
12800
13124
|
className
|
|
12801
13125
|
}, ref) {
|
|
12802
13126
|
const [internalCollapsed, setInternalCollapsed] = useState(defaultCollapsed ?? false);
|
|
@@ -12806,10 +13130,10 @@ var Sidebar = forwardRef(function Sidebar2({
|
|
|
12806
13130
|
const appShell = useAppShell();
|
|
12807
13131
|
const navbarFloating = navbarFloatingProp ?? appShell?.navbarFloating;
|
|
12808
13132
|
useLayoutEffect(() => {
|
|
12809
|
-
if (
|
|
13133
|
+
if (fill2 || !appShell) return;
|
|
12810
13134
|
return appShell.registerChrome("sidebar", position);
|
|
12811
|
-
}, [appShell?.registerChrome,
|
|
12812
|
-
const usesShellState = appShell !== null && !isControlled && defaultCollapsed === void 0 && !
|
|
13135
|
+
}, [appShell?.registerChrome, fill2, position]);
|
|
13136
|
+
const usesShellState = appShell !== null && !isControlled && defaultCollapsed === void 0 && !fill2 && type === "traditional";
|
|
12813
13137
|
const uncontrolledCollapsed = usesShellState ? appShell.sidebarCollapsed : internalCollapsed;
|
|
12814
13138
|
const collapsed = mini || (isControlled ? controlledCollapsed : uncontrolledCollapsed);
|
|
12815
13139
|
const handleCollapsedChange = (value) => {
|
|
@@ -12828,11 +13152,11 @@ var Sidebar = forwardRef(function Sidebar2({
|
|
|
12828
13152
|
effectiveDarkMode = false;
|
|
12829
13153
|
}
|
|
12830
13154
|
const isDark = effectiveDarkMode ?? variant === "dark";
|
|
12831
|
-
const showCollapse = type === "traditional" && !mini && !
|
|
13155
|
+
const showCollapse = type === "traditional" && !mini && !fill2;
|
|
12832
13156
|
const isMinimal = type === "minimal";
|
|
12833
13157
|
const isCompact = type === "compact";
|
|
12834
|
-
const isFloating = position === "floating" && !
|
|
12835
|
-
const sidebarWidth =
|
|
13158
|
+
const isFloating = position === "floating" && !fill2;
|
|
13159
|
+
const sidebarWidth = fill2 ? "100%" : isCompact ? "var(--ds-sidebar-compact-width)" : collapsed ? "var(--ds-sidebar-collapsed-width)" : "var(--ds-sidebar-width)";
|
|
12836
13160
|
const aside = /* @__PURE__ */ jsxs(
|
|
12837
13161
|
"aside",
|
|
12838
13162
|
{
|
|
@@ -12870,6 +13194,7 @@ var Sidebar = forwardRef(function Sidebar2({
|
|
|
12870
13194
|
const collapseButton = /* @__PURE__ */ jsxs(
|
|
12871
13195
|
"button",
|
|
12872
13196
|
{
|
|
13197
|
+
type: "button",
|
|
12873
13198
|
onClick: () => handleCollapsedChange(!collapsed),
|
|
12874
13199
|
"aria-expanded": !collapsed,
|
|
12875
13200
|
"aria-label": collapsed ? "Expand sidebar" : "Collapse sidebar",
|
|
@@ -13222,6 +13547,7 @@ function SidebarNav({
|
|
|
13222
13547
|
/* @__PURE__ */ jsxs(
|
|
13223
13548
|
"button",
|
|
13224
13549
|
{
|
|
13550
|
+
type: "button",
|
|
13225
13551
|
onClick: () => {
|
|
13226
13552
|
toggleExpand(key);
|
|
13227
13553
|
onItemClick?.(item, index);
|
|
@@ -13356,6 +13682,7 @@ function SidebarNav({
|
|
|
13356
13682
|
collapsible && /* @__PURE__ */ jsxs(
|
|
13357
13683
|
"button",
|
|
13358
13684
|
{
|
|
13685
|
+
type: "button",
|
|
13359
13686
|
onClick: () => onCollapsedChange(!collapsed),
|
|
13360
13687
|
title: collapsed ? "Expand sidebar" : "Collapse sidebar",
|
|
13361
13688
|
className: cn(
|
|
@@ -13422,6 +13749,7 @@ function CompactNavItem({
|
|
|
13422
13749
|
/* @__PURE__ */ jsxs(
|
|
13423
13750
|
"button",
|
|
13424
13751
|
{
|
|
13752
|
+
type: "button",
|
|
13425
13753
|
ref: setTriggerEl,
|
|
13426
13754
|
onMouseEnter: !mobile && hasChildren ? handleMouseEnter : void 0,
|
|
13427
13755
|
onMouseLeave: !mobile && hasChildren && isOpen ? handleMouseLeave : void 0,
|
|
@@ -13484,6 +13812,7 @@ function CompactNavItem({
|
|
|
13484
13812
|
mobile && expanded && hasChildren && item.children && /* @__PURE__ */ jsx("div", { className: "w-full flex flex-col gap-ds-1 pb-ds-1", children: item.children.map((child, ci) => /* @__PURE__ */ jsxs(
|
|
13485
13813
|
"button",
|
|
13486
13814
|
{
|
|
13815
|
+
type: "button",
|
|
13487
13816
|
onClick: () => onItemClick?.(child, ci),
|
|
13488
13817
|
className: cn(
|
|
13489
13818
|
"flex items-center gap-ds-2 px-ds-3 py-ds-1.5 text-[length:var(--ds-font-size-xs)] rounded-[var(--ds-radius-sm)] transition-colors cursor-pointer w-full",
|
|
@@ -13498,7 +13827,519 @@ function CompactNavItem({
|
|
|
13498
13827
|
)) })
|
|
13499
13828
|
] });
|
|
13500
13829
|
}
|
|
13830
|
+
var variantStyles4 = {
|
|
13831
|
+
default: "border-[var(--ds-border-default)] bg-[var(--ds-bg-surface)]",
|
|
13832
|
+
success: "border-[var(--ds-status-success)] bg-[var(--ds-status-success-bg)]",
|
|
13833
|
+
warning: "border-[var(--ds-status-warning)] bg-[var(--ds-status-warning-bg)]",
|
|
13834
|
+
error: "border-[var(--ds-status-error)] bg-[var(--ds-status-error-bg)]"
|
|
13835
|
+
};
|
|
13836
|
+
var variantIcons = {
|
|
13837
|
+
default: { name: "info", className: "text-[var(--ds-text-muted)]" },
|
|
13838
|
+
success: { name: "check", className: "text-[var(--ds-status-success)]" },
|
|
13839
|
+
warning: { name: "warning", className: "text-[var(--ds-status-warning)]" },
|
|
13840
|
+
error: { name: "error", className: "text-[var(--ds-status-error)]" }
|
|
13841
|
+
};
|
|
13842
|
+
var TOAST_POSITION_CLASSES = {
|
|
13843
|
+
"top-right": "top-[var(--ds-toast-inset-top)] right-[var(--ds-toast-inset-right)]",
|
|
13844
|
+
"top-left": "top-[var(--ds-toast-inset-top)] left-[var(--ds-toast-inset-left)]",
|
|
13845
|
+
"bottom-right": "bottom-[var(--ds-toast-inset-bottom-right)] right-[var(--ds-toast-inset-right)]",
|
|
13846
|
+
"bottom-left": "bottom-[var(--ds-toast-inset-bottom-left)] left-[var(--ds-toast-inset-left)]",
|
|
13847
|
+
"top-center": "top-[var(--ds-toast-inset-top)] left-1/2 -translate-x-1/2",
|
|
13848
|
+
"bottom-center": "bottom-ds-4 left-1/2 -translate-x-1/2"
|
|
13849
|
+
};
|
|
13850
|
+
var finite = (ms) => typeof ms === "number" && Number.isFinite(ms) && ms > 0;
|
|
13851
|
+
function Toast({ variant = "default", message, visible, onDismiss, duration = 5e3, pauseOnHover = false, action, actionWindow, position = "bottom-right", mode, container, inline = false, paused = false, onActionLapse, onAction, restartKey = 0 }) {
|
|
13852
|
+
const isMobile = useBreakpoint("sm");
|
|
13853
|
+
const isCentered = position === "top-center" || position === "bottom-center";
|
|
13854
|
+
const [hovered, setHovered] = useState(false);
|
|
13855
|
+
const onDismissRef = useLatest(onDismiss);
|
|
13856
|
+
const onLapseRef = useLatest(onActionLapse);
|
|
13857
|
+
const actionUsed = useRef(false);
|
|
13858
|
+
const phase = action ? finite(actionWindow) ? "window" : "none" : finite(duration) ? "plain" : "none";
|
|
13859
|
+
const total = phase === "window" ? actionWindow : phase === "plain" ? duration : 0;
|
|
13860
|
+
const timer = useRef(void 0);
|
|
13861
|
+
const remaining = useRef(total);
|
|
13862
|
+
const startedAt = useRef(0);
|
|
13863
|
+
const isPaused = paused || !inline && pauseOnHover && hovered;
|
|
13864
|
+
const stop = useCallback(() => {
|
|
13865
|
+
if (timer.current) {
|
|
13866
|
+
clearTimeout(timer.current);
|
|
13867
|
+
timer.current = void 0;
|
|
13868
|
+
remaining.current -= Date.now() - startedAt.current;
|
|
13869
|
+
}
|
|
13870
|
+
}, []);
|
|
13871
|
+
const start = useCallback(() => {
|
|
13872
|
+
if (phase === "none" || timer.current) return;
|
|
13873
|
+
startedAt.current = Date.now();
|
|
13874
|
+
const expire = phase === "window" ? () => {
|
|
13875
|
+
timer.current = void 0;
|
|
13876
|
+
if (onLapseRef.current) onLapseRef.current();
|
|
13877
|
+
else onDismissRef.current();
|
|
13878
|
+
} : () => {
|
|
13879
|
+
timer.current = void 0;
|
|
13880
|
+
onDismissRef.current();
|
|
13881
|
+
};
|
|
13882
|
+
timer.current = setTimeout(expire, Math.max(0, remaining.current));
|
|
13883
|
+
}, [phase, onDismissRef, onLapseRef]);
|
|
13884
|
+
useEffect(() => {
|
|
13885
|
+
if (!visible) return;
|
|
13886
|
+
remaining.current = total;
|
|
13887
|
+
if (timer.current) {
|
|
13888
|
+
clearTimeout(timer.current);
|
|
13889
|
+
timer.current = void 0;
|
|
13890
|
+
}
|
|
13891
|
+
if (!isPaused) start();
|
|
13892
|
+
return () => {
|
|
13893
|
+
if (timer.current) {
|
|
13894
|
+
clearTimeout(timer.current);
|
|
13895
|
+
timer.current = void 0;
|
|
13896
|
+
}
|
|
13897
|
+
};
|
|
13898
|
+
}, [visible, phase, total, restartKey]);
|
|
13899
|
+
useEffect(() => {
|
|
13900
|
+
if (!visible) return;
|
|
13901
|
+
if (isPaused) stop();
|
|
13902
|
+
else start();
|
|
13903
|
+
}, [isPaused, visible, start, stop]);
|
|
13904
|
+
useEffect(() => {
|
|
13905
|
+
actionUsed.current = false;
|
|
13906
|
+
}, [restartKey]);
|
|
13907
|
+
if (!visible) return null;
|
|
13908
|
+
const icon = variantIcons[variant];
|
|
13909
|
+
const pressAction = () => {
|
|
13910
|
+
if (!action || actionUsed.current) return;
|
|
13911
|
+
actionUsed.current = true;
|
|
13912
|
+
if (onAction) onAction();
|
|
13913
|
+
else {
|
|
13914
|
+
void action.onClick();
|
|
13915
|
+
onDismissRef.current();
|
|
13916
|
+
}
|
|
13917
|
+
};
|
|
13918
|
+
const card = /* @__PURE__ */ jsxs(
|
|
13919
|
+
"div",
|
|
13920
|
+
{
|
|
13921
|
+
"data-toast": "",
|
|
13922
|
+
"data-variant": variant,
|
|
13923
|
+
role: inline ? void 0 : variant === "error" ? "alert" : "status",
|
|
13924
|
+
"aria-live": inline ? void 0 : variant === "error" ? "assertive" : "polite",
|
|
13925
|
+
"data-mode": inline ? mode : void 0,
|
|
13926
|
+
className: cn(
|
|
13927
|
+
"flex items-center gap-ds-3 px-ds-4 py-ds-3",
|
|
13928
|
+
isCentered ? "min-w-[360px] max-w-[560px]" : "min-w-[280px] max-w-[420px]",
|
|
13929
|
+
"border-[length:var(--ds-border-width)]",
|
|
13930
|
+
GLASS_DROPDOWN,
|
|
13931
|
+
"rounded-[var(--ds-radius-md)]",
|
|
13932
|
+
"text-sm text-[var(--ds-text-primary)]",
|
|
13933
|
+
variantStyles4[variant]
|
|
13934
|
+
),
|
|
13935
|
+
children: [
|
|
13936
|
+
/* @__PURE__ */ jsx(Icon, { name: icon.name, size: 18, className: cn("shrink-0", icon.className) }),
|
|
13937
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1", children: message }),
|
|
13938
|
+
action && /* @__PURE__ */ jsx(
|
|
13939
|
+
"button",
|
|
13940
|
+
{
|
|
13941
|
+
type: "button",
|
|
13942
|
+
onClick: pressAction,
|
|
13943
|
+
className: "shrink-0 text-xs font-semibold text-[var(--ds-accent-primary)] hover:underline cursor-pointer",
|
|
13944
|
+
children: action.label
|
|
13945
|
+
}
|
|
13946
|
+
),
|
|
13947
|
+
/* @__PURE__ */ jsx(
|
|
13948
|
+
"button",
|
|
13949
|
+
{
|
|
13950
|
+
type: "button",
|
|
13951
|
+
onClick: onDismiss,
|
|
13952
|
+
"aria-label": "Dismiss notification",
|
|
13953
|
+
className: "text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)] transition-colors cursor-pointer shrink-0",
|
|
13954
|
+
children: /* @__PURE__ */ jsx(Icon, { name: "close", size: 16 })
|
|
13955
|
+
}
|
|
13956
|
+
)
|
|
13957
|
+
]
|
|
13958
|
+
}
|
|
13959
|
+
);
|
|
13960
|
+
if (inline) return card;
|
|
13961
|
+
return createPortal(
|
|
13962
|
+
/* @__PURE__ */ jsx(
|
|
13963
|
+
"div",
|
|
13964
|
+
{
|
|
13965
|
+
"data-mode": mode,
|
|
13966
|
+
onMouseEnter: pauseOnHover ? () => setHovered(true) : void 0,
|
|
13967
|
+
onMouseLeave: pauseOnHover ? () => setHovered(false) : void 0,
|
|
13968
|
+
className: cn(
|
|
13969
|
+
"fixed z-[var(--ds-z-toast)]",
|
|
13970
|
+
isMobile ? "bottom-ds-4 left-ds-4 right-ds-4" : TOAST_POSITION_CLASSES[position]
|
|
13971
|
+
),
|
|
13972
|
+
children: card
|
|
13973
|
+
}
|
|
13974
|
+
),
|
|
13975
|
+
container ?? document.body
|
|
13976
|
+
);
|
|
13977
|
+
}
|
|
13978
|
+
var ToastContext = createContext(null);
|
|
13979
|
+
var ToastLedgerCtx = createContext(null);
|
|
13980
|
+
var BottomNavPresenceCtx = createContext(null);
|
|
13981
|
+
function useToast() {
|
|
13982
|
+
const ctx = useContext(ToastContext);
|
|
13983
|
+
if (!ctx) {
|
|
13984
|
+
throw new Error("useToast must be used within <ToastProvider>: the app shell's (get_app_shell writes it around AppShell). A page outside the shell (sign-in, a public page) shows its messages inline instead: an Alert above the form, and each field's error below the field.");
|
|
13985
|
+
}
|
|
13986
|
+
return ctx;
|
|
13987
|
+
}
|
|
13988
|
+
function useToastOptional() {
|
|
13989
|
+
return useContext(ToastContext);
|
|
13990
|
+
}
|
|
13991
|
+
var toastSeq = 0;
|
|
13992
|
+
var heardSeq = 0;
|
|
13993
|
+
var HEARD_MS = 7e3;
|
|
13994
|
+
var RUN_END_MS = 20;
|
|
13995
|
+
var isThenable2 = (value) => !!value && typeof value.then === "function";
|
|
13996
|
+
function textOf(node) {
|
|
13997
|
+
if (node == null || typeof node === "boolean") return "";
|
|
13998
|
+
if (typeof node === "string" || typeof node === "number") return String(node);
|
|
13999
|
+
if (Array.isArray(node)) return node.map(textOf).join("");
|
|
14000
|
+
if (typeof node === "object" && "props" in node) return textOf(node.props.children);
|
|
14001
|
+
return "";
|
|
14002
|
+
}
|
|
14003
|
+
var mergeable = (e) => !e.action && e.variant !== "error";
|
|
14004
|
+
function fill(entries, slots) {
|
|
14005
|
+
let shown = entries.filter((e) => e.shown).length;
|
|
14006
|
+
if (shown >= slots || shown === entries.length) return entries;
|
|
14007
|
+
const next = [...entries];
|
|
14008
|
+
while (shown < slots) {
|
|
14009
|
+
const urgent = next.findIndex((e) => !e.shown && !mergeable(e));
|
|
14010
|
+
const at = urgent !== -1 ? urgent : next.findIndex((e) => !e.shown);
|
|
14011
|
+
if (at === -1) break;
|
|
14012
|
+
next[at] = { ...next[at], shown: true };
|
|
14013
|
+
shown++;
|
|
14014
|
+
}
|
|
14015
|
+
return next;
|
|
14016
|
+
}
|
|
14017
|
+
function ToastProvider({ children, maxVisible = 3, position = "bottom-right", duration = 5e3, mode, pauseOnHover = true, coalesce = true }) {
|
|
14018
|
+
const slots = Math.max(1, Math.floor(Number.isFinite(maxVisible) ? maxVisible : 1));
|
|
14019
|
+
const [list, setList] = useState([]);
|
|
14020
|
+
const entries = useRef([]);
|
|
14021
|
+
const isMobile = useBreakpoint("sm");
|
|
14022
|
+
const shownDuringRuns = useRef([]);
|
|
14023
|
+
const showSeq = useRef(0);
|
|
14024
|
+
const runs = useRef(/* @__PURE__ */ new Map());
|
|
14025
|
+
const runSeq = useRef(0);
|
|
14026
|
+
const [heard, setHeard] = useState([]);
|
|
14027
|
+
const [hovered, setHovered] = useState(false);
|
|
14028
|
+
const [focusInside, setFocusInside] = useState(false);
|
|
14029
|
+
const paused = pauseOnHover && hovered || focusInside;
|
|
14030
|
+
const stackRef = useRef(null);
|
|
14031
|
+
const returnTo = useRef(null);
|
|
14032
|
+
const pressed = useRef(/* @__PURE__ */ new Set());
|
|
14033
|
+
const pointerAt = useRef(0);
|
|
14034
|
+
const viaKey = useRef(false);
|
|
14035
|
+
const refocus = useRef(false);
|
|
14036
|
+
const pendingHeard = useRef(/* @__PURE__ */ new Map());
|
|
14037
|
+
const heardTimer = useRef(void 0);
|
|
14038
|
+
const [bottomNavs, setBottomNavs] = useState(0);
|
|
14039
|
+
const registerBottomNav = useCallback(() => {
|
|
14040
|
+
setBottomNavs((n) => n + 1);
|
|
14041
|
+
let gone = false;
|
|
14042
|
+
return () => {
|
|
14043
|
+
if (gone) return;
|
|
14044
|
+
gone = true;
|
|
14045
|
+
setBottomNavs((n) => n - 1);
|
|
14046
|
+
};
|
|
14047
|
+
}, []);
|
|
14048
|
+
const commit = useCallback((next) => {
|
|
14049
|
+
entries.current = fill(next, slots);
|
|
14050
|
+
setList(entries.current);
|
|
14051
|
+
}, [slots]);
|
|
14052
|
+
useEffect(() => {
|
|
14053
|
+
let kept = 0;
|
|
14054
|
+
const reslotted = entries.current.map((e) => e.shown && ++kept > slots ? { ...e, shown: false } : e);
|
|
14055
|
+
const next = fill(reslotted, slots);
|
|
14056
|
+
if (next.length === entries.current.length && next.every((e, i) => e === entries.current[i])) return;
|
|
14057
|
+
commit(next);
|
|
14058
|
+
}, [slots, commit]);
|
|
14059
|
+
if (list.every((t) => !t.shown) && (hovered || focusInside)) {
|
|
14060
|
+
setHovered(false);
|
|
14061
|
+
setFocusInside(false);
|
|
14062
|
+
}
|
|
14063
|
+
const clearTimers = useRef(/* @__PURE__ */ new Set());
|
|
14064
|
+
const announce = useCallback((entry) => {
|
|
14065
|
+
pendingHeard.current.set(entry.id, entry);
|
|
14066
|
+
if (heardTimer.current) return;
|
|
14067
|
+
heardTimer.current = setTimeout(() => {
|
|
14068
|
+
heardTimer.current = void 0;
|
|
14069
|
+
const batch = [...pendingHeard.current.values()].map((e) => {
|
|
14070
|
+
const words = textOf(e.message).trim();
|
|
14071
|
+
const sentence = !words || /[.!?…]$/.test(words) ? words : `${words}.`;
|
|
14072
|
+
return { id: `heard-${++heardSeq}`, assertive: e.variant === "error", text: e.action ? `${sentence} Press F8 to reach ${e.action.label}.`.trim() : sentence };
|
|
14073
|
+
}).filter((h) => h.text);
|
|
14074
|
+
pendingHeard.current.clear();
|
|
14075
|
+
if (!batch.length) return;
|
|
14076
|
+
setHeard((list2) => [...list2, ...batch].slice(-5));
|
|
14077
|
+
const ids = new Set(batch.map((h) => h.id));
|
|
14078
|
+
const timer = setTimeout(() => {
|
|
14079
|
+
clearTimers.current.delete(timer);
|
|
14080
|
+
setHeard((list2) => list2.filter((h) => !ids.has(h.id)));
|
|
14081
|
+
}, HEARD_MS);
|
|
14082
|
+
clearTimers.current.add(timer);
|
|
14083
|
+
}, 0);
|
|
14084
|
+
}, []);
|
|
14085
|
+
useEffect(() => () => {
|
|
14086
|
+
if (heardTimer.current) clearTimeout(heardTimer.current);
|
|
14087
|
+
heardTimer.current = void 0;
|
|
14088
|
+
clearTimers.current.forEach(clearTimeout);
|
|
14089
|
+
clearTimers.current.clear();
|
|
14090
|
+
}, []);
|
|
14091
|
+
const leaving = useCallback((id) => {
|
|
14092
|
+
const stack = stackRef.current;
|
|
14093
|
+
const holder = id === void 0 ? stack : [...stack?.querySelectorAll("[data-toast-id]") ?? []].find((n) => n.getAttribute("data-toast-id") === id);
|
|
14094
|
+
if (!holder?.contains(document.activeElement)) return;
|
|
14095
|
+
refocus.current = true;
|
|
14096
|
+
setFocusInside(false);
|
|
14097
|
+
}, []);
|
|
14098
|
+
const remove = useCallback((id) => {
|
|
14099
|
+
leaving(id);
|
|
14100
|
+
commit(entries.current.filter((t) => t.id !== id));
|
|
14101
|
+
}, [commit, leaving]);
|
|
14102
|
+
const dismissAll = useCallback(() => {
|
|
14103
|
+
leaving();
|
|
14104
|
+
commit([]);
|
|
14105
|
+
}, [commit, leaving]);
|
|
14106
|
+
const noteShown = useCallback((id, variant, action, fresh) => {
|
|
14107
|
+
if (runs.current.size) shownDuringRuns.current.push({ seq: ++showSeq.current, at: Date.now(), id, variant, action, fresh });
|
|
14108
|
+
}, []);
|
|
14109
|
+
const update = useCallback((id, message, options = {}) => {
|
|
14110
|
+
const list2 = entries.current;
|
|
14111
|
+
const at = list2.findIndex((t2) => t2.id === id);
|
|
14112
|
+
if (at === -1) return;
|
|
14113
|
+
pressed.current.delete(id);
|
|
14114
|
+
const t = list2[at];
|
|
14115
|
+
const next = [...list2];
|
|
14116
|
+
next[at] = { ...t, message, variant: options.variant ?? t.variant, duration: options.duration ?? t.duration, action: options.action ?? t.action, actionWindow: options.actionWindow ?? t.actionWindow, key: options.key ?? t.key, version: t.version + 1 };
|
|
14117
|
+
commit(next);
|
|
14118
|
+
announce(next[at]);
|
|
14119
|
+
noteShown(id, next[at].variant, !!next[at].action, false);
|
|
14120
|
+
}, [commit, announce, noteShown]);
|
|
14121
|
+
const toast = useCallback((message, options = {}) => {
|
|
14122
|
+
const list2 = entries.current;
|
|
14123
|
+
const base = { message, variant: options.variant ?? "default", duration: options.duration ?? duration, action: options.action, actionWindow: options.actionWindow, key: options.key };
|
|
14124
|
+
if (options.id) {
|
|
14125
|
+
const at = list2.findIndex((t) => t.id === options.id);
|
|
14126
|
+
if (at !== -1) {
|
|
14127
|
+
const next = [...list2];
|
|
14128
|
+
next[at] = { ...list2[at], ...base, version: list2[at].version + 1 };
|
|
14129
|
+
pressed.current.delete(options.id);
|
|
14130
|
+
commit(next);
|
|
14131
|
+
announce(next[at]);
|
|
14132
|
+
noteShown(options.id, base.variant, !!base.action, false);
|
|
14133
|
+
return options.id;
|
|
14134
|
+
}
|
|
14135
|
+
}
|
|
14136
|
+
if (coalesce && base.key && mergeable(base)) {
|
|
14137
|
+
const at = list2.findIndex((t) => t.key === base.key && mergeable(t));
|
|
14138
|
+
if (at !== -1) {
|
|
14139
|
+
const next = [...list2];
|
|
14140
|
+
next[at] = { ...list2[at], ...base, version: list2[at].version + 1 };
|
|
14141
|
+
commit(next);
|
|
14142
|
+
announce(next[at]);
|
|
14143
|
+
noteShown(list2[at].id, base.variant, !!base.action, false);
|
|
14144
|
+
return list2[at].id;
|
|
14145
|
+
}
|
|
14146
|
+
}
|
|
14147
|
+
const id = options.id ?? `toast-${++toastSeq}`;
|
|
14148
|
+
const entry = { id, ...base, shown: false, version: 0 };
|
|
14149
|
+
commit([...list2, entry]);
|
|
14150
|
+
announce(entry);
|
|
14151
|
+
noteShown(id, base.variant, !!base.action, true);
|
|
14152
|
+
return id;
|
|
14153
|
+
}, [duration, coalesce, commit, announce, noteShown]);
|
|
14154
|
+
const api = useMemo(() => ({
|
|
14155
|
+
toast,
|
|
14156
|
+
success: (m, o) => toast(m, { ...o, variant: "success" }),
|
|
14157
|
+
warning: (m, o) => toast(m, { ...o, variant: "warning" }),
|
|
14158
|
+
error: (m, o) => toast(m, { ...o, variant: "error" }),
|
|
14159
|
+
update,
|
|
14160
|
+
dismiss: remove,
|
|
14161
|
+
dismissAll,
|
|
14162
|
+
promise: async (promise, messages, options = {}) => {
|
|
14163
|
+
const id = toast(messages.loading, { ...options, variant: "default", duration: Infinity });
|
|
14164
|
+
try {
|
|
14165
|
+
const value = await promise;
|
|
14166
|
+
update(id, typeof messages.success === "function" ? messages.success(value) : messages.success, { variant: "success", duration });
|
|
14167
|
+
return value;
|
|
14168
|
+
} catch (err) {
|
|
14169
|
+
update(id, typeof messages.error === "function" ? messages.error(err) : messages.error, { variant: "error", duration });
|
|
14170
|
+
throw err;
|
|
14171
|
+
}
|
|
14172
|
+
}
|
|
14173
|
+
}), [toast, update, remove, dismissAll, duration]);
|
|
14174
|
+
const ledger = useMemo(() => ({
|
|
14175
|
+
begin: () => {
|
|
14176
|
+
const run = ++runSeq.current;
|
|
14177
|
+
const overlapped = runs.current.size > 0;
|
|
14178
|
+
if (overlapped) runs.current.forEach((r) => {
|
|
14179
|
+
r.overlapped = true;
|
|
14180
|
+
});
|
|
14181
|
+
runs.current.set(run, { from: showSeq.current, overlapped });
|
|
14182
|
+
return run;
|
|
14183
|
+
},
|
|
14184
|
+
end: (run) => {
|
|
14185
|
+
const watched = runs.current.get(run);
|
|
14186
|
+
runs.current.delete(run);
|
|
14187
|
+
if (!watched) return { problem: false };
|
|
14188
|
+
const during = shownDuringRuns.current.filter((s) => s.seq > watched.from);
|
|
14189
|
+
const oldest = Math.min(...[...runs.current.values()].map((r) => r.from));
|
|
14190
|
+
shownDuringRuns.current = runs.current.size ? shownDuringRuns.current.filter((s) => s.seq > oldest) : [];
|
|
14191
|
+
const problem = during.some((s) => s.variant === "error" || s.variant === "warning");
|
|
14192
|
+
const endedAt = Date.now();
|
|
14193
|
+
const confirmations = during.filter((s) => s.fresh && !s.action && (s.variant === "success" || s.variant === "default"));
|
|
14194
|
+
if (watched.overlapped || confirmations.length !== 1 || endedAt - confirmations[0].at > RUN_END_MS) return { problem };
|
|
14195
|
+
const entry = entries.current.find((t) => t.id === confirmations[0].id);
|
|
14196
|
+
return { problem, own: entry && !entry.action ? { id: entry.id, message: entry.message, variant: entry.variant } : void 0 };
|
|
14197
|
+
},
|
|
14198
|
+
has: (id) => entries.current.some((t) => t.id === id)
|
|
14199
|
+
}), []);
|
|
14200
|
+
const pressAction = useCallback((id) => {
|
|
14201
|
+
const entry = entries.current.find((t) => t.id === id);
|
|
14202
|
+
if (!entry?.action) return;
|
|
14203
|
+
const run = entry.action.onClick;
|
|
14204
|
+
leaving(id);
|
|
14205
|
+
commit(entries.current.map((t) => t.id === id ? { ...t, action: void 0, actionWindow: void 0, version: t.version + 1 } : t));
|
|
14206
|
+
pressed.current.add(id);
|
|
14207
|
+
const done = () => {
|
|
14208
|
+
if (pressed.current.delete(id)) remove(id);
|
|
14209
|
+
};
|
|
14210
|
+
const failed = (err) => {
|
|
14211
|
+
done();
|
|
14212
|
+
console.error(err);
|
|
14213
|
+
};
|
|
14214
|
+
let result;
|
|
14215
|
+
try {
|
|
14216
|
+
result = run();
|
|
14217
|
+
} catch (err) {
|
|
14218
|
+
failed(err);
|
|
14219
|
+
return;
|
|
14220
|
+
}
|
|
14221
|
+
if (isThenable2(result)) result.then(done, failed);
|
|
14222
|
+
else done();
|
|
14223
|
+
}, [commit, leaving, remove]);
|
|
14224
|
+
const lapse = useCallback((id) => {
|
|
14225
|
+
const list2 = entries.current;
|
|
14226
|
+
const at = list2.findIndex((t) => t.id === id);
|
|
14227
|
+
if (at === -1) return;
|
|
14228
|
+
const next = [...list2];
|
|
14229
|
+
next[at] = { ...list2[at], action: void 0, actionWindow: void 0, version: list2[at].version + 1 };
|
|
14230
|
+
commit(next);
|
|
14231
|
+
}, [commit]);
|
|
14232
|
+
useEffect(() => {
|
|
14233
|
+
const onKey = (e) => {
|
|
14234
|
+
if (e.key !== "F8" || e.defaultPrevented) return;
|
|
14235
|
+
const stack = stackRef.current;
|
|
14236
|
+
if (!stack) return;
|
|
14237
|
+
e.preventDefault();
|
|
14238
|
+
const active = document.activeElement;
|
|
14239
|
+
if (!stack.contains(active)) {
|
|
14240
|
+
returnTo.current = active instanceof HTMLElement && active !== document.body ? active : null;
|
|
14241
|
+
viaKey.current = true;
|
|
14242
|
+
}
|
|
14243
|
+
(stack.querySelector("button") ?? stack).focus();
|
|
14244
|
+
viaKey.current = false;
|
|
14245
|
+
};
|
|
14246
|
+
document.addEventListener("keydown", onKey);
|
|
14247
|
+
return () => document.removeEventListener("keydown", onKey);
|
|
14248
|
+
}, []);
|
|
14249
|
+
useEffect(() => {
|
|
14250
|
+
if (!refocus.current) return;
|
|
14251
|
+
refocus.current = false;
|
|
14252
|
+
const back = returnTo.current;
|
|
14253
|
+
const next = stackRef.current?.querySelector("button");
|
|
14254
|
+
const main = document.querySelector("main");
|
|
14255
|
+
const byPointer = Date.now() - pointerAt.current < 1e3;
|
|
14256
|
+
if (back?.isConnected) back.focus();
|
|
14257
|
+
else if (byPointer) {
|
|
14258
|
+
if (stackRef.current?.contains(document.activeElement)) document.activeElement.blur();
|
|
14259
|
+
} else if (next) next.focus();
|
|
14260
|
+
else if (main) {
|
|
14261
|
+
if (!main.hasAttribute("tabindex")) {
|
|
14262
|
+
main.setAttribute("tabindex", "-1");
|
|
14263
|
+
main.addEventListener("blur", () => main.removeAttribute("tabindex"), { once: true });
|
|
14264
|
+
}
|
|
14265
|
+
main.focus();
|
|
14266
|
+
}
|
|
14267
|
+
}, [list]);
|
|
14268
|
+
const shown = list.filter((t) => t.shown);
|
|
14269
|
+
const waiting = list.length - shown.length;
|
|
14270
|
+
const isTop = position.startsWith("top");
|
|
14271
|
+
const hasBottomNav = isMobile && bottomNavs > 0;
|
|
14272
|
+
return /* @__PURE__ */ jsx(ToastContext.Provider, { value: api, children: /* @__PURE__ */ jsxs(ToastLedgerCtx.Provider, { value: ledger, children: [
|
|
14273
|
+
/* @__PURE__ */ jsx(BottomNavPresenceCtx.Provider, { value: registerBottomNav, children }),
|
|
14274
|
+
/* @__PURE__ */ jsx("div", { className: "sr-only", "aria-live": "polite", "data-toast-announcer": "polite", children: heard.filter((h) => !h.assertive).map((h) => /* @__PURE__ */ jsx("p", { children: h.text }, h.id)) }),
|
|
14275
|
+
/* @__PURE__ */ jsx("div", { className: "sr-only", "aria-live": "assertive", "data-toast-announcer": "assertive", children: heard.filter((h) => h.assertive).map((h) => /* @__PURE__ */ jsx("p", { children: h.text }, h.id)) }),
|
|
14276
|
+
shown.length > 0 && createPortal(
|
|
14277
|
+
/* @__PURE__ */ jsxs(
|
|
14278
|
+
"div",
|
|
14279
|
+
{
|
|
14280
|
+
ref: stackRef,
|
|
14281
|
+
role: "region",
|
|
14282
|
+
"aria-label": "Notifications",
|
|
14283
|
+
tabIndex: -1,
|
|
14284
|
+
"data-mode": mode,
|
|
14285
|
+
"data-toast-stack": "",
|
|
14286
|
+
onMouseEnter: () => setHovered(true),
|
|
14287
|
+
onMouseLeave: () => setHovered(false),
|
|
14288
|
+
onPointerDownCapture: () => {
|
|
14289
|
+
pointerAt.current = Date.now();
|
|
14290
|
+
},
|
|
14291
|
+
onFocusCapture: (e) => {
|
|
14292
|
+
setFocusInside(true);
|
|
14293
|
+
const from = e.relatedTarget;
|
|
14294
|
+
if (viaKey.current || from instanceof Node && e.currentTarget.contains(from)) return;
|
|
14295
|
+
returnTo.current = from instanceof HTMLElement ? from : null;
|
|
14296
|
+
},
|
|
14297
|
+
onBlurCapture: (e) => {
|
|
14298
|
+
if (!e.currentTarget.contains(e.relatedTarget)) setFocusInside(false);
|
|
14299
|
+
},
|
|
14300
|
+
className: cn(
|
|
14301
|
+
"fixed z-[var(--ds-z-toast)] flex gap-ds-2 pointer-events-none outline-none",
|
|
14302
|
+
isTop ? "flex-col" : "flex-col-reverse",
|
|
14303
|
+
isMobile ? cn("left-ds-4 right-ds-4", !hasBottomNav && "bottom-ds-4") : TOAST_POSITION_CLASSES[position]
|
|
14304
|
+
),
|
|
14305
|
+
style: hasBottomNav ? { bottom: "calc(var(--ds-space-12) + var(--ds-space-2) + var(--ds-space-4) + env(safe-area-inset-bottom))" } : void 0,
|
|
14306
|
+
children: [
|
|
14307
|
+
shown.map((t) => /* @__PURE__ */ jsx("div", { "data-toast-id": t.id, className: "pointer-events-auto", children: /* @__PURE__ */ jsx(
|
|
14308
|
+
Toast,
|
|
14309
|
+
{
|
|
14310
|
+
inline: true,
|
|
14311
|
+
visible: true,
|
|
14312
|
+
variant: t.variant,
|
|
14313
|
+
message: t.message,
|
|
14314
|
+
duration: t.duration,
|
|
14315
|
+
action: t.action,
|
|
14316
|
+
actionWindow: t.actionWindow,
|
|
14317
|
+
mode,
|
|
14318
|
+
paused,
|
|
14319
|
+
restartKey: t.version,
|
|
14320
|
+
onAction: () => pressAction(t.id),
|
|
14321
|
+
onActionLapse: () => lapse(t.id),
|
|
14322
|
+
onDismiss: () => remove(t.id)
|
|
14323
|
+
}
|
|
14324
|
+
) }, t.id)),
|
|
14325
|
+
(waiting > 0 || shown.length >= 2) && /* @__PURE__ */ jsxs("div", { className: "pointer-events-auto flex items-center justify-end gap-ds-2 text-xs", "data-toast-overflow": "", children: [
|
|
14326
|
+
waiting > 0 && /* @__PURE__ */ jsxs("span", { className: "rounded-[var(--ds-radius-full)] bg-[var(--ds-bg-muted)] px-ds-2 py-ds-0.5 font-medium text-[var(--ds-text-secondary)]", children: [
|
|
14327
|
+
"+",
|
|
14328
|
+
waiting,
|
|
14329
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: " more waiting" })
|
|
14330
|
+
] }),
|
|
14331
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: dismissAll, className: "font-medium text-[var(--ds-text-secondary)] hover:text-[var(--ds-text-primary)] hover:underline cursor-pointer", children: "Clear all" })
|
|
14332
|
+
] })
|
|
14333
|
+
]
|
|
14334
|
+
}
|
|
14335
|
+
),
|
|
14336
|
+
document.body
|
|
14337
|
+
)
|
|
14338
|
+
] }) });
|
|
14339
|
+
}
|
|
13501
14340
|
function BottomNav({ items, onItemClick, maxVisible = 5, className, ref }) {
|
|
14341
|
+
const registerWithToasts = useContext(BottomNavPresenceCtx);
|
|
14342
|
+
useEffect(() => registerWithToasts?.(), [registerWithToasts]);
|
|
13502
14343
|
const needsOverflow = items.length > maxVisible;
|
|
13503
14344
|
const visibleItems = needsOverflow ? items.slice(0, maxVisible - 1) : items;
|
|
13504
14345
|
const overflowItems = needsOverflow ? items.slice(maxVisible - 1) : [];
|
|
@@ -13533,6 +14374,7 @@ function BottomNav({ items, onItemClick, maxVisible = 5, className, ref }) {
|
|
|
13533
14374
|
/* @__PURE__ */ jsxs(
|
|
13534
14375
|
"button",
|
|
13535
14376
|
{
|
|
14377
|
+
type: "button",
|
|
13536
14378
|
onClick: () => setOverflowOpen(!overflowOpen),
|
|
13537
14379
|
"aria-expanded": overflowOpen,
|
|
13538
14380
|
"aria-haspopup": "true",
|
|
@@ -13560,6 +14402,7 @@ function BottomNav({ items, onItemClick, maxVisible = 5, className, ref }) {
|
|
|
13560
14402
|
children: overflowItems.map((item, i) => /* @__PURE__ */ jsxs(
|
|
13561
14403
|
"button",
|
|
13562
14404
|
{
|
|
14405
|
+
type: "button",
|
|
13563
14406
|
role: "menuitem",
|
|
13564
14407
|
onClick: () => {
|
|
13565
14408
|
onItemClick?.(item, maxVisible - 1 + i);
|
|
@@ -13589,6 +14432,7 @@ function NavButton({ item, onClick }) {
|
|
|
13589
14432
|
return /* @__PURE__ */ jsxs(
|
|
13590
14433
|
"button",
|
|
13591
14434
|
{
|
|
14435
|
+
type: "button",
|
|
13592
14436
|
onClick,
|
|
13593
14437
|
className: cn(
|
|
13594
14438
|
"flex flex-col items-center justify-center gap-ds-0.5 flex-1 h-full",
|
|
@@ -14991,6 +15835,7 @@ function NavMenu({
|
|
|
14991
15835
|
/* @__PURE__ */ jsxs(
|
|
14992
15836
|
"button",
|
|
14993
15837
|
{
|
|
15838
|
+
type: "button",
|
|
14994
15839
|
ref: triggerRef,
|
|
14995
15840
|
onClick: () => setOpen(!open),
|
|
14996
15841
|
"aria-expanded": open,
|
|
@@ -15187,7 +16032,8 @@ var sizeClasses = {
|
|
|
15187
16032
|
full: "max-w-[calc(100vw-2rem)]"
|
|
15188
16033
|
};
|
|
15189
16034
|
function Dialog({ open, onClose: onCloseProp, title, description, children, footer, variant = "default", size = "md", alert = false, container, onSubmit, dirty, onDiscard }) {
|
|
15190
|
-
const
|
|
16035
|
+
const { marked, mark } = useOverlayMark(open);
|
|
16036
|
+
const guard = useDirtyGuard(dirty ?? marked, onCloseProp, onDiscard);
|
|
15191
16037
|
const onClose = guard.requestClose;
|
|
15192
16038
|
const titleId = useId();
|
|
15193
16039
|
const descriptionId = useId();
|
|
@@ -15255,7 +16101,9 @@ function Dialog({ open, onClose: onCloseProp, title, description, children, foot
|
|
|
15255
16101
|
"form",
|
|
15256
16102
|
{
|
|
15257
16103
|
onSubmit: (e) => {
|
|
16104
|
+
if (e.target !== e.currentTarget) return;
|
|
15258
16105
|
e.preventDefault();
|
|
16106
|
+
e.stopPropagation();
|
|
15259
16107
|
if (variant === "destructive") return;
|
|
15260
16108
|
const submitter = e.nativeEvent.submitter;
|
|
15261
16109
|
const implicit = !submitter || submitter === defaultButtonRef.current;
|
|
@@ -15284,6 +16132,7 @@ function Dialog({ open, onClose: onCloseProp, title, description, children, foot
|
|
|
15284
16132
|
{
|
|
15285
16133
|
ref: dialogRef,
|
|
15286
16134
|
role: alert ? "alertdialog" : "dialog",
|
|
16135
|
+
...{ [OVERLAY_ROOT_ATTR]: "" },
|
|
15287
16136
|
"aria-modal": "true",
|
|
15288
16137
|
"data-gs": "dialog",
|
|
15289
16138
|
"aria-labelledby": titleId,
|
|
@@ -15324,7 +16173,7 @@ function Dialog({ open, onClose: onCloseProp, title, description, children, foot
|
|
|
15324
16173
|
}
|
|
15325
16174
|
),
|
|
15326
16175
|
description && /* @__PURE__ */ jsx("p", { id: descriptionId, className: "mt-ds-2 text-sm text-[var(--ds-text-muted)]", children: description }),
|
|
15327
|
-
children && /* @__PURE__ */ jsx("div", { className: "mt-ds-4", children: /* @__PURE__ */ jsx(OverlayCloseCtx, { value: onClose, children }) })
|
|
16176
|
+
children && /* @__PURE__ */ jsx("div", { className: "mt-ds-4", children: /* @__PURE__ */ jsx(OverlayMarkScope, { mark, children: /* @__PURE__ */ jsx(OverlayCloseCtx, { value: onClose, children }) }) })
|
|
15328
16177
|
] })
|
|
15329
16178
|
] }) }),
|
|
15330
16179
|
/* @__PURE__ */ jsx(DiscardConfirm, { open: guard.confirming, onKeep: guard.keep, onDiscard: guard.discard }),
|
|
@@ -15350,6 +16199,7 @@ function HamburgerButton({ onClick, open, className: cls }) {
|
|
|
15350
16199
|
return /* @__PURE__ */ jsx(
|
|
15351
16200
|
"button",
|
|
15352
16201
|
{
|
|
16202
|
+
type: "button",
|
|
15353
16203
|
onClick,
|
|
15354
16204
|
"aria-label": open ? "Close navigation menu" : "Open navigation menu",
|
|
15355
16205
|
"aria-expanded": open ?? void 0,
|
|
@@ -15484,7 +16334,7 @@ var Navbar = forwardRef(function Navbar2({
|
|
|
15484
16334
|
}
|
|
15485
16335
|
focus.onExit?.();
|
|
15486
16336
|
};
|
|
15487
|
-
const exitControl = focus ? /* @__PURE__ */ jsx(Button, { variant: "secondary", size: "sm", onClick: requestExit, children: focus.exitLabel ?? (focus.kind === "before-app" ? "Save and log out" : "Exit") }) : null;
|
|
16337
|
+
const exitControl = focus ? /* @__PURE__ */ jsx(Button, { type: "button", variant: "secondary", size: "sm", onClick: requestExit, children: focus.exitLabel ?? (focus.kind === "before-app" ? "Save and log out" : "Exit") }) : null;
|
|
15488
16338
|
const shownUserMenu = focus?.kind === "before-app" ? null : userMenu;
|
|
15489
16339
|
const asking = confirmExit && focus?.kind === "in-app" && !!appShell?.hasUnsavedChanges;
|
|
15490
16340
|
if (confirmExit && !asking) setConfirmExit(false);
|
|
@@ -15500,8 +16350,8 @@ var Navbar = forwardRef(function Navbar2({
|
|
|
15500
16350
|
alert: true,
|
|
15501
16351
|
container: shellEl ?? void 0,
|
|
15502
16352
|
footer: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
15503
|
-
/* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () => setConfirmExit(false), children: "Keep editing" }),
|
|
15504
|
-
/* @__PURE__ */ jsx(Button, { variant: "destructive", onClick: () => {
|
|
16353
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "secondary", onClick: () => setConfirmExit(false), children: "Keep editing" }),
|
|
16354
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "destructive", onClick: () => {
|
|
15505
16355
|
setConfirmExit(false);
|
|
15506
16356
|
focus.onExit?.();
|
|
15507
16357
|
}, children: "Discard changes" })
|
|
@@ -15652,6 +16502,7 @@ function MobileMenuItem({
|
|
|
15652
16502
|
return /* @__PURE__ */ jsxs(
|
|
15653
16503
|
"button",
|
|
15654
16504
|
{
|
|
16505
|
+
type: "button",
|
|
15655
16506
|
onClick,
|
|
15656
16507
|
className: cn(
|
|
15657
16508
|
"flex items-center gap-ds-3 px-ds-3 py-ds-3 text-sm relative cursor-pointer w-full text-left",
|
|
@@ -15676,6 +16527,7 @@ function MobileMenuItem({
|
|
|
15676
16527
|
return /* @__PURE__ */ jsxs(
|
|
15677
16528
|
"button",
|
|
15678
16529
|
{
|
|
16530
|
+
type: "button",
|
|
15679
16531
|
onClick,
|
|
15680
16532
|
className: cn(
|
|
15681
16533
|
"flex items-center gap-ds-3 px-ds-3 py-ds-2.5 text-sm cursor-pointer w-full text-left",
|
|
@@ -15693,6 +16545,7 @@ function MobileMenuItem({
|
|
|
15693
16545
|
return /* @__PURE__ */ jsxs(
|
|
15694
16546
|
"button",
|
|
15695
16547
|
{
|
|
16548
|
+
type: "button",
|
|
15696
16549
|
onClick,
|
|
15697
16550
|
className: cn(
|
|
15698
16551
|
"flex items-center gap-ds-3 px-ds-3 py-ds-2.5 text-sm rounded-[var(--ds-radius-md)] cursor-pointer w-full text-left",
|
|
@@ -15709,6 +16562,7 @@ function MobileMenuItem({
|
|
|
15709
16562
|
return /* @__PURE__ */ jsxs(
|
|
15710
16563
|
"button",
|
|
15711
16564
|
{
|
|
16565
|
+
type: "button",
|
|
15712
16566
|
onClick,
|
|
15713
16567
|
className: cn(
|
|
15714
16568
|
"flex items-center gap-ds-3 px-ds-3 py-ds-2.5 text-sm rounded-[var(--ds-radius-md)] cursor-pointer w-full text-left",
|
|
@@ -15870,6 +16724,7 @@ function CommandPalette({ open, onOpenChange, commands, placeholder = "Type a co
|
|
|
15870
16724
|
return /* @__PURE__ */ jsxs(
|
|
15871
16725
|
"button",
|
|
15872
16726
|
{
|
|
16727
|
+
type: "button",
|
|
15873
16728
|
id: `${listboxId}-opt-${myIdx}`,
|
|
15874
16729
|
role: "option",
|
|
15875
16730
|
tabIndex: -1,
|
|
@@ -16058,6 +16913,7 @@ function ContextMenu({ items, children, className, ref, container }) {
|
|
|
16058
16913
|
return /* @__PURE__ */ jsxs(
|
|
16059
16914
|
"button",
|
|
16060
16915
|
{
|
|
16916
|
+
type: "button",
|
|
16061
16917
|
role: "menuitem",
|
|
16062
16918
|
disabled: item.disabled,
|
|
16063
16919
|
onClick: () => {
|
|
@@ -16168,6 +17024,7 @@ function NotificationCenter({
|
|
|
16168
17024
|
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-3", children: unreadCount > 0 && /* @__PURE__ */ jsx(
|
|
16169
17025
|
"button",
|
|
16170
17026
|
{
|
|
17027
|
+
type: "button",
|
|
16171
17028
|
onClick: onMarkAllRead,
|
|
16172
17029
|
className: "text-sm text-[var(--ds-accent-primary)] hover:underline cursor-pointer",
|
|
16173
17030
|
children: "Mark all read"
|
|
@@ -16178,6 +17035,7 @@ function NotificationCenter({
|
|
|
16178
17035
|
/* @__PURE__ */ jsx(
|
|
16179
17036
|
"button",
|
|
16180
17037
|
{
|
|
17038
|
+
type: "button",
|
|
16181
17039
|
onClick: () => setFilter("all"),
|
|
16182
17040
|
className: cn(
|
|
16183
17041
|
"px-ds-3 py-ds-1.5 text-sm rounded-[var(--ds-radius-md)] transition-colors cursor-pointer",
|
|
@@ -16189,6 +17047,7 @@ function NotificationCenter({
|
|
|
16189
17047
|
/* @__PURE__ */ jsxs(
|
|
16190
17048
|
"button",
|
|
16191
17049
|
{
|
|
17050
|
+
type: "button",
|
|
16192
17051
|
onClick: () => setFilter("unread"),
|
|
16193
17052
|
className: cn(
|
|
16194
17053
|
"px-ds-3 py-ds-1.5 text-sm rounded-[var(--ds-radius-md)] transition-colors cursor-pointer",
|
|
@@ -16238,6 +17097,7 @@ function NotificationCenter({
|
|
|
16238
17097
|
!n.read && onMarkRead && /* @__PURE__ */ jsx(
|
|
16239
17098
|
"button",
|
|
16240
17099
|
{
|
|
17100
|
+
type: "button",
|
|
16241
17101
|
onClick: () => onMarkRead(n.id),
|
|
16242
17102
|
"aria-label": "Mark as read",
|
|
16243
17103
|
className: "text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)] transition-colors cursor-pointer p-ds-0.5",
|
|
@@ -16247,6 +17107,7 @@ function NotificationCenter({
|
|
|
16247
17107
|
onDismiss && /* @__PURE__ */ jsx(
|
|
16248
17108
|
"button",
|
|
16249
17109
|
{
|
|
17110
|
+
type: "button",
|
|
16250
17111
|
onClick: () => onDismiss(n.id),
|
|
16251
17112
|
"aria-label": "Dismiss",
|
|
16252
17113
|
className: "text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)] transition-colors cursor-pointer p-ds-0.5",
|
|
@@ -16265,6 +17126,7 @@ function NotificationCenter({
|
|
|
16265
17126
|
/* @__PURE__ */ jsxs(
|
|
16266
17127
|
"button",
|
|
16267
17128
|
{
|
|
17129
|
+
type: "button",
|
|
16268
17130
|
ref: triggerRef,
|
|
16269
17131
|
onClick: () => setOpen(!open),
|
|
16270
17132
|
"aria-label": `Notifications${unreadCount ? ` (${unreadCount} unread)` : ""}`,
|
|
@@ -16304,6 +17166,7 @@ function NotificationCenter({
|
|
|
16304
17166
|
unreadCount > 0 && /* @__PURE__ */ jsx(
|
|
16305
17167
|
"button",
|
|
16306
17168
|
{
|
|
17169
|
+
type: "button",
|
|
16307
17170
|
onClick: onMarkAllRead,
|
|
16308
17171
|
className: "text-xs text-[var(--ds-accent-primary)] hover:underline cursor-pointer",
|
|
16309
17172
|
children: "Mark all read"
|
|
@@ -16348,6 +17211,7 @@ function NotificationCenter({
|
|
|
16348
17211
|
!n.read && onMarkRead && /* @__PURE__ */ jsx(
|
|
16349
17212
|
"button",
|
|
16350
17213
|
{
|
|
17214
|
+
type: "button",
|
|
16351
17215
|
onClick: () => onMarkRead(n.id),
|
|
16352
17216
|
"aria-label": "Mark as read",
|
|
16353
17217
|
className: "text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)] transition-colors cursor-pointer p-ds-0.5",
|
|
@@ -16357,6 +17221,7 @@ function NotificationCenter({
|
|
|
16357
17221
|
onDismiss && /* @__PURE__ */ jsx(
|
|
16358
17222
|
"button",
|
|
16359
17223
|
{
|
|
17224
|
+
type: "button",
|
|
16360
17225
|
onClick: () => onDismiss(n.id),
|
|
16361
17226
|
"aria-label": "Dismiss",
|
|
16362
17227
|
className: "text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)] transition-colors cursor-pointer p-ds-0.5",
|
|
@@ -16520,6 +17385,7 @@ function Tour({ steps, open, onClose, onComplete, container }) {
|
|
|
16520
17385
|
/* @__PURE__ */ jsx(
|
|
16521
17386
|
"button",
|
|
16522
17387
|
{
|
|
17388
|
+
type: "button",
|
|
16523
17389
|
onClick: onClose,
|
|
16524
17390
|
className: "shrink-0 text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)] transition-colors cursor-pointer -mt-ds-0.5",
|
|
16525
17391
|
"aria-label": "Close tour",
|
|
@@ -16539,6 +17405,7 @@ function Tour({ steps, open, onClose, onComplete, container }) {
|
|
|
16539
17405
|
current > 0 && /* @__PURE__ */ jsx(
|
|
16540
17406
|
"button",
|
|
16541
17407
|
{
|
|
17408
|
+
type: "button",
|
|
16542
17409
|
onClick: handlePrev,
|
|
16543
17410
|
className: cn(
|
|
16544
17411
|
"px-ds-3 py-ds-1.5 text-xs font-medium rounded-[var(--ds-radius-sm)]",
|
|
@@ -16552,6 +17419,7 @@ function Tour({ steps, open, onClose, onComplete, container }) {
|
|
|
16552
17419
|
/* @__PURE__ */ jsx(
|
|
16553
17420
|
"button",
|
|
16554
17421
|
{
|
|
17422
|
+
type: "button",
|
|
16555
17423
|
ref: nextRef,
|
|
16556
17424
|
onClick: handleNext,
|
|
16557
17425
|
className: cn(
|
|
@@ -16600,223 +17468,6 @@ function getPopoverPosition(rect, placement, padding) {
|
|
|
16600
17468
|
top = Math.max(8, Math.min(top, window.innerHeight - popH - 8));
|
|
16601
17469
|
return { top, left };
|
|
16602
17470
|
}
|
|
16603
|
-
var variantStyles4 = {
|
|
16604
|
-
default: "border-[var(--ds-border-default)] bg-[var(--ds-bg-surface)]",
|
|
16605
|
-
success: "border-[var(--ds-status-success)] bg-[var(--ds-status-success-bg)]",
|
|
16606
|
-
warning: "border-[var(--ds-status-warning)] bg-[var(--ds-status-warning-bg)]",
|
|
16607
|
-
error: "border-[var(--ds-status-error)] bg-[var(--ds-status-error-bg)]"
|
|
16608
|
-
};
|
|
16609
|
-
var variantIcons = {
|
|
16610
|
-
default: { name: "info", className: "text-[var(--ds-text-muted)]" },
|
|
16611
|
-
success: { name: "check", className: "text-[var(--ds-status-success)]" },
|
|
16612
|
-
warning: { name: "warning", className: "text-[var(--ds-status-warning)]" },
|
|
16613
|
-
error: { name: "error", className: "text-[var(--ds-status-error)]" }
|
|
16614
|
-
};
|
|
16615
|
-
var TOAST_POSITION_CLASSES = {
|
|
16616
|
-
"top-right": "top-[var(--ds-toast-inset-top)] right-[var(--ds-toast-inset-right)]",
|
|
16617
|
-
"top-left": "top-[var(--ds-toast-inset-top)] left-[var(--ds-toast-inset-left)]",
|
|
16618
|
-
"bottom-right": "bottom-[var(--ds-toast-inset-bottom-right)] right-[var(--ds-toast-inset-right)]",
|
|
16619
|
-
"bottom-left": "bottom-[var(--ds-toast-inset-bottom-left)] left-[var(--ds-toast-inset-left)]",
|
|
16620
|
-
"top-center": "top-[var(--ds-toast-inset-top)] left-1/2 -translate-x-1/2",
|
|
16621
|
-
"bottom-center": "bottom-ds-4 left-1/2 -translate-x-1/2"
|
|
16622
|
-
};
|
|
16623
|
-
function Toast({ variant = "default", message, visible, onDismiss, duration = 5e3, pauseOnHover = false, action, position = "bottom-right", mode, container, inline = false }) {
|
|
16624
|
-
const isMobile = useBreakpoint("sm");
|
|
16625
|
-
const isCentered = position === "top-center" || position === "bottom-center";
|
|
16626
|
-
const timerRef = useRef(void 0);
|
|
16627
|
-
const startedAtRef = useRef(0);
|
|
16628
|
-
const remainingRef = useRef(duration);
|
|
16629
|
-
const onDismissRef = useLatest(onDismiss);
|
|
16630
|
-
const startTimer = useCallback((ms) => {
|
|
16631
|
-
const delay = ms ?? remainingRef.current;
|
|
16632
|
-
remainingRef.current = delay;
|
|
16633
|
-
startedAtRef.current = Date.now();
|
|
16634
|
-
if (!Number.isFinite(delay) || delay <= 0) return;
|
|
16635
|
-
timerRef.current = setTimeout(() => onDismissRef.current(), delay);
|
|
16636
|
-
}, [onDismissRef]);
|
|
16637
|
-
const clearTimer = useCallback(() => {
|
|
16638
|
-
if (timerRef.current) {
|
|
16639
|
-
clearTimeout(timerRef.current);
|
|
16640
|
-
remainingRef.current -= Date.now() - startedAtRef.current;
|
|
16641
|
-
}
|
|
16642
|
-
}, []);
|
|
16643
|
-
useEffect(() => {
|
|
16644
|
-
if (!visible) return;
|
|
16645
|
-
remainingRef.current = duration;
|
|
16646
|
-
startTimer(duration);
|
|
16647
|
-
return () => {
|
|
16648
|
-
if (timerRef.current) clearTimeout(timerRef.current);
|
|
16649
|
-
};
|
|
16650
|
-
}, [visible, duration, startTimer]);
|
|
16651
|
-
const handleMouseEnter = pauseOnHover ? () => {
|
|
16652
|
-
clearTimer();
|
|
16653
|
-
} : void 0;
|
|
16654
|
-
const handleMouseLeave = pauseOnHover ? () => {
|
|
16655
|
-
startTimer();
|
|
16656
|
-
} : void 0;
|
|
16657
|
-
if (!visible) return null;
|
|
16658
|
-
const icon = variantIcons[variant];
|
|
16659
|
-
const card = /* @__PURE__ */ jsxs(
|
|
16660
|
-
"div",
|
|
16661
|
-
{
|
|
16662
|
-
role: variant === "error" ? "alert" : "status",
|
|
16663
|
-
"aria-live": variant === "error" ? "assertive" : "polite",
|
|
16664
|
-
"data-mode": inline ? mode : void 0,
|
|
16665
|
-
onMouseEnter: inline ? handleMouseEnter : void 0,
|
|
16666
|
-
onMouseLeave: inline ? handleMouseLeave : void 0,
|
|
16667
|
-
className: cn(
|
|
16668
|
-
"flex items-center gap-ds-3 px-ds-4 py-ds-3",
|
|
16669
|
-
isCentered ? "min-w-[360px] max-w-[560px]" : "min-w-[280px] max-w-[420px]",
|
|
16670
|
-
"border-[length:var(--ds-border-width)]",
|
|
16671
|
-
GLASS_DROPDOWN,
|
|
16672
|
-
"rounded-[var(--ds-radius-md)]",
|
|
16673
|
-
"text-sm text-[var(--ds-text-primary)]",
|
|
16674
|
-
variantStyles4[variant]
|
|
16675
|
-
),
|
|
16676
|
-
children: [
|
|
16677
|
-
/* @__PURE__ */ jsx(Icon, { name: icon.name, size: 18, className: cn("shrink-0", icon.className) }),
|
|
16678
|
-
/* @__PURE__ */ jsx("span", { className: "flex-1", children: message }),
|
|
16679
|
-
action && /* @__PURE__ */ jsx(
|
|
16680
|
-
"button",
|
|
16681
|
-
{
|
|
16682
|
-
type: "button",
|
|
16683
|
-
onClick: action.onClick,
|
|
16684
|
-
className: "shrink-0 text-xs font-semibold text-[var(--ds-accent-primary)] hover:underline cursor-pointer",
|
|
16685
|
-
children: action.label
|
|
16686
|
-
}
|
|
16687
|
-
),
|
|
16688
|
-
/* @__PURE__ */ jsx(
|
|
16689
|
-
"button",
|
|
16690
|
-
{
|
|
16691
|
-
type: "button",
|
|
16692
|
-
onClick: onDismiss,
|
|
16693
|
-
"aria-label": "Dismiss notification",
|
|
16694
|
-
className: "text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)] transition-colors cursor-pointer shrink-0",
|
|
16695
|
-
children: /* @__PURE__ */ jsx(Icon, { name: "close", size: 16 })
|
|
16696
|
-
}
|
|
16697
|
-
)
|
|
16698
|
-
]
|
|
16699
|
-
}
|
|
16700
|
-
);
|
|
16701
|
-
if (inline) return card;
|
|
16702
|
-
return createPortal(
|
|
16703
|
-
/* @__PURE__ */ jsx(
|
|
16704
|
-
"div",
|
|
16705
|
-
{
|
|
16706
|
-
"data-mode": mode,
|
|
16707
|
-
onMouseEnter: handleMouseEnter,
|
|
16708
|
-
onMouseLeave: handleMouseLeave,
|
|
16709
|
-
className: cn(
|
|
16710
|
-
"fixed z-[var(--ds-z-toast)]",
|
|
16711
|
-
isMobile ? "bottom-ds-4 left-ds-4 right-ds-4" : TOAST_POSITION_CLASSES[position]
|
|
16712
|
-
),
|
|
16713
|
-
children: card
|
|
16714
|
-
}
|
|
16715
|
-
),
|
|
16716
|
-
container ?? document.body
|
|
16717
|
-
);
|
|
16718
|
-
}
|
|
16719
|
-
var ToastContext = createContext(null);
|
|
16720
|
-
function useToast() {
|
|
16721
|
-
const ctx = useContext(ToastContext);
|
|
16722
|
-
if (!ctx) {
|
|
16723
|
-
throw new Error("useToast must be used within <ToastProvider>: the app shell's (get_app_shell writes it around AppShell). A page outside the shell (sign-in, a public page) shows its messages inline instead: an Alert above the form, and each field's error below the field.");
|
|
16724
|
-
}
|
|
16725
|
-
return ctx;
|
|
16726
|
-
}
|
|
16727
|
-
function useToastOptional() {
|
|
16728
|
-
return useContext(ToastContext);
|
|
16729
|
-
}
|
|
16730
|
-
var toastSeq = 0;
|
|
16731
|
-
function ToastProvider({ children, maxVisible = 1, position = "bottom-right", duration = 5e3, mode, pauseOnHover = true, coalesce = true }) {
|
|
16732
|
-
const [queue, setQueue] = useState([]);
|
|
16733
|
-
const isMobile = useBreakpoint("sm");
|
|
16734
|
-
const dismiss = useCallback((id) => {
|
|
16735
|
-
setQueue((q) => q.filter((t) => t.id !== id));
|
|
16736
|
-
}, []);
|
|
16737
|
-
const dismissAll = useCallback(() => setQueue([]), []);
|
|
16738
|
-
const update = useCallback((id, message, options = {}) => {
|
|
16739
|
-
setQueue((q) => q.map((t) => t.id === id ? { ...t, message, variant: options.variant ?? t.variant, duration: options.duration ?? t.duration, action: options.action ?? t.action } : t));
|
|
16740
|
-
}, []);
|
|
16741
|
-
const toast = useCallback((message, options = {}) => {
|
|
16742
|
-
const id = options.id ?? `toast-${++toastSeq}`;
|
|
16743
|
-
const entry = {
|
|
16744
|
-
id,
|
|
16745
|
-
message,
|
|
16746
|
-
variant: options.variant ?? "default",
|
|
16747
|
-
duration: options.duration ?? duration,
|
|
16748
|
-
action: options.action,
|
|
16749
|
-
key: options.key ?? options.variant ?? "default"
|
|
16750
|
-
};
|
|
16751
|
-
const slots = Math.max(1, maxVisible);
|
|
16752
|
-
setQueue((q) => {
|
|
16753
|
-
if (q.some((t) => t.id === id)) return q.map((t) => t.id === id ? entry : t);
|
|
16754
|
-
if (coalesce && q.length >= slots) {
|
|
16755
|
-
const waiting = q.findIndex((t, i) => i >= slots && t.key === entry.key);
|
|
16756
|
-
if (waiting >= 0) {
|
|
16757
|
-
const next = [...q];
|
|
16758
|
-
next[waiting] = entry;
|
|
16759
|
-
return next;
|
|
16760
|
-
}
|
|
16761
|
-
}
|
|
16762
|
-
return [...q, entry];
|
|
16763
|
-
});
|
|
16764
|
-
return id;
|
|
16765
|
-
}, [duration, maxVisible, coalesce]);
|
|
16766
|
-
const api = useMemo(() => ({
|
|
16767
|
-
toast,
|
|
16768
|
-
success: (m, o) => toast(m, { ...o, variant: "success" }),
|
|
16769
|
-
warning: (m, o) => toast(m, { ...o, variant: "warning" }),
|
|
16770
|
-
error: (m, o) => toast(m, { ...o, variant: "error" }),
|
|
16771
|
-
update,
|
|
16772
|
-
dismiss,
|
|
16773
|
-
dismissAll,
|
|
16774
|
-
promise: async (promise, messages, options = {}) => {
|
|
16775
|
-
const id = toast(messages.loading, { ...options, variant: "default", duration: Infinity });
|
|
16776
|
-
try {
|
|
16777
|
-
const value = await promise;
|
|
16778
|
-
update(id, typeof messages.success === "function" ? messages.success(value) : messages.success, { variant: "success", duration });
|
|
16779
|
-
return value;
|
|
16780
|
-
} catch (err) {
|
|
16781
|
-
update(id, typeof messages.error === "function" ? messages.error(err) : messages.error, { variant: "error", duration });
|
|
16782
|
-
throw err;
|
|
16783
|
-
}
|
|
16784
|
-
}
|
|
16785
|
-
}), [toast, update, dismiss, dismissAll, duration]);
|
|
16786
|
-
const visible = queue.slice(0, Math.max(1, maxVisible));
|
|
16787
|
-
const isTop = position.startsWith("top");
|
|
16788
|
-
return /* @__PURE__ */ jsxs(ToastContext.Provider, { value: api, children: [
|
|
16789
|
-
children,
|
|
16790
|
-
visible.length > 0 && createPortal(
|
|
16791
|
-
/* @__PURE__ */ jsx(
|
|
16792
|
-
"div",
|
|
16793
|
-
{
|
|
16794
|
-
"data-mode": mode,
|
|
16795
|
-
className: cn(
|
|
16796
|
-
"fixed z-[var(--ds-z-toast)] flex gap-ds-2 pointer-events-none",
|
|
16797
|
-
isTop ? "flex-col" : "flex-col-reverse",
|
|
16798
|
-
isMobile ? "bottom-ds-4 left-ds-4 right-ds-4" : TOAST_POSITION_CLASSES[position]
|
|
16799
|
-
),
|
|
16800
|
-
children: visible.map((t) => /* @__PURE__ */ jsx("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx(
|
|
16801
|
-
Toast,
|
|
16802
|
-
{
|
|
16803
|
-
inline: true,
|
|
16804
|
-
visible: true,
|
|
16805
|
-
variant: t.variant,
|
|
16806
|
-
message: t.message,
|
|
16807
|
-
duration: t.duration,
|
|
16808
|
-
pauseOnHover,
|
|
16809
|
-
action: t.action,
|
|
16810
|
-
mode,
|
|
16811
|
-
onDismiss: () => dismiss(t.id)
|
|
16812
|
-
}
|
|
16813
|
-
) }, t.id))
|
|
16814
|
-
}
|
|
16815
|
-
),
|
|
16816
|
-
document.body
|
|
16817
|
-
)
|
|
16818
|
-
] });
|
|
16819
|
-
}
|
|
16820
17471
|
function firstKey(item) {
|
|
16821
17472
|
if (item !== null && typeof item === "object") return "id" in item ? item.id : void 0;
|
|
16822
17473
|
return item;
|
|
@@ -16879,9 +17530,10 @@ function usePagination(list, options = {}) {
|
|
|
16879
17530
|
};
|
|
16880
17531
|
}
|
|
16881
17532
|
function useDestructiveAction(options) {
|
|
16882
|
-
const { action, title, description, confirmLabel, typeToConfirm, onConfirm, onUndo, undoMessage, severity } = options;
|
|
17533
|
+
const { action, title, description, confirmLabel, typeToConfirm, onConfirm, onUndo, doneMessage, undoMessage, restoredMessage, severity } = options;
|
|
16883
17534
|
const preferences = useShellPreferences();
|
|
16884
17535
|
const toast = useToastOptional();
|
|
17536
|
+
const ledger = useContext(ToastLedgerCtx);
|
|
16885
17537
|
const [open, setOpen] = useState(false);
|
|
16886
17538
|
const [typed, setTyped] = useState("");
|
|
16887
17539
|
const [busy, setBusy] = useState(false);
|
|
@@ -16898,28 +17550,66 @@ function useDestructiveAction(options) {
|
|
|
16898
17550
|
setTyped("");
|
|
16899
17551
|
};
|
|
16900
17552
|
const failureMessage = (err) => err instanceof Error && err.message ? err.message : `${title.replace(/\?$/, "")} failed. Try again.`;
|
|
17553
|
+
const done = doneMessage ?? undoMessage ?? pastTenseOf(label);
|
|
17554
|
+
const watch = async (step) => {
|
|
17555
|
+
const run2 = ledger?.begin();
|
|
17556
|
+
try {
|
|
17557
|
+
await step();
|
|
17558
|
+
} catch (err) {
|
|
17559
|
+
if (run2 !== void 0) ledger.end(run2);
|
|
17560
|
+
throw err;
|
|
17561
|
+
}
|
|
17562
|
+
return run2 !== void 0 ? ledger.end(run2) : { problem: false };
|
|
17563
|
+
};
|
|
16901
17564
|
const confirm = async () => {
|
|
16902
17565
|
setBusy(true);
|
|
16903
17566
|
try {
|
|
16904
|
-
await onConfirm
|
|
17567
|
+
const seen = await watch(onConfirm);
|
|
16905
17568
|
close();
|
|
17569
|
+
if (toast && !seen.problem && !seen.own) toast.success(done);
|
|
16906
17570
|
} catch (err) {
|
|
16907
17571
|
toast?.error(failureMessage(err));
|
|
16908
17572
|
} finally {
|
|
16909
17573
|
setBusy(false);
|
|
16910
17574
|
}
|
|
16911
17575
|
};
|
|
17576
|
+
const undo = async (id) => {
|
|
17577
|
+
const here = () => !!toast && (ledger?.has(id) ?? false);
|
|
17578
|
+
try {
|
|
17579
|
+
const seen = await watch(onUndo);
|
|
17580
|
+
if (seen.problem) {
|
|
17581
|
+
if (here()) toast.dismiss(id);
|
|
17582
|
+
} else if (seen.own) {
|
|
17583
|
+
if (here()) {
|
|
17584
|
+
toast.update(id, seen.own.message, { variant: seen.own.variant });
|
|
17585
|
+
toast.dismiss(seen.own.id);
|
|
17586
|
+
}
|
|
17587
|
+
} else if (here()) toast.update(id, restoredMessage ?? "Restored", { variant: "success" });
|
|
17588
|
+
else toast?.success(restoredMessage ?? "Restored");
|
|
17589
|
+
} catch (err) {
|
|
17590
|
+
const message = err instanceof Error && err.message ? err.message : "Undo didn't work. Try again.";
|
|
17591
|
+
if (here()) toast.update(id, message, { variant: "error" });
|
|
17592
|
+
else toast?.error(message);
|
|
17593
|
+
}
|
|
17594
|
+
};
|
|
16912
17595
|
const run = () => {
|
|
16913
17596
|
if (undoable) {
|
|
16914
17597
|
void (async () => {
|
|
17598
|
+
let seen;
|
|
16915
17599
|
try {
|
|
16916
|
-
await onConfirm
|
|
17600
|
+
seen = await watch(onConfirm);
|
|
16917
17601
|
} catch (err) {
|
|
16918
17602
|
toast.error(failureMessage(err));
|
|
16919
17603
|
return;
|
|
16920
17604
|
}
|
|
17605
|
+
if (seen.problem) return;
|
|
16921
17606
|
const seconds = preferences.undoWindowSeconds ?? 5;
|
|
16922
|
-
|
|
17607
|
+
let id = "";
|
|
17608
|
+
const undoAction = { label: "Undo", onClick: () => undo(id) };
|
|
17609
|
+
if (seen.own) {
|
|
17610
|
+
id = seen.own.id;
|
|
17611
|
+
toast.update(id, seen.own.message, { action: undoAction, actionWindow: seconds * 1e3 });
|
|
17612
|
+
} else id = toast.success(done, { action: undoAction, actionWindow: seconds * 1e3 });
|
|
16923
17613
|
})();
|
|
16924
17614
|
return;
|
|
16925
17615
|
}
|
|
@@ -16935,8 +17625,8 @@ function useDestructiveAction(options) {
|
|
|
16935
17625
|
description,
|
|
16936
17626
|
variant: "destructive",
|
|
16937
17627
|
footer: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
16938
|
-
/* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: close, disabled: busy, children: "Cancel" }),
|
|
16939
|
-
/* @__PURE__ */ jsx(Button, { variant: "destructive", onClick: () => void confirm(), disabled: !matches2 || busy, loading: busy, children: label })
|
|
17628
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "secondary", onClick: close, disabled: busy, children: "Cancel" }),
|
|
17629
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "destructive", onClick: () => void confirm(), disabled: !matches2 || busy, loading: busy, children: label })
|
|
16940
17630
|
] }),
|
|
16941
17631
|
children: typedRequired && /* @__PURE__ */ jsx(Field, { label: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
16942
17632
|
"Type ",
|
|
@@ -16947,6 +17637,61 @@ function useDestructiveAction(options) {
|
|
|
16947
17637
|
) : null;
|
|
16948
17638
|
return { run, element, open };
|
|
16949
17639
|
}
|
|
17640
|
+
var PAST_TENSE = {
|
|
17641
|
+
delete: "Deleted",
|
|
17642
|
+
remove: "Removed",
|
|
17643
|
+
archive: "Archived",
|
|
17644
|
+
leave: "Left",
|
|
17645
|
+
revoke: "Revoked",
|
|
17646
|
+
disconnect: "Disconnected",
|
|
17647
|
+
cancel: "Cancelled",
|
|
17648
|
+
reset: "Reset",
|
|
17649
|
+
clear: "Cleared",
|
|
17650
|
+
discard: "Discarded",
|
|
17651
|
+
unpublish: "Unpublished",
|
|
17652
|
+
deactivate: "Deactivated",
|
|
17653
|
+
disable: "Disabled",
|
|
17654
|
+
uninstall: "Uninstalled",
|
|
17655
|
+
unsubscribe: "Unsubscribed",
|
|
17656
|
+
block: "Blocked",
|
|
17657
|
+
ban: "Banned",
|
|
17658
|
+
suspend: "Suspended",
|
|
17659
|
+
close: "Closed",
|
|
17660
|
+
end: "Ended",
|
|
17661
|
+
stop: "Stopped",
|
|
17662
|
+
"sign out": "Signed out",
|
|
17663
|
+
"log out": "Logged out",
|
|
17664
|
+
transfer: "Transferred",
|
|
17665
|
+
merge: "Merged",
|
|
17666
|
+
overwrite: "Overwritten",
|
|
17667
|
+
replace: "Replaced",
|
|
17668
|
+
erase: "Erased",
|
|
17669
|
+
purge: "Purged",
|
|
17670
|
+
wipe: "Wiped",
|
|
17671
|
+
drop: "Dropped",
|
|
17672
|
+
detach: "Detached",
|
|
17673
|
+
unlink: "Unlinked",
|
|
17674
|
+
expire: "Expired",
|
|
17675
|
+
reject: "Rejected",
|
|
17676
|
+
decline: "Declined"
|
|
17677
|
+
};
|
|
17678
|
+
var warned3 = /* @__PURE__ */ new Set();
|
|
17679
|
+
function pastTenseOf(label) {
|
|
17680
|
+
const words = label.trim().toLowerCase().split(/\s+/);
|
|
17681
|
+
const found = PAST_TENSE[words.slice(0, 2).join(" ")] ?? PAST_TENSE[words[0] ?? ""];
|
|
17682
|
+
if (found) return found;
|
|
17683
|
+
let dev = false;
|
|
17684
|
+
try {
|
|
17685
|
+
dev = process.env.NODE_ENV !== "production";
|
|
17686
|
+
} catch {
|
|
17687
|
+
dev = false;
|
|
17688
|
+
}
|
|
17689
|
+
if (dev && !warned3.has(label)) {
|
|
17690
|
+
warned3.add(label);
|
|
17691
|
+
console.warn(`useDestructiveAction: "${label}" isn't a verb the hook knows; pass doneMessage so the confirmation says what happened.`);
|
|
17692
|
+
}
|
|
17693
|
+
return "Done";
|
|
17694
|
+
}
|
|
16950
17695
|
var SectionHeading = forwardRef(function SectionHeading2({
|
|
16951
17696
|
title,
|
|
16952
17697
|
description,
|
|
@@ -17087,6 +17832,6 @@ var TextOverflow = forwardRef(function TextOverflow2({
|
|
|
17087
17832
|
return /* @__PURE__ */ jsx(Tooltip, { content: resolvedTooltipContent, children: content });
|
|
17088
17833
|
});
|
|
17089
17834
|
|
|
17090
|
-
export { Accordion, ActionPanel, ActionPanelGroup, Alert, AsidePanel, Avatar, AvatarGroup, BottomNav, Breadcrumbs, BulkActionBar, Calendar, Card, CardContent, CardDescription, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, ChatMessageList, ChatPanel, Checkbox, CheckboxGroup, CheckboxGroupItem, Collapsible, ColorPicker, Combobox, CommandPalette, ContextMenu, CornerPanel, DEFAULT_DATE_RANGE_PRESETS, DataList, DatePicker, DateRangePicker, DescriptionList, Dialog, Dock, Dropdown, DropdownMenu, EmptyState, EntityCell, Field, FileUpload, FormWrapper, Gantt, HoverCard, InlineFieldError, Input, Kbd, Label, Launcher, MentionInput, MobileHeaderMenu, NavItem, NavMenu, Navbar, NotificationCenter, NumberInput, PageContainer, PageHeader, Pagination, PinInput, Popover, Progress, RadioGroup, Rating, ScrollArea, SectionHeading, SegmentedControl, SettingsLayout, Sidebar, SidebarNav, SliderRange, StackedList, StatsCard, StatusDot, Stepper, TIME_ZOOMS, Table, TableToolbar, Tabs, Tag, TagInput, TextOverflow, Textarea, TimeBar, TimePicker, TimeRow, TimeScaleHeader, TimeViewport, Timeline, Toast, ToastProvider, Toggle, Tour, TransferList, TreeView, dateOfDay, dayOf, endDayOf, fitLabel, fitLabels, formatDateRange, timeExtent, useContentWidth, useDestructiveAction, useFittedLabels,
|
|
17835
|
+
export { Accordion, ActionPanel, ActionPanelGroup, AddAnother, Alert, AsidePanel, Avatar, AvatarGroup, BottomNav, Breadcrumbs, BulkActionBar, Calendar, Card, CardContent, CardDescription, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, ChatMessageList, ChatPanel, Checkbox, CheckboxGroup, CheckboxGroupItem, Collapsible, ColorPicker, Combobox, CommandPalette, ContextMenu, CornerPanel, DEFAULT_DATE_RANGE_PRESETS, DataList, DatePicker, DateRangePicker, DescriptionList, Dialog, Dock, Dropdown, DropdownMenu, EmptyState, EntityCell, Field, FileUpload, FormWrapper, Gantt, HoverCard, InlineFieldError, Input, Kbd, Label, Launcher, MentionInput, MobileHeaderMenu, NavItem, NavMenu, Navbar, NotificationCenter, NumberInput, PageContainer, PageHeader, Pagination, PinInput, Popover, Progress, RadioGroup, Rating, ScrollArea, SectionHeading, SegmentedControl, SettingsLayout, Sidebar, SidebarNav, SliderRange, StackedList, StatsCard, StatusDot, Stepper, TIME_ZOOMS, Table, TableToolbar, Tabs, Tag, TagInput, TextOverflow, Textarea, TimeBar, TimePicker, TimeRow, TimeScaleHeader, TimeViewport, Timeline, Toast, ToastProvider, Toggle, Tour, TransferList, TreeView, dateOfDay, dayOf, endDayOf, fitLabel, fitLabels, formatDateRange, timeExtent, useContentWidth, useDestructiveAction, useFittedLabels, usePagination, useSidebar, useTextMeasure, useTimeScale, useTimeViewport, useTimeViewportLayout, useToast, useToastOptional };
|
|
17091
17836
|
//# sourceMappingURL=index.js.map
|
|
17092
17837
|
//# sourceMappingURL=index.js.map
|