@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,91 @@
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 TONE_DOT = {
8
+ danger: "bg-red-500",
9
+ info: "bg-blue-500",
10
+ neutral: "bg-muted-foreground",
11
+ success: "bg-emerald-500",
12
+ warn: "bg-amber-500"
13
+ };
14
+ const DEFAULT_LABELS = {
15
+ empty: "No recent activity",
16
+ region: "Recent activity"
17
+ };
18
+ const ChipBody = (props) => {
19
+ const { event } = props;
20
+ const tone = event.tone ?? "neutral";
21
+ return /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5 whitespace-nowrap", children: [
22
+ /* @__PURE__ */ jsx(
23
+ "span",
24
+ {
25
+ "aria-hidden": "true",
26
+ className: cn("h-1.5 w-1.5 rounded-full", TONE_DOT[tone])
27
+ }
28
+ ),
29
+ /* @__PURE__ */ jsx("span", { className: "text-foreground", children: event.label }),
30
+ /* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground", "data-strip-event-ts": true, children: event.ts })
31
+ ] });
32
+ };
33
+ const Chip = (props) => {
34
+ const { event } = props;
35
+ const tone = event.tone ?? "neutral";
36
+ if (event.onActivate) {
37
+ const handleClick = () => {
38
+ event.onActivate?.();
39
+ };
40
+ return /* @__PURE__ */ jsx(
41
+ "button",
42
+ {
43
+ className: "flex items-center rounded-full border border-border bg-background px-2 py-1 text-[11px] transition-colors hover:bg-muted/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
44
+ "data-strip-event": event.id,
45
+ "data-strip-event-tone": tone,
46
+ onClick: handleClick,
47
+ type: "button",
48
+ children: /* @__PURE__ */ jsx(ChipBody, { event })
49
+ }
50
+ );
51
+ }
52
+ return /* @__PURE__ */ jsx(
53
+ "span",
54
+ {
55
+ className: "flex items-center rounded-full border border-border bg-background px-2 py-1 text-[11px]",
56
+ "data-strip-event": event.id,
57
+ "data-strip-event-tone": tone,
58
+ children: /* @__PURE__ */ jsx(ChipBody, { event })
59
+ }
60
+ );
61
+ };
62
+ const BottomActivityStrip = forwardRef((props, ref) => {
63
+ const { className, events, labels, maxEvents, ...rest } = props;
64
+ const resolvedLabels = { ...DEFAULT_LABELS, ...labels };
65
+ const visible = maxEvents === void 0 || maxEvents >= events.length ? events : events.slice(0, maxEvents);
66
+ return /* @__PURE__ */ jsx(
67
+ "section",
68
+ {
69
+ "aria-label": resolvedLabels.region,
70
+ className: cn(
71
+ "flex w-full items-center gap-2 overflow-x-auto rounded-md border border-border bg-background/90 px-2 py-1 text-foreground",
72
+ className
73
+ ),
74
+ "data-bottom-activity-strip": true,
75
+ ref,
76
+ ...rest,
77
+ children: visible.length === 0 ? /* @__PURE__ */ jsx(
78
+ "span",
79
+ {
80
+ className: "px-2 text-[11px] text-muted-foreground",
81
+ "data-strip-state": "empty",
82
+ children: resolvedLabels.empty
83
+ }
84
+ ) : visible.map((event) => /* @__PURE__ */ jsx(Chip, { event }, event.id))
85
+ }
86
+ );
87
+ });
88
+ BottomActivityStrip.displayName = "BottomActivityStrip";
89
+ export {
90
+ BottomActivityStrip
91
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ BottomActivityStrip
3
+ } from "./bottom-activity-strip";
4
+ export {
5
+ BottomActivityStrip
6
+ };
@@ -0,0 +1,25 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ import { cn } from "../../lib/utils";
4
+ const BottomBar = forwardRef(
5
+ ({ center, className, leading, trailing, ...props }, ref) => /* @__PURE__ */ jsxs(
6
+ "div",
7
+ {
8
+ className: cn(
9
+ "flex min-h-14 items-center gap-3 px-4 py-3 text-sm",
10
+ className
11
+ ),
12
+ ref,
13
+ ...props,
14
+ children: [
15
+ /* @__PURE__ */ jsx("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: leading }),
16
+ center ? /* @__PURE__ */ jsx("div", { className: "flex shrink-0 items-center justify-center gap-2", children: center }) : null,
17
+ /* @__PURE__ */ jsx("div", { className: "flex min-w-0 flex-1 items-center justify-end gap-2", children: trailing })
18
+ ]
19
+ }
20
+ )
21
+ );
22
+ BottomBar.displayName = "BottomBar";
23
+ export {
24
+ BottomBar
25
+ };
@@ -0,0 +1,4 @@
1
+ import { BottomBar } from "./bottom-bar";
2
+ export {
3
+ BottomBar
4
+ };
@@ -0,0 +1,183 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { Activity, Bot, Compass, Layers3, Sparkles } from "lucide-react";
3
+ import { BottomBar } from "../bottom-bar";
4
+ import { Button } from "../button";
5
+ import { CanvasView } from "../canvas-view";
6
+ import { ChatDockSection } from "../chat-dock-section";
7
+ import { GlassPanel } from "../glass-panel";
8
+ import { LeftRail } from "../left-rail";
9
+ import { RightDock } from "../right-dock";
10
+ import { TopBar } from "../top-bar";
11
+ import { WorkspaceSwitcher } from "../workspace-switcher";
12
+ import { CanvasShell } from "./canvas-shell";
13
+ function DemoLeftBar() {
14
+ return /* @__PURE__ */ jsx(GlassPanel, { className: "overflow-hidden", children: /* @__PURE__ */ jsxs(
15
+ LeftRail,
16
+ {
17
+ className: "w-[5rem] border-0 bg-transparent px-3 py-4",
18
+ footer: /* @__PURE__ */ jsx(Button, { "aria-label": "Runs", size: "icon", type: "button", variant: "ghost", children: /* @__PURE__ */ jsx(Activity, { className: "size-4" }) }),
19
+ title: "Mode",
20
+ children: [
21
+ /* @__PURE__ */ jsx(
22
+ Button,
23
+ {
24
+ "aria-label": "Overview",
25
+ size: "icon",
26
+ type: "button",
27
+ variant: "secondary",
28
+ children: /* @__PURE__ */ jsx(Compass, { className: "size-4" })
29
+ }
30
+ ),
31
+ /* @__PURE__ */ jsx(Button, { "aria-label": "Objects", size: "icon", type: "button", variant: "ghost", children: /* @__PURE__ */ jsx(Layers3, { className: "size-4" }) }),
32
+ /* @__PURE__ */ jsx(Button, { "aria-label": "Agents", size: "icon", type: "button", variant: "ghost", children: /* @__PURE__ */ jsx(Bot, { className: "size-4" }) })
33
+ ]
34
+ }
35
+ ) });
36
+ }
37
+ function DemoTopBar() {
38
+ return /* @__PURE__ */ jsx(GlassPanel, { children: /* @__PURE__ */ jsx(
39
+ TopBar,
40
+ {
41
+ className: "border-0 bg-transparent px-5 font-sans",
42
+ leading: /* @__PURE__ */ jsx("div", { className: "flex size-9 items-center justify-center rounded-xl bg-primary/10 text-primary", children: /* @__PURE__ */ jsx(Sparkles, { className: "size-4" }) }),
43
+ subtitle: "Calm operating surface",
44
+ title: "Operator workspace",
45
+ trailing: /* @__PURE__ */ jsx(Button, { size: "sm", type: "button", variant: "outline", children: "Open command" }),
46
+ children: /* @__PURE__ */ jsx(
47
+ WorkspaceSwitcher,
48
+ {
49
+ className: "bg-background/60",
50
+ defaultValue: "orchestrate",
51
+ workspaces: [
52
+ { id: "orchestrate", label: "Orchestrate" },
53
+ { id: "objects", label: "Objects" },
54
+ { id: "signals", label: "Signals" }
55
+ ]
56
+ }
57
+ )
58
+ }
59
+ ) });
60
+ }
61
+ function DemoRightBar() {
62
+ return /* @__PURE__ */ jsx(GlassPanel, { className: "h-full overflow-hidden", children: /* @__PURE__ */ jsx(
63
+ RightDock,
64
+ {
65
+ className: "h-full min-w-[22rem] max-w-[22rem] border-0 bg-transparent",
66
+ footer: /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: "Chat stays contextual and secondary to the center workspace." }),
67
+ header: /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: "Context shifts by route while the shell stays stable." }),
68
+ title: "Context",
69
+ children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
70
+ /* @__PURE__ */ jsx(
71
+ ChatDockSection,
72
+ {
73
+ contextLabel: "Today \xB7 overview",
74
+ messages: [
75
+ {
76
+ body: "Three failed runs came in overnight. Start with the invoice retry and the security digest.",
77
+ id: "assistant",
78
+ speaker: "Assistant"
79
+ },
80
+ {
81
+ body: "Queue the approvals first, then review the stale automations after lunch.",
82
+ id: "operator",
83
+ speaker: "Operator"
84
+ }
85
+ ]
86
+ }
87
+ ),
88
+ /* @__PURE__ */ jsxs("div", { className: "rounded-2xl border border-border/70 bg-background/75 p-4 shadow-[0_10px_35px_hsl(var(--foreground)/0.06)] backdrop-blur-xl", children: [
89
+ /* @__PURE__ */ jsx("div", { className: "text-[11px] font-medium uppercase tracking-[0.24em] text-muted-foreground", children: "Selected context" }),
90
+ /* @__PURE__ */ jsx("div", { className: "mt-2 text-sm font-medium text-foreground", children: "Inbox triage" }),
91
+ /* @__PURE__ */ jsx("div", { className: "mt-2 text-sm leading-6 text-muted-foreground", children: "Landing route keeps the assistant close to the operational queue instead of taking over the center canvas." })
92
+ ] })
93
+ ] })
94
+ }
95
+ ) });
96
+ }
97
+ function DemoBottomBar() {
98
+ return /* @__PURE__ */ jsx(GlassPanel, { children: /* @__PURE__ */ jsx(
99
+ BottomBar,
100
+ {
101
+ center: /* @__PURE__ */ jsxs(Fragment, { children: [
102
+ /* @__PURE__ */ jsx("div", { className: "rounded-full border border-border/70 px-3 py-1 text-xs text-muted-foreground", children: "3 errors" }),
103
+ /* @__PURE__ */ jsx("div", { className: "rounded-full border border-border/70 px-3 py-1 text-xs text-muted-foreground", children: "7 awaiting action" })
104
+ ] }),
105
+ leading: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
106
+ /* @__PURE__ */ jsx(Activity, { className: "size-4" }),
107
+ "System healthy enough to proceed"
108
+ ] }),
109
+ trailing: /* @__PURE__ */ jsx(Button, { size: "sm", type: "button", variant: "ghost", children: "Open inbox" })
110
+ }
111
+ ) });
112
+ }
113
+ function DemoCanvasObjects() {
114
+ return /* @__PURE__ */ jsxs("div", { className: "relative h-[1200px] w-[1600px] overflow-hidden rounded-[28px] border border-border/12 bg-[radial-gradient(circle_at_top,hsl(var(--primary)/0.07),transparent_38%),linear-gradient(180deg,hsl(var(--background)/0.18),hsl(var(--background)/0.04))]", children: [
115
+ /* @__PURE__ */ jsxs("div", { className: "absolute left-[14%] top-[22%] w-72 rounded-[2rem] border border-border/18 bg-background/18 p-5 shadow-[0_22px_80px_hsl(var(--foreground)/0.05)] backdrop-blur-xl", children: [
116
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
117
+ /* @__PURE__ */ jsx("div", { className: "flex size-11 items-center justify-center rounded-2xl bg-primary/10 text-primary", children: /* @__PURE__ */ jsx(Layers3, { className: "size-5" }) }),
118
+ /* @__PURE__ */ jsx("div", { className: "h-2 w-2 rounded-full bg-primary/50" })
119
+ ] }),
120
+ /* @__PURE__ */ jsxs("div", { className: "mt-5 space-y-3", children: [
121
+ /* @__PURE__ */ jsx("div", { className: "h-3 w-24 rounded-full bg-foreground/10" }),
122
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3", children: [
123
+ /* @__PURE__ */ jsx("div", { className: "h-20 rounded-[1.5rem] border border-border/18 bg-background/35" }),
124
+ /* @__PURE__ */ jsx("div", { className: "h-20 rounded-[1.5rem] border border-border/18 bg-background/28" })
125
+ ] }),
126
+ /* @__PURE__ */ jsx("div", { className: "h-10 rounded-[1.25rem] border border-border/18 bg-background/30" })
127
+ ] })
128
+ ] }),
129
+ /* @__PURE__ */ jsxs("div", { className: "absolute right-[15%] top-[18%] w-56 rounded-[1.75rem] border border-border/18 bg-background/14 p-4 shadow-[0_18px_60px_hsl(var(--foreground)/0.04)] backdrop-blur-xl", children: [
130
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
131
+ /* @__PURE__ */ jsx("div", { className: "flex size-10 items-center justify-center rounded-2xl bg-background/60 text-foreground/70", children: /* @__PURE__ */ jsx(Activity, { className: "size-4" }) }),
132
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-1.5", children: [
133
+ /* @__PURE__ */ jsx("div", { className: "h-2 w-2 rounded-full bg-foreground/10" }),
134
+ /* @__PURE__ */ jsx("div", { className: "h-2 w-2 rounded-full bg-foreground/10" }),
135
+ /* @__PURE__ */ jsx("div", { className: "h-2 w-2 rounded-full bg-primary/45" })
136
+ ] })
137
+ ] }),
138
+ /* @__PURE__ */ jsxs("div", { className: "mt-4 space-y-3", children: [
139
+ /* @__PURE__ */ jsx("div", { className: "h-3 w-20 rounded-full bg-foreground/10" }),
140
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
141
+ /* @__PURE__ */ jsx("div", { className: "h-11 rounded-[1rem] border border-border/18 bg-background/32" }),
142
+ /* @__PURE__ */ jsx("div", { className: "h-11 rounded-[1rem] border border-border/18 bg-background/24" }),
143
+ /* @__PURE__ */ jsx("div", { className: "h-11 rounded-[1rem] border border-border/18 bg-background/18" })
144
+ ] })
145
+ ] })
146
+ ] }),
147
+ /* @__PURE__ */ jsxs("div", { className: "absolute bottom-[18%] left-[22%] w-64 rounded-[1.75rem] border border-border/18 bg-background/12 p-4 shadow-[0_18px_60px_hsl(var(--foreground)/0.04)] backdrop-blur-xl", children: [
148
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
149
+ /* @__PURE__ */ jsx("div", { className: "flex size-10 items-center justify-center rounded-2xl bg-background/55 text-foreground/70", children: /* @__PURE__ */ jsx(Sparkles, { className: "size-4" }) }),
150
+ /* @__PURE__ */ jsx("div", { className: "h-7 w-16 rounded-full border border-border/18 bg-background/38" })
151
+ ] }),
152
+ /* @__PURE__ */ jsxs("div", { className: "mt-4 grid grid-cols-3 gap-2", children: [
153
+ /* @__PURE__ */ jsx("div", { className: "h-16 rounded-[1rem] border border-border/18 bg-background/26" }),
154
+ /* @__PURE__ */ jsx("div", { className: "h-16 rounded-[1rem] border border-border/18 bg-background/20" }),
155
+ /* @__PURE__ */ jsx("div", { className: "h-16 rounded-[1rem] border border-border/18 bg-background/14" })
156
+ ] })
157
+ ] })
158
+ ] });
159
+ }
160
+ function CanvasFoundationDemo() {
161
+ return /* @__PURE__ */ jsx(
162
+ CanvasShell,
163
+ {
164
+ bottomBar: /* @__PURE__ */ jsx(DemoBottomBar, {}),
165
+ className: "h-[100dvh] min-h-[720px]",
166
+ contentPadding: { bottom: 120, left: 112, right: 392, top: 112 },
167
+ leftBar: /* @__PURE__ */ jsx(DemoLeftBar, {}),
168
+ rightBar: /* @__PURE__ */ jsx(DemoRightBar, {}),
169
+ topBar: /* @__PURE__ */ jsx(DemoTopBar, {}),
170
+ children: /* @__PURE__ */ jsx(
171
+ CanvasView,
172
+ {
173
+ className: "h-full rounded-none border-0 bg-background/25",
174
+ defaultViewport: { x: 0, y: 0, zoom: 1 },
175
+ children: /* @__PURE__ */ jsx(DemoCanvasObjects, {})
176
+ }
177
+ )
178
+ }
179
+ );
180
+ }
181
+ export {
182
+ CanvasFoundationDemo
183
+ };
@@ -0,0 +1,261 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ import { cn } from "../../lib/utils";
4
+ function toInsetValue(value) {
5
+ if (typeof value === "number") {
6
+ return `${value}px`;
7
+ }
8
+ return value;
9
+ }
10
+ const FLOATING_BOTTOM_BAR_FOOTPRINT = "3.5rem";
11
+ const FLOATING_LEFT_BAR_FOOTPRINT = "4.5rem";
12
+ const FLOATING_RIGHT_BAR_FOOTPRINT = "18rem";
13
+ const FLOATING_TOP_BAR_FOOTPRINT = "3.5rem";
14
+ function getReservedInset(inset, footprint, override) {
15
+ return toInsetValue(override) ?? `calc(${inset} + ${footprint})`;
16
+ }
17
+ function getSafeAreaInsets({
18
+ chromeInset,
19
+ contentPadding,
20
+ hasBottomBar,
21
+ hasLeftBar,
22
+ hasRightBar,
23
+ hasTopBar
24
+ }) {
25
+ const inset = toInsetValue(chromeInset) ?? "16px";
26
+ return {
27
+ bottom: hasBottomBar ? getReservedInset(
28
+ inset,
29
+ FLOATING_BOTTOM_BAR_FOOTPRINT,
30
+ contentPadding?.bottom
31
+ ) : toInsetValue(contentPadding?.bottom) ?? inset,
32
+ left: hasLeftBar ? getReservedInset(
33
+ inset,
34
+ FLOATING_LEFT_BAR_FOOTPRINT,
35
+ contentPadding?.left
36
+ ) : toInsetValue(contentPadding?.left) ?? inset,
37
+ right: hasRightBar ? getReservedInset(
38
+ inset,
39
+ FLOATING_RIGHT_BAR_FOOTPRINT,
40
+ contentPadding?.right
41
+ ) : toInsetValue(contentPadding?.right) ?? inset,
42
+ top: hasTopBar ? getReservedInset(inset, FLOATING_TOP_BAR_FOOTPRINT, contentPadding?.top) : toInsetValue(contentPadding?.top) ?? inset
43
+ };
44
+ }
45
+ function getSafeAreaStyle(insets) {
46
+ return {
47
+ "--canvas-shell-safe-bottom": insets.bottom,
48
+ "--canvas-shell-safe-left": insets.left,
49
+ "--canvas-shell-safe-right": insets.right,
50
+ "--canvas-shell-safe-top": insets.top
51
+ };
52
+ }
53
+ const hasChromeContent = Boolean;
54
+ function CanvasShellChromeBefore({
55
+ inset,
56
+ leftBar,
57
+ topBar
58
+ }) {
59
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
60
+ hasChromeContent(topBar) ? /* @__PURE__ */ jsx(
61
+ "div",
62
+ {
63
+ className: "pointer-events-none absolute inset-x-0 z-30",
64
+ style: { top: inset },
65
+ children: /* @__PURE__ */ jsx(
66
+ "div",
67
+ {
68
+ className: "pointer-events-auto mx-auto w-full max-w-[960px]",
69
+ style: { paddingLeft: inset, paddingRight: inset },
70
+ children: topBar
71
+ }
72
+ )
73
+ }
74
+ ) : null,
75
+ hasChromeContent(leftBar) ? /* @__PURE__ */ jsx(
76
+ "div",
77
+ {
78
+ className: "pointer-events-none absolute left-0 z-30 flex",
79
+ style: {
80
+ bottom: "var(--canvas-shell-safe-bottom)",
81
+ left: inset,
82
+ top: "var(--canvas-shell-safe-top)"
83
+ },
84
+ children: /* @__PURE__ */ jsx("div", { className: "pointer-events-auto flex", children: leftBar })
85
+ }
86
+ ) : null
87
+ ] });
88
+ }
89
+ function CanvasShellChromeAfter({
90
+ bottomBar,
91
+ inset,
92
+ rightBar
93
+ }) {
94
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
95
+ hasChromeContent(rightBar) ? /* @__PURE__ */ jsx(
96
+ "div",
97
+ {
98
+ className: "pointer-events-none absolute right-0 z-30 flex",
99
+ style: {
100
+ bottom: "var(--canvas-shell-safe-bottom)",
101
+ right: inset,
102
+ top: "var(--canvas-shell-safe-top)"
103
+ },
104
+ children: /* @__PURE__ */ jsx("div", { className: "pointer-events-auto flex", children: rightBar })
105
+ }
106
+ ) : null,
107
+ hasChromeContent(bottomBar) ? /* @__PURE__ */ jsx(
108
+ "div",
109
+ {
110
+ className: "pointer-events-none absolute inset-x-0 z-30",
111
+ style: { bottom: inset },
112
+ children: /* @__PURE__ */ jsx(
113
+ "div",
114
+ {
115
+ className: "pointer-events-auto mx-auto w-full max-w-[960px]",
116
+ style: { paddingLeft: inset, paddingRight: inset },
117
+ children: bottomBar
118
+ }
119
+ )
120
+ }
121
+ ) : null
122
+ ] });
123
+ }
124
+ function renderLegacyCanvasShell({
125
+ bottomBar: _bottomBar,
126
+ bottomSlot,
127
+ children,
128
+ chromeInset: _chromeInset = 16,
129
+ className,
130
+ contentPadding: _contentPadding,
131
+ leftBar: _leftBar,
132
+ leftRail,
133
+ rightBar: _rightBar,
134
+ rightDock,
135
+ style,
136
+ topBar,
137
+ ...props
138
+ }, ref) {
139
+ return /* @__PURE__ */ jsxs(
140
+ "section",
141
+ {
142
+ className: cn(
143
+ "flex min-h-[720px] w-full flex-col overflow-hidden rounded-md border border-border bg-background",
144
+ className
145
+ ),
146
+ ref,
147
+ style,
148
+ ...props,
149
+ children: [
150
+ topBar,
151
+ /* @__PURE__ */ jsxs("div", { className: "grid min-h-0 flex-1 grid-cols-[auto_minmax(0,1fr)_auto] overflow-hidden bg-background", children: [
152
+ leftRail ?? /* @__PURE__ */ jsx("div", {}),
153
+ /* @__PURE__ */ jsx("div", { className: "relative min-h-0 min-w-0 overflow-hidden", children }),
154
+ rightDock ?? /* @__PURE__ */ jsx("div", {})
155
+ ] }),
156
+ bottomSlot ? /* @__PURE__ */ jsx("div", { className: "border-t border-border bg-background px-4 py-2", children: bottomSlot }) : null
157
+ ]
158
+ }
159
+ );
160
+ }
161
+ function renderFloatingContent(children, contentStyle) {
162
+ return /* @__PURE__ */ jsx(
163
+ "div",
164
+ {
165
+ className: "relative z-0 h-full w-full min-h-0 min-w-0",
166
+ "data-slot": "canvas-shell-content",
167
+ style: contentStyle,
168
+ children: /* @__PURE__ */ jsx("div", { className: "h-full w-full min-h-0 min-w-0 overflow-hidden", children })
169
+ }
170
+ );
171
+ }
172
+ function renderFloatingCanvasShell({
173
+ bottomBar,
174
+ bottomSlot,
175
+ children,
176
+ chromeInset = 16,
177
+ className,
178
+ contentPadding,
179
+ leftBar,
180
+ leftRail,
181
+ rightBar,
182
+ rightDock,
183
+ style,
184
+ topBar,
185
+ ...props
186
+ }, ref) {
187
+ const inset = toInsetValue(chromeInset) ?? "16px";
188
+ const resolvedBottomBar = bottomBar ?? bottomSlot;
189
+ const resolvedLeftBar = leftBar ?? leftRail;
190
+ const resolvedRightBar = rightBar ?? rightDock;
191
+ const hasTopBar = hasChromeContent(topBar);
192
+ const hasLeftBar = hasChromeContent(resolvedLeftBar);
193
+ const hasRightBar = hasChromeContent(resolvedRightBar);
194
+ const hasBottomBar = hasChromeContent(resolvedBottomBar);
195
+ const safeAreaInsets = getSafeAreaInsets({
196
+ chromeInset,
197
+ contentPadding,
198
+ hasBottomBar,
199
+ hasLeftBar,
200
+ hasRightBar,
201
+ hasTopBar
202
+ });
203
+ const mergedStyle = {
204
+ ...getSafeAreaStyle(safeAreaInsets),
205
+ ...style
206
+ };
207
+ const contentStyle = {
208
+ paddingBottom: "var(--canvas-shell-safe-bottom)",
209
+ paddingLeft: "var(--canvas-shell-safe-left)",
210
+ paddingRight: "var(--canvas-shell-safe-right)",
211
+ paddingTop: "var(--canvas-shell-safe-top)"
212
+ };
213
+ return /* @__PURE__ */ jsxs(
214
+ "section",
215
+ {
216
+ className: cn(
217
+ "relative isolate flex min-h-[720px] w-full overflow-hidden bg-[radial-gradient(circle_at_top,hsl(var(--background)/0.94),hsl(var(--muted)/0.6))]",
218
+ className
219
+ ),
220
+ ref,
221
+ style: mergedStyle,
222
+ ...props,
223
+ children: [
224
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-[linear-gradient(180deg,hsl(var(--background)/0.94),hsl(var(--background)/0.8))]" }),
225
+ /* @__PURE__ */ jsx(
226
+ CanvasShellChromeBefore,
227
+ {
228
+ inset,
229
+ leftBar: hasLeftBar ? resolvedLeftBar : void 0,
230
+ topBar: hasTopBar ? topBar : void 0
231
+ }
232
+ ),
233
+ renderFloatingContent(children, contentStyle),
234
+ /* @__PURE__ */ jsx(
235
+ CanvasShellChromeAfter,
236
+ {
237
+ bottomBar: hasBottomBar ? resolvedBottomBar : void 0,
238
+ inset,
239
+ rightBar: hasRightBar ? resolvedRightBar : void 0
240
+ }
241
+ )
242
+ ]
243
+ }
244
+ );
245
+ }
246
+ const CanvasShell = forwardRef((props, ref) => {
247
+ const { bottomBar, chromeInset, contentPadding, leftBar, rightBar } = props;
248
+ const hasExplicitChromeInset = Object.prototype.hasOwnProperty.call(
249
+ props,
250
+ "chromeInset"
251
+ );
252
+ const usesFloatingChrome = hasChromeContent(bottomBar) || hasChromeContent(leftBar) || hasChromeContent(rightBar) || contentPadding !== void 0 || hasExplicitChromeInset && chromeInset !== void 0;
253
+ if (!usesFloatingChrome) {
254
+ return renderLegacyCanvasShell(props, ref);
255
+ }
256
+ return renderFloatingCanvasShell(props, ref);
257
+ });
258
+ CanvasShell.displayName = "CanvasShell";
259
+ export {
260
+ CanvasShell
261
+ };
@@ -0,0 +1,4 @@
1
+ import { CanvasShell } from "./canvas-shell";
2
+ export {
3
+ CanvasShell
4
+ };