@nocoo/basalt 2.0.2 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +134 -15
- package/ai/COMPATIBILITY.md +180 -0
- package/ai/INTEGRATION.md +1760 -0
- package/ai/RECIPES.md +161 -0
- package/ai/USAGE.md +99 -0
- package/ai/registry.json +38099 -0
- package/ai/sources.json +10 -0
- package/dist/assets/brand-mark.d.ts +1 -0
- package/dist/assets/brand-mark.js +7 -0
- package/dist/assets/brand-mark.js.map +1 -0
- package/dist/charts/area.d.ts +58 -5
- package/dist/charts/area.js +20 -12
- package/dist/charts/area.js.map +1 -1
- package/dist/charts/bar.d.ts +54 -5
- package/dist/charts/bar.js +16 -10
- package/dist/charts/bar.js.map +1 -1
- package/dist/charts/bullet.d.ts +18 -1
- package/dist/charts/bullet.js +6 -3
- package/dist/charts/bullet.js.map +1 -1
- package/dist/charts/charts.d.ts +58 -5
- package/dist/charts/charts.js +13 -2
- package/dist/charts/charts.js.map +1 -1
- package/dist/charts/config.d.ts +7 -0
- package/dist/charts/config.js +5 -1
- package/dist/charts/config.js.map +1 -1
- package/dist/charts/custom-chart.d.ts +58 -5
- package/dist/charts/custom-chart.js +13 -2
- package/dist/charts/custom-chart.js.map +1 -1
- package/dist/charts/donut.d.ts +18 -1
- package/dist/charts/donut.js +6 -3
- package/dist/charts/donut.js.map +1 -1
- package/dist/charts/frame.d.ts +40 -3
- package/dist/charts/frame.js +55 -28
- package/dist/charts/frame.js.map +1 -1
- package/dist/charts/funnel.d.ts +18 -1
- package/dist/charts/funnel.js +5 -1
- package/dist/charts/funnel.js.map +1 -1
- package/dist/charts/gauge.d.ts +18 -1
- package/dist/charts/gauge.js +38 -20
- package/dist/charts/gauge.js.map +1 -1
- package/dist/charts/grouped-bar.d.ts +54 -5
- package/dist/charts/grouped-bar.js +16 -10
- package/dist/charts/grouped-bar.js.map +1 -1
- package/dist/charts/heatmap-calendar.d.ts +61 -0
- package/dist/charts/heatmap-calendar.js +287 -96
- package/dist/charts/heatmap-calendar.js.map +1 -1
- package/dist/charts/heatmap-matrix.d.ts +99 -0
- package/dist/charts/heatmap-matrix.js +249 -0
- package/dist/charts/heatmap-matrix.js.map +1 -0
- package/dist/charts/line.d.ts +66 -5
- package/dist/charts/line.js +37 -30
- package/dist/charts/line.js.map +1 -1
- package/dist/charts/palette.d.ts +1 -0
- package/dist/charts/palette.js +7 -1
- package/dist/charts/palette.js.map +1 -1
- package/dist/charts/radar.d.ts +18 -1
- package/dist/charts/radar.js +26 -19
- package/dist/charts/radar.js.map +1 -1
- package/dist/charts/sankey.d.ts +18 -1
- package/dist/charts/sankey.js +4 -1
- package/dist/charts/sankey.js.map +1 -1
- package/dist/charts/series.d.ts +5 -7
- package/dist/charts/series.js.map +1 -1
- package/dist/charts/slot-bar.d.ts +38 -6
- package/dist/charts/slot-bar.js +5 -2
- package/dist/charts/slot-bar.js.map +1 -1
- package/dist/charts/sparkline.d.ts +35 -5
- package/dist/charts/sparkline.js +22 -18
- package/dist/charts/sparkline.js.map +1 -1
- package/dist/charts/stacked-bar.d.ts +58 -5
- package/dist/charts/stacked-bar.js +19 -12
- package/dist/charts/stacked-bar.js.map +1 -1
- package/dist/charts/stat-card.d.ts +51 -1
- package/dist/charts/stat-card.js +66 -39
- package/dist/charts/stat-card.js.map +1 -1
- package/dist/charts/timeline.d.ts +3 -0
- package/dist/charts/timeline.js +4 -3
- package/dist/charts/timeline.js.map +1 -1
- package/dist/charts/timeseries.d.ts +58 -5
- package/dist/charts/timeseries.js +13 -2
- package/dist/charts/timeseries.js.map +1 -1
- package/dist/charts/tooltip.d.ts +57 -0
- package/dist/charts/tooltip.js +119 -2
- package/dist/charts/tooltip.js.map +1 -1
- package/dist/components/accordion.d.ts +117 -2
- package/dist/components/accordion.js +20 -13
- package/dist/components/accordion.js.map +1 -1
- package/dist/components/alert-dialog.d.ts +131 -13
- package/dist/components/alert-dialog.js +13 -10
- package/dist/components/alert-dialog.js.map +1 -1
- package/dist/components/app-header.js +18 -17
- package/dist/components/app-header.js.map +1 -1
- package/dist/components/app-shell.js +15 -14
- package/dist/components/app-shell.js.map +1 -1
- package/dist/components/autocomplete.d.ts +4 -0
- package/dist/components/autocomplete.js.map +1 -1
- package/dist/components/avatar.d.ts +76 -3
- package/dist/components/avatar.js.map +1 -1
- package/dist/components/badge.d.ts +15 -1
- package/dist/components/badge.js +17 -16
- package/dist/components/badge.js.map +1 -1
- package/dist/components/banner.d.ts +88 -2
- package/dist/components/banner.js +41 -40
- package/dist/components/banner.js.map +1 -1
- package/dist/components/basalt-mark.js +14 -8
- package/dist/components/basalt-mark.js.map +1 -1
- package/dist/components/battery-meter.d.ts +10 -0
- package/dist/components/battery-meter.js +56 -0
- package/dist/components/battery-meter.js.map +1 -0
- package/dist/components/breadcrumbs.d.ts +27 -7
- package/dist/components/breadcrumbs.js +21 -20
- package/dist/components/breadcrumbs.js.map +1 -1
- package/dist/components/button.d.ts +48 -2
- package/dist/components/button.js +87 -36
- package/dist/components/button.js.map +1 -1
- package/dist/components/chat-bubble.d.ts +24 -0
- package/dist/components/chat-bubble.js +26 -0
- package/dist/components/chat-bubble.js.map +1 -0
- package/dist/components/chat-composer.d.ts +45 -0
- package/dist/components/chat-composer.js +74 -0
- package/dist/components/chat-composer.js.map +1 -0
- package/dist/components/chat-header.d.ts +25 -0
- package/dist/components/chat-header.js +34 -0
- package/dist/components/chat-header.js.map +1 -0
- package/dist/components/chat-inbox.d.ts +33 -0
- package/dist/components/chat-inbox.js +44 -0
- package/dist/components/chat-inbox.js.map +1 -0
- package/dist/components/checkbox.js +84 -53
- package/dist/components/checkbox.js.map +1 -1
- package/dist/components/clipboard-text.d.ts +13 -2
- package/dist/components/clipboard-text.js +4 -4
- package/dist/components/clipboard-text.js.map +1 -1
- package/dist/components/collapsible.d.ts +58 -15
- package/dist/components/collapsible.js.map +1 -1
- package/dist/components/command-palette.d.ts +151 -61
- package/dist/components/command-palette.js.map +1 -1
- package/dist/components/confirm-dialog.d.ts +1 -1
- package/dist/components/confirm-dialog.js +6 -4
- package/dist/components/confirm-dialog.js.map +1 -1
- package/dist/components/context-menu.d.ts +210 -2
- package/dist/components/context-menu.js +7 -4
- package/dist/components/context-menu.js.map +1 -1
- package/dist/components/data-table.d.ts +40 -2
- package/dist/components/data-table.js +168 -120
- package/dist/components/data-table.js.map +1 -1
- package/dist/components/date-picker.d.ts +53 -2
- package/dist/components/date-picker.js +387 -219
- package/dist/components/date-picker.js.map +1 -1
- package/dist/components/delete-resource.d.ts +7 -1
- package/dist/components/delete-resource.js +22 -18
- package/dist/components/delete-resource.js.map +1 -1
- package/dist/components/description-list.js +16 -15
- package/dist/components/description-list.js.map +1 -1
- package/dist/components/dialog.d.ts +141 -12
- package/dist/components/dialog.js +43 -39
- package/dist/components/dialog.js.map +1 -1
- package/dist/components/dock.d.ts +39 -0
- package/dist/components/dock.js +97 -0
- package/dist/components/dock.js.map +1 -0
- package/dist/components/dropdown-menu.d.ts +229 -15
- package/dist/components/dropdown-menu.js +9 -6
- package/dist/components/dropdown-menu.js.map +1 -1
- package/dist/components/editable-nav-item.d.ts +33 -0
- package/dist/components/editable-nav-item.js +90 -0
- package/dist/components/editable-nav-item.js.map +1 -0
- package/dist/components/empty.d.ts +22 -2
- package/dist/components/empty.js +22 -13
- package/dist/components/empty.js.map +1 -1
- package/dist/components/fab.d.ts +23 -0
- package/dist/components/fab.js +25 -0
- package/dist/components/fab.js.map +1 -0
- package/dist/components/field.js +31 -30
- package/dist/components/field.js.map +1 -1
- package/dist/components/file-dropzone.d.ts +37 -0
- package/dist/components/file-dropzone.js +103 -0
- package/dist/components/file-dropzone.js.map +1 -0
- package/dist/components/filter-bar.d.ts +34 -0
- package/dist/components/filter-bar.js +52 -0
- package/dist/components/filter-bar.js.map +1 -0
- package/dist/components/flow.js +19 -18
- package/dist/components/flow.js.map +1 -1
- package/dist/components/grid.d.ts +3 -1
- package/dist/components/grid.js.map +1 -1
- package/dist/components/hover-card.d.ts +111 -1
- package/dist/components/hover-card.js +9 -6
- package/dist/components/hover-card.js.map +1 -1
- package/dist/components/icon-picker.d.ts +34 -0
- package/dist/components/icon-picker.js +77 -0
- package/dist/components/icon-picker.js.map +1 -0
- package/dist/components/inline-editable.d.ts +46 -0
- package/dist/components/inline-editable.js +124 -0
- package/dist/components/inline-editable.js.map +1 -0
- package/dist/components/input-area.js +3 -3
- package/dist/components/input-group.js +7 -7
- package/dist/components/input.js +3 -3
- package/dist/components/label.js +18 -17
- package/dist/components/label.js.map +1 -1
- package/dist/components/layer-card.d.ts +10 -2
- package/dist/components/layer-card.js +71 -68
- package/dist/components/layer-card.js.map +1 -1
- package/dist/components/loader.d.ts +10 -2
- package/dist/components/loader.js.map +1 -1
- package/dist/components/menu-bar.d.ts +174 -6
- package/dist/components/menu-bar.js +33 -29
- package/dist/components/menu-bar.js.map +1 -1
- package/dist/components/meter.d.ts +27 -2
- package/dist/components/meter.js.map +1 -1
- package/dist/components/multi-select.d.ts +64 -0
- package/dist/components/multi-select.js +218 -0
- package/dist/components/multi-select.js.map +1 -0
- package/dist/components/navigation-menu.d.ts +88 -5
- package/dist/components/navigation-menu.js.map +1 -1
- package/dist/components/overlay.js +6 -5
- package/dist/components/overlay.js.map +1 -1
- package/dist/components/page-header.js +23 -21
- package/dist/components/page-header.js.map +1 -1
- package/dist/components/pagination.js +7 -7
- package/dist/components/popover.d.ts +136 -16
- package/dist/components/popover.js +32 -28
- package/dist/components/popover.js.map +1 -1
- package/dist/components/radio.js +38 -37
- package/dist/components/radio.js.map +1 -1
- package/dist/components/resource-list.d.ts +26 -1
- package/dist/components/resource-list.js +28 -15
- package/dist/components/resource-list.js.map +1 -1
- package/dist/components/responsive-master-detail.d.ts +27 -0
- package/dist/components/responsive-master-detail.js +85 -0
- package/dist/components/responsive-master-detail.js.map +1 -0
- package/dist/components/section-rule.js +23 -22
- package/dist/components/section-rule.js.map +1 -1
- package/dist/components/select.d.ts +27 -3
- package/dist/components/select.js +11 -11
- package/dist/components/select.js.map +1 -1
- package/dist/components/sheet.d.ts +115 -11
- package/dist/components/sheet.js +37 -30
- package/dist/components/sheet.js.map +1 -1
- package/dist/components/sidebar.d.ts +109 -17
- package/dist/components/sidebar.js +109 -108
- package/dist/components/sidebar.js.map +1 -1
- package/dist/components/skeleton-line.d.ts +22 -2
- package/dist/components/skeleton-line.js.map +1 -1
- package/dist/components/slider.d.ts +61 -1
- package/dist/components/slider.js +31 -15
- package/dist/components/slider.js.map +1 -1
- package/dist/components/stat-strip.js +16 -15
- package/dist/components/stat-strip.js.map +1 -1
- package/dist/components/switch.js +78 -47
- package/dist/components/switch.js.map +1 -1
- package/dist/components/table-of-contents.js +18 -17
- package/dist/components/table-of-contents.js.map +1 -1
- package/dist/components/table-pager.js +20 -19
- package/dist/components/table-pager.js.map +1 -1
- package/dist/components/table.d.ts +9 -3
- package/dist/components/table.js +19 -18
- package/dist/components/table.js.map +1 -1
- package/dist/components/tabs.js +29 -22
- package/dist/components/tabs.js.map +1 -1
- package/dist/components/tag-badge.d.ts +58 -0
- package/dist/components/tag-badge.js +72 -0
- package/dist/components/tag-badge.js.map +1 -0
- package/dist/components/tag-color-picker.d.ts +20 -0
- package/dist/components/tag-color-picker.js +42 -0
- package/dist/components/tag-color-picker.js.map +1 -0
- package/dist/components/text.js +17 -16
- package/dist/components/text.js.map +1 -1
- package/dist/components/toast.d.ts +173 -3
- package/dist/components/toast.js +1 -1
- package/dist/components/toast.js.map +1 -1
- package/dist/components/toggle-group.d.ts +88 -2
- package/dist/components/toggle-group.js +32 -31
- package/dist/components/toggle-group.js.map +1 -1
- package/dist/components/toggle.d.ts +35 -2
- package/dist/components/toggle.js +12 -11
- package/dist/components/toggle.js.map +1 -1
- package/dist/components/tooltip.d.ts +144 -6
- package/dist/components/tooltip.js +9 -6
- package/dist/components/tooltip.js.map +1 -1
- package/dist/components/typeahead-field.js +193 -132
- package/dist/components/typeahead-field.js.map +1 -1
- package/dist/components/upload-queue.d.ts +51 -0
- package/dist/components/upload-queue.js +116 -0
- package/dist/components/upload-queue.js.map +1 -0
- package/dist/providers/accent.d.ts +46 -2
- package/dist/providers/accent.js +358 -172
- package/dist/providers/accent.js.map +1 -1
- package/dist/providers/link.d.ts +14 -4
- package/dist/providers/link.js.map +1 -1
- package/dist/providers/theme.d.ts +38 -2
- package/dist/providers/theme.js +160 -27
- package/dist/providers/theme.js.map +1 -1
- package/dist/styles/base.css +83 -0
- package/dist/styles/standalone.css +820 -120
- package/dist/styles/tailwind.css +21 -7
- package/dist/styles/tokens.css +146 -91
- package/dist/utils/control-surface.d.ts +2 -1
- package/dist/utils/control-surface.js +4 -4
- package/dist/utils/control-surface.js.map +1 -1
- package/dist/utils/selection-indicator.js +2 -2
- package/dist/utils/selection-indicator.js.map +1 -1
- package/package.json +8 -4
|
@@ -1,52 +1,53 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn as e } from "../utils/cn.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import
|
|
3
|
+
import { BASALT_UI_CLASS as t } from "../utils/control-surface.js";
|
|
4
|
+
import { OVERLAY_LAYER as n, OVERLAY_MOTION as r } from "./overlay.js";
|
|
5
|
+
import { Dialog as i, DialogOverlay as a, DialogPortal as o } from "./dialog.js";
|
|
6
|
+
import { Collapsible as s, CollapsibleContent as c, CollapsibleTrigger as l } from "./collapsible.js";
|
|
7
|
+
import { SkeletonLine as u } from "./skeleton-line.js";
|
|
8
|
+
import { createContext as d, useCallback as f, useContext as p, useLayoutEffect as m, useRef as h, useState as g } from "react";
|
|
9
|
+
import { ChevronUp as _, Search as v } from "lucide-react";
|
|
10
|
+
import { jsx as y, jsxs as b } from "react/jsx-runtime";
|
|
11
|
+
import * as x from "@radix-ui/react-dialog";
|
|
11
12
|
//#region src/components/sidebar.tsx
|
|
12
|
-
var
|
|
13
|
-
function
|
|
14
|
-
let e =
|
|
13
|
+
var S = d(null);
|
|
14
|
+
function C() {
|
|
15
|
+
let e = p(S);
|
|
15
16
|
if (!e) throw Error("useSidebar must be used within SidebarProvider");
|
|
16
17
|
return e;
|
|
17
18
|
}
|
|
18
|
-
function
|
|
19
|
-
let [l, u] =
|
|
20
|
-
|
|
21
|
-
}, []),
|
|
22
|
-
|
|
23
|
-
o && !E && (C.current || !
|
|
19
|
+
function w({ collapsed: e, defaultCollapsed: t = !1, onCollapsedChange: n, side: r = "left", loading: i = !1, peek: a = !1, overlay: o = !1, defaultWidth: s = 260, children: c }) {
|
|
20
|
+
let [l, u] = g(t), [d, p] = g(!1), [_, v] = g(() => T(s)), b = f((e) => {
|
|
21
|
+
v(T(e));
|
|
22
|
+
}, []), x = h(null), C = h(e ?? t), w = h(o), E = e ?? l;
|
|
23
|
+
m(() => {
|
|
24
|
+
o && !E && (C.current || !w.current) && document.activeElement instanceof HTMLElement && (x.current = document.activeElement), C.current = E, w.current = o;
|
|
24
25
|
});
|
|
25
|
-
let D =
|
|
26
|
-
!t && document.activeElement instanceof HTMLElement && (
|
|
26
|
+
let D = f((t) => {
|
|
27
|
+
!t && document.activeElement instanceof HTMLElement && (x.current = document.activeElement), e === void 0 && u(t), n?.(t);
|
|
27
28
|
}, [e, n]);
|
|
28
|
-
return /* @__PURE__ */
|
|
29
|
+
return /* @__PURE__ */ y(S.Provider, {
|
|
29
30
|
value: {
|
|
30
31
|
collapsed: E,
|
|
31
32
|
setCollapsed: D,
|
|
32
33
|
side: r,
|
|
33
34
|
loading: i,
|
|
34
35
|
peek: a,
|
|
35
|
-
peeking:
|
|
36
|
-
setPeeking:
|
|
36
|
+
peeking: d,
|
|
37
|
+
setPeeking: p,
|
|
37
38
|
overlay: o,
|
|
38
39
|
width: _,
|
|
39
40
|
setWidth: b,
|
|
40
|
-
lastFocusRef:
|
|
41
|
+
lastFocusRef: x
|
|
41
42
|
},
|
|
42
43
|
children: c
|
|
43
44
|
});
|
|
44
45
|
}
|
|
45
|
-
function
|
|
46
|
+
function T(e) {
|
|
46
47
|
return Math.min(400, Math.max(180, e));
|
|
47
48
|
}
|
|
48
|
-
function
|
|
49
|
-
return /* @__PURE__ */
|
|
49
|
+
function E({ side: t, width: n, onWidth: r }) {
|
|
50
|
+
return /* @__PURE__ */ y("div", {
|
|
50
51
|
role: "separator",
|
|
51
52
|
"aria-orientation": "vertical",
|
|
52
53
|
"aria-valuenow": n,
|
|
@@ -59,7 +60,7 @@ function T({ side: t, width: n, onWidth: r }) {
|
|
|
59
60
|
e.preventDefault(), e.currentTarget.setPointerCapture(e.pointerId);
|
|
60
61
|
let i = e.clientX, a = n, o = e.currentTarget, s = (e) => {
|
|
61
62
|
let n = t === "right" ? i - e.clientX : e.clientX - i;
|
|
62
|
-
r(
|
|
63
|
+
r(T(a + n));
|
|
63
64
|
}, c = () => {
|
|
64
65
|
o.removeEventListener("pointermove", s), o.removeEventListener("pointerup", c), o.removeEventListener("pointercancel", c);
|
|
65
66
|
};
|
|
@@ -69,177 +70,177 @@ function T({ side: t, width: n, onWidth: r }) {
|
|
|
69
70
|
if (e.key !== "ArrowLeft" && e.key !== "ArrowRight") return;
|
|
70
71
|
e.preventDefault();
|
|
71
72
|
let i = e.key === "ArrowRight" ? 1 : -1;
|
|
72
|
-
r(
|
|
73
|
+
r(T(n + (t === "right" ? -i * 8 : i * 8)));
|
|
73
74
|
}
|
|
74
75
|
});
|
|
75
76
|
}
|
|
76
|
-
function
|
|
77
|
-
let
|
|
77
|
+
function D({ collapsed: s, className: c, children: l, onMouseEnter: d, onMouseLeave: f, style: m, ...h }) {
|
|
78
|
+
let g = p(S), _ = g ? g.collapsed && !(g.peek && g.peeking) : s ?? !1, v = g?.side ?? "left", C = g?.overlay ?? !1, w = g?.width ?? 260, T = g?.loading ? /* @__PURE__ */ b("div", {
|
|
78
79
|
className: "flex flex-col gap-2 p-3",
|
|
79
80
|
role: "status",
|
|
80
81
|
"aria-live": "polite",
|
|
81
82
|
children: [
|
|
82
|
-
/* @__PURE__ */
|
|
83
|
-
/* @__PURE__ */
|
|
84
|
-
/* @__PURE__ */
|
|
83
|
+
/* @__PURE__ */ y(u, {}),
|
|
84
|
+
/* @__PURE__ */ y(u, {}),
|
|
85
|
+
/* @__PURE__ */ y(u, {})
|
|
85
86
|
]
|
|
86
|
-
}) :
|
|
87
|
-
side:
|
|
88
|
-
width:
|
|
89
|
-
onWidth:
|
|
90
|
-
}) : null,
|
|
91
|
-
return
|
|
92
|
-
open: !
|
|
93
|
-
onOpenChange: (e) =>
|
|
94
|
-
children: /* @__PURE__ */
|
|
87
|
+
}) : l, D = g && !_ ? /* @__PURE__ */ y(E, {
|
|
88
|
+
side: v,
|
|
89
|
+
width: g.width,
|
|
90
|
+
onWidth: g.setWidth
|
|
91
|
+
}) : null, O = e(t, "relative flex h-screen shrink-0 flex-col bg-basalt-background text-sm text-basalt-foreground", r, c);
|
|
92
|
+
return C && g ? /* @__PURE__ */ y(i, {
|
|
93
|
+
open: !g.collapsed,
|
|
94
|
+
onOpenChange: (e) => g.setCollapsed(!e),
|
|
95
|
+
children: /* @__PURE__ */ b(o, { children: [/* @__PURE__ */ y(a, {}), /* @__PURE__ */ b(x.Content, {
|
|
95
96
|
"aria-label": "Sidebar",
|
|
96
97
|
"data-overlay": "",
|
|
97
|
-
"data-side":
|
|
98
|
-
"aria-busy":
|
|
99
|
-
onMouseEnter:
|
|
100
|
-
onMouseLeave:
|
|
98
|
+
"data-side": v,
|
|
99
|
+
"aria-busy": g.loading || void 0,
|
|
100
|
+
onMouseEnter: d,
|
|
101
|
+
onMouseLeave: f,
|
|
101
102
|
ref: (e) => {
|
|
102
|
-
e && document.activeElement instanceof HTMLElement && !e.contains(document.activeElement) && (
|
|
103
|
+
e && document.activeElement instanceof HTMLElement && !e.contains(document.activeElement) && (g.lastFocusRef.current = document.activeElement);
|
|
103
104
|
},
|
|
104
105
|
onOpenAutoFocus: (e) => {
|
|
105
106
|
let t = "relatedTarget" in e ? e.relatedTarget : null;
|
|
106
|
-
t instanceof HTMLElement && (
|
|
107
|
+
t instanceof HTMLElement && (g.lastFocusRef.current = t);
|
|
107
108
|
},
|
|
108
109
|
onCloseAutoFocus: (e) => {
|
|
109
|
-
e.preventDefault(),
|
|
110
|
+
e.preventDefault(), g.lastFocusRef.current?.focus();
|
|
110
111
|
},
|
|
111
|
-
className: e(
|
|
112
|
+
className: e(O, n, "fixed inset-y-0 overflow-hidden shadow-md", v === "right" ? "right-0" : "left-0"),
|
|
112
113
|
style: {
|
|
113
|
-
width:
|
|
114
|
-
...
|
|
114
|
+
width: w,
|
|
115
|
+
...m
|
|
115
116
|
},
|
|
116
|
-
...
|
|
117
|
-
children: [
|
|
117
|
+
...h,
|
|
118
|
+
children: [T, D]
|
|
118
119
|
})] })
|
|
119
|
-
}) : /* @__PURE__ */
|
|
120
|
-
"data-collapsed":
|
|
121
|
-
"data-side":
|
|
122
|
-
"aria-busy":
|
|
120
|
+
}) : /* @__PURE__ */ b("aside", {
|
|
121
|
+
"data-collapsed": _ ? "" : void 0,
|
|
122
|
+
"data-side": v,
|
|
123
|
+
"aria-busy": g?.loading || void 0,
|
|
123
124
|
onMouseEnter: (e) => {
|
|
124
|
-
|
|
125
|
+
g?.peek && g.collapsed && g.setPeeking(!0), d?.(e);
|
|
125
126
|
},
|
|
126
127
|
onMouseLeave: (e) => {
|
|
127
|
-
|
|
128
|
+
g?.peek && g.setPeeking(!1), f?.(e);
|
|
128
129
|
},
|
|
129
|
-
className: e(
|
|
130
|
-
style:
|
|
131
|
-
width:
|
|
132
|
-
...
|
|
130
|
+
className: e(O, "sticky top-0 transition-all duration-300 ease-in-out", v === "right" ? "order-last" : void 0, _ ? "w-[68px] overflow-y-hidden" : "overflow-hidden"),
|
|
131
|
+
style: _ ? m : {
|
|
132
|
+
width: w,
|
|
133
|
+
...m
|
|
133
134
|
},
|
|
134
|
-
...
|
|
135
|
-
children: [
|
|
135
|
+
...h,
|
|
136
|
+
children: [T, D]
|
|
136
137
|
});
|
|
137
138
|
}
|
|
138
|
-
function
|
|
139
|
-
return /* @__PURE__ */
|
|
139
|
+
function O({ className: t, ...n }) {
|
|
140
|
+
return /* @__PURE__ */ y("div", {
|
|
140
141
|
className: e("flex h-14 shrink-0 items-center px-3", t),
|
|
141
142
|
...n
|
|
142
143
|
});
|
|
143
144
|
}
|
|
144
|
-
function
|
|
145
|
-
return /* @__PURE__ */
|
|
145
|
+
function k({ shortcut: n = "⌘K", className: r, children: i, ...a }) {
|
|
146
|
+
return /* @__PURE__ */ b("button", {
|
|
146
147
|
type: "button",
|
|
147
|
-
className: e("flex w-full cursor-pointer items-center gap-3 rounded-lg bg-basalt-secondary px-3 py-1.5 transition-colors hover:bg-basalt-accent",
|
|
148
|
-
...
|
|
148
|
+
className: e(t, "flex w-full cursor-pointer items-center gap-3 rounded-lg bg-basalt-secondary px-3 py-1.5 transition-colors hover:bg-basalt-accent", r),
|
|
149
|
+
...a,
|
|
149
150
|
children: [
|
|
150
|
-
/* @__PURE__ */ v
|
|
151
|
+
/* @__PURE__ */ y(v, {
|
|
151
152
|
className: "h-4 w-4 text-basalt-muted-foreground",
|
|
152
153
|
strokeWidth: 1.5
|
|
153
154
|
}),
|
|
154
|
-
/* @__PURE__ */
|
|
155
|
+
/* @__PURE__ */ y("span", {
|
|
155
156
|
className: "flex-1 text-left text-sm text-basalt-muted-foreground",
|
|
156
|
-
children:
|
|
157
|
+
children: i
|
|
157
158
|
}),
|
|
158
|
-
/* @__PURE__ */
|
|
159
|
+
/* @__PURE__ */ y("kbd", {
|
|
159
160
|
className: "pointer-events-none hidden rounded-sm border border-basalt-border bg-basalt-card px-1.5 py-0.5 text-[10px] font-medium text-basalt-muted-foreground sm:inline-block",
|
|
160
|
-
children:
|
|
161
|
+
children: n
|
|
161
162
|
})
|
|
162
163
|
]
|
|
163
164
|
});
|
|
164
165
|
}
|
|
165
|
-
function
|
|
166
|
-
return /* @__PURE__ */
|
|
166
|
+
function A({ className: t, ...n }) {
|
|
167
|
+
return /* @__PURE__ */ y("nav", {
|
|
167
168
|
className: e("flex min-h-0 flex-1 flex-col overflow-y-auto", t),
|
|
168
169
|
...n
|
|
169
170
|
});
|
|
170
171
|
}
|
|
171
|
-
function
|
|
172
|
-
return /* @__PURE__ */
|
|
172
|
+
function j({ className: t, ...n }) {
|
|
173
|
+
return /* @__PURE__ */ y("p", {
|
|
173
174
|
className: e("px-6 pt-3 pb-1 text-[11px] font-medium tracking-[0.14em] text-basalt-muted-foreground uppercase", t),
|
|
174
175
|
...n
|
|
175
176
|
});
|
|
176
177
|
}
|
|
177
|
-
function
|
|
178
|
-
return /* @__PURE__ */
|
|
178
|
+
function M({ active: t = !1, className: n, ...r }) {
|
|
179
|
+
return /* @__PURE__ */ y("button", {
|
|
179
180
|
type: "button",
|
|
180
181
|
"aria-current": t ? "page" : void 0,
|
|
181
182
|
className: e("flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-normal transition-colors", t ? "bg-basalt-accent text-basalt-foreground" : "text-basalt-muted-foreground hover:bg-basalt-accent hover:text-basalt-foreground", n),
|
|
182
183
|
...r
|
|
183
184
|
});
|
|
184
185
|
}
|
|
185
|
-
function
|
|
186
|
-
return /* @__PURE__ */
|
|
186
|
+
function N({ active: t = !1, className: n, ...r }) {
|
|
187
|
+
return /* @__PURE__ */ y("button", {
|
|
187
188
|
type: "button",
|
|
188
189
|
"aria-current": t ? "page" : void 0,
|
|
189
190
|
className: e("relative flex h-10 w-10 items-center justify-center rounded-lg transition-colors", t ? "bg-basalt-accent text-basalt-foreground" : "text-basalt-muted-foreground hover:bg-basalt-accent hover:text-basalt-foreground", n),
|
|
190
191
|
...r
|
|
191
192
|
});
|
|
192
193
|
}
|
|
193
|
-
function
|
|
194
|
-
let [a,
|
|
195
|
-
return /* @__PURE__ */
|
|
194
|
+
function P({ label: t, defaultOpen: n = !0, children: i }) {
|
|
195
|
+
let [a, o] = g(n);
|
|
196
|
+
return /* @__PURE__ */ b(s, {
|
|
196
197
|
open: a,
|
|
197
|
-
onOpenChange:
|
|
198
|
-
children: [/* @__PURE__ */
|
|
198
|
+
onOpenChange: o,
|
|
199
|
+
children: [/* @__PURE__ */ y("div", {
|
|
199
200
|
className: "mt-2 px-3",
|
|
200
|
-
children: /* @__PURE__ */
|
|
201
|
+
children: /* @__PURE__ */ y(l, {
|
|
201
202
|
asChild: !0,
|
|
202
|
-
children: /* @__PURE__ */
|
|
203
|
+
children: /* @__PURE__ */ b("button", {
|
|
203
204
|
type: "button",
|
|
204
205
|
className: "flex w-full items-center justify-between px-3 py-2.5",
|
|
205
|
-
children: [/* @__PURE__ */
|
|
206
|
+
children: [/* @__PURE__ */ y("span", {
|
|
206
207
|
className: "text-sm font-normal text-basalt-muted-foreground",
|
|
207
208
|
children: t
|
|
208
|
-
}), /* @__PURE__ */
|
|
209
|
+
}), /* @__PURE__ */ y("span", {
|
|
209
210
|
className: "flex h-7 w-7 shrink-0 items-center justify-center",
|
|
210
|
-
children: /* @__PURE__ */
|
|
211
|
-
className: e("h-4 w-4 text-basalt-muted-foreground transition-transform duration-200",
|
|
211
|
+
children: /* @__PURE__ */ y(_, {
|
|
212
|
+
className: e("h-4 w-4 text-basalt-muted-foreground transition-transform duration-200", r, !a && "rotate-180"),
|
|
212
213
|
strokeWidth: 1.5
|
|
213
214
|
})
|
|
214
215
|
})]
|
|
215
216
|
})
|
|
216
217
|
})
|
|
217
|
-
}), /* @__PURE__ */
|
|
218
|
+
}), /* @__PURE__ */ y(c, {
|
|
218
219
|
unstyled: !0,
|
|
219
|
-
children: /* @__PURE__ */
|
|
220
|
+
children: /* @__PURE__ */ y("div", {
|
|
220
221
|
className: "flex flex-col gap-0.5 px-3",
|
|
221
222
|
children: i
|
|
222
223
|
})
|
|
223
224
|
})]
|
|
224
225
|
});
|
|
225
226
|
}
|
|
226
|
-
function
|
|
227
|
-
return /* @__PURE__ */
|
|
227
|
+
function F({ className: t, ...n }) {
|
|
228
|
+
return /* @__PURE__ */ y("div", {
|
|
228
229
|
className: e("px-4 py-3", t),
|
|
229
230
|
...n
|
|
230
231
|
});
|
|
231
232
|
}
|
|
232
|
-
function
|
|
233
|
-
return /* @__PURE__ */
|
|
233
|
+
function I({ name: t, email: n, avatar: r, action: i, className: a }) {
|
|
234
|
+
return /* @__PURE__ */ b("div", {
|
|
234
235
|
className: e("flex items-center gap-3", a),
|
|
235
236
|
children: [
|
|
236
237
|
r,
|
|
237
|
-
/* @__PURE__ */
|
|
238
|
+
/* @__PURE__ */ b("div", {
|
|
238
239
|
className: "min-w-0 flex-1",
|
|
239
|
-
children: [/* @__PURE__ */
|
|
240
|
+
children: [/* @__PURE__ */ y("p", {
|
|
240
241
|
className: "truncate text-sm font-medium text-basalt-foreground",
|
|
241
242
|
children: t
|
|
242
|
-
}), n ? /* @__PURE__ */
|
|
243
|
+
}), n ? /* @__PURE__ */ y("p", {
|
|
243
244
|
className: "truncate text-xs text-basalt-muted-foreground",
|
|
244
245
|
children: n
|
|
245
246
|
}) : null]
|
|
@@ -248,14 +249,14 @@ function F({ name: t, email: n, avatar: r, action: i, className: a }) {
|
|
|
248
249
|
]
|
|
249
250
|
});
|
|
250
251
|
}
|
|
251
|
-
function
|
|
252
|
-
return /* @__PURE__ */
|
|
252
|
+
function L({ className: t, ...n }) {
|
|
253
|
+
return /* @__PURE__ */ y("div", {
|
|
253
254
|
"data-basalt-surface-root": "",
|
|
254
255
|
className: e("min-h-0 flex-1 overflow-y-auto rounded-[16px] bg-basalt-card p-3 text-basalt-card-foreground shadow-sm ring-1 ring-basalt-border/40 md:rounded-basalt-island md:p-5", t),
|
|
255
256
|
...n
|
|
256
257
|
});
|
|
257
258
|
}
|
|
258
259
|
//#endregion
|
|
259
|
-
export {
|
|
260
|
+
export { L as ContentIsland, D as Sidebar, F as SidebarFooter, P as SidebarGroup, O as SidebarHeader, N as SidebarIconItem, M as SidebarItem, A as SidebarNav, j as SidebarPartition, w as SidebarProvider, k as SidebarSearch, I as SidebarUser, C as useSidebar };
|
|
260
261
|
|
|
261
262
|
//# sourceMappingURL=sidebar.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sidebar.js","names":[],"sources":["../../src/components/sidebar.tsx"],"sourcesContent":["import * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { ChevronUp, Search } from \"lucide-react\";\nimport {\n\ttype ButtonHTMLAttributes,\n\tcreateContext,\n\ttype HTMLAttributes,\n\ttype ReactNode,\n\ttype PointerEvent as ReactPointerEvent,\n\ttype RefObject,\n\tuseCallback,\n\tuseContext,\n\tuseLayoutEffect,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from \"./collapsible\";\nimport { Dialog, DialogOverlay, DialogPortal } from \"./dialog\";\nimport { OVERLAY_LAYER, OVERLAY_MOTION } from \"./overlay\";\nimport { SkeletonLine } from \"./skeleton-line\";\n\nexport type SidebarSide = \"left\" | \"right\";\n\ntype SidebarContextValue = {\n\tcollapsed: boolean;\n\tsetCollapsed: (next: boolean) => void;\n\tside: SidebarSide;\n\tloading: boolean;\n\tpeek: boolean;\n\tpeeking: boolean;\n\tsetPeeking: (next: boolean) => void;\n\toverlay: boolean;\n\twidth: number;\n\tsetWidth: (next: number) => void;\n\tlastFocusRef: RefObject<HTMLElement | null>;\n};\n\nconst SidebarContext = createContext<SidebarContextValue | null>(null);\n\nexport function useSidebar() {\n\tconst context = useContext(SidebarContext);\n\tif (!context) {\n\t\tthrow new Error(\"useSidebar must be used within SidebarProvider\");\n\t}\n\treturn context;\n}\n\nexport type SidebarProviderProps = {\n\t/**\n\t * The controlled collapsed state.\n\t */\n\tcollapsed?: boolean;\n\t/**\n\t * The uncontrolled initial collapsed state.\n\t * @default false\n\t */\n\tdefaultCollapsed?: boolean;\n\t/**\n\t * Called when the collapsed state changes.\n\t */\n\tonCollapsedChange?: (collapsed: boolean) => void;\n\t/**\n\t * Which edge the sidebar occupies.\n\t * @default left\n\t */\n\tside?: SidebarSide;\n\t/**\n\t * Replace the nav with a loading skeleton.\n\t * @default false\n\t */\n\tloading?: boolean;\n\t/**\n\t * Expand the collapsed rail on hover.\n\t * @default false\n\t */\n\tpeek?: boolean;\n\t/**\n\t * Render as an overlay instead of in-flow chrome.\n\t * @default false\n\t */\n\toverlay?: boolean;\n\t/**\n\t * Expanded width in pixels.\n\t * @default 260\n\t */\n\tdefaultWidth?: number;\n\t/**\n\t * Sidebar chrome and page content.\n\t */\n\tchildren: ReactNode;\n};\n\nexport function SidebarProvider({\n\tcollapsed,\n\tdefaultCollapsed = false,\n\tonCollapsedChange,\n\tside = \"left\",\n\tloading = false,\n\tpeek = false,\n\toverlay = false,\n\tdefaultWidth = 260,\n\tchildren,\n}: SidebarProviderProps) {\n\tconst [uncontrolled, setUncontrolled] = useState(defaultCollapsed);\n\tconst [peeking, setPeeking] = useState(false);\n\tconst [width, setWidthState] = useState(() => clampSidebarWidth(defaultWidth));\n\tconst setWidth = useCallback((next: number) => {\n\t\tsetWidthState(clampSidebarWidth(next));\n\t}, []);\n\tconst lastFocusRef = useRef<HTMLElement | null>(null);\n\tconst prevCollapsed = useRef(collapsed ?? defaultCollapsed);\n\tconst prevOverlay = useRef(overlay);\n\tconst resolved = collapsed ?? uncontrolled;\n\tuseLayoutEffect(() => {\n\t\tif (\n\t\t\toverlay &&\n\t\t\t!resolved &&\n\t\t\t(prevCollapsed.current || !prevOverlay.current) &&\n\t\t\tdocument.activeElement instanceof HTMLElement\n\t\t) {\n\t\t\tlastFocusRef.current = document.activeElement;\n\t\t}\n\t\tprevCollapsed.current = resolved;\n\t\tprevOverlay.current = overlay;\n\t});\n\tconst setCollapsed = useCallback(\n\t\t(next: boolean) => {\n\t\t\tif (!next && document.activeElement instanceof HTMLElement) {\n\t\t\t\tlastFocusRef.current = document.activeElement;\n\t\t\t}\n\t\t\tif (collapsed === undefined) {\n\t\t\t\tsetUncontrolled(next);\n\t\t\t}\n\t\t\tonCollapsedChange?.(next);\n\t\t},\n\t\t[collapsed, onCollapsedChange],\n\t);\n\treturn (\n\t\t<SidebarContext.Provider\n\t\t\tvalue={{\n\t\t\t\tcollapsed: resolved,\n\t\t\t\tsetCollapsed,\n\t\t\t\tside,\n\t\t\t\tloading,\n\t\t\t\tpeek,\n\t\t\t\tpeeking,\n\t\t\t\tsetPeeking,\n\t\t\t\toverlay,\n\t\t\t\twidth,\n\t\t\t\tsetWidth,\n\t\t\t\tlastFocusRef,\n\t\t\t}}\n\t\t>\n\t\t\t{children}\n\t\t</SidebarContext.Provider>\n\t);\n}\n\nexport type SidebarProps = HTMLAttributes<HTMLElement> & {\n\t/**\n\t * Collapse the rail when no provider is present.\n\t * @default false\n\t */\n\tcollapsed?: boolean;\n};\n\nfunction clampSidebarWidth(next: number) {\n\treturn Math.min(400, Math.max(180, next));\n}\n\nfunction SidebarResize({\n\tside,\n\twidth,\n\tonWidth,\n}: {\n\tside: SidebarSide;\n\twidth: number;\n\tonWidth: (next: number) => void;\n}) {\n\tconst onPointerDown = (event: ReactPointerEvent<HTMLDivElement>) => {\n\t\tevent.preventDefault();\n\t\tevent.currentTarget.setPointerCapture(event.pointerId);\n\t\tconst startX = event.clientX;\n\t\tconst startWidth = width;\n\t\tconst target = event.currentTarget;\n\t\tconst onMove = (move: PointerEvent) => {\n\t\t\tconst delta = side === \"right\" ? startX - move.clientX : move.clientX - startX;\n\t\t\tonWidth(clampSidebarWidth(startWidth + delta));\n\t\t};\n\t\tconst onUp = () => {\n\t\t\ttarget.removeEventListener(\"pointermove\", onMove);\n\t\t\ttarget.removeEventListener(\"pointerup\", onUp);\n\t\t\ttarget.removeEventListener(\"pointercancel\", onUp);\n\t\t};\n\t\ttarget.addEventListener(\"pointermove\", onMove);\n\t\ttarget.addEventListener(\"pointerup\", onUp);\n\t\ttarget.addEventListener(\"pointercancel\", onUp);\n\t};\n\treturn (\n\t\t<div\n\t\t\trole=\"separator\"\n\t\t\taria-orientation=\"vertical\"\n\t\t\taria-valuenow={width}\n\t\t\taria-valuemin={180}\n\t\t\taria-valuemax={400}\n\t\t\taria-label=\"Resize sidebar\"\n\t\t\ttabIndex={0}\n\t\t\tclassName={cn(\n\t\t\t\t\"absolute top-0 h-full w-1 cursor-col-resize bg-transparent\",\n\t\t\t\tside === \"right\" ? \"left-0\" : \"right-0\",\n\t\t\t)}\n\t\t\tonPointerDown={onPointerDown}\n\t\t\tonKeyDown={(event) => {\n\t\t\t\tif (event.key !== \"ArrowLeft\" && event.key !== \"ArrowRight\") {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tevent.preventDefault();\n\t\t\t\tconst dir = event.key === \"ArrowRight\" ? 1 : -1;\n\t\t\t\tconst delta = side === \"right\" ? -dir * 8 : dir * 8;\n\t\t\t\tonWidth(clampSidebarWidth(width + delta));\n\t\t\t}}\n\t\t/>\n\t);\n}\n\nexport function Sidebar({\n\tcollapsed: collapsedProp,\n\tclassName,\n\tchildren,\n\tonMouseEnter,\n\tonMouseLeave,\n\tstyle,\n\t...props\n}: SidebarProps) {\n\tconst context = useContext(SidebarContext);\n\tconst collapsed = context\n\t\t? context.collapsed && !(context.peek && context.peeking)\n\t\t: (collapsedProp ?? false);\n\tconst side = context?.side ?? \"left\";\n\tconst overlay = context?.overlay ?? false;\n\tconst width = context?.width ?? 260;\n\tconst body = context?.loading ? (\n\t\t<div className=\"flex flex-col gap-2 p-3\" role=\"status\" aria-live=\"polite\">\n\t\t\t<SkeletonLine />\n\t\t\t<SkeletonLine />\n\t\t\t<SkeletonLine />\n\t\t</div>\n\t) : (\n\t\tchildren\n\t);\n\tconst resize =\n\t\tcontext && !collapsed ? (\n\t\t\t<SidebarResize side={side} width={context.width} onWidth={context.setWidth} />\n\t\t) : null;\n\tconst frameClass = cn(\n\t\t\"relative flex h-screen shrink-0 flex-col bg-basalt-background text-sm text-basalt-foreground\",\n\t\tOVERLAY_MOTION,\n\t\tclassName,\n\t);\n\tif (overlay && context) {\n\t\treturn (\n\t\t\t<Dialog open={!context.collapsed} onOpenChange={(open) => context.setCollapsed(!open)}>\n\t\t\t\t<DialogPortal>\n\t\t\t\t\t<DialogOverlay />\n\t\t\t\t\t<DialogPrimitive.Content\n\t\t\t\t\t\taria-label=\"Sidebar\"\n\t\t\t\t\t\tdata-overlay=\"\"\n\t\t\t\t\t\tdata-side={side}\n\t\t\t\t\t\taria-busy={context.loading || undefined}\n\t\t\t\t\t\tonMouseEnter={onMouseEnter}\n\t\t\t\t\t\tonMouseLeave={onMouseLeave}\n\t\t\t\t\t\tref={(node) => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tnode &&\n\t\t\t\t\t\t\t\tdocument.activeElement instanceof HTMLElement &&\n\t\t\t\t\t\t\t\t!node.contains(document.activeElement)\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tcontext.lastFocusRef.current = document.activeElement;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonOpenAutoFocus={(event) => {\n\t\t\t\t\t\t\tconst from = \"relatedTarget\" in event ? event.relatedTarget : null;\n\t\t\t\t\t\t\tif (from instanceof HTMLElement) {\n\t\t\t\t\t\t\t\tcontext.lastFocusRef.current = from;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonCloseAutoFocus={(event) => {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tcontext.lastFocusRef.current?.focus();\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\tframeClass,\n\t\t\t\t\t\t\tOVERLAY_LAYER,\n\t\t\t\t\t\t\t\"fixed inset-y-0 overflow-hidden shadow-md\",\n\t\t\t\t\t\t\tside === \"right\" ? \"right-0\" : \"left-0\",\n\t\t\t\t\t\t)}\n\t\t\t\t\t\tstyle={{ width, ...style }}\n\t\t\t\t\t\t{...props}\n\t\t\t\t\t>\n\t\t\t\t\t\t{body}\n\t\t\t\t\t\t{resize}\n\t\t\t\t\t</DialogPrimitive.Content>\n\t\t\t\t</DialogPortal>\n\t\t\t</Dialog>\n\t\t);\n\t}\n\treturn (\n\t\t<aside\n\t\t\tdata-collapsed={collapsed ? \"\" : undefined}\n\t\t\tdata-side={side}\n\t\t\taria-busy={context?.loading || undefined}\n\t\t\tonMouseEnter={(event) => {\n\t\t\t\tif (context?.peek && context.collapsed) {\n\t\t\t\t\tcontext.setPeeking(true);\n\t\t\t\t}\n\t\t\t\tonMouseEnter?.(event);\n\t\t\t}}\n\t\t\tonMouseLeave={(event) => {\n\t\t\t\tif (context?.peek) {\n\t\t\t\t\tcontext.setPeeking(false);\n\t\t\t\t}\n\t\t\t\tonMouseLeave?.(event);\n\t\t\t}}\n\t\t\tclassName={cn(\n\t\t\t\tframeClass,\n\t\t\t\t\"sticky top-0 transition-all duration-300 ease-in-out\",\n\t\t\t\tside === \"right\" ? \"order-last\" : undefined,\n\t\t\t\tcollapsed ? \"w-[68px] overflow-y-hidden\" : \"overflow-hidden\",\n\t\t\t)}\n\t\t\tstyle={!collapsed ? { width, ...style } : style}\n\t\t\t{...props}\n\t\t>\n\t\t\t{body}\n\t\t\t{resize}\n\t\t</aside>\n\t);\n}\n\nexport function SidebarHeader({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n\treturn <div className={cn(\"flex h-14 shrink-0 items-center px-3\", className)} {...props} />;\n}\n\nexport function SidebarSearch({\n\tshortcut = \"⌘K\",\n\tclassName,\n\tchildren,\n\t...props\n}: ButtonHTMLAttributes<HTMLButtonElement> & { shortcut?: string }) {\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclassName={cn(\n\t\t\t\t\"flex w-full cursor-pointer items-center gap-3 rounded-lg bg-basalt-secondary px-3 py-1.5 transition-colors hover:bg-basalt-accent\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<Search className=\"h-4 w-4 text-basalt-muted-foreground\" strokeWidth={1.5} />\n\t\t\t<span className=\"flex-1 text-left text-sm text-basalt-muted-foreground\">{children}</span>\n\t\t\t<kbd className=\"pointer-events-none hidden rounded-sm border border-basalt-border bg-basalt-card px-1.5 py-0.5 text-[10px] font-medium text-basalt-muted-foreground sm:inline-block\">\n\t\t\t\t{shortcut}\n\t\t\t</kbd>\n\t\t</button>\n\t);\n}\n\nexport function SidebarNav({ className, ...props }: HTMLAttributes<HTMLElement>) {\n\treturn (\n\t\t<nav className={cn(\"flex min-h-0 flex-1 flex-col overflow-y-auto\", className)} {...props} />\n\t);\n}\n\nexport function SidebarPartition({ className, ...props }: HTMLAttributes<HTMLParagraphElement>) {\n\treturn (\n\t\t<p\n\t\t\tclassName={cn(\n\t\t\t\t\"px-6 pt-3 pb-1 text-[11px] font-medium tracking-[0.14em] text-basalt-muted-foreground uppercase\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport type SidebarItemProps = ButtonHTMLAttributes<HTMLButtonElement> & {\n\t/**\n\t * Mark the item as the current page.\n\t * @default false\n\t */\n\tactive?: boolean;\n};\n\nexport function SidebarItem({ active = false, className, ...props }: SidebarItemProps) {\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\taria-current={active ? \"page\" : undefined}\n\t\t\tclassName={cn(\n\t\t\t\t\"flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-normal transition-colors\",\n\t\t\t\tactive\n\t\t\t\t\t? \"bg-basalt-accent text-basalt-foreground\"\n\t\t\t\t\t: \"text-basalt-muted-foreground hover:bg-basalt-accent hover:text-basalt-foreground\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport function SidebarIconItem({\n\tactive = false,\n\tclassName,\n\t...props\n}: ButtonHTMLAttributes<HTMLButtonElement> & { active?: boolean }) {\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\taria-current={active ? \"page\" : undefined}\n\t\t\tclassName={cn(\n\t\t\t\t\"relative flex h-10 w-10 items-center justify-center rounded-lg transition-colors\",\n\t\t\t\tactive\n\t\t\t\t\t? \"bg-basalt-accent text-basalt-foreground\"\n\t\t\t\t\t: \"text-basalt-muted-foreground hover:bg-basalt-accent hover:text-basalt-foreground\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport function SidebarGroup({\n\tlabel,\n\tdefaultOpen = true,\n\tchildren,\n}: {\n\tlabel: ReactNode;\n\tdefaultOpen?: boolean;\n\tchildren: ReactNode;\n}) {\n\tconst [open, setOpen] = useState(defaultOpen);\n\treturn (\n\t\t<Collapsible open={open} onOpenChange={setOpen}>\n\t\t\t<div className=\"mt-2 px-3\">\n\t\t\t\t<CollapsibleTrigger asChild>\n\t\t\t\t\t<button type=\"button\" className=\"flex w-full items-center justify-between px-3 py-2.5\">\n\t\t\t\t\t\t<span className=\"text-sm font-normal text-basalt-muted-foreground\">{label}</span>\n\t\t\t\t\t\t<span className=\"flex h-7 w-7 shrink-0 items-center justify-center\">\n\t\t\t\t\t\t\t<ChevronUp\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\"h-4 w-4 text-basalt-muted-foreground transition-transform duration-200\",\n\t\t\t\t\t\t\t\t\tOVERLAY_MOTION,\n\t\t\t\t\t\t\t\t\t!open && \"rotate-180\",\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\tstrokeWidth={1.5}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</button>\n\t\t\t\t</CollapsibleTrigger>\n\t\t\t</div>\n\t\t\t<CollapsibleContent unstyled>\n\t\t\t\t<div className=\"flex flex-col gap-0.5 px-3\">{children}</div>\n\t\t\t</CollapsibleContent>\n\t\t</Collapsible>\n\t);\n}\n\nexport function SidebarFooter({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n\treturn <div className={cn(\"px-4 py-3\", className)} {...props} />;\n}\n\nexport function SidebarUser({\n\tname,\n\temail,\n\tavatar,\n\taction,\n\tclassName,\n}: {\n\tname: ReactNode;\n\temail?: ReactNode;\n\tavatar?: ReactNode;\n\taction?: ReactNode;\n\tclassName?: string;\n}) {\n\treturn (\n\t\t<div className={cn(\"flex items-center gap-3\", className)}>\n\t\t\t{avatar}\n\t\t\t<div className=\"min-w-0 flex-1\">\n\t\t\t\t<p className=\"truncate text-sm font-medium text-basalt-foreground\">{name}</p>\n\t\t\t\t{email ? <p className=\"truncate text-xs text-basalt-muted-foreground\">{email}</p> : null}\n\t\t\t</div>\n\t\t\t{action}\n\t\t</div>\n\t);\n}\n\nexport function ContentIsland({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n\treturn (\n\t\t<div\n\t\t\tdata-basalt-surface-root=\"\"\n\t\t\tclassName={cn(\n\t\t\t\t\"min-h-0 flex-1 overflow-y-auto rounded-[16px] bg-basalt-card p-3 text-basalt-card-foreground shadow-sm ring-1 ring-basalt-border/40 md:rounded-basalt-island md:p-5\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sidebar.js","names":[],"sources":["../../src/components/sidebar.tsx"],"sourcesContent":["import * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { ChevronUp, Search } from \"lucide-react\";\nimport {\n\ttype ButtonHTMLAttributes,\n\tcreateContext,\n\ttype HTMLAttributes,\n\ttype ReactNode,\n\ttype PointerEvent as ReactPointerEvent,\n\ttype RefObject,\n\tuseCallback,\n\tuseContext,\n\tuseLayoutEffect,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from \"./collapsible\";\nimport { Dialog, DialogOverlay, DialogPortal } from \"./dialog\";\nimport { OVERLAY_LAYER, OVERLAY_MOTION } from \"./overlay\";\nimport { SkeletonLine } from \"./skeleton-line\";\n\nexport type SidebarSide = \"left\" | \"right\";\n\nexport interface SidebarContextValue {\n\t/**\n\t * Whether the sidebar is currently collapsed.\n\t */\n\tcollapsed: boolean;\n\t/**\n\t * Callback to update the collapsed state.\n\t */\n\tsetCollapsed: (next: boolean) => void;\n\t/**\n\t * Which edge the sidebar occupies.\n\t */\n\tside: SidebarSide;\n\t/**\n\t * Whether the sidebar is currently displaying a loading skeleton.\n\t */\n\tloading: boolean;\n\t/**\n\t * Whether the sidebar rail expands on pointer hover.\n\t */\n\tpeek: boolean;\n\t/**\n\t * Whether the sidebar is actively hovering in peek preview mode.\n\t */\n\tpeeking: boolean;\n\t/**\n\t * Callback to update the peek preview state.\n\t */\n\tsetPeeking: (next: boolean) => void;\n\t/**\n\t * Whether the sidebar is rendering as a modal overlay drawer instead of in-flow layout chrome.\n\t */\n\toverlay: boolean;\n\t/**\n\t * Current expanded width in pixels, clamped between 180 and 400.\n\t */\n\twidth: number;\n\t/**\n\t * Callback to update the sidebar width. Value is clamped between 180 and 400 pixels.\n\t */\n\tsetWidth: (next: number) => void;\n\t/**\n\t * Reference to the last active element that held focus before opening the sidebar drawer.\n\t */\n\tlastFocusRef: RefObject<HTMLElement | null>;\n}\n\nconst SidebarContext = createContext<SidebarContextValue | null>(null);\n\n/**\n * Accesses the sidebar context value. Must be used within a `SidebarProvider`; throws an error if called outside.\n * Returns the active sidebar state and control callbacks.\n */\nexport function useSidebar(): SidebarContextValue {\n\tconst context = useContext(SidebarContext);\n\tif (!context) {\n\t\tthrow new Error(\"useSidebar must be used within SidebarProvider\");\n\t}\n\treturn context;\n}\n\nexport type SidebarProviderProps = {\n\t/**\n\t * The controlled collapsed state.\n\t */\n\tcollapsed?: boolean;\n\t/**\n\t * The uncontrolled initial collapsed state.\n\t * @default false\n\t */\n\tdefaultCollapsed?: boolean;\n\t/**\n\t * Called when the collapsed state changes.\n\t */\n\tonCollapsedChange?: (collapsed: boolean) => void;\n\t/**\n\t * Which edge the sidebar occupies.\n\t * @default left\n\t */\n\tside?: SidebarSide;\n\t/**\n\t * Replace the nav with a loading skeleton.\n\t * @default false\n\t */\n\tloading?: boolean;\n\t/**\n\t * Expand the collapsed rail on hover.\n\t * @default false\n\t */\n\tpeek?: boolean;\n\t/**\n\t * Render as an overlay instead of in-flow chrome.\n\t * @default false\n\t */\n\toverlay?: boolean;\n\t/**\n\t * Initial expanded width in pixels, clamped between 180 and 400.\n\t * @default 260\n\t */\n\tdefaultWidth?: number;\n\t/**\n\t * Sidebar chrome and page content.\n\t */\n\tchildren: ReactNode;\n};\n\nexport function SidebarProvider({\n\tcollapsed,\n\tdefaultCollapsed = false,\n\tonCollapsedChange,\n\tside = \"left\",\n\tloading = false,\n\tpeek = false,\n\toverlay = false,\n\tdefaultWidth = 260,\n\tchildren,\n}: SidebarProviderProps) {\n\tconst [uncontrolled, setUncontrolled] = useState(defaultCollapsed);\n\tconst [peeking, setPeeking] = useState(false);\n\tconst [width, setWidthState] = useState(() => clampSidebarWidth(defaultWidth));\n\tconst setWidth = useCallback((next: number) => {\n\t\tsetWidthState(clampSidebarWidth(next));\n\t}, []);\n\tconst lastFocusRef = useRef<HTMLElement | null>(null);\n\tconst prevCollapsed = useRef(collapsed ?? defaultCollapsed);\n\tconst prevOverlay = useRef(overlay);\n\tconst resolved = collapsed ?? uncontrolled;\n\tuseLayoutEffect(() => {\n\t\tif (\n\t\t\toverlay &&\n\t\t\t!resolved &&\n\t\t\t(prevCollapsed.current || !prevOverlay.current) &&\n\t\t\tdocument.activeElement instanceof HTMLElement\n\t\t) {\n\t\t\tlastFocusRef.current = document.activeElement;\n\t\t}\n\t\tprevCollapsed.current = resolved;\n\t\tprevOverlay.current = overlay;\n\t});\n\tconst setCollapsed = useCallback(\n\t\t(next: boolean) => {\n\t\t\tif (!next && document.activeElement instanceof HTMLElement) {\n\t\t\t\tlastFocusRef.current = document.activeElement;\n\t\t\t}\n\t\t\tif (collapsed === undefined) {\n\t\t\t\tsetUncontrolled(next);\n\t\t\t}\n\t\t\tonCollapsedChange?.(next);\n\t\t},\n\t\t[collapsed, onCollapsedChange],\n\t);\n\treturn (\n\t\t<SidebarContext.Provider\n\t\t\tvalue={{\n\t\t\t\tcollapsed: resolved,\n\t\t\t\tsetCollapsed,\n\t\t\t\tside,\n\t\t\t\tloading,\n\t\t\t\tpeek,\n\t\t\t\tpeeking,\n\t\t\t\tsetPeeking,\n\t\t\t\toverlay,\n\t\t\t\twidth,\n\t\t\t\tsetWidth,\n\t\t\t\tlastFocusRef,\n\t\t\t}}\n\t\t>\n\t\t\t{children}\n\t\t</SidebarContext.Provider>\n\t);\n}\n\nexport type SidebarProps = HTMLAttributes<HTMLElement> & {\n\t/**\n\t * Collapse the rail when no provider is present.\n\t * @default false\n\t */\n\tcollapsed?: boolean;\n};\n\nfunction clampSidebarWidth(next: number) {\n\treturn Math.min(400, Math.max(180, next));\n}\n\nfunction SidebarResize({\n\tside,\n\twidth,\n\tonWidth,\n}: {\n\tside: SidebarSide;\n\twidth: number;\n\tonWidth: (next: number) => void;\n}) {\n\tconst onPointerDown = (event: ReactPointerEvent<HTMLDivElement>) => {\n\t\tevent.preventDefault();\n\t\tevent.currentTarget.setPointerCapture(event.pointerId);\n\t\tconst startX = event.clientX;\n\t\tconst startWidth = width;\n\t\tconst target = event.currentTarget;\n\t\tconst onMove = (move: PointerEvent) => {\n\t\t\tconst delta = side === \"right\" ? startX - move.clientX : move.clientX - startX;\n\t\t\tonWidth(clampSidebarWidth(startWidth + delta));\n\t\t};\n\t\tconst onUp = () => {\n\t\t\ttarget.removeEventListener(\"pointermove\", onMove);\n\t\t\ttarget.removeEventListener(\"pointerup\", onUp);\n\t\t\ttarget.removeEventListener(\"pointercancel\", onUp);\n\t\t};\n\t\ttarget.addEventListener(\"pointermove\", onMove);\n\t\ttarget.addEventListener(\"pointerup\", onUp);\n\t\ttarget.addEventListener(\"pointercancel\", onUp);\n\t};\n\treturn (\n\t\t<div\n\t\t\trole=\"separator\"\n\t\t\taria-orientation=\"vertical\"\n\t\t\taria-valuenow={width}\n\t\t\taria-valuemin={180}\n\t\t\taria-valuemax={400}\n\t\t\taria-label=\"Resize sidebar\"\n\t\t\ttabIndex={0}\n\t\t\tclassName={cn(\n\t\t\t\t\"absolute top-0 h-full w-1 cursor-col-resize bg-transparent\",\n\t\t\t\tside === \"right\" ? \"left-0\" : \"right-0\",\n\t\t\t)}\n\t\t\tonPointerDown={onPointerDown}\n\t\t\tonKeyDown={(event) => {\n\t\t\t\tif (event.key !== \"ArrowLeft\" && event.key !== \"ArrowRight\") {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tevent.preventDefault();\n\t\t\t\tconst dir = event.key === \"ArrowRight\" ? 1 : -1;\n\t\t\t\tconst delta = side === \"right\" ? -dir * 8 : dir * 8;\n\t\t\t\tonWidth(clampSidebarWidth(width + delta));\n\t\t\t}}\n\t\t/>\n\t);\n}\n\nexport function Sidebar({\n\tcollapsed: collapsedProp,\n\tclassName,\n\tchildren,\n\tonMouseEnter,\n\tonMouseLeave,\n\tstyle,\n\t...props\n}: SidebarProps) {\n\tconst context = useContext(SidebarContext);\n\tconst collapsed = context\n\t\t? context.collapsed && !(context.peek && context.peeking)\n\t\t: (collapsedProp ?? false);\n\tconst side = context?.side ?? \"left\";\n\tconst overlay = context?.overlay ?? false;\n\tconst width = context?.width ?? 260;\n\tconst body = context?.loading ? (\n\t\t<div className=\"flex flex-col gap-2 p-3\" role=\"status\" aria-live=\"polite\">\n\t\t\t<SkeletonLine />\n\t\t\t<SkeletonLine />\n\t\t\t<SkeletonLine />\n\t\t</div>\n\t) : (\n\t\tchildren\n\t);\n\tconst resize =\n\t\tcontext && !collapsed ? (\n\t\t\t<SidebarResize side={side} width={context.width} onWidth={context.setWidth} />\n\t\t) : null;\n\tconst frameClass = cn(\n\t\tBASALT_UI_CLASS,\n\t\t\"relative flex h-screen shrink-0 flex-col bg-basalt-background text-sm text-basalt-foreground\",\n\t\tOVERLAY_MOTION,\n\t\tclassName,\n\t);\n\tif (overlay && context) {\n\t\treturn (\n\t\t\t<Dialog open={!context.collapsed} onOpenChange={(open) => context.setCollapsed(!open)}>\n\t\t\t\t<DialogPortal>\n\t\t\t\t\t<DialogOverlay />\n\t\t\t\t\t<DialogPrimitive.Content\n\t\t\t\t\t\taria-label=\"Sidebar\"\n\t\t\t\t\t\tdata-overlay=\"\"\n\t\t\t\t\t\tdata-side={side}\n\t\t\t\t\t\taria-busy={context.loading || undefined}\n\t\t\t\t\t\tonMouseEnter={onMouseEnter}\n\t\t\t\t\t\tonMouseLeave={onMouseLeave}\n\t\t\t\t\t\tref={(node) => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tnode &&\n\t\t\t\t\t\t\t\tdocument.activeElement instanceof HTMLElement &&\n\t\t\t\t\t\t\t\t!node.contains(document.activeElement)\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tcontext.lastFocusRef.current = document.activeElement;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonOpenAutoFocus={(event) => {\n\t\t\t\t\t\t\tconst from = \"relatedTarget\" in event ? event.relatedTarget : null;\n\t\t\t\t\t\t\tif (from instanceof HTMLElement) {\n\t\t\t\t\t\t\t\tcontext.lastFocusRef.current = from;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonCloseAutoFocus={(event) => {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tcontext.lastFocusRef.current?.focus();\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\tframeClass,\n\t\t\t\t\t\t\tOVERLAY_LAYER,\n\t\t\t\t\t\t\t\"fixed inset-y-0 overflow-hidden shadow-md\",\n\t\t\t\t\t\t\tside === \"right\" ? \"right-0\" : \"left-0\",\n\t\t\t\t\t\t)}\n\t\t\t\t\t\tstyle={{ width, ...style }}\n\t\t\t\t\t\t{...props}\n\t\t\t\t\t>\n\t\t\t\t\t\t{body}\n\t\t\t\t\t\t{resize}\n\t\t\t\t\t</DialogPrimitive.Content>\n\t\t\t\t</DialogPortal>\n\t\t\t</Dialog>\n\t\t);\n\t}\n\treturn (\n\t\t<aside\n\t\t\tdata-collapsed={collapsed ? \"\" : undefined}\n\t\t\tdata-side={side}\n\t\t\taria-busy={context?.loading || undefined}\n\t\t\tonMouseEnter={(event) => {\n\t\t\t\tif (context?.peek && context.collapsed) {\n\t\t\t\t\tcontext.setPeeking(true);\n\t\t\t\t}\n\t\t\t\tonMouseEnter?.(event);\n\t\t\t}}\n\t\t\tonMouseLeave={(event) => {\n\t\t\t\tif (context?.peek) {\n\t\t\t\t\tcontext.setPeeking(false);\n\t\t\t\t}\n\t\t\t\tonMouseLeave?.(event);\n\t\t\t}}\n\t\t\tclassName={cn(\n\t\t\t\tframeClass,\n\t\t\t\t\"sticky top-0 transition-all duration-300 ease-in-out\",\n\t\t\t\tside === \"right\" ? \"order-last\" : undefined,\n\t\t\t\tcollapsed ? \"w-[68px] overflow-y-hidden\" : \"overflow-hidden\",\n\t\t\t)}\n\t\t\tstyle={!collapsed ? { width, ...style } : style}\n\t\t\t{...props}\n\t\t>\n\t\t\t{body}\n\t\t\t{resize}\n\t\t</aside>\n\t);\n}\n\nexport interface SidebarHeaderProps extends HTMLAttributes<HTMLDivElement> {}\n\nexport function SidebarHeader({ className, ...props }: SidebarHeaderProps) {\n\treturn <div className={cn(\"flex h-14 shrink-0 items-center px-3\", className)} {...props} />;\n}\n\n/**\n * Props for `SidebarSearch`. Renders a native `<button>` element and accepts all standard button HTML attributes and click handlers.\n */\nexport interface SidebarSearchProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n\t/**\n\t * Shortcut key display label rendered inside the trailing kbd tag. Note: this is a visual label only and does not register a global keyboard shortcut.\n\t * @default \"⌘K\"\n\t */\n\tshortcut?: string;\n}\n\nexport function SidebarSearch({\n\tshortcut = \"⌘K\",\n\tclassName,\n\tchildren,\n\t...props\n}: SidebarSearchProps) {\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"flex w-full cursor-pointer items-center gap-3 rounded-lg bg-basalt-secondary px-3 py-1.5 transition-colors hover:bg-basalt-accent\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<Search className=\"h-4 w-4 text-basalt-muted-foreground\" strokeWidth={1.5} />\n\t\t\t<span className=\"flex-1 text-left text-sm text-basalt-muted-foreground\">{children}</span>\n\t\t\t<kbd className=\"pointer-events-none hidden rounded-sm border border-basalt-border bg-basalt-card px-1.5 py-0.5 text-[10px] font-medium text-basalt-muted-foreground sm:inline-block\">\n\t\t\t\t{shortcut}\n\t\t\t</kbd>\n\t\t</button>\n\t);\n}\n\nexport interface SidebarNavProps extends HTMLAttributes<HTMLElement> {}\n\nexport function SidebarNav({ className, ...props }: SidebarNavProps) {\n\treturn (\n\t\t<nav className={cn(\"flex min-h-0 flex-1 flex-col overflow-y-auto\", className)} {...props} />\n\t);\n}\n\nexport interface SidebarPartitionProps extends HTMLAttributes<HTMLParagraphElement> {}\n\nexport function SidebarPartition({ className, ...props }: SidebarPartitionProps) {\n\treturn (\n\t\t<p\n\t\t\tclassName={cn(\n\t\t\t\t\"px-6 pt-3 pb-1 text-[11px] font-medium tracking-[0.14em] text-basalt-muted-foreground uppercase\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport type SidebarItemProps = ButtonHTMLAttributes<HTMLButtonElement> & {\n\t/**\n\t * Mark the item as the current page.\n\t * @default false\n\t */\n\tactive?: boolean;\n};\n\nexport function SidebarItem({ active = false, className, ...props }: SidebarItemProps) {\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\taria-current={active ? \"page\" : undefined}\n\t\t\tclassName={cn(\n\t\t\t\t\"flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-normal transition-colors\",\n\t\t\t\tactive\n\t\t\t\t\t? \"bg-basalt-accent text-basalt-foreground\"\n\t\t\t\t\t: \"text-basalt-muted-foreground hover:bg-basalt-accent hover:text-basalt-foreground\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\n/**\n * Props for `SidebarIconItem`. Accepts standard button HTML attributes. The caller is responsible for providing accessible labeling via `aria-label` or `aria-labelledby` as icon buttons do not automatically generate accessible names.\n */\nexport interface SidebarIconItemProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n\t/**\n\t * Mark the icon button as active page item.\n\t * @default false\n\t */\n\tactive?: boolean;\n}\n\nexport function SidebarIconItem({ active = false, className, ...props }: SidebarIconItemProps) {\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\taria-current={active ? \"page\" : undefined}\n\t\t\tclassName={cn(\n\t\t\t\t\"relative flex h-10 w-10 items-center justify-center rounded-lg transition-colors\",\n\t\t\t\tactive\n\t\t\t\t\t? \"bg-basalt-accent text-basalt-foreground\"\n\t\t\t\t\t: \"text-basalt-muted-foreground hover:bg-basalt-accent hover:text-basalt-foreground\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\n/**\n * Props for `SidebarGroup`. Uncontrolled collapsible section that accepts only the documented properties. It does not accept controlled open props or arbitrary DOM attributes.\n */\nexport interface SidebarGroupProps {\n\t/**\n\t * Section label displayed on the group trigger.\n\t */\n\tlabel: ReactNode;\n\t/**\n\t * Uncontrolled initial open state for the collapsible group.\n\t * @default true\n\t */\n\tdefaultOpen?: boolean;\n\t/**\n\t * Navigation items rendered inside the group.\n\t */\n\tchildren: ReactNode;\n}\n\nexport function SidebarGroup({ label, defaultOpen = true, children }: SidebarGroupProps) {\n\tconst [open, setOpen] = useState(defaultOpen);\n\treturn (\n\t\t<Collapsible open={open} onOpenChange={setOpen}>\n\t\t\t<div className=\"mt-2 px-3\">\n\t\t\t\t<CollapsibleTrigger asChild>\n\t\t\t\t\t<button type=\"button\" className=\"flex w-full items-center justify-between px-3 py-2.5\">\n\t\t\t\t\t\t<span className=\"text-sm font-normal text-basalt-muted-foreground\">{label}</span>\n\t\t\t\t\t\t<span className=\"flex h-7 w-7 shrink-0 items-center justify-center\">\n\t\t\t\t\t\t\t<ChevronUp\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\"h-4 w-4 text-basalt-muted-foreground transition-transform duration-200\",\n\t\t\t\t\t\t\t\t\tOVERLAY_MOTION,\n\t\t\t\t\t\t\t\t\t!open && \"rotate-180\",\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\tstrokeWidth={1.5}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</button>\n\t\t\t\t</CollapsibleTrigger>\n\t\t\t</div>\n\t\t\t<CollapsibleContent unstyled>\n\t\t\t\t<div className=\"flex flex-col gap-0.5 px-3\">{children}</div>\n\t\t\t</CollapsibleContent>\n\t\t</Collapsible>\n\t);\n}\n\nexport interface SidebarFooterProps extends HTMLAttributes<HTMLDivElement> {}\n\nexport function SidebarFooter({ className, ...props }: SidebarFooterProps) {\n\treturn <div className={cn(\"px-4 py-3\", className)} {...props} />;\n}\n\nexport interface SidebarUserProps {\n\t/**\n\t * User display name.\n\t */\n\tname: ReactNode;\n\t/**\n\t * Optional user email or secondary text.\n\t */\n\temail?: ReactNode;\n\t/**\n\t * Avatar element slot.\n\t */\n\tavatar?: ReactNode;\n\t/**\n\t * Trailing action slot (e.g. settings or logout button).\n\t */\n\taction?: ReactNode;\n\t/**\n\t * Additional CSS class name.\n\t */\n\tclassName?: string;\n}\n\nexport function SidebarUser({ name, email, avatar, action, className }: SidebarUserProps) {\n\treturn (\n\t\t<div className={cn(\"flex items-center gap-3\", className)}>\n\t\t\t{avatar}\n\t\t\t<div className=\"min-w-0 flex-1\">\n\t\t\t\t<p className=\"truncate text-sm font-medium text-basalt-foreground\">{name}</p>\n\t\t\t\t{email ? <p className=\"truncate text-xs text-basalt-muted-foreground\">{email}</p> : null}\n\t\t\t</div>\n\t\t\t{action}\n\t\t</div>\n\t);\n}\n\nexport interface ContentIslandProps extends HTMLAttributes<HTMLDivElement> {}\n\nexport function ContentIsland({ className, ...props }: ContentIslandProps) {\n\treturn (\n\t\t<div\n\t\t\tdata-basalt-surface-root=\"\"\n\t\t\tclassName={cn(\n\t\t\t\t\"min-h-0 flex-1 overflow-y-auto rounded-[16px] bg-basalt-card p-3 text-basalt-card-foreground shadow-sm ring-1 ring-basalt-border/40 md:rounded-basalt-island md:p-5\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,26 @@
|
|
|
1
1
|
import type { HTMLAttributes } from "react";
|
|
2
|
-
export
|
|
2
|
+
export interface SkeletonLineProps extends HTMLAttributes<HTMLDivElement> {
|
|
3
|
+
/**
|
|
4
|
+
* Minimum width percentage used for deterministic width computation.
|
|
5
|
+
*
|
|
6
|
+
* Note: Sorted with maxWidth to compute the midpoint width percentage.
|
|
7
|
+
*
|
|
8
|
+
* @default 30
|
|
9
|
+
*/
|
|
3
10
|
minWidth?: number;
|
|
11
|
+
/**
|
|
12
|
+
* Maximum width percentage used for deterministic width computation.
|
|
13
|
+
*
|
|
14
|
+
* Note: Sorted with minWidth to compute the midpoint width percentage.
|
|
15
|
+
*
|
|
16
|
+
* @default 100
|
|
17
|
+
*/
|
|
4
18
|
maxWidth?: number;
|
|
19
|
+
/**
|
|
20
|
+
* Explicit height of the skeleton line in pixels.
|
|
21
|
+
*
|
|
22
|
+
* Note: When omitted, default height is governed by CSS class tokens (h-2).
|
|
23
|
+
*/
|
|
5
24
|
height?: number;
|
|
6
|
-
}
|
|
25
|
+
}
|
|
26
|
+
export declare function SkeletonLine({ className, minWidth, maxWidth, height, style, ...props }: SkeletonLineProps): import("react").JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skeleton-line.js","names":[],"sources":["../../src/components/skeleton-line.tsx"],"sourcesContent":["import type { CSSProperties, HTMLAttributes } from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport
|
|
1
|
+
{"version":3,"file":"skeleton-line.js","names":[],"sources":["../../src/components/skeleton-line.tsx"],"sourcesContent":["import type { CSSProperties, HTMLAttributes } from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport interface SkeletonLineProps extends HTMLAttributes<HTMLDivElement> {\n\t/**\n\t * Minimum width percentage used for deterministic width computation.\n\t *\n\t * Note: Sorted with maxWidth to compute the midpoint width percentage.\n\t *\n\t * @default 30\n\t */\n\tminWidth?: number;\n\n\t/**\n\t * Maximum width percentage used for deterministic width computation.\n\t *\n\t * Note: Sorted with minWidth to compute the midpoint width percentage.\n\t *\n\t * @default 100\n\t */\n\tmaxWidth?: number;\n\n\t/**\n\t * Explicit height of the skeleton line in pixels.\n\t *\n\t * Note: When omitted, default height is governed by CSS class tokens (h-2).\n\t */\n\theight?: number;\n}\n\nexport function SkeletonLine({\n\tclassName,\n\tminWidth = 30,\n\tmaxWidth = 100,\n\theight,\n\tstyle,\n\t...props\n}: SkeletonLineProps) {\n\tconst low = Math.min(minWidth, maxWidth);\n\tconst high = Math.max(minWidth, maxWidth);\n\tconst width = (low + high) / 2;\n\tconst lineStyle: CSSProperties = {\n\t\twidth: `${width}%`,\n\t\t...(height !== undefined ? { height } : {}),\n\t\t...style,\n\t};\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\"relative h-2 overflow-hidden rounded-sm bg-basalt-muted\", className)}\n\t\t\tstyle={lineStyle}\n\t\t\taria-hidden=\"true\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<span className=\"pointer-events-none absolute inset-0 animate-basalt-shimmer bg-gradient-to-r from-transparent via-black/10 to-transparent motion-reduce:animate-none\" />\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;AA8BA,SAAgB,EAAa,EAC5B,cACA,cAAW,IACX,cAAW,KACX,WACA,UACA,GAAG,KACkB;CAIrB,IAAM,IAA2B;EAChC,OAAO,IAJI,KAAK,IAAI,GAAU,CAEhB,IADF,KAAK,IAAI,GAAU,CACX,KAAQ,EAEZ;EAChB,GAAI,MAAW,KAAA,IAAyB,CAAC,IAAd,EAAE,UAAO;EACpC,GAAG;CACJ;CACA,OACC,kBAAC,OAAD;EACC,WAAW,EAAG,2DAA2D,CAAS;EAClF,OAAO;EACP,eAAY;EACZ,GAAI;EAEJ,UAAA,kBAAC,QAAD,EAAM,WAAU,uJAAwJ,CAAA;CACpK,CAAA;AAEP"}
|
|
@@ -1,3 +1,63 @@
|
|
|
1
1
|
import * as SliderPrimitive from "@radix-ui/react-slider";
|
|
2
2
|
import * as React from "react";
|
|
3
|
-
|
|
3
|
+
type RadixSliderRootProps = React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root>;
|
|
4
|
+
export interface SliderProps extends Omit<RadixSliderRootProps, "value" | "defaultValue" | "onValueChange" | "onValueCommit" | "disabled" | "name" | "min" | "max" | "step" | "orientation"> {
|
|
5
|
+
/**
|
|
6
|
+
* Controlled value array for the slider. Forwards ref to root span element.
|
|
7
|
+
* When multiple values are provided, renders a thumb for each value.
|
|
8
|
+
*/
|
|
9
|
+
value?: RadixSliderRootProps["value"];
|
|
10
|
+
/**
|
|
11
|
+
* Uncontrolled default value array for the slider.
|
|
12
|
+
* When multiple values are provided, renders a thumb for each value.
|
|
13
|
+
* @default [min ?? 0]
|
|
14
|
+
*/
|
|
15
|
+
defaultValue?: RadixSliderRootProps["defaultValue"];
|
|
16
|
+
/**
|
|
17
|
+
* Callback invoked when slider value changes during interaction.
|
|
18
|
+
*/
|
|
19
|
+
onValueChange?: RadixSliderRootProps["onValueChange"];
|
|
20
|
+
/**
|
|
21
|
+
* Callback invoked when slider interaction finishes and value is committed.
|
|
22
|
+
*/
|
|
23
|
+
onValueCommit?: RadixSliderRootProps["onValueCommit"];
|
|
24
|
+
/**
|
|
25
|
+
* Whether the slider is disabled from user interaction.
|
|
26
|
+
* @default false
|
|
27
|
+
*/
|
|
28
|
+
disabled?: RadixSliderRootProps["disabled"];
|
|
29
|
+
/**
|
|
30
|
+
* Form field name submitted with the slider values.
|
|
31
|
+
*/
|
|
32
|
+
name?: RadixSliderRootProps["name"];
|
|
33
|
+
/**
|
|
34
|
+
* Minimum allowable value.
|
|
35
|
+
* @default 0
|
|
36
|
+
*/
|
|
37
|
+
min?: RadixSliderRootProps["min"];
|
|
38
|
+
/**
|
|
39
|
+
* Maximum allowable value.
|
|
40
|
+
* @default 100
|
|
41
|
+
*/
|
|
42
|
+
max?: RadixSliderRootProps["max"];
|
|
43
|
+
/**
|
|
44
|
+
* Step interval between selectable values.
|
|
45
|
+
* @default 1
|
|
46
|
+
*/
|
|
47
|
+
step?: RadixSliderRootProps["step"];
|
|
48
|
+
/**
|
|
49
|
+
* Layout orientation of the slider track.
|
|
50
|
+
* When set to `"vertical"`, the slider track and range align vertically. A container with an explicit height is required.
|
|
51
|
+
* @default "horizontal"
|
|
52
|
+
*/
|
|
53
|
+
orientation?: RadixSliderRootProps["orientation"];
|
|
54
|
+
/**
|
|
55
|
+
* Accessible labels for thumbs when rendering single or multiple values.
|
|
56
|
+
* When provided, thumb at index `i` receives `labels[i]`. For a single thumb, `labels[0]` takes precedence over `aria-label`.
|
|
57
|
+
* When omitted on a multi-value slider, the root `aria-label` provides a contextual fallback (e.g. `ariaLabel + " minimum"`),
|
|
58
|
+
* or falls back to Radix default names (`"Minimum"`, `"Maximum"`, or `"Value N of Total"`).
|
|
59
|
+
*/
|
|
60
|
+
labels?: string[];
|
|
61
|
+
}
|
|
62
|
+
export declare const Slider: React.ForwardRefExoticComponent<SliderProps & React.RefAttributes<HTMLSpanElement>>;
|
|
63
|
+
export {};
|