@nextlyhq/ui 0.0.2-alpha.52 → 0.0.2-alpha.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/color.cjs +160 -0
- package/dist/color.cjs.map +1 -0
- package/dist/color.d.cts +168 -0
- package/dist/color.d.ts +168 -0
- package/dist/color.mjs +152 -0
- package/dist/color.mjs.map +1 -0
- package/dist/index.cjs +1181 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +488 -1
- package/dist/index.d.ts +488 -1
- package/dist/index.mjs +1168 -6
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/styles.scoped.css +1 -1
- package/dist/theme.css +97 -91
- package/package.json +18 -5
package/dist/index.cjs
CHANGED
|
@@ -29,8 +29,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
29
29
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
30
|
|
|
31
31
|
// src/index.ts
|
|
32
|
-
var
|
|
33
|
-
__export(
|
|
32
|
+
var src_exports = {};
|
|
33
|
+
__export(src_exports, {
|
|
34
34
|
Accordion: () => Accordion,
|
|
35
35
|
AccordionContent: () => AccordionContent,
|
|
36
36
|
AccordionItem: () => AccordionItem,
|
|
@@ -149,7 +149,10 @@ __export(index_exports, {
|
|
|
149
149
|
SheetPortal: () => SheetPortal,
|
|
150
150
|
SheetTitle: () => SheetTitle,
|
|
151
151
|
SheetTrigger: () => SheetTrigger,
|
|
152
|
+
ShortcutProvider: () => ShortcutProvider,
|
|
153
|
+
ShortcutScope: () => ShortcutScope,
|
|
152
154
|
Skeleton: () => Skeleton,
|
|
155
|
+
Slider: () => Slider,
|
|
153
156
|
Spinner: () => Spinner,
|
|
154
157
|
Stack: () => Stack,
|
|
155
158
|
Stat: () => Stat,
|
|
@@ -177,21 +180,27 @@ __export(index_exports, {
|
|
|
177
180
|
TooltipContent: () => TooltipContent,
|
|
178
181
|
TooltipProvider: () => TooltipProvider,
|
|
179
182
|
TooltipTrigger: () => TooltipTrigger,
|
|
183
|
+
TreeView: () => TreeView,
|
|
180
184
|
alertVariants: () => alertVariants,
|
|
181
185
|
avatarVariants: () => avatarVariants,
|
|
182
186
|
badgeVariants: () => badgeVariants,
|
|
183
187
|
buttonVariants: () => buttonVariants,
|
|
184
188
|
cardVariants: () => cardVariants,
|
|
189
|
+
createShortcutManager: () => createShortcutManager,
|
|
185
190
|
dialogContentVariants: () => dialogContentVariants,
|
|
186
191
|
inputVariants: () => inputVariants,
|
|
192
|
+
parseKeys: () => parseKeys,
|
|
187
193
|
progressVariants: () => progressVariants,
|
|
188
194
|
selectTriggerVariants: () => selectTriggerVariants,
|
|
189
195
|
sheetVariants: () => sheetVariants,
|
|
190
196
|
spinnerVariants: () => spinnerVariants,
|
|
191
197
|
toast: () => import_sonner.toast,
|
|
192
|
-
|
|
198
|
+
useActiveShortcuts: () => useActiveShortcuts,
|
|
199
|
+
usePortalContainer: () => usePortalContainer,
|
|
200
|
+
useShortcutManager: () => useShortcutManager,
|
|
201
|
+
useShortcuts: () => useShortcuts
|
|
193
202
|
});
|
|
194
|
-
module.exports = __toCommonJS(
|
|
203
|
+
module.exports = __toCommonJS(src_exports);
|
|
195
204
|
|
|
196
205
|
// src/components/button.tsx
|
|
197
206
|
var import_react_slot = require("@radix-ui/react-slot");
|
|
@@ -215,11 +224,15 @@ var buttonVariants = (0, import_class_variance_authority.cva)(
|
|
|
215
224
|
variant: {
|
|
216
225
|
default: "bg-primary text-primary-foreground border border-transparent hover:opacity-90",
|
|
217
226
|
primary: "bg-primary text-primary-foreground border border-transparent hover:opacity-90",
|
|
218
|
-
// Solid fill uses the emphasis token so
|
|
219
|
-
//
|
|
220
|
-
// Hover darkens to a deeper shade
|
|
221
|
-
// composite the fill toward the page and drop
|
|
222
|
-
|
|
227
|
+
// Solid fill uses the emphasis token so on-color text stays AA in dark
|
|
228
|
+
// mode (the base token is the readable text color, too light here).
|
|
229
|
+
// Hover darkens to a deeper shade rather than opacity-90, which would
|
|
230
|
+
// composite the fill toward the page and drop the label under 4.5:1.
|
|
231
|
+
// One step, not two: the label is white in light mode and black in
|
|
232
|
+
// dark, so mixing the fill toward black moves it away from the label in
|
|
233
|
+
// one mode and into it in the other. `-600` clears both (5.92:1 light,
|
|
234
|
+
// 5.67:1 dark); `-700` reads at 3.70:1 against the dark label.
|
|
235
|
+
destructive: "bg-destructive-solid text-destructive-foreground border border-transparent hover:bg-destructive-600",
|
|
223
236
|
// border-border is the decorative separator token, and it is the right
|
|
224
237
|
// one here: a button is identified by its label and fill, so its edge
|
|
225
238
|
// carries no meaning on its own and is not held to the 3:1 minimum that
|
|
@@ -2489,6 +2502,1155 @@ var ResizableHandle = ({
|
|
|
2489
2502
|
]
|
|
2490
2503
|
}
|
|
2491
2504
|
);
|
|
2505
|
+
|
|
2506
|
+
// src/components/tree-view.tsx
|
|
2507
|
+
var import_react_virtual = require("@tanstack/react-virtual");
|
|
2508
|
+
var import_lucide_react14 = require("lucide-react");
|
|
2509
|
+
var React10 = __toESM(require("react"), 1);
|
|
2510
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
2511
|
+
var ROW_HEIGHT = 28;
|
|
2512
|
+
var INDENT_PER_LEVEL = 12;
|
|
2513
|
+
function textOf(node) {
|
|
2514
|
+
if (typeof node.textValue === "string") return node.textValue;
|
|
2515
|
+
return typeof node.label === "string" ? node.label : "";
|
|
2516
|
+
}
|
|
2517
|
+
function flatten(nodes, expanded) {
|
|
2518
|
+
const rows = [];
|
|
2519
|
+
const pending = [{ list: nodes, index: 0, level: 0 }];
|
|
2520
|
+
while (pending.length > 0) {
|
|
2521
|
+
const frame = pending[pending.length - 1];
|
|
2522
|
+
if (frame === void 0 || frame.index >= frame.list.length) {
|
|
2523
|
+
pending.pop();
|
|
2524
|
+
continue;
|
|
2525
|
+
}
|
|
2526
|
+
const node = frame.list[frame.index];
|
|
2527
|
+
const posInSet = frame.index;
|
|
2528
|
+
frame.index += 1;
|
|
2529
|
+
if (node === void 0) continue;
|
|
2530
|
+
const hasChildren = node.children !== void 0;
|
|
2531
|
+
rows.push({
|
|
2532
|
+
node,
|
|
2533
|
+
level: frame.level,
|
|
2534
|
+
setSize: frame.list.length,
|
|
2535
|
+
posInSet,
|
|
2536
|
+
parentId: frame.parentId,
|
|
2537
|
+
hasChildren
|
|
2538
|
+
});
|
|
2539
|
+
if (hasChildren && expanded.has(node.id)) {
|
|
2540
|
+
pending.push({
|
|
2541
|
+
list: node.children ?? [],
|
|
2542
|
+
index: 0,
|
|
2543
|
+
level: frame.level + 1,
|
|
2544
|
+
parentId: node.id
|
|
2545
|
+
});
|
|
2546
|
+
}
|
|
2547
|
+
}
|
|
2548
|
+
return rows;
|
|
2549
|
+
}
|
|
2550
|
+
function useControllable(controlled, fallback) {
|
|
2551
|
+
const [uncontrolled, setUncontrolled] = React10.useState(fallback);
|
|
2552
|
+
return [
|
|
2553
|
+
controlled === void 0 ? uncontrolled : controlled,
|
|
2554
|
+
setUncontrolled
|
|
2555
|
+
];
|
|
2556
|
+
}
|
|
2557
|
+
var TreeView = React10.forwardRef(
|
|
2558
|
+
({
|
|
2559
|
+
nodes,
|
|
2560
|
+
expandedIds,
|
|
2561
|
+
defaultExpandedIds,
|
|
2562
|
+
onExpandedChange,
|
|
2563
|
+
selectedId,
|
|
2564
|
+
defaultSelectedId,
|
|
2565
|
+
onSelectedChange,
|
|
2566
|
+
className,
|
|
2567
|
+
"aria-label": ariaLabel,
|
|
2568
|
+
"aria-labelledby": ariaLabelledBy,
|
|
2569
|
+
"aria-describedby": ariaDescribedBy,
|
|
2570
|
+
...props
|
|
2571
|
+
}, forwardedRef) => {
|
|
2572
|
+
const scrollRef = React10.useRef(null);
|
|
2573
|
+
const attachScroll = React10.useCallback(
|
|
2574
|
+
(node) => {
|
|
2575
|
+
scrollRef.current = node;
|
|
2576
|
+
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
2577
|
+
else if (forwardedRef !== null && forwardedRef !== void 0) {
|
|
2578
|
+
forwardedRef.current = node;
|
|
2579
|
+
}
|
|
2580
|
+
},
|
|
2581
|
+
[forwardedRef]
|
|
2582
|
+
);
|
|
2583
|
+
const [expandedState, setExpandedState] = useControllable(
|
|
2584
|
+
expandedIds === void 0 ? void 0 : [...expandedIds],
|
|
2585
|
+
[...defaultExpandedIds ?? []]
|
|
2586
|
+
);
|
|
2587
|
+
const expanded = React10.useMemo(
|
|
2588
|
+
() => new Set(expandedIds ?? expandedState),
|
|
2589
|
+
[expandedIds, expandedState]
|
|
2590
|
+
);
|
|
2591
|
+
const [selected, setSelected] = useControllable(
|
|
2592
|
+
selectedId === void 0 ? void 0 : selectedId,
|
|
2593
|
+
defaultSelectedId ?? null
|
|
2594
|
+
);
|
|
2595
|
+
const rows = React10.useMemo(
|
|
2596
|
+
() => flatten(nodes, expanded),
|
|
2597
|
+
[nodes, expanded]
|
|
2598
|
+
);
|
|
2599
|
+
const [activeId, setActiveId] = React10.useState(null);
|
|
2600
|
+
const activeIndex = Math.max(
|
|
2601
|
+
0,
|
|
2602
|
+
rows.findIndex((row) => row.node.id === (activeId ?? selected))
|
|
2603
|
+
);
|
|
2604
|
+
const virtualizer = (0, import_react_virtual.useVirtualizer)({
|
|
2605
|
+
count: rows.length,
|
|
2606
|
+
getScrollElement: () => scrollRef.current,
|
|
2607
|
+
estimateSize: () => ROW_HEIGHT,
|
|
2608
|
+
overscan: 8
|
|
2609
|
+
});
|
|
2610
|
+
const commitExpanded = (next) => {
|
|
2611
|
+
const ids = [...next];
|
|
2612
|
+
if (expandedIds === void 0) setExpandedState(ids);
|
|
2613
|
+
onExpandedChange?.(ids);
|
|
2614
|
+
};
|
|
2615
|
+
const setExpansion = (id, open) => {
|
|
2616
|
+
const next = new Set(expanded);
|
|
2617
|
+
if (open) next.add(id);
|
|
2618
|
+
else next.delete(id);
|
|
2619
|
+
commitExpanded(next);
|
|
2620
|
+
};
|
|
2621
|
+
const choose = (id) => {
|
|
2622
|
+
if (selectedId === void 0) setSelected(id);
|
|
2623
|
+
onSelectedChange?.(id);
|
|
2624
|
+
};
|
|
2625
|
+
const focusRow = (index) => {
|
|
2626
|
+
const row = rows[index];
|
|
2627
|
+
if (row === void 0) return;
|
|
2628
|
+
setActiveId(row.node.id);
|
|
2629
|
+
virtualizer.scrollToIndex(index, { align: "auto" });
|
|
2630
|
+
requestAnimationFrame(() => {
|
|
2631
|
+
const element = scrollRef.current?.querySelector(
|
|
2632
|
+
`[data-tree-index="${index}"]`
|
|
2633
|
+
);
|
|
2634
|
+
element?.focus();
|
|
2635
|
+
});
|
|
2636
|
+
};
|
|
2637
|
+
const step = (from, delta) => {
|
|
2638
|
+
for (let index = from + delta; index >= 0 && index < rows.length; index += delta) {
|
|
2639
|
+
if (rows[index]?.node.disabled !== true) return index;
|
|
2640
|
+
}
|
|
2641
|
+
return from;
|
|
2642
|
+
};
|
|
2643
|
+
const typeahead = React10.useRef({ query: "", at: 0 });
|
|
2644
|
+
const onKeyDown = (event) => {
|
|
2645
|
+
const index = activeIndex;
|
|
2646
|
+
const row = rows[index];
|
|
2647
|
+
if (row === void 0) return;
|
|
2648
|
+
switch (event.key) {
|
|
2649
|
+
case "ArrowDown":
|
|
2650
|
+
event.preventDefault();
|
|
2651
|
+
focusRow(step(index, 1));
|
|
2652
|
+
return;
|
|
2653
|
+
case "ArrowUp":
|
|
2654
|
+
event.preventDefault();
|
|
2655
|
+
focusRow(step(index, -1));
|
|
2656
|
+
return;
|
|
2657
|
+
case "ArrowRight":
|
|
2658
|
+
event.preventDefault();
|
|
2659
|
+
if (row.hasChildren && !expanded.has(row.node.id)) {
|
|
2660
|
+
setExpansion(row.node.id, true);
|
|
2661
|
+
} else if (row.hasChildren) {
|
|
2662
|
+
for (let child = index + 1; child < rows.length && (rows[child]?.level ?? 0) > row.level; child += 1) {
|
|
2663
|
+
if (rows[child]?.parentId === row.node.id && rows[child]?.node.disabled !== true) {
|
|
2664
|
+
focusRow(child);
|
|
2665
|
+
break;
|
|
2666
|
+
}
|
|
2667
|
+
}
|
|
2668
|
+
}
|
|
2669
|
+
return;
|
|
2670
|
+
case "ArrowLeft":
|
|
2671
|
+
event.preventDefault();
|
|
2672
|
+
if (row.hasChildren && expanded.has(row.node.id)) {
|
|
2673
|
+
setExpansion(row.node.id, false);
|
|
2674
|
+
} else if (row.parentId !== void 0) {
|
|
2675
|
+
let ancestor = row.parentId;
|
|
2676
|
+
while (ancestor !== void 0) {
|
|
2677
|
+
const at = rows.findIndex(
|
|
2678
|
+
(candidate) => candidate.node.id === ancestor
|
|
2679
|
+
);
|
|
2680
|
+
if (at < 0) break;
|
|
2681
|
+
if (rows[at]?.node.disabled !== true) {
|
|
2682
|
+
focusRow(at);
|
|
2683
|
+
break;
|
|
2684
|
+
}
|
|
2685
|
+
ancestor = rows[at]?.parentId;
|
|
2686
|
+
}
|
|
2687
|
+
}
|
|
2688
|
+
return;
|
|
2689
|
+
case "Home":
|
|
2690
|
+
event.preventDefault();
|
|
2691
|
+
focusRow(rows[0]?.node.disabled === true ? step(0, 1) : 0);
|
|
2692
|
+
return;
|
|
2693
|
+
case "End": {
|
|
2694
|
+
event.preventDefault();
|
|
2695
|
+
const last = rows.length - 1;
|
|
2696
|
+
focusRow(rows[last]?.node.disabled === true ? step(last, -1) : last);
|
|
2697
|
+
return;
|
|
2698
|
+
}
|
|
2699
|
+
case "Enter":
|
|
2700
|
+
case " ":
|
|
2701
|
+
event.preventDefault();
|
|
2702
|
+
if (row.node.disabled !== true) choose(row.node.id);
|
|
2703
|
+
return;
|
|
2704
|
+
case "*": {
|
|
2705
|
+
event.preventDefault();
|
|
2706
|
+
const next = new Set(expanded);
|
|
2707
|
+
for (const sibling of rows) {
|
|
2708
|
+
if (sibling.parentId === row.parentId && sibling.hasChildren) {
|
|
2709
|
+
next.add(sibling.node.id);
|
|
2710
|
+
}
|
|
2711
|
+
}
|
|
2712
|
+
commitExpanded(next);
|
|
2713
|
+
return;
|
|
2714
|
+
}
|
|
2715
|
+
default:
|
|
2716
|
+
break;
|
|
2717
|
+
}
|
|
2718
|
+
if (event.key.length !== 1 || event.metaKey || event.ctrlKey || event.altKey) {
|
|
2719
|
+
return;
|
|
2720
|
+
}
|
|
2721
|
+
event.preventDefault();
|
|
2722
|
+
const now = Date.now();
|
|
2723
|
+
const state = typeahead.current;
|
|
2724
|
+
state.query = now - state.at > 500 ? event.key : state.query + event.key;
|
|
2725
|
+
state.at = now;
|
|
2726
|
+
const query = state.query.toLowerCase();
|
|
2727
|
+
for (let offset = 1; offset <= rows.length; offset += 1) {
|
|
2728
|
+
const candidate = rows[(index + offset) % rows.length];
|
|
2729
|
+
if (candidate === void 0 || candidate.node.disabled === true)
|
|
2730
|
+
continue;
|
|
2731
|
+
if (textOf(candidate.node).toLowerCase().startsWith(query)) {
|
|
2732
|
+
focusRow(rows.indexOf(candidate));
|
|
2733
|
+
return;
|
|
2734
|
+
}
|
|
2735
|
+
}
|
|
2736
|
+
};
|
|
2737
|
+
const virtualItems = virtualizer.getVirtualItems();
|
|
2738
|
+
const usable = (index) => rows[index]?.node.disabled !== true;
|
|
2739
|
+
const tabStopIndex = virtualItems.some((item) => item.index === activeIndex) && usable(activeIndex) ? activeIndex : virtualItems.find((item) => usable(item.index))?.index ?? -1;
|
|
2740
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
2741
|
+
"div",
|
|
2742
|
+
{
|
|
2743
|
+
ref: attachScroll,
|
|
2744
|
+
className: cn("overflow-auto", className),
|
|
2745
|
+
...props,
|
|
2746
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
2747
|
+
"div",
|
|
2748
|
+
{
|
|
2749
|
+
role: "tree",
|
|
2750
|
+
"aria-label": ariaLabel,
|
|
2751
|
+
"aria-labelledby": ariaLabelledBy,
|
|
2752
|
+
"aria-describedby": ariaDescribedBy,
|
|
2753
|
+
onKeyDown,
|
|
2754
|
+
style: { height: virtualizer.getTotalSize(), position: "relative" },
|
|
2755
|
+
children: virtualItems.map((item) => {
|
|
2756
|
+
const row = rows[item.index];
|
|
2757
|
+
if (row === void 0) return null;
|
|
2758
|
+
const isSelected = selected === row.node.id;
|
|
2759
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
2760
|
+
"div",
|
|
2761
|
+
{
|
|
2762
|
+
"data-tree-index": item.index,
|
|
2763
|
+
role: "treeitem",
|
|
2764
|
+
"aria-level": row.level + 1,
|
|
2765
|
+
"aria-setsize": row.setSize,
|
|
2766
|
+
"aria-posinset": row.posInSet + 1,
|
|
2767
|
+
"aria-selected": isSelected,
|
|
2768
|
+
"aria-expanded": row.hasChildren ? expanded.has(row.node.id) : void 0,
|
|
2769
|
+
"aria-disabled": row.node.disabled === true ? true : void 0,
|
|
2770
|
+
tabIndex: item.index === tabStopIndex ? 0 : -1,
|
|
2771
|
+
onFocus: () => setActiveId(row.node.id),
|
|
2772
|
+
onClick: () => {
|
|
2773
|
+
if (row.node.disabled === true) return;
|
|
2774
|
+
setActiveId(row.node.id);
|
|
2775
|
+
choose(row.node.id);
|
|
2776
|
+
},
|
|
2777
|
+
className: cn(
|
|
2778
|
+
"absolute left-0 flex w-full select-none items-center gap-1 rounded-sm pr-2 text-sm outline-none",
|
|
2779
|
+
"focus-visible:ring-1 focus-visible:ring-ring",
|
|
2780
|
+
row.node.disabled === true ? "pointer-events-none opacity-50" : "cursor-pointer",
|
|
2781
|
+
isSelected ? "bg-muted text-foreground" : "hover:bg-muted/50"
|
|
2782
|
+
),
|
|
2783
|
+
style: {
|
|
2784
|
+
height: item.size,
|
|
2785
|
+
transform: `translateY(${item.start}px)`,
|
|
2786
|
+
paddingLeft: 4 + row.level * INDENT_PER_LEVEL
|
|
2787
|
+
},
|
|
2788
|
+
children: [
|
|
2789
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
2790
|
+
"span",
|
|
2791
|
+
{
|
|
2792
|
+
"aria-hidden": "true",
|
|
2793
|
+
className: "flex size-4 shrink-0 items-center justify-center",
|
|
2794
|
+
onClick: (event) => {
|
|
2795
|
+
if (!row.hasChildren) return;
|
|
2796
|
+
event.stopPropagation();
|
|
2797
|
+
setExpansion(row.node.id, !expanded.has(row.node.id));
|
|
2798
|
+
},
|
|
2799
|
+
children: row.hasChildren ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
2800
|
+
import_lucide_react14.ChevronRight,
|
|
2801
|
+
{
|
|
2802
|
+
className: cn(
|
|
2803
|
+
"size-3.5 text-muted-foreground transition-transform",
|
|
2804
|
+
expanded.has(row.node.id) && "rotate-90"
|
|
2805
|
+
)
|
|
2806
|
+
}
|
|
2807
|
+
) : null
|
|
2808
|
+
}
|
|
2809
|
+
),
|
|
2810
|
+
row.node.icon !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "flex size-4 shrink-0 items-center justify-center text-muted-foreground", children: row.node.icon }) : null,
|
|
2811
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "truncate", children: row.node.label })
|
|
2812
|
+
]
|
|
2813
|
+
},
|
|
2814
|
+
row.node.id
|
|
2815
|
+
);
|
|
2816
|
+
})
|
|
2817
|
+
}
|
|
2818
|
+
)
|
|
2819
|
+
}
|
|
2820
|
+
);
|
|
2821
|
+
}
|
|
2822
|
+
);
|
|
2823
|
+
TreeView.displayName = "TreeView";
|
|
2824
|
+
|
|
2825
|
+
// src/components/slider.tsx
|
|
2826
|
+
var SliderPrimitive = __toESM(require("@radix-ui/react-slider"), 1);
|
|
2827
|
+
var React11 = __toESM(require("react"), 1);
|
|
2828
|
+
|
|
2829
|
+
// src/lib/dev-warn.ts
|
|
2830
|
+
var emitted = /* @__PURE__ */ new Set();
|
|
2831
|
+
var SPEAKING_ENVIRONMENTS = /* @__PURE__ */ new Set(["development", "test"]);
|
|
2832
|
+
function isDevelopmentRuntime() {
|
|
2833
|
+
if (typeof process === "undefined") return false;
|
|
2834
|
+
const env = process?.env?.NODE_ENV;
|
|
2835
|
+
return env !== void 0 && SPEAKING_ENVIRONMENTS.has(env);
|
|
2836
|
+
}
|
|
2837
|
+
function devWarnOnce(condition, message) {
|
|
2838
|
+
if (condition) return;
|
|
2839
|
+
if (!isDevelopmentRuntime()) return;
|
|
2840
|
+
if (emitted.has(message)) return;
|
|
2841
|
+
emitted.add(message);
|
|
2842
|
+
console.warn(`[@nextlyhq/ui] ${message}`);
|
|
2843
|
+
}
|
|
2844
|
+
|
|
2845
|
+
// src/components/slider.tsx
|
|
2846
|
+
var import_jsx_runtime37 = (
|
|
2847
|
+
// `aria-label`/`aria-labelledby` are destructured out above rather than
|
|
2848
|
+
// spread here: left on the root they would be a second, roleless copy
|
|
2849
|
+
// of a name only the thumb is read for.
|
|
2850
|
+
require("react/jsx-runtime")
|
|
2851
|
+
);
|
|
2852
|
+
function thumbCount(value, defaultValue) {
|
|
2853
|
+
return Math.max(1, value?.length ?? defaultValue?.length ?? 1);
|
|
2854
|
+
}
|
|
2855
|
+
function hasAccessibleName(value) {
|
|
2856
|
+
return value !== void 0 && value.trim() !== "";
|
|
2857
|
+
}
|
|
2858
|
+
var Slider = React11.forwardRef(
|
|
2859
|
+
({
|
|
2860
|
+
className,
|
|
2861
|
+
value,
|
|
2862
|
+
defaultValue,
|
|
2863
|
+
thumbs,
|
|
2864
|
+
orientation = "horizontal",
|
|
2865
|
+
"aria-label": ariaLabel,
|
|
2866
|
+
"aria-labelledby": ariaLabelledBy,
|
|
2867
|
+
...props
|
|
2868
|
+
}, ref) => {
|
|
2869
|
+
const initialUncontrolledCount = React11.useRef(
|
|
2870
|
+
thumbCount(void 0, defaultValue)
|
|
2871
|
+
).current;
|
|
2872
|
+
const count = value?.length ?? initialUncontrolledCount;
|
|
2873
|
+
const isEmptyDefault = defaultValue !== void 0 && defaultValue.length === 0;
|
|
2874
|
+
const isEmptyControlled = value !== void 0 && value.length === 0;
|
|
2875
|
+
devWarnOnce(
|
|
2876
|
+
!isEmptyDefault && !isEmptyControlled,
|
|
2877
|
+
"Slider: `value`/`defaultValue` must hold one number per thumb, and an empty array holds none \u2014 the control has nothing to slide. An empty `defaultValue` falls back to `min`; an empty `value` renders nothing at all, because a controlled slider cannot be given a value without taking state the caller owns. Render nothing until the value is loaded rather than passing `[]`."
|
|
2878
|
+
);
|
|
2879
|
+
if (isEmptyControlled) return null;
|
|
2880
|
+
const isNamed = (index) => {
|
|
2881
|
+
const own = thumbs?.[index];
|
|
2882
|
+
if (hasAccessibleName(own?.["aria-label"])) return true;
|
|
2883
|
+
if (hasAccessibleName(own?.["aria-labelledby"])) return true;
|
|
2884
|
+
return count === 1 && (hasAccessibleName(ariaLabel) || hasAccessibleName(ariaLabelledBy));
|
|
2885
|
+
};
|
|
2886
|
+
devWarnOnce(
|
|
2887
|
+
Array.from({ length: count }).every((_, i) => isNamed(i)),
|
|
2888
|
+
"Slider: every thumb needs an accessible name. A single thumb may take it from the root's `aria-label`/`aria-labelledby`; a range needs one `thumbs` entry per thumb, because the root's name is not inherited and two thumbs sharing one name are announced identically."
|
|
2889
|
+
);
|
|
2890
|
+
const ariaFor = (index) => {
|
|
2891
|
+
const supplied = thumbs?.[index] ?? {};
|
|
2892
|
+
const ownLabel = hasAccessibleName(supplied["aria-label"]) ? supplied["aria-label"] : void 0;
|
|
2893
|
+
const ownLabelledBy = hasAccessibleName(supplied["aria-labelledby"]) ? supplied["aria-labelledby"] : void 0;
|
|
2894
|
+
if (count !== 1) {
|
|
2895
|
+
return {
|
|
2896
|
+
...supplied,
|
|
2897
|
+
"aria-label": ownLabel,
|
|
2898
|
+
"aria-labelledby": ownLabelledBy
|
|
2899
|
+
};
|
|
2900
|
+
}
|
|
2901
|
+
const namesItself = ownLabel !== void 0 || ownLabelledBy !== void 0;
|
|
2902
|
+
return {
|
|
2903
|
+
"aria-label": namesItself ? ownLabel : ariaLabel,
|
|
2904
|
+
"aria-labelledby": namesItself ? ownLabelledBy : ariaLabelledBy,
|
|
2905
|
+
"aria-valuetext": supplied["aria-valuetext"],
|
|
2906
|
+
"aria-describedby": supplied["aria-describedby"]
|
|
2907
|
+
};
|
|
2908
|
+
};
|
|
2909
|
+
const isVertical = orientation === "vertical";
|
|
2910
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
|
|
2911
|
+
SliderPrimitive.Root,
|
|
2912
|
+
{
|
|
2913
|
+
ref,
|
|
2914
|
+
className: cn(
|
|
2915
|
+
"relative flex touch-none select-none items-center",
|
|
2916
|
+
// WCAG 2.5.8 wants a 24px target. Padding alone does not reach it: the
|
|
2917
|
+
// thumb is absolutely positioned, so the cross-axis size is the 6px
|
|
2918
|
+
// track plus the padding — 22px with `py-2`. An explicit minimum
|
|
2919
|
+
// states the target rather than leaving it to arithmetic that moves
|
|
2920
|
+
// whenever the track thickness does.
|
|
2921
|
+
isVertical ? (
|
|
2922
|
+
// A vertical slider needs a LENGTH, and it cannot inherit one:
|
|
2923
|
+
// `h-full` inside an auto-height parent resolves to zero, leaving
|
|
2924
|
+
// a control with no track to drag along. A concrete default is
|
|
2925
|
+
// usable everywhere and, being a plain utility, is replaced by a
|
|
2926
|
+
// caller's own `h-*` — including `h-full`, for the fill-the-parent
|
|
2927
|
+
// case this default gives up.
|
|
2928
|
+
"h-44 min-w-6 flex-col px-2"
|
|
2929
|
+
) : "min-h-6 w-full py-2",
|
|
2930
|
+
"data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
2931
|
+
className
|
|
2932
|
+
),
|
|
2933
|
+
orientation,
|
|
2934
|
+
value,
|
|
2935
|
+
defaultValue: isEmptyDefault ? void 0 : defaultValue,
|
|
2936
|
+
...props,
|
|
2937
|
+
children: [
|
|
2938
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
2939
|
+
SliderPrimitive.Track,
|
|
2940
|
+
{
|
|
2941
|
+
className: cn(
|
|
2942
|
+
"bg-secondary relative grow overflow-hidden rounded-full",
|
|
2943
|
+
isVertical ? "h-full w-1.5" : "h-1.5 w-full"
|
|
2944
|
+
),
|
|
2945
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
2946
|
+
SliderPrimitive.Range,
|
|
2947
|
+
{
|
|
2948
|
+
className: cn(
|
|
2949
|
+
"bg-primary absolute",
|
|
2950
|
+
isVertical ? "w-full" : "h-full"
|
|
2951
|
+
)
|
|
2952
|
+
}
|
|
2953
|
+
)
|
|
2954
|
+
}
|
|
2955
|
+
),
|
|
2956
|
+
Array.from({ length: count }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
2957
|
+
SliderPrimitive.Thumb,
|
|
2958
|
+
{
|
|
2959
|
+
...ariaFor(i),
|
|
2960
|
+
className: cn(
|
|
2961
|
+
"border-primary bg-background block h-4 w-4 rounded-full border-2",
|
|
2962
|
+
"ring-offset-background transition-colors",
|
|
2963
|
+
"focus-visible:ring-ring focus-visible:outline-none focus-visible:ring-2",
|
|
2964
|
+
"focus-visible:ring-offset-2",
|
|
2965
|
+
"disabled:pointer-events-none disabled:opacity-50"
|
|
2966
|
+
)
|
|
2967
|
+
},
|
|
2968
|
+
i
|
|
2969
|
+
))
|
|
2970
|
+
]
|
|
2971
|
+
}
|
|
2972
|
+
);
|
|
2973
|
+
}
|
|
2974
|
+
);
|
|
2975
|
+
Slider.displayName = SliderPrimitive.Root.displayName;
|
|
2976
|
+
|
|
2977
|
+
// src/lib/shortcuts/react.tsx
|
|
2978
|
+
var React12 = __toESM(require("react"), 1);
|
|
2979
|
+
|
|
2980
|
+
// src/lib/shortcuts/key-spec.ts
|
|
2981
|
+
function normalizeKey(key) {
|
|
2982
|
+
return [...key].length === 1 ? key.toLowerCase() : key;
|
|
2983
|
+
}
|
|
2984
|
+
function shiftIsMeaningful(key) {
|
|
2985
|
+
if (key.length > 1) return true;
|
|
2986
|
+
if (key === " ") return true;
|
|
2987
|
+
return /[\p{L}\p{N}]/u.test(key);
|
|
2988
|
+
}
|
|
2989
|
+
function parseKeys(spec) {
|
|
2990
|
+
const steps = spec.trim().split(/\s+/).filter(Boolean);
|
|
2991
|
+
if (steps.length === 0) {
|
|
2992
|
+
throw new Error(`Shortcut spec is empty: ${JSON.stringify(spec)}`);
|
|
2993
|
+
}
|
|
2994
|
+
return steps.map((step) => parseChord(step, spec));
|
|
2995
|
+
}
|
|
2996
|
+
function parseChord(step, spec) {
|
|
2997
|
+
const trailingPlusIsKey = step.length > 2 && step.endsWith("++");
|
|
2998
|
+
const body = trailingPlusIsKey ? step.slice(0, -1) : step;
|
|
2999
|
+
const parts = step === "+" ? ["+"] : body.split("+").filter(Boolean);
|
|
3000
|
+
let mod = false;
|
|
3001
|
+
let ctrl = false;
|
|
3002
|
+
let meta = false;
|
|
3003
|
+
let alt = false;
|
|
3004
|
+
let shift = false;
|
|
3005
|
+
let key;
|
|
3006
|
+
for (const raw of parts) {
|
|
3007
|
+
switch (raw.toLowerCase()) {
|
|
3008
|
+
case "mod":
|
|
3009
|
+
mod = true;
|
|
3010
|
+
break;
|
|
3011
|
+
case "ctrl":
|
|
3012
|
+
case "control":
|
|
3013
|
+
ctrl = true;
|
|
3014
|
+
break;
|
|
3015
|
+
case "meta":
|
|
3016
|
+
case "cmd":
|
|
3017
|
+
case "command":
|
|
3018
|
+
meta = true;
|
|
3019
|
+
break;
|
|
3020
|
+
case "alt":
|
|
3021
|
+
case "option":
|
|
3022
|
+
alt = true;
|
|
3023
|
+
break;
|
|
3024
|
+
case "shift":
|
|
3025
|
+
shift = true;
|
|
3026
|
+
break;
|
|
3027
|
+
case "space":
|
|
3028
|
+
key = " ";
|
|
3029
|
+
break;
|
|
3030
|
+
default:
|
|
3031
|
+
if (key !== void 0) {
|
|
3032
|
+
throw new Error(
|
|
3033
|
+
`Shortcut step "${step}" names two keys ("${key}" and "${raw}") in ${JSON.stringify(spec)}`
|
|
3034
|
+
);
|
|
3035
|
+
}
|
|
3036
|
+
key = raw;
|
|
3037
|
+
}
|
|
3038
|
+
}
|
|
3039
|
+
if (trailingPlusIsKey) {
|
|
3040
|
+
if (key !== void 0) {
|
|
3041
|
+
throw new Error(
|
|
3042
|
+
`Shortcut step has more than one key: ${JSON.stringify(step)} in ${JSON.stringify(spec)}`
|
|
3043
|
+
);
|
|
3044
|
+
}
|
|
3045
|
+
key = "+";
|
|
3046
|
+
}
|
|
3047
|
+
if (key === void 0) {
|
|
3048
|
+
throw new Error(
|
|
3049
|
+
`Shortcut step "${step}" names modifiers but no key, in ${JSON.stringify(spec)}`
|
|
3050
|
+
);
|
|
3051
|
+
}
|
|
3052
|
+
return { key: normalizeKey(key), mod, ctrl, meta, alt, shift };
|
|
3053
|
+
}
|
|
3054
|
+
function chordMatches(chord, key, state, isApple) {
|
|
3055
|
+
if (normalizeKey(key) !== chord.key) return false;
|
|
3056
|
+
const wantsCtrl = chord.ctrl || chord.mod && !isApple;
|
|
3057
|
+
const wantsMeta = chord.meta || chord.mod && isApple;
|
|
3058
|
+
if (state.metaKey !== wantsMeta) return false;
|
|
3059
|
+
const altGraph = state.getModifierState?.("AltGraph") ?? false;
|
|
3060
|
+
const synthetic = altGraph && [...chord.key].length === 1 && !wantsCtrl && !chord.alt;
|
|
3061
|
+
if (!synthetic) {
|
|
3062
|
+
if (state.ctrlKey !== wantsCtrl) return false;
|
|
3063
|
+
if (state.altKey !== chord.alt) return false;
|
|
3064
|
+
}
|
|
3065
|
+
if (shiftIsMeaningful(chord.key) && state.shiftKey !== chord.shift)
|
|
3066
|
+
return false;
|
|
3067
|
+
return true;
|
|
3068
|
+
}
|
|
3069
|
+
function detectApplePlatform() {
|
|
3070
|
+
if (typeof navigator === "undefined") return false;
|
|
3071
|
+
const candidate = navigator;
|
|
3072
|
+
const platform = candidate.userAgentData?.platform ?? navigator.platform ?? "";
|
|
3073
|
+
return /mac|iphone|ipad|ipod/i.test(platform);
|
|
3074
|
+
}
|
|
3075
|
+
|
|
3076
|
+
// src/lib/shortcuts/manager.ts
|
|
3077
|
+
var DEFAULT_SEQUENCE_TIMEOUT_MS = 1e3;
|
|
3078
|
+
function signature(event) {
|
|
3079
|
+
return event.code || event.key;
|
|
3080
|
+
}
|
|
3081
|
+
function eventTarget(event) {
|
|
3082
|
+
const path = event.composedPath?.();
|
|
3083
|
+
return path && path.length > 0 ? path[0] ?? null : event.target;
|
|
3084
|
+
}
|
|
3085
|
+
function asElement(target) {
|
|
3086
|
+
if (target === null || typeof target !== "object") return null;
|
|
3087
|
+
const node = target;
|
|
3088
|
+
if (node.nodeType !== 1 || typeof node.tagName !== "string") return null;
|
|
3089
|
+
return target;
|
|
3090
|
+
}
|
|
3091
|
+
function inputType(element) {
|
|
3092
|
+
if (element.tagName !== "INPUT") return "";
|
|
3093
|
+
const value = element.type;
|
|
3094
|
+
return typeof value === "string" ? value.toLowerCase() : "";
|
|
3095
|
+
}
|
|
3096
|
+
function controlOwnsKey(target, event) {
|
|
3097
|
+
if (event.ctrlKey || event.metaKey || event.altKey) return false;
|
|
3098
|
+
const element = asElement(target);
|
|
3099
|
+
if (!element) return false;
|
|
3100
|
+
const tag = element.tagName;
|
|
3101
|
+
const type = inputType(element);
|
|
3102
|
+
if (tag === "BUTTON" || type === "button" || type === "submit" || type === "reset" || type === "image") {
|
|
3103
|
+
return event.key === " " || event.key === "Enter";
|
|
3104
|
+
}
|
|
3105
|
+
if (tag === "A" && element.getAttribute("href") !== null) {
|
|
3106
|
+
return event.key === "Enter";
|
|
3107
|
+
}
|
|
3108
|
+
if (tag === "SUMMARY") return event.key === " " || event.key === "Enter";
|
|
3109
|
+
if (type === "checkbox") return event.key === " ";
|
|
3110
|
+
if (type === "color") return event.key === " " || event.key === "Enter";
|
|
3111
|
+
if (type === "file") return event.key === " " || event.key === "Enter";
|
|
3112
|
+
if (type === "range") {
|
|
3113
|
+
return event.key.startsWith("Arrow") || RANGE_KEYS.has(event.key);
|
|
3114
|
+
}
|
|
3115
|
+
if (type === "radio") {
|
|
3116
|
+
return event.key === " " || event.key.startsWith("Arrow");
|
|
3117
|
+
}
|
|
3118
|
+
return false;
|
|
3119
|
+
}
|
|
3120
|
+
function isTypingTarget(target) {
|
|
3121
|
+
const element = asElement(target);
|
|
3122
|
+
if (!element) return false;
|
|
3123
|
+
if (element.isContentEditable) return true;
|
|
3124
|
+
const tag = element.tagName;
|
|
3125
|
+
if (tag === "TEXTAREA") return true;
|
|
3126
|
+
if (tag === "SELECT") return true;
|
|
3127
|
+
if (tag === "INPUT") {
|
|
3128
|
+
return !NON_TEXT_INPUT_TYPES.has(inputType(element));
|
|
3129
|
+
}
|
|
3130
|
+
const role = element.getAttribute("role");
|
|
3131
|
+
return role !== null && TYPE_AHEAD_ROLES.has(role);
|
|
3132
|
+
}
|
|
3133
|
+
var NON_TEXT_INPUT_TYPES = /* @__PURE__ */ new Set([
|
|
3134
|
+
"button",
|
|
3135
|
+
"checkbox",
|
|
3136
|
+
"color",
|
|
3137
|
+
"file",
|
|
3138
|
+
"hidden",
|
|
3139
|
+
"image",
|
|
3140
|
+
"radio",
|
|
3141
|
+
"range",
|
|
3142
|
+
"reset",
|
|
3143
|
+
"submit"
|
|
3144
|
+
]);
|
|
3145
|
+
function firesWhileTyping(prepared) {
|
|
3146
|
+
const explicit = prepared.binding.whenTyping;
|
|
3147
|
+
if (explicit !== void 0) return explicit;
|
|
3148
|
+
const first = prepared.keys[0];
|
|
3149
|
+
if (first === void 0) return false;
|
|
3150
|
+
return first.mod || first.ctrl || first.meta || first.alt || first.key === "Escape";
|
|
3151
|
+
}
|
|
3152
|
+
function createShortcutManager(options = {}) {
|
|
3153
|
+
const isApple = options.isApple ?? detectApplePlatform();
|
|
3154
|
+
const sequenceTimeoutMs = options.sequenceTimeoutMs ?? DEFAULT_SEQUENCE_TIMEOUT_MS;
|
|
3155
|
+
const now = options.now ?? (() => Date.now());
|
|
3156
|
+
const layers = /* @__PURE__ */ new Set();
|
|
3157
|
+
let nextSequence = 0;
|
|
3158
|
+
let pendingAt = null;
|
|
3159
|
+
let pendingLayer = null;
|
|
3160
|
+
const consumedPresses = /* @__PURE__ */ new Map();
|
|
3161
|
+
let pendingKey = null;
|
|
3162
|
+
function layerShape(bindings, options2) {
|
|
3163
|
+
const keys = bindings.map((b) => b.binding.keys).join("\0");
|
|
3164
|
+
return `${keys}${options2.depth}${options2.blocking === true}${options2.enabled !== false}`;
|
|
3165
|
+
}
|
|
3166
|
+
function blocking() {
|
|
3167
|
+
return ordered().some((layer) => layer.options.blocking === true);
|
|
3168
|
+
}
|
|
3169
|
+
function abandonSequence() {
|
|
3170
|
+
pendingAt = null;
|
|
3171
|
+
pressedEvents.length = 0;
|
|
3172
|
+
pendingLayer = null;
|
|
3173
|
+
pendingKey = null;
|
|
3174
|
+
}
|
|
3175
|
+
function prepare(bindings) {
|
|
3176
|
+
return bindings.map((binding) => ({
|
|
3177
|
+
binding,
|
|
3178
|
+
keys: parseKeys(binding.keys)
|
|
3179
|
+
}));
|
|
3180
|
+
}
|
|
3181
|
+
function ordered() {
|
|
3182
|
+
return [...layers].filter((layer) => layer.options.enabled !== false).sort(
|
|
3183
|
+
(a, b) => b.options.depth - a.options.depth || b.sequence - a.sequence
|
|
3184
|
+
);
|
|
3185
|
+
}
|
|
3186
|
+
function matchDepth(prepared, pressed) {
|
|
3187
|
+
if (pressed.length > prepared.keys.length) return "none";
|
|
3188
|
+
for (let i = 0; i < pressed.length; i++) {
|
|
3189
|
+
const chord = prepared.keys[i];
|
|
3190
|
+
const event = pressed[i];
|
|
3191
|
+
if (chord === void 0 || event === void 0) return "none";
|
|
3192
|
+
if (!chordMatches(chord, event.key, event, isApple)) return "none";
|
|
3193
|
+
}
|
|
3194
|
+
return pressed.length === prepared.keys.length ? "exact" : "prefix";
|
|
3195
|
+
}
|
|
3196
|
+
function fire(prepared, event, invoke) {
|
|
3197
|
+
if (prepared.binding.preventDefault !== false) event.preventDefault();
|
|
3198
|
+
if (invoke) prepared.binding.run(event);
|
|
3199
|
+
}
|
|
3200
|
+
function insertsText(event, typing) {
|
|
3201
|
+
if (event.key === "Tab")
|
|
3202
|
+
return !event.ctrlKey && !event.metaKey && !event.altKey;
|
|
3203
|
+
if (!typing) return false;
|
|
3204
|
+
const altGraph = event.getModifierState?.("AltGraph") ?? false;
|
|
3205
|
+
if (!altGraph && (event.ctrlKey || event.metaKey)) {
|
|
3206
|
+
const letter = event.key.length === 1 ? event.key.toLowerCase() : event.key;
|
|
3207
|
+
if (letter === "z" && event.shiftKey) return !event.altKey;
|
|
3208
|
+
if (letter === REDO_LETTER)
|
|
3209
|
+
return !isApple && !event.shiftKey && !event.altKey;
|
|
3210
|
+
if (EDITING_NAVIGATION.has(event.key)) return !event.altKey || isApple;
|
|
3211
|
+
if (event.shiftKey || event.altKey) return false;
|
|
3212
|
+
return EDITING_LETTERS.has(letter);
|
|
3213
|
+
}
|
|
3214
|
+
if (!altGraph && event.altKey) {
|
|
3215
|
+
if ((event.key === "ArrowDown" || event.key === "ArrowUp") && asElement(eventTarget(event))?.tagName === "SELECT") {
|
|
3216
|
+
return true;
|
|
3217
|
+
}
|
|
3218
|
+
if (!isApple) return false;
|
|
3219
|
+
if (EDITING_NAVIGATION.has(event.key)) return true;
|
|
3220
|
+
}
|
|
3221
|
+
if (event.key === "Dead" || event.key === "Process") return true;
|
|
3222
|
+
if ([...event.key].length === 1) return true;
|
|
3223
|
+
if (AMBIGUOUS_KEYS.has(event.key)) return targetOwnsAmbiguousKey(event);
|
|
3224
|
+
return FIELD_KEYS.has(event.key);
|
|
3225
|
+
}
|
|
3226
|
+
function offer(pressed, event, typing, invoke) {
|
|
3227
|
+
for (const layer of ordered()) {
|
|
3228
|
+
const mayMatch = pressed.length <= 1 || pendingLayer === null || layer === pendingLayer;
|
|
3229
|
+
if (mayMatch) {
|
|
3230
|
+
let prefixed = false;
|
|
3231
|
+
for (const prepared of layer.bindings) {
|
|
3232
|
+
if (typing && !firesWhileTyping(prepared)) continue;
|
|
3233
|
+
if (prepared.binding.when && !prepared.binding.when()) continue;
|
|
3234
|
+
const depth = matchDepth(prepared, pressed);
|
|
3235
|
+
if (depth === "exact") {
|
|
3236
|
+
fire(prepared, event, invoke);
|
|
3237
|
+
return "fired";
|
|
3238
|
+
}
|
|
3239
|
+
if (depth === "prefix") prefixed = true;
|
|
3240
|
+
}
|
|
3241
|
+
if (prefixed) {
|
|
3242
|
+
pendingLayer = layer;
|
|
3243
|
+
event.preventDefault();
|
|
3244
|
+
return "pending";
|
|
3245
|
+
}
|
|
3246
|
+
}
|
|
3247
|
+
if (layer.options.blocking) return "blocked";
|
|
3248
|
+
}
|
|
3249
|
+
return "none";
|
|
3250
|
+
}
|
|
3251
|
+
function warnOnPrefixConflicts(prepared, layerName) {
|
|
3252
|
+
const resolved = (chord) => {
|
|
3253
|
+
const ctrl = chord.ctrl || chord.mod && !isApple;
|
|
3254
|
+
const meta = chord.meta || chord.mod && isApple;
|
|
3255
|
+
const shift = shiftIsMeaningful(chord.key) ? chord.shift : false;
|
|
3256
|
+
return `${chord.key}\0${ctrl}${meta}${chord.alt}${shift}`;
|
|
3257
|
+
};
|
|
3258
|
+
const sameChord = (a, b) => resolved(a) === resolved(b);
|
|
3259
|
+
for (const short of prepared) {
|
|
3260
|
+
for (const long of prepared) {
|
|
3261
|
+
if (short === long || short.keys.length >= long.keys.length) continue;
|
|
3262
|
+
if (short.binding.when !== void 0) continue;
|
|
3263
|
+
if (!firesWhileTyping(short) && firesWhileTyping(long)) continue;
|
|
3264
|
+
if (short.keys.every((chord, i) => sameChord(chord, long.keys[i]))) {
|
|
3265
|
+
devWarnOnce(
|
|
3266
|
+
false,
|
|
3267
|
+
`shortcuts: in layer "${layerName}", "${short.binding.keys}" is a prefix of "${long.binding.keys}", so the longer one can never fire. Bind one or the other.`
|
|
3268
|
+
);
|
|
3269
|
+
}
|
|
3270
|
+
}
|
|
3271
|
+
}
|
|
3272
|
+
}
|
|
3273
|
+
const watchers = /* @__PURE__ */ new Set();
|
|
3274
|
+
let snapshot = null;
|
|
3275
|
+
function computeSnapshot() {
|
|
3276
|
+
return ordered().flatMap(
|
|
3277
|
+
(layer) => layer.bindings.map((prepared) => ({
|
|
3278
|
+
keys: prepared.binding.keys,
|
|
3279
|
+
description: prepared.binding.description,
|
|
3280
|
+
layer: layer.options.name
|
|
3281
|
+
}))
|
|
3282
|
+
);
|
|
3283
|
+
}
|
|
3284
|
+
function sameShortcuts(a, b) {
|
|
3285
|
+
return a.length === b.length && a.every(
|
|
3286
|
+
(entry, index) => entry.keys === b[index]?.keys && entry.description === b[index]?.description && entry.layer === b[index]?.layer
|
|
3287
|
+
);
|
|
3288
|
+
}
|
|
3289
|
+
function changed() {
|
|
3290
|
+
const previous = snapshot;
|
|
3291
|
+
snapshot = null;
|
|
3292
|
+
if (watchers.size === 0) return;
|
|
3293
|
+
const next = computeSnapshot();
|
|
3294
|
+
if (previous && sameShortcuts(previous, next)) {
|
|
3295
|
+
snapshot = previous;
|
|
3296
|
+
return;
|
|
3297
|
+
}
|
|
3298
|
+
snapshot = next;
|
|
3299
|
+
for (const watcher of watchers) watcher();
|
|
3300
|
+
}
|
|
3301
|
+
const pressedEvents = [];
|
|
3302
|
+
function runOffer(pressed, event, typing) {
|
|
3303
|
+
try {
|
|
3304
|
+
return offer(pressed, event, typing, true);
|
|
3305
|
+
} catch (error) {
|
|
3306
|
+
abandonSequence();
|
|
3307
|
+
consumedPresses.delete(signature(event));
|
|
3308
|
+
throw error;
|
|
3309
|
+
}
|
|
3310
|
+
}
|
|
3311
|
+
function handle(event) {
|
|
3312
|
+
if (event.defaultPrevented) {
|
|
3313
|
+
abandonSequence();
|
|
3314
|
+
return true;
|
|
3315
|
+
}
|
|
3316
|
+
if (event.isComposing) {
|
|
3317
|
+
abandonSequence();
|
|
3318
|
+
return true;
|
|
3319
|
+
}
|
|
3320
|
+
if (MODIFIER_KEYS.has(event.key)) return blocking();
|
|
3321
|
+
if (controlOwnsKey(eventTarget(event), event)) {
|
|
3322
|
+
abandonSequence();
|
|
3323
|
+
return true;
|
|
3324
|
+
}
|
|
3325
|
+
const typing = isTypingTarget(eventTarget(event));
|
|
3326
|
+
if (event.repeat) {
|
|
3327
|
+
if (pendingKey !== signature(event)) {
|
|
3328
|
+
abandonSequence();
|
|
3329
|
+
}
|
|
3330
|
+
const held = consumedPresses.get(signature(event));
|
|
3331
|
+
if (held) {
|
|
3332
|
+
if (held.prevented) {
|
|
3333
|
+
event.preventDefault();
|
|
3334
|
+
} else {
|
|
3335
|
+
const still = offer([event], event, typing, false);
|
|
3336
|
+
if (still !== "fired" && !insertsText(event, typing)) {
|
|
3337
|
+
event.preventDefault();
|
|
3338
|
+
}
|
|
3339
|
+
}
|
|
3340
|
+
return true;
|
|
3341
|
+
}
|
|
3342
|
+
const repeated = offer([event], event, typing, false);
|
|
3343
|
+
if (repeated === "blocked" && !insertsText(event, typing)) {
|
|
3344
|
+
event.preventDefault();
|
|
3345
|
+
}
|
|
3346
|
+
return repeated !== "none";
|
|
3347
|
+
}
|
|
3348
|
+
if (pendingAt !== null && now() - pendingAt > sequenceTimeoutMs) {
|
|
3349
|
+
abandonSequence();
|
|
3350
|
+
}
|
|
3351
|
+
pressedEvents.push(event);
|
|
3352
|
+
let outcome = runOffer(pressedEvents, event, typing);
|
|
3353
|
+
if (pressedEvents.length > 1 && (outcome === "none" || outcome === "blocked")) {
|
|
3354
|
+
abandonSequence();
|
|
3355
|
+
pressedEvents.push(event);
|
|
3356
|
+
outcome = runOffer(pressedEvents, event, typing);
|
|
3357
|
+
}
|
|
3358
|
+
if (outcome === "pending") {
|
|
3359
|
+
pendingAt = now();
|
|
3360
|
+
pendingKey = signature(event);
|
|
3361
|
+
consumedPresses.set(signature(event), {
|
|
3362
|
+
prevented: event.defaultPrevented
|
|
3363
|
+
});
|
|
3364
|
+
return true;
|
|
3365
|
+
}
|
|
3366
|
+
abandonSequence();
|
|
3367
|
+
if (outcome === "blocked") {
|
|
3368
|
+
if (!insertsText(event, typing)) event.preventDefault();
|
|
3369
|
+
}
|
|
3370
|
+
const consumed = outcome === "fired" || outcome === "blocked";
|
|
3371
|
+
if (consumed) {
|
|
3372
|
+
consumedPresses.set(signature(event), {
|
|
3373
|
+
prevented: event.defaultPrevented
|
|
3374
|
+
});
|
|
3375
|
+
} else {
|
|
3376
|
+
consumedPresses.delete(signature(event));
|
|
3377
|
+
}
|
|
3378
|
+
return consumed;
|
|
3379
|
+
}
|
|
3380
|
+
return {
|
|
3381
|
+
register(bindings, layerOptions) {
|
|
3382
|
+
const prepared = prepare(bindings);
|
|
3383
|
+
const layer = {
|
|
3384
|
+
options: layerOptions,
|
|
3385
|
+
bindings: prepared,
|
|
3386
|
+
sequence: nextSequence++,
|
|
3387
|
+
shape: layerShape(prepared, layerOptions)
|
|
3388
|
+
};
|
|
3389
|
+
warnOnPrefixConflicts(layer.bindings, layerOptions.name);
|
|
3390
|
+
layers.add(layer);
|
|
3391
|
+
changed();
|
|
3392
|
+
return {
|
|
3393
|
+
update(nextBindings, nextOptions) {
|
|
3394
|
+
layer.bindings = prepare(nextBindings);
|
|
3395
|
+
layer.options = nextOptions;
|
|
3396
|
+
warnOnPrefixConflicts(layer.bindings, nextOptions.name);
|
|
3397
|
+
const shape = layerShape(layer.bindings, nextOptions);
|
|
3398
|
+
const shapeChanged = shape !== layer.shape;
|
|
3399
|
+
layer.shape = shape;
|
|
3400
|
+
if (shapeChanged && pendingLayer === layer) abandonSequence();
|
|
3401
|
+
changed();
|
|
3402
|
+
},
|
|
3403
|
+
dispose() {
|
|
3404
|
+
layers.delete(layer);
|
|
3405
|
+
changed();
|
|
3406
|
+
if (pendingLayer === layer) abandonSequence();
|
|
3407
|
+
}
|
|
3408
|
+
};
|
|
3409
|
+
},
|
|
3410
|
+
handle,
|
|
3411
|
+
attach(target) {
|
|
3412
|
+
const listener = (event) => {
|
|
3413
|
+
try {
|
|
3414
|
+
if (handle(event)) event.stopPropagation();
|
|
3415
|
+
} catch (error) {
|
|
3416
|
+
event.stopPropagation();
|
|
3417
|
+
throw error;
|
|
3418
|
+
}
|
|
3419
|
+
};
|
|
3420
|
+
target.addEventListener("keydown", listener);
|
|
3421
|
+
return () => {
|
|
3422
|
+
target.removeEventListener("keydown", listener);
|
|
3423
|
+
abandonSequence();
|
|
3424
|
+
consumedPresses.clear();
|
|
3425
|
+
};
|
|
3426
|
+
},
|
|
3427
|
+
subscribe(onChange) {
|
|
3428
|
+
watchers.add(onChange);
|
|
3429
|
+
return () => {
|
|
3430
|
+
watchers.delete(onChange);
|
|
3431
|
+
};
|
|
3432
|
+
},
|
|
3433
|
+
activeBindings() {
|
|
3434
|
+
if (snapshot) return snapshot;
|
|
3435
|
+
snapshot = computeSnapshot();
|
|
3436
|
+
return snapshot;
|
|
3437
|
+
}
|
|
3438
|
+
};
|
|
3439
|
+
}
|
|
3440
|
+
var MODIFIER_KEYS = /* @__PURE__ */ new Set([
|
|
3441
|
+
"Control",
|
|
3442
|
+
"Meta",
|
|
3443
|
+
"Alt",
|
|
3444
|
+
"Shift",
|
|
3445
|
+
// A dedicated AltGraph key reports its own keydown before the character-producing one. Without
|
|
3446
|
+
// it here, pressing AltGraph mid-sequence abandons the sequence before the character that would
|
|
3447
|
+
// have completed it ever arrives.
|
|
3448
|
+
"AltGraph"
|
|
3449
|
+
]);
|
|
3450
|
+
var TYPE_AHEAD_ROLES = /* @__PURE__ */ new Set([
|
|
3451
|
+
"textbox",
|
|
3452
|
+
"combobox",
|
|
3453
|
+
"listbox",
|
|
3454
|
+
// The focused element inside an open listbox is the OPTION, and it is what the event reports;
|
|
3455
|
+
// the listbox itself is only its ancestor.
|
|
3456
|
+
"option",
|
|
3457
|
+
"menu",
|
|
3458
|
+
"menuitem",
|
|
3459
|
+
"menuitemcheckbox",
|
|
3460
|
+
"menuitemradio"
|
|
3461
|
+
]);
|
|
3462
|
+
var RANGE_KEYS = /* @__PURE__ */ new Set(["Home", "End", "PageUp", "PageDown"]);
|
|
3463
|
+
var EDITING_LETTERS = /* @__PURE__ */ new Set(["a", "c", "v", "x", "z"]);
|
|
3464
|
+
var REDO_LETTER = "y";
|
|
3465
|
+
var EDITING_NAVIGATION = /* @__PURE__ */ new Set([
|
|
3466
|
+
"Insert",
|
|
3467
|
+
"ArrowLeft",
|
|
3468
|
+
"ArrowRight",
|
|
3469
|
+
"ArrowUp",
|
|
3470
|
+
"ArrowDown",
|
|
3471
|
+
"Home",
|
|
3472
|
+
"End",
|
|
3473
|
+
"Backspace",
|
|
3474
|
+
"Delete"
|
|
3475
|
+
]);
|
|
3476
|
+
var AMBIGUOUS_KEYS = /* @__PURE__ */ new Set(["Enter", "PageUp", "PageDown"]);
|
|
3477
|
+
function targetOwnsAmbiguousKey(event) {
|
|
3478
|
+
const element = asElement(eventTarget(event));
|
|
3479
|
+
if (element === null) return false;
|
|
3480
|
+
const multiline = element.tagName === "TEXTAREA" || element.isContentEditable;
|
|
3481
|
+
if (event.key === "Enter") return multiline;
|
|
3482
|
+
return multiline || element.tagName === "SELECT";
|
|
3483
|
+
}
|
|
3484
|
+
var FIELD_KEYS = /* @__PURE__ */ new Set([
|
|
3485
|
+
"Backspace",
|
|
3486
|
+
"Delete",
|
|
3487
|
+
"ArrowUp",
|
|
3488
|
+
"ArrowDown",
|
|
3489
|
+
"ArrowLeft",
|
|
3490
|
+
"ArrowRight",
|
|
3491
|
+
"Home",
|
|
3492
|
+
"End",
|
|
3493
|
+
// Shift+Insert pastes and carries no ctrl or meta, so it arrives here rather than at the
|
|
3494
|
+
// chord branch where Ctrl+Insert is recognised.
|
|
3495
|
+
"Insert",
|
|
3496
|
+
// Tab moves focus, and a blocking layer must NOT take it. The documented case for blocking is
|
|
3497
|
+
// a modal, whose focus trap only calls `preventDefault()` at the first and last tabbable
|
|
3498
|
+
// element — ordinary moves between the controls inside it rely on the browser default.
|
|
3499
|
+
// Suppressing every Tab therefore pinned focus to one control in exactly the situation
|
|
3500
|
+
// blocking exists to serve. A layer that genuinely wants Tab binds it.
|
|
3501
|
+
"Tab"
|
|
3502
|
+
]);
|
|
3503
|
+
|
|
3504
|
+
// src/lib/shortcuts/react.tsx
|
|
3505
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
3506
|
+
var ShortcutContext = React12.createContext(null);
|
|
3507
|
+
var ownersByTarget = /* @__PURE__ */ new WeakMap();
|
|
3508
|
+
var useIsomorphicLayoutEffect = typeof document === "undefined" ? React12.useEffect : React12.useLayoutEffect;
|
|
3509
|
+
function optionsFingerprint(options) {
|
|
3510
|
+
return [
|
|
3511
|
+
options.isApple ?? "auto",
|
|
3512
|
+
options.sequenceTimeoutMs ?? "default",
|
|
3513
|
+
options.now ? "clock" : "no-clock"
|
|
3514
|
+
].join("\0");
|
|
3515
|
+
}
|
|
3516
|
+
function ShortcutProvider({
|
|
3517
|
+
children,
|
|
3518
|
+
target,
|
|
3519
|
+
...managerOptions
|
|
3520
|
+
}) {
|
|
3521
|
+
const parent = React12.useContext(ShortcutContext);
|
|
3522
|
+
const resolvedTarget = target === null ? null : target ?? (typeof document === "undefined" ? null : document);
|
|
3523
|
+
const nestedOnSameTarget = parent !== null && parent.target === resolvedTarget;
|
|
3524
|
+
const optionsRef = React12.useRef(managerOptions);
|
|
3525
|
+
const ownManagers = React12.useRef(/* @__PURE__ */ new WeakMap());
|
|
3526
|
+
const ownDetached = React12.useRef(null);
|
|
3527
|
+
const detached = React12.useMemo(() => {
|
|
3528
|
+
if (resolvedTarget === null) {
|
|
3529
|
+
ownDetached.current ??= createShortcutManager(optionsRef.current);
|
|
3530
|
+
return ownDetached.current;
|
|
3531
|
+
}
|
|
3532
|
+
const existing = ownManagers.current.get(resolvedTarget);
|
|
3533
|
+
if (existing) return existing;
|
|
3534
|
+
const created = createShortcutManager(optionsRef.current);
|
|
3535
|
+
ownManagers.current.set(resolvedTarget, created);
|
|
3536
|
+
return created;
|
|
3537
|
+
}, [resolvedTarget]);
|
|
3538
|
+
let owner = resolvedTarget === null ? null : ownersByTarget.get(resolvedTarget);
|
|
3539
|
+
const fingerprint = optionsFingerprint(optionsRef.current);
|
|
3540
|
+
if (resolvedTarget !== null && (!owner || owner.retired)) {
|
|
3541
|
+
owner = {
|
|
3542
|
+
manager: detached,
|
|
3543
|
+
providers: 0,
|
|
3544
|
+
retired: false,
|
|
3545
|
+
options: fingerprint
|
|
3546
|
+
};
|
|
3547
|
+
ownersByTarget.set(resolvedTarget, owner);
|
|
3548
|
+
}
|
|
3549
|
+
const adoptedDiffers = Boolean(owner) && owner?.options !== fingerprint || nestedOnSameTarget && parent !== null && parent.options !== fingerprint;
|
|
3550
|
+
devWarnOnce(
|
|
3551
|
+
!adoptedDiffers,
|
|
3552
|
+
"ShortcutProvider: another provider is already listening on this target with different options, so the ones passed here are being ignored. Managers are shared per target; give the providers matching options, or a target of their own."
|
|
3553
|
+
);
|
|
3554
|
+
const manager = nestedOnSameTarget && parent ? parent.manager : owner ? owner.manager : detached;
|
|
3555
|
+
useIsomorphicLayoutEffect(() => {
|
|
3556
|
+
if (resolvedTarget === null) return;
|
|
3557
|
+
let entry = ownersByTarget.get(resolvedTarget);
|
|
3558
|
+
if (!entry) {
|
|
3559
|
+
entry = {
|
|
3560
|
+
manager,
|
|
3561
|
+
providers: 0,
|
|
3562
|
+
retired: false,
|
|
3563
|
+
options: optionsFingerprint(optionsRef.current)
|
|
3564
|
+
};
|
|
3565
|
+
ownersByTarget.set(resolvedTarget, entry);
|
|
3566
|
+
}
|
|
3567
|
+
const owned = entry;
|
|
3568
|
+
owned.providers += 1;
|
|
3569
|
+
owned.retired = false;
|
|
3570
|
+
if (owned.providers === 1) {
|
|
3571
|
+
owned.detach = owned.manager.attach(resolvedTarget);
|
|
3572
|
+
}
|
|
3573
|
+
return () => {
|
|
3574
|
+
owned.providers -= 1;
|
|
3575
|
+
if (owned.providers === 0) {
|
|
3576
|
+
owned.detach?.();
|
|
3577
|
+
owned.detach = void 0;
|
|
3578
|
+
owned.retired = true;
|
|
3579
|
+
}
|
|
3580
|
+
};
|
|
3581
|
+
}, [resolvedTarget, manager]);
|
|
3582
|
+
const depth = nestedOnSameTarget && parent ? parent.depth : 0;
|
|
3583
|
+
const value = React12.useMemo(
|
|
3584
|
+
() => ({ manager, depth, target: resolvedTarget, options: fingerprint }),
|
|
3585
|
+
[manager, depth, resolvedTarget, fingerprint]
|
|
3586
|
+
);
|
|
3587
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(ShortcutContext.Provider, { value, children });
|
|
3588
|
+
}
|
|
3589
|
+
function ShortcutScope({
|
|
3590
|
+
children
|
|
3591
|
+
}) {
|
|
3592
|
+
const parent = React12.useContext(ShortcutContext);
|
|
3593
|
+
if (!parent) {
|
|
3594
|
+
throw new Error("ShortcutScope must be rendered inside a ShortcutProvider");
|
|
3595
|
+
}
|
|
3596
|
+
const value = React12.useMemo(
|
|
3597
|
+
() => ({
|
|
3598
|
+
manager: parent.manager,
|
|
3599
|
+
depth: parent.depth + 1,
|
|
3600
|
+
target: parent.target,
|
|
3601
|
+
// Inherited: a scope raises precedence, it does not build a manager, so the options in force
|
|
3602
|
+
// are still the ones the provider above it used.
|
|
3603
|
+
options: parent.options
|
|
3604
|
+
}),
|
|
3605
|
+
[parent.manager, parent.depth, parent.target, parent.options]
|
|
3606
|
+
);
|
|
3607
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(ShortcutContext.Provider, { value, children });
|
|
3608
|
+
}
|
|
3609
|
+
function useShortcuts(bindings, options) {
|
|
3610
|
+
const context = React12.useContext(ShortcutContext);
|
|
3611
|
+
if (!context) {
|
|
3612
|
+
throw new Error("useShortcuts must be called inside a ShortcutProvider");
|
|
3613
|
+
}
|
|
3614
|
+
const { manager, depth } = context;
|
|
3615
|
+
const registration = React12.useRef(null);
|
|
3616
|
+
const latest = React12.useRef({ bindings, options });
|
|
3617
|
+
useIsomorphicLayoutEffect(() => {
|
|
3618
|
+
registration.current = manager.register([], {
|
|
3619
|
+
name: latest.current.options.name,
|
|
3620
|
+
depth
|
|
3621
|
+
});
|
|
3622
|
+
return () => {
|
|
3623
|
+
registration.current?.dispose();
|
|
3624
|
+
registration.current = null;
|
|
3625
|
+
};
|
|
3626
|
+
}, [manager, depth]);
|
|
3627
|
+
useIsomorphicLayoutEffect(() => {
|
|
3628
|
+
latest.current = { bindings, options };
|
|
3629
|
+
registration.current?.update(bindings, {
|
|
3630
|
+
name: options.name,
|
|
3631
|
+
depth,
|
|
3632
|
+
enabled: options.enabled,
|
|
3633
|
+
blocking: options.blocking
|
|
3634
|
+
});
|
|
3635
|
+
});
|
|
3636
|
+
}
|
|
3637
|
+
function useShortcutManager() {
|
|
3638
|
+
const context = React12.useContext(ShortcutContext);
|
|
3639
|
+
if (!context) {
|
|
3640
|
+
throw new Error(
|
|
3641
|
+
"useShortcutManager must be called inside a ShortcutProvider"
|
|
3642
|
+
);
|
|
3643
|
+
}
|
|
3644
|
+
return context.manager;
|
|
3645
|
+
}
|
|
3646
|
+
function useActiveShortcuts() {
|
|
3647
|
+
const manager = useShortcutManager();
|
|
3648
|
+
return React12.useSyncExternalStore(
|
|
3649
|
+
manager.subscribe,
|
|
3650
|
+
manager.activeBindings,
|
|
3651
|
+
manager.activeBindings
|
|
3652
|
+
);
|
|
3653
|
+
}
|
|
2492
3654
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2493
3655
|
0 && (module.exports = {
|
|
2494
3656
|
Accordion,
|
|
@@ -2609,7 +3771,10 @@ var ResizableHandle = ({
|
|
|
2609
3771
|
SheetPortal,
|
|
2610
3772
|
SheetTitle,
|
|
2611
3773
|
SheetTrigger,
|
|
3774
|
+
ShortcutProvider,
|
|
3775
|
+
ShortcutScope,
|
|
2612
3776
|
Skeleton,
|
|
3777
|
+
Slider,
|
|
2613
3778
|
Spinner,
|
|
2614
3779
|
Stack,
|
|
2615
3780
|
Stat,
|
|
@@ -2637,18 +3802,24 @@ var ResizableHandle = ({
|
|
|
2637
3802
|
TooltipContent,
|
|
2638
3803
|
TooltipProvider,
|
|
2639
3804
|
TooltipTrigger,
|
|
3805
|
+
TreeView,
|
|
2640
3806
|
alertVariants,
|
|
2641
3807
|
avatarVariants,
|
|
2642
3808
|
badgeVariants,
|
|
2643
3809
|
buttonVariants,
|
|
2644
3810
|
cardVariants,
|
|
3811
|
+
createShortcutManager,
|
|
2645
3812
|
dialogContentVariants,
|
|
2646
3813
|
inputVariants,
|
|
3814
|
+
parseKeys,
|
|
2647
3815
|
progressVariants,
|
|
2648
3816
|
selectTriggerVariants,
|
|
2649
3817
|
sheetVariants,
|
|
2650
3818
|
spinnerVariants,
|
|
2651
3819
|
toast,
|
|
2652
|
-
|
|
3820
|
+
useActiveShortcuts,
|
|
3821
|
+
usePortalContainer,
|
|
3822
|
+
useShortcutManager,
|
|
3823
|
+
useShortcuts
|
|
2653
3824
|
});
|
|
2654
3825
|
//# sourceMappingURL=index.cjs.map
|