@vllnt/ui 0.2.1-canary.0aaaad2 → 0.2.1-canary.0cc4e50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3 -0
- package/dist/components/activity-heatmap/activity-heatmap.js +2 -1
- package/dist/components/activity-log/activity-log.js +1 -1
- package/dist/components/ai-artifact/ai-artifact.js +8 -8
- package/dist/components/ai-chat-input/ai-chat-input.js +1 -1
- package/dist/components/ai-message-bubble/ai-message-bubble.js +1 -1
- package/dist/components/ai-sidebar/ai-sidebar.js +4 -4
- package/dist/components/ai-tool-call-display/ai-tool-call-display.js +1 -1
- package/dist/components/animated-text/animated-text.js +6 -3
- package/dist/components/annotation/annotation.js +1 -1
- package/dist/components/auto-reload/auto-reload.js +1 -1
- package/dist/components/avatar-group/avatar-group.js +1 -1
- package/dist/components/blog-card/blog-card.js +4 -2
- 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/canvas-shell/canvas-foundation-demo.js +1 -1
- package/dist/components/carousel/carousel.js +14 -6
- package/dist/components/category-filter/category-filter.js +1 -1
- package/dist/components/chat-dock-section/chat-dock-section.js +1 -1
- 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 +3 -2
- package/dist/components/combobox/combobox.js +1 -6
- 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 +19 -11
- package/dist/components/connector-edge/connector-edge.js +1 -1
- package/dist/components/content-intro/content-intro.js +18 -15
- package/dist/components/conversation-thread/conversation-thread.js +4 -4
- package/dist/components/countdown-timer/countdown-timer.js +1 -1
- package/dist/components/data-table/data-table.js +1 -1
- package/dist/components/date-picker/date-picker.js +1 -6
- package/dist/components/exercise/exercise.js +11 -3
- package/dist/components/faq/faq.js +6 -2
- package/dist/components/file-upload/file-upload.js +1 -6
- package/dist/components/filter-bar/filter-bar.js +7 -7
- package/dist/components/flashcard/flashcard.js +1 -1
- package/dist/components/floating-toolbar/floating-toolbar.js +2 -2
- package/dist/components/form/form.js +1 -1
- 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/inline-input/inline-input.js +1 -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/lang-provider/lang-provider.js +3 -3
- package/dist/components/learning-objectives/learning-objectives.js +2 -1
- package/dist/components/live-feed/live-feed.js +2 -2
- 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 +17 -8
- package/dist/components/metric-gauge/metric-gauge.js +1 -1
- package/dist/components/model-selector/model-selector.js +1 -1
- package/dist/components/multi-select/multi-select.js +1 -1
- package/dist/components/navbar-saas/navbar-saas.js +5 -5
- package/dist/components/number-input/number-input.js +1 -1
- package/dist/components/number-ticker/number-ticker.js +1 -1
- package/dist/components/object-card/object-card.js +1 -1
- package/dist/components/order-book/order-book.js +2 -2
- package/dist/components/overview-board/overview-board.js +1 -1
- 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-card/progress-card.js +1 -1
- package/dist/components/progress-tracker/progress-tracker.js +17 -9
- 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/scope-selector/scope-selector.js +1 -1
- package/dist/components/search-dialog/search-dialog.js +484 -51
- 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 +30 -25
- package/dist/components/sidebar-toggle/sidebar-toggle.js +1 -1
- package/dist/components/slideshow/slideshow.js +3 -2
- package/dist/components/social-fab/social-fab.js +10 -10
- package/dist/components/spinner/spinner.js +1 -1
- package/dist/components/spinner/unicode-spinner.js +4 -2
- package/dist/components/stat-card/stat-card.js +2 -2
- package/dist/components/status-board/status-board.js +13 -6
- 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/tabs/tabs.js +26 -8
- package/dist/components/tags-input/tags-input.js +11 -3
- package/dist/components/terminal/terminal.js +11 -3
- package/dist/components/theme-toggle/theme-toggle.js +2 -2
- package/dist/components/thinking-block/thinking-block.js +2 -2
- package/dist/components/ticker-tape/ticker-tape.js +1 -1
- package/dist/components/timeline-scrubber/timeline-scrubber.js +2 -2
- package/dist/components/tldr-section/tldr-section.js +9 -7
- package/dist/components/tour/tour.js +1 -1
- package/dist/components/transaction-list/transaction-list.js +2 -2
- package/dist/components/tutorial-card/tutorial-card.js +1 -1
- package/dist/components/tutorial-complete/tutorial-complete.js +8 -6
- package/dist/components/tutorial-filters/tutorial-filters.js +2 -2
- package/dist/components/tutorial-intro-content/tutorial-intro-content.js +5 -5
- package/dist/components/tutorial-mdx/tutorial-mdx.js +6 -6
- package/dist/components/usage-breakdown/usage-breakdown.js +1 -1
- 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 +5 -4
- package/dist/components/zoom-hud/zoom-hud.js +1 -1
- package/dist/index.d.ts +113 -29
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
|
10
10
|
|
|
11
11
|
### Added
|
|
12
12
|
|
|
13
|
+
- **Release intelligence surface** — `/changelog`, `/releases`, `/rss.xml`, and `/atom.xml` expose one changelog source through HTML, GitHub release cards, and feed readers. `/docs/changelog` redirects to `/changelog`.
|
|
13
14
|
- **Hooks + utility primitives** — `CopyButton` (+ `useCopyToClipboard` hook), `Banner` + `BannerAction`, `Kbd`, `EmptyState`, `DocumentSiblingNav`.
|
|
14
15
|
- **Pricing + identity cards** — `PricingTable` + `PricingPlan`, `HistoricalFigureCard`, `CivilizationCard` (+ `CivilizationComparison`).
|
|
15
16
|
- **Newsletter** — `NewsletterSignup` (state-machine driven submit flow).
|
|
@@ -29,6 +30,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
|
29
30
|
- **Time navigation** — `TimelineScrubber`, `PlaybackGhost`, `BottomActivityStrip`, `RunTimeline`.
|
|
30
31
|
- Total component count: **225** (up from 140).
|
|
31
32
|
|
|
33
|
+
- **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`.
|
|
34
|
+
|
|
32
35
|
### Changed
|
|
33
36
|
|
|
34
37
|
- 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,6 +145,7 @@ function HeatmapGrid({
|
|
|
145
145
|
}
|
|
146
146
|
const ActivityHeatmap = React.forwardRef(
|
|
147
147
|
({
|
|
148
|
+
as: Heading = "h2",
|
|
148
149
|
className,
|
|
149
150
|
data,
|
|
150
151
|
description,
|
|
@@ -157,7 +158,7 @@ const ActivityHeatmap = React.forwardRef(
|
|
|
157
158
|
const gridData = getGridData(data, normalizedEndDate, weeks);
|
|
158
159
|
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-4", className), ref, ...props, children: [
|
|
159
160
|
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
160
|
-
/* @__PURE__ */ jsx(
|
|
161
|
+
/* @__PURE__ */ jsx(Heading, { className: "text-lg font-semibold tracking-tight", children: title }),
|
|
161
162
|
description ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: description }) : null
|
|
162
163
|
] }),
|
|
163
164
|
/* @__PURE__ */ jsx("div", { className: "overflow-x-auto rounded-lg border bg-card p-4 shadow-sm", children: /* @__PURE__ */ jsx(HeatmapGrid, { gridData, weeks }) })
|
|
@@ -3,7 +3,7 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { forwardRef, useMemo, useState } from "react";
|
|
4
4
|
import { ArrowRight, ChevronLeft, ChevronRight } from "lucide-react";
|
|
5
5
|
import { cn } from "../../lib/utils";
|
|
6
|
-
import { Avatar, AvatarFallback } from "../avatar";
|
|
6
|
+
import { Avatar, AvatarFallback } from "../avatar/avatar";
|
|
7
7
|
import { Badge } from "../badge";
|
|
8
8
|
import { Button } from "../button";
|
|
9
9
|
import {
|
|
@@ -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 handleCopyArtifact = 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: handleCopyArtifact,
|
|
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 handleEditArtifact = 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: handleEditArtifact,
|
|
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 handleDownloadArtifact = 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: handleDownloadArtifact,
|
|
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 handleToggleArtifactFullscreen = 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: handleToggleArtifactFullscreen,
|
|
356
356
|
ref,
|
|
357
357
|
size: "icon",
|
|
358
358
|
type: "button",
|
|
@@ -3,7 +3,7 @@ import { forwardRef } from "react";
|
|
|
3
3
|
import { cva } from "class-variance-authority";
|
|
4
4
|
import { LoaderCircle, SendHorizontal } from "lucide-react";
|
|
5
5
|
import { cn } from "../../lib/utils";
|
|
6
|
-
import { Button } from "../button";
|
|
6
|
+
import { Button } from "../button/button";
|
|
7
7
|
import { Textarea } from "../textarea";
|
|
8
8
|
const formShellVariants = cva(
|
|
9
9
|
"rounded-2xl border border-border/70 bg-background shadow-sm"
|
|
@@ -2,7 +2,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { forwardRef } from "react";
|
|
3
3
|
import { cva } from "class-variance-authority";
|
|
4
4
|
import { cn } from "../../lib/utils";
|
|
5
|
-
import { Avatar, AvatarFallback } from "../avatar";
|
|
5
|
+
import { Avatar, AvatarFallback } from "../avatar/avatar";
|
|
6
6
|
import { Badge } from "../badge";
|
|
7
7
|
const bubbleVariants = cva(
|
|
8
8
|
"rounded-2xl border px-4 py-3 shadow-sm transition-colors",
|
|
@@ -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 handleCloseSidebar = 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: handleCloseSidebar,
|
|
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 handleToggleSidebar = 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: handleToggleSidebar,
|
|
234
234
|
ref,
|
|
235
235
|
size: children ? "sm" : "icon",
|
|
236
236
|
type: "button",
|
|
@@ -3,7 +3,7 @@ import { forwardRef } from "react";
|
|
|
3
3
|
import { cva } from "class-variance-authority";
|
|
4
4
|
import { AlertCircle, CheckCircle2, Clock3, Wrench } from "lucide-react";
|
|
5
5
|
import { cn } from "../../lib/utils";
|
|
6
|
-
import { Badge } from "../badge";
|
|
6
|
+
import { Badge } from "../badge/badge";
|
|
7
7
|
const statusVariants = cva(
|
|
8
8
|
"rounded-full px-2 py-0 text-[10px] uppercase tracking-wide",
|
|
9
9
|
{
|
|
@@ -87,13 +87,16 @@ function buildRevealPlan(direction, length, randomness) {
|
|
|
87
87
|
return revealPlan;
|
|
88
88
|
}
|
|
89
89
|
function useRevealProgress(active, length, stagger) {
|
|
90
|
-
const [progress, setProgress] = React.useState(0);
|
|
90
|
+
const [progress, setProgress] = React.useState(() => active ? 0 : length);
|
|
91
|
+
const [revealKey, setRevealKey] = React.useState({ active, length, stagger });
|
|
92
|
+
if (revealKey.active !== active || revealKey.length !== length || revealKey.stagger !== stagger) {
|
|
93
|
+
setRevealKey({ active, length, stagger });
|
|
94
|
+
setProgress(active ? 0 : length);
|
|
95
|
+
}
|
|
91
96
|
React.useEffect(() => {
|
|
92
97
|
if (!active) {
|
|
93
|
-
setProgress(length);
|
|
94
98
|
return;
|
|
95
99
|
}
|
|
96
|
-
setProgress(0);
|
|
97
100
|
const revealInterval = window.setInterval(
|
|
98
101
|
() => {
|
|
99
102
|
setProgress((current) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { cn } from "../../lib/utils";
|
|
4
|
-
import { Popover, PopoverContent, PopoverTrigger } from "../popover";
|
|
4
|
+
import { Popover, PopoverContent, PopoverTrigger } from "../popover/popover";
|
|
5
5
|
const toneClasses = {
|
|
6
6
|
amber: "bg-amber-500/20 text-amber-950 dark:text-amber-100",
|
|
7
7
|
emerald: "bg-emerald-500/20 text-emerald-950 dark:text-emerald-100",
|
|
@@ -39,7 +39,7 @@ function getCurrencyFormatter(locale, currency) {
|
|
|
39
39
|
const key = `${locale}|${currency}`;
|
|
40
40
|
let formatter = CURRENCY_FORMATTER_CACHE.get(key);
|
|
41
41
|
if (!formatter) {
|
|
42
|
-
formatter =
|
|
42
|
+
formatter = Intl.NumberFormat(locale, {
|
|
43
43
|
currency,
|
|
44
44
|
style: "currency"
|
|
45
45
|
});
|
|
@@ -2,7 +2,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { cva } from "class-variance-authority";
|
|
4
4
|
import { cn } from "../../lib/utils";
|
|
5
|
-
import { Avatar, AvatarFallback, AvatarImage } from "../avatar";
|
|
5
|
+
import { Avatar, AvatarFallback, AvatarImage } from "../avatar/avatar";
|
|
6
6
|
const avatarGroupVariants = cva("flex items-center", {
|
|
7
7
|
defaultVariants: {
|
|
8
8
|
size: "md"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import Link from "next/link";
|
|
3
|
-
import { Badge } from "../badge";
|
|
3
|
+
import { Badge } from "../badge/badge";
|
|
4
4
|
import {
|
|
5
5
|
Card,
|
|
6
6
|
CardContent,
|
|
@@ -43,7 +43,9 @@ function ContentCard({
|
|
|
43
43
|
] }) }) : null
|
|
44
44
|
] }) });
|
|
45
45
|
}
|
|
46
|
-
|
|
46
|
+
function BlogCard(props) {
|
|
47
|
+
return /* @__PURE__ */ jsx(ContentCard, { ...props });
|
|
48
|
+
}
|
|
47
49
|
export {
|
|
48
50
|
BlogCard,
|
|
49
51
|
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
|
|
37
|
+
const handleActivateEvent = () => {
|
|
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: handleActivateEvent,
|
|
47
47
|
type: "button",
|
|
48
48
|
children: /* @__PURE__ */ jsx(ChipBody, { event })
|
|
49
49
|
}
|
|
@@ -158,6 +158,7 @@ function SessionPill({ sessionChange }) {
|
|
|
158
158
|
}
|
|
159
159
|
const CandlestickChart = React.forwardRef(
|
|
160
160
|
({
|
|
161
|
+
as: Heading = "h3",
|
|
161
162
|
className,
|
|
162
163
|
data,
|
|
163
164
|
height = DEFAULT_HEIGHT,
|
|
@@ -185,7 +186,7 @@ const CandlestickChart = React.forwardRef(
|
|
|
185
186
|
/* @__PURE__ */ jsxs("div", { className: "mb-4 flex flex-wrap items-start justify-between gap-3", children: [
|
|
186
187
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
187
188
|
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium uppercase tracking-[0.28em] text-muted-foreground", children: "OHLC session" }),
|
|
188
|
-
/* @__PURE__ */ jsx(
|
|
189
|
+
/* @__PURE__ */ jsx(Heading, { className: "text-lg font-semibold text-foreground", children: "Candlestick chart" })
|
|
189
190
|
] }),
|
|
190
191
|
/* @__PURE__ */ jsx(SessionPill, { sessionChange })
|
|
191
192
|
] }),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Activity, Bot, Compass, Layers3, Sparkles } from "lucide-react";
|
|
3
|
-
import { BottomBar } from "../bottom-bar";
|
|
3
|
+
import { BottomBar } from "../bottom-bar/bottom-bar";
|
|
4
4
|
import { Button } from "../button";
|
|
5
5
|
import { CanvasView } from "../canvas-view";
|
|
6
6
|
import { ChatDockSection } from "../chat-dock-section";
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
useContext,
|
|
8
8
|
useEffect,
|
|
9
9
|
useMemo,
|
|
10
|
+
useRef,
|
|
10
11
|
useState
|
|
11
12
|
} from "react";
|
|
12
13
|
import useEmblaCarousel from "embla-carousel-react";
|
|
@@ -43,6 +44,10 @@ function useCarouselLogic({
|
|
|
43
44
|
setCanScrollPrevious(api2.canScrollPrev());
|
|
44
45
|
setCanScrollNext(api2.canScrollNext());
|
|
45
46
|
}, []);
|
|
47
|
+
const onSelectReference = useRef(onSelect);
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
onSelectReference.current = onSelect;
|
|
50
|
+
}, [onSelect]);
|
|
46
51
|
const scrollPrevious = useCallback(() => {
|
|
47
52
|
api?.scrollPrev();
|
|
48
53
|
}, [api]);
|
|
@@ -71,17 +76,20 @@ function useCarouselLogic({
|
|
|
71
76
|
if (!api) {
|
|
72
77
|
return;
|
|
73
78
|
}
|
|
74
|
-
|
|
75
|
-
|
|
79
|
+
const notifySelection = (selectedApi) => {
|
|
80
|
+
onSelectReference.current(selectedApi);
|
|
81
|
+
};
|
|
82
|
+
api.on("reInit", notifySelection);
|
|
83
|
+
api.on("select", notifySelection);
|
|
76
84
|
const rafId = requestAnimationFrame(() => {
|
|
77
|
-
|
|
85
|
+
notifySelection(api);
|
|
78
86
|
});
|
|
79
87
|
return () => {
|
|
80
|
-
api?.off("select",
|
|
81
|
-
api?.off("reInit",
|
|
88
|
+
api?.off("select", notifySelection);
|
|
89
|
+
api?.off("reInit", notifySelection);
|
|
82
90
|
cancelAnimationFrame(rafId);
|
|
83
91
|
};
|
|
84
|
-
}, [api
|
|
92
|
+
}, [api]);
|
|
85
93
|
return {
|
|
86
94
|
api,
|
|
87
95
|
canScrollNext,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
3
|
import Link from "next/link";
|
|
4
4
|
import { usePathname } from "next/navigation";
|
|
5
|
-
import { Badge } from "../badge";
|
|
5
|
+
import { Badge } from "../badge/badge";
|
|
6
6
|
function slugify(text) {
|
|
7
7
|
return text.toLowerCase().normalize("NFD").replaceAll(/[\u0300-\u036F]/g, "").replaceAll(/[^\s\w-]/g, "").trim().replaceAll(/\s+/g, "-").replaceAll(/-+/g, "-").replaceAll(/^-+|-+$/g, "");
|
|
8
8
|
}
|
|
@@ -2,7 +2,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { forwardRef } from "react";
|
|
3
3
|
import { ArrowUpRight, MessageSquareText } from "lucide-react";
|
|
4
4
|
import { cn } from "../../lib/utils";
|
|
5
|
-
import { Button } from "../button";
|
|
5
|
+
import { Button } from "../button/button";
|
|
6
6
|
const ChatDockSection = forwardRef(
|
|
7
7
|
({
|
|
8
8
|
className,
|
|
@@ -3,6 +3,31 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useState } from "react";
|
|
4
4
|
import { cn } from "../../lib/utils";
|
|
5
5
|
const CHECKLIST_PROGRESS_EVENT = "vllnt:checklist-progress-change";
|
|
6
|
+
const CHECKLIST_STORAGE_VERSION = 1;
|
|
7
|
+
function stringItemsFromUnknown(value) {
|
|
8
|
+
return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
9
|
+
}
|
|
10
|
+
function parseChecklistStorageValue(saved) {
|
|
11
|
+
try {
|
|
12
|
+
const parsed = JSON.parse(saved);
|
|
13
|
+
if (Array.isArray(parsed)) {
|
|
14
|
+
return stringItemsFromUnknown(parsed);
|
|
15
|
+
}
|
|
16
|
+
if (typeof parsed === "object" && parsed !== null && "version" in parsed && "checked" in parsed && parsed.version === CHECKLIST_STORAGE_VERSION) {
|
|
17
|
+
return stringItemsFromUnknown(parsed.checked);
|
|
18
|
+
}
|
|
19
|
+
} catch {
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
return [];
|
|
23
|
+
}
|
|
24
|
+
function createChecklistStorageValue(ids) {
|
|
25
|
+
const payload = {
|
|
26
|
+
checked: [...ids],
|
|
27
|
+
version: CHECKLIST_STORAGE_VERSION
|
|
28
|
+
};
|
|
29
|
+
return JSON.stringify(payload);
|
|
30
|
+
}
|
|
6
31
|
function ChecklistItemRow({
|
|
7
32
|
isChecked,
|
|
8
33
|
item,
|
|
@@ -67,13 +92,14 @@ function ChecklistItemRow({
|
|
|
67
92
|
}
|
|
68
93
|
function ChecklistHeader({
|
|
69
94
|
checked,
|
|
95
|
+
Heading,
|
|
70
96
|
progress,
|
|
71
97
|
title,
|
|
72
98
|
total
|
|
73
99
|
}) {
|
|
74
100
|
if (!title) return null;
|
|
75
101
|
return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-3", children: [
|
|
76
|
-
/* @__PURE__ */ jsxs(
|
|
102
|
+
/* @__PURE__ */ jsxs(Heading, { className: "font-semibold flex items-center gap-2", children: [
|
|
77
103
|
/* @__PURE__ */ jsx(
|
|
78
104
|
"svg",
|
|
79
105
|
{
|
|
@@ -105,6 +131,7 @@ function ChecklistHeader({
|
|
|
105
131
|
] });
|
|
106
132
|
}
|
|
107
133
|
function Checklist({
|
|
134
|
+
as: Heading = "h4",
|
|
108
135
|
className,
|
|
109
136
|
items,
|
|
110
137
|
onComplete,
|
|
@@ -115,10 +142,7 @@ function Checklist({
|
|
|
115
142
|
if (typeof window !== "undefined" && persistKey) {
|
|
116
143
|
const saved = localStorage.getItem(`checklist:${persistKey}`);
|
|
117
144
|
if (saved) {
|
|
118
|
-
|
|
119
|
-
return new Set(JSON.parse(saved));
|
|
120
|
-
} catch {
|
|
121
|
-
}
|
|
145
|
+
return new Set(parseChecklistStorageValue(saved));
|
|
122
146
|
}
|
|
123
147
|
}
|
|
124
148
|
return /* @__PURE__ */ new Set();
|
|
@@ -132,7 +156,7 @@ function Checklist({
|
|
|
132
156
|
try {
|
|
133
157
|
localStorage.setItem(
|
|
134
158
|
`checklist:${persistKey}`,
|
|
135
|
-
|
|
159
|
+
createChecklistStorageValue(newChecked)
|
|
136
160
|
);
|
|
137
161
|
window.dispatchEvent(
|
|
138
162
|
new CustomEvent(CHECKLIST_PROGRESS_EVENT, {
|
|
@@ -153,6 +177,7 @@ function Checklist({
|
|
|
153
177
|
ChecklistHeader,
|
|
154
178
|
{
|
|
155
179
|
checked: checked.size,
|
|
180
|
+
Heading,
|
|
156
181
|
progress,
|
|
157
182
|
title,
|
|
158
183
|
total: items.length
|
|
@@ -184,5 +209,8 @@ function Checklist({
|
|
|
184
209
|
}
|
|
185
210
|
export {
|
|
186
211
|
CHECKLIST_PROGRESS_EVENT,
|
|
187
|
-
|
|
212
|
+
CHECKLIST_STORAGE_VERSION,
|
|
213
|
+
Checklist,
|
|
214
|
+
createChecklistStorageValue,
|
|
215
|
+
parseChecklistStorageValue
|
|
188
216
|
};
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Checklist,
|
|
3
|
-
CHECKLIST_PROGRESS_EVENT
|
|
3
|
+
CHECKLIST_PROGRESS_EVENT,
|
|
4
|
+
CHECKLIST_STORAGE_VERSION,
|
|
5
|
+
createChecklistStorageValue,
|
|
6
|
+
parseChecklistStorageValue
|
|
4
7
|
} from "./checklist";
|
|
5
8
|
export {
|
|
6
9
|
CHECKLIST_PROGRESS_EVENT,
|
|
7
|
-
|
|
10
|
+
CHECKLIST_STORAGE_VERSION,
|
|
11
|
+
Checklist,
|
|
12
|
+
createChecklistStorageValue,
|
|
13
|
+
parseChecklistStorageValue
|
|
8
14
|
};
|
|
@@ -168,7 +168,7 @@ const ChronoEvent = forwardRef(
|
|
|
168
168
|
},
|
|
169
169
|
[eventId, forwardedRef, registerEvent]
|
|
170
170
|
);
|
|
171
|
-
const
|
|
171
|
+
const handleFocusEvent = 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: handleFocusEvent,
|
|
186
186
|
ref: refCallback,
|
|
187
187
|
...rest,
|
|
188
188
|
children: [
|
|
@@ -3,7 +3,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useState } from "react";
|
|
4
4
|
import { Check, Code, Copy, FileCode } from "lucide-react";
|
|
5
5
|
import { cn } from "../../lib/utils";
|
|
6
|
-
import { Button } from "../button";
|
|
6
|
+
import { Button } from "../button/button";
|
|
7
7
|
function CodeLine({ highlightLines, line, lineNumber }) {
|
|
8
8
|
const isHighlighted = highlightLines.includes(lineNumber);
|
|
9
9
|
return /* @__PURE__ */ jsxs("div", { className: cn("flex", isHighlighted && "bg-primary/10 -mx-4 px-4"), children: [
|
|
@@ -13,6 +13,7 @@ function CodeLine({ highlightLines, line, lineNumber }) {
|
|
|
13
13
|
}
|
|
14
14
|
const EMPTY_HIGHLIGHT_LINES = [];
|
|
15
15
|
function CodePlayground({
|
|
16
|
+
as: Heading = "h4",
|
|
16
17
|
children,
|
|
17
18
|
description,
|
|
18
19
|
filename,
|
|
@@ -36,7 +37,7 @@ function CodePlayground({
|
|
|
36
37
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
37
38
|
/* @__PURE__ */ jsx("div", { className: "flex size-8 items-center justify-center rounded bg-primary/10", children: /* @__PURE__ */ jsx(Code, { className: "size-4 text-primary" }) }),
|
|
38
39
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
39
|
-
/* @__PURE__ */ jsx(
|
|
40
|
+
/* @__PURE__ */ jsx(Heading, { className: "font-semibold text-sm", children: title }),
|
|
40
41
|
description ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: description }) : null
|
|
41
42
|
] })
|
|
42
43
|
] }),
|
|
@@ -3,7 +3,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import { Check, ChevronsUpDown } from "lucide-react";
|
|
5
5
|
import { cn } from "../../lib/utils";
|
|
6
|
-
import { Button } from "../button";
|
|
6
|
+
import { Button } from "../button/button";
|
|
7
7
|
import {
|
|
8
8
|
Command,
|
|
9
9
|
CommandEmpty,
|
|
@@ -15,11 +15,6 @@ import {
|
|
|
15
15
|
import { Popover, PopoverContent, PopoverTrigger } from "../popover";
|
|
16
16
|
function useComboboxValue(value, onValueChange) {
|
|
17
17
|
const [internalValue, setInternalValue] = React.useState(value ?? "");
|
|
18
|
-
React.useEffect(() => {
|
|
19
|
-
if (value !== void 0) {
|
|
20
|
-
setInternalValue(value);
|
|
21
|
-
}
|
|
22
|
-
}, [value]);
|
|
23
18
|
const resolvedValue = value ?? internalValue;
|
|
24
19
|
const setResolvedValue = (nextValue) => {
|
|
25
20
|
if (value === void 0) {
|
|
@@ -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 handleActivateComment = () => {
|
|
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: handleActivateComment,
|
|
93
93
|
type: "button",
|
|
94
94
|
children: body
|
|
95
95
|
}
|
|
@@ -24,6 +24,7 @@ const variantConfig = {
|
|
|
24
24
|
};
|
|
25
25
|
function Comparison({
|
|
26
26
|
after,
|
|
27
|
+
as: Heading = "h4",
|
|
27
28
|
before,
|
|
28
29
|
title,
|
|
29
30
|
...rest
|
|
@@ -40,7 +41,7 @@ function Comparison({
|
|
|
40
41
|
const BeforeIcon = beforeConfig.icon;
|
|
41
42
|
const AfterIcon = afterConfig.icon;
|
|
42
43
|
return /* @__PURE__ */ jsxs("div", { className: "my-6", children: [
|
|
43
|
-
title ? /* @__PURE__ */ jsx(
|
|
44
|
+
title ? /* @__PURE__ */ jsx(Heading, { className: "font-semibold mb-3", children: title }) : null,
|
|
44
45
|
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
45
46
|
/* @__PURE__ */ jsxs("div", { className: cn("rounded-lg border", beforeConfig.className), children: [
|
|
46
47
|
/* @__PURE__ */ jsx(
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { memo,
|
|
3
|
+
import { memo, useEffect, useRef } from "react";
|
|
4
4
|
import { cn } from "../../lib/utils";
|
|
5
|
-
import { Button } from "../button";
|
|
5
|
+
import { Button } from "../button/button";
|
|
6
6
|
function DialogContent({
|
|
7
|
+
as: Heading = "h2",
|
|
7
8
|
cancelLabel = "Skip",
|
|
8
9
|
cancelShortcut = "S",
|
|
9
10
|
className,
|
|
@@ -57,7 +58,7 @@ function DialogContent({
|
|
|
57
58
|
}
|
|
58
59
|
),
|
|
59
60
|
/* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
|
|
60
|
-
/* @__PURE__ */ jsx(
|
|
61
|
+
/* @__PURE__ */ jsx(Heading, { className: "text-lg font-semibold", id: "completion-dialog-title", children: title }),
|
|
61
62
|
description ? /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground mt-1.5", children: description }) : null
|
|
62
63
|
] }),
|
|
63
64
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-row gap-2", children: [
|
|
@@ -83,6 +84,7 @@ function DialogContent({
|
|
|
83
84
|
);
|
|
84
85
|
}
|
|
85
86
|
function CompletionDialogImpl({
|
|
87
|
+
as,
|
|
86
88
|
cancelLabel,
|
|
87
89
|
cancelShortcut = "S",
|
|
88
90
|
className,
|
|
@@ -96,8 +98,11 @@ function CompletionDialogImpl({
|
|
|
96
98
|
onConfirm,
|
|
97
99
|
title
|
|
98
100
|
}) {
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
+
const keyDownHandlerRef = useRef(() => {
|
|
102
|
+
return;
|
|
103
|
+
});
|
|
104
|
+
useEffect(() => {
|
|
105
|
+
keyDownHandlerRef.current = (event) => {
|
|
101
106
|
if (!isOpen) return;
|
|
102
107
|
if (event.key === "Escape") {
|
|
103
108
|
event.preventDefault();
|
|
@@ -116,16 +121,18 @@ function CompletionDialogImpl({
|
|
|
116
121
|
event.stopPropagation();
|
|
117
122
|
onCancel();
|
|
118
123
|
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
);
|
|
124
|
+
};
|
|
125
|
+
}, [cancelShortcut, confirmShortcut, isOpen, onCancel, onClose, onConfirm]);
|
|
122
126
|
useEffect(() => {
|
|
123
127
|
if (!isOpen) return;
|
|
124
|
-
|
|
128
|
+
const onDocumentKeyDown = (event) => {
|
|
129
|
+
keyDownHandlerRef.current(event);
|
|
130
|
+
};
|
|
131
|
+
document.addEventListener("keydown", onDocumentKeyDown, true);
|
|
125
132
|
return () => {
|
|
126
|
-
document.removeEventListener("keydown",
|
|
133
|
+
document.removeEventListener("keydown", onDocumentKeyDown, true);
|
|
127
134
|
};
|
|
128
|
-
}, [isOpen
|
|
135
|
+
}, [isOpen]);
|
|
129
136
|
if (!isOpen) return null;
|
|
130
137
|
return /* @__PURE__ */ jsxs(
|
|
131
138
|
"div",
|
|
@@ -149,6 +156,7 @@ function CompletionDialogImpl({
|
|
|
149
156
|
/* @__PURE__ */ jsx(
|
|
150
157
|
DialogContent,
|
|
151
158
|
{
|
|
159
|
+
as,
|
|
152
160
|
cancelLabel,
|
|
153
161
|
cancelShortcut,
|
|
154
162
|
className,
|