@vllnt/ui 0.1.8 → 0.1.11-canary.54f8a77

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 (99) hide show
  1. package/LICENSE +21 -0
  2. package/dist/components/activity-heatmap/activity-heatmap.js +168 -0
  3. package/dist/components/activity-heatmap/index.js +6 -0
  4. package/dist/components/activity-log/activity-log.js +256 -0
  5. package/dist/components/activity-log/index.js +6 -0
  6. package/dist/components/ai-chat-input/ai-chat-input.js +107 -0
  7. package/dist/components/ai-chat-input/index.js +4 -0
  8. package/dist/components/ai-message-bubble/ai-message-bubble.js +119 -0
  9. package/dist/components/ai-message-bubble/index.js +6 -0
  10. package/dist/components/ai-source-citation/ai-source-citation.js +39 -0
  11. package/dist/components/ai-source-citation/index.js +6 -0
  12. package/dist/components/ai-streaming-text/ai-streaming-text.js +41 -0
  13. package/dist/components/ai-streaming-text/index.js +6 -0
  14. package/dist/components/ai-tool-call-display/ai-tool-call-display.js +93 -0
  15. package/dist/components/ai-tool-call-display/index.js +6 -0
  16. package/dist/components/animated-text/animated-text.js +328 -0
  17. package/dist/components/animated-text/index.js +4 -0
  18. package/dist/components/annotation/annotation.js +49 -0
  19. package/dist/components/annotation/index.js +8 -0
  20. package/dist/components/avatar-group/avatar-group.js +82 -0
  21. package/dist/components/avatar-group/index.js +10 -0
  22. package/dist/components/border-beam/border-beam.js +51 -0
  23. package/dist/components/border-beam/index.js +4 -0
  24. package/dist/components/candlestick-chart/candlestick-chart.js +215 -0
  25. package/dist/components/candlestick-chart/index.js +6 -0
  26. package/dist/components/combobox/combobox.js +130 -0
  27. package/dist/components/combobox/index.js +4 -0
  28. package/dist/components/countdown-timer/countdown-timer.js +184 -0
  29. package/dist/components/countdown-timer/index.js +4 -0
  30. package/dist/components/credit-badge/credit-badge.js +59 -0
  31. package/dist/components/credit-badge/index.js +6 -0
  32. package/dist/components/data-list/data-list.js +99 -0
  33. package/dist/components/data-list/index.js +16 -0
  34. package/dist/components/data-table/data-table.js +242 -0
  35. package/dist/components/data-table/index.js +6 -0
  36. package/dist/components/date-picker/date-picker.js +74 -0
  37. package/dist/components/date-picker/index.js +4 -0
  38. package/dist/components/file-upload/file-upload.js +227 -0
  39. package/dist/components/file-upload/index.js +4 -0
  40. package/dist/components/flashcard/flashcard.js +66 -0
  41. package/dist/components/flashcard/index.js +4 -0
  42. package/dist/components/index.js +172 -1
  43. package/dist/components/live-feed/index.js +4 -0
  44. package/dist/components/live-feed/live-feed.js +168 -0
  45. package/dist/components/market-treemap/index.js +6 -0
  46. package/dist/components/market-treemap/market-treemap.js +100 -0
  47. package/dist/components/marquee/index.js +4 -0
  48. package/dist/components/marquee/marquee.js +98 -0
  49. package/dist/components/metric-gauge/index.js +6 -0
  50. package/dist/components/metric-gauge/metric-gauge.js +213 -0
  51. package/dist/components/model-selector/model-selector.js +11 -2
  52. package/dist/components/number-input/index.js +4 -0
  53. package/dist/components/number-input/number-input.js +167 -0
  54. package/dist/components/number-ticker/index.js +4 -0
  55. package/dist/components/number-ticker/number-ticker.js +63 -0
  56. package/dist/components/order-book/index.js +6 -0
  57. package/dist/components/order-book/order-book.js +128 -0
  58. package/dist/components/password-input/index.js +4 -0
  59. package/dist/components/password-input/password-input.js +45 -0
  60. package/dist/components/plan-badge/index.js +6 -0
  61. package/dist/components/plan-badge/plan-badge.js +67 -0
  62. package/dist/components/rating/index.js +4 -0
  63. package/dist/components/rating/rating.js +121 -0
  64. package/dist/components/role-badge/index.js +6 -0
  65. package/dist/components/role-badge/role-badge.js +50 -0
  66. package/dist/components/scope-selector/index.js +6 -0
  67. package/dist/components/scope-selector/scope-selector.js +336 -0
  68. package/dist/components/severity-badge/index.js +8 -0
  69. package/dist/components/severity-badge/severity-badge.js +163 -0
  70. package/dist/components/sparkline-grid/index.js +6 -0
  71. package/dist/components/sparkline-grid/sparkline-grid.js +92 -0
  72. package/dist/components/spinner/index.js +5 -1
  73. package/dist/components/spinner/unicode-spinner.js +708 -0
  74. package/dist/components/stat-card/index.js +5 -0
  75. package/dist/components/stat-card/stat-card.js +102 -0
  76. package/dist/components/status-board/index.js +6 -0
  77. package/dist/components/status-board/status-board.js +138 -0
  78. package/dist/components/status-indicator/index.js +10 -0
  79. package/dist/components/status-indicator/status-indicator.js +175 -0
  80. package/dist/components/stepper/index.js +4 -0
  81. package/dist/components/stepper/stepper.js +117 -0
  82. package/dist/components/subscription-card/index.js +6 -0
  83. package/dist/components/subscription-card/subscription-card.js +161 -0
  84. package/dist/components/ticker-tape/index.js +6 -0
  85. package/dist/components/ticker-tape/ticker-tape.js +106 -0
  86. package/dist/components/tour/index.js +4 -0
  87. package/dist/components/tour/tour.js +157 -0
  88. package/dist/components/usage-breakdown/index.js +6 -0
  89. package/dist/components/usage-breakdown/usage-breakdown.js +140 -0
  90. package/dist/components/wallet-card/index.js +4 -0
  91. package/dist/components/wallet-card/wallet-card.js +115 -0
  92. package/dist/components/watchlist/index.js +6 -0
  93. package/dist/components/watchlist/watchlist.js +110 -0
  94. package/dist/components/world-clock-bar/index.js +6 -0
  95. package/dist/components/world-clock-bar/world-clock-bar.js +101 -0
  96. package/dist/index.d.ts +1173 -7
  97. package/dist/test-setup.js +19 -0
  98. package/package.json +45 -41
  99. package/styles.css +55 -0
@@ -0,0 +1,102 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import { cva } from "class-variance-authority";
4
+ import { ArrowDownRight, ArrowRight, ArrowUpRight } from "lucide-react";
5
+ import { cn } from "../../lib/utils";
6
+ import { Card, CardContent, CardDescription, CardHeader } from "../card";
7
+ const statCardVariants = cva("overflow-hidden border shadow-sm", {
8
+ defaultVariants: {
9
+ tone: "neutral"
10
+ },
11
+ variants: {
12
+ tone: {
13
+ danger: "border-red-200/70 dark:border-red-950/70",
14
+ neutral: "",
15
+ success: "border-emerald-200/70 dark:border-emerald-950/70",
16
+ warning: "border-amber-200/70 dark:border-amber-950/70"
17
+ }
18
+ }
19
+ });
20
+ const accentVariants = cva("h-1 w-full", {
21
+ defaultVariants: {
22
+ tone: "neutral"
23
+ },
24
+ variants: {
25
+ tone: {
26
+ danger: "bg-red-500/80",
27
+ neutral: "bg-primary/70",
28
+ success: "bg-emerald-500/80",
29
+ warning: "bg-amber-500/80"
30
+ }
31
+ }
32
+ });
33
+ const changeVariants = cva(
34
+ "inline-flex items-center gap-1 text-xs font-medium",
35
+ {
36
+ defaultVariants: {
37
+ trend: "neutral"
38
+ },
39
+ variants: {
40
+ trend: {
41
+ down: "text-red-600 dark:text-red-400",
42
+ neutral: "text-muted-foreground",
43
+ up: "text-emerald-600 dark:text-emerald-400"
44
+ }
45
+ }
46
+ }
47
+ );
48
+ function TrendIcon({ trend }) {
49
+ if (trend === "up") {
50
+ return /* @__PURE__ */ jsx(ArrowUpRight, { className: "h-3.5 w-3.5" });
51
+ }
52
+ if (trend === "down") {
53
+ return /* @__PURE__ */ jsx(ArrowDownRight, { className: "h-3.5 w-3.5" });
54
+ }
55
+ return /* @__PURE__ */ jsx(ArrowRight, { className: "h-3.5 w-3.5" });
56
+ }
57
+ const StatCard = React.forwardRef(
58
+ ({
59
+ change,
60
+ className,
61
+ description,
62
+ icon,
63
+ label,
64
+ meta,
65
+ tone,
66
+ trend = "neutral",
67
+ value,
68
+ ...props
69
+ }, reference) => /* @__PURE__ */ jsxs(
70
+ Card,
71
+ {
72
+ className: cn(statCardVariants({ tone }), className),
73
+ ref: reference,
74
+ ...props,
75
+ children: [
76
+ /* @__PURE__ */ jsx("div", { className: accentVariants({ tone }) }),
77
+ /* @__PURE__ */ jsxs(CardHeader, { className: "flex flex-row items-start justify-between gap-4 space-y-0 pb-3", children: [
78
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
79
+ /* @__PURE__ */ jsx(CardDescription, { className: "text-xs font-medium uppercase tracking-[0.14em]", children: label }),
80
+ /* @__PURE__ */ jsx("div", { className: "text-3xl font-semibold tracking-tight", children: value })
81
+ ] }),
82
+ icon ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border bg-muted/50 p-2 text-muted-foreground", children: icon }) : null
83
+ ] }),
84
+ description || change || meta ? /* @__PURE__ */ jsxs(CardContent, { className: "space-y-3", children: [
85
+ description ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: description }) : null,
86
+ change || meta ? /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [
87
+ change ? /* @__PURE__ */ jsxs("div", { className: changeVariants({ trend }), children: [
88
+ /* @__PURE__ */ jsx(TrendIcon, { trend }),
89
+ /* @__PURE__ */ jsx("span", { children: change })
90
+ ] }) : null,
91
+ meta ? /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: meta }) : null
92
+ ] }) : null
93
+ ] }) : null
94
+ ]
95
+ }
96
+ )
97
+ );
98
+ StatCard.displayName = "StatCard";
99
+ export {
100
+ StatCard,
101
+ statCardVariants
102
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ StatusBoard
3
+ } from "./status-board";
4
+ export {
5
+ StatusBoard
6
+ };
@@ -0,0 +1,138 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import { cn } from "../../lib/utils";
4
+ import { Badge } from "../badge";
5
+ import {
6
+ Card,
7
+ CardContent,
8
+ CardDescription,
9
+ CardHeader,
10
+ CardTitle
11
+ } from "../card";
12
+ const STATUS_META = {
13
+ critical: {
14
+ badgeVariant: "destructive",
15
+ dotClassName: "bg-destructive",
16
+ label: "Critical",
17
+ panelClassName: "border-destructive/30 bg-destructive/5"
18
+ },
19
+ healthy: {
20
+ badgeVariant: "default",
21
+ dotClassName: "bg-emerald-500",
22
+ label: "Healthy",
23
+ panelClassName: "border-emerald-500/25 bg-emerald-500/5"
24
+ },
25
+ maintenance: {
26
+ badgeVariant: "secondary",
27
+ dotClassName: "bg-sky-500",
28
+ label: "Maintenance",
29
+ panelClassName: "border-sky-500/25 bg-sky-500/5"
30
+ },
31
+ offline: {
32
+ badgeVariant: "outline",
33
+ dotClassName: "bg-muted-foreground",
34
+ label: "Offline",
35
+ panelClassName: "border-border bg-muted/30"
36
+ },
37
+ warning: {
38
+ badgeVariant: "secondary",
39
+ dotClassName: "bg-amber-500",
40
+ label: "Warning",
41
+ panelClassName: "border-amber-500/25 bg-amber-500/5"
42
+ }
43
+ };
44
+ const STATUS_ORDER = [
45
+ "healthy",
46
+ "warning",
47
+ "critical",
48
+ "maintenance",
49
+ "offline"
50
+ ];
51
+ function getColumnsClassName(columns) {
52
+ if (columns === 2) {
53
+ return "md:grid-cols-2";
54
+ }
55
+ if (columns === 4) {
56
+ return "md:grid-cols-2 xl:grid-cols-4";
57
+ }
58
+ return "md:grid-cols-2 xl:grid-cols-3";
59
+ }
60
+ function getSummary(items) {
61
+ const counts = items.reduce(
62
+ (summary, item) => ({
63
+ ...summary,
64
+ [item.status]: summary[item.status] + 1
65
+ }),
66
+ {
67
+ critical: 0,
68
+ healthy: 0,
69
+ maintenance: 0,
70
+ offline: 0,
71
+ warning: 0
72
+ }
73
+ );
74
+ return STATUS_ORDER.map((status) => ({
75
+ count: counts[status],
76
+ status
77
+ })).filter((entry) => entry.count > 0);
78
+ }
79
+ function StatusBoardSummary({ items }) {
80
+ return /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: getSummary(items).map(({ count, status }) => {
81
+ const meta = STATUS_META[status];
82
+ return /* @__PURE__ */ jsxs(Badge, { variant: meta.badgeVariant, children: [
83
+ count,
84
+ " ",
85
+ meta.label
86
+ ] }, status);
87
+ }) });
88
+ }
89
+ function StatusBoardCard({ item }) {
90
+ const meta = STATUS_META[item.status];
91
+ return /* @__PURE__ */ jsxs(Card, { className: cn("shadow-sm", meta.panelClassName), children: [
92
+ /* @__PURE__ */ jsx(CardHeader, { className: "gap-3 space-y-0", children: /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
93
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
94
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
95
+ /* @__PURE__ */ jsx(
96
+ "span",
97
+ {
98
+ "aria-hidden": "true",
99
+ className: cn("h-2.5 w-2.5 rounded-full", meta.dotClassName)
100
+ }
101
+ ),
102
+ /* @__PURE__ */ jsx(CardTitle, { className: "text-base leading-none", children: item.label })
103
+ ] }),
104
+ item.description ? /* @__PURE__ */ jsx(CardDescription, { children: item.description }) : null
105
+ ] }),
106
+ /* @__PURE__ */ jsx(Badge, { variant: meta.badgeVariant, children: meta.label })
107
+ ] }) }),
108
+ /* @__PURE__ */ jsxs(CardContent, { className: "flex items-end justify-between gap-3", children: [
109
+ /* @__PURE__ */ jsx("div", { children: item.value ? /* @__PURE__ */ jsx("div", { className: "text-2xl font-semibold tracking-tight", children: item.value }) : /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground", children: "No metric reported" }) }),
110
+ item.meta ? /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: item.meta }) : null
111
+ ] })
112
+ ] });
113
+ }
114
+ const StatusBoard = React.forwardRef(
115
+ ({
116
+ className,
117
+ columns = 3,
118
+ description,
119
+ items,
120
+ title = "Status board",
121
+ ...props
122
+ }, ref) => {
123
+ return /* @__PURE__ */ jsxs("div", { className: cn("space-y-4", className), ref, ...props, children: [
124
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between", children: [
125
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
126
+ /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold tracking-tight", children: title }),
127
+ description ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: description }) : null
128
+ ] }),
129
+ /* @__PURE__ */ jsx(StatusBoardSummary, { items })
130
+ ] }),
131
+ /* @__PURE__ */ jsx("div", { className: cn("grid gap-4", getColumnsClassName(columns)), children: items.map((item) => /* @__PURE__ */ jsx(StatusBoardCard, { item }, item.label)) })
132
+ ] });
133
+ }
134
+ );
135
+ StatusBoard.displayName = "StatusBoard";
136
+ export {
137
+ StatusBoard
138
+ };
@@ -0,0 +1,10 @@
1
+ import {
2
+ dotVariants,
3
+ StatusIndicator,
4
+ statusIndicatorVariants
5
+ } from "./status-indicator";
6
+ export {
7
+ StatusIndicator,
8
+ dotVariants,
9
+ statusIndicatorVariants
10
+ };
@@ -0,0 +1,175 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import { cva } from "class-variance-authority";
4
+ import { cn } from "../../lib/utils";
5
+ const statusIndicatorVariants = cva(
6
+ "inline-flex items-center justify-center gap-2 rounded-full border font-medium transition-colors",
7
+ {
8
+ compoundVariants: [
9
+ {
10
+ className: "border-border text-foreground",
11
+ tone: "neutral",
12
+ variant: "outline"
13
+ },
14
+ {
15
+ className: "border-transparent bg-muted text-foreground",
16
+ tone: "neutral",
17
+ variant: "soft"
18
+ },
19
+ {
20
+ className: "bg-foreground text-background",
21
+ tone: "neutral",
22
+ variant: "solid"
23
+ },
24
+ {
25
+ className: "border-emerald-200 text-emerald-700 dark:border-emerald-900 dark:text-emerald-300",
26
+ tone: "success",
27
+ variant: "outline"
28
+ },
29
+ {
30
+ className: "bg-emerald-100 text-emerald-800 dark:bg-emerald-950/60 dark:text-emerald-300",
31
+ tone: "success",
32
+ variant: "soft"
33
+ },
34
+ {
35
+ className: "bg-emerald-600 text-white dark:bg-emerald-500",
36
+ tone: "success",
37
+ variant: "solid"
38
+ },
39
+ {
40
+ className: "border-amber-200 text-amber-700 dark:border-amber-900 dark:text-amber-300",
41
+ tone: "warning",
42
+ variant: "outline"
43
+ },
44
+ {
45
+ className: "bg-amber-100 text-amber-800 dark:bg-amber-950/60 dark:text-amber-300",
46
+ tone: "warning",
47
+ variant: "soft"
48
+ },
49
+ {
50
+ className: "bg-amber-500 text-amber-950 dark:bg-amber-400 dark:text-amber-950",
51
+ tone: "warning",
52
+ variant: "solid"
53
+ },
54
+ {
55
+ className: "border-red-200 text-red-700 dark:border-red-900 dark:text-red-300",
56
+ tone: "danger",
57
+ variant: "outline"
58
+ },
59
+ {
60
+ className: "bg-red-100 text-red-800 dark:bg-red-950/60 dark:text-red-300",
61
+ tone: "danger",
62
+ variant: "soft"
63
+ },
64
+ {
65
+ className: "bg-red-600 text-white dark:bg-red-500",
66
+ tone: "danger",
67
+ variant: "solid"
68
+ },
69
+ {
70
+ className: "border-sky-200 text-sky-700 dark:border-sky-900 dark:text-sky-300",
71
+ tone: "info",
72
+ variant: "outline"
73
+ },
74
+ {
75
+ className: "bg-sky-100 text-sky-800 dark:bg-sky-950/60 dark:text-sky-300",
76
+ tone: "info",
77
+ variant: "soft"
78
+ },
79
+ {
80
+ className: "bg-sky-600 text-white dark:bg-sky-500",
81
+ tone: "info",
82
+ variant: "solid"
83
+ }
84
+ ],
85
+ defaultVariants: {
86
+ size: "md",
87
+ tone: "neutral",
88
+ variant: "soft"
89
+ },
90
+ variants: {
91
+ size: {
92
+ lg: "min-h-8 px-3 text-sm",
93
+ md: "min-h-7 px-2.5 text-xs",
94
+ sm: "min-h-6 px-2 text-[11px]"
95
+ },
96
+ tone: {
97
+ danger: "",
98
+ info: "",
99
+ neutral: "",
100
+ success: "",
101
+ warning: ""
102
+ },
103
+ variant: {
104
+ outline: "bg-background",
105
+ soft: "border-transparent",
106
+ solid: "border-transparent text-primary-foreground"
107
+ }
108
+ }
109
+ }
110
+ );
111
+ const dotVariants = cva("rounded-full", {
112
+ defaultVariants: {
113
+ size: "md",
114
+ tone: "neutral"
115
+ },
116
+ variants: {
117
+ size: {
118
+ lg: "h-2.5 w-2.5",
119
+ md: "h-2 w-2",
120
+ sm: "h-1.5 w-1.5"
121
+ },
122
+ tone: {
123
+ danger: "bg-red-500",
124
+ info: "bg-sky-500",
125
+ neutral: "bg-muted-foreground",
126
+ success: "bg-emerald-500",
127
+ warning: "bg-amber-500"
128
+ }
129
+ }
130
+ });
131
+ const StatusIndicator = React.forwardRef(
132
+ ({
133
+ children,
134
+ className,
135
+ label,
136
+ pulse = false,
137
+ showDot = true,
138
+ size,
139
+ tone,
140
+ variant,
141
+ ...props
142
+ }, reference) => {
143
+ const content = children ?? label;
144
+ return /* @__PURE__ */ jsxs(
145
+ "span",
146
+ {
147
+ className: cn(
148
+ statusIndicatorVariants({ size, tone, variant }),
149
+ className
150
+ ),
151
+ ref: reference,
152
+ ...props,
153
+ children: [
154
+ showDot ? /* @__PURE__ */ jsx(
155
+ "span",
156
+ {
157
+ "aria-hidden": "true",
158
+ className: cn(
159
+ dotVariants({ size, tone }),
160
+ pulse ? "animate-pulse" : void 0
161
+ )
162
+ }
163
+ ) : null,
164
+ content
165
+ ]
166
+ }
167
+ );
168
+ }
169
+ );
170
+ StatusIndicator.displayName = "StatusIndicator";
171
+ export {
172
+ StatusIndicator,
173
+ dotVariants,
174
+ statusIndicatorVariants
175
+ };
@@ -0,0 +1,4 @@
1
+ import { Stepper } from "./stepper";
2
+ export {
3
+ Stepper
4
+ };
@@ -0,0 +1,117 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Check, Circle } from "lucide-react";
3
+ import { cn } from "../../lib/utils";
4
+ function getStepState(index, currentStep) {
5
+ const stepNumber = index + 1;
6
+ if (stepNumber < currentStep) return "complete";
7
+ if (stepNumber === currentStep) return "current";
8
+ return "upcoming";
9
+ }
10
+ function StepIcon({
11
+ showNumbers,
12
+ state,
13
+ stepNumber
14
+ }) {
15
+ if (state === "complete") {
16
+ return /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" });
17
+ }
18
+ if (!showNumbers) {
19
+ return /* @__PURE__ */ jsx(Circle, { className: "h-3.5 w-3.5 fill-current stroke-none" });
20
+ }
21
+ return /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold", children: stepNumber });
22
+ }
23
+ function StepperItem({
24
+ index,
25
+ isVertical,
26
+ onStepClick,
27
+ showNumbers,
28
+ step,
29
+ stepState,
30
+ totalSteps
31
+ }) {
32
+ const clickable = Boolean(onStepClick);
33
+ const stepNumber = index + 1;
34
+ return /* @__PURE__ */ jsxs("li", { className: cn("relative", !isVertical && "min-w-0"), children: [
35
+ !isVertical && index < totalSteps - 1 ? /* @__PURE__ */ jsx("div", { className: "absolute left-[calc(50%+1rem)] right-[calc(-50%+1rem)] top-4 hidden h-px bg-border md:block" }) : null,
36
+ /* @__PURE__ */ jsxs(
37
+ "button",
38
+ {
39
+ className: cn(
40
+ "flex w-full items-start gap-3 rounded-lg text-left transition-colors",
41
+ clickable ? "hover:bg-muted/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring" : "cursor-default",
42
+ isVertical ? "p-2" : "flex-col items-start p-2 md:p-0"
43
+ ),
44
+ disabled: !clickable,
45
+ onClick: () => {
46
+ onStepClick?.(step, index);
47
+ },
48
+ type: "button",
49
+ children: [
50
+ /* @__PURE__ */ jsx(
51
+ "span",
52
+ {
53
+ "aria-current": stepState === "current" ? "step" : void 0,
54
+ className: cn(
55
+ "relative z-10 flex h-8 w-8 items-center justify-center rounded-full border text-sm transition-colors",
56
+ stepState === "complete" && "border-primary bg-primary text-primary-foreground",
57
+ stepState === "current" && "border-primary bg-primary/10 text-primary shadow-sm",
58
+ stepState === "upcoming" && "border-border bg-background text-muted-foreground"
59
+ ),
60
+ children: /* @__PURE__ */ jsx(
61
+ StepIcon,
62
+ {
63
+ showNumbers,
64
+ state: stepState,
65
+ stepNumber
66
+ }
67
+ )
68
+ }
69
+ ),
70
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0 space-y-1", children: [
71
+ /* @__PURE__ */ jsxs("span", { className: "flex flex-wrap items-center gap-2", children: [
72
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-foreground", children: step.title }),
73
+ step.meta ? /* @__PURE__ */ jsx("span", { className: "rounded-full bg-muted px-2 py-0.5 text-[11px] font-medium text-muted-foreground", children: step.meta }) : null
74
+ ] }),
75
+ step.description ? /* @__PURE__ */ jsx("span", { className: "block text-sm text-muted-foreground", children: step.description }) : null
76
+ ] })
77
+ ]
78
+ }
79
+ )
80
+ ] });
81
+ }
82
+ function Stepper({
83
+ className,
84
+ currentStep,
85
+ onStepClick,
86
+ orientation = "horizontal",
87
+ showNumbers = true,
88
+ steps
89
+ }) {
90
+ const isVertical = orientation === "vertical";
91
+ if (steps.length === 0) {
92
+ return null;
93
+ }
94
+ return /* @__PURE__ */ jsx("div", { className: cn("my-6 rounded-xl border bg-card p-4", className), children: /* @__PURE__ */ jsx(
95
+ "ol",
96
+ {
97
+ className: cn("gap-3", isVertical ? "flex flex-col" : "grid gap-4"),
98
+ style: isVertical ? void 0 : { gridTemplateColumns: `repeat(${steps.length}, minmax(0, 1fr))` },
99
+ children: steps.map((step, index) => /* @__PURE__ */ jsx(
100
+ StepperItem,
101
+ {
102
+ index,
103
+ isVertical,
104
+ onStepClick,
105
+ showNumbers,
106
+ step,
107
+ stepState: getStepState(index, currentStep),
108
+ totalSteps: steps.length
109
+ },
110
+ step.id
111
+ ))
112
+ }
113
+ ) });
114
+ }
115
+ export {
116
+ Stepper
117
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ SubscriptionCard
3
+ } from "./subscription-card";
4
+ export {
5
+ SubscriptionCard
6
+ };