@vllnt/ui 0.2.1-canary.25c4600 → 0.2.1-canary.2ff6ef3

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 (53) hide show
  1. package/CHANGELOG.md +0 -2
  2. package/dist/components/activity-heatmap/activity-heatmap.js +1 -2
  3. package/dist/components/ai-artifact/ai-artifact.js +8 -8
  4. package/dist/components/ai-sidebar/ai-sidebar.js +4 -4
  5. package/dist/components/blog-card/blog-card.js +1 -3
  6. package/dist/components/bottom-activity-strip/bottom-activity-strip.js +2 -2
  7. package/dist/components/candlestick-chart/candlestick-chart.js +1 -2
  8. package/dist/components/checklist/checklist.js +1 -4
  9. package/dist/components/chronological-timeline/chronological-timeline.js +2 -2
  10. package/dist/components/code-playground/code-playground.js +1 -2
  11. package/dist/components/comment-pin/comment-pin.js +2 -2
  12. package/dist/components/comparison/comparison.js +1 -2
  13. package/dist/components/completion-dialog/completion-dialog.js +1 -4
  14. package/dist/components/content-intro/content-intro.js +3 -5
  15. package/dist/components/exercise/exercise.js +2 -10
  16. package/dist/components/faq/faq.js +2 -6
  17. package/dist/components/floating-toolbar/floating-toolbar.js +2 -2
  18. package/dist/components/horizontal-scroll-row/horizontal-scroll-row.js +1 -2
  19. package/dist/components/interactive-timeline/interactive-timeline.js +2 -2
  20. package/dist/components/jarvis-dock/jarvis-dock.js +2 -2
  21. package/dist/components/key-concept/key-concept.js +1 -2
  22. package/dist/components/keyboard-shortcuts-help/keyboard-shortcuts-help.js +1 -2
  23. package/dist/components/knowledge-check/knowledge-check.js +2 -2
  24. package/dist/components/learning-objectives/learning-objectives.js +1 -2
  25. package/dist/components/map-timeline/map-timeline.js +4 -4
  26. package/dist/components/market-treemap/market-treemap.js +2 -2
  27. package/dist/components/navbar-saas/navbar-saas.js +0 -1
  28. package/dist/components/order-book/order-book.js +2 -2
  29. package/dist/components/policy-delivery-panel/policy-delivery-panel.js +2 -2
  30. package/dist/components/profile-section/profile-section.js +1 -2
  31. package/dist/components/prompt-templates/prompt-templates.js +2 -2
  32. package/dist/components/quiz/quiz.js +2 -3
  33. package/dist/components/relationship-inspector/relationship-inspector.js +2 -2
  34. package/dist/components/routing-assignment-panel/routing-assignment-panel.js +2 -2
  35. package/dist/components/run-timeline/run-timeline.js +2 -2
  36. package/dist/components/share-dialog/share-dialog.js +2 -2
  37. package/dist/components/share-section/share-section.js +1 -2
  38. package/dist/components/sidebar/sidebar.js +17 -18
  39. package/dist/components/slideshow/slideshow.js +1 -2
  40. package/dist/components/social-fab/social-fab.js +6 -6
  41. package/dist/components/status-board/status-board.js +1 -2
  42. package/dist/components/step-by-step/step-by-step.js +1 -2
  43. package/dist/components/table-of-contents/table-of-contents.js +2 -5
  44. package/dist/components/table-of-contents-panel/table-of-contents-panel.js +1 -3
  45. package/dist/components/timeline-scrubber/timeline-scrubber.js +2 -2
  46. package/dist/components/tutorial-complete/tutorial-complete.js +4 -6
  47. package/dist/components/tutorial-filters/tutorial-filters.js +1 -1
  48. package/dist/components/viewport-bookmarks/viewport-bookmarks.js +2 -2
  49. package/dist/components/watchlist/watchlist.js +1 -2
  50. package/dist/components/world-breadcrumbs/world-breadcrumbs.js +2 -2
  51. package/dist/components/world-clock-bar/world-clock-bar.js +1 -2
  52. package/dist/index.d.ts +24 -95
  53. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -29,8 +29,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
29
29
  - **Time navigation** — `TimelineScrubber`, `PlaybackGhost`, `BottomActivityStrip`, `RunTimeline`.
30
30
  - Total component count: **225** (up from 140).
31
31
 
32
- - **A11y heading-level override** — every title-bearing component (`ProfileSection`, `FAQ`, `Slideshow`, `WorldClockBar`, `TableOfContentsPanel`, `TableOfContents`, `KeyboardShortcutsHelp`, `Watchlist`, `OrderBook`, `HorizontalScrollRow`, `MarketTreemap`, `ActivityHeatmap`, `Glossary`, `StatusBoard`, `CodePlayground`, `Comparison`, `Quiz`, `Exercise`, `ShareSection`, `CompletionDialog`, `Checklist`, `LearningObjectives`, `CandlestickChart`, `StepByStep`) accepts an `as` prop (`"h1"`–`"h6"`); multi-title components (`ContentIntro`, `TutorialComplete`) expose `titleAs` + `tocLabelAs` / `sectionLabelAs`. Defaults preserve existing heading tags. `HeadingTag` is re-exported from `@vllnt/ui`.
33
-
34
32
  ### Changed
35
33
 
36
34
  - Registry installs use a **hybrid CLI strategy** — leaf component source is inlined, sibling registry items resolve via `@vllnt/ui` to keep installs minimal and dedupe shared primitives.
@@ -145,7 +145,6 @@ function HeatmapGrid({
145
145
  }
146
146
  const ActivityHeatmap = React.forwardRef(
147
147
  ({
148
- as: Heading = "h2",
149
148
  className,
150
149
  data,
151
150
  description,
@@ -158,7 +157,7 @@ const ActivityHeatmap = React.forwardRef(
158
157
  const gridData = getGridData(data, normalizedEndDate, weeks);
159
158
  return /* @__PURE__ */ jsxs("div", { className: cn("space-y-4", className), ref, ...props, children: [
160
159
  /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
161
- /* @__PURE__ */ jsx(Heading, { className: "text-lg font-semibold tracking-tight", children: title }),
160
+ /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold tracking-tight", children: title }),
162
161
  description ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: description }) : null
163
162
  ] }),
164
163
  /* @__PURE__ */ jsx("div", { className: "overflow-x-auto rounded-lg border bg-card p-4 shadow-sm", children: /* @__PURE__ */ jsx(HeatmapGrid, { gridData, weeks }) })
@@ -259,7 +259,7 @@ const AIArtifactToolbar = forwardRef(({ className, ...rest }, ref) => /* @__PURE
259
259
  AIArtifactToolbar.displayName = "AIArtifactToolbar";
260
260
  const AIArtifactCopyButton = forwardRef(({ className, onClick, ...rest }, ref) => {
261
261
  const { copied, copy, labels } = useAIArtifact();
262
- const handleCopyArtifact = useCallback(
262
+ const handleClick = useCallback(
263
263
  (event) => {
264
264
  onClick?.(event);
265
265
  if (event.defaultPrevented) return;
@@ -272,7 +272,7 @@ const AIArtifactCopyButton = forwardRef(({ className, onClick, ...rest }, ref) =
272
272
  {
273
273
  "aria-label": copied ? labels.copied : labels.copy,
274
274
  className: cn("size-8", className),
275
- onClick: handleCopyArtifact,
275
+ onClick: handleClick,
276
276
  ref,
277
277
  size: "icon",
278
278
  type: "button",
@@ -285,7 +285,7 @@ const AIArtifactCopyButton = forwardRef(({ className, onClick, ...rest }, ref) =
285
285
  AIArtifactCopyButton.displayName = "AIArtifactCopyButton";
286
286
  const AIArtifactEditButton = forwardRef(({ className, onClick, ...rest }, ref) => {
287
287
  const { hasOnEdit, labels, onEdit } = useAIArtifact();
288
- const handleEditArtifact = useCallback(
288
+ const handleClick = useCallback(
289
289
  (event) => {
290
290
  onClick?.(event);
291
291
  if (event.defaultPrevented) return;
@@ -299,7 +299,7 @@ const AIArtifactEditButton = forwardRef(({ className, onClick, ...rest }, ref) =
299
299
  {
300
300
  "aria-label": labels.edit,
301
301
  className: cn("size-8", className),
302
- onClick: handleEditArtifact,
302
+ onClick: handleClick,
303
303
  ref,
304
304
  size: "icon",
305
305
  type: "button",
@@ -312,7 +312,7 @@ const AIArtifactEditButton = forwardRef(({ className, onClick, ...rest }, ref) =
312
312
  AIArtifactEditButton.displayName = "AIArtifactEditButton";
313
313
  const AIArtifactDownloadButton = forwardRef(({ className, onClick, ...rest }, ref) => {
314
314
  const { download, labels } = useAIArtifact();
315
- const handleDownloadArtifact = useCallback(
315
+ const handleClick = useCallback(
316
316
  (event) => {
317
317
  onClick?.(event);
318
318
  if (event.defaultPrevented) return;
@@ -325,7 +325,7 @@ const AIArtifactDownloadButton = forwardRef(({ className, onClick, ...rest }, re
325
325
  {
326
326
  "aria-label": labels.download,
327
327
  className: cn("size-8", className),
328
- onClick: handleDownloadArtifact,
328
+ onClick: handleClick,
329
329
  ref,
330
330
  size: "icon",
331
331
  type: "button",
@@ -338,7 +338,7 @@ const AIArtifactDownloadButton = forwardRef(({ className, onClick, ...rest }, re
338
338
  AIArtifactDownloadButton.displayName = "AIArtifactDownloadButton";
339
339
  const AIArtifactFullscreenButton = forwardRef(({ className, onClick, ...rest }, ref) => {
340
340
  const { fullscreen, labels, toggleFullscreen } = useAIArtifact();
341
- const handleToggleArtifactFullscreen = useCallback(
341
+ const handleClick = useCallback(
342
342
  (event) => {
343
343
  onClick?.(event);
344
344
  if (event.defaultPrevented) return;
@@ -352,7 +352,7 @@ const AIArtifactFullscreenButton = forwardRef(({ className, onClick, ...rest },
352
352
  "aria-label": fullscreen ? labels.exitFullscreen : labels.enterFullscreen,
353
353
  "aria-pressed": fullscreen,
354
354
  className: cn("size-8", className),
355
- onClick: handleToggleArtifactFullscreen,
355
+ onClick: handleClick,
356
356
  ref,
357
357
  size: "icon",
358
358
  type: "button",
@@ -169,7 +169,7 @@ const AISidebarTitle = forwardRef(({ children, className, ...rest }, ref) => {
169
169
  AISidebarTitle.displayName = "AISidebarTitle";
170
170
  const AISidebarClose = forwardRef(({ className, onClick, ...rest }, ref) => {
171
171
  const { close, labels } = useAISidebar();
172
- const handleCloseSidebar = useCallback(
172
+ const handleClick = useCallback(
173
173
  (event) => {
174
174
  onClick?.(event);
175
175
  if (event.defaultPrevented) return;
@@ -182,7 +182,7 @@ const AISidebarClose = forwardRef(({ className, onClick, ...rest }, ref) => {
182
182
  {
183
183
  "aria-label": labels.close,
184
184
  className: cn("size-8", className),
185
- onClick: handleCloseSidebar,
185
+ onClick: handleClick,
186
186
  ref,
187
187
  size: "icon",
188
188
  type: "button",
@@ -215,7 +215,7 @@ const AISidebarFooter = forwardRef(({ children, className, ...rest }, ref) => /*
215
215
  AISidebarFooter.displayName = "AISidebarFooter";
216
216
  const AISidebarTrigger = forwardRef(({ children, className, onClick, ...rest }, ref) => {
217
217
  const { labels, openState, toggle } = useAISidebar();
218
- const handleToggleSidebar = useCallback(
218
+ const handleClick = useCallback(
219
219
  (event) => {
220
220
  onClick?.(event);
221
221
  if (event.defaultPrevented) return;
@@ -230,7 +230,7 @@ const AISidebarTrigger = forwardRef(({ children, className, onClick, ...rest },
230
230
  "aria-label": children ? void 0 : labels.open,
231
231
  className: cn(className),
232
232
  "data-state": openState ? "open" : "closed",
233
- onClick: handleToggleSidebar,
233
+ onClick: handleClick,
234
234
  ref,
235
235
  size: children ? "sm" : "icon",
236
236
  type: "button",
@@ -43,9 +43,7 @@ function ContentCard({
43
43
  ] }) }) : null
44
44
  ] }) });
45
45
  }
46
- function BlogCard(props) {
47
- return /* @__PURE__ */ jsx(ContentCard, { ...props });
48
- }
46
+ const BlogCard = ContentCard;
49
47
  export {
50
48
  BlogCard,
51
49
  ContentCard
@@ -34,7 +34,7 @@ const Chip = (props) => {
34
34
  const { event } = props;
35
35
  const tone = event.tone ?? "neutral";
36
36
  if (event.onActivate) {
37
- const handleActivateEvent = () => {
37
+ const handleClick = () => {
38
38
  event.onActivate?.();
39
39
  };
40
40
  return /* @__PURE__ */ jsx(
@@ -43,7 +43,7 @@ const Chip = (props) => {
43
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
44
  "data-strip-event": event.id,
45
45
  "data-strip-event-tone": tone,
46
- onClick: handleActivateEvent,
46
+ onClick: handleClick,
47
47
  type: "button",
48
48
  children: /* @__PURE__ */ jsx(ChipBody, { event })
49
49
  }
@@ -158,7 +158,6 @@ function SessionPill({ sessionChange }) {
158
158
  }
159
159
  const CandlestickChart = React.forwardRef(
160
160
  ({
161
- as: Heading = "h3",
162
161
  className,
163
162
  data,
164
163
  height = DEFAULT_HEIGHT,
@@ -186,7 +185,7 @@ const CandlestickChart = React.forwardRef(
186
185
  /* @__PURE__ */ jsxs("div", { className: "mb-4 flex flex-wrap items-start justify-between gap-3", children: [
187
186
  /* @__PURE__ */ jsxs("div", { children: [
188
187
  /* @__PURE__ */ jsx("p", { className: "text-xs font-medium uppercase tracking-[0.28em] text-muted-foreground", children: "OHLC session" }),
189
- /* @__PURE__ */ jsx(Heading, { className: "text-lg font-semibold text-foreground", children: "Candlestick chart" })
188
+ /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-foreground", children: "Candlestick chart" })
190
189
  ] }),
191
190
  /* @__PURE__ */ jsx(SessionPill, { sessionChange })
192
191
  ] }),
@@ -67,14 +67,13 @@ function ChecklistItemRow({
67
67
  }
68
68
  function ChecklistHeader({
69
69
  checked,
70
- Heading,
71
70
  progress,
72
71
  title,
73
72
  total
74
73
  }) {
75
74
  if (!title) return null;
76
75
  return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-3", children: [
77
- /* @__PURE__ */ jsxs(Heading, { className: "font-semibold flex items-center gap-2", children: [
76
+ /* @__PURE__ */ jsxs("h4", { className: "font-semibold flex items-center gap-2", children: [
78
77
  /* @__PURE__ */ jsx(
79
78
  "svg",
80
79
  {
@@ -106,7 +105,6 @@ function ChecklistHeader({
106
105
  ] });
107
106
  }
108
107
  function Checklist({
109
- as: Heading = "h4",
110
108
  className,
111
109
  items,
112
110
  onComplete,
@@ -155,7 +153,6 @@ function Checklist({
155
153
  ChecklistHeader,
156
154
  {
157
155
  checked: checked.size,
158
- Heading,
159
156
  progress,
160
157
  title,
161
158
  total: items.length
@@ -168,7 +168,7 @@ const ChronoEvent = forwardRef(
168
168
  },
169
169
  [eventId, forwardedRef, registerEvent]
170
170
  );
171
- const handleFocusEvent = useCallback(() => {
171
+ const handleFocus = useCallback(() => {
172
172
  setActiveId(eventId);
173
173
  }, [eventId, setActiveId]);
174
174
  return /* @__PURE__ */ jsxs(
@@ -182,7 +182,7 @@ const ChronoEvent = forwardRef(
182
182
  "data-event-id": eventId,
183
183
  "data-featured": featured ? "true" : void 0,
184
184
  id: eventId,
185
- onFocus: handleFocusEvent,
185
+ onFocus: handleFocus,
186
186
  ref: refCallback,
187
187
  ...rest,
188
188
  children: [
@@ -13,7 +13,6 @@ function CodeLine({ highlightLines, line, lineNumber }) {
13
13
  }
14
14
  const EMPTY_HIGHLIGHT_LINES = [];
15
15
  function CodePlayground({
16
- as: Heading = "h4",
17
16
  children,
18
17
  description,
19
18
  filename,
@@ -37,7 +36,7 @@ function CodePlayground({
37
36
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
38
37
  /* @__PURE__ */ jsx("div", { className: "flex size-8 items-center justify-center rounded bg-primary/10", children: /* @__PURE__ */ jsx(Code, { className: "size-4 text-primary" }) }),
39
38
  /* @__PURE__ */ jsxs("div", { children: [
40
- /* @__PURE__ */ jsx(Heading, { className: "font-semibold text-sm", children: title }),
39
+ /* @__PURE__ */ jsx("h4", { className: "font-semibold text-sm", children: title }),
41
40
  description ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: description }) : null
42
41
  ] })
43
42
  ] }),
@@ -57,7 +57,7 @@ const CommentPin = forwardRef(
57
57
  const resolvedLabels = { ...DEFAULT_LABELS, ...labels };
58
58
  const showBadge = typeof unread === "number" && unread > 0;
59
59
  const ariaLabel = showBadge ? `${resolvedLabels.region}, ${unread} ${resolvedLabels.unreadSuffix}` : resolvedLabels.region;
60
- const handleActivateComment = () => {
60
+ const handleClick = () => {
61
61
  onActivate?.();
62
62
  };
63
63
  const body = /* @__PURE__ */ jsx(
@@ -89,7 +89,7 @@ const CommentPin = forwardRef(
89
89
  "aria-label": ariaLabel,
90
90
  className: "relative inline-flex rounded-full focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
91
91
  "data-comment-pin-trigger": true,
92
- onClick: handleActivateComment,
92
+ onClick: handleClick,
93
93
  type: "button",
94
94
  children: body
95
95
  }
@@ -24,7 +24,6 @@ const variantConfig = {
24
24
  };
25
25
  function Comparison({
26
26
  after,
27
- as: Heading = "h4",
28
27
  before,
29
28
  title,
30
29
  ...rest
@@ -41,7 +40,7 @@ function Comparison({
41
40
  const BeforeIcon = beforeConfig.icon;
42
41
  const AfterIcon = afterConfig.icon;
43
42
  return /* @__PURE__ */ jsxs("div", { className: "my-6", children: [
44
- title ? /* @__PURE__ */ jsx(Heading, { className: "font-semibold mb-3", children: title }) : null,
43
+ title ? /* @__PURE__ */ jsx("h4", { className: "font-semibold mb-3", children: title }) : null,
45
44
  /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
46
45
  /* @__PURE__ */ jsxs("div", { className: cn("rounded-lg border", beforeConfig.className), children: [
47
46
  /* @__PURE__ */ jsx(
@@ -4,7 +4,6 @@ import { memo, useCallback, useEffect, useRef } from "react";
4
4
  import { cn } from "../../lib/utils";
5
5
  import { Button } from "../button";
6
6
  function DialogContent({
7
- as: Heading = "h2",
8
7
  cancelLabel = "Skip",
9
8
  cancelShortcut = "S",
10
9
  className,
@@ -58,7 +57,7 @@ function DialogContent({
58
57
  }
59
58
  ),
60
59
  /* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
61
- /* @__PURE__ */ jsx(Heading, { className: "text-lg font-semibold", id: "completion-dialog-title", children: title }),
60
+ /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", id: "completion-dialog-title", children: title }),
62
61
  description ? /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground mt-1.5", children: description }) : null
63
62
  ] }),
64
63
  /* @__PURE__ */ jsxs("div", { className: "flex flex-row gap-2", children: [
@@ -84,7 +83,6 @@ function DialogContent({
84
83
  );
85
84
  }
86
85
  function CompletionDialogImpl({
87
- as,
88
86
  cancelLabel,
89
87
  cancelShortcut = "S",
90
88
  className,
@@ -151,7 +149,6 @@ function CompletionDialogImpl({
151
149
  /* @__PURE__ */ jsx(
152
150
  DialogContent,
153
151
  {
154
- as,
155
152
  cancelLabel,
156
153
  cancelShortcut,
157
154
  className,
@@ -19,9 +19,7 @@ function ContentIntroImpl({
19
19
  onStart,
20
20
  renderIntroContent,
21
21
  sections,
22
- title,
23
- titleAs: TitleHeading = "h2",
24
- tocLabelAs: TocHeading = "h3"
22
+ title
25
23
  }) {
26
24
  const mergedLabels = { ...DEFAULT_LABELS, ...labels };
27
25
  const hasProgress = completedSections.size > 0;
@@ -43,11 +41,11 @@ function ContentIntroImpl({
43
41
  return /* @__PURE__ */ jsxs(Fragment, { children: [
44
42
  /* @__PURE__ */ jsxs("div", { className: "animate-in fade-in-0 duration-500 pb-24", children: [
45
43
  /* @__PURE__ */ jsxs("section", { className: "py-6", children: [
46
- /* @__PURE__ */ jsx(TitleHeading, { className: "text-2xl md:text-3xl font-semibold mb-6", children: title }),
44
+ /* @__PURE__ */ jsx("h2", { className: "text-2xl md:text-3xl font-semibold mb-6", children: title }),
47
45
  /* @__PURE__ */ jsx("div", { className: cn("max-w-none", "[&_h2:first-of-type]:hidden"), children: renderIntroContent() })
48
46
  ] }),
49
47
  /* @__PURE__ */ jsxs("section", { className: "mt-8 py-6 border-t border-border", children: [
50
- /* @__PURE__ */ jsx(TocHeading, { className: "text-lg font-semibold mb-4", children: mergedLabels.tableOfContentsLabel }),
48
+ /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold mb-4", children: mergedLabels.tableOfContentsLabel }),
51
49
  /* @__PURE__ */ jsx("ol", { className: "space-y-2", children: sections.map((section, index) => {
52
50
  const isCompleted = !isLoading && completedSections.has(section.id);
53
51
  return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
@@ -9,18 +9,12 @@ const difficultyConfig = {
9
9
  hard: { className: "text-red-600 dark:text-red-400", label: "Hard" },
10
10
  medium: { className: "text-amber-600 dark:text-amber-400", label: "Medium" }
11
11
  };
12
- function ExerciseHeader({
13
- completed,
14
- config,
15
- Heading,
16
- onToggle,
17
- title
18
- }) {
12
+ function ExerciseHeader({ completed, config, onToggle, title }) {
19
13
  return /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-4 mb-4", children: [
20
14
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
21
15
  /* @__PURE__ */ jsx("div", { className: "flex size-10 items-center justify-center rounded-full bg-primary/10", children: /* @__PURE__ */ jsx(Dumbbell, { className: "size-5 text-primary" }) }),
22
16
  /* @__PURE__ */ jsxs("div", { children: [
23
- /* @__PURE__ */ jsx(Heading, { className: "font-semibold text-foreground", children: title }),
17
+ /* @__PURE__ */ jsx("h4", { className: "font-semibold text-foreground", children: title }),
24
18
  /* @__PURE__ */ jsx("span", { className: cn("text-xs font-medium", config.className), children: config.label })
25
19
  ] })
26
20
  ] }),
@@ -69,7 +63,6 @@ function ExerciseSolution({ onToggle, showSolution, solution }) {
69
63
  ] });
70
64
  }
71
65
  function Exercise({
72
- as: Heading = "h4",
73
66
  children,
74
67
  difficulty = "medium",
75
68
  hint,
@@ -85,7 +78,6 @@ function Exercise({
85
78
  {
86
79
  completed,
87
80
  config: difficultyConfig[difficulty],
88
- Heading,
89
81
  onToggle: () => {
90
82
  setCompleted(!completed);
91
83
  },
@@ -40,15 +40,11 @@ function FAQItem({ children, defaultOpen = false, question }) {
40
40
  )
41
41
  ] });
42
42
  }
43
- function FAQ({
44
- as: Heading = "h4",
45
- children,
46
- title = "Frequently Asked Questions"
47
- }) {
43
+ function FAQ({ children, title = "Frequently Asked Questions" }) {
48
44
  return /* @__PURE__ */ jsxs("div", { className: "my-6 rounded-lg border bg-card", children: [
49
45
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 p-4 border-b border-border", children: [
50
46
  /* @__PURE__ */ jsx(HelpCircle, { className: "size-5 text-primary" }),
51
- /* @__PURE__ */ jsx(Heading, { className: "font-semibold", children: title })
47
+ /* @__PURE__ */ jsx("h4", { className: "font-semibold", children: title })
52
48
  ] }),
53
49
  /* @__PURE__ */ jsx("div", { className: "px-4", children })
54
50
  ] });
@@ -31,7 +31,7 @@ const FloatingToolbar = forwardRef(
31
31
  ...rest,
32
32
  children: actions.map((action) => {
33
33
  const variant = action.variant ?? "ghost";
34
- const handleActivateToolbarAction = () => {
34
+ const handleClick = () => {
35
35
  action.onActivate();
36
36
  };
37
37
  return /* @__PURE__ */ jsxs(
@@ -46,7 +46,7 @@ const FloatingToolbar = forwardRef(
46
46
  "data-action-id": action.id,
47
47
  "data-variant": variant,
48
48
  disabled: action.disabled,
49
- onClick: handleActivateToolbarAction,
49
+ onClick: handleClick,
50
50
  type: "button",
51
51
  children: [
52
52
  action.glyph ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "inline-flex size-3", children: action.glyph }) : null,
@@ -6,7 +6,6 @@ import { useHorizontalScroll } from "../../lib/use-horizontal-scroll";
6
6
  import { cn } from "../../lib/utils";
7
7
  import { Button } from "../button/button";
8
8
  const HorizontalScrollRow = memo(function HorizontalScrollRow2({
9
- as: Heading = "h3",
10
9
  children,
11
10
  className,
12
11
  description,
@@ -17,7 +16,7 @@ const HorizontalScrollRow = memo(function HorizontalScrollRow2({
17
16
  return /* @__PURE__ */ jsxs("section", { className: cn("space-y-4", className), children: [
18
17
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
19
18
  /* @__PURE__ */ jsxs("div", { children: [
20
- /* @__PURE__ */ jsx(Heading, { className: "text-lg font-semibold", children: title }),
19
+ /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold", children: title }),
21
20
  description ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: description }) : null
22
21
  ] }),
23
22
  showControls ? /* @__PURE__ */ jsxs("div", { className: "flex gap-1", children: [
@@ -219,7 +219,7 @@ function EventNode({
219
219
  if (!visible) return null;
220
220
  const titleText = typeof event.title === "string" ? event.title : "Event";
221
221
  const tooltipId = `${event.id}-tooltip`;
222
- const handleSelectTimelineEvent = (mouseEvent) => {
222
+ const handleClick = (mouseEvent) => {
223
223
  mouseEvent.stopPropagation();
224
224
  onSelect(event);
225
225
  };
@@ -236,7 +236,7 @@ function EventNode({
236
236
  "data-event-id": event.id,
237
237
  "data-event-track": event.track ?? "",
238
238
  "data-selected": active ? "true" : void 0,
239
- onClick: handleSelectTimelineEvent,
239
+ onClick: handleClick,
240
240
  style: {
241
241
  left: `${(left * 100).toString()}%`,
242
242
  width: isDuration ? `${(width * 100).toString()}%` : void 0
@@ -17,7 +17,7 @@ const DEFAULT_LABELS = {
17
17
  const ActionButton = (props) => {
18
18
  const { action } = props;
19
19
  const tone = action.tone ?? "neutral";
20
- const handleActivateAction = () => {
20
+ const handleClick = () => {
21
21
  action.onActivate();
22
22
  };
23
23
  return /* @__PURE__ */ jsxs(
@@ -26,7 +26,7 @@ const ActionButton = (props) => {
26
26
  className: "group relative flex size-12 flex-col items-center justify-center gap-0.5 rounded-md border border-transparent text-[10px] uppercase tracking-wide text-muted-foreground transition-colors hover:border-border hover:bg-muted/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
27
27
  "data-jarvis-action": action.id,
28
28
  "data-jarvis-tone": tone,
29
- onClick: handleActivateAction,
29
+ onClick: handleClick,
30
30
  type: "button",
31
31
  children: [
32
32
  /* @__PURE__ */ jsx(
@@ -43,14 +43,13 @@ function KeyConcept({
43
43
  );
44
44
  }
45
45
  function Glossary({
46
- as: Heading = "h4",
47
46
  children,
48
47
  className,
49
48
  icon,
50
49
  title = "Key Terms"
51
50
  }) {
52
51
  return /* @__PURE__ */ jsxs("div", { className: cn("my-6", className), children: [
53
- /* @__PURE__ */ jsxs(Heading, { className: "font-semibold mb-3 flex items-center gap-2", children: [
52
+ /* @__PURE__ */ jsxs("h4", { className: "font-semibold mb-3 flex items-center gap-2", children: [
54
53
  icon ? /* @__PURE__ */ jsx("span", { className: "size-4", children: icon }) : /* @__PURE__ */ jsx(
55
54
  "svg",
56
55
  {
@@ -3,7 +3,6 @@ import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { memo, useEffect, useRef } from "react";
4
4
  import { cn } from "../../lib/utils";
5
5
  function KeyboardShortcutsHelpImpl({
6
- as: Heading = "h2",
7
6
  className,
8
7
  closeIcon,
9
8
  footer,
@@ -59,7 +58,7 @@ function KeyboardShortcutsHelpImpl({
59
58
  ),
60
59
  children: [
61
60
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-4", children: [
62
- /* @__PURE__ */ jsx(Heading, { className: "text-lg font-semibold", id: "shortcuts-title", children: title }),
61
+ /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", id: "shortcuts-title", children: title }),
63
62
  /* @__PURE__ */ jsx(
64
63
  "button",
65
64
  {
@@ -238,13 +238,13 @@ function FillBlankField({
238
238
  onChange,
239
239
  value
240
240
  }) {
241
- const handleBlankValueChange = useCallback(
241
+ const handleChange = useCallback(
242
242
  (event) => {
243
243
  onChange(event.target.value);
244
244
  },
245
245
  [onChange]
246
246
  );
247
- return /* @__PURE__ */ jsx(Input, { id: inputId, onChange: handleBlankValueChange, value });
247
+ return /* @__PURE__ */ jsx(Input, { id: inputId, onChange: handleChange, value });
248
248
  }
249
249
  function QuestionField({
250
250
  groupName,
@@ -2,7 +2,6 @@
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { CheckCircle2, Clock, GraduationCap, Target } from "lucide-react";
4
4
  function LearningObjectives({
5
- as: Heading = "h4",
6
5
  estimatedTime,
7
6
  objectives,
8
7
  title = "What you'll learn"
@@ -11,7 +10,7 @@ function LearningObjectives({
11
10
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-4", children: [
12
11
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
13
12
  /* @__PURE__ */ jsx(Target, { className: "size-5 text-primary" }),
14
- /* @__PURE__ */ jsx(Heading, { className: "font-semibold text-foreground", children: title })
13
+ /* @__PURE__ */ jsx("h4", { className: "font-semibold text-foreground", children: title })
15
14
  ] }),
16
15
  estimatedTime ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
17
16
  /* @__PURE__ */ jsx(Clock, { className: "size-4" }),
@@ -214,7 +214,7 @@ MapTimelineControls.displayName = "MapTimelineControls";
214
214
  const MapTimelineSlider = forwardRef(({ className, ...rest }, ref) => {
215
215
  const { endYear, labels, setYear, startYear, year } = useTimelineContext();
216
216
  const sliderId = useId();
217
- const handleYearChange = (event) => {
217
+ const handleChange = (event) => {
218
218
  setYear(Number.parseInt(event.target.value, 10));
219
219
  };
220
220
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 items-center gap-2 text-xs font-medium text-muted-foreground", children: [
@@ -230,7 +230,7 @@ const MapTimelineSlider = forwardRef(({ className, ...rest }, ref) => {
230
230
  id: sliderId,
231
231
  max: endYear,
232
232
  min: startYear,
233
- onChange: handleYearChange,
233
+ onChange: handleChange,
234
234
  ref,
235
235
  type: "range",
236
236
  value: year,
@@ -251,7 +251,7 @@ const MapTimelineSlider = forwardRef(({ className, ...rest }, ref) => {
251
251
  MapTimelineSlider.displayName = "MapTimelineSlider";
252
252
  const MapTimelinePlayButton = forwardRef(({ className, ...rest }, ref) => {
253
253
  const { isPlaying, labels, setIsPlaying } = useTimelineContext();
254
- const handleTogglePlayback = () => {
254
+ const handleClick = () => {
255
255
  setIsPlaying(!isPlaying);
256
256
  };
257
257
  return /* @__PURE__ */ jsx(
@@ -264,7 +264,7 @@ const MapTimelinePlayButton = forwardRef(({ className, ...rest }, ref) => {
264
264
  className
265
265
  ),
266
266
  "data-playing": isPlaying ? "true" : void 0,
267
- onClick: handleTogglePlayback,
267
+ onClick: handleClick,
268
268
  ref,
269
269
  type: "button",
270
270
  ...rest,
@@ -67,7 +67,7 @@ function MarketTreemapTile({
67
67
  }
68
68
  );
69
69
  }
70
- const MarketTreemap = React.forwardRef(({ as: Heading = "h2", className, items, ...props }, reference) => {
70
+ const MarketTreemap = React.forwardRef(({ className, items, ...props }, reference) => {
71
71
  if (items.length === 0) {
72
72
  return null;
73
73
  }
@@ -85,7 +85,7 @@ const MarketTreemap = React.forwardRef(({ as: Heading = "h2", className, items,
85
85
  /* @__PURE__ */ jsxs("div", { className: "mb-4 flex flex-wrap items-center justify-between gap-3", children: [
86
86
  /* @__PURE__ */ jsxs("div", { children: [
87
87
  /* @__PURE__ */ jsx("p", { className: "text-xs font-medium uppercase tracking-[0.28em] text-muted-foreground", children: "Sector heatmap" }),
88
- /* @__PURE__ */ jsx(Heading, { className: "text-lg font-semibold text-foreground", children: "Market treemap" })
88
+ /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold text-foreground", children: "Market treemap" })
89
89
  ] }),
90
90
  /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Tile size maps market cap proxy; color reflects session change." })
91
91
  ] }),
@@ -24,7 +24,6 @@ function NavbarSaas({
24
24
  Button,
25
25
  {
26
26
  className: "lg:hidden",
27
- "data-testid": "navbar-saas-mobile-trigger",
28
27
  onClick: () => {
29
28
  setOpen(!open);
30
29
  },
@@ -68,7 +68,7 @@ function BookSide({
68
68
  ] });
69
69
  }
70
70
  const OrderBook = React.forwardRef(
71
- ({ as: Heading = "h2", asks, bids, className, precision = 2, ...props }, reference) => {
71
+ ({ asks, bids, className, precision = 2, ...props }, reference) => {
72
72
  if (asks.length === 0 && bids.length === 0) {
73
73
  return null;
74
74
  }
@@ -90,7 +90,7 @@ const OrderBook = React.forwardRef(
90
90
  /* @__PURE__ */ jsxs("div", { className: "mb-4 flex flex-wrap items-start justify-between gap-3", children: [
91
91
  /* @__PURE__ */ jsxs("div", { children: [
92
92
  /* @__PURE__ */ jsx("p", { className: "text-xs font-medium uppercase tracking-[0.28em] text-muted-foreground", children: "Level II" }),
93
- /* @__PURE__ */ jsx(Heading, { className: "text-lg font-semibold text-foreground", children: "Order book" })
93
+ /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold text-foreground", children: "Order book" })
94
94
  ] }),
95
95
  /* @__PURE__ */ jsxs("div", { className: "rounded-full border border-border bg-background/70 px-3 py-1 text-sm text-muted-foreground tabular-nums", children: [
96
96
  "Spread ",