@vllnt/ui 0.2.1-canary.ab2c69a → 0.2.1-canary.b3f1dff

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.
@@ -0,0 +1,91 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import {
4
+ forwardRef
5
+ } from "react";
6
+ import { cn } from "../../lib/utils";
7
+ const TONE_DOT = {
8
+ danger: "bg-red-500",
9
+ info: "bg-blue-500",
10
+ neutral: "bg-muted-foreground",
11
+ success: "bg-emerald-500",
12
+ warn: "bg-amber-500"
13
+ };
14
+ const DEFAULT_LABELS = {
15
+ empty: "No recent activity",
16
+ region: "Recent activity"
17
+ };
18
+ const ChipBody = (props) => {
19
+ const { event } = props;
20
+ const tone = event.tone ?? "neutral";
21
+ return /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5 whitespace-nowrap", children: [
22
+ /* @__PURE__ */ jsx(
23
+ "span",
24
+ {
25
+ "aria-hidden": "true",
26
+ className: cn("h-1.5 w-1.5 rounded-full", TONE_DOT[tone])
27
+ }
28
+ ),
29
+ /* @__PURE__ */ jsx("span", { className: "text-foreground", children: event.label }),
30
+ /* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground", "data-strip-event-ts": true, children: event.ts })
31
+ ] });
32
+ };
33
+ const Chip = (props) => {
34
+ const { event } = props;
35
+ const tone = event.tone ?? "neutral";
36
+ if (event.onActivate) {
37
+ const handleClick = () => {
38
+ event.onActivate?.();
39
+ };
40
+ return /* @__PURE__ */ jsx(
41
+ "button",
42
+ {
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
+ "data-strip-event": event.id,
45
+ "data-strip-event-tone": tone,
46
+ onClick: handleClick,
47
+ type: "button",
48
+ children: /* @__PURE__ */ jsx(ChipBody, { event })
49
+ }
50
+ );
51
+ }
52
+ return /* @__PURE__ */ jsx(
53
+ "span",
54
+ {
55
+ className: "flex items-center rounded-full border border-border bg-background px-2 py-1 text-[11px]",
56
+ "data-strip-event": event.id,
57
+ "data-strip-event-tone": tone,
58
+ children: /* @__PURE__ */ jsx(ChipBody, { event })
59
+ }
60
+ );
61
+ };
62
+ const BottomActivityStrip = forwardRef((props, ref) => {
63
+ const { className, events, labels, maxEvents, ...rest } = props;
64
+ const resolvedLabels = { ...DEFAULT_LABELS, ...labels };
65
+ const visible = maxEvents === void 0 || maxEvents >= events.length ? events : events.slice(0, maxEvents);
66
+ return /* @__PURE__ */ jsx(
67
+ "section",
68
+ {
69
+ "aria-label": resolvedLabels.region,
70
+ className: cn(
71
+ "flex w-full items-center gap-2 overflow-x-auto rounded-md border border-border bg-background/90 px-2 py-1 text-foreground",
72
+ className
73
+ ),
74
+ "data-bottom-activity-strip": true,
75
+ ref,
76
+ ...rest,
77
+ children: visible.length === 0 ? /* @__PURE__ */ jsx(
78
+ "span",
79
+ {
80
+ className: "px-2 text-[11px] text-muted-foreground",
81
+ "data-strip-state": "empty",
82
+ children: resolvedLabels.empty
83
+ }
84
+ ) : visible.map((event) => /* @__PURE__ */ jsx(Chip, { event }, event.id))
85
+ }
86
+ );
87
+ });
88
+ BottomActivityStrip.displayName = "BottomActivityStrip";
89
+ export {
90
+ BottomActivityStrip
91
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ BottomActivityStrip
3
+ } from "./bottom-activity-strip";
4
+ export {
5
+ BottomActivityStrip
6
+ };
@@ -0,0 +1,104 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import {
4
+ forwardRef
5
+ } from "react";
6
+ import { cn } from "../../lib/utils";
7
+ const DEFAULT_LABELS = {
8
+ region: "Comment",
9
+ unreadSuffix: "unread"
10
+ };
11
+ const STATE_FILL = {
12
+ open: "bg-foreground text-background",
13
+ resolved: "bg-muted text-muted-foreground"
14
+ };
15
+ const PinBody = (props) => {
16
+ const showBadge = typeof props.unread === "number" && props.unread > 0;
17
+ const useAccent = props.accent && props.state === "open";
18
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
19
+ /* @__PURE__ */ jsx(
20
+ "span",
21
+ {
22
+ "aria-hidden": "true",
23
+ className: cn(
24
+ "flex h-7 w-7 items-center justify-center rounded-full border border-background text-[11px] font-semibold shadow-sm",
25
+ STATE_FILL[props.state]
26
+ ),
27
+ "data-comment-pin-body": true,
28
+ style: useAccent ? { backgroundColor: props.accent, color: "white" } : void 0,
29
+ children: props.authorInitial ?? "\u2022"
30
+ }
31
+ ),
32
+ showBadge ? /* @__PURE__ */ jsx(
33
+ "span",
34
+ {
35
+ "aria-hidden": "true",
36
+ className: "absolute -right-1 -top-1 inline-flex min-h-[14px] min-w-[14px] items-center justify-center rounded-full bg-red-500 px-1 text-[9px] font-medium text-white",
37
+ "data-comment-pin-unread": true,
38
+ children: props.unread
39
+ }
40
+ ) : null
41
+ ] });
42
+ };
43
+ const CommentPin = forwardRef(
44
+ (props, ref) => {
45
+ const {
46
+ authorInitial,
47
+ className,
48
+ color,
49
+ labels,
50
+ onActivate,
51
+ state = "open",
52
+ unread,
53
+ x,
54
+ y,
55
+ ...rest
56
+ } = props;
57
+ const resolvedLabels = { ...DEFAULT_LABELS, ...labels };
58
+ const showBadge = typeof unread === "number" && unread > 0;
59
+ const ariaLabel = showBadge ? `${resolvedLabels.region}, ${unread} ${resolvedLabels.unreadSuffix}` : resolvedLabels.region;
60
+ const handleClick = () => {
61
+ onActivate?.();
62
+ };
63
+ const body = /* @__PURE__ */ jsx(
64
+ PinBody,
65
+ {
66
+ accent: color,
67
+ authorInitial,
68
+ state,
69
+ unread
70
+ }
71
+ );
72
+ return /* @__PURE__ */ jsx(
73
+ "div",
74
+ {
75
+ "aria-label": ariaLabel,
76
+ className: cn(
77
+ "absolute z-30 inline-flex -translate-x-1/2 -translate-y-1/2",
78
+ className
79
+ ),
80
+ "data-comment-pin": true,
81
+ "data-comment-pin-state": state,
82
+ ref,
83
+ role: "img",
84
+ style: { left: x, top: y },
85
+ ...rest,
86
+ children: onActivate ? /* @__PURE__ */ jsx(
87
+ "button",
88
+ {
89
+ "aria-label": ariaLabel,
90
+ className: "relative inline-flex rounded-full focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
91
+ "data-comment-pin-trigger": true,
92
+ onClick: handleClick,
93
+ type: "button",
94
+ children: body
95
+ }
96
+ ) : /* @__PURE__ */ jsx("span", { className: "relative inline-flex", children: body })
97
+ }
98
+ );
99
+ }
100
+ );
101
+ CommentPin.displayName = "CommentPin";
102
+ export {
103
+ CommentPin
104
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ CommentPin
3
+ } from "./comment-pin";
4
+ export {
5
+ CommentPin
6
+ };
@@ -0,0 +1,92 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { forwardRef, useId } from "react";
4
+ import { cn } from "../../lib/utils";
5
+ const TONE_FILL = {
6
+ cool: "fill-blue-500",
7
+ danger: "fill-red-500",
8
+ neutral: "fill-foreground",
9
+ warn: "fill-amber-500"
10
+ };
11
+ const DEFAULT_LABELS = {
12
+ region: "Heat overlay"
13
+ };
14
+ const clamp01 = (v) => {
15
+ if (v < 0) {
16
+ return 0;
17
+ }
18
+ if (v > 1) {
19
+ return 1;
20
+ }
21
+ return v;
22
+ };
23
+ const HeatBlob = (props) => {
24
+ const { defaultTone, gradientId, intensity, point } = props;
25
+ const weight = clamp01(point.weight);
26
+ const tone = point.tone ?? defaultTone;
27
+ return /* @__PURE__ */ jsx(
28
+ "circle",
29
+ {
30
+ className: cn("mix-blend-multiply", TONE_FILL[tone]),
31
+ cx: point.x,
32
+ cy: point.y,
33
+ "data-heat-point": point.id,
34
+ "data-heat-tone": tone,
35
+ fill: `url(#${gradientId})`,
36
+ fillOpacity: weight * 0.6,
37
+ r: Math.max(8, intensity * weight)
38
+ }
39
+ );
40
+ };
41
+ const HeatOverlay = forwardRef(
42
+ (props, ref) => {
43
+ const {
44
+ className,
45
+ defaultTone = "warn",
46
+ intensity = 48,
47
+ labels,
48
+ points,
49
+ ...rest
50
+ } = props;
51
+ const resolvedLabels = { ...DEFAULT_LABELS, ...labels };
52
+ const gradientId = useId();
53
+ if (points.length === 0) {
54
+ return null;
55
+ }
56
+ return /* @__PURE__ */ jsxs(
57
+ "svg",
58
+ {
59
+ "aria-label": resolvedLabels.region,
60
+ className: cn(
61
+ "pointer-events-none absolute inset-0 z-10 h-full w-full",
62
+ className
63
+ ),
64
+ "data-heat-overlay": true,
65
+ ref,
66
+ role: "img",
67
+ ...rest,
68
+ children: [
69
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("radialGradient", { cx: "50%", cy: "50%", id: gradientId, r: "50%", children: [
70
+ /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: "currentColor", stopOpacity: "1" }),
71
+ /* @__PURE__ */ jsx("stop", { offset: "70%", stopColor: "currentColor", stopOpacity: "0.4" }),
72
+ /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: "currentColor", stopOpacity: "0" })
73
+ ] }) }),
74
+ points.map((point) => /* @__PURE__ */ jsx(
75
+ HeatBlob,
76
+ {
77
+ defaultTone,
78
+ gradientId,
79
+ intensity,
80
+ point
81
+ },
82
+ point.id
83
+ ))
84
+ ]
85
+ }
86
+ );
87
+ }
88
+ );
89
+ HeatOverlay.displayName = "HeatOverlay";
90
+ export {
91
+ HeatOverlay
92
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ HeatOverlay
3
+ } from "./heat-overlay";
4
+ export {
5
+ HeatOverlay
6
+ };
@@ -539,24 +539,54 @@ import {
539
539
  useFlowDiagram
540
540
  } from "./flow-diagram";
541
541
  import { AnchorPort } from "./anchor-port";
542
+ import {
543
+ BottomActivityStrip
544
+ } from "./bottom-activity-strip";
545
+ import {
546
+ CommentPin
547
+ } from "./comment-pin";
542
548
  import {
543
549
  ConnectorEdge
544
550
  } from "./connector-edge";
545
551
  import { EdgeLabel } from "./edge-label";
546
552
  import { GroupHull } from "./group-hull";
553
+ import {
554
+ HeatOverlay
555
+ } from "./heat-overlay";
556
+ import {
557
+ LiveCursor
558
+ } from "./live-cursor";
559
+ import {
560
+ MetricCluster
561
+ } from "./metric-cluster";
547
562
  import {
548
563
  ObjectCard
549
564
  } from "./object-card";
550
565
  import { ObjectHandle } from "./object-handle";
566
+ import {
567
+ PlaybackGhost
568
+ } from "./playback-ghost";
551
569
  import {
552
570
  PresenceStack
553
571
  } from "./presence-stack";
572
+ import {
573
+ PresenceSyncIndicator
574
+ } from "./presence-sync-indicator";
575
+ import {
576
+ RunTimeline
577
+ } from "./run-timeline";
554
578
  import {
555
579
  SelectionPresence
556
580
  } from "./selection-presence";
581
+ import {
582
+ StateBadgeOverlay
583
+ } from "./state-badge-overlay";
557
584
  import {
558
585
  ThreadBubble
559
586
  } from "./thread-bubble";
587
+ import {
588
+ TimelineScrubber
589
+ } from "./timeline-scrubber";
560
590
  import {
561
591
  ConversationEmpty,
562
592
  ConversationHeader,
@@ -613,6 +643,7 @@ export {
613
643
  BeforeAfter,
614
644
  BlogCard,
615
645
  BorderBeam,
646
+ BottomActivityStrip,
616
647
  BottomBar,
617
648
  Breadcrumb,
618
649
  Button,
@@ -651,6 +682,7 @@ export {
651
682
  CommandList,
652
683
  CommandSeparator,
653
684
  CommandShortcut,
685
+ CommentPin,
654
686
  CommonMistake,
655
687
  Comparison,
656
688
  CompletionDialog,
@@ -750,6 +782,7 @@ export {
750
782
  GlassPanel,
751
783
  Glossary,
752
784
  GroupHull,
785
+ HeatOverlay,
753
786
  Highlight,
754
787
  HorizontalScrollRow,
755
788
  HoverCard,
@@ -769,6 +802,7 @@ export {
769
802
  LearningObjectives,
770
803
  LeftRail,
771
804
  LineChart,
805
+ LiveCursor,
772
806
  LiveFeed,
773
807
  MDXContent,
774
808
  MarketTreemap,
@@ -789,6 +823,7 @@ export {
789
823
  MenubarSubContent,
790
824
  MenubarSubTrigger,
791
825
  MenubarTrigger,
826
+ MetricCluster,
792
827
  MetricGauge,
793
828
  MiniMapPanel,
794
829
  ModelSelector,
@@ -812,12 +847,14 @@ export {
812
847
  Pagination,
813
848
  PasswordInput,
814
849
  PlanBadge,
850
+ PlaybackGhost,
815
851
  Popover,
816
852
  PopoverAnchor,
817
853
  PopoverContent,
818
854
  PopoverTrigger,
819
855
  Prerequisites,
820
856
  PresenceStack,
857
+ PresenceSyncIndicator,
821
858
  ProTip,
822
859
  ProfileSection,
823
860
  ProgressBar,
@@ -838,6 +875,7 @@ export {
838
875
  ResizablePanelGroup,
839
876
  RightDock,
840
877
  RoleBadge,
878
+ RunTimeline,
841
879
  ScopeSelector,
842
880
  ScrollArea,
843
881
  ScrollBar,
@@ -881,6 +919,7 @@ export {
881
919
  SparklineGrid,
882
920
  Spinner,
883
921
  StatCard,
922
+ StateBadgeOverlay,
884
923
  StatusBoard,
885
924
  StatusIndicator,
886
925
  Step,
@@ -913,6 +952,7 @@ export {
913
952
  ThinkingBlock,
914
953
  ThreadBubble,
915
954
  TickerTape,
955
+ TimelineScrubber,
916
956
  Toast,
917
957
  ToastAction,
918
958
  ToastClose,
@@ -0,0 +1,6 @@
1
+ import {
2
+ LiveCursor
3
+ } from "./live-cursor";
4
+ export {
5
+ LiveCursor
6
+ };
@@ -0,0 +1,62 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import {
4
+ forwardRef
5
+ } from "react";
6
+ import { cn } from "../../lib/utils";
7
+ const DEFAULT_LABELS = {
8
+ region: "Live cursor"
9
+ };
10
+ const LiveCursor = forwardRef(
11
+ (props, ref) => {
12
+ const { className, color, labels, name, status, x, y, ...rest } = props;
13
+ const resolvedLabels = { ...DEFAULT_LABELS, ...labels };
14
+ const resolvedColor = color ?? "var(--foreground)";
15
+ return /* @__PURE__ */ jsxs(
16
+ "div",
17
+ {
18
+ "aria-label": typeof name === "string" ? `${resolvedLabels.region}: ${name}` : resolvedLabels.region,
19
+ className: cn(
20
+ "pointer-events-none absolute z-30 flex items-start gap-1",
21
+ className
22
+ ),
23
+ "data-live-cursor": true,
24
+ ref,
25
+ role: "img",
26
+ style: { left: x, top: y },
27
+ ...rest,
28
+ children: [
29
+ /* @__PURE__ */ jsx(
30
+ "svg",
31
+ {
32
+ "aria-hidden": "true",
33
+ className: "-ml-1 -mt-1 drop-shadow-sm",
34
+ "data-live-cursor-pointer": true,
35
+ fill: resolvedColor,
36
+ height: 18,
37
+ viewBox: "0 0 16 18",
38
+ width: 16,
39
+ children: /* @__PURE__ */ jsx("path", { d: "M0 0 L0 14 L4 11 L7 17 L10 16 L7 10 L13 10 Z" })
40
+ }
41
+ ),
42
+ name === null || name === void 0 ? null : /* @__PURE__ */ jsxs(
43
+ "span",
44
+ {
45
+ className: "ml-2 mt-2 inline-flex flex-col rounded-md px-1.5 py-0.5 text-[10px] font-medium text-white shadow-sm",
46
+ "data-live-cursor-chip": true,
47
+ style: { backgroundColor: resolvedColor },
48
+ children: [
49
+ /* @__PURE__ */ jsx("span", { children: name }),
50
+ status ? /* @__PURE__ */ jsx("span", { className: "text-[9px] opacity-80", "data-live-cursor-status": true, children: status }) : null
51
+ ]
52
+ }
53
+ )
54
+ ]
55
+ }
56
+ );
57
+ }
58
+ );
59
+ LiveCursor.displayName = "LiveCursor";
60
+ export {
61
+ LiveCursor
62
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ MetricCluster
3
+ } from "./metric-cluster";
4
+ export {
5
+ MetricCluster
6
+ };
@@ -0,0 +1,96 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import {
4
+ forwardRef
5
+ } from "react";
6
+ import { cn } from "../../lib/utils";
7
+ const TONE_DOT = {
8
+ danger: "bg-red-500",
9
+ neutral: "bg-muted-foreground",
10
+ success: "bg-emerald-500",
11
+ warn: "bg-amber-500"
12
+ };
13
+ const ANCHOR_TRANSFORM = {
14
+ "bottom-left": "translate(-100%, 100%)",
15
+ "bottom-right": "translate(0%, 100%)",
16
+ "top-left": "translate(-100%, -100%)",
17
+ "top-right": "translate(0%, -100%)"
18
+ };
19
+ const DEFAULT_LABELS = {
20
+ region: "Metric cluster"
21
+ };
22
+ const Row = (props) => {
23
+ const { entry } = props;
24
+ const tone = entry.tone ?? "neutral";
25
+ return /* @__PURE__ */ jsxs(
26
+ "li",
27
+ {
28
+ className: "flex items-center justify-between gap-2 text-[11px]",
29
+ "data-metric-cluster-row": entry.id,
30
+ "data-metric-cluster-tone": tone,
31
+ children: [
32
+ /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5 text-muted-foreground", children: [
33
+ /* @__PURE__ */ jsx(
34
+ "span",
35
+ {
36
+ "aria-hidden": "true",
37
+ className: cn("h-1.5 w-1.5 rounded-full", TONE_DOT[tone])
38
+ }
39
+ ),
40
+ entry.label
41
+ ] }),
42
+ /* @__PURE__ */ jsx("span", { className: "font-semibold text-foreground", children: entry.value })
43
+ ]
44
+ }
45
+ );
46
+ };
47
+ const MetricCluster = forwardRef(
48
+ (props, ref) => {
49
+ const {
50
+ anchor = "top-right",
51
+ className,
52
+ labels,
53
+ metrics,
54
+ title,
55
+ x,
56
+ y,
57
+ ...rest
58
+ } = props;
59
+ const resolvedLabels = { ...DEFAULT_LABELS, ...labels };
60
+ return /* @__PURE__ */ jsxs(
61
+ "div",
62
+ {
63
+ "aria-label": resolvedLabels.region,
64
+ className: cn(
65
+ "pointer-events-none absolute z-20 flex flex-col gap-1 rounded-md border border-border bg-background/90 p-2 shadow-sm backdrop-blur",
66
+ className
67
+ ),
68
+ "data-metric-cluster": true,
69
+ "data-metric-cluster-anchor": anchor,
70
+ ref,
71
+ role: "status",
72
+ style: {
73
+ left: x,
74
+ top: y,
75
+ transform: ANCHOR_TRANSFORM[anchor]
76
+ },
77
+ ...rest,
78
+ children: [
79
+ title ? /* @__PURE__ */ jsx(
80
+ "header",
81
+ {
82
+ className: "text-[10px] font-medium uppercase tracking-wide text-muted-foreground",
83
+ "data-metric-cluster-title": true,
84
+ children: title
85
+ }
86
+ ) : null,
87
+ /* @__PURE__ */ jsx("ul", { className: "space-y-0.5", children: metrics.map((entry) => /* @__PURE__ */ jsx(Row, { entry }, entry.id)) })
88
+ ]
89
+ }
90
+ );
91
+ }
92
+ );
93
+ MetricCluster.displayName = "MetricCluster";
94
+ export {
95
+ MetricCluster
96
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ PlaybackGhost
3
+ } from "./playback-ghost";
4
+ export {
5
+ PlaybackGhost
6
+ };