@agent-factory-platform/ui-kit 0.7.1 → 0.9.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.
Files changed (90) hide show
  1. package/README.md +22 -0
  2. package/dist/charts/adapter.js +111 -0
  3. package/dist/charts/basic.d.ts +2 -0
  4. package/dist/charts/basic.js +115 -0
  5. package/dist/charts/chart-tooltip.js +21 -0
  6. package/dist/charts/event-markers-primitive.d.ts +10 -1
  7. package/dist/charts/event-markers-primitive.js +116 -0
  8. package/dist/charts/index.d.ts +1 -0
  9. package/dist/charts/ohlc-annotations.d.ts +56 -0
  10. package/dist/charts/ohlc-annotations.js +84 -0
  11. package/dist/charts/ohlc.d.ts +5 -1
  12. package/dist/charts/ohlc.js +240 -0
  13. package/dist/charts/series.js +584 -0
  14. package/dist/charts/theme.js +35 -0
  15. package/dist/charts/time-combo.js +17 -0
  16. package/dist/component-api.js +3 -5
  17. package/dist/component-api.json.js +9 -0
  18. package/dist/component-manifest.json.js +9 -0
  19. package/dist/components/alert.js +35 -0
  20. package/dist/components/avatar.js +101 -0
  21. package/dist/components/badge.js +111 -0
  22. package/dist/components/button-group.js +22 -0
  23. package/dist/components/button.js +64 -0
  24. package/dist/components/calendar-period-navigator.js +34 -0
  25. package/dist/components/card.js +35 -0
  26. package/dist/components/chart-frame.js +53 -0
  27. package/dist/components/color-picker.js +155 -0
  28. package/dist/components/combobox.js +129 -0
  29. package/dist/components/command-dialog.js +89 -0
  30. package/dist/components/confirm-dialog.js +57 -0
  31. package/dist/components/data-table.js +135 -0
  32. package/dist/components/date-time.js +203 -0
  33. package/dist/components/disclosure.js +29 -0
  34. package/dist/components/drawer.js +150 -0
  35. package/dist/components/dropdown-select.js +191 -0
  36. package/dist/components/field.js +21 -0
  37. package/dist/components/floating-window.js +159 -0
  38. package/dist/components/heading.js +21 -0
  39. package/dist/components/hover-tip.js +90 -0
  40. package/dist/components/icon-tip.js +12 -0
  41. package/dist/components/input-group.js +16 -0
  42. package/dist/components/input-otp.js +56 -0
  43. package/dist/components/input.js +44 -0
  44. package/dist/components/item.js +47 -0
  45. package/dist/components/kbd.js +18 -0
  46. package/dist/components/line-chart.js +79 -0
  47. package/dist/components/listbox.js +33 -0
  48. package/dist/components/live-value.js +26 -0
  49. package/dist/components/modal.js +140 -0
  50. package/dist/components/multi-select.js +54 -0
  51. package/dist/components/native-select.js +17 -0
  52. package/dist/components/navigation.js +42 -0
  53. package/dist/components/page.js +24 -0
  54. package/dist/components/popover-menu.js +164 -0
  55. package/dist/components/progress.js +23 -0
  56. package/dist/components/resizable-pane.js +73 -0
  57. package/dist/components/scroll-load-more.js +61 -0
  58. package/dist/components/seg-slider.js +42 -0
  59. package/dist/components/segmented-control.js +46 -0
  60. package/dist/components/selection-controls.js +119 -0
  61. package/dist/components/sidebar.js +23 -0
  62. package/dist/components/skeleton.js +9 -0
  63. package/dist/components/slider.js +162 -0
  64. package/dist/components/sliding-tabs.js +118 -0
  65. package/dist/components/spinner.js +9 -0
  66. package/dist/components/spotlight-tour.js +122 -0
  67. package/dist/components/stat-card.js +23 -0
  68. package/dist/components/state-view.js +75 -0
  69. package/dist/components/stats-table.js +17 -0
  70. package/dist/components/table.js +24 -0
  71. package/dist/components/tag-pill.d.ts +4 -1
  72. package/dist/components/tag-pill.js +69 -0
  73. package/dist/components/theme-editor.js +159 -0
  74. package/dist/components/toast.js +66 -0
  75. package/dist/components/toolbar.js +46 -0
  76. package/dist/components/utility.js +19 -0
  77. package/dist/components/widget-frame.js +41 -0
  78. package/dist/components/widget-picker.js +87 -0
  79. package/dist/components/workspace-grid.js +468 -0
  80. package/dist/focus-modality.js +3 -15
  81. package/dist/index.d.ts +1 -1
  82. package/dist/index.js +228 -5564
  83. package/dist/lib/cn.js +6 -0
  84. package/dist/lib/focus-modality.js +16 -0
  85. package/dist/lib/motion.js +27 -0
  86. package/dist/lib/viewport.js +13 -0
  87. package/dist/manifest.js +5 -7
  88. package/dist/styles.js +1 -1
  89. package/dist/theme.js +158 -0
  90. package/package.json +1 -1
@@ -0,0 +1,162 @@
1
+ import { jsx as a, jsxs as P, Fragment as U } from "react/jsx-runtime";
2
+ import { useRef as I, useState as X, useCallback as A } from "react";
3
+ import { Slider as w } from "radix-ui";
4
+ import { cn as M } from "../lib/cn.js";
5
+ function _({
6
+ value: t,
7
+ min: r = 0,
8
+ max: o = 100,
9
+ step: i = 1,
10
+ density: d = "default",
11
+ onChange: n,
12
+ onCommit: l,
13
+ disabled: s = !1,
14
+ ariaLabel: k,
15
+ formatValue: c,
16
+ marks: f = [],
17
+ variant: u = "plain",
18
+ className: $,
19
+ testId: S
20
+ }) {
21
+ const z = I(null), [y, v] = X(!1), h = A(
22
+ (e) => {
23
+ const g = Math.round((e - r) / i) * i + r, x = (i.toString().split(".")[1] ?? "").length;
24
+ return parseFloat(Math.min(o, Math.max(r, g)).toFixed(x));
25
+ },
26
+ [r, o, i]
27
+ ), p = u === "boxed" ? 8 : u === "allocation" ? 2 : 0, N = A(
28
+ (e) => {
29
+ const g = z.current;
30
+ if (!g) return t;
31
+ const { left: x, width: D } = g.getBoundingClientRect(), R = Math.max(1, D - p * 2), T = Math.min(1, Math.max(0, (e - x - p) / R));
32
+ return h(r + (o - r) * T);
33
+ },
34
+ [p, r, o, h, t]
35
+ ), b = Math.min(100, Math.max(0, (t - r) / (o - r) * 100));
36
+ return /* @__PURE__ */ a(
37
+ "div",
38
+ {
39
+ ref: z,
40
+ role: "slider",
41
+ "aria-disabled": s || void 0,
42
+ "aria-valuemin": r,
43
+ "aria-valuemax": o,
44
+ "aria-valuenow": t,
45
+ "aria-valuetext": c == null ? void 0 : c(t),
46
+ "aria-label": k,
47
+ "data-density": d,
48
+ "data-variant": u,
49
+ tabIndex: s ? -1 : 0,
50
+ "data-testid": S,
51
+ onPointerDown: (e) => {
52
+ s || (e.currentTarget.setPointerCapture(e.pointerId), v(!0), n(N(e.clientX)));
53
+ },
54
+ onPointerMove: (e) => {
55
+ s || !y || n(N(e.clientX));
56
+ },
57
+ onPointerUp: (e) => {
58
+ e.currentTarget.hasPointerCapture(e.pointerId) && e.currentTarget.releasePointerCapture(e.pointerId), !(!y || s) && (v(!1), l == null || l(N(e.clientX)));
59
+ },
60
+ onPointerCancel: () => v(!1),
61
+ onKeyDown: (e) => {
62
+ s || ((e.key === "ArrowLeft" || e.key === "ArrowDown") && n(h(t - i)), (e.key === "ArrowRight" || e.key === "ArrowUp") && n(h(t + i)), e.key === "Home" && n(r), e.key === "End" && n(o), e.key === "PageDown" && n(h(t - i * 10)), e.key === "PageUp" && n(h(t + i * 10)));
63
+ },
64
+ onKeyUp: (e) => {
65
+ !s && ["ArrowLeft", "ArrowDown", "ArrowRight", "ArrowUp", "Home", "End", "PageDown", "PageUp"].includes(e.key) && (l == null || l(t));
66
+ },
67
+ onBlur: () => {
68
+ s || l == null || l(t);
69
+ },
70
+ className: M(
71
+ "group relative w-full shrink-0 touch-none cursor-pointer select-none outline-none focus-visible:ring-2 focus-visible:ring-rust/35 focus-visible:ring-offset-2 focus-visible:ring-offset-surface-canvas",
72
+ s && "cursor-not-allowed opacity-50",
73
+ u === "boxed" || u === "allocation" ? "h-control-default overflow-hidden rounded-control border border-border bg-surface-raised" : d === "compact" ? "h-6" : "h-control-touch",
74
+ $
75
+ ),
76
+ children: /* @__PURE__ */ P("div", { className: "absolute inset-y-0", style: { left: p, right: p }, children: [
77
+ u === "allocation" ? /* @__PURE__ */ P(U, { children: [
78
+ /* @__PURE__ */ a("div", { "data-slot": "allocation-track", className: "absolute inset-y-0 w-full bg-surface-raised" }),
79
+ /* @__PURE__ */ a(
80
+ "div",
81
+ {
82
+ "data-slot": "allocation-fill",
83
+ "data-risk": b >= 75 ? "high" : b >= 50 ? "medium" : "low",
84
+ className: "absolute inset-y-0 left-0 bg-rust/30",
85
+ style: { width: `${b}%` }
86
+ }
87
+ )
88
+ ] }) : /* @__PURE__ */ a("div", { "data-slot": "slider-track", className: "absolute top-1/2 h-slider-track w-full -translate-y-1/2 rounded-full bg-dove/40" }),
89
+ f.map((e) => {
90
+ const g = Math.min(100, Math.max(0, (e - r) / (o - r) * 100));
91
+ return /* @__PURE__ */ a("span", { "data-slider-mark": !0, "aria-hidden": !0, className: M("pointer-events-none absolute top-1/2 -translate-x-1/2 -translate-y-1/2", u === "allocation" ? "h-3 w-px rounded-full bg-graphite/70 shadow-[0_0_0_1px_var(--color-surface-canvas)]" : "size-1 rounded-full bg-graphite/70 ring-1 ring-surface-canvas"), style: { left: `${g}%` } }, e);
92
+ }),
93
+ u !== "allocation" && /* @__PURE__ */ a("div", { "data-slot": "slider-range", className: "absolute top-1/2 h-slider-track -translate-y-1/2 rounded-full bg-rust", style: { width: `${b}%` } }),
94
+ u === "allocation" ? /* @__PURE__ */ a(
95
+ "div",
96
+ {
97
+ "data-slot": "allocation-thumb",
98
+ className: M("absolute top-1/2 z-10 h-6 w-1 -translate-x-1/2 -translate-y-1/2 rounded-full border border-on-accent/70 bg-rust shadow-subtle transition-transform", y && "scale-y-110"),
99
+ style: { left: `${b}%` }
100
+ }
101
+ ) : /* @__PURE__ */ a("div", { "data-slot": "slider-thumb", className: ["absolute top-1/2 z-10 -translate-x-1/2 -translate-y-1/2 rounded-full bg-rust ring-2 ring-pure-white shadow-subtle transition-transform", d === "compact" ? "size-slider-thumb-compact" : "size-slider-thumb-default", y ? "scale-110" : "group-hover:scale-110 group-focus:scale-110"].join(" "), style: { left: `${b}%` } })
102
+ ] })
103
+ }
104
+ );
105
+ }
106
+ function H(t) {
107
+ return /* @__PURE__ */ a(_, { ...t, density: "compact", variant: "allocation" });
108
+ }
109
+ function K({
110
+ value: t,
111
+ min: r = 0,
112
+ max: o = 100,
113
+ step: i = 1,
114
+ density: d = "default",
115
+ onChange: n,
116
+ onCommit: l,
117
+ lowerLabel: s,
118
+ upperLabel: k,
119
+ formatValue: c
120
+ }) {
121
+ return /* @__PURE__ */ P(
122
+ w.Root,
123
+ {
124
+ value: t,
125
+ min: r,
126
+ max: o,
127
+ step: i,
128
+ minStepsBetweenThumbs: 1,
129
+ "data-density": d,
130
+ "data-focus-shell": !0,
131
+ onValueChange: (f) => n([f[0], f[1]]),
132
+ onValueCommit: (f) => l == null ? void 0 : l([f[0], f[1]]),
133
+ className: `relative flex w-full touch-none select-none items-center outline-none has-[:focus-visible]:ring-2 has-[:focus-visible]:ring-rust/35 ${d === "compact" ? "h-6" : "h-control-touch"}`,
134
+ children: [
135
+ /* @__PURE__ */ a(w.Track, { "data-slot": "slider-track", className: "relative h-slider-track w-full grow overflow-hidden rounded-full bg-dove/40", children: /* @__PURE__ */ a(w.Range, { "data-slot": "slider-range", className: "absolute h-full bg-rust" }) }),
136
+ /* @__PURE__ */ a(
137
+ w.Thumb,
138
+ {
139
+ "data-slot": "slider-thumb-lower",
140
+ "aria-label": s,
141
+ "aria-valuetext": c == null ? void 0 : c(t[0]),
142
+ className: `block rounded-full bg-rust ring-2 ring-pure-white shadow-subtle outline-none focus-visible:ring-rust ${d === "compact" ? "size-slider-thumb-compact" : "size-slider-thumb-default"}`
143
+ }
144
+ ),
145
+ /* @__PURE__ */ a(
146
+ w.Thumb,
147
+ {
148
+ "data-slot": "slider-thumb-upper",
149
+ "aria-label": k,
150
+ "aria-valuetext": c == null ? void 0 : c(t[1]),
151
+ className: `block rounded-full bg-rust ring-2 ring-pure-white shadow-subtle outline-none focus-visible:ring-rust ${d === "compact" ? "size-slider-thumb-compact" : "size-slider-thumb-default"}`
152
+ }
153
+ )
154
+ ]
155
+ }
156
+ );
157
+ }
158
+ export {
159
+ H as AllocationSlider,
160
+ K as RangeSlider,
161
+ _ as Slider
162
+ };
@@ -0,0 +1,118 @@
1
+ import { jsxs as b, jsx as g, Fragment as I } from "react/jsx-runtime";
2
+ import { useState as L, useRef as x, useLayoutEffect as R } from "react";
3
+ import { cn as K } from "../lib/cn.js";
4
+ function S(r) {
5
+ const s = x(null), c = x(/* @__PURE__ */ new Map()), i = x(null), d = x(!1);
6
+ return R(() => {
7
+ const o = () => {
8
+ const a = c.current.get(r), p = i.current;
9
+ !a || !p || (p.style.transform = `translateX(${a.offsetLeft}px)`, p.style.width = `${a.offsetWidth}px`);
10
+ };
11
+ o(), d.current || requestAnimationFrame(() => {
12
+ var a;
13
+ (a = i.current) == null || a.classList.add("is-ready"), d.current = !0;
14
+ });
15
+ const n = new ResizeObserver(o);
16
+ return s.current && n.observe(s.current), () => n.disconnect();
17
+ }, [r]), { listRef: s, indRef: i, setBtn: (o) => (n) => {
18
+ n ? c.current.set(o, n) : c.current.delete(o);
19
+ }, focusTab: (o) => {
20
+ var n;
21
+ return (n = c.current.get(o)) == null ? void 0 : n.focus();
22
+ } };
23
+ }
24
+ function j({
25
+ tabs: r,
26
+ value: s,
27
+ onChange: c,
28
+ onReorder: i,
29
+ size: d = "md",
30
+ variant: l = "underline",
31
+ className: w,
32
+ ariaLabel: o
33
+ }) {
34
+ const { listRef: n, indRef: a, setBtn: p, focusTab: N } = S(s), [m, h] = L(null), [D, k] = L(null), A = d === "sm" ? "text-body-sm" : "text-body", u = !!i;
35
+ return /* @__PURE__ */ b(
36
+ "div",
37
+ {
38
+ ref: n,
39
+ role: "tablist",
40
+ "aria-label": o,
41
+ "aria-orientation": "horizontal",
42
+ "data-variant": l,
43
+ className: K("relative flex items-center overflow-x-auto", l === "toolbar" ? "gap-1" : d === "sm" ? "gap-4" : "gap-5", w),
44
+ children: [
45
+ r.map((e) => /* @__PURE__ */ b(
46
+ "button",
47
+ {
48
+ ref: p(e.key),
49
+ type: "button",
50
+ role: "tab",
51
+ "data-testid": e.testId,
52
+ "aria-selected": s === e.key,
53
+ tabIndex: s === e.key ? 0 : -1,
54
+ draggable: u,
55
+ onClick: () => c(e.key),
56
+ onKeyDown: (t) => {
57
+ var T;
58
+ const f = r.findIndex((E) => E.key === e.key);
59
+ let y = f;
60
+ if (t.key === "ArrowRight") y = (f + 1) % r.length;
61
+ else if (t.key === "ArrowLeft") y = (f - 1 + r.length) % r.length;
62
+ else if (t.key === "Home") y = 0;
63
+ else if (t.key === "End") y = r.length - 1;
64
+ else return;
65
+ t.preventDefault();
66
+ const v = (T = r[y]) == null ? void 0 : T.key;
67
+ v != null && (c(v), requestAnimationFrame(() => N(v)));
68
+ },
69
+ onDragStart: u ? (t) => {
70
+ h(e.key), t.dataTransfer.effectAllowed = "move", t.dataTransfer.setData("text/plain", e.key);
71
+ } : void 0,
72
+ onDragEnd: u ? () => {
73
+ h(null), k(null);
74
+ } : void 0,
75
+ onDragOver: u ? (t) => {
76
+ t.preventDefault(), t.dataTransfer.dropEffect = "move", D !== e.key && k(e.key);
77
+ } : void 0,
78
+ onDrop: u ? (t) => {
79
+ t.preventDefault();
80
+ const f = t.dataTransfer.getData("text/plain") || m;
81
+ f && f !== e.key && (i == null || i(f, e.key)), h(null), k(null);
82
+ } : void 0,
83
+ className: K(
84
+ "relative whitespace-nowrap font-sohne outline-none transition focus-visible:ring-2 focus-visible:ring-rust/35",
85
+ l === "toolbar" ? "inline-flex h-6 min-h-6 items-center rounded-control border px-2 text-micro" : "min-h-control-default px-0.5 pb-2 pt-1",
86
+ l === "toolbar" ? void 0 : A,
87
+ s === e.key ? l === "toolbar" ? "border-border bg-surface-muted font-[500] text-ink" : "font-[480] text-ink" : l === "toolbar" ? "border-transparent text-graphite hover:bg-surface-hover hover:text-ink" : "text-graphite hover:text-ink",
88
+ u && "cursor-grab active:cursor-grabbing",
89
+ m === e.key && "opacity-40",
90
+ D === e.key && m && m !== e.key && "text-ink"
91
+ ),
92
+ children: [
93
+ e.label,
94
+ e.count !== void 0 && /* @__PURE__ */ g("span", { className: "ml-1.5 text-caption text-graphite", children: e.count }),
95
+ e.live && /* @__PURE__ */ b(I, { children: [
96
+ /* @__PURE__ */ g("span", { className: "sr-only", children: e.liveLabel ?? "Live" }),
97
+ /* @__PURE__ */ g(
98
+ "span",
99
+ {
100
+ title: e.liveLabel,
101
+ className: "absolute -right-2 top-0 h-1.5 w-1.5 animate-pulse rounded-full bg-up",
102
+ "aria-hidden": !0
103
+ }
104
+ )
105
+ ] })
106
+ ]
107
+ },
108
+ e.key
109
+ )),
110
+ l === "underline" && /* @__PURE__ */ g("span", { ref: a, className: "t-tab-underline", "aria-hidden": !0 })
111
+ ]
112
+ }
113
+ );
114
+ }
115
+ export {
116
+ j as SlidingTabs,
117
+ S as useSlideIndicator
118
+ };
@@ -0,0 +1,9 @@
1
+ import { jsx as r } from "react/jsx-runtime";
2
+ import { LoaderCircle as t } from "lucide-react";
3
+ import { cn as n } from "../lib/cn.js";
4
+ function c({ label: a, size: e = "default", className: i }) {
5
+ return /* @__PURE__ */ r("span", { role: "status", "aria-label": a, "data-size": e, className: n("inline-grid shrink-0 place-items-center text-graphite", i), children: /* @__PURE__ */ r(t, { size: e === "compact" ? 14 : 18, className: "animate-spin", "aria-hidden": !0 }) });
6
+ }
7
+ export {
8
+ c as Spinner
9
+ };
@@ -0,0 +1,122 @@
1
+ import { jsxs as k, jsx as h } from "react/jsx-runtime";
2
+ import { useRef as R, useState as S, useLayoutEffect as z, useEffect as D } from "react";
3
+ import { createPortal as A } from "react-dom";
4
+ import { motion as G } from "motion/react";
5
+ import { cn as P } from "../lib/cn.js";
6
+ import { transitions as T } from "../lib/motion.js";
7
+ const a = 12, d = 12, v = 6, g = (t, e, o) => Math.max(e, Math.min(o, t));
8
+ function C(t, e, o) {
9
+ const p = window.innerWidth, c = window.innerHeight;
10
+ if (!t)
11
+ return {
12
+ top: (c - e.height) / 2,
13
+ left: (p - e.width) / 2,
14
+ placement: "center",
15
+ arrow: 0
16
+ };
17
+ const b = t.left + t.width / 2, w = t.top + t.height / 2, r = {
18
+ bottom: t.top + t.height + a + e.height <= c - d,
19
+ top: t.top - a - e.height >= d,
20
+ right: t.left + t.width + a + e.width <= p - d,
21
+ left: t.left - a - e.width >= d
22
+ }, s = (o && o !== "auto" ? [o, "bottom", "top", "right", "left"] : ["bottom", "top", "right", "left"]).find((u) => r[u]) ?? "bottom";
23
+ let l, n;
24
+ s === "bottom" || s === "top" ? (n = g(b - e.width / 2, d, p - d - e.width), l = s === "bottom" ? t.top + t.height + a : t.top - a - e.height) : (l = g(w - e.height / 2, d, c - d - e.height), n = s === "right" ? t.left + t.width + a : t.left - a - e.width);
25
+ const f = s === "bottom" || s === "top" ? g(b - n, 20, e.width - 20) : g(w - l, 20, e.height - 20);
26
+ return { top: l, left: n, placement: s, arrow: f };
27
+ }
28
+ function I({ placement: t, offset: e }) {
29
+ const o = "absolute size-2.5 rotate-45 border border-border bg-surface-raised";
30
+ return t === "bottom" ? /* @__PURE__ */ h("span", { "aria-hidden": !0, className: o, style: { top: -5, left: e - 5 } }) : t === "top" ? /* @__PURE__ */ h("span", { "aria-hidden": !0, className: o, style: { bottom: -5, left: e - 5 } }) : t === "right" ? /* @__PURE__ */ h("span", { "aria-hidden": !0, className: o, style: { left: -5, top: e - 5 } }) : t === "left" ? /* @__PURE__ */ h("span", { "aria-hidden": !0, className: o, style: { right: -5, top: e - 5 } }) : null;
31
+ }
32
+ function F({
33
+ open: t,
34
+ label: e,
35
+ target: o = null,
36
+ preferredPlacement: p = "auto",
37
+ onEscape: c,
38
+ children: b,
39
+ className: w
40
+ }) {
41
+ const r = R(null), [x, s] = S({ width: 320, height: 180 });
42
+ if (z(() => {
43
+ if (!t || !r.current) return;
44
+ const n = r.current, f = () => {
45
+ const m = n.getBoundingClientRect();
46
+ s((i) => i.width === m.width && i.height === m.height ? i : { width: m.width, height: m.height });
47
+ };
48
+ if (f(), typeof ResizeObserver > "u") return;
49
+ const u = new ResizeObserver(f);
50
+ return u.observe(n), () => u.disconnect();
51
+ }, [b, t, o]), D(() => {
52
+ if (!t) return;
53
+ const n = document.activeElement, f = document.body.style.overflow, u = (i) => {
54
+ if (i.key === "Escape") {
55
+ c();
56
+ return;
57
+ }
58
+ if (i.key !== "Tab" || !r.current) return;
59
+ const y = r.current.querySelectorAll(
60
+ 'a[href],button:not([disabled]),input:not([disabled]),[tabindex]:not([tabindex="-1"])'
61
+ );
62
+ if (y.length === 0) {
63
+ i.preventDefault();
64
+ return;
65
+ }
66
+ const N = y[0], E = y[y.length - 1];
67
+ i.shiftKey && (document.activeElement === N || document.activeElement === r.current) ? (i.preventDefault(), E.focus()) : !i.shiftKey && document.activeElement === E && (i.preventDefault(), N.focus());
68
+ };
69
+ document.body.style.overflow = "hidden", document.addEventListener("keydown", u);
70
+ const m = requestAnimationFrame(() => {
71
+ var i;
72
+ return (i = r.current) == null ? void 0 : i.focus();
73
+ });
74
+ return () => {
75
+ var i;
76
+ cancelAnimationFrame(m), document.removeEventListener("keydown", u), document.body.style.overflow = f, (i = n == null ? void 0 : n.focus) == null || i.call(n);
77
+ };
78
+ }, [c, t]), !t || typeof document > "u") return null;
79
+ const l = C(o, x, p);
80
+ return A(
81
+ /* @__PURE__ */ k("div", { className: "fixed inset-0 z-[60]", role: "dialog", "aria-modal": "true", "aria-label": e, "data-overlay": "spotlight-tour", children: [
82
+ /* @__PURE__ */ h("div", { "data-uikit-interaction-shield": !0, className: "absolute inset-0", onClick: (n) => n.stopPropagation() }),
83
+ o ? /* @__PURE__ */ h(
84
+ "div",
85
+ {
86
+ "aria-hidden": !0,
87
+ className: "pointer-events-none absolute rounded-panel transition-[top,left,width,height] duration-300 ease-out motion-reduce:transition-none",
88
+ style: {
89
+ top: o.top - v,
90
+ left: o.left - v,
91
+ width: o.width + v * 2,
92
+ height: o.height + v * 2,
93
+ boxShadow: "0 0 0 3px color-mix(in srgb, var(--color-pure-white) 55%, transparent), 0 0 0 9999px color-mix(in srgb, black 60%, transparent)"
94
+ }
95
+ }
96
+ ) : /* @__PURE__ */ h("div", { "aria-hidden": !0, className: "pointer-events-none absolute inset-0 bg-black/60" }),
97
+ /* @__PURE__ */ k(
98
+ G.div,
99
+ {
100
+ ref: r,
101
+ tabIndex: -1,
102
+ initial: { opacity: 0, scale: 0.98 },
103
+ animate: { opacity: 1, scale: 1 },
104
+ transition: T.fade,
105
+ className: P(
106
+ "absolute w-80 max-w-[calc(100vw-24px)] rounded-panel border border-border bg-surface-raised p-5 shadow-pop outline-none",
107
+ w
108
+ ),
109
+ style: { top: l.top, left: l.left },
110
+ children: [
111
+ /* @__PURE__ */ h(I, { placement: l.placement, offset: l.arrow }),
112
+ b
113
+ ]
114
+ }
115
+ )
116
+ ] }),
117
+ document.body
118
+ );
119
+ }
120
+ export {
121
+ F as SpotlightTour
122
+ };
@@ -0,0 +1,23 @@
1
+ import { jsxs as n, jsx as r } from "react/jsx-runtime";
2
+ import { Card as p, CardLabel as c } from "./card.js";
3
+ import { cn as i } from "../lib/cn.js";
4
+ function d({
5
+ label: a,
6
+ value: o,
7
+ delta: e,
8
+ direction: s = "up"
9
+ }) {
10
+ const t = s === "up";
11
+ return /* @__PURE__ */ n(p, { className: "flex flex-col gap-2 p-5", children: [
12
+ /* @__PURE__ */ r(c, { children: a }),
13
+ /* @__PURE__ */ r("span", { className: "font-sohne text-heading-sm font-[480] leading-none tracking-[0] text-ink", children: o }),
14
+ e && /* @__PURE__ */ n("span", { className: i("flex items-center gap-1 text-[12px]", t ? "text-up" : "text-down"), children: [
15
+ t ? "↑" : "↓",
16
+ " ",
17
+ e
18
+ ] })
19
+ ] });
20
+ }
21
+ export {
22
+ d as StatCard
23
+ };
@@ -0,0 +1,75 @@
1
+ import { jsxs as b, jsx as t } from "react/jsx-runtime";
2
+ import "react";
3
+ import { LoaderCircle as y, AlertTriangle as w, Inbox as z } from "lucide-react";
4
+ import { cn as a } from "../lib/cn.js";
5
+ import { Button as N } from "./button.js";
6
+ const j = {
7
+ sm: { pad: "py-8", wrap: "size-9", icon: 18, title: "text-caption", desc: "text-[11px]", gap: "gap-2", button: "compact" },
8
+ md: { pad: "py-12", wrap: "size-12", icon: 24, title: "text-body", desc: "text-caption", gap: "gap-2.5", button: "default" },
9
+ lg: { pad: "py-16", wrap: "size-14", icon: 28, title: "text-body-lg", desc: "text-body", gap: "gap-3", button: "default" }
10
+ };
11
+ function B({
12
+ variant: e = "empty",
13
+ size: s = "md",
14
+ tone: u = "default",
15
+ icon: m,
16
+ title: o,
17
+ description: i,
18
+ /** Shorthand for a single primary action. Prefer `actions` when you need more than one. */
19
+ action: d,
20
+ actions: g,
21
+ children: x,
22
+ className: f,
23
+ "data-testid": h
24
+ }) {
25
+ const r = j[s], l = u === "scrim" ? "text-ash" : "text-graphite", c = g ?? (d ? [d] : []);
26
+ return /* @__PURE__ */ b(
27
+ "div",
28
+ {
29
+ role: e === "error" ? "alert" : "status",
30
+ "data-testid": h,
31
+ "data-variant": e,
32
+ "data-size": s,
33
+ className: a("flex flex-col items-center justify-center text-center", r.pad, r.gap, f),
34
+ children: [
35
+ e === "loading" ? /* @__PURE__ */ t(k, { size: r.icon }) : /* @__PURE__ */ t(
36
+ "div",
37
+ {
38
+ className: a(
39
+ "grid shrink-0 place-items-center rounded-full",
40
+ r.wrap,
41
+ e === "error" ? "bg-danger/10 text-danger" : a("bg-fog", l)
42
+ ),
43
+ children: m ?? (e === "error" ? /* @__PURE__ */ t(S, { size: r.icon }) : /* @__PURE__ */ t(I, { size: r.icon }))
44
+ }
45
+ ),
46
+ o != null && o !== "" && /* @__PURE__ */ t("p", { className: a("font-sohne font-[480]", r.title, e === "error" ? "text-danger" : "text-ink"), children: o }),
47
+ i != null && i !== "" && /* @__PURE__ */ t("p", { className: a("max-w-sm font-sohne leading-snug", l, r.desc), children: i }),
48
+ x,
49
+ c.length > 0 && /* @__PURE__ */ t("div", { className: "mt-1 flex flex-wrap items-center justify-center gap-2", children: c.map((n, p) => /* @__PURE__ */ t(
50
+ N,
51
+ {
52
+ size: r.button,
53
+ variant: n.variant ?? (p === 0 ? "primary" : "secondary"),
54
+ disabled: n.disabled,
55
+ onClick: n.onClick,
56
+ children: n.label
57
+ },
58
+ `${n.label}-${p}`
59
+ )) })
60
+ ]
61
+ }
62
+ );
63
+ }
64
+ function k({ size: e }) {
65
+ return /* @__PURE__ */ t(y, { size: e, className: "animate-spin text-graphite", "aria-hidden": !0 });
66
+ }
67
+ function I({ size: e }) {
68
+ return /* @__PURE__ */ t(z, { size: e, "aria-hidden": !0 });
69
+ }
70
+ function S({ size: e }) {
71
+ return /* @__PURE__ */ t(w, { size: e, "aria-hidden": !0 });
72
+ }
73
+ export {
74
+ B as StateView
75
+ };
@@ -0,0 +1,17 @@
1
+ import { jsxs as l, jsx as e } from "react/jsx-runtime";
2
+ import { Card as s, CardTitle as c } from "./card.js";
3
+ function m({
4
+ title: t,
5
+ rows: n
6
+ }) {
7
+ return /* @__PURE__ */ l(s, { className: "flex flex-col gap-3 p-5", children: [
8
+ /* @__PURE__ */ e(c, { children: t }),
9
+ /* @__PURE__ */ e("ul", { className: "flex flex-col gap-3", children: n.map((a) => /* @__PURE__ */ l("li", { className: "flex items-center justify-between font-sohne text-[14px]", children: [
10
+ /* @__PURE__ */ e("span", { className: "text-graphite", children: a.name }),
11
+ /* @__PURE__ */ e("span", { className: "font-[480] text-ink", children: a.count })
12
+ ] }, a.name)) })
13
+ ] });
14
+ }
15
+ export {
16
+ m as StatsTable
17
+ };
@@ -0,0 +1,24 @@
1
+ import { jsx as o } from "react/jsx-runtime";
2
+ import { forwardRef as a } from "react";
3
+ import { cn as l } from "../lib/cn.js";
4
+ const b = a(function({ className: e, ...t }, r) {
5
+ return /* @__PURE__ */ o("table", { ref: r, className: l("w-full border-collapse font-product text-caption text-ink", e), ...t });
6
+ }), i = a(function({ className: e, ...t }, r) {
7
+ return /* @__PURE__ */ o("thead", { ref: r, className: l("bg-surface-muted text-micro text-graphite", e), ...t });
8
+ }), f = a(function({ className: e, ...t }, r) {
9
+ return /* @__PURE__ */ o("tbody", { ref: r, className: l("[&_tr:last-child]:border-b-0", e), ...t });
10
+ }), u = a(function({ className: e, ...t }, r) {
11
+ return /* @__PURE__ */ o("tr", { ref: r, className: l("border-b border-divider transition-colors hover:bg-surface-hover", e), ...t });
12
+ }), m = a(function({ className: e, ...t }, r) {
13
+ return /* @__PURE__ */ o("th", { ref: r, className: l("h-row-compact px-3 text-left align-middle font-[500]", e), ...t });
14
+ }), T = a(function({ className: e, ...t }, r) {
15
+ return /* @__PURE__ */ o("td", { ref: r, className: l("h-row-default px-3 align-middle", e), ...t });
16
+ });
17
+ export {
18
+ b as Table,
19
+ f as TableBody,
20
+ T as TableCell,
21
+ m as TableHead,
22
+ i as TableHeader,
23
+ u as TableRow
24
+ };
@@ -2,6 +2,7 @@ import { type ReactNode } from "react";
2
2
  /** Visual weight — higher levels read stronger on light cards. */
3
3
  export type TagLevel = "emphasis" | "accent" | "default" | "muted";
4
4
  export type TagSize = "xs" | "sm";
5
+ export type TagDotTone = "up" | "down" | "accent" | "warning" | "muted";
5
6
  /** Compact label pill — use `level` to control contrast; default is readable on white cards. */
6
7
  export declare function TagPill({ children, level, size, className, title, }: {
7
8
  children: ReactNode;
@@ -11,11 +12,13 @@ export declare function TagPill({ children, level, size, className, title, }: {
11
12
  title?: string;
12
13
  }): import("react").JSX.Element;
13
14
  /** Render a truncated tag row with a muted overflow counter (single line — never wraps). */
14
- export declare function TagList({ items, limit, size, levelForItem, labelForItem, className, }: {
15
+ export declare function TagList({ items, limit, size, levelForItem, variant, toneForItem, labelForItem, className, }: {
15
16
  items: string[];
16
17
  limit?: number;
17
18
  size?: TagSize;
18
19
  levelForItem?: (item: string) => TagLevel;
20
+ variant?: "pill" | "dot";
21
+ toneForItem?: (item: string) => TagDotTone;
19
22
  labelForItem: (item: string) => string;
20
23
  className?: string;
21
24
  }): import("react").JSX.Element | null;
@@ -0,0 +1,69 @@
1
+ import { jsxs as i, jsx as g } from "react/jsx-runtime";
2
+ import "react";
3
+ import { cn as p } from "../lib/cn.js";
4
+ const h = {
5
+ up: "bg-up",
6
+ down: "bg-down",
7
+ accent: "bg-data-blue",
8
+ warning: "bg-warning",
9
+ muted: "bg-graphite"
10
+ }, f = {
11
+ emphasis: "bg-apricot-wash text-rust ring-rust/25",
12
+ accent: "bg-sky-wash text-data-blue ring-data-blue/20",
13
+ default: "bg-fog text-ink ring-dove/55",
14
+ muted: "bg-pure-white text-graphite ring-border"
15
+ }, w = {
16
+ xs: "max-w-[7.5rem] truncate rounded-md px-1.5 py-0.5 text-[10.5px] leading-snug",
17
+ sm: "rounded-full px-2 py-0.5 text-[11px] leading-tight"
18
+ };
19
+ function c({
20
+ children: n,
21
+ level: s = "default",
22
+ size: t = "xs",
23
+ className: l,
24
+ title: r
25
+ }) {
26
+ return /* @__PURE__ */ g(
27
+ "span",
28
+ {
29
+ title: r,
30
+ className: p(
31
+ "inline-flex shrink-0 items-center font-sohne font-[480] ring-1 ring-inset",
32
+ f[s],
33
+ w[t],
34
+ l
35
+ ),
36
+ children: n
37
+ }
38
+ );
39
+ }
40
+ function k({
41
+ items: n,
42
+ limit: s = 3,
43
+ size: t = "xs",
44
+ levelForItem: l = () => "default",
45
+ variant: r = "pill",
46
+ toneForItem: u = () => "muted",
47
+ labelForItem: a,
48
+ className: x
49
+ }) {
50
+ if (!n.length) return null;
51
+ const o = n.slice(0, s), d = n.length - o.length;
52
+ return /* @__PURE__ */ i("div", { className: p("flex min-w-0 flex-nowrap items-center gap-1", x), children: [
53
+ o.map((e) => r === "dot" ? /* @__PURE__ */ i("span", { title: a(e), className: "inline-flex shrink-0 items-center gap-1 whitespace-nowrap font-sohne text-[11px] leading-4 text-graphite", children: [
54
+ /* @__PURE__ */ g("span", { "aria-hidden": "true", className: p("size-1.5 shrink-0 rounded-full", h[u(e)]) }),
55
+ a(e)
56
+ ] }, e) : /* @__PURE__ */ g(c, { level: l(e), size: t, title: a(e), children: a(e) }, e)),
57
+ d > 0 && (r === "dot" ? /* @__PURE__ */ i("span", { className: "shrink-0 font-data text-[11px] text-graphite", children: [
58
+ "+",
59
+ d
60
+ ] }) : /* @__PURE__ */ i(c, { level: "muted", size: t, children: [
61
+ "+",
62
+ d
63
+ ] }))
64
+ ] });
65
+ }
66
+ export {
67
+ k as TagList,
68
+ c as TagPill
69
+ };