@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.
- package/CHANGELOG.md +0 -2
- package/dist/components/activity-heatmap/activity-heatmap.js +1 -2
- package/dist/components/ai-artifact/ai-artifact.js +8 -8
- package/dist/components/ai-sidebar/ai-sidebar.js +4 -4
- package/dist/components/blog-card/blog-card.js +1 -3
- package/dist/components/bottom-activity-strip/bottom-activity-strip.js +2 -2
- package/dist/components/candlestick-chart/candlestick-chart.js +1 -2
- package/dist/components/checklist/checklist.js +1 -4
- package/dist/components/chronological-timeline/chronological-timeline.js +2 -2
- package/dist/components/code-playground/code-playground.js +1 -2
- package/dist/components/comment-pin/comment-pin.js +2 -2
- package/dist/components/comparison/comparison.js +1 -2
- package/dist/components/completion-dialog/completion-dialog.js +1 -4
- package/dist/components/content-intro/content-intro.js +3 -5
- package/dist/components/exercise/exercise.js +2 -10
- package/dist/components/faq/faq.js +2 -6
- package/dist/components/floating-toolbar/floating-toolbar.js +2 -2
- package/dist/components/horizontal-scroll-row/horizontal-scroll-row.js +1 -2
- package/dist/components/interactive-timeline/interactive-timeline.js +2 -2
- package/dist/components/jarvis-dock/jarvis-dock.js +2 -2
- package/dist/components/key-concept/key-concept.js +1 -2
- package/dist/components/keyboard-shortcuts-help/keyboard-shortcuts-help.js +1 -2
- package/dist/components/knowledge-check/knowledge-check.js +2 -2
- package/dist/components/learning-objectives/learning-objectives.js +1 -2
- package/dist/components/map-timeline/map-timeline.js +4 -4
- package/dist/components/market-treemap/market-treemap.js +2 -2
- package/dist/components/navbar-saas/navbar-saas.js +0 -1
- package/dist/components/order-book/order-book.js +2 -2
- package/dist/components/policy-delivery-panel/policy-delivery-panel.js +2 -2
- package/dist/components/profile-section/profile-section.js +1 -2
- package/dist/components/prompt-templates/prompt-templates.js +2 -2
- package/dist/components/quiz/quiz.js +2 -3
- package/dist/components/relationship-inspector/relationship-inspector.js +2 -2
- package/dist/components/routing-assignment-panel/routing-assignment-panel.js +2 -2
- package/dist/components/run-timeline/run-timeline.js +2 -2
- package/dist/components/share-dialog/share-dialog.js +2 -2
- package/dist/components/share-section/share-section.js +1 -2
- package/dist/components/sidebar/sidebar.js +17 -18
- package/dist/components/slideshow/slideshow.js +1 -2
- package/dist/components/social-fab/social-fab.js +6 -6
- package/dist/components/status-board/status-board.js +1 -2
- package/dist/components/step-by-step/step-by-step.js +1 -2
- package/dist/components/table-of-contents/table-of-contents.js +2 -5
- package/dist/components/table-of-contents-panel/table-of-contents-panel.js +1 -3
- package/dist/components/timeline-scrubber/timeline-scrubber.js +2 -2
- package/dist/components/tutorial-complete/tutorial-complete.js +4 -6
- package/dist/components/tutorial-filters/tutorial-filters.js +1 -1
- package/dist/components/viewport-bookmarks/viewport-bookmarks.js +2 -2
- package/dist/components/watchlist/watchlist.js +1 -2
- package/dist/components/world-breadcrumbs/world-breadcrumbs.js +2 -2
- package/dist/components/world-clock-bar/world-clock-bar.js +1 -2
- package/dist/index.d.ts +24 -95
- 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(
|
|
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
|
|
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:
|
|
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
|
|
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:
|
|
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
|
|
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:
|
|
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
|
|
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:
|
|
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
|
|
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:
|
|
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
|
|
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:
|
|
233
|
+
onClick: handleClick,
|
|
234
234
|
ref,
|
|
235
235
|
size: children ? "sm" : "icon",
|
|
236
236
|
type: "button",
|
|
@@ -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
|
|
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:
|
|
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(
|
|
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(
|
|
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
|
|
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:
|
|
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(
|
|
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
|
|
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:
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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:
|
|
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(
|
|
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
|
|
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:
|
|
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
|
|
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:
|
|
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(
|
|
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(
|
|
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
|
|
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:
|
|
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(
|
|
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
|
|
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:
|
|
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
|
|
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:
|
|
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(({
|
|
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(
|
|
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
|
] }),
|
|
@@ -68,7 +68,7 @@ function BookSide({
|
|
|
68
68
|
] });
|
|
69
69
|
}
|
|
70
70
|
const OrderBook = React.forwardRef(
|
|
71
|
-
({
|
|
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(
|
|
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 ",
|