@vllnt/ui 0.2.0 → 0.2.1-canary.06f0e84

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 (202) hide show
  1. package/CHANGELOG.md +46 -1
  2. package/README.md +27 -12
  3. package/dist/components/activity-log/activity-log.js +1 -0
  4. package/dist/components/agent-activity/agent-activity.js +311 -0
  5. package/dist/components/agent-activity/index.js +18 -0
  6. package/dist/components/ai-artifact/ai-artifact.js +422 -0
  7. package/dist/components/ai-artifact/index.js +24 -0
  8. package/dist/components/ai-sidebar/ai-sidebar.js +254 -0
  9. package/dist/components/ai-sidebar/index.js +22 -0
  10. package/dist/components/alert-pulse/alert-pulse.js +93 -0
  11. package/dist/components/alert-pulse/index.js +6 -0
  12. package/dist/components/anchor-port/anchor-port.js +51 -0
  13. package/dist/components/anchor-port/index.js +4 -0
  14. package/dist/components/animated-text/animated-text.js +1 -0
  15. package/dist/components/auto-reload/auto-reload.js +367 -0
  16. package/dist/components/auto-reload/index.js +6 -0
  17. package/dist/components/banner/banner.js +155 -0
  18. package/dist/components/banner/index.js +10 -0
  19. package/dist/components/bottom-activity-strip/bottom-activity-strip.js +91 -0
  20. package/dist/components/bottom-activity-strip/index.js +6 -0
  21. package/dist/components/bottom-bar/bottom-bar.js +25 -0
  22. package/dist/components/bottom-bar/index.js +4 -0
  23. package/dist/components/canvas-shell/canvas-foundation-demo.js +183 -0
  24. package/dist/components/canvas-shell/canvas-shell-route-config.js +0 -0
  25. package/dist/components/canvas-shell/canvas-shell.js +261 -0
  26. package/dist/components/canvas-shell/index.js +4 -0
  27. package/dist/components/canvas-view/canvas-view.js +461 -0
  28. package/dist/components/canvas-view/index.js +6 -0
  29. package/dist/components/chart/area-chart.js +1 -0
  30. package/dist/components/chart/line-chart.js +1 -0
  31. package/dist/components/chat-dock-section/chat-dock-section.js +56 -0
  32. package/dist/components/chat-dock-section/index.js +6 -0
  33. package/dist/components/checklist/checklist.js +7 -0
  34. package/dist/components/checklist/index.js +3 -1
  35. package/dist/components/choropleth-map/choropleth-map.js +373 -0
  36. package/dist/components/choropleth-map/index.js +10 -0
  37. package/dist/components/chronological-timeline/chronological-timeline.js +337 -0
  38. package/dist/components/chronological-timeline/index.js +8 -0
  39. package/dist/components/civilization-card/civilization-card.js +258 -0
  40. package/dist/components/civilization-card/index.js +8 -0
  41. package/dist/components/combobox/combobox.js +44 -20
  42. package/dist/components/comment-pin/comment-pin.js +104 -0
  43. package/dist/components/comment-pin/index.js +6 -0
  44. package/dist/components/connector-edge/connector-edge.js +66 -0
  45. package/dist/components/connector-edge/index.js +6 -0
  46. package/dist/components/context-lens/context-lens.js +98 -0
  47. package/dist/components/context-lens/index.js +6 -0
  48. package/dist/components/conversation-thread/conversation-thread.js +348 -0
  49. package/dist/components/conversation-thread/index.js +20 -0
  50. package/dist/components/copy-button/copy-button.js +189 -0
  51. package/dist/components/copy-button/index.js +8 -0
  52. package/dist/components/curriculum/curriculum.js +349 -0
  53. package/dist/components/curriculum/index.js +10 -0
  54. package/dist/components/data-list/data-list.js +1 -0
  55. package/dist/components/document-sibling-nav/document-sibling-nav.js +111 -0
  56. package/dist/components/document-sibling-nav/index.js +8 -0
  57. package/dist/components/edge-label/edge-label.js +26 -0
  58. package/dist/components/edge-label/index.js +4 -0
  59. package/dist/components/empty-state/empty-state.js +93 -0
  60. package/dist/components/empty-state/index.js +8 -0
  61. package/dist/components/era-comparison/era-comparison.js +198 -0
  62. package/dist/components/era-comparison/index.js +16 -0
  63. package/dist/components/floating-toolbar/floating-toolbar.js +66 -0
  64. package/dist/components/floating-toolbar/index.js +6 -0
  65. package/dist/components/follow-mode/follow-mode.js +89 -0
  66. package/dist/components/follow-mode/index.js +6 -0
  67. package/dist/components/form/form.js +432 -0
  68. package/dist/components/form/index.js +20 -0
  69. package/dist/components/gantt-chart/gantt-chart.js +331 -0
  70. package/dist/components/gantt-chart/index.js +6 -0
  71. package/dist/components/geography-quiz-map/geography-quiz-map.js +343 -0
  72. package/dist/components/geography-quiz-map/index.js +12 -0
  73. package/dist/components/glass-panel/glass-panel.js +21 -0
  74. package/dist/components/glass-panel/index.js +4 -0
  75. package/dist/components/globe-3d/globe-3d.js +417 -0
  76. package/dist/components/globe-3d/index.js +10 -0
  77. package/dist/components/group-hull/group-hull.js +29 -0
  78. package/dist/components/group-hull/index.js +4 -0
  79. package/dist/components/handoff-beacon/handoff-beacon.js +78 -0
  80. package/dist/components/handoff-beacon/index.js +6 -0
  81. package/dist/components/heat-map-overlay/heat-map-overlay.js +215 -0
  82. package/dist/components/heat-map-overlay/index.js +6 -0
  83. package/dist/components/heat-overlay/heat-overlay.js +92 -0
  84. package/dist/components/heat-overlay/index.js +6 -0
  85. package/dist/components/historic-timeline/historic-timeline.js +342 -0
  86. package/dist/components/historic-timeline/index.js +6 -0
  87. package/dist/components/historical-figure-card/historical-figure-card.js +273 -0
  88. package/dist/components/historical-figure-card/index.js +6 -0
  89. package/dist/components/index.js +568 -1
  90. package/dist/components/infinite-plane/index.js +6 -0
  91. package/dist/components/infinite-plane/infinite-plane.js +75 -0
  92. package/dist/components/interactive-timeline/index.js +16 -0
  93. package/dist/components/interactive-timeline/interactive-timeline.js +708 -0
  94. package/dist/components/jarvis-dock/index.js +6 -0
  95. package/dist/components/jarvis-dock/jarvis-dock.js +98 -0
  96. package/dist/components/kbd/index.js +5 -0
  97. package/dist/components/kbd/kbd.js +117 -0
  98. package/dist/components/knowledge-check/index.js +6 -0
  99. package/dist/components/knowledge-check/knowledge-check.js +448 -0
  100. package/dist/components/left-rail/index.js +4 -0
  101. package/dist/components/left-rail/left-rail.js +25 -0
  102. package/dist/components/live-cursor/index.js +6 -0
  103. package/dist/components/live-cursor/live-cursor.js +62 -0
  104. package/dist/components/map-2d/index.js +20 -0
  105. package/dist/components/map-2d/map-2d.js +455 -0
  106. package/dist/components/map-timeline/index.js +16 -0
  107. package/dist/components/map-timeline/map-timeline.js +506 -0
  108. package/dist/components/metric-cluster/index.js +6 -0
  109. package/dist/components/metric-cluster/metric-cluster.js +96 -0
  110. package/dist/components/mini-map-panel/index.js +6 -0
  111. package/dist/components/mini-map-panel/mini-map-panel.js +74 -0
  112. package/dist/components/model-comparison/index.js +12 -0
  113. package/dist/components/model-comparison/model-comparison.js +211 -0
  114. package/dist/components/multi-select/index.js +6 -0
  115. package/dist/components/multi-select/multi-select.js +258 -0
  116. package/dist/components/multi-select-lasso/index.js +6 -0
  117. package/dist/components/multi-select-lasso/multi-select-lasso.js +76 -0
  118. package/dist/components/newsletter-signup/index.js +8 -0
  119. package/dist/components/newsletter-signup/newsletter-signup.js +269 -0
  120. package/dist/components/object-card/index.js +6 -0
  121. package/dist/components/object-card/object-card.js +126 -0
  122. package/dist/components/object-handle/index.js +4 -0
  123. package/dist/components/object-handle/object-handle.js +38 -0
  124. package/dist/components/object-inspector/index.js +6 -0
  125. package/dist/components/object-inspector/object-inspector.js +136 -0
  126. package/dist/components/overview-board/index.js +8 -0
  127. package/dist/components/overview-board/overview-board.js +127 -0
  128. package/dist/components/parallel-timeline/index.js +6 -0
  129. package/dist/components/parallel-timeline/parallel-timeline.js +251 -0
  130. package/dist/components/playback-ghost/index.js +6 -0
  131. package/dist/components/playback-ghost/playback-ghost.js +83 -0
  132. package/dist/components/policy-delivery-panel/index.js +6 -0
  133. package/dist/components/policy-delivery-panel/policy-delivery-panel.js +99 -0
  134. package/dist/components/presence-stack/index.js +6 -0
  135. package/dist/components/presence-stack/presence-stack.js +108 -0
  136. package/dist/components/presence-sync-indicator/index.js +6 -0
  137. package/dist/components/presence-sync-indicator/presence-sync-indicator.js +73 -0
  138. package/dist/components/pricing-table/index.js +8 -0
  139. package/dist/components/pricing-table/pricing-table.js +247 -0
  140. package/dist/components/primary-source-viewer/index.js +26 -0
  141. package/dist/components/primary-source-viewer/primary-source-viewer.js +439 -0
  142. package/dist/components/progress-tracker/index.js +20 -0
  143. package/dist/components/progress-tracker/progress-tracker.js +527 -0
  144. package/dist/components/prompt-templates/index.js +6 -0
  145. package/dist/components/prompt-templates/prompt-templates.js +403 -0
  146. package/dist/components/property-section/index.js +6 -0
  147. package/dist/components/property-section/property-section.js +101 -0
  148. package/dist/components/relationship-inspector/index.js +6 -0
  149. package/dist/components/relationship-inspector/relationship-inspector.js +102 -0
  150. package/dist/components/right-dock/index.js +4 -0
  151. package/dist/components/right-dock/right-dock.js +28 -0
  152. package/dist/components/route-map/index.js +6 -0
  153. package/dist/components/route-map/route-map.js +339 -0
  154. package/dist/components/routing-assignment-panel/index.js +6 -0
  155. package/dist/components/routing-assignment-panel/routing-assignment-panel.js +122 -0
  156. package/dist/components/run-timeline/index.js +6 -0
  157. package/dist/components/run-timeline/run-timeline.js +221 -0
  158. package/dist/components/runtime-overview-panel/index.js +6 -0
  159. package/dist/components/runtime-overview-panel/runtime-overview-panel.js +89 -0
  160. package/dist/components/segmented-control/index.js +12 -0
  161. package/dist/components/segmented-control/segmented-control.js +61 -0
  162. package/dist/components/selection-halo/index.js +6 -0
  163. package/dist/components/selection-halo/selection-halo.js +72 -0
  164. package/dist/components/selection-presence/index.js +6 -0
  165. package/dist/components/selection-presence/selection-presence.js +50 -0
  166. package/dist/components/snap-guides/index.js +6 -0
  167. package/dist/components/snap-guides/snap-guides.js +45 -0
  168. package/dist/components/spinner/unicode-spinner.js +1 -0
  169. package/dist/components/state-badge-overlay/index.js +6 -0
  170. package/dist/components/state-badge-overlay/state-badge-overlay.js +90 -0
  171. package/dist/components/sticky-metric/index.js +6 -0
  172. package/dist/components/sticky-metric/sticky-metric.js +83 -0
  173. package/dist/components/story-map/index.js +8 -0
  174. package/dist/components/story-map/story-map.js +414 -0
  175. package/dist/components/tags-input/index.js +4 -0
  176. package/dist/components/tags-input/tags-input.js +178 -0
  177. package/dist/components/thread-bubble/index.js +6 -0
  178. package/dist/components/thread-bubble/thread-bubble.js +85 -0
  179. package/dist/components/threshold-ring/index.js +6 -0
  180. package/dist/components/threshold-ring/threshold-ring.js +160 -0
  181. package/dist/components/timeline/index.js +12 -0
  182. package/dist/components/timeline/timeline.js +239 -0
  183. package/dist/components/timeline-scrubber/index.js +6 -0
  184. package/dist/components/timeline-scrubber/timeline-scrubber.js +179 -0
  185. package/dist/components/top-bar/index.js +4 -0
  186. package/dist/components/top-bar/top-bar.js +31 -0
  187. package/dist/components/transaction-list/index.js +14 -0
  188. package/dist/components/transaction-list/transaction-list.js +226 -0
  189. package/dist/components/tree-view/index.js +6 -0
  190. package/dist/components/tree-view/tree-view.js +298 -0
  191. package/dist/components/usage-breakdown/usage-breakdown.js +1 -0
  192. package/dist/components/viewport-bookmarks/index.js +6 -0
  193. package/dist/components/viewport-bookmarks/viewport-bookmarks.js +116 -0
  194. package/dist/components/workspace-switcher/index.js +6 -0
  195. package/dist/components/workspace-switcher/workspace-switcher.js +61 -0
  196. package/dist/components/world-breadcrumbs/index.js +6 -0
  197. package/dist/components/world-breadcrumbs/world-breadcrumbs.js +114 -0
  198. package/dist/components/zoom-hud/index.js +4 -0
  199. package/dist/components/zoom-hud/zoom-hud.js +61 -0
  200. package/dist/index.d.ts +7906 -225
  201. package/dist/index.js +3 -1
  202. package/package.json +9 -5
@@ -0,0 +1,127 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ import { AlertCircle, ArrowRight, Inbox, ListTodo, Siren } from "lucide-react";
4
+ import { cn } from "../../lib/utils";
5
+ import { Button } from "../button";
6
+ const toneClassNames = {
7
+ danger: "border-red-500/30 bg-red-500/8",
8
+ default: "border-border/70 bg-background/80",
9
+ warning: "border-amber-500/30 bg-amber-500/8"
10
+ };
11
+ const toneAccentClassNames = {
12
+ danger: "text-red-600 dark:text-red-300",
13
+ default: "text-primary",
14
+ warning: "text-amber-600 dark:text-amber-300"
15
+ };
16
+ const OverviewCard = forwardRef(
17
+ ({
18
+ className,
19
+ ctaLabel,
20
+ description,
21
+ handleCtaClick,
22
+ heading,
23
+ icon,
24
+ metric,
25
+ tone = "default",
26
+ ...props
27
+ }, ref) => /* @__PURE__ */ jsxs(
28
+ "section",
29
+ {
30
+ className: cn(
31
+ "flex min-h-[172px] flex-col gap-4 rounded-2xl border p-5 shadow-[0_8px_30px_hsl(var(--foreground)/0.06)] backdrop-blur-xl",
32
+ toneClassNames[tone],
33
+ className
34
+ ),
35
+ ref,
36
+ ...props,
37
+ children: [
38
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
39
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
40
+ /* @__PURE__ */ jsx("div", { className: "text-[11px] font-medium uppercase tracking-[0.24em] text-muted-foreground", children: heading }),
41
+ /* @__PURE__ */ jsx("div", { className: "text-3xl font-semibold tracking-tight text-foreground", children: metric })
42
+ ] }),
43
+ /* @__PURE__ */ jsx(
44
+ "div",
45
+ {
46
+ className: cn(
47
+ "flex size-10 items-center justify-center rounded-xl bg-background/80",
48
+ toneAccentClassNames[tone]
49
+ ),
50
+ children: icon
51
+ }
52
+ )
53
+ ] }),
54
+ /* @__PURE__ */ jsx("p", { className: "text-sm leading-6 text-muted-foreground", children: description }),
55
+ ctaLabel ? /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(
56
+ Button,
57
+ {
58
+ onClick: handleCtaClick,
59
+ size: "sm",
60
+ type: "button",
61
+ variant: "ghost",
62
+ children: [
63
+ ctaLabel,
64
+ /* @__PURE__ */ jsx(ArrowRight, { className: "size-4" })
65
+ ]
66
+ }
67
+ ) }) : null
68
+ ]
69
+ }
70
+ )
71
+ );
72
+ OverviewCard.displayName = "OverviewCard";
73
+ function getDefaultIcon(heading) {
74
+ if (typeof heading !== "string") {
75
+ return /* @__PURE__ */ jsx(Inbox, { className: "size-5" });
76
+ }
77
+ if (heading.toLowerCase().includes("error")) {
78
+ return /* @__PURE__ */ jsx(AlertCircle, { className: "size-5" });
79
+ }
80
+ if (heading.toLowerCase().includes("action")) {
81
+ return /* @__PURE__ */ jsx(ListTodo, { className: "size-5" });
82
+ }
83
+ if (heading.toLowerCase().includes("run")) {
84
+ return /* @__PURE__ */ jsx(Siren, { className: "size-5" });
85
+ }
86
+ return /* @__PURE__ */ jsx(Inbox, { className: "size-5" });
87
+ }
88
+ const OverviewBoard = forwardRef(
89
+ ({ className, eyebrow, heading, items, subtitle, ...props }, ref) => /* @__PURE__ */ jsxs(
90
+ "section",
91
+ {
92
+ className: cn("mx-auto flex w-full max-w-6xl flex-col gap-6", className),
93
+ ref,
94
+ ...props,
95
+ children: [
96
+ /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
97
+ eyebrow ? /* @__PURE__ */ jsx("div", { className: "text-[11px] font-medium uppercase tracking-[0.28em] text-muted-foreground", children: eyebrow }) : null,
98
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
99
+ /* @__PURE__ */ jsx("h2", { className: "text-3xl font-semibold tracking-tight text-foreground", children: heading }),
100
+ subtitle ? /* @__PURE__ */ jsx("p", { className: "max-w-3xl text-sm leading-6 text-muted-foreground", children: subtitle }) : null
101
+ ] })
102
+ ] }),
103
+ /* @__PURE__ */ jsx("div", { className: "grid gap-4 md:grid-cols-2 xl:grid-cols-3", children: items.map((item) => {
104
+ const handleCtaClick = item.handleCtaClick;
105
+ return /* @__PURE__ */ jsx(
106
+ OverviewCard,
107
+ {
108
+ ctaLabel: item.ctaLabel,
109
+ description: item.description,
110
+ handleCtaClick,
111
+ heading: item.heading,
112
+ icon: item.icon ?? getDefaultIcon(item.heading),
113
+ metric: item.metric,
114
+ tone: item.tone
115
+ },
116
+ item.id
117
+ );
118
+ }) })
119
+ ]
120
+ }
121
+ )
122
+ );
123
+ OverviewBoard.displayName = "OverviewBoard";
124
+ export {
125
+ OverviewBoard,
126
+ OverviewCard
127
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ ParallelTimeline
3
+ } from "./parallel-timeline";
4
+ export {
5
+ ParallelTimeline
6
+ };
@@ -0,0 +1,251 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import {
4
+ forwardRef,
5
+ useMemo
6
+ } from "react";
7
+ import { cn } from "../../lib/utils";
8
+ const DEFAULT_TICK_COUNT = 8;
9
+ const COLOR_CLASSES = {
10
+ amber: {
11
+ accent: "bg-amber-500",
12
+ chip: "bg-amber-500/15 text-amber-700 dark:text-amber-300",
13
+ marker: "border-amber-500 bg-amber-500"
14
+ },
15
+ blue: {
16
+ accent: "bg-blue-500",
17
+ chip: "bg-blue-500/15 text-blue-700 dark:text-blue-300",
18
+ marker: "border-blue-500 bg-blue-500"
19
+ },
20
+ emerald: {
21
+ accent: "bg-emerald-500",
22
+ chip: "bg-emerald-500/15 text-emerald-700 dark:text-emerald-300",
23
+ marker: "border-emerald-500 bg-emerald-500"
24
+ },
25
+ neutral: {
26
+ accent: "bg-muted-foreground/40",
27
+ chip: "bg-muted text-muted-foreground",
28
+ marker: "border-muted-foreground bg-muted-foreground"
29
+ },
30
+ purple: {
31
+ accent: "bg-purple-500",
32
+ chip: "bg-purple-500/15 text-purple-700 dark:text-purple-300",
33
+ marker: "border-purple-500 bg-purple-500"
34
+ },
35
+ red: {
36
+ accent: "bg-red-500",
37
+ chip: "bg-red-500/15 text-red-700 dark:text-red-300",
38
+ marker: "border-red-500 bg-red-500"
39
+ },
40
+ rose: {
41
+ accent: "bg-rose-500",
42
+ chip: "bg-rose-500/15 text-rose-700 dark:text-rose-300",
43
+ marker: "border-rose-500 bg-rose-500"
44
+ }
45
+ };
46
+ const DEFAULT_LABELS = {
47
+ region: "Parallel timeline"
48
+ };
49
+ function clamp(value, min, max) {
50
+ return Math.min(Math.max(value, min), max);
51
+ }
52
+ function formatYear(year) {
53
+ if (year < 0) return `${Math.abs(year).toString()} BCE`;
54
+ return `${year.toString()} CE`;
55
+ }
56
+ function yearToPercent(year, start, end) {
57
+ const span = end - start;
58
+ if (span <= 0) return 0;
59
+ return clamp((year - start) / span * 100, 0, 100);
60
+ }
61
+ function buildTicks(start, end, count) {
62
+ const safeCount = Math.max(2, count);
63
+ const span = end - start;
64
+ if (span <= 0) return [];
65
+ const step = span / (safeCount - 1);
66
+ return Array.from({ length: safeCount }).map((_, index) => {
67
+ const year = Math.round(start + step * index);
68
+ return {
69
+ label: formatYear(year),
70
+ offset: yearToPercent(year, start, end)
71
+ };
72
+ });
73
+ }
74
+ function Axis({ ticks }) {
75
+ return /* @__PURE__ */ jsx(
76
+ "div",
77
+ {
78
+ "aria-hidden": "true",
79
+ className: "relative h-7 border-b border-border text-[10px] font-medium uppercase tracking-wide text-muted-foreground",
80
+ children: ticks.map((tick) => /* @__PURE__ */ jsx(
81
+ "span",
82
+ {
83
+ className: "absolute top-1 -translate-x-1/2",
84
+ style: { left: `${tick.offset.toString()}%` },
85
+ children: tick.label
86
+ },
87
+ tick.label
88
+ ))
89
+ }
90
+ );
91
+ }
92
+ function EraBands({ endYear, eras, startYear }) {
93
+ if (eras.length === 0) return null;
94
+ return /* @__PURE__ */ jsx("div", { "aria-hidden": "true", className: "pointer-events-none absolute inset-0", children: eras.map((era) => {
95
+ const left = yearToPercent(era.start, startYear, endYear);
96
+ const right = yearToPercent(era.end, startYear, endYear);
97
+ const width = Math.max(0, right - left);
98
+ if (width <= 0) return null;
99
+ const palette = COLOR_CLASSES[era.color ?? "neutral"];
100
+ return /* @__PURE__ */ jsx(
101
+ "div",
102
+ {
103
+ className: cn("absolute inset-y-0", palette.chip),
104
+ "data-era-id": era.id,
105
+ style: {
106
+ left: `${left.toString()}%`,
107
+ width: `${width.toString()}%`
108
+ }
109
+ },
110
+ era.id
111
+ );
112
+ }) });
113
+ }
114
+ function EventMarker({
115
+ color,
116
+ endYear,
117
+ event,
118
+ startYear
119
+ }) {
120
+ if (event.year < startYear || event.year > endYear) return null;
121
+ const left = yearToPercent(event.year, startYear, endYear);
122
+ const palette = COLOR_CLASSES[color];
123
+ const titleText = typeof event.title === "string" ? event.title : "";
124
+ const ariaLabel = titleText ? `${titleText}, ${formatYear(event.year)}` : void 0;
125
+ return /* @__PURE__ */ jsxs(
126
+ "div",
127
+ {
128
+ "aria-label": ariaLabel,
129
+ className: "absolute top-1/2 z-10 -translate-x-1/2 -translate-y-1/2",
130
+ "data-event-id": event.id,
131
+ "data-event-year": event.year,
132
+ style: { left: `${left.toString()}%` },
133
+ children: [
134
+ /* @__PURE__ */ jsx(
135
+ "div",
136
+ {
137
+ "aria-hidden": "true",
138
+ className: cn(
139
+ "h-3 w-3 rounded-full border-2 ring-2 ring-background",
140
+ palette.marker
141
+ )
142
+ }
143
+ ),
144
+ /* @__PURE__ */ jsxs("div", { className: "absolute left-1/2 top-4 w-40 -translate-x-1/2 text-center", children: [
145
+ /* @__PURE__ */ jsx("p", { className: "truncate text-xs font-medium text-foreground", children: event.title }),
146
+ /* @__PURE__ */ jsxs("p", { className: "truncate text-[10px] text-muted-foreground", children: [
147
+ formatYear(event.year),
148
+ event.meta ? /* @__PURE__ */ jsxs("span", { children: [
149
+ " \xB7 ",
150
+ event.meta
151
+ ] }) : null
152
+ ] })
153
+ ] })
154
+ ]
155
+ }
156
+ );
157
+ }
158
+ function TrackRow({ endYear, startYear, track }) {
159
+ const color = track.color ?? "neutral";
160
+ const palette = COLOR_CLASSES[color];
161
+ return /* @__PURE__ */ jsxs("div", { className: "relative flex items-stretch gap-3 border-t border-border first:border-t-0", children: [
162
+ /* @__PURE__ */ jsxs("div", { className: "flex w-32 shrink-0 flex-col gap-1 border-r border-border bg-muted/20 px-3 py-3", children: [
163
+ /* @__PURE__ */ jsx(
164
+ "span",
165
+ {
166
+ "aria-hidden": "true",
167
+ className: cn("h-1 w-8 rounded-full", palette.accent)
168
+ }
169
+ ),
170
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold tracking-tight text-foreground", children: track.name }),
171
+ track.region ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: track.region }) : null
172
+ ] }),
173
+ /* @__PURE__ */ jsxs(
174
+ "div",
175
+ {
176
+ "aria-label": typeof track.name === "string" ? track.name : void 0,
177
+ className: "relative h-16 min-w-0 flex-1",
178
+ "data-track-id": track.id,
179
+ children: [
180
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-x-0 top-1/2 h-px -translate-y-1/2 bg-border" }),
181
+ track.events.map((event) => /* @__PURE__ */ jsx(
182
+ EventMarker,
183
+ {
184
+ color,
185
+ endYear,
186
+ event,
187
+ startYear
188
+ },
189
+ event.id
190
+ ))
191
+ ]
192
+ }
193
+ )
194
+ ] });
195
+ }
196
+ const ParallelTimeline = forwardRef(
197
+ (props, ref) => {
198
+ const {
199
+ className,
200
+ endYear,
201
+ eras = [],
202
+ labels,
203
+ startYear,
204
+ tickCount = DEFAULT_TICK_COUNT,
205
+ tracks,
206
+ ...rest
207
+ } = props;
208
+ const resolvedLabels = useMemo(
209
+ () => ({ ...DEFAULT_LABELS, ...labels }),
210
+ [labels]
211
+ );
212
+ const ticks = useMemo(
213
+ () => buildTicks(startYear, endYear, tickCount),
214
+ [endYear, startYear, tickCount]
215
+ );
216
+ return /* @__PURE__ */ jsxs(
217
+ "section",
218
+ {
219
+ "aria-label": resolvedLabels.region,
220
+ className: cn(
221
+ "flex w-full flex-col overflow-x-auto rounded-2xl border bg-background text-foreground",
222
+ className
223
+ ),
224
+ ref,
225
+ ...rest,
226
+ children: [
227
+ /* @__PURE__ */ jsxs("div", { className: "flex items-stretch gap-3 border-b border-border", children: [
228
+ /* @__PURE__ */ jsx("div", { "aria-hidden": "true", className: "w-32 shrink-0" }),
229
+ /* @__PURE__ */ jsx(Axis, { ticks })
230
+ ] }),
231
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
232
+ /* @__PURE__ */ jsx(EraBands, { endYear, eras, startYear }),
233
+ tracks.map((track) => /* @__PURE__ */ jsx(
234
+ TrackRow,
235
+ {
236
+ endYear,
237
+ startYear,
238
+ track
239
+ },
240
+ track.id
241
+ ))
242
+ ] })
243
+ ]
244
+ }
245
+ );
246
+ }
247
+ );
248
+ ParallelTimeline.displayName = "ParallelTimeline";
249
+ export {
250
+ ParallelTimeline
251
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ PlaybackGhost
3
+ } from "./playback-ghost";
4
+ export {
5
+ PlaybackGhost
6
+ };
@@ -0,0 +1,83 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import {
4
+ forwardRef
5
+ } from "react";
6
+ import { cn } from "../../lib/utils";
7
+ const KIND_GLYPH = {
8
+ agent: "\u25C7",
9
+ artifact: "\u25CC",
10
+ input: "\u2198",
11
+ output: "\u2197",
12
+ run: "\u25B6",
13
+ task: "\u25A2"
14
+ };
15
+ const KIND_LABEL = {
16
+ agent: "Agent",
17
+ artifact: "Artifact",
18
+ input: "Input",
19
+ output: "Output",
20
+ run: "Run",
21
+ task: "Task"
22
+ };
23
+ const DEFAULT_LABELS = {
24
+ region: "Playback ghost"
25
+ };
26
+ const clamp01 = (v) => {
27
+ if (v < 0) {
28
+ return 0;
29
+ }
30
+ if (v > 1) {
31
+ return 1;
32
+ }
33
+ return v;
34
+ };
35
+ const PlaybackGhost = forwardRef(
36
+ (props, ref) => {
37
+ const {
38
+ className,
39
+ kind,
40
+ label,
41
+ labels,
42
+ opacity = 0.4,
43
+ size = 40,
44
+ x,
45
+ y,
46
+ ...rest
47
+ } = props;
48
+ const resolvedLabels = { ...DEFAULT_LABELS, ...labels };
49
+ const safeOpacity = clamp01(opacity);
50
+ const safeSize = size < 16 ? 16 : size;
51
+ const ariaLabel = kind ? `${resolvedLabels.region}: ${KIND_LABEL[kind]}` : resolvedLabels.region;
52
+ return /* @__PURE__ */ jsxs(
53
+ "div",
54
+ {
55
+ "aria-label": ariaLabel,
56
+ className: cn(
57
+ "pointer-events-none absolute z-10 inline-flex -translate-x-1/2 -translate-y-1/2 items-center justify-center gap-1.5 rounded-md border border-dashed border-border/70 bg-background/40 px-2 py-1 text-xs text-foreground backdrop-blur-sm",
58
+ className
59
+ ),
60
+ "data-playback-ghost": true,
61
+ "data-playback-kind": kind ?? "unknown",
62
+ ref,
63
+ role: "img",
64
+ style: {
65
+ left: x,
66
+ minHeight: safeSize,
67
+ minWidth: safeSize,
68
+ opacity: safeOpacity,
69
+ top: y
70
+ },
71
+ ...rest,
72
+ children: [
73
+ kind ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "text-muted-foreground", children: KIND_GLYPH[kind] }) : null,
74
+ label ? /* @__PURE__ */ jsx("span", { className: "truncate", "data-playback-ghost-label": true, children: label }) : null
75
+ ]
76
+ }
77
+ );
78
+ }
79
+ );
80
+ PlaybackGhost.displayName = "PlaybackGhost";
81
+ export {
82
+ PlaybackGhost
83
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ PolicyDeliveryPanel
3
+ } from "./policy-delivery-panel";
4
+ export {
5
+ PolicyDeliveryPanel
6
+ };
@@ -0,0 +1,99 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import {
4
+ forwardRef
5
+ } from "react";
6
+ import { cn } from "../../lib/utils";
7
+ const STATUS_LABEL = {
8
+ advisory: "Advisory",
9
+ disabled: "Disabled",
10
+ enforced: "Enforced"
11
+ };
12
+ const STATUS_TONE = {
13
+ advisory: "border-amber-500/40 bg-amber-500/10 text-amber-700 dark:text-amber-300",
14
+ disabled: "border-border bg-muted/40 text-muted-foreground",
15
+ enforced: "border-emerald-500/40 bg-emerald-500/10 text-emerald-700 dark:text-emerald-300"
16
+ };
17
+ const DEFAULT_LABELS = {
18
+ empty: "No policies",
19
+ region: "Policy delivery"
20
+ };
21
+ const RowBody = (props) => {
22
+ const { policy } = props;
23
+ return /* @__PURE__ */ jsxs("span", { className: "flex flex-1 flex-col gap-0.5 text-left", children: [
24
+ /* @__PURE__ */ jsxs("span", { className: "flex items-center justify-between gap-2", children: [
25
+ /* @__PURE__ */ jsx("span", { className: "truncate text-xs font-medium text-foreground", children: policy.name }),
26
+ /* @__PURE__ */ jsx(
27
+ "span",
28
+ {
29
+ className: cn(
30
+ "rounded-full border px-1.5 py-0.5 text-[10px] uppercase tracking-wide",
31
+ STATUS_TONE[policy.status]
32
+ ),
33
+ children: STATUS_LABEL[policy.status]
34
+ }
35
+ )
36
+ ] }),
37
+ policy.description ? /* @__PURE__ */ jsx("span", { className: "truncate text-[10px] text-muted-foreground", children: policy.description }) : null
38
+ ] });
39
+ };
40
+ const Row = (props) => {
41
+ const { policy } = props;
42
+ if (policy.onToggle) {
43
+ const handleClick = () => {
44
+ policy.onToggle?.();
45
+ };
46
+ return /* @__PURE__ */ jsx(
47
+ "button",
48
+ {
49
+ className: "flex w-full items-center gap-2 rounded-md border border-transparent px-2 py-1.5 text-left transition-colors hover:border-border hover:bg-muted/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
50
+ "data-policy-row": policy.id,
51
+ "data-policy-status": policy.status,
52
+ onClick: handleClick,
53
+ type: "button",
54
+ children: /* @__PURE__ */ jsx(RowBody, { policy })
55
+ }
56
+ );
57
+ }
58
+ return /* @__PURE__ */ jsx(
59
+ "div",
60
+ {
61
+ className: "flex w-full items-center gap-2 rounded-md px-2 py-1.5",
62
+ "data-policy-row": policy.id,
63
+ "data-policy-status": policy.status,
64
+ children: /* @__PURE__ */ jsx(RowBody, { policy })
65
+ }
66
+ );
67
+ };
68
+ const PolicyDeliveryPanel = forwardRef((props, ref) => {
69
+ const { className, labels, policies, title = "Policies", ...rest } = props;
70
+ const resolvedLabels = { ...DEFAULT_LABELS, ...labels };
71
+ return /* @__PURE__ */ jsxs(
72
+ "section",
73
+ {
74
+ "aria-label": resolvedLabels.region,
75
+ className: cn(
76
+ "flex w-full flex-col gap-2 rounded-lg border bg-background p-3 text-foreground",
77
+ className
78
+ ),
79
+ "data-policy-delivery-panel": true,
80
+ ref,
81
+ ...rest,
82
+ children: [
83
+ /* @__PURE__ */ jsx("header", { children: /* @__PURE__ */ jsx("h3", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: title }) }),
84
+ policies.length === 0 ? /* @__PURE__ */ jsx(
85
+ "p",
86
+ {
87
+ className: "px-2 py-3 text-center text-xs text-muted-foreground",
88
+ "data-policy-state": "empty",
89
+ children: resolvedLabels.empty
90
+ }
91
+ ) : /* @__PURE__ */ jsx("ul", { className: "space-y-0.5", children: policies.map((policy) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(Row, { policy }) }, policy.id)) })
92
+ ]
93
+ }
94
+ );
95
+ });
96
+ PolicyDeliveryPanel.displayName = "PolicyDeliveryPanel";
97
+ export {
98
+ PolicyDeliveryPanel
99
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ PresenceStack
3
+ } from "./presence-stack";
4
+ export {
5
+ PresenceStack
6
+ };
@@ -0,0 +1,108 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import {
4
+ forwardRef
5
+ } from "react";
6
+ import { cn } from "../../lib/utils";
7
+ const STATUS_DOT = {
8
+ active: "bg-emerald-500",
9
+ away: "bg-amber-500",
10
+ idle: "bg-muted-foreground",
11
+ offline: "bg-muted-foreground/40"
12
+ };
13
+ const DEFAULT_LABELS = {
14
+ overflowSuffix: "more",
15
+ region: "Live presence"
16
+ };
17
+ const Avatar = (props) => {
18
+ const { user } = props;
19
+ const status = user.status ?? "active";
20
+ return /* @__PURE__ */ jsxs(
21
+ "span",
22
+ {
23
+ className: "relative -ml-2 inline-flex h-7 w-7 items-center justify-center rounded-full border-2 border-background text-[11px] font-semibold text-white shadow-sm first:ml-0",
24
+ "data-presence-stack-status": status,
25
+ "data-presence-stack-user": user.id,
26
+ style: { backgroundColor: user.color ?? "var(--foreground)" },
27
+ title: user.name,
28
+ children: [
29
+ user.initial,
30
+ /* @__PURE__ */ jsx(
31
+ "span",
32
+ {
33
+ "aria-hidden": "true",
34
+ className: cn(
35
+ "absolute -bottom-0.5 -right-0.5 h-2 w-2 rounded-full border border-background",
36
+ STATUS_DOT[status]
37
+ ),
38
+ "data-presence-stack-dot": true
39
+ }
40
+ )
41
+ ]
42
+ }
43
+ );
44
+ };
45
+ const PresenceStack = forwardRef(
46
+ (props, ref) => {
47
+ const {
48
+ className,
49
+ labels,
50
+ max = 5,
51
+ onOverflowActivate,
52
+ users,
53
+ ...rest
54
+ } = props;
55
+ const resolvedLabels = { ...DEFAULT_LABELS, ...labels };
56
+ const visible = max >= users.length ? users : users.slice(0, max);
57
+ const hidden = users.length - visible.length;
58
+ const handleOverflow = () => {
59
+ onOverflowActivate?.();
60
+ };
61
+ return /* @__PURE__ */ jsxs(
62
+ "div",
63
+ {
64
+ "aria-label": resolvedLabels.region,
65
+ className: cn("inline-flex items-center pl-2", className),
66
+ "data-presence-stack": true,
67
+ ref,
68
+ role: "group",
69
+ ...rest,
70
+ children: [
71
+ visible.map((user) => /* @__PURE__ */ jsx(Avatar, { user }, user.id)),
72
+ hidden > 0 ? renderOverflow({
73
+ count: hidden,
74
+ handleClick: handleOverflow,
75
+ handlerProvided: Boolean(onOverflowActivate),
76
+ labels: resolvedLabels
77
+ }) : null
78
+ ]
79
+ }
80
+ );
81
+ }
82
+ );
83
+ PresenceStack.displayName = "PresenceStack";
84
+ const renderOverflow = (input) => {
85
+ const text = `+${input.count}`;
86
+ const aria = `${input.count} ${input.labels.overflowSuffix}`;
87
+ const className = "relative -ml-2 inline-flex h-7 min-w-7 items-center justify-center rounded-full border-2 border-background bg-muted px-1.5 text-[10px] font-semibold text-muted-foreground shadow-sm";
88
+ if (input.handlerProvided) {
89
+ return /* @__PURE__ */ jsx(
90
+ "button",
91
+ {
92
+ "aria-label": aria,
93
+ className: cn(
94
+ className,
95
+ "transition-colors hover:bg-muted/80 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
96
+ ),
97
+ "data-presence-stack-overflow": true,
98
+ onClick: input.handleClick,
99
+ type: "button",
100
+ children: text
101
+ }
102
+ );
103
+ }
104
+ return /* @__PURE__ */ jsx("span", { "aria-label": aria, className, "data-presence-stack-overflow": true, children: text });
105
+ };
106
+ export {
107
+ PresenceStack
108
+ };