@vllnt/ui 0.2.1-canary.06f0e84 → 0.2.1-canary.0cc4e50

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 (177) hide show
  1. package/CHANGELOG.md +3 -0
  2. package/dist/components/accordion/accordion.js +2 -2
  3. package/dist/components/activity-heatmap/activity-heatmap.js +17 -14
  4. package/dist/components/activity-log/activity-log.js +6 -6
  5. package/dist/components/agent-activity/agent-activity.js +8 -8
  6. package/dist/components/ai-artifact/ai-artifact.js +16 -16
  7. package/dist/components/ai-chat-input/ai-chat-input.js +3 -3
  8. package/dist/components/ai-message-bubble/ai-message-bubble.js +2 -2
  9. package/dist/components/ai-sidebar/ai-sidebar.js +8 -8
  10. package/dist/components/ai-source-citation/ai-source-citation.js +2 -2
  11. package/dist/components/ai-tool-call-display/ai-tool-call-display.js +5 -5
  12. package/dist/components/animated-text/animated-text.js +7 -7
  13. package/dist/components/annotation/annotation.js +1 -1
  14. package/dist/components/auto-reload/auto-reload.js +14 -4
  15. package/dist/components/avatar/avatar.js +1 -1
  16. package/dist/components/avatar-group/avatar-group.js +5 -5
  17. package/dist/components/banner/banner.js +3 -3
  18. package/dist/components/blog-card/blog-card.js +4 -2
  19. package/dist/components/bottom-activity-strip/bottom-activity-strip.js +3 -3
  20. package/dist/components/breadcrumb/breadcrumb.js +33 -26
  21. package/dist/components/button/button.js +1 -1
  22. package/dist/components/calendar/calendar.js +6 -6
  23. package/dist/components/callout/callout.js +1 -1
  24. package/dist/components/candlestick-chart/candlestick-chart.js +3 -2
  25. package/dist/components/canvas-shell/canvas-foundation-demo.js +5 -5
  26. package/dist/components/carousel/carousel.js +18 -10
  27. package/dist/components/category-filter/category-filter.js +1 -1
  28. package/dist/components/chat-dock-section/chat-dock-section.js +2 -2
  29. package/dist/components/checkbox/checkbox.js +2 -2
  30. package/dist/components/checklist/checklist.js +38 -10
  31. package/dist/components/checklist/index.js +8 -2
  32. package/dist/components/chronological-timeline/chronological-timeline.js +8 -7
  33. package/dist/components/civilization-card/civilization-card.js +1 -1
  34. package/dist/components/code-block/code-block.js +2 -2
  35. package/dist/components/code-playground/code-playground.js +11 -9
  36. package/dist/components/combobox/combobox.js +3 -8
  37. package/dist/components/command/command.js +1 -1
  38. package/dist/components/comment-pin/comment-pin.js +3 -3
  39. package/dist/components/comparison/comparison.js +11 -10
  40. package/dist/components/completion-dialog/completion-dialog.js +20 -12
  41. package/dist/components/connector-edge/connector-edge.js +1 -1
  42. package/dist/components/content-intro/content-intro.js +25 -21
  43. package/dist/components/context-menu/context-menu.js +4 -4
  44. package/dist/components/conversation-thread/conversation-thread.js +9 -9
  45. package/dist/components/cookie-consent/cookie-consent.js +1 -1
  46. package/dist/components/copy-button/copy-button.js +3 -3
  47. package/dist/components/countdown-timer/countdown-timer.js +9 -8
  48. package/dist/components/credit-badge/credit-badge.js +1 -7
  49. package/dist/components/curriculum/curriculum.js +10 -10
  50. package/dist/components/data-list/data-list.js +1 -1
  51. package/dist/components/data-table/data-table.js +6 -5
  52. package/dist/components/date-picker/date-picker.js +2 -7
  53. package/dist/components/dialog/dialog.js +1 -1
  54. package/dist/components/dropdown-menu/dropdown-menu.js +3 -3
  55. package/dist/components/empty-state/empty-state.js +3 -3
  56. package/dist/components/exercise/exercise.js +15 -7
  57. package/dist/components/faq/faq.js +8 -4
  58. package/dist/components/file-upload/file-upload.js +4 -9
  59. package/dist/components/filter-bar/filter-bar.js +9 -8
  60. package/dist/components/flashcard/flashcard.js +2 -2
  61. package/dist/components/floating-action-button/floating-action-button.js +1 -1
  62. package/dist/components/floating-toolbar/floating-toolbar.js +3 -3
  63. package/dist/components/flow-diagram/flow-controls.js +9 -9
  64. package/dist/components/flow-diagram/flow-error-boundary.js +2 -2
  65. package/dist/components/flow-diagram/flow-fullscreen.js +2 -2
  66. package/dist/components/form/form.js +1 -1
  67. package/dist/components/gantt-chart/gantt-chart.js +22 -19
  68. package/dist/components/globe-3d/globe-3d.js +16 -4
  69. package/dist/components/handoff-beacon/handoff-beacon.js +1 -1
  70. package/dist/components/historic-timeline/historic-timeline.js +2 -2
  71. package/dist/components/historical-figure-card/historical-figure-card.js +4 -7
  72. package/dist/components/horizontal-scroll-row/horizontal-scroll-row.js +6 -5
  73. package/dist/components/inline-input/inline-input.js +1 -1
  74. package/dist/components/input-otp/input-otp.js +1 -1
  75. package/dist/components/interactive-timeline/interactive-timeline.js +12 -9
  76. package/dist/components/jarvis-dock/jarvis-dock.js +4 -4
  77. package/dist/components/key-concept/key-concept.js +6 -5
  78. package/dist/components/keyboard-shortcuts-help/keyboard-shortcuts-help.js +4 -3
  79. package/dist/components/knowledge-check/knowledge-check.js +5 -5
  80. package/dist/components/lang-provider/lang-provider.js +3 -3
  81. package/dist/components/learning-objectives/learning-objectives.js +14 -13
  82. package/dist/components/live-feed/live-feed.js +17 -15
  83. package/dist/components/map-2d/map-2d.js +3 -3
  84. package/dist/components/map-timeline/map-timeline.js +5 -5
  85. package/dist/components/market-treemap/market-treemap.js +3 -3
  86. package/dist/components/mdx-content/mdx-content.js +19 -9
  87. package/dist/components/menubar/menubar.js +4 -4
  88. package/dist/components/metric-cluster/metric-cluster.js +1 -1
  89. package/dist/components/metric-gauge/metric-gauge.js +2 -2
  90. package/dist/components/model-comparison/model-comparison.js +2 -2
  91. package/dist/components/model-selector/model-selector.js +3 -3
  92. package/dist/components/multi-select/multi-select.js +4 -4
  93. package/dist/components/navbar-saas/navbar-saas.js +8 -7
  94. package/dist/components/navigation-menu/navigation-menu.js +2 -2
  95. package/dist/components/newsletter-signup/newsletter-signup.js +3 -3
  96. package/dist/components/number-input/number-input.js +2 -2
  97. package/dist/components/number-ticker/number-ticker.js +11 -4
  98. package/dist/components/object-card/object-card.js +1 -1
  99. package/dist/components/object-inspector/object-inspector.js +1 -1
  100. package/dist/components/order-book/order-book.js +2 -2
  101. package/dist/components/overview-board/overview-board.js +1 -1
  102. package/dist/components/parallel-timeline/parallel-timeline.js +2 -2
  103. package/dist/components/password-input/password-input.js +1 -1
  104. package/dist/components/plan-badge/plan-badge.js +1 -7
  105. package/dist/components/policy-delivery-panel/policy-delivery-panel.js +2 -2
  106. package/dist/components/presence-stack/presence-stack.js +2 -2
  107. package/dist/components/presence-sync-indicator/presence-sync-indicator.js +1 -1
  108. package/dist/components/pricing-table/pricing-table.js +3 -3
  109. package/dist/components/pro-tip/pro-tip.js +6 -6
  110. package/dist/components/profile-section/profile-section.js +3 -2
  111. package/dist/components/progress-card/progress-card.js +5 -4
  112. package/dist/components/progress-tracker/progress-tracker.js +24 -14
  113. package/dist/components/prompt-templates/prompt-templates.js +4 -4
  114. package/dist/components/quiz/quiz.js +7 -6
  115. package/dist/components/radio-group/radio-group.js +2 -2
  116. package/dist/components/rating/rating.js +3 -3
  117. package/dist/components/relationship-inspector/relationship-inspector.js +2 -2
  118. package/dist/components/resizable/resizable.js +1 -1
  119. package/dist/components/routing-assignment-panel/routing-assignment-panel.js +2 -2
  120. package/dist/components/run-timeline/run-timeline.js +2 -2
  121. package/dist/components/runtime-overview-panel/runtime-overview-panel.js +1 -1
  122. package/dist/components/scope-selector/scope-selector.js +8 -8
  123. package/dist/components/search-bar/search-bar.js +24 -2
  124. package/dist/components/search-dialog/search-dialog.js +484 -51
  125. package/dist/components/select/select.js +5 -5
  126. package/dist/components/selection-halo/selection-halo.js +1 -1
  127. package/dist/components/severity-badge/severity-badge.js +2 -2
  128. package/dist/components/share-dialog/share-dialog.js +2 -2
  129. package/dist/components/share-section/share-section.js +2 -1
  130. package/dist/components/sheet/sheet.js +1 -1
  131. package/dist/components/sidebar/sidebar.js +31 -26
  132. package/dist/components/sidebar-toggle/sidebar-toggle.js +3 -3
  133. package/dist/components/slider/slider.js +1 -1
  134. package/dist/components/slideshow/slideshow.js +15 -13
  135. package/dist/components/social-fab/social-fab.js +12 -11
  136. package/dist/components/sparkline-grid/sparkline-grid.js +1 -1
  137. package/dist/components/spinner/spinner.js +4 -4
  138. package/dist/components/spinner/unicode-spinner.js +4 -2
  139. package/dist/components/stat-card/stat-card.js +5 -5
  140. package/dist/components/state-badge-overlay/state-badge-overlay.js +1 -1
  141. package/dist/components/status-board/status-board.js +14 -7
  142. package/dist/components/status-indicator/status-indicator.js +3 -3
  143. package/dist/components/step-by-step/step-by-step.js +10 -8
  144. package/dist/components/step-navigation/step-navigation.js +2 -2
  145. package/dist/components/stepper/stepper.js +3 -3
  146. package/dist/components/sticky-metric/sticky-metric.js +1 -1
  147. package/dist/components/subscription-card/subscription-card.js +1 -1
  148. package/dist/components/switch/switch.js +1 -1
  149. package/dist/components/table-of-contents/table-of-contents.js +5 -2
  150. package/dist/components/table-of-contents-panel/table-of-contents-panel.js +8 -6
  151. package/dist/components/tabs/tabs.js +26 -8
  152. package/dist/components/tags-input/tags-input.js +12 -4
  153. package/dist/components/terminal/terminal.js +59 -37
  154. package/dist/components/theme-toggle/theme-toggle.js +2 -2
  155. package/dist/components/thinking-block/thinking-block.js +3 -3
  156. package/dist/components/ticker-tape/ticker-tape.js +4 -4
  157. package/dist/components/timeline/timeline.js +2 -2
  158. package/dist/components/timeline-scrubber/timeline-scrubber.js +2 -2
  159. package/dist/components/tldr-section/tldr-section.js +11 -9
  160. package/dist/components/tour/tour.js +2 -2
  161. package/dist/components/transaction-list/transaction-list.js +30 -9
  162. package/dist/components/tree-view/tree-view.js +2 -2
  163. package/dist/components/tutorial-card/tutorial-card.js +1 -1
  164. package/dist/components/tutorial-complete/tutorial-complete.js +16 -14
  165. package/dist/components/tutorial-filters/tutorial-filters.js +2 -2
  166. package/dist/components/tutorial-intro-content/tutorial-intro-content.js +5 -5
  167. package/dist/components/tutorial-mdx/tutorial-mdx.js +6 -6
  168. package/dist/components/usage-breakdown/usage-breakdown.js +10 -6
  169. package/dist/components/video-embed/video-embed.js +2 -2
  170. package/dist/components/viewport-bookmarks/viewport-bookmarks.js +3 -3
  171. package/dist/components/wallet-card/wallet-card.js +1 -1
  172. package/dist/components/watchlist/watchlist.js +7 -6
  173. package/dist/components/world-breadcrumbs/world-breadcrumbs.js +2 -2
  174. package/dist/components/world-clock-bar/world-clock-bar.js +35 -14
  175. package/dist/components/zoom-hud/zoom-hud.js +1 -1
  176. package/dist/index.d.ts +114 -30
  177. package/package.json +3 -3
@@ -20,39 +20,46 @@ function Breadcrumb({
20
20
  {
21
21
  "aria-label": "Breadcrumb",
22
22
  className: cn("flex items-center space-x-1 text-sm", className),
23
- children: items.map((item, index) => /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
24
- index > 0 && /* @__PURE__ */ jsx("span", { className: "mx-2", children: /* @__PURE__ */ jsx(SeparatorIcon, { type: separator }) }),
25
- item.href ? /* @__PURE__ */ jsxs(
26
- Link,
27
- {
28
- className: "flex items-center gap-1 hover:text-foreground transition-colors",
29
- href: item.href,
30
- children: [
23
+ children: items.map((item, index) => /* @__PURE__ */ jsxs(
24
+ "div",
25
+ {
26
+ className: "flex items-center",
27
+ children: [
28
+ index > 0 && /* @__PURE__ */ jsx("span", { className: "mx-2", children: /* @__PURE__ */ jsx(SeparatorIcon, { type: separator }) }),
29
+ item.href ? /* @__PURE__ */ jsxs(
30
+ Link,
31
+ {
32
+ className: "flex items-center gap-1 hover:text-foreground transition-colors",
33
+ href: item.href,
34
+ children: [
35
+ item.icon ? /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: item.icon }) : null,
36
+ /* @__PURE__ */ jsx(
37
+ "span",
38
+ {
39
+ className: cn(
40
+ // Truncate plain string labels; custom React elements handle their own overflow
41
+ typeof item.label === "string" && "truncate",
42
+ variant === "minimal" ? "text-muted-foreground" : "text-foreground"
43
+ ),
44
+ children: item.label
45
+ }
46
+ )
47
+ ]
48
+ }
49
+ ) : /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-muted-foreground", children: [
31
50
  item.icon ? /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: item.icon }) : null,
32
51
  /* @__PURE__ */ jsx(
33
52
  "span",
34
53
  {
35
- className: cn(
36
- // Truncate plain string labels; custom React elements handle their own overflow
37
- typeof item.label === "string" && "truncate",
38
- variant === "minimal" ? "text-muted-foreground" : "text-foreground"
39
- ),
54
+ className: cn(typeof item.label === "string" && "truncate"),
40
55
  children: item.label
41
56
  }
42
57
  )
43
- ]
44
- }
45
- ) : /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-muted-foreground", children: [
46
- item.icon ? /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: item.icon }) : null,
47
- /* @__PURE__ */ jsx(
48
- "span",
49
- {
50
- className: cn(typeof item.label === "string" && "truncate"),
51
- children: item.label
52
- }
53
- )
54
- ] })
55
- ] }, index))
58
+ ] })
59
+ ]
60
+ },
61
+ typeof item.label === "string" ? item.label : `breadcrumb-${index}`
62
+ ))
56
63
  }
57
64
  );
58
65
  }
@@ -13,7 +13,7 @@ const buttonVariants = cva(
13
13
  variants: {
14
14
  size: {
15
15
  default: "h-10 px-4 py-2",
16
- icon: "h-10 w-10",
16
+ icon: "size-10",
17
17
  lg: "h-11 rounded-md px-8",
18
18
  sm: "h-9 rounded-md px-3"
19
19
  },
@@ -5,10 +5,10 @@ import { DayPicker } from "react-day-picker";
5
5
  import { cn } from "../../lib/utils";
6
6
  import { buttonVariants } from "../button/button";
7
7
  function IconLeft() {
8
- return /* @__PURE__ */ jsx(ChevronLeft, { className: "h-4 w-4" });
8
+ return /* @__PURE__ */ jsx(ChevronLeft, { className: "size-4" });
9
9
  }
10
10
  function IconRight() {
11
- return /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" });
11
+ return /* @__PURE__ */ jsx(ChevronRight, { className: "size-4" });
12
12
  }
13
13
  function ChevronComponent({
14
14
  orientation = "right"
@@ -28,17 +28,17 @@ function Calendar({
28
28
  classNames: {
29
29
  button_next: cn(
30
30
  buttonVariants({ variant: "outline" }),
31
- "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100 absolute right-1"
31
+ "size-7 bg-transparent p-0 opacity-50 hover:opacity-100 absolute right-1"
32
32
  ),
33
33
  button_previous: cn(
34
34
  buttonVariants({ variant: "outline" }),
35
- "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100 absolute left-1"
35
+ "size-7 bg-transparent p-0 opacity-50 hover:opacity-100 absolute left-1"
36
36
  ),
37
37
  caption_label: "text-sm font-medium",
38
- day: "h-9 w-9 text-center text-sm p-0 relative [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20",
38
+ day: "size-9 text-center text-sm p-0 relative [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20",
39
39
  day_button: cn(
40
40
  buttonVariants({ variant: "ghost" }),
41
- "h-9 w-9 p-0 font-normal aria-selected:opacity-100"
41
+ "size-9 p-0 font-normal aria-selected:opacity-100"
42
42
  ),
43
43
  disabled: "text-muted-foreground opacity-50",
44
44
  hidden: "invisible",
@@ -45,7 +45,7 @@ function Callout({
45
45
  ),
46
46
  role: "alert",
47
47
  children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
48
- icon ? /* @__PURE__ */ jsx("span", { className: "h-5 w-5 flex-shrink-0 mt-0.5", children: icon }) : null,
48
+ icon ? /* @__PURE__ */ jsx("span", { className: "size-5 flex-shrink-0 mt-0.5", children: icon }) : null,
49
49
  /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
50
50
  displayTitle ? /* @__PURE__ */ jsx("p", { className: "font-semibold mb-1", children: displayTitle }) : null,
51
51
  /* @__PURE__ */ jsx("div", { className: "text-sm [&>p]:mb-0 [&>p:last-child]:mb-0", children })
@@ -149,7 +149,7 @@ function SessionPill({ sessionChange }) {
149
149
  isPositive ? "border-emerald-500/30 bg-emerald-500/10 text-emerald-600 dark:text-emerald-400" : "border-rose-500/30 bg-rose-500/10 text-rose-600 dark:text-rose-400"
150
150
  ),
151
151
  children: [
152
- /* @__PURE__ */ jsx(TrendIcon, { className: "h-4 w-4" }),
152
+ /* @__PURE__ */ jsx(TrendIcon, { className: "size-4" }),
153
153
  sessionChange >= 0 ? "+" : "",
154
154
  formatValue(sessionChange)
155
155
  ]
@@ -158,6 +158,7 @@ function SessionPill({ sessionChange }) {
158
158
  }
159
159
  const CandlestickChart = React.forwardRef(
160
160
  ({
161
+ as: Heading = "h3",
161
162
  className,
162
163
  data,
163
164
  height = DEFAULT_HEIGHT,
@@ -185,7 +186,7 @@ const CandlestickChart = React.forwardRef(
185
186
  /* @__PURE__ */ jsxs("div", { className: "mb-4 flex flex-wrap items-start justify-between gap-3", children: [
186
187
  /* @__PURE__ */ jsxs("div", { children: [
187
188
  /* @__PURE__ */ jsx("p", { className: "text-xs font-medium uppercase tracking-[0.28em] text-muted-foreground", children: "OHLC session" }),
188
- /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-foreground", children: "Candlestick chart" })
189
+ /* @__PURE__ */ jsx(Heading, { className: "text-lg font-semibold text-foreground", children: "Candlestick chart" })
189
190
  ] }),
190
191
  /* @__PURE__ */ jsx(SessionPill, { sessionChange })
191
192
  ] }),
@@ -1,6 +1,6 @@
1
1
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
2
  import { Activity, Bot, Compass, Layers3, Sparkles } from "lucide-react";
3
- import { BottomBar } from "../bottom-bar";
3
+ import { BottomBar } from "../bottom-bar/bottom-bar";
4
4
  import { Button } from "../button";
5
5
  import { CanvasView } from "../canvas-view";
6
6
  import { ChatDockSection } from "../chat-dock-section";
@@ -115,7 +115,7 @@ function DemoCanvasObjects() {
115
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
116
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
117
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" })
118
+ /* @__PURE__ */ jsx("div", { className: "size-2 rounded-full bg-primary/50" })
119
119
  ] }),
120
120
  /* @__PURE__ */ jsxs("div", { className: "mt-5 space-y-3", children: [
121
121
  /* @__PURE__ */ jsx("div", { className: "h-3 w-24 rounded-full bg-foreground/10" }),
@@ -130,9 +130,9 @@ function DemoCanvasObjects() {
130
130
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
131
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
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" })
133
+ /* @__PURE__ */ jsx("div", { className: "size-2 rounded-full bg-foreground/10" }),
134
+ /* @__PURE__ */ jsx("div", { className: "size-2 rounded-full bg-foreground/10" }),
135
+ /* @__PURE__ */ jsx("div", { className: "size-2 rounded-full bg-primary/45" })
136
136
  ] })
137
137
  ] }),
138
138
  /* @__PURE__ */ jsxs("div", { className: "mt-4 space-y-3", children: [
@@ -7,6 +7,7 @@ import {
7
7
  useContext,
8
8
  useEffect,
9
9
  useMemo,
10
+ useRef,
10
11
  useState
11
12
  } from "react";
12
13
  import useEmblaCarousel from "embla-carousel-react";
@@ -43,6 +44,10 @@ function useCarouselLogic({
43
44
  setCanScrollPrevious(api2.canScrollPrev());
44
45
  setCanScrollNext(api2.canScrollNext());
45
46
  }, []);
47
+ const onSelectReference = useRef(onSelect);
48
+ useEffect(() => {
49
+ onSelectReference.current = onSelect;
50
+ }, [onSelect]);
46
51
  const scrollPrevious = useCallback(() => {
47
52
  api?.scrollPrev();
48
53
  }, [api]);
@@ -71,17 +76,20 @@ function useCarouselLogic({
71
76
  if (!api) {
72
77
  return;
73
78
  }
74
- api.on("reInit", onSelect);
75
- api.on("select", onSelect);
79
+ const notifySelection = (selectedApi) => {
80
+ onSelectReference.current(selectedApi);
81
+ };
82
+ api.on("reInit", notifySelection);
83
+ api.on("select", notifySelection);
76
84
  const rafId = requestAnimationFrame(() => {
77
- onSelect(api);
85
+ notifySelection(api);
78
86
  });
79
87
  return () => {
80
- api?.off("select", onSelect);
81
- api?.off("reInit", onSelect);
88
+ api?.off("select", notifySelection);
89
+ api?.off("reInit", notifySelection);
82
90
  cancelAnimationFrame(rafId);
83
91
  };
84
- }, [api, onSelect]);
92
+ }, [api]);
85
93
  return {
86
94
  api,
87
95
  canScrollNext,
@@ -188,7 +196,7 @@ const CarouselPrevious = forwardRef(({ className, size = "icon", variant = "outl
188
196
  Button,
189
197
  {
190
198
  className: cn(
191
- "absolute h-8 w-8 rounded-full",
199
+ "absolute size-8 rounded-full",
192
200
  orientation === "horizontal" ? "-left-12 top-1/2 -translate-y-1/2" : "-top-12 left-1/2 -translate-x-1/2 rotate-90",
193
201
  className
194
202
  ),
@@ -199,7 +207,7 @@ const CarouselPrevious = forwardRef(({ className, size = "icon", variant = "outl
199
207
  variant,
200
208
  ...props,
201
209
  children: [
202
- /* @__PURE__ */ jsx(ArrowLeft, { className: "h-4 w-4" }),
210
+ /* @__PURE__ */ jsx(ArrowLeft, { className: "size-4" }),
203
211
  /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Previous slide" })
204
212
  ]
205
213
  }
@@ -212,7 +220,7 @@ const CarouselNext = forwardRef(({ className, size = "icon", variant = "outline"
212
220
  Button,
213
221
  {
214
222
  className: cn(
215
- "absolute h-8 w-8 rounded-full",
223
+ "absolute size-8 rounded-full",
216
224
  orientation === "horizontal" ? "-right-12 top-1/2 -translate-y-1/2" : "-bottom-12 left-1/2 -translate-x-1/2 rotate-90",
217
225
  className
218
226
  ),
@@ -223,7 +231,7 @@ const CarouselNext = forwardRef(({ className, size = "icon", variant = "outline"
223
231
  variant,
224
232
  ...props,
225
233
  children: [
226
- /* @__PURE__ */ jsx(ArrowRight, { className: "h-4 w-4" }),
234
+ /* @__PURE__ */ jsx(ArrowRight, { className: "size-4" }),
227
235
  /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Next slide" })
228
236
  ]
229
237
  }
@@ -2,7 +2,7 @@
2
2
  import { jsx } from "react/jsx-runtime";
3
3
  import Link from "next/link";
4
4
  import { usePathname } from "next/navigation";
5
- import { Badge } from "../badge";
5
+ import { Badge } from "../badge/badge";
6
6
  function slugify(text) {
7
7
  return text.toLowerCase().normalize("NFD").replaceAll(/[\u0300-\u036F]/g, "").replaceAll(/[^\s\w-]/g, "").trim().replaceAll(/\s+/g, "-").replaceAll(/-+/g, "-").replaceAll(/^-+|-+$/g, "");
8
8
  }
@@ -2,7 +2,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { forwardRef } from "react";
3
3
  import { ArrowUpRight, MessageSquareText } from "lucide-react";
4
4
  import { cn } from "../../lib/utils";
5
- import { Button } from "../button";
5
+ import { Button } from "../button/button";
6
6
  const ChatDockSection = forwardRef(
7
7
  ({
8
8
  className,
@@ -45,7 +45,7 @@ const ChatDockSection = forwardRef(
45
45
  },
46
46
  message.id
47
47
  )) }),
48
- /* @__PURE__ */ jsx("div", { className: "rounded-xl border border-dashed border-border/80 bg-background/70 px-3 py-3 text-sm text-muted-foreground", children: composerPlaceholder })
48
+ /* @__PURE__ */ jsx("div", { className: "rounded-xl border border-dashed border-border/80 bg-background/70 p-3 text-sm text-muted-foreground", children: composerPlaceholder })
49
49
  ]
50
50
  }
51
51
  )
@@ -8,7 +8,7 @@ const Checkbox = React.forwardRef(({ className, ...props }, reference) => /* @__
8
8
  CheckboxPrimitive.Root,
9
9
  {
10
10
  className: cn(
11
- "peer h-4 w-4 shrink-0 rounded border border-input bg-background ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[state=checked]:border-primary",
11
+ "peer size-4 shrink-0 rounded border border-input bg-background ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[state=checked]:border-primary",
12
12
  className
13
13
  ),
14
14
  ref: reference,
@@ -17,7 +17,7 @@ const Checkbox = React.forwardRef(({ className, ...props }, reference) => /* @__
17
17
  CheckboxPrimitive.Indicator,
18
18
  {
19
19
  className: cn("flex items-center justify-center text-current"),
20
- children: /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" })
20
+ children: /* @__PURE__ */ jsx(Check, { className: "size-4" })
21
21
  }
22
22
  )
23
23
  }
@@ -3,6 +3,31 @@ import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useState } from "react";
4
4
  import { cn } from "../../lib/utils";
5
5
  const CHECKLIST_PROGRESS_EVENT = "vllnt:checklist-progress-change";
6
+ const CHECKLIST_STORAGE_VERSION = 1;
7
+ function stringItemsFromUnknown(value) {
8
+ return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
9
+ }
10
+ function parseChecklistStorageValue(saved) {
11
+ try {
12
+ const parsed = JSON.parse(saved);
13
+ if (Array.isArray(parsed)) {
14
+ return stringItemsFromUnknown(parsed);
15
+ }
16
+ if (typeof parsed === "object" && parsed !== null && "version" in parsed && "checked" in parsed && parsed.version === CHECKLIST_STORAGE_VERSION) {
17
+ return stringItemsFromUnknown(parsed.checked);
18
+ }
19
+ } catch {
20
+ return [];
21
+ }
22
+ return [];
23
+ }
24
+ function createChecklistStorageValue(ids) {
25
+ const payload = {
26
+ checked: [...ids],
27
+ version: CHECKLIST_STORAGE_VERSION
28
+ };
29
+ return JSON.stringify(payload);
30
+ }
6
31
  function ChecklistItemRow({
7
32
  isChecked,
8
33
  item,
@@ -21,7 +46,7 @@ function ChecklistItemRow({
21
46
  isChecked ? /* @__PURE__ */ jsx(
22
47
  "svg",
23
48
  {
24
- className: "h-5 w-5 text-green-500 flex-shrink-0 mt-0.5",
49
+ className: "size-5 text-green-500 flex-shrink-0 mt-0.5",
25
50
  fill: "none",
26
51
  stroke: "currentColor",
27
52
  viewBox: "0 0 24 24",
@@ -38,7 +63,7 @@ function ChecklistItemRow({
38
63
  ) : /* @__PURE__ */ jsx(
39
64
  "svg",
40
65
  {
41
- className: "h-5 w-5 text-muted-foreground flex-shrink-0 mt-0.5",
66
+ className: "size-5 text-muted-foreground flex-shrink-0 mt-0.5",
42
67
  fill: "none",
43
68
  stroke: "currentColor",
44
69
  viewBox: "0 0 24 24",
@@ -67,17 +92,18 @@ function ChecklistItemRow({
67
92
  }
68
93
  function ChecklistHeader({
69
94
  checked,
95
+ Heading,
70
96
  progress,
71
97
  title,
72
98
  total
73
99
  }) {
74
100
  if (!title) return null;
75
101
  return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-3", children: [
76
- /* @__PURE__ */ jsxs("h4", { className: "font-semibold flex items-center gap-2", children: [
102
+ /* @__PURE__ */ jsxs(Heading, { className: "font-semibold flex items-center gap-2", children: [
77
103
  /* @__PURE__ */ jsx(
78
104
  "svg",
79
105
  {
80
- className: "h-5 w-5 text-primary",
106
+ className: "size-5 text-primary",
81
107
  fill: "none",
82
108
  stroke: "currentColor",
83
109
  viewBox: "0 0 24 24",
@@ -105,6 +131,7 @@ function ChecklistHeader({
105
131
  ] });
106
132
  }
107
133
  function Checklist({
134
+ as: Heading = "h4",
108
135
  className,
109
136
  items,
110
137
  onComplete,
@@ -115,10 +142,7 @@ function Checklist({
115
142
  if (typeof window !== "undefined" && persistKey) {
116
143
  const saved = localStorage.getItem(`checklist:${persistKey}`);
117
144
  if (saved) {
118
- try {
119
- return new Set(JSON.parse(saved));
120
- } catch {
121
- }
145
+ return new Set(parseChecklistStorageValue(saved));
122
146
  }
123
147
  }
124
148
  return /* @__PURE__ */ new Set();
@@ -132,7 +156,7 @@ function Checklist({
132
156
  try {
133
157
  localStorage.setItem(
134
158
  `checklist:${persistKey}`,
135
- JSON.stringify([...newChecked])
159
+ createChecklistStorageValue(newChecked)
136
160
  );
137
161
  window.dispatchEvent(
138
162
  new CustomEvent(CHECKLIST_PROGRESS_EVENT, {
@@ -153,6 +177,7 @@ function Checklist({
153
177
  ChecklistHeader,
154
178
  {
155
179
  checked: checked.size,
180
+ Heading,
156
181
  progress,
157
182
  title,
158
183
  total: items.length
@@ -184,5 +209,8 @@ function Checklist({
184
209
  }
185
210
  export {
186
211
  CHECKLIST_PROGRESS_EVENT,
187
- Checklist
212
+ CHECKLIST_STORAGE_VERSION,
213
+ Checklist,
214
+ createChecklistStorageValue,
215
+ parseChecklistStorageValue
188
216
  };
@@ -1,8 +1,14 @@
1
1
  import {
2
2
  Checklist,
3
- CHECKLIST_PROGRESS_EVENT
3
+ CHECKLIST_PROGRESS_EVENT,
4
+ CHECKLIST_STORAGE_VERSION,
5
+ createChecklistStorageValue,
6
+ parseChecklistStorageValue
4
7
  } from "./checklist";
5
8
  export {
6
9
  CHECKLIST_PROGRESS_EVENT,
7
- Checklist
10
+ CHECKLIST_STORAGE_VERSION,
11
+ Checklist,
12
+ createChecklistStorageValue,
13
+ parseChecklistStorageValue
8
14
  };
@@ -38,6 +38,7 @@ function ImageMedia({ media }) {
38
38
  ] });
39
39
  }
40
40
  function VideoMedia({ media }) {
41
+ const iframeTitle = media.title || "Embedded timeline video";
41
42
  return /* @__PURE__ */ jsxs("figure", { className: "overflow-hidden rounded-xl border bg-muted", children: [
42
43
  /* @__PURE__ */ jsx("div", { className: "aspect-video w-full", children: /* @__PURE__ */ jsx(
43
44
  "iframe",
@@ -46,7 +47,7 @@ function VideoMedia({ media }) {
46
47
  allowFullScreen: true,
47
48
  className: "h-full w-full",
48
49
  src: media.src,
49
- title: media.title ?? "Embedded video"
50
+ title: iframeTitle
50
51
  }
51
52
  ) }),
52
53
  media.caption || media.credit ? /* @__PURE__ */ jsxs("figcaption", { className: "border-t bg-background px-3 py-2 text-xs text-muted-foreground", children: [
@@ -56,7 +57,7 @@ function VideoMedia({ media }) {
56
57
  ] });
57
58
  }
58
59
  function AudioMedia({ media }) {
59
- return /* @__PURE__ */ jsxs("figure", { className: "overflow-hidden rounded-xl border bg-muted px-3 py-3", children: [
60
+ return /* @__PURE__ */ jsxs("figure", { className: "overflow-hidden rounded-xl border bg-muted p-3", children: [
60
61
  /* @__PURE__ */ jsx(
61
62
  "audio",
62
63
  {
@@ -94,8 +95,8 @@ function RailColumn({ featured }) {
94
95
  "span",
95
96
  {
96
97
  className: cn(
97
- "relative z-10 mt-3 block h-3 w-3 rounded-full border-2 border-background bg-primary",
98
- featured ? "h-4 w-4" : ""
98
+ "relative z-10 mt-3 block size-3 rounded-full border-2 border-background bg-primary",
99
+ featured ? "size-4" : ""
99
100
  )
100
101
  }
101
102
  )
@@ -167,7 +168,7 @@ const ChronoEvent = forwardRef(
167
168
  },
168
169
  [eventId, forwardedRef, registerEvent]
169
170
  );
170
- const handleFocus = useCallback(() => {
171
+ const handleFocusEvent = useCallback(() => {
171
172
  setActiveId(eventId);
172
173
  }, [eventId, setActiveId]);
173
174
  return /* @__PURE__ */ jsxs(
@@ -181,7 +182,7 @@ const ChronoEvent = forwardRef(
181
182
  "data-event-id": eventId,
182
183
  "data-featured": featured ? "true" : void 0,
183
184
  id: eventId,
184
- onFocus: handleFocus,
185
+ onFocus: handleFocusEvent,
185
186
  ref: refCallback,
186
187
  ...rest,
187
188
  children: [
@@ -308,7 +309,7 @@ const ChronologicalTimeline = forwardRef((props, ref) => {
308
309
  ...rest,
309
310
  children: [
310
311
  /* @__PURE__ */ jsx(ProgressStrip, { activeId, ids, label: progressLabel }),
311
- title ? /* @__PURE__ */ jsx("header", { className: "px-6 py-6", children: /* @__PURE__ */ jsx("h2", { className: "text-2xl font-semibold tracking-tight", id: titleId, children: title }) }) : null,
312
+ title ? /* @__PURE__ */ jsx("header", { className: "p-6", children: /* @__PURE__ */ jsx("h2", { className: "text-2xl font-semibold tracking-tight", id: titleId, children: title }) }) : null,
312
313
  /* @__PURE__ */ jsx(EventList, { activeId, children })
313
314
  ]
314
315
  }
@@ -71,7 +71,7 @@ function CivilizationHero({ color, image, imageAlt }) {
71
71
  className: "h-full w-full object-cover mix-blend-multiply",
72
72
  src: image
73
73
  }
74
- ) : /* @__PURE__ */ jsx("div", { className: "flex h-full w-full items-center justify-center text-muted-foreground/50", children: /* @__PURE__ */ jsx(Globe, { "aria-hidden": "true", className: "h-12 w-12" }) })
74
+ ) : /* @__PURE__ */ jsx("div", { className: "flex h-full w-full items-center justify-center text-muted-foreground/50", children: /* @__PURE__ */ jsx(Globe, { "aria-hidden": "true", className: "size-12" }) })
75
75
  }
76
76
  );
77
77
  }
@@ -107,11 +107,11 @@ function CodeBlock({
107
107
  /* @__PURE__ */ jsx(
108
108
  Button,
109
109
  {
110
- className: "h-8 w-8",
110
+ className: "size-8",
111
111
  onClick: handleCopy,
112
112
  size: "icon",
113
113
  variant: "ghost",
114
- children: copied ? /* @__PURE__ */ jsx(Check, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx(Copy, { className: "h-3 w-3" })
114
+ children: copied ? /* @__PURE__ */ jsx(Check, { className: "size-3" }) : /* @__PURE__ */ jsx(Copy, { className: "size-3" })
115
115
  }
116
116
  )
117
117
  ] })
@@ -3,7 +3,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useState } from "react";
4
4
  import { Check, Code, Copy, FileCode } from "lucide-react";
5
5
  import { cn } from "../../lib/utils";
6
- import { Button } from "../button";
6
+ import { Button } from "../button/button";
7
7
  function CodeLine({ highlightLines, line, lineNumber }) {
8
8
  const isHighlighted = highlightLines.includes(lineNumber);
9
9
  return /* @__PURE__ */ jsxs("div", { className: cn("flex", isHighlighted && "bg-primary/10 -mx-4 px-4"), children: [
@@ -11,11 +11,13 @@ function CodeLine({ highlightLines, line, lineNumber }) {
11
11
  /* @__PURE__ */ jsx("span", { children: line })
12
12
  ] });
13
13
  }
14
+ const EMPTY_HIGHLIGHT_LINES = [];
14
15
  function CodePlayground({
16
+ as: Heading = "h4",
15
17
  children,
16
18
  description,
17
19
  filename,
18
- highlightLines = [],
20
+ highlightLines = EMPTY_HIGHLIGHT_LINES,
19
21
  language = "typescript",
20
22
  showLineNumbers = false,
21
23
  title
@@ -33,25 +35,25 @@ function CodePlayground({
33
35
  return /* @__PURE__ */ jsxs("div", { className: "my-6 rounded-lg border bg-card overflow-hidden", children: [
34
36
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-b bg-muted/30", children: [
35
37
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
36
- /* @__PURE__ */ jsx("div", { className: "flex h-8 w-8 items-center justify-center rounded bg-primary/10", children: /* @__PURE__ */ jsx(Code, { className: "h-4 w-4 text-primary" }) }),
38
+ /* @__PURE__ */ jsx("div", { className: "flex size-8 items-center justify-center rounded bg-primary/10", children: /* @__PURE__ */ jsx(Code, { className: "size-4 text-primary" }) }),
37
39
  /* @__PURE__ */ jsxs("div", { children: [
38
- /* @__PURE__ */ jsx("h4", { className: "font-semibold text-sm", children: title }),
40
+ /* @__PURE__ */ jsx(Heading, { className: "font-semibold text-sm", children: title }),
39
41
  description ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: description }) : null
40
42
  ] })
41
43
  ] }),
42
44
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
43
45
  filename ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 text-xs text-muted-foreground", children: [
44
- /* @__PURE__ */ jsx(FileCode, { className: "h-3 w-3" }),
46
+ /* @__PURE__ */ jsx(FileCode, { className: "size-3" }),
45
47
  /* @__PURE__ */ jsx("span", { className: "font-mono", children: filename })
46
48
  ] }) : null,
47
49
  /* @__PURE__ */ jsx(
48
50
  Button,
49
51
  {
50
- className: "h-8 w-8",
52
+ className: "size-8",
51
53
  onClick: handleCopy,
52
54
  size: "icon",
53
55
  variant: "ghost",
54
- children: copied ? /* @__PURE__ */ jsx(Check, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx(Copy, { className: "h-3 w-3" })
56
+ children: copied ? /* @__PURE__ */ jsx(Check, { className: "size-3" }) : /* @__PURE__ */ jsx(Copy, { className: "size-3" })
55
57
  }
56
58
  )
57
59
  ] })
@@ -63,7 +65,7 @@ function CodePlayground({
63
65
  line,
64
66
  lineNumber: index + 1
65
67
  },
66
- index
68
+ `${line}-${index + 1}`
67
69
  )) }) : /* @__PURE__ */ jsx("code", { children: code }) }) }),
68
70
  /* @__PURE__ */ jsx("div", { className: "px-4 py-2 border-t bg-muted/30", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-mono text-muted-foreground uppercase tracking-wider", children: language }) })
69
71
  ] });
@@ -74,7 +76,7 @@ function FileTree({
74
76
  }) {
75
77
  return /* @__PURE__ */ jsxs("div", { className: "my-6 rounded-lg border bg-card overflow-hidden", children: [
76
78
  /* @__PURE__ */ jsx("div", { className: "px-4 py-2 border-b bg-muted/30", children: /* @__PURE__ */ jsxs("h4", { className: "font-semibold text-sm flex items-center gap-2", children: [
77
- /* @__PURE__ */ jsx(FileCode, { className: "h-4 w-4" }),
79
+ /* @__PURE__ */ jsx(FileCode, { className: "size-4" }),
78
80
  title
79
81
  ] }) }),
80
82
  /* @__PURE__ */ jsx("div", { className: "p-4 font-mono text-sm [&>ul]:m-0 [&>ul]:list-none [&_ul]:ml-4 [&_ul]:list-none [&_li]:text-muted-foreground", children })
@@ -3,7 +3,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import { Check, ChevronsUpDown } from "lucide-react";
5
5
  import { cn } from "../../lib/utils";
6
- import { Button } from "../button";
6
+ import { Button } from "../button/button";
7
7
  import {
8
8
  Command,
9
9
  CommandEmpty,
@@ -15,11 +15,6 @@ import {
15
15
  import { Popover, PopoverContent, PopoverTrigger } from "../popover";
16
16
  function useComboboxValue(value, onValueChange) {
17
17
  const [internalValue, setInternalValue] = React.useState(value ?? "");
18
- React.useEffect(() => {
19
- if (value !== void 0) {
20
- setInternalValue(value);
21
- }
22
- }, [value]);
23
18
  const resolvedValue = value ?? internalValue;
24
19
  const setResolvedValue = (nextValue) => {
25
20
  if (value === void 0) {
@@ -48,7 +43,7 @@ function ComboboxOptionItem({
48
43
  Check,
49
44
  {
50
45
  className: cn(
51
- "mr-2 h-4 w-4",
46
+ "mr-2 size-4",
52
47
  selectedValue === option.value ? "opacity-100" : "opacity-0"
53
48
  )
54
49
  }
@@ -128,7 +123,7 @@ const Combobox = React.forwardRef(
128
123
  variant: "outline",
129
124
  children: [
130
125
  /* @__PURE__ */ jsx("span", { className: "truncate", children: selectedOption ? selectedOption.label : placeholder }),
131
- /* @__PURE__ */ jsx(ChevronsUpDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })
126
+ /* @__PURE__ */ jsx(ChevronsUpDown, { className: "ml-2 size-4 shrink-0 opacity-50" })
132
127
  ]
133
128
  }
134
129
  ) }),