@nextlyhq/ui 0.0.2-alpha.60 → 0.0.2-alpha.64
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 +35 -8
- package/dist/index.cjs +475 -221
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +301 -23
- package/dist/index.d.ts +301 -23
- package/dist/index.mjs +479 -221
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/styles.scoped.css +1 -1
- package/dist/tailwind-preset.cjs.map +1 -1
- package/dist/tailwind-preset.mjs.map +1 -1
- package/dist/theme.css +132 -0
- package/package.json +6 -5
package/dist/index.cjs
CHANGED
|
@@ -53,6 +53,7 @@ __export(src_exports, {
|
|
|
53
53
|
AvatarFallback: () => AvatarFallback,
|
|
54
54
|
AvatarImage: () => AvatarImage,
|
|
55
55
|
Badge: () => Badge,
|
|
56
|
+
Bleed: () => Bleed,
|
|
56
57
|
Button: () => Button,
|
|
57
58
|
Card: () => Card,
|
|
58
59
|
CardAction: () => CardAction,
|
|
@@ -117,11 +118,12 @@ __export(src_exports, {
|
|
|
117
118
|
FieldShell: () => FieldShell,
|
|
118
119
|
FormActions: () => FormActions,
|
|
119
120
|
FormLabelWithTooltip: () => FormLabelWithTooltip,
|
|
120
|
-
FormLayout: () => FormLayout,
|
|
121
121
|
FormSection: () => FormSection,
|
|
122
122
|
Grid: () => Grid,
|
|
123
123
|
Input: () => Input,
|
|
124
124
|
Label: () => Label,
|
|
125
|
+
PageHeader: () => PageHeader,
|
|
126
|
+
PageShell: () => PageShell,
|
|
125
127
|
Popover: () => Popover,
|
|
126
128
|
PopoverAnchor: () => PopoverAnchor,
|
|
127
129
|
PopoverContent: () => PopoverContent,
|
|
@@ -133,6 +135,7 @@ __export(src_exports, {
|
|
|
133
135
|
ResizableHandle: () => ResizableHandle,
|
|
134
136
|
ResizablePanel: () => ResizablePanel,
|
|
135
137
|
ResizablePanelGroup: () => ResizablePanelGroup,
|
|
138
|
+
SHELL_MEASURE: () => SHELL_MEASURE,
|
|
136
139
|
Select: () => Select,
|
|
137
140
|
SelectContent: () => SelectContent,
|
|
138
141
|
SelectGroup: () => SelectGroup,
|
|
@@ -191,8 +194,10 @@ __export(src_exports, {
|
|
|
191
194
|
badgeVariants: () => badgeVariants,
|
|
192
195
|
buttonVariants: () => buttonVariants,
|
|
193
196
|
cardVariants: () => cardVariants,
|
|
197
|
+
chordMatches: () => chordMatches,
|
|
194
198
|
commandDefaultFilter: () => commandDefaultFilter,
|
|
195
199
|
createShortcutManager: () => createShortcutManager,
|
|
200
|
+
detectApplePlatform: () => detectApplePlatform,
|
|
196
201
|
dialogContentVariants: () => dialogContentVariants,
|
|
197
202
|
inputVariants: () => inputVariants,
|
|
198
203
|
parseKeys: () => parseKeys,
|
|
@@ -202,6 +207,8 @@ __export(src_exports, {
|
|
|
202
207
|
spinnerVariants: () => spinnerVariants,
|
|
203
208
|
toast: () => import_sonner.toast,
|
|
204
209
|
useActiveShortcuts: () => useActiveShortcuts,
|
|
210
|
+
useCommandHighlight: () => useCommandHighlight,
|
|
211
|
+
useIsomorphicLayoutEffect: () => useIsomorphicLayoutEffect,
|
|
205
212
|
usePortalContainer: () => usePortalContainer,
|
|
206
213
|
useShortcutManager: () => useShortcutManager,
|
|
207
214
|
useShortcuts: () => useShortcuts
|
|
@@ -1193,15 +1200,23 @@ var tabsListVariants = (0, import_class_variance_authority8.cva)(
|
|
|
1193
1200
|
defaultVariants: { variant: "default" }
|
|
1194
1201
|
}
|
|
1195
1202
|
);
|
|
1196
|
-
var TabsList = (0, import_react13.forwardRef)(({ className, variant, ...props }, ref) =>
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1203
|
+
var TabsList = (0, import_react13.forwardRef)(({ className, variant, scrollable = false, ...props }, ref) => {
|
|
1204
|
+
const list = /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1205
|
+
import_react_tabs.List,
|
|
1206
|
+
{
|
|
1207
|
+
ref,
|
|
1208
|
+
"data-slot": "tabs-list",
|
|
1209
|
+
className: cn(
|
|
1210
|
+
tabsListVariants({ variant }),
|
|
1211
|
+
scrollable && "w-max min-w-full",
|
|
1212
|
+
className
|
|
1213
|
+
),
|
|
1214
|
+
...props
|
|
1215
|
+
}
|
|
1216
|
+
);
|
|
1217
|
+
if (!scrollable) return list;
|
|
1218
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { "data-slot": "tabs-list-scroller", className: "w-full overflow-x-auto", children: list });
|
|
1219
|
+
});
|
|
1205
1220
|
TabsList.displayName = import_react_tabs.List.displayName;
|
|
1206
1221
|
var TABS_TRIGGER_SIZES = {
|
|
1207
1222
|
default: "text-sm",
|
|
@@ -1850,6 +1865,7 @@ var SheetPortal = DialogPrimitive2.Portal;
|
|
|
1850
1865
|
var SheetOverlay = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
1851
1866
|
DialogPrimitive2.Overlay,
|
|
1852
1867
|
{
|
|
1868
|
+
"data-slot": "sheet-overlay",
|
|
1853
1869
|
className: cn(
|
|
1854
1870
|
// A modal scrim, from the `--nx-overlay` token rather than a surface
|
|
1855
1871
|
// token. A black wash is the point — painting it from `background` would
|
|
@@ -2176,6 +2192,7 @@ var CommandShortcut = (0, import_react17.forwardRef)(
|
|
|
2176
2192
|
);
|
|
2177
2193
|
CommandShortcut.displayName = "CommandShortcut";
|
|
2178
2194
|
var commandDefaultFilter = import_cmdk.defaultFilter;
|
|
2195
|
+
var useCommandHighlight = () => (0, import_cmdk.useCommandState)((state) => state.value);
|
|
2179
2196
|
|
|
2180
2197
|
// src/components/spinner.tsx
|
|
2181
2198
|
var import_class_variance_authority12 = require("class-variance-authority");
|
|
@@ -2444,7 +2461,7 @@ TableSkeleton.displayName = "TableSkeleton";
|
|
|
2444
2461
|
|
|
2445
2462
|
// src/components/color-picker.tsx
|
|
2446
2463
|
var import_lucide_react12 = require("lucide-react");
|
|
2447
|
-
var
|
|
2464
|
+
var React10 = __toESM(require("react"), 1);
|
|
2448
2465
|
|
|
2449
2466
|
// src/lib/color/convert.ts
|
|
2450
2467
|
var clamp01 = (n) => n < 0 ? 0 : n > 1 ? 1 : n;
|
|
@@ -2549,6 +2566,10 @@ function hueSliderValue(hue, max) {
|
|
|
2549
2566
|
return step > max ? max : step;
|
|
2550
2567
|
}
|
|
2551
2568
|
|
|
2569
|
+
// src/lib/isomorphic-layout-effect.ts
|
|
2570
|
+
var React9 = __toESM(require("react"), 1);
|
|
2571
|
+
var useIsomorphicLayoutEffect = typeof document === "undefined" ? React9.useEffect : React9.useLayoutEffect;
|
|
2572
|
+
|
|
2552
2573
|
// src/components/color-picker.tsx
|
|
2553
2574
|
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
2554
2575
|
function toHsva(hex) {
|
|
@@ -2570,6 +2591,9 @@ var CHECKERBOARD = "repeating-conic-gradient(#c8c8c8 0% 25%, #ffffff 0% 50%)";
|
|
|
2570
2591
|
function eyeDropperSupported() {
|
|
2571
2592
|
return typeof window !== "undefined" && "EyeDropper" in window;
|
|
2572
2593
|
}
|
|
2594
|
+
function isNode(value) {
|
|
2595
|
+
return value !== null && typeof value.nodeType === "number";
|
|
2596
|
+
}
|
|
2573
2597
|
function ColorPicker({
|
|
2574
2598
|
color,
|
|
2575
2599
|
onColorChange,
|
|
@@ -2579,20 +2603,100 @@ function ColorPicker({
|
|
|
2579
2603
|
showAlpha = false,
|
|
2580
2604
|
className
|
|
2581
2605
|
}) {
|
|
2582
|
-
const fieldId =
|
|
2583
|
-
const
|
|
2584
|
-
const
|
|
2585
|
-
const
|
|
2606
|
+
const fieldId = React10.useId();
|
|
2607
|
+
const rootRef = React10.useRef(null);
|
|
2608
|
+
const insidePress = React10.useRef(false);
|
|
2609
|
+
const owedFinish = React10.useRef(false);
|
|
2610
|
+
const pendingTap = React10.useRef(null);
|
|
2611
|
+
const latestCommit = React10.useRef(() => void 0);
|
|
2612
|
+
const surfaceRef = React10.useRef(null);
|
|
2613
|
+
const [hsva, setHsva] = React10.useState(() => toHsva(color));
|
|
2614
|
+
const [draftHex, setDraftHex] = React10.useState(null);
|
|
2615
|
+
const draftRef = React10.useRef(null);
|
|
2586
2616
|
const rendered = toHexString(hsva, showAlpha);
|
|
2587
|
-
|
|
2617
|
+
useIsomorphicLayoutEffect(() => {
|
|
2588
2618
|
const incoming = parseHex(color);
|
|
2589
2619
|
if (incoming && toHex(incoming, showAlpha ? incoming.alpha : 1) !== rendered) {
|
|
2620
|
+
dropDraft();
|
|
2590
2621
|
setHsva((prev) => hsvaFrom(incoming, incoming.alpha, prev.h));
|
|
2591
2622
|
}
|
|
2592
2623
|
}, [color, rendered, showAlpha]);
|
|
2624
|
+
const dropDraft = () => {
|
|
2625
|
+
owedFinish.current = false;
|
|
2626
|
+
draftRef.current = null;
|
|
2627
|
+
setDraftHex(null);
|
|
2628
|
+
};
|
|
2629
|
+
const commitDraft = () => {
|
|
2630
|
+
owedFinish.current = false;
|
|
2631
|
+
const text = draftRef.current;
|
|
2632
|
+
draftRef.current = null;
|
|
2633
|
+
if (text === null) return;
|
|
2634
|
+
setDraftHex(null);
|
|
2635
|
+
const parsed = parseHex(text);
|
|
2636
|
+
if (!parsed) return;
|
|
2637
|
+
setHsva((prev) => hsvaFrom(parsed, parsed.alpha, prev.h));
|
|
2638
|
+
onColorChange(toHex(parsed, showAlpha ? parsed.alpha : 1));
|
|
2639
|
+
};
|
|
2640
|
+
useIsomorphicLayoutEffect(() => {
|
|
2641
|
+
const root = rootRef.current;
|
|
2642
|
+
if (root === null) return;
|
|
2643
|
+
latestCommit.current = commitDraft;
|
|
2644
|
+
const onPointerDown = (event) => {
|
|
2645
|
+
pendingTap.current?.();
|
|
2646
|
+
pendingTap.current = null;
|
|
2647
|
+
const path = typeof event.composedPath === "function" ? event.composedPath() : [];
|
|
2648
|
+
const inside = path.includes(root) || isNode(event.target) && root.contains(event.target);
|
|
2649
|
+
insidePress.current = true;
|
|
2650
|
+
if (inside) return;
|
|
2651
|
+
const pointerType = event.pointerType;
|
|
2652
|
+
if (pointerType === "touch") {
|
|
2653
|
+
const onClick = () => {
|
|
2654
|
+
owner.removeEventListener("click", onClick, true);
|
|
2655
|
+
pendingTap.current = null;
|
|
2656
|
+
latestCommit.current();
|
|
2657
|
+
};
|
|
2658
|
+
owner.addEventListener("click", onClick, true);
|
|
2659
|
+
pendingTap.current = () => {
|
|
2660
|
+
owner.removeEventListener("click", onClick, true);
|
|
2661
|
+
};
|
|
2662
|
+
return;
|
|
2663
|
+
}
|
|
2664
|
+
commitDraft();
|
|
2665
|
+
};
|
|
2666
|
+
const owner = root.ownerDocument;
|
|
2667
|
+
const onPointerCancel = () => {
|
|
2668
|
+
insidePress.current = false;
|
|
2669
|
+
pendingTap.current?.();
|
|
2670
|
+
pendingTap.current = null;
|
|
2671
|
+
};
|
|
2672
|
+
const onPointerUp = () => {
|
|
2673
|
+
insidePress.current = false;
|
|
2674
|
+
};
|
|
2675
|
+
const onClickResolve = () => {
|
|
2676
|
+
if (!owedFinish.current) return;
|
|
2677
|
+
latestCommit.current();
|
|
2678
|
+
};
|
|
2679
|
+
owner.addEventListener("pointerdown", onPointerDown, true);
|
|
2680
|
+
owner.addEventListener("pointercancel", onPointerCancel, true);
|
|
2681
|
+
owner.addEventListener("pointerup", onPointerUp, true);
|
|
2682
|
+
owner.addEventListener("click", onClickResolve, false);
|
|
2683
|
+
return () => {
|
|
2684
|
+
owner.removeEventListener("pointerdown", onPointerDown, true);
|
|
2685
|
+
owner.removeEventListener("pointercancel", onPointerCancel, true);
|
|
2686
|
+
owner.removeEventListener("pointerup", onPointerUp, true);
|
|
2687
|
+
owner.removeEventListener("click", onClickResolve, false);
|
|
2688
|
+
};
|
|
2689
|
+
});
|
|
2690
|
+
useIsomorphicLayoutEffect(
|
|
2691
|
+
() => () => {
|
|
2692
|
+
pendingTap.current?.();
|
|
2693
|
+
pendingTap.current = null;
|
|
2694
|
+
},
|
|
2695
|
+
[]
|
|
2696
|
+
);
|
|
2593
2697
|
const commit = (next) => {
|
|
2594
2698
|
setHsva(next);
|
|
2595
|
-
|
|
2699
|
+
dropDraft();
|
|
2596
2700
|
onColorChange(toHexString(next, showAlpha));
|
|
2597
2701
|
};
|
|
2598
2702
|
const trackPointer = (event) => {
|
|
@@ -2622,8 +2726,8 @@ function ColorPicker({
|
|
|
2622
2726
|
event.preventDefault();
|
|
2623
2727
|
nudge(move[0], move[1]);
|
|
2624
2728
|
};
|
|
2625
|
-
const [canPickFromScreen, setCanPickFromScreen] =
|
|
2626
|
-
|
|
2729
|
+
const [canPickFromScreen, setCanPickFromScreen] = React10.useState(false);
|
|
2730
|
+
React10.useEffect(() => {
|
|
2627
2731
|
setCanPickFromScreen(eyeDropperSupported());
|
|
2628
2732
|
}, []);
|
|
2629
2733
|
const handle = surfacePointFor(hsva.s, hsva.v);
|
|
@@ -2631,163 +2735,187 @@ function ColorPicker({
|
|
|
2631
2735
|
const pickFromScreen = async () => {
|
|
2632
2736
|
const ctor = window.EyeDropper;
|
|
2633
2737
|
if (!ctor) return;
|
|
2738
|
+
const owed = owedFinish.current;
|
|
2739
|
+
owedFinish.current = false;
|
|
2634
2740
|
let sampled;
|
|
2635
2741
|
try {
|
|
2636
2742
|
sampled = (await new ctor().open()).sRGBHex;
|
|
2637
2743
|
} catch {
|
|
2744
|
+
if (owed) commitDraft();
|
|
2638
2745
|
return;
|
|
2639
2746
|
}
|
|
2640
2747
|
const parsed = parseHex(sampled);
|
|
2641
2748
|
if (parsed) commit(hsvaFrom(parsed, hsva.a, hsva.h));
|
|
2642
2749
|
};
|
|
2643
|
-
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
// viewer, so the reverse order lets the opaque white end of the
|
|
2656
|
-
// saturation ramp cover the black end of the value ramp: the
|
|
2657
|
-
// bottom-left corner displays white while selecting black.
|
|
2658
|
-
backgroundImage: "linear-gradient(to top, #000, transparent), linear-gradient(to right, #fff, transparent)"
|
|
2659
|
-
},
|
|
2660
|
-
onKeyDown: handleSurfaceKey,
|
|
2661
|
-
onPointerDown: (event) => {
|
|
2662
|
-
event.currentTarget.setPointerCapture(event.pointerId);
|
|
2663
|
-
trackPointer(event);
|
|
2664
|
-
},
|
|
2665
|
-
onPointerMove: (event) => {
|
|
2666
|
-
if (event.buttons === 1) trackPointer(event);
|
|
2667
|
-
},
|
|
2668
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2669
|
-
"span",
|
|
2670
|
-
{
|
|
2671
|
-
"aria-hidden": "true",
|
|
2672
|
-
className: "pointer-events-none absolute size-3 -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-white shadow-sm ring-1 ring-black/60",
|
|
2673
|
-
style: { left: `${handle.x * 100}%`, top: `${handle.y * 100}%` }
|
|
2674
|
-
}
|
|
2675
|
-
)
|
|
2676
|
-
}
|
|
2677
|
-
),
|
|
2678
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("label", { className: "sr-only", htmlFor: `${fieldId}-hue`, children: "Hue" }),
|
|
2679
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2680
|
-
"input",
|
|
2681
|
-
{
|
|
2682
|
-
id: `${fieldId}-hue`,
|
|
2683
|
-
type: "range",
|
|
2684
|
-
min: 0,
|
|
2685
|
-
max: HUE_MAX,
|
|
2686
|
-
step: 1,
|
|
2687
|
-
value: hueSliderValue(hsva.h, HUE_MAX),
|
|
2688
|
-
onChange: (event) => commit({ ...hsva, h: hueAt(+event.target.value / (HUE_MAX + 1)) }),
|
|
2689
|
-
className: SLIDER,
|
|
2690
|
-
style: {
|
|
2691
|
-
backgroundImage: "linear-gradient(to right, #f00, #ff0, #0f0, #0ff, #00f, #f0f, #f00)"
|
|
2750
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
2751
|
+
"div",
|
|
2752
|
+
{
|
|
2753
|
+
ref: rootRef,
|
|
2754
|
+
className: cn("w-64 space-y-3", className),
|
|
2755
|
+
onBlur: (event) => {
|
|
2756
|
+
const next = event.relatedTarget;
|
|
2757
|
+
const root = rootRef.current;
|
|
2758
|
+
if (root !== null && isNode(next) && root.contains(next)) return;
|
|
2759
|
+
if (next === null && insidePress.current) {
|
|
2760
|
+
owedFinish.current = true;
|
|
2761
|
+
return;
|
|
2692
2762
|
}
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2763
|
+
commitDraft();
|
|
2764
|
+
},
|
|
2765
|
+
children: [
|
|
2766
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2767
|
+
"div",
|
|
2768
|
+
{
|
|
2769
|
+
ref: surfaceRef,
|
|
2770
|
+
role: "application",
|
|
2771
|
+
tabIndex: 0,
|
|
2772
|
+
"aria-label": `Saturation and brightness: ${Math.round(hsva.s * 100)}% saturation, ${Math.round(hsva.v * 100)}% brightness. Arrow keys adjust.`,
|
|
2773
|
+
className: "ring-offset-background focus-visible:ring-ring relative h-40 w-full cursor-crosshair touch-none rounded-md focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none",
|
|
2774
|
+
style: {
|
|
2775
|
+
backgroundColor: hueOnly,
|
|
2776
|
+
// Value on TOP of saturation. CSS paints the first layer nearest the
|
|
2777
|
+
// viewer, so the reverse order lets the opaque white end of the
|
|
2778
|
+
// saturation ramp cover the black end of the value ramp: the
|
|
2779
|
+
// bottom-left corner displays white while selecting black.
|
|
2780
|
+
backgroundImage: "linear-gradient(to top, #000, transparent), linear-gradient(to right, #fff, transparent)"
|
|
2781
|
+
},
|
|
2782
|
+
onKeyDown: handleSurfaceKey,
|
|
2783
|
+
onPointerDown: (event) => {
|
|
2784
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
2785
|
+
trackPointer(event);
|
|
2786
|
+
},
|
|
2787
|
+
onPointerMove: (event) => {
|
|
2788
|
+
if (event.buttons === 1) trackPointer(event);
|
|
2789
|
+
},
|
|
2790
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2791
|
+
"span",
|
|
2792
|
+
{
|
|
2793
|
+
"aria-hidden": "true",
|
|
2794
|
+
className: "pointer-events-none absolute size-3 -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-white shadow-sm ring-1 ring-black/60",
|
|
2795
|
+
style: { left: `${handle.x * 100}%`, top: `${handle.y * 100}%` }
|
|
2796
|
+
}
|
|
2797
|
+
)
|
|
2715
2798
|
}
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
if (parsed) {
|
|
2732
|
-
setHsva(hsvaFrom(parsed, parsed.alpha, hsva.h));
|
|
2733
|
-
onColorChange(toHex(parsed, showAlpha ? parsed.alpha : 1));
|
|
2799
|
+
),
|
|
2800
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("label", { className: "sr-only", htmlFor: `${fieldId}-hue`, children: "Hue" }),
|
|
2801
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2802
|
+
"input",
|
|
2803
|
+
{
|
|
2804
|
+
id: `${fieldId}-hue`,
|
|
2805
|
+
type: "range",
|
|
2806
|
+
min: 0,
|
|
2807
|
+
max: HUE_MAX,
|
|
2808
|
+
step: 1,
|
|
2809
|
+
value: hueSliderValue(hsva.h, HUE_MAX),
|
|
2810
|
+
onChange: (event) => commit({ ...hsva, h: hueAt(+event.target.value / (HUE_MAX + 1)) }),
|
|
2811
|
+
className: SLIDER,
|
|
2812
|
+
style: {
|
|
2813
|
+
backgroundImage: "linear-gradient(to right, #f00, #ff0, #0f0, #0ff, #00f, #f0f, #f00)"
|
|
2734
2814
|
}
|
|
2735
|
-
},
|
|
2736
|
-
onBlur: () => setDraftHex(null)
|
|
2737
|
-
}
|
|
2738
|
-
),
|
|
2739
|
-
canPickFromScreen && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2740
|
-
Button,
|
|
2741
|
-
{
|
|
2742
|
-
type: "button",
|
|
2743
|
-
variant: "outline",
|
|
2744
|
-
size: "icon",
|
|
2745
|
-
"aria-label": "Pick a colour from the screen",
|
|
2746
|
-
onClick: () => void pickFromScreen(),
|
|
2747
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react12.Pipette, { className: "size-4" })
|
|
2748
|
-
}
|
|
2749
|
-
)
|
|
2750
|
-
] }),
|
|
2751
|
-
swatches.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { children: [
|
|
2752
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { className: "text-muted-foreground mb-1 text-xs", children: "Presets" }),
|
|
2753
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "flex flex-wrap gap-1", children: swatches.map((swatch) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2754
|
-
"button",
|
|
2755
|
-
{
|
|
2756
|
-
type: "button",
|
|
2757
|
-
title: swatch.label,
|
|
2758
|
-
"aria-label": swatch.label,
|
|
2759
|
-
className: "size-6 rounded border shadow-sm",
|
|
2760
|
-
style: { backgroundColor: swatch.color },
|
|
2761
|
-
onClick: () => onSwatchSelect?.(swatch)
|
|
2762
|
-
},
|
|
2763
|
-
swatch.id
|
|
2764
|
-
)) })
|
|
2765
|
-
] }),
|
|
2766
|
-
recentColors.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { children: [
|
|
2767
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { className: "text-muted-foreground mb-1 text-xs", children: "Recent" }),
|
|
2768
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "flex flex-wrap gap-1", children: recentColors.map((recent) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2769
|
-
"button",
|
|
2770
|
-
{
|
|
2771
|
-
type: "button",
|
|
2772
|
-
title: recent,
|
|
2773
|
-
"aria-label": recent,
|
|
2774
|
-
className: "size-6 rounded border shadow-sm",
|
|
2775
|
-
style: { backgroundColor: recent },
|
|
2776
|
-
onClick: () => {
|
|
2777
|
-
const parsed = parseHex(recent);
|
|
2778
|
-
if (parsed) commit(hsvaFrom(parsed, parsed.alpha, hsva.h));
|
|
2779
2815
|
}
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2816
|
+
),
|
|
2817
|
+
showAlpha && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
|
|
2818
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("label", { className: "sr-only", htmlFor: `${fieldId}-alpha`, children: "Opacity" }),
|
|
2819
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2820
|
+
"input",
|
|
2821
|
+
{
|
|
2822
|
+
id: `${fieldId}-alpha`,
|
|
2823
|
+
type: "range",
|
|
2824
|
+
min: 0,
|
|
2825
|
+
max: 100,
|
|
2826
|
+
step: 1,
|
|
2827
|
+
value: Math.round(hsva.a * 100),
|
|
2828
|
+
onChange: (event) => commit({ ...hsva, a: +event.target.value / 100 }),
|
|
2829
|
+
className: SLIDER,
|
|
2830
|
+
style: {
|
|
2831
|
+
// The ramp runs to the colour being edited, over a chequerboard,
|
|
2832
|
+
// so the track shows what the slider actually controls. Without
|
|
2833
|
+
// any background this rendered as a blank 12px strip whose only
|
|
2834
|
+
// label was screen-reader-only.
|
|
2835
|
+
backgroundImage: `linear-gradient(to right, transparent, ${toHexString({ ...hsva, a: 1 }, false)}), ${CHECKERBOARD}`,
|
|
2836
|
+
backgroundSize: "100% 100%, 8px 8px"
|
|
2837
|
+
}
|
|
2838
|
+
}
|
|
2839
|
+
)
|
|
2840
|
+
] }),
|
|
2841
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
2842
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("label", { className: "sr-only", htmlFor: `${fieldId}-hex`, children: "Hex colour" }),
|
|
2843
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2844
|
+
Input,
|
|
2845
|
+
{
|
|
2846
|
+
id: `${fieldId}-hex`,
|
|
2847
|
+
className: "font-mono",
|
|
2848
|
+
value: draftHex ?? rendered,
|
|
2849
|
+
onChange: (event) => {
|
|
2850
|
+
draftRef.current = event.target.value;
|
|
2851
|
+
setDraftHex(event.target.value);
|
|
2852
|
+
},
|
|
2853
|
+
onKeyDown: (event) => {
|
|
2854
|
+
if (event.key !== "Enter") return;
|
|
2855
|
+
if (event.nativeEvent.isComposing || event.keyCode === 229) return;
|
|
2856
|
+
event.preventDefault();
|
|
2857
|
+
commitDraft();
|
|
2858
|
+
}
|
|
2859
|
+
}
|
|
2860
|
+
),
|
|
2861
|
+
canPickFromScreen && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2862
|
+
Button,
|
|
2863
|
+
{
|
|
2864
|
+
type: "button",
|
|
2865
|
+
variant: "outline",
|
|
2866
|
+
size: "icon",
|
|
2867
|
+
"aria-label": "Pick a colour from the screen",
|
|
2868
|
+
onClick: () => void pickFromScreen(),
|
|
2869
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react12.Pipette, { className: "size-4" })
|
|
2870
|
+
}
|
|
2871
|
+
)
|
|
2872
|
+
] }),
|
|
2873
|
+
swatches.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { children: [
|
|
2874
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { className: "text-muted-foreground mb-1 text-xs", children: "Presets" }),
|
|
2875
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "flex flex-wrap gap-1", children: swatches.map((swatch) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2876
|
+
"button",
|
|
2877
|
+
{
|
|
2878
|
+
type: "button",
|
|
2879
|
+
title: swatch.label,
|
|
2880
|
+
"aria-label": swatch.label,
|
|
2881
|
+
className: "size-6 rounded border shadow-sm",
|
|
2882
|
+
style: { backgroundColor: swatch.color },
|
|
2883
|
+
onClick: () => {
|
|
2884
|
+
if (onSwatchSelect === void 0) return;
|
|
2885
|
+
dropDraft();
|
|
2886
|
+
onSwatchSelect(swatch);
|
|
2887
|
+
}
|
|
2888
|
+
},
|
|
2889
|
+
swatch.id
|
|
2890
|
+
)) })
|
|
2891
|
+
] }),
|
|
2892
|
+
recentColors.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { children: [
|
|
2893
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { className: "text-muted-foreground mb-1 text-xs", children: "Recent" }),
|
|
2894
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "flex flex-wrap gap-1", children: recentColors.map((recent) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
2895
|
+
"button",
|
|
2896
|
+
{
|
|
2897
|
+
type: "button",
|
|
2898
|
+
title: recent,
|
|
2899
|
+
"aria-label": recent,
|
|
2900
|
+
className: "size-6 rounded border shadow-sm",
|
|
2901
|
+
style: { backgroundColor: recent },
|
|
2902
|
+
onClick: () => {
|
|
2903
|
+
const parsed = parseHex(recent);
|
|
2904
|
+
if (parsed) commit(hsvaFrom(parsed, parsed.alpha, hsva.h));
|
|
2905
|
+
}
|
|
2906
|
+
},
|
|
2907
|
+
recent
|
|
2908
|
+
)) })
|
|
2909
|
+
] })
|
|
2910
|
+
]
|
|
2911
|
+
}
|
|
2912
|
+
);
|
|
2785
2913
|
}
|
|
2786
2914
|
|
|
2787
2915
|
// src/components/context-menu.tsx
|
|
2788
2916
|
var ContextMenuPrimitive = __toESM(require("@radix-ui/react-context-menu"), 1);
|
|
2789
2917
|
var import_lucide_react13 = require("lucide-react");
|
|
2790
|
-
var
|
|
2918
|
+
var React11 = __toESM(require("react"), 1);
|
|
2791
2919
|
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
2792
2920
|
var menuItemBase2 = "cursor-pointer transition-colors data-[highlighted]:bg-muted data-[highlighted]:text-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50";
|
|
2793
2921
|
var menuSurface = "z-50 max-h-[var(--radix-context-menu-content-available-height)] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-lg border border-border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 origin-[--radix-context-menu-content-transform-origin]";
|
|
@@ -2796,7 +2924,7 @@ var ContextMenuTrigger = ContextMenuPrimitive.Trigger;
|
|
|
2796
2924
|
var ContextMenuGroup = ContextMenuPrimitive.Group;
|
|
2797
2925
|
var ContextMenuSub = ContextMenuPrimitive.Sub;
|
|
2798
2926
|
var ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup;
|
|
2799
|
-
var ContextMenuSubTrigger =
|
|
2927
|
+
var ContextMenuSubTrigger = React11.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
2800
2928
|
ContextMenuPrimitive.SubTrigger,
|
|
2801
2929
|
{
|
|
2802
2930
|
ref,
|
|
@@ -2814,7 +2942,7 @@ var ContextMenuSubTrigger = React10.forwardRef(({ className, inset, children, ..
|
|
|
2814
2942
|
}
|
|
2815
2943
|
));
|
|
2816
2944
|
ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName;
|
|
2817
|
-
var ContextMenuSubContent =
|
|
2945
|
+
var ContextMenuSubContent = React11.forwardRef(({ className, ...props }, ref) => {
|
|
2818
2946
|
const portalContainer = usePortalContainer();
|
|
2819
2947
|
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(ContextMenuPrimitive.Portal, { container: portalContainer, children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
2820
2948
|
ContextMenuPrimitive.SubContent,
|
|
@@ -2826,7 +2954,7 @@ var ContextMenuSubContent = React10.forwardRef(({ className, ...props }, ref) =>
|
|
|
2826
2954
|
) });
|
|
2827
2955
|
});
|
|
2828
2956
|
ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName;
|
|
2829
|
-
var ContextMenuContent =
|
|
2957
|
+
var ContextMenuContent = React11.forwardRef(({ className, ...props }, ref) => {
|
|
2830
2958
|
const portalContainer = usePortalContainer();
|
|
2831
2959
|
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(ContextMenuPrimitive.Portal, { container: portalContainer, children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
2832
2960
|
ContextMenuPrimitive.Content,
|
|
@@ -2838,7 +2966,7 @@ var ContextMenuContent = React10.forwardRef(({ className, ...props }, ref) => {
|
|
|
2838
2966
|
) });
|
|
2839
2967
|
});
|
|
2840
2968
|
ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName;
|
|
2841
|
-
var ContextMenuItem =
|
|
2969
|
+
var ContextMenuItem = React11.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
2842
2970
|
ContextMenuPrimitive.Item,
|
|
2843
2971
|
{
|
|
2844
2972
|
ref,
|
|
@@ -2852,7 +2980,7 @@ var ContextMenuItem = React10.forwardRef(({ className, inset, ...props }, ref) =
|
|
|
2852
2980
|
}
|
|
2853
2981
|
));
|
|
2854
2982
|
ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName;
|
|
2855
|
-
var ContextMenuCheckboxItem =
|
|
2983
|
+
var ContextMenuCheckboxItem = React11.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
2856
2984
|
ContextMenuPrimitive.CheckboxItem,
|
|
2857
2985
|
{
|
|
2858
2986
|
ref,
|
|
@@ -2870,7 +2998,7 @@ var ContextMenuCheckboxItem = React10.forwardRef(({ className, children, checked
|
|
|
2870
2998
|
}
|
|
2871
2999
|
));
|
|
2872
3000
|
ContextMenuCheckboxItem.displayName = ContextMenuPrimitive.CheckboxItem.displayName;
|
|
2873
|
-
var ContextMenuRadioItem =
|
|
3001
|
+
var ContextMenuRadioItem = React11.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
2874
3002
|
ContextMenuPrimitive.RadioItem,
|
|
2875
3003
|
{
|
|
2876
3004
|
ref,
|
|
@@ -2887,7 +3015,7 @@ var ContextMenuRadioItem = React10.forwardRef(({ className, children, ...props }
|
|
|
2887
3015
|
}
|
|
2888
3016
|
));
|
|
2889
3017
|
ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName;
|
|
2890
|
-
var ContextMenuLabel =
|
|
3018
|
+
var ContextMenuLabel = React11.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
2891
3019
|
ContextMenuPrimitive.Label,
|
|
2892
3020
|
{
|
|
2893
3021
|
ref,
|
|
@@ -2900,7 +3028,7 @@ var ContextMenuLabel = React10.forwardRef(({ className, inset, ...props }, ref)
|
|
|
2900
3028
|
}
|
|
2901
3029
|
));
|
|
2902
3030
|
ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName;
|
|
2903
|
-
var ContextMenuSeparator =
|
|
3031
|
+
var ContextMenuSeparator = React11.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
2904
3032
|
ContextMenuPrimitive.Separator,
|
|
2905
3033
|
{
|
|
2906
3034
|
ref,
|
|
@@ -2973,7 +3101,7 @@ var ResizableHandle = ({
|
|
|
2973
3101
|
// src/components/tree-view.tsx
|
|
2974
3102
|
var import_react_virtual = require("@tanstack/react-virtual");
|
|
2975
3103
|
var import_lucide_react15 = require("lucide-react");
|
|
2976
|
-
var
|
|
3104
|
+
var React12 = __toESM(require("react"), 1);
|
|
2977
3105
|
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
2978
3106
|
var ROW_HEIGHT = 28;
|
|
2979
3107
|
var INDENT_PER_LEVEL = 12;
|
|
@@ -3015,19 +3143,28 @@ function flatten(nodes, expanded) {
|
|
|
3015
3143
|
return rows;
|
|
3016
3144
|
}
|
|
3017
3145
|
function useControllable(controlled, fallback) {
|
|
3018
|
-
const [uncontrolled, setUncontrolled] =
|
|
3146
|
+
const [uncontrolled, setUncontrolled] = React12.useState(fallback);
|
|
3019
3147
|
return [
|
|
3020
3148
|
controlled === void 0 ? uncontrolled : controlled,
|
|
3021
3149
|
setUncontrolled
|
|
3022
3150
|
];
|
|
3023
3151
|
}
|
|
3024
|
-
|
|
3152
|
+
function treeSelectionMode(modifiers) {
|
|
3153
|
+
if (modifiers.shiftKey) return "extend";
|
|
3154
|
+
if (modifiers.metaKey || modifiers.ctrlKey) return "toggle";
|
|
3155
|
+
return "replace";
|
|
3156
|
+
}
|
|
3157
|
+
function isRowSelected(id, primary, selectedIds) {
|
|
3158
|
+
return selectedIds === void 0 ? primary === id : selectedIds.includes(id);
|
|
3159
|
+
}
|
|
3160
|
+
var TreeView = React12.forwardRef(
|
|
3025
3161
|
({
|
|
3026
3162
|
nodes,
|
|
3027
3163
|
expandedIds,
|
|
3028
3164
|
defaultExpandedIds,
|
|
3029
3165
|
onExpandedChange,
|
|
3030
3166
|
selectedId,
|
|
3167
|
+
selectedIds,
|
|
3031
3168
|
defaultSelectedId,
|
|
3032
3169
|
onSelectedChange,
|
|
3033
3170
|
className,
|
|
@@ -3036,8 +3173,8 @@ var TreeView = React11.forwardRef(
|
|
|
3036
3173
|
"aria-describedby": ariaDescribedBy,
|
|
3037
3174
|
...props
|
|
3038
3175
|
}, forwardedRef) => {
|
|
3039
|
-
const scrollRef =
|
|
3040
|
-
const attachScroll =
|
|
3176
|
+
const scrollRef = React12.useRef(null);
|
|
3177
|
+
const attachScroll = React12.useCallback(
|
|
3041
3178
|
(node) => {
|
|
3042
3179
|
scrollRef.current = node;
|
|
3043
3180
|
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
@@ -3051,7 +3188,7 @@ var TreeView = React11.forwardRef(
|
|
|
3051
3188
|
expandedIds === void 0 ? void 0 : [...expandedIds],
|
|
3052
3189
|
[...defaultExpandedIds ?? []]
|
|
3053
3190
|
);
|
|
3054
|
-
const expanded =
|
|
3191
|
+
const expanded = React12.useMemo(
|
|
3055
3192
|
() => new Set(expandedIds ?? expandedState),
|
|
3056
3193
|
[expandedIds, expandedState]
|
|
3057
3194
|
);
|
|
@@ -3059,11 +3196,11 @@ var TreeView = React11.forwardRef(
|
|
|
3059
3196
|
selectedId === void 0 ? void 0 : selectedId,
|
|
3060
3197
|
defaultSelectedId ?? null
|
|
3061
3198
|
);
|
|
3062
|
-
const rows =
|
|
3199
|
+
const rows = React12.useMemo(
|
|
3063
3200
|
() => flatten(nodes, expanded),
|
|
3064
3201
|
[nodes, expanded]
|
|
3065
3202
|
);
|
|
3066
|
-
const [activeId, setActiveId] =
|
|
3203
|
+
const [activeId, setActiveId] = React12.useState(null);
|
|
3067
3204
|
const activeIndex = Math.max(
|
|
3068
3205
|
0,
|
|
3069
3206
|
rows.findIndex((row) => row.node.id === (activeId ?? selected))
|
|
@@ -3085,9 +3222,9 @@ var TreeView = React11.forwardRef(
|
|
|
3085
3222
|
else next.delete(id);
|
|
3086
3223
|
commitExpanded(next);
|
|
3087
3224
|
};
|
|
3088
|
-
const choose = (id) => {
|
|
3225
|
+
const choose = (id, mode = "replace") => {
|
|
3089
3226
|
if (selectedId === void 0) setSelected(id);
|
|
3090
|
-
onSelectedChange?.(id);
|
|
3227
|
+
onSelectedChange?.(id, mode);
|
|
3091
3228
|
};
|
|
3092
3229
|
const focusRow = (index) => {
|
|
3093
3230
|
const row = rows[index];
|
|
@@ -3107,11 +3244,12 @@ var TreeView = React11.forwardRef(
|
|
|
3107
3244
|
}
|
|
3108
3245
|
return from;
|
|
3109
3246
|
};
|
|
3110
|
-
const typeahead =
|
|
3247
|
+
const typeahead = React12.useRef({ query: "", at: 0 });
|
|
3111
3248
|
const onKeyDown = (event) => {
|
|
3112
3249
|
const index = activeIndex;
|
|
3113
3250
|
const row = rows[index];
|
|
3114
3251
|
if (row === void 0) return;
|
|
3252
|
+
if (event.altKey) return;
|
|
3115
3253
|
switch (event.key) {
|
|
3116
3254
|
case "ArrowDown":
|
|
3117
3255
|
event.preventDefault();
|
|
@@ -3166,7 +3304,9 @@ var TreeView = React11.forwardRef(
|
|
|
3166
3304
|
case "Enter":
|
|
3167
3305
|
case " ":
|
|
3168
3306
|
event.preventDefault();
|
|
3169
|
-
if (row.node.disabled !== true)
|
|
3307
|
+
if (row.node.disabled !== true) {
|
|
3308
|
+
choose(row.node.id, treeSelectionMode(event));
|
|
3309
|
+
}
|
|
3170
3310
|
return;
|
|
3171
3311
|
case "*": {
|
|
3172
3312
|
event.preventDefault();
|
|
@@ -3214,6 +3354,7 @@ var TreeView = React11.forwardRef(
|
|
|
3214
3354
|
"div",
|
|
3215
3355
|
{
|
|
3216
3356
|
role: "tree",
|
|
3357
|
+
"aria-multiselectable": selectedIds === void 0 ? void 0 : true,
|
|
3217
3358
|
"aria-label": ariaLabel,
|
|
3218
3359
|
"aria-labelledby": ariaLabelledBy,
|
|
3219
3360
|
"aria-describedby": ariaDescribedBy,
|
|
@@ -3222,7 +3363,12 @@ var TreeView = React11.forwardRef(
|
|
|
3222
3363
|
children: virtualItems.map((item) => {
|
|
3223
3364
|
const row = rows[item.index];
|
|
3224
3365
|
if (row === void 0) return null;
|
|
3225
|
-
const isSelected =
|
|
3366
|
+
const isSelected = isRowSelected(
|
|
3367
|
+
row.node.id,
|
|
3368
|
+
selected,
|
|
3369
|
+
selectedIds
|
|
3370
|
+
);
|
|
3371
|
+
const isPrimary = selected === row.node.id;
|
|
3226
3372
|
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
|
|
3227
3373
|
"div",
|
|
3228
3374
|
{
|
|
@@ -3236,16 +3382,21 @@ var TreeView = React11.forwardRef(
|
|
|
3236
3382
|
"aria-disabled": row.node.disabled === true ? true : void 0,
|
|
3237
3383
|
tabIndex: item.index === tabStopIndex ? 0 : -1,
|
|
3238
3384
|
onFocus: () => setActiveId(row.node.id),
|
|
3239
|
-
onClick: () => {
|
|
3385
|
+
onClick: (event) => {
|
|
3240
3386
|
if (row.node.disabled === true) return;
|
|
3241
3387
|
setActiveId(row.node.id);
|
|
3242
|
-
choose(row.node.id);
|
|
3388
|
+
choose(row.node.id, treeSelectionMode(event));
|
|
3243
3389
|
},
|
|
3244
3390
|
className: cn(
|
|
3245
3391
|
"absolute left-0 flex w-full select-none items-center gap-1 rounded-sm pr-2 text-sm outline-none",
|
|
3246
3392
|
"focus-visible:ring-1 focus-visible:ring-ring",
|
|
3247
3393
|
row.node.disabled === true ? "pointer-events-none opacity-50" : "cursor-pointer",
|
|
3248
|
-
isSelected ? "bg-muted text-foreground" : "hover:bg-muted/50"
|
|
3394
|
+
isSelected ? "bg-muted text-foreground" : "hover:bg-muted/50",
|
|
3395
|
+
// WEIGHT, not a second colour. Every row here is selected and
|
|
3396
|
+
// an action applies to all of them; what a reader needs is
|
|
3397
|
+
// which one the detail panel describes, and a second colour
|
|
3398
|
+
// would have to mean a second kind of selected.
|
|
3399
|
+
isSelected && isPrimary && "font-medium"
|
|
3249
3400
|
),
|
|
3250
3401
|
style: {
|
|
3251
3402
|
height: item.size,
|
|
@@ -3291,7 +3442,7 @@ TreeView.displayName = "TreeView";
|
|
|
3291
3442
|
|
|
3292
3443
|
// src/components/slider.tsx
|
|
3293
3444
|
var SliderPrimitive = __toESM(require("@radix-ui/react-slider"), 1);
|
|
3294
|
-
var
|
|
3445
|
+
var React13 = __toESM(require("react"), 1);
|
|
3295
3446
|
|
|
3296
3447
|
// src/lib/dev-warn.ts
|
|
3297
3448
|
var emitted = /* @__PURE__ */ new Set();
|
|
@@ -3322,7 +3473,7 @@ function thumbCount(value, defaultValue) {
|
|
|
3322
3473
|
function hasAccessibleName(value) {
|
|
3323
3474
|
return value !== void 0 && value.trim() !== "";
|
|
3324
3475
|
}
|
|
3325
|
-
var Slider =
|
|
3476
|
+
var Slider = React13.forwardRef(
|
|
3326
3477
|
({
|
|
3327
3478
|
className,
|
|
3328
3479
|
value,
|
|
@@ -3333,7 +3484,7 @@ var Slider = React12.forwardRef(
|
|
|
3333
3484
|
"aria-labelledby": ariaLabelledBy,
|
|
3334
3485
|
...props
|
|
3335
3486
|
}, ref) => {
|
|
3336
|
-
const initialUncontrolledCount =
|
|
3487
|
+
const initialUncontrolledCount = React13.useRef(
|
|
3337
3488
|
thumbCount(void 0, defaultValue)
|
|
3338
3489
|
).current;
|
|
3339
3490
|
const count = value?.length ?? initialUncontrolledCount;
|
|
@@ -3442,7 +3593,7 @@ var Slider = React12.forwardRef(
|
|
|
3442
3593
|
Slider.displayName = SliderPrimitive.Root.displayName;
|
|
3443
3594
|
|
|
3444
3595
|
// src/lib/shortcuts/react.tsx
|
|
3445
|
-
var
|
|
3596
|
+
var React14 = __toESM(require("react"), 1);
|
|
3446
3597
|
|
|
3447
3598
|
// src/lib/shortcuts/key-spec.ts
|
|
3448
3599
|
function normalizeKey(key) {
|
|
@@ -3971,9 +4122,8 @@ var FIELD_KEYS = /* @__PURE__ */ new Set([
|
|
|
3971
4122
|
|
|
3972
4123
|
// src/lib/shortcuts/react.tsx
|
|
3973
4124
|
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
3974
|
-
var ShortcutContext =
|
|
4125
|
+
var ShortcutContext = React14.createContext(null);
|
|
3975
4126
|
var ownersByTarget = /* @__PURE__ */ new WeakMap();
|
|
3976
|
-
var useIsomorphicLayoutEffect = typeof document === "undefined" ? React13.useEffect : React13.useLayoutEffect;
|
|
3977
4127
|
function optionsFingerprint(options) {
|
|
3978
4128
|
return [
|
|
3979
4129
|
options.isApple ?? "auto",
|
|
@@ -3986,13 +4136,13 @@ function ShortcutProvider({
|
|
|
3986
4136
|
target,
|
|
3987
4137
|
...managerOptions
|
|
3988
4138
|
}) {
|
|
3989
|
-
const parent =
|
|
4139
|
+
const parent = React14.useContext(ShortcutContext);
|
|
3990
4140
|
const resolvedTarget = target === null ? null : target ?? (typeof document === "undefined" ? null : document);
|
|
3991
4141
|
const nestedOnSameTarget = parent !== null && parent.target === resolvedTarget;
|
|
3992
|
-
const optionsRef =
|
|
3993
|
-
const ownManagers =
|
|
3994
|
-
const ownDetached =
|
|
3995
|
-
const detached =
|
|
4142
|
+
const optionsRef = React14.useRef(managerOptions);
|
|
4143
|
+
const ownManagers = React14.useRef(/* @__PURE__ */ new WeakMap());
|
|
4144
|
+
const ownDetached = React14.useRef(null);
|
|
4145
|
+
const detached = React14.useMemo(() => {
|
|
3996
4146
|
if (resolvedTarget === null) {
|
|
3997
4147
|
ownDetached.current ??= createShortcutManager(optionsRef.current);
|
|
3998
4148
|
return ownDetached.current;
|
|
@@ -4048,7 +4198,7 @@ function ShortcutProvider({
|
|
|
4048
4198
|
};
|
|
4049
4199
|
}, [resolvedTarget, manager]);
|
|
4050
4200
|
const depth = nestedOnSameTarget && parent ? parent.depth : 0;
|
|
4051
|
-
const value =
|
|
4201
|
+
const value = React14.useMemo(
|
|
4052
4202
|
() => ({ manager, depth, target: resolvedTarget, options: fingerprint }),
|
|
4053
4203
|
[manager, depth, resolvedTarget, fingerprint]
|
|
4054
4204
|
);
|
|
@@ -4057,11 +4207,11 @@ function ShortcutProvider({
|
|
|
4057
4207
|
function ShortcutScope({
|
|
4058
4208
|
children
|
|
4059
4209
|
}) {
|
|
4060
|
-
const parent =
|
|
4210
|
+
const parent = React14.useContext(ShortcutContext);
|
|
4061
4211
|
if (!parent) {
|
|
4062
4212
|
throw new Error("ShortcutScope must be rendered inside a ShortcutProvider");
|
|
4063
4213
|
}
|
|
4064
|
-
const value =
|
|
4214
|
+
const value = React14.useMemo(
|
|
4065
4215
|
() => ({
|
|
4066
4216
|
manager: parent.manager,
|
|
4067
4217
|
depth: parent.depth + 1,
|
|
@@ -4075,13 +4225,13 @@ function ShortcutScope({
|
|
|
4075
4225
|
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(ShortcutContext.Provider, { value, children });
|
|
4076
4226
|
}
|
|
4077
4227
|
function useShortcuts(bindings, options) {
|
|
4078
|
-
const context =
|
|
4228
|
+
const context = React14.useContext(ShortcutContext);
|
|
4079
4229
|
if (!context) {
|
|
4080
4230
|
throw new Error("useShortcuts must be called inside a ShortcutProvider");
|
|
4081
4231
|
}
|
|
4082
4232
|
const { manager, depth } = context;
|
|
4083
|
-
const registration =
|
|
4084
|
-
const latest =
|
|
4233
|
+
const registration = React14.useRef(null);
|
|
4234
|
+
const latest = React14.useRef({ bindings, options });
|
|
4085
4235
|
useIsomorphicLayoutEffect(() => {
|
|
4086
4236
|
registration.current = manager.register([], {
|
|
4087
4237
|
name: latest.current.options.name,
|
|
@@ -4104,7 +4254,7 @@ function useShortcuts(bindings, options) {
|
|
|
4104
4254
|
});
|
|
4105
4255
|
}
|
|
4106
4256
|
function useShortcutManager() {
|
|
4107
|
-
const context =
|
|
4257
|
+
const context = React14.useContext(ShortcutContext);
|
|
4108
4258
|
if (!context) {
|
|
4109
4259
|
throw new Error(
|
|
4110
4260
|
"useShortcutManager must be called inside a ShortcutProvider"
|
|
@@ -4114,7 +4264,7 @@ function useShortcutManager() {
|
|
|
4114
4264
|
}
|
|
4115
4265
|
function useActiveShortcuts() {
|
|
4116
4266
|
const manager = useShortcutManager();
|
|
4117
|
-
return
|
|
4267
|
+
return React14.useSyncExternalStore(
|
|
4118
4268
|
manager.subscribe,
|
|
4119
4269
|
manager.activeBindings,
|
|
4120
4270
|
manager.activeBindings
|
|
@@ -4241,29 +4391,12 @@ function FormSection({
|
|
|
4241
4391
|
),
|
|
4242
4392
|
description ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("p", { className: "text-sm text-muted-foreground", children: description }) : null
|
|
4243
4393
|
] }),
|
|
4244
|
-
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Card, { className: "overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "divide-y divide-foreground/10 px-6", children }) })
|
|
4394
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Card, { className: "overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "nx-form-section-rows divide-y divide-foreground/10 px-6", children }) })
|
|
4245
4395
|
] });
|
|
4246
4396
|
}
|
|
4247
4397
|
|
|
4248
|
-
// src/components/form-
|
|
4249
|
-
var import_class_variance_authority14 = require("class-variance-authority");
|
|
4398
|
+
// src/components/form-actions.tsx
|
|
4250
4399
|
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
4251
|
-
var measure = (0, import_class_variance_authority14.cva)("mx-auto w-full px-6 py-8", {
|
|
4252
|
-
variants: {
|
|
4253
|
-
width: {
|
|
4254
|
-
form: "max-w-[56rem]",
|
|
4255
|
-
wide: "max-w-[72rem]"
|
|
4256
|
-
}
|
|
4257
|
-
},
|
|
4258
|
-
defaultVariants: { width: "form" }
|
|
4259
|
-
});
|
|
4260
|
-
function FormLayout({
|
|
4261
|
-
width = "form",
|
|
4262
|
-
className,
|
|
4263
|
-
children
|
|
4264
|
-
}) {
|
|
4265
|
-
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: cn(measure({ width }), className), children });
|
|
4266
|
-
}
|
|
4267
4400
|
function FormActions({ dirty, className, children }) {
|
|
4268
4401
|
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
4269
4402
|
"div",
|
|
@@ -4286,6 +4419,120 @@ function FormActions({ dirty, className, children }) {
|
|
|
4286
4419
|
}
|
|
4287
4420
|
);
|
|
4288
4421
|
}
|
|
4422
|
+
|
|
4423
|
+
// src/components/page-shell.tsx
|
|
4424
|
+
var import_react21 = require("react");
|
|
4425
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
4426
|
+
function hasBareTextChild(shell) {
|
|
4427
|
+
return Array.from(shell.childNodes).some(
|
|
4428
|
+
(node) => node.nodeType === Node.TEXT_NODE && node.textContent?.trim() !== ""
|
|
4429
|
+
);
|
|
4430
|
+
}
|
|
4431
|
+
var InsideShell = (0, import_react21.createContext)(false);
|
|
4432
|
+
function hasDisplayContentsChild(shell) {
|
|
4433
|
+
return Array.from(shell.children).some(
|
|
4434
|
+
(child) => getComputedStyle(child).display === "contents"
|
|
4435
|
+
);
|
|
4436
|
+
}
|
|
4437
|
+
var SHELL_MEASURE = {
|
|
4438
|
+
form: "var(--nx-measure-form)",
|
|
4439
|
+
wide: "var(--nx-measure-wide)",
|
|
4440
|
+
full: "100%"
|
|
4441
|
+
};
|
|
4442
|
+
var PageShell = (0, import_react21.forwardRef)(
|
|
4443
|
+
({ width = "form", className, children, style, ...props }, ref) => {
|
|
4444
|
+
const shellRef = (0, import_react21.useRef)(null);
|
|
4445
|
+
const attachRef = (0, import_react21.useCallback)(
|
|
4446
|
+
(node) => {
|
|
4447
|
+
shellRef.current = node;
|
|
4448
|
+
if (typeof ref === "function") return ref(node);
|
|
4449
|
+
if (ref) ref.current = node;
|
|
4450
|
+
},
|
|
4451
|
+
[ref]
|
|
4452
|
+
);
|
|
4453
|
+
const nested = (0, import_react21.useContext)(InsideShell);
|
|
4454
|
+
(0, import_react21.useEffect)(() => {
|
|
4455
|
+
if (!isDevelopmentRuntime()) return;
|
|
4456
|
+
const shell = shellRef.current;
|
|
4457
|
+
if (!shell) return;
|
|
4458
|
+
devWarnOnce(
|
|
4459
|
+
!nested,
|
|
4460
|
+
"PageShell: an ancestor already renders a PageShell. The two grids each add a pair of gutter tracks, so this page's content is inset twice. Remove this shell, or move the outer one."
|
|
4461
|
+
);
|
|
4462
|
+
const check = () => {
|
|
4463
|
+
devWarnOnce(
|
|
4464
|
+
!hasBareTextChild(shell),
|
|
4465
|
+
"PageShell: a direct child renders as bare text. CSS Grid wraps it in an anonymous grid item, which no selector can reach, so it is placed in the gutter rather than the content column and sits outside the page's measure. Wrap it in an element \u2014 a `<p>`, or the section it belongs to."
|
|
4466
|
+
);
|
|
4467
|
+
devWarnOnce(
|
|
4468
|
+
!hasDisplayContentsChild(shell),
|
|
4469
|
+
"PageShell: a direct child has `display: contents`, so it generates no grid item and the content-column rule has nothing to apply to. Its own children are promoted into this grid, match no selector, and are placed from the gutter onward. Give the child a box, or move `display: contents` inside it."
|
|
4470
|
+
);
|
|
4471
|
+
};
|
|
4472
|
+
check();
|
|
4473
|
+
const observer = new MutationObserver(check);
|
|
4474
|
+
observer.observe(shell, { childList: true });
|
|
4475
|
+
return () => {
|
|
4476
|
+
observer.disconnect();
|
|
4477
|
+
};
|
|
4478
|
+
});
|
|
4479
|
+
const shellStyle = {
|
|
4480
|
+
...style,
|
|
4481
|
+
"--nx-shell-measure": SHELL_MEASURE[width]
|
|
4482
|
+
};
|
|
4483
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(InsideShell.Provider, { value: true, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
4484
|
+
"div",
|
|
4485
|
+
{
|
|
4486
|
+
ref: attachRef,
|
|
4487
|
+
"data-slot": "page-shell",
|
|
4488
|
+
style: shellStyle,
|
|
4489
|
+
className: cn("nx-page-shell py-8", className),
|
|
4490
|
+
...props,
|
|
4491
|
+
children
|
|
4492
|
+
}
|
|
4493
|
+
) });
|
|
4494
|
+
}
|
|
4495
|
+
);
|
|
4496
|
+
PageShell.displayName = "PageShell";
|
|
4497
|
+
var Bleed = (0, import_react21.forwardRef)(
|
|
4498
|
+
({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
4499
|
+
"div",
|
|
4500
|
+
{
|
|
4501
|
+
ref,
|
|
4502
|
+
"data-slot": "bleed",
|
|
4503
|
+
className: cn("nx-bleed", className),
|
|
4504
|
+
...props,
|
|
4505
|
+
children
|
|
4506
|
+
}
|
|
4507
|
+
)
|
|
4508
|
+
);
|
|
4509
|
+
Bleed.displayName = "Bleed";
|
|
4510
|
+
|
|
4511
|
+
// src/components/page-header.tsx
|
|
4512
|
+
var import_react22 = require("react");
|
|
4513
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
4514
|
+
var PageHeader = (0, import_react22.forwardRef)(
|
|
4515
|
+
({ title, description, breadcrumbs, actions, className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
|
|
4516
|
+
"header",
|
|
4517
|
+
{
|
|
4518
|
+
ref,
|
|
4519
|
+
"data-slot": "page-header",
|
|
4520
|
+
className: cn("mb-8", className),
|
|
4521
|
+
...props,
|
|
4522
|
+
children: [
|
|
4523
|
+
breadcrumbs ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "mb-6", children: breadcrumbs }) : null,
|
|
4524
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex flex-col justify-between gap-4 sm:flex-row sm:items-center", children: [
|
|
4525
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "space-y-1", children: [
|
|
4526
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("h1", { className: "text-xl font-semibold tracking-tight", children: title }),
|
|
4527
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("p", { className: "mt-1 text-sm font-normal text-muted-foreground", children: description }) : null
|
|
4528
|
+
] }),
|
|
4529
|
+
actions ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "flex items-center gap-3", children: actions }) : null
|
|
4530
|
+
] })
|
|
4531
|
+
]
|
|
4532
|
+
}
|
|
4533
|
+
)
|
|
4534
|
+
);
|
|
4535
|
+
PageHeader.displayName = "PageHeader";
|
|
4289
4536
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4290
4537
|
0 && (module.exports = {
|
|
4291
4538
|
Accordion,
|
|
@@ -4310,6 +4557,7 @@ function FormActions({ dirty, className, children }) {
|
|
|
4310
4557
|
AvatarFallback,
|
|
4311
4558
|
AvatarImage,
|
|
4312
4559
|
Badge,
|
|
4560
|
+
Bleed,
|
|
4313
4561
|
Button,
|
|
4314
4562
|
Card,
|
|
4315
4563
|
CardAction,
|
|
@@ -4374,11 +4622,12 @@ function FormActions({ dirty, className, children }) {
|
|
|
4374
4622
|
FieldShell,
|
|
4375
4623
|
FormActions,
|
|
4376
4624
|
FormLabelWithTooltip,
|
|
4377
|
-
FormLayout,
|
|
4378
4625
|
FormSection,
|
|
4379
4626
|
Grid,
|
|
4380
4627
|
Input,
|
|
4381
4628
|
Label,
|
|
4629
|
+
PageHeader,
|
|
4630
|
+
PageShell,
|
|
4382
4631
|
Popover,
|
|
4383
4632
|
PopoverAnchor,
|
|
4384
4633
|
PopoverContent,
|
|
@@ -4390,6 +4639,7 @@ function FormActions({ dirty, className, children }) {
|
|
|
4390
4639
|
ResizableHandle,
|
|
4391
4640
|
ResizablePanel,
|
|
4392
4641
|
ResizablePanelGroup,
|
|
4642
|
+
SHELL_MEASURE,
|
|
4393
4643
|
Select,
|
|
4394
4644
|
SelectContent,
|
|
4395
4645
|
SelectGroup,
|
|
@@ -4448,8 +4698,10 @@ function FormActions({ dirty, className, children }) {
|
|
|
4448
4698
|
badgeVariants,
|
|
4449
4699
|
buttonVariants,
|
|
4450
4700
|
cardVariants,
|
|
4701
|
+
chordMatches,
|
|
4451
4702
|
commandDefaultFilter,
|
|
4452
4703
|
createShortcutManager,
|
|
4704
|
+
detectApplePlatform,
|
|
4453
4705
|
dialogContentVariants,
|
|
4454
4706
|
inputVariants,
|
|
4455
4707
|
parseKeys,
|
|
@@ -4459,6 +4711,8 @@ function FormActions({ dirty, className, children }) {
|
|
|
4459
4711
|
spinnerVariants,
|
|
4460
4712
|
toast,
|
|
4461
4713
|
useActiveShortcuts,
|
|
4714
|
+
useCommandHighlight,
|
|
4715
|
+
useIsomorphicLayoutEffect,
|
|
4462
4716
|
usePortalContainer,
|
|
4463
4717
|
useShortcutManager,
|
|
4464
4718
|
useShortcuts
|