gridsmith-ui 0.6.2 → 0.6.4
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/charts.d.ts +3 -1
- package/dist/charts.js +6 -4
- package/dist/charts.js.map +1 -1
- package/dist/{chunk-R5QGJURZ.js → chunk-DDKCQVKO.js} +16 -8
- package/dist/chunk-DDKCQVKO.js.map +1 -0
- package/dist/{chunk-DPF6776I.js → chunk-EKQHHP72.js} +18 -15
- package/dist/chunk-EKQHHP72.js.map +1 -0
- package/dist/{chunk-TYU2LQGK.js → chunk-KXNJJKIV.js} +3 -3
- package/dist/{chunk-TYU2LQGK.js.map → chunk-KXNJJKIV.js.map} +1 -1
- package/dist/data-grid.d.ts +1 -1
- package/dist/data-grid.js +2 -2
- package/dist/data-grid.js.map +1 -1
- package/dist/editor.js +7 -4
- package/dist/editor.js.map +1 -1
- package/dist/index.d.ts +30 -7
- package/dist/index.js +385 -304
- package/dist/index.js.map +1 -1
- package/dist/kanban.js +2 -2
- package/dist/resizable.js +1 -1
- package/dist/{use-breakpoint-Cn51IubK.d.ts → use-breakpoint-BfKzmkxx.d.ts} +3 -0
- package/dist/virtualized.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-DPF6776I.js.map +0 -1
- package/dist/chunk-R5QGJURZ.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { Skeleton } from './chunk-QGBG72OB.js';
|
|
2
2
|
export { Skeleton } from './chunk-QGBG72OB.js';
|
|
3
|
-
import { Badge } from './chunk-
|
|
4
|
-
export { Badge } from './chunk-
|
|
5
|
-
import { useBreakpoint } from './chunk-
|
|
6
|
-
export { BreakpointWidthProvider, useBreakpoint } from './chunk-
|
|
7
|
-
import { Tooltip, useTextOverflow, usePosition, Slot } from './chunk-
|
|
8
|
-
export { Tooltip, useTextOverflow } from './chunk-
|
|
3
|
+
import { Badge } from './chunk-KXNJJKIV.js';
|
|
4
|
+
export { Badge } from './chunk-KXNJJKIV.js';
|
|
5
|
+
import { useBreakpoint } from './chunk-EKQHHP72.js';
|
|
6
|
+
export { BreakpointWidthProvider, useBreakpoint } from './chunk-EKQHHP72.js';
|
|
7
|
+
import { Tooltip, useTextOverflow, usePosition, Slot, useLatest } from './chunk-DDKCQVKO.js';
|
|
8
|
+
export { Tooltip, useTextOverflow } from './chunk-DDKCQVKO.js';
|
|
9
9
|
import { Icon } from './chunk-GX6O72IV.js';
|
|
10
|
-
import { cn, GLASS_SURFACE, ACTIVE_RING, GLASS_BACKDROP, GLASS_DROPDOWN, lockBodyScroll, unlockBodyScroll, GLASS_OVERLAY, HAS_FOCUS_RING,
|
|
11
|
-
import { createContext, forwardRef, useContext, useState, useRef, useEffect, useCallback, useId, isValidElement, cloneElement,
|
|
10
|
+
import { cn, GLASS_SURFACE, ACTIVE_RING, GLASS_BACKDROP, GLASS_DROPDOWN, FOCUS_RING, lockBodyScroll, unlockBodyScroll, GLASS_OVERLAY, HAS_FOCUS_RING, FOCUS_WITHIN_RING } from './chunk-TTZSZNJ6.js';
|
|
11
|
+
import { createContext, forwardRef, useContext, useState, useRef, useEffect, useCallback, useId, isValidElement, cloneElement, Fragment as Fragment$1, useMemo, Children, useLayoutEffect } from 'react';
|
|
12
12
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
13
13
|
import { createPortal } from 'react-dom';
|
|
14
14
|
|
|
@@ -149,11 +149,13 @@ function DropdownMenu({ trigger, items, align = "end", className, container }) {
|
|
|
149
149
|
if (!isDivider(item) && !item.disabled) acc.push(i);
|
|
150
150
|
return acc;
|
|
151
151
|
}, []);
|
|
152
|
+
const [prevOpen, setPrevOpen] = useState(open);
|
|
153
|
+
if (open !== prevOpen) {
|
|
154
|
+
setPrevOpen(open);
|
|
155
|
+
if (!open) setFocusedIdx(-1);
|
|
156
|
+
}
|
|
152
157
|
useEffect(() => {
|
|
153
|
-
if (!open)
|
|
154
|
-
setFocusedIdx(-1);
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
158
|
+
if (!open) return;
|
|
157
159
|
const onKeyDown = (e) => {
|
|
158
160
|
if (e.key === "Escape") setOpen(false);
|
|
159
161
|
};
|
|
@@ -534,13 +536,15 @@ function Dropdown({
|
|
|
534
536
|
}
|
|
535
537
|
setPos({ top, left, width });
|
|
536
538
|
}, []);
|
|
539
|
+
const [prevOpen, setPrevOpen] = useState(open);
|
|
540
|
+
if (open !== prevOpen) {
|
|
541
|
+
setPrevOpen(open);
|
|
542
|
+
if (open) setSearch("");
|
|
543
|
+
else setPositioned(false);
|
|
544
|
+
}
|
|
537
545
|
useEffect(() => {
|
|
538
|
-
if (!open)
|
|
539
|
-
setPositioned(false);
|
|
540
|
-
return;
|
|
541
|
-
}
|
|
546
|
+
if (!open) return;
|
|
542
547
|
updatePos();
|
|
543
|
-
setSearch("");
|
|
544
548
|
requestAnimationFrame(() => {
|
|
545
549
|
if (searchRef.current) {
|
|
546
550
|
searchRef.current.focus();
|
|
@@ -570,14 +574,14 @@ function Dropdown({
|
|
|
570
574
|
return () => document.removeEventListener("mousedown", handler);
|
|
571
575
|
}, [open]);
|
|
572
576
|
const typeahead = useRef({ buffer: "", at: 0 });
|
|
573
|
-
const optionButtons = () => Array.from(menuRef.current?.querySelectorAll('[role="option"]') ?? []);
|
|
574
|
-
const focusOption = (idx) => {
|
|
575
|
-
const els = optionButtons();
|
|
576
|
-
if (els.length === 0) return;
|
|
577
|
-
els[(idx % els.length + els.length) % els.length].focus();
|
|
578
|
-
};
|
|
579
577
|
useEffect(() => {
|
|
580
578
|
if (!open) return;
|
|
579
|
+
const optionButtons = () => Array.from(menuRef.current?.querySelectorAll('[role="option"]') ?? []);
|
|
580
|
+
const focusOption = (idx) => {
|
|
581
|
+
const els = optionButtons();
|
|
582
|
+
if (els.length === 0) return;
|
|
583
|
+
els[(idx % els.length + els.length) % els.length].focus();
|
|
584
|
+
};
|
|
581
585
|
const onKey = (e) => {
|
|
582
586
|
const inMenu = menuRef.current?.contains(document.activeElement) || triggerRef.current === document.activeElement;
|
|
583
587
|
if (!inMenu) return;
|
|
@@ -812,6 +816,7 @@ function Combobox({ value, onChange, options, placeholder = "Search\u2026", disa
|
|
|
812
816
|
const [highlightIdx, setHighlightIdx] = useState(0);
|
|
813
817
|
const inputRef = useRef(null);
|
|
814
818
|
const triggerRef = useRef(null);
|
|
819
|
+
const [triggerWidth, setTriggerWidth] = useState(void 0);
|
|
815
820
|
const listRef = useRef(null);
|
|
816
821
|
const listboxId = useId();
|
|
817
822
|
const pos = usePosition(triggerRef, listRef, open, { side: "bottom", align: "start", offset: 4, flip: true });
|
|
@@ -820,9 +825,11 @@ function Combobox({ value, onChange, options, placeholder = "Search\u2026", disa
|
|
|
820
825
|
);
|
|
821
826
|
const selectedLabel = options.find((o) => o.value === value)?.label ?? "";
|
|
822
827
|
const { ref: overflowRef, isTruncated: labelTruncated } = useTextOverflow({ lines: 1, content: selectedLabel, disabled: open });
|
|
823
|
-
|
|
828
|
+
const [prevQuery, setPrevQuery] = useState(query);
|
|
829
|
+
if (query !== prevQuery) {
|
|
830
|
+
setPrevQuery(query);
|
|
824
831
|
setHighlightIdx(0);
|
|
825
|
-
}
|
|
832
|
+
}
|
|
826
833
|
useEffect(() => {
|
|
827
834
|
if (!open) return;
|
|
828
835
|
const handler = (e) => {
|
|
@@ -870,6 +877,7 @@ function Combobox({ value, onChange, options, placeholder = "Search\u2026", disa
|
|
|
870
877
|
}, [overflowRef]);
|
|
871
878
|
const triggerContent = /* @__PURE__ */ jsxs("div", { ref: (node) => {
|
|
872
879
|
triggerRef.current = node;
|
|
880
|
+
setTriggerWidth(node?.offsetWidth);
|
|
873
881
|
if (typeof ref === "function") ref(node);
|
|
874
882
|
else if (ref) ref.current = node;
|
|
875
883
|
}, className: cn("relative", className), children: [
|
|
@@ -950,7 +958,7 @@ function Combobox({ value, onChange, options, placeholder = "Search\u2026", disa
|
|
|
950
958
|
"rounded-[var(--ds-radius-md)]",
|
|
951
959
|
"shadow-[var(--ds-shadow-dropdown),var(--ds-glass-inset)]"
|
|
952
960
|
),
|
|
953
|
-
style: { top: pos.top, left: pos.left, width:
|
|
961
|
+
style: { top: pos.top, left: pos.left, width: triggerWidth },
|
|
954
962
|
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(
|
|
955
963
|
"button",
|
|
956
964
|
{
|
|
@@ -1491,7 +1499,7 @@ function getMonthGrid(year, month, weekStartsOn = 0) {
|
|
|
1491
1499
|
const firstOfMonth = new Date(year, month, 1);
|
|
1492
1500
|
const gridStart = startOfWeek(firstOfMonth, weekStartsOn);
|
|
1493
1501
|
const weeks = [];
|
|
1494
|
-
|
|
1502
|
+
const current = new Date(gridStart);
|
|
1495
1503
|
for (let w = 0; w < 6; w++) {
|
|
1496
1504
|
const week = [];
|
|
1497
1505
|
for (let d = 0; d < 7; d++) {
|
|
@@ -2292,11 +2300,11 @@ function NumberInput({
|
|
|
2292
2300
|
const [focused, setFocused] = useState(false);
|
|
2293
2301
|
const [draft, setDraft] = useState(String(value));
|
|
2294
2302
|
const decimals = allowDecimals ?? step % 1 !== 0;
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
}
|
|
2303
|
+
const [prevSync, setPrevSync] = useState({ value, focused });
|
|
2304
|
+
if (value !== prevSync.value || focused !== prevSync.focused) {
|
|
2305
|
+
setPrevSync({ value, focused });
|
|
2306
|
+
if (!focused) setDraft(String(value));
|
|
2307
|
+
}
|
|
2300
2308
|
const clamp = useCallback(
|
|
2301
2309
|
(v) => Math.min(max, Math.max(min, v)),
|
|
2302
2310
|
[min, max]
|
|
@@ -2397,7 +2405,7 @@ function NumberInput({
|
|
|
2397
2405
|
onMouseDown: (e) => {
|
|
2398
2406
|
e.preventDefault();
|
|
2399
2407
|
inputRef.current?.focus();
|
|
2400
|
-
!disabled && !atMin
|
|
2408
|
+
if (!disabled && !atMin) startRepeat(decrement);
|
|
2401
2409
|
},
|
|
2402
2410
|
onMouseUp: stopRepeat,
|
|
2403
2411
|
onMouseLeave: stopRepeat,
|
|
@@ -2453,7 +2461,7 @@ function NumberInput({
|
|
|
2453
2461
|
onMouseDown: (e) => {
|
|
2454
2462
|
e.preventDefault();
|
|
2455
2463
|
inputRef.current?.focus();
|
|
2456
|
-
!disabled && !atMax
|
|
2464
|
+
if (!disabled && !atMax) startRepeat(increment);
|
|
2457
2465
|
},
|
|
2458
2466
|
onMouseUp: stopRepeat,
|
|
2459
2467
|
onMouseLeave: stopRepeat,
|
|
@@ -3012,11 +3020,12 @@ function ColorPicker({
|
|
|
3012
3020
|
const [hexInput, setHexInput] = useState(value);
|
|
3013
3021
|
const satLightRef = useRef(null);
|
|
3014
3022
|
const draggingRef = useRef(false);
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3023
|
+
const [prevValue, setPrevValue] = useState(value);
|
|
3024
|
+
if (value !== prevValue) {
|
|
3025
|
+
setPrevValue(value);
|
|
3026
|
+
setHsl(hexToHsl(value));
|
|
3018
3027
|
setHexInput(value);
|
|
3019
|
-
}
|
|
3028
|
+
}
|
|
3020
3029
|
const emitChange = useCallback(
|
|
3021
3030
|
(newHsl) => {
|
|
3022
3031
|
setHsl(newHsl);
|
|
@@ -3250,17 +3259,15 @@ function useFormContext() {
|
|
|
3250
3259
|
function FormWrapper({ onSubmit, validationMode = "onSubmit", children, className, ref }) {
|
|
3251
3260
|
const [errors, setErrors] = useState({});
|
|
3252
3261
|
const [submitted, setSubmitted] = useState(false);
|
|
3253
|
-
const errorsRef =
|
|
3254
|
-
errorsRef.current = errors;
|
|
3262
|
+
const errorsRef = useLatest(errors);
|
|
3255
3263
|
const pendingSubmit = useRef(false);
|
|
3256
|
-
const onSubmitRef =
|
|
3257
|
-
onSubmitRef.current = onSubmit;
|
|
3264
|
+
const onSubmitRef = useLatest(onSubmit);
|
|
3258
3265
|
useEffect(() => {
|
|
3259
3266
|
if (pendingSubmit.current && submitted) {
|
|
3260
3267
|
pendingSubmit.current = false;
|
|
3261
3268
|
onSubmitRef.current(errorsRef.current);
|
|
3262
3269
|
}
|
|
3263
|
-
}, [submitted, errors]);
|
|
3270
|
+
}, [submitted, errors, errorsRef, onSubmitRef]);
|
|
3264
3271
|
const setError = useCallback((field, message) => {
|
|
3265
3272
|
setErrors((prev) => ({ ...prev, [field]: message }));
|
|
3266
3273
|
}, []);
|
|
@@ -3580,13 +3587,30 @@ var sizeStyles3 = {
|
|
|
3580
3587
|
md: "h-10 w-10 text-sm",
|
|
3581
3588
|
lg: "h-12 w-12 text-base"
|
|
3582
3589
|
};
|
|
3590
|
+
var paletteStyles = {
|
|
3591
|
+
1: "bg-[var(--ds-palette-1-bg,var(--ds-bg-muted))] text-[var(--ds-palette-1-text,var(--ds-text-secondary))]",
|
|
3592
|
+
2: "bg-[var(--ds-palette-2-bg,var(--ds-bg-muted))] text-[var(--ds-palette-2-text,var(--ds-text-secondary))]",
|
|
3593
|
+
3: "bg-[var(--ds-palette-3-bg,var(--ds-bg-muted))] text-[var(--ds-palette-3-text,var(--ds-text-secondary))]",
|
|
3594
|
+
4: "bg-[var(--ds-palette-4-bg,var(--ds-bg-muted))] text-[var(--ds-palette-4-text,var(--ds-text-secondary))]",
|
|
3595
|
+
5: "bg-[var(--ds-palette-5-bg,var(--ds-bg-muted))] text-[var(--ds-palette-5-text,var(--ds-text-secondary))]"
|
|
3596
|
+
};
|
|
3597
|
+
function paletteFor(seed) {
|
|
3598
|
+
let h = 0;
|
|
3599
|
+
for (const ch of seed) h = h * 31 + ch.charCodeAt(0) >>> 0;
|
|
3600
|
+
return h % 5 + 1;
|
|
3601
|
+
}
|
|
3602
|
+
function colorStyles(color, seed) {
|
|
3603
|
+
if (color === "accent") return "bg-[var(--ds-accent-primary)] text-[var(--ds-text-on-primary)]";
|
|
3604
|
+
if (color === "neutral") return "bg-[var(--ds-bg-muted)] text-[var(--ds-text-secondary)]";
|
|
3605
|
+
return paletteStyles[color === "auto" ? paletteFor(seed) : color];
|
|
3606
|
+
}
|
|
3583
3607
|
var statusVariantMap = {
|
|
3584
3608
|
online: "success",
|
|
3585
3609
|
away: "warning",
|
|
3586
3610
|
busy: "error",
|
|
3587
3611
|
offline: "offline"
|
|
3588
3612
|
};
|
|
3589
|
-
function Avatar({ initials, src, alt, size = "md", status, className }) {
|
|
3613
|
+
function Avatar({ initials, src, alt, size = "md", status, color = "auto", className }) {
|
|
3590
3614
|
const base = cn(
|
|
3591
3615
|
"inline-flex items-center justify-center font-medium shrink-0",
|
|
3592
3616
|
"rounded-[var(--ds-radius-full)]",
|
|
@@ -3605,7 +3629,7 @@ function Avatar({ initials, src, alt, size = "md", status, className }) {
|
|
|
3605
3629
|
{
|
|
3606
3630
|
className: cn(
|
|
3607
3631
|
base,
|
|
3608
|
-
|
|
3632
|
+
colorStyles(color, alt ?? initials ?? ""),
|
|
3609
3633
|
"border-[length:var(--ds-border-width)] border-transparent"
|
|
3610
3634
|
),
|
|
3611
3635
|
children: initials
|
|
@@ -5801,9 +5825,12 @@ function MonthDropdown({
|
|
|
5801
5825
|
offset: 8,
|
|
5802
5826
|
flip: true
|
|
5803
5827
|
});
|
|
5804
|
-
|
|
5828
|
+
const browseSyncKey = open ? currentDate.getTime() : null;
|
|
5829
|
+
const [prevBrowseSyncKey, setPrevBrowseSyncKey] = useState(browseSyncKey);
|
|
5830
|
+
if (browseSyncKey !== prevBrowseSyncKey) {
|
|
5831
|
+
setPrevBrowseSyncKey(browseSyncKey);
|
|
5805
5832
|
if (open) setBrowseYear(currentDate.getFullYear());
|
|
5806
|
-
}
|
|
5833
|
+
}
|
|
5807
5834
|
useEffect(() => {
|
|
5808
5835
|
if (!open) return;
|
|
5809
5836
|
const onKey = (e) => {
|
|
@@ -5921,9 +5948,12 @@ function YearDropdown({
|
|
|
5921
5948
|
});
|
|
5922
5949
|
const currentYear = currentDate.getFullYear();
|
|
5923
5950
|
const [rangeStart, setRangeStart] = useState(() => currentYear - 4);
|
|
5924
|
-
|
|
5951
|
+
const rangeSyncKey = open ? currentYear : null;
|
|
5952
|
+
const [prevRangeSyncKey, setPrevRangeSyncKey] = useState(rangeSyncKey);
|
|
5953
|
+
if (rangeSyncKey !== prevRangeSyncKey) {
|
|
5954
|
+
setPrevRangeSyncKey(rangeSyncKey);
|
|
5925
5955
|
if (open) setRangeStart(currentYear - 4);
|
|
5926
|
-
}
|
|
5956
|
+
}
|
|
5927
5957
|
useEffect(() => {
|
|
5928
5958
|
if (!open) return;
|
|
5929
5959
|
const onKey = (e) => {
|
|
@@ -6344,6 +6374,7 @@ function AvatarGroup({ items, max = 4, size = "sm", ring = "canvas", onOverflowC
|
|
|
6344
6374
|
initials,
|
|
6345
6375
|
size,
|
|
6346
6376
|
status: item.status,
|
|
6377
|
+
color: item.color,
|
|
6347
6378
|
className: ringClass
|
|
6348
6379
|
},
|
|
6349
6380
|
i
|
|
@@ -6644,6 +6675,13 @@ function TruncLabel2({ children }) {
|
|
|
6644
6675
|
if (!isTruncated) return label;
|
|
6645
6676
|
return /* @__PURE__ */ jsx(Tooltip, { content: children, children: label });
|
|
6646
6677
|
}
|
|
6678
|
+
function allDescendantIds(node) {
|
|
6679
|
+
const ids = [node.id];
|
|
6680
|
+
if (node.children) {
|
|
6681
|
+
for (const child of node.children) ids.push(...allDescendantIds(child));
|
|
6682
|
+
}
|
|
6683
|
+
return ids;
|
|
6684
|
+
}
|
|
6647
6685
|
function TreeView({
|
|
6648
6686
|
nodes,
|
|
6649
6687
|
selectable,
|
|
@@ -6686,13 +6724,6 @@ function TreeView({
|
|
|
6686
6724
|
},
|
|
6687
6725
|
[selectable, multiSelect, onSelect]
|
|
6688
6726
|
);
|
|
6689
|
-
const allDescendantIds = useCallback((node) => {
|
|
6690
|
-
const ids = [node.id];
|
|
6691
|
-
if (node.children) {
|
|
6692
|
-
for (const child of node.children) ids.push(...allDescendantIds(child));
|
|
6693
|
-
}
|
|
6694
|
-
return ids;
|
|
6695
|
-
}, []);
|
|
6696
6727
|
const handleCheck = useCallback(
|
|
6697
6728
|
(node) => {
|
|
6698
6729
|
if (!checkable) return;
|
|
@@ -6708,7 +6739,7 @@ function TreeView({
|
|
|
6708
6739
|
return next;
|
|
6709
6740
|
});
|
|
6710
6741
|
},
|
|
6711
|
-
[checkable,
|
|
6742
|
+
[checkable, onCheck]
|
|
6712
6743
|
);
|
|
6713
6744
|
const getCheckState = useCallback(
|
|
6714
6745
|
(node) => {
|
|
@@ -6719,7 +6750,7 @@ function TreeView({
|
|
|
6719
6750
|
if (checkedCount > 0) return "indeterminate";
|
|
6720
6751
|
return "unchecked";
|
|
6721
6752
|
},
|
|
6722
|
-
[checked
|
|
6753
|
+
[checked]
|
|
6723
6754
|
);
|
|
6724
6755
|
const flatNodes = useCallback(() => {
|
|
6725
6756
|
const result = [];
|
|
@@ -7561,9 +7592,23 @@ function TabsRoot(props) {
|
|
|
7561
7592
|
overflow = "scroll",
|
|
7562
7593
|
className
|
|
7563
7594
|
} = props;
|
|
7595
|
+
const isMobile = useBreakpoint("md");
|
|
7596
|
+
const effectiveOrientation = orientation === "responsive" ? "vertical" : orientation;
|
|
7564
7597
|
if ("tabs" in props && props.tabs) {
|
|
7565
|
-
const { tabs } = props;
|
|
7566
|
-
|
|
7598
|
+
const { tabs, mobile = "scroll" } = props;
|
|
7599
|
+
const collapseToDropdown = isMobile && (orientation === "responsive" || mobile === "dropdown");
|
|
7600
|
+
if (collapseToDropdown) {
|
|
7601
|
+
return /* @__PURE__ */ jsx(
|
|
7602
|
+
Dropdown,
|
|
7603
|
+
{
|
|
7604
|
+
options: tabs.filter((t) => !t.disabled).map((t) => ({ id: t.id, label: t.label, group: t.group })),
|
|
7605
|
+
value: activeTab,
|
|
7606
|
+
onChange: (v) => onTabChange(v),
|
|
7607
|
+
className
|
|
7608
|
+
}
|
|
7609
|
+
);
|
|
7610
|
+
}
|
|
7611
|
+
if (effectiveOrientation === "vertical") {
|
|
7567
7612
|
return /* @__PURE__ */ jsx(
|
|
7568
7613
|
"div",
|
|
7569
7614
|
{
|
|
@@ -7574,7 +7619,20 @@ function TabsRoot(props) {
|
|
|
7574
7619
|
variant === "underline" && "border-r-[length:var(--ds-border-width)] border-[var(--ds-border-default)] pr-ds-1",
|
|
7575
7620
|
className
|
|
7576
7621
|
),
|
|
7577
|
-
children: tabs.map((tab) => /* @__PURE__ */
|
|
7622
|
+
children: tabs.map((tab, i) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
7623
|
+
tab.group && tab.group !== tabs[i - 1]?.group && /* @__PURE__ */ jsx(
|
|
7624
|
+
"span",
|
|
7625
|
+
{
|
|
7626
|
+
"aria-hidden": "true",
|
|
7627
|
+
className: cn(
|
|
7628
|
+
"px-ds-3 pb-ds-1 text-xs font-semibold uppercase tracking-wider text-[var(--ds-text-muted)]",
|
|
7629
|
+
i > 0 && "mt-ds-3"
|
|
7630
|
+
),
|
|
7631
|
+
children: tab.group
|
|
7632
|
+
}
|
|
7633
|
+
),
|
|
7634
|
+
/* @__PURE__ */ jsx(TabButton, { hasPanel: false, ...tab, orientation: effectiveOrientation, variant, activeTab, onTabChange, fullWidth, onKeyDown: (e) => handleTabKeyDown(e, tab.id, () => tabs, effectiveOrientation, onTabChange) })
|
|
7635
|
+
] }, tab.id))
|
|
7578
7636
|
}
|
|
7579
7637
|
);
|
|
7580
7638
|
}
|
|
@@ -7591,11 +7649,11 @@ function TabsRoot(props) {
|
|
|
7591
7649
|
fullWidth && "w-full",
|
|
7592
7650
|
className
|
|
7593
7651
|
),
|
|
7594
|
-
children: tabs.map((tab) => /* @__PURE__ */ jsx(TabButton, { hasPanel: false, ...tab, orientation, variant, activeTab, onTabChange, fullWidth, onKeyDown: (e) => handleTabKeyDown(e, tab.id, () => tabs,
|
|
7652
|
+
children: tabs.map((tab) => /* @__PURE__ */ jsx(TabButton, { hasPanel: false, ...tab, orientation: effectiveOrientation, variant, activeTab, onTabChange, fullWidth, onKeyDown: (e) => handleTabKeyDown(e, tab.id, () => tabs, effectiveOrientation, onTabChange) }, tab.id))
|
|
7595
7653
|
}
|
|
7596
7654
|
);
|
|
7597
7655
|
}
|
|
7598
|
-
return /* @__PURE__ */ jsx(TabsContext.Provider, { value: { activeTab, onTabChange, orientation, variant, fullWidth, overflow }, children: /* @__PURE__ */ jsx("div", { className, children: props.children }) });
|
|
7656
|
+
return /* @__PURE__ */ jsx(TabsContext.Provider, { value: { activeTab, onTabChange, orientation: effectiveOrientation, variant, fullWidth, overflow }, children: /* @__PURE__ */ jsx("div", { className, children: props.children }) });
|
|
7599
7657
|
}
|
|
7600
7658
|
var Tabs = Object.assign(TabsRoot, {
|
|
7601
7659
|
List: TabsList,
|
|
@@ -7800,6 +7858,11 @@ var Breadcrumbs = forwardRef(function Breadcrumbs2({
|
|
|
7800
7858
|
function Popover({ open, onOpenChange, trigger, children, side = "bottom", align = "center", width, className, container }) {
|
|
7801
7859
|
const triggerRef = useRef(null);
|
|
7802
7860
|
const floatingRef = useRef(null);
|
|
7861
|
+
const [triggerWidth, setTriggerWidth] = useState(void 0);
|
|
7862
|
+
const setTriggerNode = useCallback((node) => {
|
|
7863
|
+
triggerRef.current = node;
|
|
7864
|
+
setTriggerWidth(node?.offsetWidth);
|
|
7865
|
+
}, []);
|
|
7803
7866
|
const pos = usePosition(triggerRef, floatingRef, open, { side, align, offset: 8, flip: true });
|
|
7804
7867
|
useEffect(() => {
|
|
7805
7868
|
if (!open) return;
|
|
@@ -7825,8 +7888,11 @@ function Popover({ open, onOpenChange, trigger, children, side = "bottom", align
|
|
|
7825
7888
|
/* @__PURE__ */ jsx(
|
|
7826
7889
|
Slot,
|
|
7827
7890
|
{
|
|
7828
|
-
ref:
|
|
7829
|
-
onClick: () =>
|
|
7891
|
+
ref: setTriggerNode,
|
|
7892
|
+
onClick: () => {
|
|
7893
|
+
setTriggerWidth(triggerRef.current?.offsetWidth);
|
|
7894
|
+
onOpenChange(!open);
|
|
7895
|
+
},
|
|
7830
7896
|
children: trigger
|
|
7831
7897
|
}
|
|
7832
7898
|
),
|
|
@@ -7846,7 +7912,7 @@ function Popover({ open, onOpenChange, trigger, children, side = "bottom", align
|
|
|
7846
7912
|
style: {
|
|
7847
7913
|
top: pos.top,
|
|
7848
7914
|
left: pos.left,
|
|
7849
|
-
width: width === "trigger" ?
|
|
7915
|
+
width: width === "trigger" ? triggerWidth : width === "auto" ? void 0 : width
|
|
7850
7916
|
},
|
|
7851
7917
|
children
|
|
7852
7918
|
}
|
|
@@ -8462,10 +8528,7 @@ function CompactFlyout({
|
|
|
8462
8528
|
onMouseEnter,
|
|
8463
8529
|
onMouseLeave
|
|
8464
8530
|
}) {
|
|
8465
|
-
const
|
|
8466
|
-
useLayoutEffect(() => {
|
|
8467
|
-
setPos(computeCompactFlyoutPos(anchorEl, items.length));
|
|
8468
|
-
}, [anchorEl, items.length]);
|
|
8531
|
+
const pos = useMemo(() => computeCompactFlyoutPos(anchorEl, items.length), [anchorEl, items.length]);
|
|
8469
8532
|
useEffect(() => {
|
|
8470
8533
|
function handler(e) {
|
|
8471
8534
|
if (e.key === "Escape") onClose();
|
|
@@ -8855,7 +8918,7 @@ function CompactNavItem({
|
|
|
8855
8918
|
expanded,
|
|
8856
8919
|
onToggleExpand
|
|
8857
8920
|
}) {
|
|
8858
|
-
const
|
|
8921
|
+
const [triggerEl, setTriggerEl] = useState(null);
|
|
8859
8922
|
const handleMouseEnter = useCallback(() => {
|
|
8860
8923
|
onCancelClose();
|
|
8861
8924
|
if (hasChildren && !isOpen) onOpen(flyoutKey);
|
|
@@ -8874,7 +8937,7 @@ function CompactNavItem({
|
|
|
8874
8937
|
/* @__PURE__ */ jsxs(
|
|
8875
8938
|
"button",
|
|
8876
8939
|
{
|
|
8877
|
-
ref:
|
|
8940
|
+
ref: setTriggerEl,
|
|
8878
8941
|
onMouseEnter: !mobile && hasChildren ? handleMouseEnter : void 0,
|
|
8879
8942
|
onMouseLeave: !mobile && hasChildren && isOpen ? handleMouseLeave : void 0,
|
|
8880
8943
|
onClick: handleClick,
|
|
@@ -8908,12 +8971,12 @@ function CompactNavItem({
|
|
|
8908
8971
|
]
|
|
8909
8972
|
}
|
|
8910
8973
|
),
|
|
8911
|
-
!mobile && isOpen && hasChildren && item.children &&
|
|
8974
|
+
!mobile && isOpen && hasChildren && item.children && triggerEl && /* @__PURE__ */ jsx(
|
|
8912
8975
|
CompactFlyout,
|
|
8913
8976
|
{
|
|
8914
8977
|
parentLabel: item.label,
|
|
8915
8978
|
items: item.children,
|
|
8916
|
-
anchorEl:
|
|
8979
|
+
anchorEl: triggerEl,
|
|
8917
8980
|
portalContainer,
|
|
8918
8981
|
onItemClick,
|
|
8919
8982
|
onClose,
|
|
@@ -9903,6 +9966,187 @@ function Dock({
|
|
|
9903
9966
|
}
|
|
9904
9967
|
);
|
|
9905
9968
|
}
|
|
9969
|
+
function Sheet({ open, onClose, title, children, footer, snapPoints = [0.5, 0.92], container, flush }) {
|
|
9970
|
+
const titleId = useId();
|
|
9971
|
+
const panelRef = useRef(null);
|
|
9972
|
+
const [mounted, setMounted] = useState(open);
|
|
9973
|
+
const [snapIdx, setSnapIdx] = useState(0);
|
|
9974
|
+
const [dragOffset, setDragOffset] = useState(0);
|
|
9975
|
+
const [dragging, setDragging] = useState(false);
|
|
9976
|
+
const dragStartY = useRef(0);
|
|
9977
|
+
const startHeight = useRef(0);
|
|
9978
|
+
const onCloseRef = useLatest(onClose);
|
|
9979
|
+
const [prevOpen, setPrevOpen] = useState(open);
|
|
9980
|
+
if (open !== prevOpen) {
|
|
9981
|
+
setPrevOpen(open);
|
|
9982
|
+
if (open) {
|
|
9983
|
+
setMounted(true);
|
|
9984
|
+
setSnapIdx(0);
|
|
9985
|
+
setDragOffset(0);
|
|
9986
|
+
}
|
|
9987
|
+
}
|
|
9988
|
+
const viewportHeight = useCallback(
|
|
9989
|
+
() => container instanceof HTMLElement ? container.clientHeight : window.innerHeight,
|
|
9990
|
+
[container]
|
|
9991
|
+
);
|
|
9992
|
+
function handleTransitionEnd() {
|
|
9993
|
+
if (!open) setMounted(false);
|
|
9994
|
+
}
|
|
9995
|
+
useReturnFocus(open);
|
|
9996
|
+
useEffect(() => {
|
|
9997
|
+
if (!open || !mounted) return;
|
|
9998
|
+
const raf = requestAnimationFrame(() => focusInitial(panelRef.current));
|
|
9999
|
+
return () => cancelAnimationFrame(raf);
|
|
10000
|
+
}, [open, mounted]);
|
|
10001
|
+
useEffect(() => {
|
|
10002
|
+
if (!open) return;
|
|
10003
|
+
const onKeyDown = (e) => {
|
|
10004
|
+
if (e.key === "Escape") onCloseRef.current();
|
|
10005
|
+
};
|
|
10006
|
+
document.addEventListener("keydown", onKeyDown);
|
|
10007
|
+
if (!container) lockBodyScroll();
|
|
10008
|
+
return () => {
|
|
10009
|
+
document.removeEventListener("keydown", onKeyDown);
|
|
10010
|
+
if (!container) unlockBodyScroll();
|
|
10011
|
+
};
|
|
10012
|
+
}, [open, container, onCloseRef]);
|
|
10013
|
+
const handlePointerDown = useCallback((e) => {
|
|
10014
|
+
setDragging(true);
|
|
10015
|
+
dragStartY.current = e.clientY;
|
|
10016
|
+
startHeight.current = (snapPoints[snapIdx] ?? snapPoints[0]) * viewportHeight();
|
|
10017
|
+
setDragOffset(0);
|
|
10018
|
+
e.target.setPointerCapture(e.pointerId);
|
|
10019
|
+
}, [snapIdx, snapPoints, viewportHeight]);
|
|
10020
|
+
const handlePointerMove = useCallback((e) => {
|
|
10021
|
+
if (!dragging) return;
|
|
10022
|
+
const delta = dragStartY.current - e.clientY;
|
|
10023
|
+
setDragOffset(delta);
|
|
10024
|
+
}, [dragging]);
|
|
10025
|
+
const handlePointerUp = useCallback(() => {
|
|
10026
|
+
if (!dragging) return;
|
|
10027
|
+
setDragging(false);
|
|
10028
|
+
const currentHeightPx = startHeight.current + dragOffset;
|
|
10029
|
+
const currentFraction = currentHeightPx / viewportHeight();
|
|
10030
|
+
if (currentFraction < snapPoints[0] * 0.6) {
|
|
10031
|
+
onClose();
|
|
10032
|
+
setDragOffset(0);
|
|
10033
|
+
return;
|
|
10034
|
+
}
|
|
10035
|
+
let bestIdx = 0;
|
|
10036
|
+
let bestDist = Math.abs(currentFraction - snapPoints[0]);
|
|
10037
|
+
for (let i = 1; i < snapPoints.length; i++) {
|
|
10038
|
+
const dist = Math.abs(currentFraction - snapPoints[i]);
|
|
10039
|
+
if (dist < bestDist) {
|
|
10040
|
+
bestDist = dist;
|
|
10041
|
+
bestIdx = i;
|
|
10042
|
+
}
|
|
10043
|
+
}
|
|
10044
|
+
setSnapIdx(bestIdx);
|
|
10045
|
+
setDragOffset(0);
|
|
10046
|
+
}, [dragging, dragOffset, snapPoints, onClose, viewportHeight]);
|
|
10047
|
+
if (!mounted) return null;
|
|
10048
|
+
const baseHeight = (snapPoints[snapIdx] ?? snapPoints[0]) * 100;
|
|
10049
|
+
const heightUnit = container ? "%" : "vh";
|
|
10050
|
+
const dragPx = dragging ? dragOffset : 0;
|
|
10051
|
+
const positionClass = container ? "absolute" : "fixed";
|
|
10052
|
+
return createPortal(
|
|
10053
|
+
/* @__PURE__ */ jsxs(
|
|
10054
|
+
"div",
|
|
10055
|
+
{
|
|
10056
|
+
className: cn(
|
|
10057
|
+
`${positionClass} inset-0 z-[var(--ds-z-modal)] transition-opacity duration-[var(--ds-transition-speed)]`,
|
|
10058
|
+
open ? "pointer-events-auto" : "pointer-events-none"
|
|
10059
|
+
),
|
|
10060
|
+
onTransitionEnd: handleTransitionEnd,
|
|
10061
|
+
children: [
|
|
10062
|
+
/* @__PURE__ */ jsx(
|
|
10063
|
+
"div",
|
|
10064
|
+
{
|
|
10065
|
+
className: cn(
|
|
10066
|
+
"absolute inset-0 bg-black/50 transition-opacity duration-[var(--ds-transition-speed)]",
|
|
10067
|
+
open ? "opacity-100" : "opacity-0"
|
|
10068
|
+
),
|
|
10069
|
+
onClick: onClose
|
|
10070
|
+
}
|
|
10071
|
+
),
|
|
10072
|
+
/* @__PURE__ */ jsxs(
|
|
10073
|
+
"div",
|
|
10074
|
+
{
|
|
10075
|
+
ref: panelRef,
|
|
10076
|
+
role: "dialog",
|
|
10077
|
+
"aria-modal": "true",
|
|
10078
|
+
"aria-labelledby": title ? titleId : void 0,
|
|
10079
|
+
"data-ds-sheet": "",
|
|
10080
|
+
className: cn(
|
|
10081
|
+
`${positionClass} bottom-0 left-0 right-0 z-10 flex flex-col`,
|
|
10082
|
+
"bg-[var(--ds-bg-surface)] text-[var(--ds-text-primary)]",
|
|
10083
|
+
GLASS_OVERLAY,
|
|
10084
|
+
"border-t-[length:var(--ds-border-width)] border-[var(--ds-border-default)]",
|
|
10085
|
+
"rounded-t-[var(--ds-radius-xl)]",
|
|
10086
|
+
!dragging && "transition-[transform,height] duration-[var(--ds-transition-speed)] ease-[var(--ds-transition-ease)]",
|
|
10087
|
+
open ? "translate-y-0" : "translate-y-full"
|
|
10088
|
+
),
|
|
10089
|
+
style: {
|
|
10090
|
+
containerType: "inline-size",
|
|
10091
|
+
height: dragPx ? `calc(${baseHeight}${heightUnit} + ${dragPx}px)` : `${baseHeight}${heightUnit}`
|
|
10092
|
+
},
|
|
10093
|
+
children: [
|
|
10094
|
+
/* @__PURE__ */ jsx(
|
|
10095
|
+
"div",
|
|
10096
|
+
{
|
|
10097
|
+
className: "flex justify-center pt-ds-2 pb-ds-1 cursor-grab active:cursor-grabbing touch-none",
|
|
10098
|
+
onPointerDown: handlePointerDown,
|
|
10099
|
+
onPointerMove: handlePointerMove,
|
|
10100
|
+
onPointerUp: handlePointerUp,
|
|
10101
|
+
onPointerCancel: handlePointerUp,
|
|
10102
|
+
children: /* @__PURE__ */ jsx("div", { className: "w-10 h-1 rounded-[var(--ds-radius-full)] bg-[var(--ds-border-default)]" })
|
|
10103
|
+
}
|
|
10104
|
+
),
|
|
10105
|
+
title && /* @__PURE__ */ jsxs(
|
|
10106
|
+
"div",
|
|
10107
|
+
{
|
|
10108
|
+
className: "flex items-center justify-between shrink-0 border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]",
|
|
10109
|
+
style: { padding: "var(--ds-space-2) var(--ds-space-5)" },
|
|
10110
|
+
children: [
|
|
10111
|
+
/* @__PURE__ */ jsx("h2", { id: titleId, className: "font-[family-name:var(--ds-font-display)] text-lg font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)] truncate", children: title }),
|
|
10112
|
+
/* @__PURE__ */ jsx(
|
|
10113
|
+
"button",
|
|
10114
|
+
{
|
|
10115
|
+
onClick: onClose,
|
|
10116
|
+
...{ [OVERLAY_CLOSE_ATTR]: "" },
|
|
10117
|
+
className: "text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)] transition-colors cursor-pointer",
|
|
10118
|
+
"aria-label": "Close",
|
|
10119
|
+
children: /* @__PURE__ */ jsx(Icon, { name: "close", size: 18 })
|
|
10120
|
+
}
|
|
10121
|
+
)
|
|
10122
|
+
]
|
|
10123
|
+
}
|
|
10124
|
+
),
|
|
10125
|
+
/* @__PURE__ */ jsx(
|
|
10126
|
+
"div",
|
|
10127
|
+
{
|
|
10128
|
+
className: "flex-1 overflow-y-auto",
|
|
10129
|
+
style: flush ? void 0 : { padding: "var(--ds-space-5)" },
|
|
10130
|
+
children
|
|
10131
|
+
}
|
|
10132
|
+
),
|
|
10133
|
+
footer && /* @__PURE__ */ jsx(
|
|
10134
|
+
"div",
|
|
10135
|
+
{
|
|
10136
|
+
className: "shrink-0 flex items-center justify-end gap-ds-2 border-t-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]",
|
|
10137
|
+
style: { padding: "var(--ds-space-3) var(--ds-space-5)" },
|
|
10138
|
+
children: footer
|
|
10139
|
+
}
|
|
10140
|
+
)
|
|
10141
|
+
]
|
|
10142
|
+
}
|
|
10143
|
+
)
|
|
10144
|
+
]
|
|
10145
|
+
}
|
|
10146
|
+
),
|
|
10147
|
+
container ?? document.body
|
|
10148
|
+
);
|
|
10149
|
+
}
|
|
9906
10150
|
var slideClasses = {
|
|
9907
10151
|
right: {
|
|
9908
10152
|
panel: "top-0 right-0 h-full",
|
|
@@ -9925,19 +10169,23 @@ var borderByPosition = {
|
|
|
9925
10169
|
left: "border-r-[length:var(--ds-border-width)] border-r-[var(--ds-border-default)]",
|
|
9926
10170
|
bottom: "border-t-[length:var(--ds-border-width)] border-t-[var(--ds-border-default)]"
|
|
9927
10171
|
};
|
|
9928
|
-
function Drawer(
|
|
10172
|
+
function Drawer(props) {
|
|
10173
|
+
const { position = "right", mobile, snapPoints, open, onClose, title, children, footer, container, flush } = props;
|
|
10174
|
+
const isPhone = useBreakpoint("sm");
|
|
10175
|
+
const mobileMode = mobile ?? (position === "left" ? "panel" : "sheet");
|
|
10176
|
+
if (isPhone && mobileMode === "sheet") {
|
|
10177
|
+
return /* @__PURE__ */ jsx(Sheet, { open, onClose, title, footer, container, flush, snapPoints, children });
|
|
10178
|
+
}
|
|
10179
|
+
return /* @__PURE__ */ jsx(DrawerPanel, { ...props });
|
|
10180
|
+
}
|
|
10181
|
+
function DrawerPanel({ open, onClose, position = "right", width = "400px", title, children, footer, container, flush, lightBackdrop, topOffset }) {
|
|
9929
10182
|
const titleId = useId();
|
|
9930
10183
|
const { ref: titleOverflowRef, isTruncated: titleTruncated } = useTextOverflow({ lines: 1 });
|
|
9931
10184
|
const isMobile = useBreakpoint("sm");
|
|
9932
10185
|
const panelRef = useRef(null);
|
|
9933
|
-
const [mounted, setMounted] = useState(
|
|
9934
|
-
const onCloseRef =
|
|
9935
|
-
|
|
9936
|
-
useEffect(() => {
|
|
9937
|
-
if (open) {
|
|
9938
|
-
setMounted(true);
|
|
9939
|
-
}
|
|
9940
|
-
}, [open]);
|
|
10186
|
+
const [mounted, setMounted] = useState(open);
|
|
10187
|
+
const onCloseRef = useLatest(onClose);
|
|
10188
|
+
if (open && !mounted) setMounted(true);
|
|
9941
10189
|
function handleTransitionEnd() {
|
|
9942
10190
|
if (!open) setMounted(false);
|
|
9943
10191
|
}
|
|
@@ -9952,7 +10200,7 @@ function Drawer({ open, onClose, position = "right", width = "400px", title, chi
|
|
|
9952
10200
|
document.removeEventListener("keydown", onKeyDown);
|
|
9953
10201
|
if (!container) unlockBodyScroll();
|
|
9954
10202
|
};
|
|
9955
|
-
}, [open, container]);
|
|
10203
|
+
}, [open, container, onCloseRef]);
|
|
9956
10204
|
useReturnFocus(open);
|
|
9957
10205
|
useEffect(() => {
|
|
9958
10206
|
if (!open || !mounted) return;
|
|
@@ -10087,13 +10335,13 @@ var AppShell = forwardRef(function AppShell2({
|
|
|
10087
10335
|
const hasMobileMenu = mobileMenu != null;
|
|
10088
10336
|
const hasMobileNav = mobileNav != null;
|
|
10089
10337
|
const showMobileDrawer = hasMobileMenu && !(isSmallMobile && hasMobileNav);
|
|
10090
|
-
const
|
|
10338
|
+
const [shellEl, setShellEl] = useState(null);
|
|
10091
10339
|
return /* @__PURE__ */ jsx(
|
|
10092
10340
|
AppShellContext,
|
|
10093
10341
|
{
|
|
10094
10342
|
value: { hasSidebar, hasMobileMenu, hasMobileNav, sidebarOpen, setSidebarOpen, isMobile, isTablet },
|
|
10095
10343
|
children: /* @__PURE__ */ jsxs("div", { ref: (el) => {
|
|
10096
|
-
|
|
10344
|
+
setShellEl(el);
|
|
10097
10345
|
if (typeof ref === "function") ref(el);
|
|
10098
10346
|
else if (ref) ref.current = el;
|
|
10099
10347
|
}, className: cn("relative h-screen flex flex-col bg-[var(--ds-bg-canvas)] overflow-hidden", className), children: [
|
|
@@ -10125,7 +10373,7 @@ var AppShell = forwardRef(function AppShell2({
|
|
|
10125
10373
|
onClose: () => setSidebarOpen(false),
|
|
10126
10374
|
position: "left",
|
|
10127
10375
|
width: mobileMenuWidth ?? "var(--ds-drawer-width)",
|
|
10128
|
-
container:
|
|
10376
|
+
container: shellEl ?? void 0,
|
|
10129
10377
|
flush: mobileMenuFlush,
|
|
10130
10378
|
lightBackdrop: mobileMenuLightBackdrop,
|
|
10131
10379
|
topOffset: layout !== "stacked" && navbar != null ? "var(--ds-navbar-height)" : void 0,
|
|
@@ -10604,8 +10852,7 @@ function Dialog({ open, onClose, title, description, children, footer, variant =
|
|
|
10604
10852
|
const overlayRef = useRef(null);
|
|
10605
10853
|
const dialogRef = useRef(null);
|
|
10606
10854
|
const triggerRef = useRef(null);
|
|
10607
|
-
const onCloseRef =
|
|
10608
|
-
onCloseRef.current = onClose;
|
|
10855
|
+
const onCloseRef = useLatest(onClose);
|
|
10609
10856
|
const trapFocus = useCallback((e) => {
|
|
10610
10857
|
if (e.key !== "Tab" || !dialogRef.current) return;
|
|
10611
10858
|
const focusable = dialogRef.current.querySelectorAll(FOCUSABLE);
|
|
@@ -10641,7 +10888,7 @@ function Dialog({ open, onClose, title, description, children, footer, variant =
|
|
|
10641
10888
|
return () => {
|
|
10642
10889
|
document.removeEventListener("keydown", handler);
|
|
10643
10890
|
};
|
|
10644
|
-
}, [open, trapFocus, alert]);
|
|
10891
|
+
}, [open, trapFocus, alert, onCloseRef]);
|
|
10645
10892
|
useEffect(() => {
|
|
10646
10893
|
if (!open) return;
|
|
10647
10894
|
lockBodyScroll();
|
|
@@ -10753,16 +11000,22 @@ function CommandPalette({ open, onOpenChange, commands, placeholder = "Type a co
|
|
|
10753
11000
|
groups.get(g).push(cmd);
|
|
10754
11001
|
}
|
|
10755
11002
|
const flatFiltered = filtered;
|
|
10756
|
-
|
|
11003
|
+
const [prevOpen, setPrevOpen] = useState(open);
|
|
11004
|
+
if (open !== prevOpen) {
|
|
11005
|
+
setPrevOpen(open);
|
|
10757
11006
|
if (open) {
|
|
10758
11007
|
setQuery("");
|
|
10759
11008
|
setSelectedIdx(0);
|
|
10760
|
-
requestAnimationFrame(() => inputRef.current?.focus());
|
|
10761
11009
|
}
|
|
10762
|
-
}
|
|
10763
|
-
|
|
11010
|
+
}
|
|
11011
|
+
const [prevQuery, setPrevQuery] = useState(query);
|
|
11012
|
+
if (query !== prevQuery) {
|
|
11013
|
+
setPrevQuery(query);
|
|
10764
11014
|
setSelectedIdx(0);
|
|
10765
|
-
}
|
|
11015
|
+
}
|
|
11016
|
+
useEffect(() => {
|
|
11017
|
+
if (open) requestAnimationFrame(() => inputRef.current?.focus());
|
|
11018
|
+
}, [open]);
|
|
10766
11019
|
useEffect(() => {
|
|
10767
11020
|
if (!open) return;
|
|
10768
11021
|
const handler = (e) => {
|
|
@@ -10778,23 +11031,20 @@ function CommandPalette({ open, onOpenChange, commands, placeholder = "Type a co
|
|
|
10778
11031
|
},
|
|
10779
11032
|
[onOpenChange]
|
|
10780
11033
|
);
|
|
10781
|
-
const handleKeyDown =
|
|
10782
|
-
(e)
|
|
10783
|
-
|
|
10784
|
-
|
|
10785
|
-
|
|
10786
|
-
|
|
10787
|
-
|
|
10788
|
-
|
|
10789
|
-
|
|
10790
|
-
|
|
10791
|
-
|
|
10792
|
-
|
|
10793
|
-
|
|
10794
|
-
|
|
10795
|
-
},
|
|
10796
|
-
[flatFiltered, selectedIdx, handleSelect]
|
|
10797
|
-
);
|
|
11034
|
+
const handleKeyDown = (e) => {
|
|
11035
|
+
if (e.key === "ArrowDown") {
|
|
11036
|
+
e.preventDefault();
|
|
11037
|
+
setSelectedIdx((prev) => Math.min(prev + 1, flatFiltered.length - 1));
|
|
11038
|
+
listRef.current?.children[Math.min(selectedIdx + 1, flatFiltered.length - 1)]?.scrollIntoView({ block: "nearest" });
|
|
11039
|
+
} else if (e.key === "ArrowUp") {
|
|
11040
|
+
e.preventDefault();
|
|
11041
|
+
setSelectedIdx((prev) => Math.max(prev - 1, 0));
|
|
11042
|
+
listRef.current?.children[Math.max(selectedIdx - 1, 0)]?.scrollIntoView({ block: "nearest" });
|
|
11043
|
+
} else if (e.key === "Enter" && flatFiltered[selectedIdx]) {
|
|
11044
|
+
e.preventDefault();
|
|
11045
|
+
handleSelect(flatFiltered[selectedIdx]);
|
|
11046
|
+
}
|
|
11047
|
+
};
|
|
10798
11048
|
if (!open) return null;
|
|
10799
11049
|
let flatIdx = 0;
|
|
10800
11050
|
return createPortal(
|
|
@@ -11087,179 +11337,6 @@ function ContextMenu({ items, children, className, ref, container }) {
|
|
|
11087
11337
|
}
|
|
11088
11338
|
);
|
|
11089
11339
|
}
|
|
11090
|
-
function Sheet({ open, onClose, title, children, footer, snapPoints = [0.5, 0.92] }) {
|
|
11091
|
-
const titleId = useId();
|
|
11092
|
-
const panelRef = useRef(null);
|
|
11093
|
-
const [mounted, setMounted] = useState(false);
|
|
11094
|
-
const [snapIdx, setSnapIdx] = useState(0);
|
|
11095
|
-
const [dragOffset, setDragOffset] = useState(0);
|
|
11096
|
-
const isDragging = useRef(false);
|
|
11097
|
-
const dragStartY = useRef(0);
|
|
11098
|
-
const startHeight = useRef(0);
|
|
11099
|
-
const onCloseRef = useRef(onClose);
|
|
11100
|
-
onCloseRef.current = onClose;
|
|
11101
|
-
useEffect(() => {
|
|
11102
|
-
if (open) {
|
|
11103
|
-
setMounted(true);
|
|
11104
|
-
setSnapIdx(0);
|
|
11105
|
-
setDragOffset(0);
|
|
11106
|
-
}
|
|
11107
|
-
}, [open]);
|
|
11108
|
-
function handleTransitionEnd() {
|
|
11109
|
-
if (!open) setMounted(false);
|
|
11110
|
-
}
|
|
11111
|
-
useReturnFocus(open);
|
|
11112
|
-
useEffect(() => {
|
|
11113
|
-
if (!open || !mounted) return;
|
|
11114
|
-
const raf = requestAnimationFrame(() => focusInitial(panelRef.current));
|
|
11115
|
-
return () => cancelAnimationFrame(raf);
|
|
11116
|
-
}, [open, mounted]);
|
|
11117
|
-
useEffect(() => {
|
|
11118
|
-
if (!open) return;
|
|
11119
|
-
const onKeyDown = (e) => {
|
|
11120
|
-
if (e.key === "Escape") onCloseRef.current();
|
|
11121
|
-
};
|
|
11122
|
-
document.addEventListener("keydown", onKeyDown);
|
|
11123
|
-
lockBodyScroll();
|
|
11124
|
-
return () => {
|
|
11125
|
-
document.removeEventListener("keydown", onKeyDown);
|
|
11126
|
-
unlockBodyScroll();
|
|
11127
|
-
};
|
|
11128
|
-
}, [open]);
|
|
11129
|
-
const handlePointerDown = useCallback((e) => {
|
|
11130
|
-
isDragging.current = true;
|
|
11131
|
-
dragStartY.current = e.clientY;
|
|
11132
|
-
startHeight.current = (snapPoints[snapIdx] ?? snapPoints[0]) * window.innerHeight;
|
|
11133
|
-
setDragOffset(0);
|
|
11134
|
-
e.target.setPointerCapture(e.pointerId);
|
|
11135
|
-
}, [snapIdx, snapPoints]);
|
|
11136
|
-
const handlePointerMove = useCallback((e) => {
|
|
11137
|
-
if (!isDragging.current) return;
|
|
11138
|
-
const delta = dragStartY.current - e.clientY;
|
|
11139
|
-
setDragOffset(delta);
|
|
11140
|
-
}, []);
|
|
11141
|
-
const handlePointerUp = useCallback(() => {
|
|
11142
|
-
if (!isDragging.current) return;
|
|
11143
|
-
isDragging.current = false;
|
|
11144
|
-
const currentHeightPx = startHeight.current + dragOffset;
|
|
11145
|
-
const currentFraction = currentHeightPx / window.innerHeight;
|
|
11146
|
-
if (currentFraction < snapPoints[0] * 0.6) {
|
|
11147
|
-
onClose();
|
|
11148
|
-
setDragOffset(0);
|
|
11149
|
-
return;
|
|
11150
|
-
}
|
|
11151
|
-
let bestIdx = 0;
|
|
11152
|
-
let bestDist = Math.abs(currentFraction - snapPoints[0]);
|
|
11153
|
-
for (let i = 1; i < snapPoints.length; i++) {
|
|
11154
|
-
const dist = Math.abs(currentFraction - snapPoints[i]);
|
|
11155
|
-
if (dist < bestDist) {
|
|
11156
|
-
bestDist = dist;
|
|
11157
|
-
bestIdx = i;
|
|
11158
|
-
}
|
|
11159
|
-
}
|
|
11160
|
-
setSnapIdx(bestIdx);
|
|
11161
|
-
setDragOffset(0);
|
|
11162
|
-
}, [dragOffset, snapPoints, onClose]);
|
|
11163
|
-
if (!mounted) return null;
|
|
11164
|
-
const baseHeightVh = (snapPoints[snapIdx] ?? snapPoints[0]) * 100;
|
|
11165
|
-
const dragPx = isDragging.current ? dragOffset : 0;
|
|
11166
|
-
return createPortal(
|
|
11167
|
-
/* @__PURE__ */ jsxs(
|
|
11168
|
-
"div",
|
|
11169
|
-
{
|
|
11170
|
-
className: cn(
|
|
11171
|
-
"fixed inset-0 z-[var(--ds-z-modal)] transition-opacity duration-[var(--ds-transition-speed)]",
|
|
11172
|
-
open ? "pointer-events-auto" : "pointer-events-none"
|
|
11173
|
-
),
|
|
11174
|
-
onTransitionEnd: handleTransitionEnd,
|
|
11175
|
-
children: [
|
|
11176
|
-
/* @__PURE__ */ jsx(
|
|
11177
|
-
"div",
|
|
11178
|
-
{
|
|
11179
|
-
className: cn(
|
|
11180
|
-
"absolute inset-0 bg-black/50 transition-opacity duration-[var(--ds-transition-speed)]",
|
|
11181
|
-
open ? "opacity-100" : "opacity-0"
|
|
11182
|
-
),
|
|
11183
|
-
onClick: onClose
|
|
11184
|
-
}
|
|
11185
|
-
),
|
|
11186
|
-
/* @__PURE__ */ jsxs(
|
|
11187
|
-
"div",
|
|
11188
|
-
{
|
|
11189
|
-
ref: panelRef,
|
|
11190
|
-
role: "dialog",
|
|
11191
|
-
"aria-modal": "true",
|
|
11192
|
-
"aria-labelledby": title ? titleId : void 0,
|
|
11193
|
-
className: cn(
|
|
11194
|
-
"fixed bottom-0 left-0 right-0 z-10 flex flex-col",
|
|
11195
|
-
"bg-[var(--ds-bg-surface)] text-[var(--ds-text-primary)]",
|
|
11196
|
-
GLASS_OVERLAY,
|
|
11197
|
-
"border-t-[length:var(--ds-border-width)] border-[var(--ds-border-default)]",
|
|
11198
|
-
"rounded-t-[var(--ds-radius-xl)]",
|
|
11199
|
-
!isDragging.current && "transition-[transform,height] duration-[var(--ds-transition-speed)] ease-[var(--ds-transition-ease)]",
|
|
11200
|
-
open ? "translate-y-0" : "translate-y-full"
|
|
11201
|
-
),
|
|
11202
|
-
style: {
|
|
11203
|
-
containerType: "inline-size",
|
|
11204
|
-
height: dragPx ? `calc(${baseHeightVh}vh + ${dragPx}px)` : `${baseHeightVh}vh`
|
|
11205
|
-
},
|
|
11206
|
-
children: [
|
|
11207
|
-
/* @__PURE__ */ jsx(
|
|
11208
|
-
"div",
|
|
11209
|
-
{
|
|
11210
|
-
className: "flex justify-center pt-ds-2 pb-ds-1 cursor-grab active:cursor-grabbing touch-none",
|
|
11211
|
-
onPointerDown: handlePointerDown,
|
|
11212
|
-
onPointerMove: handlePointerMove,
|
|
11213
|
-
onPointerUp: handlePointerUp,
|
|
11214
|
-
onPointerCancel: handlePointerUp,
|
|
11215
|
-
children: /* @__PURE__ */ jsx("div", { className: "w-10 h-1 rounded-[var(--ds-radius-full)] bg-[var(--ds-border-default)]" })
|
|
11216
|
-
}
|
|
11217
|
-
),
|
|
11218
|
-
title && /* @__PURE__ */ jsxs(
|
|
11219
|
-
"div",
|
|
11220
|
-
{
|
|
11221
|
-
className: "flex items-center justify-between shrink-0 border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]",
|
|
11222
|
-
style: { padding: "var(--ds-space-2) var(--ds-space-5)" },
|
|
11223
|
-
children: [
|
|
11224
|
-
/* @__PURE__ */ jsx("h2", { id: titleId, className: "font-[family-name:var(--ds-font-display)] text-lg font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)] truncate", children: title }),
|
|
11225
|
-
/* @__PURE__ */ jsx(
|
|
11226
|
-
"button",
|
|
11227
|
-
{
|
|
11228
|
-
onClick: onClose,
|
|
11229
|
-
...{ [OVERLAY_CLOSE_ATTR]: "" },
|
|
11230
|
-
className: "text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)] transition-colors cursor-pointer",
|
|
11231
|
-
"aria-label": "Close",
|
|
11232
|
-
children: /* @__PURE__ */ jsx(Icon, { name: "close", size: 18 })
|
|
11233
|
-
}
|
|
11234
|
-
)
|
|
11235
|
-
]
|
|
11236
|
-
}
|
|
11237
|
-
),
|
|
11238
|
-
/* @__PURE__ */ jsx(
|
|
11239
|
-
"div",
|
|
11240
|
-
{
|
|
11241
|
-
className: "flex-1 overflow-y-auto",
|
|
11242
|
-
style: { padding: "var(--ds-space-5)" },
|
|
11243
|
-
children
|
|
11244
|
-
}
|
|
11245
|
-
),
|
|
11246
|
-
footer && /* @__PURE__ */ jsx(
|
|
11247
|
-
"div",
|
|
11248
|
-
{
|
|
11249
|
-
className: "shrink-0 flex items-center justify-end gap-ds-2 border-t-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]",
|
|
11250
|
-
style: { padding: "var(--ds-space-3) var(--ds-space-5)" },
|
|
11251
|
-
children: footer
|
|
11252
|
-
}
|
|
11253
|
-
)
|
|
11254
|
-
]
|
|
11255
|
-
}
|
|
11256
|
-
)
|
|
11257
|
-
]
|
|
11258
|
-
}
|
|
11259
|
-
),
|
|
11260
|
-
document.body
|
|
11261
|
-
);
|
|
11262
|
-
}
|
|
11263
11340
|
function TruncTitle({ children }) {
|
|
11264
11341
|
const { ref, isTruncated } = useTextOverflow({ lines: 1 });
|
|
11265
11342
|
const el = /* @__PURE__ */ jsx("span", { ref, className: "truncate", children });
|
|
@@ -11290,7 +11367,10 @@ function NotificationCenter({
|
|
|
11290
11367
|
const [internalFilter, setInternalFilter] = useState("all");
|
|
11291
11368
|
const isControlled = controlledOpen !== void 0;
|
|
11292
11369
|
const open = isControlled ? controlledOpen : internalOpen;
|
|
11293
|
-
const setOpen =
|
|
11370
|
+
const setOpen = useCallback((v) => {
|
|
11371
|
+
if (isControlled) onOpenChange?.(v);
|
|
11372
|
+
else setInternalOpen(v);
|
|
11373
|
+
}, [isControlled, onOpenChange]);
|
|
11294
11374
|
const triggerRef = useRef(null);
|
|
11295
11375
|
const panelRef = useRef(null);
|
|
11296
11376
|
const pos = usePosition(triggerRef, panelRef, open, { side: "bottom", align: "end", offset: 8, flip: true });
|
|
@@ -11314,7 +11394,7 @@ function NotificationCenter({
|
|
|
11314
11394
|
document.removeEventListener("keydown", onKey);
|
|
11315
11395
|
document.removeEventListener("mousedown", onClick);
|
|
11316
11396
|
};
|
|
11317
|
-
}, [open]);
|
|
11397
|
+
}, [open, setOpen]);
|
|
11318
11398
|
const grouped = groupByDate(filteredNotifications);
|
|
11319
11399
|
if (variant === "page") {
|
|
11320
11400
|
return /* @__PURE__ */ jsxs("div", { ref, className: cn("w-full", className), children: [
|
|
@@ -11561,11 +11641,13 @@ function Tour({ steps, open, onClose, onComplete, container }) {
|
|
|
11561
11641
|
if (el) setRect(el.getBoundingClientRect());
|
|
11562
11642
|
else setRect(null);
|
|
11563
11643
|
}, [step]);
|
|
11644
|
+
const [prevOpen, setPrevOpen] = useState(open);
|
|
11645
|
+
if (open !== prevOpen) {
|
|
11646
|
+
setPrevOpen(open);
|
|
11647
|
+
if (!open) setCurrent(0);
|
|
11648
|
+
}
|
|
11564
11649
|
useEffect(() => {
|
|
11565
|
-
if (!open)
|
|
11566
|
-
setCurrent(0);
|
|
11567
|
-
return;
|
|
11568
|
-
}
|
|
11650
|
+
if (!open) return;
|
|
11569
11651
|
measureTarget();
|
|
11570
11652
|
window.addEventListener("resize", measureTarget);
|
|
11571
11653
|
window.addEventListener("scroll", measureTarget, true);
|
|
@@ -11574,16 +11656,6 @@ function Tour({ steps, open, onClose, onComplete, container }) {
|
|
|
11574
11656
|
window.removeEventListener("scroll", measureTarget, true);
|
|
11575
11657
|
};
|
|
11576
11658
|
}, [open, current, measureTarget]);
|
|
11577
|
-
useEffect(() => {
|
|
11578
|
-
if (!open) return;
|
|
11579
|
-
const onKey = (e) => {
|
|
11580
|
-
if (e.key === "Escape") onClose();
|
|
11581
|
-
else if (e.key === "ArrowRight") handleNext();
|
|
11582
|
-
else if (e.key === "ArrowLeft") handlePrev();
|
|
11583
|
-
};
|
|
11584
|
-
document.addEventListener("keydown", onKey);
|
|
11585
|
-
return () => document.removeEventListener("keydown", onKey);
|
|
11586
|
-
});
|
|
11587
11659
|
const handleNext = useCallback(() => {
|
|
11588
11660
|
if (current < steps.length - 1) setCurrent((c) => c + 1);
|
|
11589
11661
|
else {
|
|
@@ -11594,6 +11666,16 @@ function Tour({ steps, open, onClose, onComplete, container }) {
|
|
|
11594
11666
|
const handlePrev = useCallback(() => {
|
|
11595
11667
|
if (current > 0) setCurrent((c) => c - 1);
|
|
11596
11668
|
}, [current]);
|
|
11669
|
+
useEffect(() => {
|
|
11670
|
+
if (!open) return;
|
|
11671
|
+
const onKey = (e) => {
|
|
11672
|
+
if (e.key === "Escape") onClose();
|
|
11673
|
+
else if (e.key === "ArrowRight") handleNext();
|
|
11674
|
+
else if (e.key === "ArrowLeft") handlePrev();
|
|
11675
|
+
};
|
|
11676
|
+
document.addEventListener("keydown", onKey);
|
|
11677
|
+
return () => document.removeEventListener("keydown", onKey);
|
|
11678
|
+
}, [open, onClose, handleNext, handlePrev]);
|
|
11597
11679
|
if (!open || !step) return null;
|
|
11598
11680
|
const padding = 8;
|
|
11599
11681
|
const spotlightRadius = 8;
|
|
@@ -11897,15 +11979,14 @@ function Toast({ variant = "default", message, visible, onDismiss, duration = 3e
|
|
|
11897
11979
|
const timerRef = useRef(void 0);
|
|
11898
11980
|
const startedAtRef = useRef(0);
|
|
11899
11981
|
const remainingRef = useRef(duration);
|
|
11900
|
-
const onDismissRef =
|
|
11901
|
-
onDismissRef.current = onDismiss;
|
|
11982
|
+
const onDismissRef = useLatest(onDismiss);
|
|
11902
11983
|
const startTimer = useCallback((ms) => {
|
|
11903
11984
|
const delay = ms ?? remainingRef.current;
|
|
11904
11985
|
remainingRef.current = delay;
|
|
11905
11986
|
startedAtRef.current = Date.now();
|
|
11906
11987
|
if (!Number.isFinite(delay) || delay <= 0) return;
|
|
11907
11988
|
timerRef.current = setTimeout(() => onDismissRef.current(), delay);
|
|
11908
|
-
}, []);
|
|
11989
|
+
}, [onDismissRef]);
|
|
11909
11990
|
const clearTimer = useCallback(() => {
|
|
11910
11991
|
if (timerRef.current) {
|
|
11911
11992
|
clearTimeout(timerRef.current);
|