@vllnt/ui 0.2.1-canary.0aaaad2 → 0.2.1-canary.2994ef2
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 +2 -0
- package/dist/components/activity-heatmap/activity-heatmap.js +2 -1
- package/dist/components/ai-artifact/ai-artifact.js +8 -8
- package/dist/components/ai-sidebar/ai-sidebar.js +4 -4
- package/dist/components/auto-reload/auto-reload.js +1 -1
- package/dist/components/blog-card/blog-card.js +3 -1
- package/dist/components/bottom-activity-strip/bottom-activity-strip.js +2 -2
- package/dist/components/candlestick-chart/candlestick-chart.js +2 -1
- package/dist/components/carousel/carousel.js +14 -6
- package/dist/components/checklist/checklist.js +35 -7
- package/dist/components/checklist/index.js +8 -2
- package/dist/components/chronological-timeline/chronological-timeline.js +2 -2
- package/dist/components/code-playground/code-playground.js +2 -1
- package/dist/components/comment-pin/comment-pin.js +2 -2
- package/dist/components/comparison/comparison.js +2 -1
- package/dist/components/completion-dialog/completion-dialog.js +18 -10
- package/dist/components/content-intro/content-intro.js +17 -14
- package/dist/components/conversation-thread/conversation-thread.js +3 -3
- package/dist/components/exercise/exercise.js +10 -2
- package/dist/components/faq/faq.js +6 -2
- package/dist/components/filter-bar/filter-bar.js +6 -6
- package/dist/components/floating-toolbar/floating-toolbar.js +2 -2
- package/dist/components/gantt-chart/gantt-chart.js +8 -7
- package/dist/components/globe-3d/globe-3d.js +16 -4
- package/dist/components/horizontal-scroll-row/horizontal-scroll-row.js +2 -1
- package/dist/components/interactive-timeline/interactive-timeline.js +8 -5
- package/dist/components/jarvis-dock/jarvis-dock.js +2 -2
- package/dist/components/key-concept/key-concept.js +2 -1
- package/dist/components/keyboard-shortcuts-help/keyboard-shortcuts-help.js +2 -1
- package/dist/components/knowledge-check/knowledge-check.js +2 -2
- package/dist/components/learning-objectives/learning-objectives.js +2 -1
- package/dist/components/live-feed/live-feed.js +1 -1
- package/dist/components/map-2d/map-2d.js +1 -1
- package/dist/components/map-timeline/map-timeline.js +5 -5
- package/dist/components/market-treemap/market-treemap.js +2 -2
- package/dist/components/mdx-content/mdx-content.js +6 -6
- package/dist/components/navbar-saas/navbar-saas.js +1 -0
- package/dist/components/number-ticker/number-ticker.js +1 -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 +2 -1
- package/dist/components/progress-tracker/progress-tracker.js +12 -6
- package/dist/components/prompt-templates/prompt-templates.js +2 -2
- package/dist/components/quiz/quiz.js +3 -2
- 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 +2 -1
- package/dist/components/sidebar/sidebar.js +19 -18
- package/dist/components/slideshow/slideshow.js +2 -1
- package/dist/components/social-fab/social-fab.js +10 -10
- package/dist/components/spinner/spinner.js +1 -1
- package/dist/components/stat-card/stat-card.js +1 -1
- package/dist/components/status-board/status-board.js +12 -5
- package/dist/components/step-by-step/step-by-step.js +2 -1
- package/dist/components/table-of-contents/table-of-contents.js +5 -2
- package/dist/components/table-of-contents-panel/table-of-contents-panel.js +3 -1
- package/dist/components/tags-input/tags-input.js +11 -3
- package/dist/components/terminal/terminal.js +10 -2
- package/dist/components/theme-toggle/theme-toggle.js +2 -2
- package/dist/components/thinking-block/thinking-block.js +2 -2
- package/dist/components/timeline-scrubber/timeline-scrubber.js +2 -2
- package/dist/components/tldr-section/tldr-section.js +9 -7
- package/dist/components/transaction-list/transaction-list.js +2 -2
- package/dist/components/tutorial-complete/tutorial-complete.js +7 -5
- package/dist/components/tutorial-filters/tutorial-filters.js +1 -1
- package/dist/components/tutorial-intro-content/tutorial-intro-content.js +5 -5
- package/dist/components/tutorial-mdx/tutorial-mdx.js +5 -5
- package/dist/components/viewport-bookmarks/viewport-bookmarks.js +2 -2
- package/dist/components/watchlist/watchlist.js +2 -1
- package/dist/components/world-breadcrumbs/world-breadcrumbs.js +2 -2
- package/dist/components/world-clock-bar/world-clock-bar.js +4 -3
- package/dist/index.d.ts +95 -24
- package/package.json +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { memo, useCallback,
|
|
3
|
+
import { memo, useCallback, useTransition } from "react";
|
|
4
4
|
import { cn } from "../../lib/utils";
|
|
5
5
|
import { Badge } from "../badge";
|
|
6
6
|
function SearchInput({
|
|
@@ -160,15 +160,15 @@ function FilterBarImpl({
|
|
|
160
160
|
searchQuery,
|
|
161
161
|
tags
|
|
162
162
|
}) {
|
|
163
|
-
const [isPending,
|
|
163
|
+
const [isPending, startTransition] = useTransition();
|
|
164
164
|
const mergedLabels = { ...DEFAULT_LABELS, ...labels };
|
|
165
165
|
const handleDifficultyChange = useCallback(
|
|
166
166
|
(difficulty) => {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
167
|
+
startTransition(() => {
|
|
168
|
+
onFiltersChange({ difficulty });
|
|
169
|
+
});
|
|
170
170
|
},
|
|
171
|
-
[onFiltersChange]
|
|
171
|
+
[onFiltersChange, startTransition]
|
|
172
172
|
);
|
|
173
173
|
const handleSearchChange = useCallback(
|
|
174
174
|
(search) => {
|
|
@@ -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 handleActivateToolbarAction = () => {
|
|
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: handleActivateToolbarAction,
|
|
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,
|
|
@@ -56,7 +56,7 @@ function getTickDateTimeFormatter(locale, scale) {
|
|
|
56
56
|
let formatter = TICK_FORMATTER_CACHE.get(key);
|
|
57
57
|
if (!formatter) {
|
|
58
58
|
const options = scale === "month" ? { month: "short", year: "numeric" } : { day: "2-digit", month: "short" };
|
|
59
|
-
formatter =
|
|
59
|
+
formatter = Intl.DateTimeFormat(locale, options);
|
|
60
60
|
TICK_FORMATTER_CACHE.set(key, formatter);
|
|
61
61
|
}
|
|
62
62
|
return formatter;
|
|
@@ -93,13 +93,14 @@ function buildTicks(input) {
|
|
|
93
93
|
const formatter = buildTickFormatter(scale, locale);
|
|
94
94
|
const stepDays = getTickStep(scale);
|
|
95
95
|
const tickCount = Math.floor(totalDays / stepDays);
|
|
96
|
-
return Array.from({ length: tickCount + 1 }).
|
|
96
|
+
return Array.from({ length: tickCount + 1 }).reduce((ticks, _, index) => {
|
|
97
97
|
const day = index * stepDays;
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
offset: day
|
|
101
|
-
}
|
|
102
|
-
|
|
98
|
+
const date = new Date(start.getTime() + day * MS_PER_DAY);
|
|
99
|
+
if (date.getTime() <= end.getTime()) {
|
|
100
|
+
ticks.push({ label: formatter(date), offset: day });
|
|
101
|
+
}
|
|
102
|
+
return ticks;
|
|
103
|
+
}, []);
|
|
103
104
|
}
|
|
104
105
|
function useChartGeometry(options) {
|
|
105
106
|
const { endDate, locale, scale, startDate } = options;
|
|
@@ -161,9 +161,12 @@ const GlobeArc = forwardRef(
|
|
|
161
161
|
GlobeArc.displayName = "GlobeArc";
|
|
162
162
|
function buildLine(arguments_) {
|
|
163
163
|
const { points, rotationLat, rotationLng } = arguments_;
|
|
164
|
-
return points.
|
|
165
|
-
(state,
|
|
166
|
-
|
|
164
|
+
return points.reduce(
|
|
165
|
+
(state, coord) => {
|
|
166
|
+
const projected = project(coord, rotationLng, rotationLat);
|
|
167
|
+
if (!projected.visible) {
|
|
168
|
+
return { path: state.path, pen: "up" };
|
|
169
|
+
}
|
|
167
170
|
const head = state.pen === "up" ? "M" : "L";
|
|
168
171
|
const separator = state.path.length > 0 ? " " : "";
|
|
169
172
|
return {
|
|
@@ -185,7 +188,16 @@ function Graticule({ rotationLat, rotationLng }) {
|
|
|
185
188
|
const meridians = range(-150, 180, 30).map(
|
|
186
189
|
(lng) => range(-85, 85, 5).map((lat) => ({ lat, lng }))
|
|
187
190
|
);
|
|
188
|
-
const lines = [...parallels, ...meridians].
|
|
191
|
+
const lines = [...parallels, ...meridians].reduce(
|
|
192
|
+
(paths, points) => {
|
|
193
|
+
const path = buildLine({ points, rotationLat, rotationLng });
|
|
194
|
+
if (path.length > 0) {
|
|
195
|
+
paths.push(path);
|
|
196
|
+
}
|
|
197
|
+
return paths;
|
|
198
|
+
},
|
|
199
|
+
[]
|
|
200
|
+
);
|
|
189
201
|
return /* @__PURE__ */ jsx(
|
|
190
202
|
"g",
|
|
191
203
|
{
|
|
@@ -6,6 +6,7 @@ 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",
|
|
9
10
|
children,
|
|
10
11
|
className,
|
|
11
12
|
description,
|
|
@@ -16,7 +17,7 @@ const HorizontalScrollRow = memo(function HorizontalScrollRow2({
|
|
|
16
17
|
return /* @__PURE__ */ jsxs("section", { className: cn("space-y-4", className), children: [
|
|
17
18
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
18
19
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
19
|
-
/* @__PURE__ */ jsx(
|
|
20
|
+
/* @__PURE__ */ jsx(Heading, { className: "text-lg font-semibold", children: title }),
|
|
20
21
|
description ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: description }) : null
|
|
21
22
|
] }),
|
|
22
23
|
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 handleSelectTimelineEvent = (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: handleSelectTimelineEvent,
|
|
240
240
|
style: {
|
|
241
241
|
left: `${(left * 100).toString()}%`,
|
|
242
242
|
width: isDuration ? `${(width * 100).toString()}%` : void 0
|
|
@@ -607,9 +607,12 @@ function useTimelineContextValue(arguments_) {
|
|
|
607
607
|
function useTimelineFilter(categories, events) {
|
|
608
608
|
const [hidden, setHidden] = useState(() => /* @__PURE__ */ new Set());
|
|
609
609
|
const visibleCategories = useMemo(
|
|
610
|
-
() =>
|
|
611
|
-
|
|
612
|
-
|
|
610
|
+
() => categories.reduce((visible, category) => {
|
|
611
|
+
if (!hidden.has(category.id)) {
|
|
612
|
+
visible.add(category.id);
|
|
613
|
+
}
|
|
614
|
+
return visible;
|
|
615
|
+
}, /* @__PURE__ */ new Set()),
|
|
613
616
|
[categories, hidden]
|
|
614
617
|
);
|
|
615
618
|
const toggleCategory = useCallback((id) => {
|
|
@@ -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 handleActivateAction = () => {
|
|
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: handleActivateAction,
|
|
30
30
|
type: "button",
|
|
31
31
|
children: [
|
|
32
32
|
/* @__PURE__ */ jsx(
|
|
@@ -43,13 +43,14 @@ function KeyConcept({
|
|
|
43
43
|
);
|
|
44
44
|
}
|
|
45
45
|
function Glossary({
|
|
46
|
+
as: Heading = "h4",
|
|
46
47
|
children,
|
|
47
48
|
className,
|
|
48
49
|
icon,
|
|
49
50
|
title = "Key Terms"
|
|
50
51
|
}) {
|
|
51
52
|
return /* @__PURE__ */ jsxs("div", { className: cn("my-6", className), children: [
|
|
52
|
-
/* @__PURE__ */ jsxs(
|
|
53
|
+
/* @__PURE__ */ jsxs(Heading, { className: "font-semibold mb-3 flex items-center gap-2", children: [
|
|
53
54
|
icon ? /* @__PURE__ */ jsx("span", { className: "size-4", children: icon }) : /* @__PURE__ */ jsx(
|
|
54
55
|
"svg",
|
|
55
56
|
{
|
|
@@ -3,6 +3,7 @@ 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",
|
|
6
7
|
className,
|
|
7
8
|
closeIcon,
|
|
8
9
|
footer,
|
|
@@ -58,7 +59,7 @@ function KeyboardShortcutsHelpImpl({
|
|
|
58
59
|
),
|
|
59
60
|
children: [
|
|
60
61
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-4", children: [
|
|
61
|
-
/* @__PURE__ */ jsx(
|
|
62
|
+
/* @__PURE__ */ jsx(Heading, { className: "text-lg font-semibold", id: "shortcuts-title", children: title }),
|
|
62
63
|
/* @__PURE__ */ jsx(
|
|
63
64
|
"button",
|
|
64
65
|
{
|
|
@@ -238,13 +238,13 @@ function FillBlankField({
|
|
|
238
238
|
onChange,
|
|
239
239
|
value
|
|
240
240
|
}) {
|
|
241
|
-
const
|
|
241
|
+
const handleBlankValueChange = 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: handleBlankValueChange, value });
|
|
248
248
|
}
|
|
249
249
|
function QuestionField({
|
|
250
250
|
groupName,
|
|
@@ -2,6 +2,7 @@
|
|
|
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",
|
|
5
6
|
estimatedTime,
|
|
6
7
|
objectives,
|
|
7
8
|
title = "What you'll learn"
|
|
@@ -10,7 +11,7 @@ function LearningObjectives({
|
|
|
10
11
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-4", children: [
|
|
11
12
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
12
13
|
/* @__PURE__ */ jsx(Target, { className: "size-5 text-primary" }),
|
|
13
|
-
/* @__PURE__ */ jsx(
|
|
14
|
+
/* @__PURE__ */ jsx(Heading, { className: "font-semibold text-foreground", children: title })
|
|
14
15
|
] }),
|
|
15
16
|
estimatedTime ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
|
|
16
17
|
/* @__PURE__ */ jsx(Clock, { className: "size-4" }),
|
|
@@ -131,7 +131,7 @@ const LiveFeed = React.forwardRef(
|
|
|
131
131
|
[events, maxItems]
|
|
132
132
|
);
|
|
133
133
|
return /* @__PURE__ */ jsxs(Card, { className: cn("shadow-sm", className), ref, ...props, children: [
|
|
134
|
-
/* @__PURE__ */ jsxs(CardHeader, { className: "flex flex-row items-start justify-between gap-3
|
|
134
|
+
/* @__PURE__ */ jsxs(CardHeader, { className: "flex flex-row items-start justify-between gap-3 gap-y-0 pb-3", children: [
|
|
135
135
|
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
136
136
|
/* @__PURE__ */ jsx(CardTitle, { className: "text-base", children: title }),
|
|
137
137
|
description ? /* @__PURE__ */ jsx(CardDescription, { children: description }) : null
|
|
@@ -53,7 +53,7 @@ function useMapState(arguments_) {
|
|
|
53
53
|
}, [center]);
|
|
54
54
|
const [pan, setPan] = useState(initialPan);
|
|
55
55
|
const [zoom, setZoom] = useState(
|
|
56
|
-
clamp(initialZoom, MIN_ZOOM, MAX_ZOOM)
|
|
56
|
+
() => clamp(initialZoom, MIN_ZOOM, MAX_ZOOM)
|
|
57
57
|
);
|
|
58
58
|
const zoomIn = useCallback(() => {
|
|
59
59
|
setZoom((current) => clamp(current * ZOOM_STEP, MIN_ZOOM, MAX_ZOOM));
|
|
@@ -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 handleYearChange = (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: handleYearChange,
|
|
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 handleTogglePlayback = () => {
|
|
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: handleTogglePlayback,
|
|
268
268
|
ref,
|
|
269
269
|
type: "button",
|
|
270
270
|
...rest,
|
|
@@ -301,7 +301,7 @@ function useTimelineCtx(arguments_) {
|
|
|
301
301
|
function useTimelineState(arguments_) {
|
|
302
302
|
const { endYear, initialYear, onYearChange, startYear } = arguments_;
|
|
303
303
|
const [year, setYear] = useState(
|
|
304
|
-
clamp(initialYear ?? startYear, startYear, endYear)
|
|
304
|
+
() => clamp(initialYear ?? startYear, startYear, endYear)
|
|
305
305
|
);
|
|
306
306
|
const [isPlaying, setIsPlaying] = useState(false);
|
|
307
307
|
const updateYear = useCallback(
|
|
@@ -67,7 +67,7 @@ function MarketTreemapTile({
|
|
|
67
67
|
}
|
|
68
68
|
);
|
|
69
69
|
}
|
|
70
|
-
const MarketTreemap = React.forwardRef(({ className, items, ...props }, reference) => {
|
|
70
|
+
const MarketTreemap = React.forwardRef(({ as: Heading = "h2", className, items, ...props }, reference) => {
|
|
71
71
|
if (items.length === 0) {
|
|
72
72
|
return null;
|
|
73
73
|
}
|
|
@@ -85,7 +85,7 @@ const MarketTreemap = React.forwardRef(({ className, items, ...props }, referenc
|
|
|
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(Heading, { 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
|
] }),
|
|
@@ -16,7 +16,7 @@ const MDXComponents = {
|
|
|
16
16
|
blockquote: ({ children, ...props }) => /* @__PURE__ */ jsx(
|
|
17
17
|
"blockquote",
|
|
18
18
|
{
|
|
19
|
-
className: "border-l
|
|
19
|
+
className: "border-l border-primary pl-4 italic text-muted-foreground my-6 py-2 text-sm",
|
|
20
20
|
...props,
|
|
21
21
|
children
|
|
22
22
|
}
|
|
@@ -37,9 +37,9 @@ const MDXComponents = {
|
|
|
37
37
|
);
|
|
38
38
|
},
|
|
39
39
|
em: ({ children, ...props }) => /* @__PURE__ */ jsx("em", { className: "italic", ...props, children }),
|
|
40
|
-
h1: ({ children, ...props }) => /* @__PURE__ */ jsx("h1", { className: "text-2xl font-
|
|
41
|
-
h2: ({ children, ...props }) => /* @__PURE__ */ jsx("h2", { className: "text-xl font-
|
|
42
|
-
h3: ({ children, ...props }) => /* @__PURE__ */ jsx("h3", { className: "text-lg font-
|
|
40
|
+
h1: ({ children, ...props }) => /* @__PURE__ */ jsx("h1", { className: "text-2xl font-semibold mt-8 mb-4", ...props, children }),
|
|
41
|
+
h2: ({ children, ...props }) => /* @__PURE__ */ jsx("h2", { className: "text-xl font-semibold mt-6 mb-3", ...props, children }),
|
|
42
|
+
h3: ({ children, ...props }) => /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold mt-4 mb-2", ...props, children }),
|
|
43
43
|
hr: ({ ...props }) => /* @__PURE__ */ jsx("hr", { className: "my-8 border-border", ...props }),
|
|
44
44
|
li: ({ children, ...props }) => /* @__PURE__ */ jsx(
|
|
45
45
|
"li",
|
|
@@ -89,8 +89,8 @@ const proseClasses = [
|
|
|
89
89
|
"prose-strong:font-semibold prose-em:italic",
|
|
90
90
|
"prose-a:text-primary prose-a:underline prose-a:underline-offset-4 hover:prose-a:text-primary/80",
|
|
91
91
|
"prose-code:bg-muted prose-code:px-1 prose-code:py-0.5 prose-code:rounded prose-code:text-sm prose-code:font-mono",
|
|
92
|
-
"prose-pre:my-6 prose-pre:overflow-x-auto prose-pre:rounded-lg prose-pre:border prose-pre:bg-
|
|
93
|
-
"prose-blockquote:border-l
|
|
92
|
+
"prose-pre:my-6 prose-pre:overflow-x-auto prose-pre:rounded-lg prose-pre:border prose-pre:bg-zinc-950 prose-pre:py-4 prose-pre:font-mono prose-pre:text-sm prose-pre:text-white prose-pre:shadow-lg dark:prose-pre:bg-zinc-900",
|
|
93
|
+
"prose-blockquote:border-l prose-blockquote:border-primary prose-blockquote:pl-4 prose-blockquote:italic prose-blockquote:text-muted-foreground prose-blockquote:my-6 prose-blockquote:py-2",
|
|
94
94
|
"prose-hr:my-8 prose-hr:border-border",
|
|
95
95
|
"prose-table:w-full prose-table:border-collapse prose-table:border prose-table:border-border",
|
|
96
96
|
"prose-th:border prose-th:border-border prose-th:bg-muted prose-th:p-2 prose-th:text-left prose-th:font-medium",
|
|
@@ -7,7 +7,7 @@ function getNumberTickerFormatter(locale, formatOptions) {
|
|
|
7
7
|
const key = `${locale ?? ""}|${formatOptions ? JSON.stringify(formatOptions) : ""}`;
|
|
8
8
|
let formatter = NUMBER_FORMATTER_CACHE.get(key);
|
|
9
9
|
if (!formatter) {
|
|
10
|
-
formatter =
|
|
10
|
+
formatter = Intl.NumberFormat(locale, formatOptions);
|
|
11
11
|
NUMBER_FORMATTER_CACHE.set(key, formatter);
|
|
12
12
|
}
|
|
13
13
|
return formatter;
|
|
@@ -68,7 +68,7 @@ function BookSide({
|
|
|
68
68
|
] });
|
|
69
69
|
}
|
|
70
70
|
const OrderBook = React.forwardRef(
|
|
71
|
-
({ asks, bids, className, precision = 2, ...props }, reference) => {
|
|
71
|
+
({ as: Heading = "h2", 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(Heading, { 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 ",
|
|
@@ -40,7 +40,7 @@ const RowBody = (props) => {
|
|
|
40
40
|
const Row = (props) => {
|
|
41
41
|
const { policy } = props;
|
|
42
42
|
if (policy.onToggle) {
|
|
43
|
-
const
|
|
43
|
+
const handleTogglePolicy = () => {
|
|
44
44
|
policy.onToggle?.();
|
|
45
45
|
};
|
|
46
46
|
return /* @__PURE__ */ jsx(
|
|
@@ -49,7 +49,7 @@ const Row = (props) => {
|
|
|
49
49
|
className: "flex w-full items-center gap-2 rounded-md border border-transparent px-2 py-1.5 text-left transition-colors hover:border-border hover:bg-muted/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
50
50
|
"data-policy-row": policy.id,
|
|
51
51
|
"data-policy-status": policy.status,
|
|
52
|
-
onClick:
|
|
52
|
+
onClick: handleTogglePolicy,
|
|
53
53
|
type: "button",
|
|
54
54
|
children: /* @__PURE__ */ jsx(RowBody, { policy })
|
|
55
55
|
}
|
|
@@ -3,6 +3,7 @@ import Image from "next/image";
|
|
|
3
3
|
import Link from "next/link";
|
|
4
4
|
import { Button } from "../button/button";
|
|
5
5
|
function ProfileSection({
|
|
6
|
+
as: Heading = "h3",
|
|
6
7
|
compact = false,
|
|
7
8
|
dict,
|
|
8
9
|
imageAlt,
|
|
@@ -25,7 +26,7 @@ function ProfileSection({
|
|
|
25
26
|
}
|
|
26
27
|
) }) : null,
|
|
27
28
|
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
28
|
-
/* @__PURE__ */ jsx(
|
|
29
|
+
/* @__PURE__ */ jsx(Heading, { className: `font-semibold ${compact ? "text-lg" : "text-xl"}`, children: dict.profile.name }),
|
|
29
30
|
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: compact ? dict.profile.tagline : `> ${dict.profile.tagline}` })
|
|
30
31
|
] }),
|
|
31
32
|
showSocialLinks ? /* @__PURE__ */ jsx("div", { className: "flex flex-wrap justify-center items-center gap-2", children: socialLinks?.map((link) => /* @__PURE__ */ jsx(
|
|
@@ -10,7 +10,10 @@ import {
|
|
|
10
10
|
CardHeader,
|
|
11
11
|
CardTitle
|
|
12
12
|
} from "../card";
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
CHECKLIST_PROGRESS_EVENT,
|
|
15
|
+
parseChecklistStorageValue
|
|
16
|
+
} from "../checklist";
|
|
14
17
|
import { ProgressBar } from "../progress-bar";
|
|
15
18
|
const ProgressTrackerContext = React.createContext(null);
|
|
16
19
|
function clampPercentage(value) {
|
|
@@ -41,15 +44,13 @@ function readPersistedChecklistItems(persistKey) {
|
|
|
41
44
|
try {
|
|
42
45
|
const saved = localStorage.getItem(`checklist:${persistKey}`);
|
|
43
46
|
if (!saved) return [];
|
|
44
|
-
|
|
45
|
-
return Array.isArray(parsed) ? parsed.filter((item) => typeof item === "string") : [];
|
|
47
|
+
return parseChecklistStorageValue(saved);
|
|
46
48
|
} catch {
|
|
47
49
|
return [];
|
|
48
50
|
}
|
|
49
51
|
}
|
|
50
52
|
function areStringArraysEqual(left, right) {
|
|
51
|
-
|
|
52
|
-
return left.every((value, index) => value === right[index]);
|
|
53
|
+
return left.length === right.length && left.every((value, index) => value === right[index]);
|
|
53
54
|
}
|
|
54
55
|
function getChecklistPersistKey(event) {
|
|
55
56
|
if (!(event instanceof CustomEvent)) return null;
|
|
@@ -162,7 +163,12 @@ function ProgressTrackerOverview({
|
|
|
162
163
|
}) {
|
|
163
164
|
const { modules, overallProgress, streak, title } = useProgressTrackerContext();
|
|
164
165
|
const trackedPersistKeys = React.useMemo(
|
|
165
|
-
() => modules.
|
|
166
|
+
() => modules.reduce((keys, module) => {
|
|
167
|
+
if (module.persistKey) {
|
|
168
|
+
keys.push(module.persistKey);
|
|
169
|
+
}
|
|
170
|
+
return keys;
|
|
171
|
+
}, []),
|
|
166
172
|
[modules]
|
|
167
173
|
);
|
|
168
174
|
const [, forceChecklistRefresh] = React.useState(0);
|
|
@@ -243,7 +243,7 @@ function VariableField({
|
|
|
243
243
|
onValueChange,
|
|
244
244
|
value
|
|
245
245
|
}) {
|
|
246
|
-
const
|
|
246
|
+
const handleVariableValueChange = useCallback(
|
|
247
247
|
(event) => {
|
|
248
248
|
onValueChange(name, event.target.value);
|
|
249
249
|
},
|
|
@@ -255,7 +255,7 @@ function VariableField({
|
|
|
255
255
|
Input,
|
|
256
256
|
{
|
|
257
257
|
id: fieldId,
|
|
258
|
-
onChange:
|
|
258
|
+
onChange: handleVariableValueChange,
|
|
259
259
|
placeholder: `Value for ${name}`,
|
|
260
260
|
value
|
|
261
261
|
}
|
|
@@ -118,6 +118,7 @@ function QuizResult({
|
|
|
118
118
|
);
|
|
119
119
|
}
|
|
120
120
|
function Quiz({
|
|
121
|
+
as: Heading = "h4",
|
|
121
122
|
className,
|
|
122
123
|
explanation,
|
|
123
124
|
hint,
|
|
@@ -159,7 +160,7 @@ function Quiz({
|
|
|
159
160
|
)
|
|
160
161
|
}
|
|
161
162
|
),
|
|
162
|
-
/* @__PURE__ */ jsx(
|
|
163
|
+
/* @__PURE__ */ jsx(Heading, { className: "font-semibold text-foreground", children: question })
|
|
163
164
|
] }),
|
|
164
165
|
/* @__PURE__ */ jsx("div", { className: "space-y-2 mb-4", children: options.map((opt, index) => /* @__PURE__ */ jsx(
|
|
165
166
|
QuizOptionButton,
|
|
@@ -172,7 +173,7 @@ function Quiz({
|
|
|
172
173
|
selectedIndex,
|
|
173
174
|
submitted
|
|
174
175
|
},
|
|
175
|
-
|
|
176
|
+
`quiz-option-${index}-${opt.label}`
|
|
176
177
|
)) }),
|
|
177
178
|
hint && !submitted ? /* @__PURE__ */ jsx(
|
|
178
179
|
QuizHint,
|
|
@@ -28,7 +28,7 @@ const RowBody = (props) => {
|
|
|
28
28
|
const Row = (props) => {
|
|
29
29
|
const { edge } = props;
|
|
30
30
|
if (edge.onActivate) {
|
|
31
|
-
const
|
|
31
|
+
const handleActivateRelationship = () => {
|
|
32
32
|
edge.onActivate?.();
|
|
33
33
|
};
|
|
34
34
|
return /* @__PURE__ */ jsx(
|
|
@@ -37,7 +37,7 @@ const Row = (props) => {
|
|
|
37
37
|
className: "flex w-full items-center gap-2 rounded-md border border-transparent px-2 py-1.5 text-left transition-colors hover:border-border hover:bg-muted/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
38
38
|
"data-relationship-direction": edge.direction,
|
|
39
39
|
"data-relationship-row": true,
|
|
40
|
-
onClick:
|
|
40
|
+
onClick: handleActivateRelationship,
|
|
41
41
|
type: "button",
|
|
42
42
|
children: /* @__PURE__ */ jsx(RowBody, { edge })
|
|
43
43
|
}
|
|
@@ -63,7 +63,7 @@ const RowBody = (props) => {
|
|
|
63
63
|
const Row = (props) => {
|
|
64
64
|
const { assignment } = props;
|
|
65
65
|
if (assignment.onActivate) {
|
|
66
|
-
const
|
|
66
|
+
const handleActivateAssignment = () => {
|
|
67
67
|
assignment.onActivate?.();
|
|
68
68
|
};
|
|
69
69
|
return /* @__PURE__ */ jsx(
|
|
@@ -72,7 +72,7 @@ const Row = (props) => {
|
|
|
72
72
|
className: "flex w-full items-center gap-2 rounded-md border border-transparent px-2 py-1.5 text-left transition-colors hover:border-border hover:bg-muted/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
73
73
|
"data-routing-assignment": assignment.id,
|
|
74
74
|
"data-routing-role": assignment.role,
|
|
75
|
-
onClick:
|
|
75
|
+
onClick: handleActivateAssignment,
|
|
76
76
|
type: "button",
|
|
77
77
|
children: /* @__PURE__ */ jsx(RowBody, { assignment })
|
|
78
78
|
}
|
|
@@ -63,7 +63,7 @@ const PhaseBar = (props) => {
|
|
|
63
63
|
};
|
|
64
64
|
const ariaLabel = `${STATE_LABEL[state]} ${phase.start} \u2192 ${phase.end}`;
|
|
65
65
|
if (phase.onActivate) {
|
|
66
|
-
const
|
|
66
|
+
const handleActivatePhase = () => {
|
|
67
67
|
phase.onActivate?.();
|
|
68
68
|
};
|
|
69
69
|
return /* @__PURE__ */ jsx(
|
|
@@ -76,7 +76,7 @@ const PhaseBar = (props) => {
|
|
|
76
76
|
),
|
|
77
77
|
"data-run-phase": phase.id,
|
|
78
78
|
"data-run-phase-state": state,
|
|
79
|
-
onClick:
|
|
79
|
+
onClick: handleActivatePhase,
|
|
80
80
|
style: sharedStyle,
|
|
81
81
|
type: "button",
|
|
82
82
|
children: phase.label
|
|
@@ -13,7 +13,7 @@ function PlatformButton({
|
|
|
13
13
|
onClick,
|
|
14
14
|
platform
|
|
15
15
|
}) {
|
|
16
|
-
const
|
|
16
|
+
const handleSelectPlatform = () => {
|
|
17
17
|
onClick(platform.key);
|
|
18
18
|
};
|
|
19
19
|
return /* @__PURE__ */ jsx(
|
|
@@ -26,7 +26,7 @@ function PlatformButton({
|
|
|
26
26
|
"hover:bg-accent hover:text-accent-foreground",
|
|
27
27
|
"focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2"
|
|
28
28
|
),
|
|
29
|
-
onClick:
|
|
29
|
+
onClick: handleSelectPlatform,
|
|
30
30
|
type: "button",
|
|
31
31
|
children: platform.label
|
|
32
32
|
}
|
|
@@ -26,6 +26,7 @@ function buildShareUrl(platform, url, title) {
|
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
function ShareSection({
|
|
29
|
+
as: Heading = "h3",
|
|
29
30
|
buildUrl: buildUrlFunction = buildShareUrl,
|
|
30
31
|
platforms = defaultPlatforms,
|
|
31
32
|
shareOn,
|
|
@@ -34,7 +35,7 @@ function ShareSection({
|
|
|
34
35
|
url
|
|
35
36
|
}) {
|
|
36
37
|
return /* @__PURE__ */ jsxs("div", { className: "border-t border-border pt-6 mt-8", children: [
|
|
37
|
-
/* @__PURE__ */ jsx(
|
|
38
|
+
/* @__PURE__ */ jsx(Heading, { className: "text-lg font-semibold mb-4", children: shareTitle }),
|
|
38
39
|
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-3", children: platforms.map((platform) => /* @__PURE__ */ jsxs(
|
|
39
40
|
"a",
|
|
40
41
|
{
|