@vllnt/ui 0.1.11 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/README.md +106 -1
  3. package/dist/components/activity-heatmap/activity-heatmap.js +168 -0
  4. package/dist/components/activity-heatmap/index.js +6 -0
  5. package/dist/components/activity-log/activity-log.js +256 -0
  6. package/dist/components/activity-log/index.js +6 -0
  7. package/dist/components/ai-chat-input/ai-chat-input.js +107 -0
  8. package/dist/components/ai-chat-input/index.js +4 -0
  9. package/dist/components/ai-message-bubble/ai-message-bubble.js +119 -0
  10. package/dist/components/ai-message-bubble/index.js +6 -0
  11. package/dist/components/ai-source-citation/ai-source-citation.js +39 -0
  12. package/dist/components/ai-source-citation/index.js +6 -0
  13. package/dist/components/ai-streaming-text/ai-streaming-text.js +41 -0
  14. package/dist/components/ai-streaming-text/index.js +6 -0
  15. package/dist/components/ai-tool-call-display/ai-tool-call-display.js +93 -0
  16. package/dist/components/ai-tool-call-display/index.js +6 -0
  17. package/dist/components/animated-text/animated-text.js +328 -0
  18. package/dist/components/animated-text/index.js +4 -0
  19. package/dist/components/annotation/annotation.js +49 -0
  20. package/dist/components/annotation/index.js +8 -0
  21. package/dist/components/avatar-group/avatar-group.js +82 -0
  22. package/dist/components/avatar-group/index.js +10 -0
  23. package/dist/components/border-beam/border-beam.js +51 -0
  24. package/dist/components/border-beam/index.js +4 -0
  25. package/dist/components/candlestick-chart/candlestick-chart.js +215 -0
  26. package/dist/components/candlestick-chart/index.js +6 -0
  27. package/dist/components/combobox/combobox.js +130 -0
  28. package/dist/components/combobox/index.js +4 -0
  29. package/dist/components/countdown-timer/countdown-timer.js +184 -0
  30. package/dist/components/countdown-timer/index.js +4 -0
  31. package/dist/components/credit-badge/credit-badge.js +59 -0
  32. package/dist/components/credit-badge/index.js +6 -0
  33. package/dist/components/data-list/data-list.js +99 -0
  34. package/dist/components/data-list/index.js +16 -0
  35. package/dist/components/data-table/data-table.js +242 -0
  36. package/dist/components/data-table/index.js +6 -0
  37. package/dist/components/date-picker/date-picker.js +74 -0
  38. package/dist/components/date-picker/index.js +4 -0
  39. package/dist/components/file-upload/file-upload.js +227 -0
  40. package/dist/components/file-upload/index.js +4 -0
  41. package/dist/components/flashcard/flashcard.js +66 -0
  42. package/dist/components/flashcard/index.js +4 -0
  43. package/dist/components/index.js +172 -1
  44. package/dist/components/live-feed/index.js +4 -0
  45. package/dist/components/live-feed/live-feed.js +168 -0
  46. package/dist/components/market-treemap/index.js +6 -0
  47. package/dist/components/market-treemap/market-treemap.js +100 -0
  48. package/dist/components/marquee/index.js +4 -0
  49. package/dist/components/marquee/marquee.js +98 -0
  50. package/dist/components/metric-gauge/index.js +6 -0
  51. package/dist/components/metric-gauge/metric-gauge.js +213 -0
  52. package/dist/components/model-selector/model-selector.js +11 -2
  53. package/dist/components/number-input/index.js +4 -0
  54. package/dist/components/number-input/number-input.js +167 -0
  55. package/dist/components/number-ticker/index.js +4 -0
  56. package/dist/components/number-ticker/number-ticker.js +63 -0
  57. package/dist/components/order-book/index.js +6 -0
  58. package/dist/components/order-book/order-book.js +128 -0
  59. package/dist/components/password-input/index.js +4 -0
  60. package/dist/components/password-input/password-input.js +45 -0
  61. package/dist/components/plan-badge/index.js +6 -0
  62. package/dist/components/plan-badge/plan-badge.js +67 -0
  63. package/dist/components/rating/index.js +4 -0
  64. package/dist/components/rating/rating.js +121 -0
  65. package/dist/components/role-badge/index.js +6 -0
  66. package/dist/components/role-badge/role-badge.js +50 -0
  67. package/dist/components/scope-selector/index.js +6 -0
  68. package/dist/components/scope-selector/scope-selector.js +336 -0
  69. package/dist/components/severity-badge/index.js +8 -0
  70. package/dist/components/severity-badge/severity-badge.js +163 -0
  71. package/dist/components/sparkline-grid/index.js +6 -0
  72. package/dist/components/sparkline-grid/sparkline-grid.js +92 -0
  73. package/dist/components/spinner/index.js +5 -1
  74. package/dist/components/spinner/unicode-spinner.js +708 -0
  75. package/dist/components/stat-card/index.js +5 -0
  76. package/dist/components/stat-card/stat-card.js +102 -0
  77. package/dist/components/status-board/index.js +6 -0
  78. package/dist/components/status-board/status-board.js +138 -0
  79. package/dist/components/status-indicator/index.js +10 -0
  80. package/dist/components/status-indicator/status-indicator.js +175 -0
  81. package/dist/components/stepper/index.js +4 -0
  82. package/dist/components/stepper/stepper.js +117 -0
  83. package/dist/components/subscription-card/index.js +6 -0
  84. package/dist/components/subscription-card/subscription-card.js +161 -0
  85. package/dist/components/ticker-tape/index.js +6 -0
  86. package/dist/components/ticker-tape/ticker-tape.js +106 -0
  87. package/dist/components/tour/index.js +4 -0
  88. package/dist/components/tour/tour.js +157 -0
  89. package/dist/components/usage-breakdown/index.js +6 -0
  90. package/dist/components/usage-breakdown/usage-breakdown.js +140 -0
  91. package/dist/components/wallet-card/index.js +4 -0
  92. package/dist/components/wallet-card/wallet-card.js +115 -0
  93. package/dist/components/watchlist/index.js +6 -0
  94. package/dist/components/watchlist/watchlist.js +110 -0
  95. package/dist/components/world-clock-bar/index.js +6 -0
  96. package/dist/components/world-clock-bar/world-clock-bar.js +101 -0
  97. package/dist/index.d.ts +1173 -7
  98. package/dist/test-setup.js +19 -0
  99. package/package.json +27 -6
  100. package/styles.css +55 -0
@@ -0,0 +1,107 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ import { cva } from "class-variance-authority";
4
+ import { LoaderCircle, SendHorizontal } from "lucide-react";
5
+ import { cn } from "../../lib/utils";
6
+ import { Button } from "../button";
7
+ import { Textarea } from "../textarea";
8
+ const formShellVariants = cva(
9
+ "rounded-2xl border border-border/70 bg-background shadow-sm"
10
+ );
11
+ function AIChatInputFooter({
12
+ currentLength,
13
+ helperText,
14
+ isSubmitDisabled,
15
+ isSubmitting,
16
+ maxLength,
17
+ status,
18
+ submitLabel
19
+ }) {
20
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 border-t border-border/60 pt-3 sm:flex-row sm:items-end sm:justify-between", children: [
21
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1 text-xs text-muted-foreground", children: [
22
+ helperText ? /* @__PURE__ */ jsx("p", { children: helperText }) : null,
23
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
24
+ status ? /* @__PURE__ */ jsx("span", { children: status }) : null,
25
+ typeof maxLength === "number" ? /* @__PURE__ */ jsxs("span", { children: [
26
+ currentLength,
27
+ "/",
28
+ maxLength
29
+ ] }) : null
30
+ ] })
31
+ ] }),
32
+ /* @__PURE__ */ jsxs(
33
+ Button,
34
+ {
35
+ className: "self-start rounded-full px-4 sm:self-auto",
36
+ disabled: isSubmitDisabled,
37
+ type: "submit",
38
+ children: [
39
+ isSubmitting ? /* @__PURE__ */ jsx(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(SendHorizontal, { className: "mr-2 h-4 w-4" }),
40
+ submitLabel
41
+ ]
42
+ }
43
+ )
44
+ ] });
45
+ }
46
+ const AIChatInput = forwardRef(
47
+ ({
48
+ className,
49
+ disabled = false,
50
+ helperText,
51
+ isSubmitting = false,
52
+ onSubmit,
53
+ onValueChange,
54
+ status,
55
+ submitLabel = "Send",
56
+ textareaProps,
57
+ toolbar,
58
+ value,
59
+ ...props
60
+ }, ref) => {
61
+ const currentValue = value ?? "";
62
+ const maxLength = textareaProps?.maxLength;
63
+ const isSubmitDisabled = disabled || isSubmitting || currentValue.trim().length === 0;
64
+ return /* @__PURE__ */ jsx(
65
+ "form",
66
+ {
67
+ className: cn(formShellVariants(), "w-full p-3", className),
68
+ onSubmit,
69
+ ref,
70
+ ...props,
71
+ children: /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
72
+ /* @__PURE__ */ jsx(
73
+ Textarea,
74
+ {
75
+ className: "min-h-[120px] resize-none rounded-xl border-0 bg-transparent px-1 py-1 shadow-none focus-visible:ring-0 focus-visible:ring-offset-0",
76
+ disabled,
77
+ onChange: (event) => {
78
+ textareaProps?.onChange?.(event);
79
+ onValueChange?.(event.target.value);
80
+ },
81
+ placeholder: "Ask a follow-up question, paste context, or describe what you need...",
82
+ value,
83
+ ...textareaProps
84
+ }
85
+ ),
86
+ toolbar ? /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: toolbar }) : null,
87
+ /* @__PURE__ */ jsx(
88
+ AIChatInputFooter,
89
+ {
90
+ currentLength: currentValue.length,
91
+ helperText,
92
+ isSubmitDisabled,
93
+ isSubmitting,
94
+ maxLength,
95
+ status,
96
+ submitLabel
97
+ }
98
+ )
99
+ ] })
100
+ }
101
+ );
102
+ }
103
+ );
104
+ AIChatInput.displayName = "AIChatInput";
105
+ export {
106
+ AIChatInput
107
+ };
@@ -0,0 +1,4 @@
1
+ import { AIChatInput } from "./ai-chat-input";
2
+ export {
3
+ AIChatInput
4
+ };
@@ -0,0 +1,119 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ import { cva } from "class-variance-authority";
4
+ import { cn } from "../../lib/utils";
5
+ import { Avatar, AvatarFallback } from "../avatar";
6
+ import { Badge } from "../badge";
7
+ const bubbleVariants = cva(
8
+ "rounded-2xl border px-4 py-3 shadow-sm transition-colors",
9
+ {
10
+ defaultVariants: {
11
+ messageRole: "assistant"
12
+ },
13
+ variants: {
14
+ messageRole: {
15
+ assistant: "border-border bg-card text-card-foreground",
16
+ system: "border-border/80 bg-muted/60 text-foreground",
17
+ tool: "border-border bg-muted/40 text-foreground",
18
+ user: "border-primary/20 bg-primary/10 text-foreground"
19
+ }
20
+ }
21
+ }
22
+ );
23
+ function AIMessageMeta({
24
+ author,
25
+ isUser,
26
+ status,
27
+ timestamp
28
+ }) {
29
+ return /* @__PURE__ */ jsxs(
30
+ "div",
31
+ {
32
+ className: cn(
33
+ "flex flex-wrap items-center gap-2 text-xs text-muted-foreground",
34
+ isUser ? "justify-end" : "justify-start"
35
+ ),
36
+ children: [
37
+ author ? /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: author }) : null,
38
+ timestamp ? /* @__PURE__ */ jsx("span", { children: timestamp }) : null,
39
+ status ? /* @__PURE__ */ jsx(
40
+ Badge,
41
+ {
42
+ className: "rounded-full px-2 py-0 text-[10px]",
43
+ variant: "secondary",
44
+ children: status
45
+ }
46
+ ) : null
47
+ ]
48
+ }
49
+ );
50
+ }
51
+ const AIMessageBubble = forwardRef(
52
+ ({
53
+ author,
54
+ children,
55
+ className,
56
+ messageRole = "assistant",
57
+ status,
58
+ timestamp,
59
+ ...props
60
+ }, ref) => {
61
+ const resolvedMessageRole = messageRole ?? "assistant";
62
+ const isUser = resolvedMessageRole === "user";
63
+ const fallbackLabel = (author ?? resolvedMessageRole).charAt(0).toUpperCase();
64
+ return /* @__PURE__ */ jsx(
65
+ "div",
66
+ {
67
+ className: cn("flex w-full", isUser ? "justify-end" : "justify-start"),
68
+ children: /* @__PURE__ */ jsxs(
69
+ "div",
70
+ {
71
+ className: cn(
72
+ "flex w-full max-w-3xl gap-3",
73
+ isUser ? "flex-row-reverse text-right" : "flex-row"
74
+ ),
75
+ children: [
76
+ /* @__PURE__ */ jsx(Avatar, { className: "mt-0.5 h-8 w-8 border border-border/70", children: /* @__PURE__ */ jsx(AvatarFallback, { className: "bg-muted text-[11px] font-medium uppercase text-muted-foreground", children: fallbackLabel }) }),
77
+ /* @__PURE__ */ jsxs(
78
+ "div",
79
+ {
80
+ className: cn(
81
+ "min-w-0 space-y-2",
82
+ isUser ? "items-end" : "items-start"
83
+ ),
84
+ children: [
85
+ /* @__PURE__ */ jsx(
86
+ AIMessageMeta,
87
+ {
88
+ author,
89
+ isUser,
90
+ status,
91
+ timestamp
92
+ }
93
+ ),
94
+ /* @__PURE__ */ jsx(
95
+ "div",
96
+ {
97
+ className: cn(
98
+ bubbleVariants({ messageRole: resolvedMessageRole }),
99
+ className
100
+ ),
101
+ ref,
102
+ ...props,
103
+ children: /* @__PURE__ */ jsx("div", { className: "text-sm leading-6 whitespace-pre-wrap", children })
104
+ }
105
+ )
106
+ ]
107
+ }
108
+ )
109
+ ]
110
+ }
111
+ )
112
+ }
113
+ );
114
+ }
115
+ );
116
+ AIMessageBubble.displayName = "AIMessageBubble";
117
+ export {
118
+ AIMessageBubble
119
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ AIMessageBubble
3
+ } from "./ai-message-bubble";
4
+ export {
5
+ AIMessageBubble
6
+ };
@@ -0,0 +1,39 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ import { ExternalLink, Quote } from "lucide-react";
4
+ import { cn } from "../../lib/utils";
5
+ const AISourceCitation = forwardRef(
6
+ ({ className, href, snippet, source, target = "_blank", title, ...props }, ref) => {
7
+ return /* @__PURE__ */ jsxs(
8
+ "a",
9
+ {
10
+ className: cn(
11
+ "group inline-flex max-w-full flex-col gap-2 rounded-xl border border-border/70 bg-background px-3 py-2 text-left shadow-sm transition-colors hover:bg-muted/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
12
+ className
13
+ ),
14
+ href,
15
+ ref,
16
+ rel: target === "_blank" ? "noreferrer" : void 0,
17
+ target,
18
+ ...props,
19
+ children: [
20
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
21
+ /* @__PURE__ */ jsx(Quote, { className: "mt-0.5 h-4 w-4 shrink-0 text-muted-foreground" }),
22
+ /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
23
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
24
+ /* @__PURE__ */ jsx("p", { className: "truncate text-sm font-medium text-foreground", children: title }),
25
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: source })
26
+ ] }),
27
+ /* @__PURE__ */ jsx(ExternalLink, { className: "h-4 w-4 shrink-0 text-muted-foreground transition-transform group-hover:-translate-y-0.5 group-hover:translate-x-0.5" })
28
+ ] }) })
29
+ ] }),
30
+ snippet ? /* @__PURE__ */ jsx("p", { className: "line-clamp-3 text-sm leading-6 text-muted-foreground", children: snippet }) : null
31
+ ]
32
+ }
33
+ );
34
+ }
35
+ );
36
+ AISourceCitation.displayName = "AISourceCitation";
37
+ export {
38
+ AISourceCitation
39
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ AISourceCitation
3
+ } from "./ai-source-citation";
4
+ export {
5
+ AISourceCitation
6
+ };
@@ -0,0 +1,41 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ import { cn } from "../../lib/utils";
4
+ const AIStreamingText = forwardRef(
5
+ ({
6
+ className,
7
+ cursor = "\u258D",
8
+ isStreaming = false,
9
+ showCursor = true,
10
+ text,
11
+ ...props
12
+ }, ref) => {
13
+ return /* @__PURE__ */ jsxs(
14
+ "div",
15
+ {
16
+ "aria-live": isStreaming ? "polite" : void 0,
17
+ className: cn(
18
+ "text-sm leading-6 text-foreground whitespace-pre-wrap",
19
+ className
20
+ ),
21
+ ref,
22
+ ...props,
23
+ children: [
24
+ text,
25
+ isStreaming && showCursor ? /* @__PURE__ */ jsx(
26
+ "span",
27
+ {
28
+ "aria-hidden": "true",
29
+ className: "ml-0.5 inline-block animate-pulse text-muted-foreground",
30
+ children: cursor
31
+ }
32
+ ) : null
33
+ ]
34
+ }
35
+ );
36
+ }
37
+ );
38
+ AIStreamingText.displayName = "AIStreamingText";
39
+ export {
40
+ AIStreamingText
41
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ AIStreamingText
3
+ } from "./ai-streaming-text";
4
+ export {
5
+ AIStreamingText
6
+ };
@@ -0,0 +1,93 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ import { cva } from "class-variance-authority";
4
+ import { AlertCircle, CheckCircle2, Clock3, Wrench } from "lucide-react";
5
+ import { cn } from "../../lib/utils";
6
+ import { Badge } from "../badge";
7
+ const statusVariants = cva(
8
+ "rounded-full px-2 py-0 text-[10px] uppercase tracking-wide",
9
+ {
10
+ defaultVariants: {
11
+ status: "queued"
12
+ },
13
+ variants: {
14
+ status: {
15
+ complete: "bg-emerald-500/10 text-emerald-700 dark:text-emerald-300",
16
+ error: "bg-red-500/10 text-red-700 dark:text-red-300",
17
+ queued: "bg-muted text-muted-foreground",
18
+ running: "bg-blue-500/10 text-blue-700 dark:text-blue-300"
19
+ }
20
+ }
21
+ }
22
+ );
23
+ const statusIconMap = {
24
+ complete: /* @__PURE__ */ jsx(CheckCircle2, { className: "h-4 w-4" }),
25
+ error: /* @__PURE__ */ jsx(AlertCircle, { className: "h-4 w-4" }),
26
+ queued: /* @__PURE__ */ jsx(Clock3, { className: "h-4 w-4" }),
27
+ running: /* @__PURE__ */ jsx(Wrench, { className: "h-4 w-4 animate-pulse" })
28
+ };
29
+ const AIToolCallDisplay = forwardRef(
30
+ ({
31
+ className,
32
+ description,
33
+ duration,
34
+ input,
35
+ output,
36
+ status = "queued",
37
+ toolName,
38
+ ...props
39
+ }, ref) => {
40
+ return /* @__PURE__ */ jsxs(
41
+ "div",
42
+ {
43
+ className: cn(
44
+ "rounded-2xl border border-border/70 bg-card p-4 shadow-sm",
45
+ className
46
+ ),
47
+ ref,
48
+ ...props,
49
+ children: [
50
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-start justify-between gap-3", children: [
51
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 space-y-1", children: [
52
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm font-medium text-foreground", children: [
53
+ statusIconMap[status],
54
+ /* @__PURE__ */ jsx("span", { children: toolName })
55
+ ] }),
56
+ description ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: description }) : null
57
+ ] }),
58
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
59
+ duration ? /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: duration }) : null,
60
+ /* @__PURE__ */ jsx(Badge, { className: statusVariants({ status }), variant: "secondary", children: status })
61
+ ] })
62
+ ] }),
63
+ input ? /* @__PURE__ */ jsxs(
64
+ "details",
65
+ {
66
+ className: "mt-4 rounded-xl border border-border/60 bg-muted/20 p-3",
67
+ open: status !== "complete",
68
+ children: [
69
+ /* @__PURE__ */ jsx("summary", { className: "cursor-pointer text-xs font-medium uppercase tracking-wide text-muted-foreground", children: "Tool input" }),
70
+ /* @__PURE__ */ jsx("pre", { className: "mt-3 overflow-x-auto whitespace-pre-wrap text-xs leading-5 text-foreground", children: input })
71
+ ]
72
+ }
73
+ ) : null,
74
+ output ? /* @__PURE__ */ jsxs(
75
+ "details",
76
+ {
77
+ className: "mt-3 rounded-xl border border-border/60 bg-muted/20 p-3",
78
+ open: status !== "complete",
79
+ children: [
80
+ /* @__PURE__ */ jsx("summary", { className: "cursor-pointer text-xs font-medium uppercase tracking-wide text-muted-foreground", children: "Tool output" }),
81
+ /* @__PURE__ */ jsx("pre", { className: "mt-3 overflow-x-auto whitespace-pre-wrap text-xs leading-5 text-foreground", children: output })
82
+ ]
83
+ }
84
+ ) : null
85
+ ]
86
+ }
87
+ );
88
+ }
89
+ );
90
+ AIToolCallDisplay.displayName = "AIToolCallDisplay";
91
+ export {
92
+ AIToolCallDisplay
93
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ AIToolCallDisplay
3
+ } from "./ai-tool-call-display";
4
+ export {
5
+ AIToolCallDisplay
6
+ };