@vllnt/ui 0.2.1-canary.e1bc2b3 → 0.2.1-canary.ee942df

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 (137) hide show
  1. package/dist/components/agent-activity/agent-activity.js +311 -0
  2. package/dist/components/agent-activity/index.js +18 -0
  3. package/dist/components/ai-artifact/ai-artifact.js +422 -0
  4. package/dist/components/ai-artifact/index.js +24 -0
  5. package/dist/components/ai-sidebar/ai-sidebar.js +254 -0
  6. package/dist/components/ai-sidebar/index.js +22 -0
  7. package/dist/components/alert-pulse/alert-pulse.js +93 -0
  8. package/dist/components/alert-pulse/index.js +6 -0
  9. package/dist/components/auto-reload/auto-reload.js +367 -0
  10. package/dist/components/auto-reload/index.js +6 -0
  11. package/dist/components/banner/banner.js +155 -0
  12. package/dist/components/banner/index.js +10 -0
  13. package/dist/components/bottom-activity-strip/bottom-activity-strip.js +91 -0
  14. package/dist/components/bottom-activity-strip/index.js +6 -0
  15. package/dist/components/choropleth-map/choropleth-map.js +373 -0
  16. package/dist/components/choropleth-map/index.js +10 -0
  17. package/dist/components/chronological-timeline/chronological-timeline.js +337 -0
  18. package/dist/components/chronological-timeline/index.js +8 -0
  19. package/dist/components/civilization-card/civilization-card.js +258 -0
  20. package/dist/components/civilization-card/index.js +8 -0
  21. package/dist/components/comment-pin/comment-pin.js +104 -0
  22. package/dist/components/comment-pin/index.js +6 -0
  23. package/dist/components/context-lens/context-lens.js +98 -0
  24. package/dist/components/context-lens/index.js +6 -0
  25. package/dist/components/copy-button/copy-button.js +189 -0
  26. package/dist/components/copy-button/index.js +8 -0
  27. package/dist/components/document-sibling-nav/document-sibling-nav.js +111 -0
  28. package/dist/components/document-sibling-nav/index.js +8 -0
  29. package/dist/components/empty-state/empty-state.js +93 -0
  30. package/dist/components/empty-state/index.js +8 -0
  31. package/dist/components/era-comparison/era-comparison.js +198 -0
  32. package/dist/components/era-comparison/index.js +16 -0
  33. package/dist/components/floating-toolbar/floating-toolbar.js +66 -0
  34. package/dist/components/floating-toolbar/index.js +6 -0
  35. package/dist/components/follow-mode/follow-mode.js +89 -0
  36. package/dist/components/follow-mode/index.js +6 -0
  37. package/dist/components/gantt-chart/gantt-chart.js +331 -0
  38. package/dist/components/gantt-chart/index.js +6 -0
  39. package/dist/components/geography-quiz-map/geography-quiz-map.js +343 -0
  40. package/dist/components/geography-quiz-map/index.js +12 -0
  41. package/dist/components/globe-3d/globe-3d.js +417 -0
  42. package/dist/components/globe-3d/index.js +10 -0
  43. package/dist/components/handoff-beacon/handoff-beacon.js +78 -0
  44. package/dist/components/handoff-beacon/index.js +6 -0
  45. package/dist/components/heat-map-overlay/heat-map-overlay.js +215 -0
  46. package/dist/components/heat-map-overlay/index.js +6 -0
  47. package/dist/components/heat-overlay/heat-overlay.js +92 -0
  48. package/dist/components/heat-overlay/index.js +6 -0
  49. package/dist/components/historic-timeline/historic-timeline.js +342 -0
  50. package/dist/components/historic-timeline/index.js +6 -0
  51. package/dist/components/historical-figure-card/historical-figure-card.js +273 -0
  52. package/dist/components/historical-figure-card/index.js +6 -0
  53. package/dist/components/index.js +432 -1
  54. package/dist/components/infinite-plane/index.js +6 -0
  55. package/dist/components/infinite-plane/infinite-plane.js +75 -0
  56. package/dist/components/interactive-timeline/index.js +16 -0
  57. package/dist/components/interactive-timeline/interactive-timeline.js +708 -0
  58. package/dist/components/jarvis-dock/index.js +6 -0
  59. package/dist/components/jarvis-dock/jarvis-dock.js +98 -0
  60. package/dist/components/kbd/index.js +5 -0
  61. package/dist/components/kbd/kbd.js +117 -0
  62. package/dist/components/knowledge-check/index.js +6 -0
  63. package/dist/components/knowledge-check/knowledge-check.js +448 -0
  64. package/dist/components/live-cursor/index.js +6 -0
  65. package/dist/components/live-cursor/live-cursor.js +62 -0
  66. package/dist/components/map-2d/index.js +20 -0
  67. package/dist/components/map-2d/map-2d.js +455 -0
  68. package/dist/components/map-timeline/index.js +16 -0
  69. package/dist/components/map-timeline/map-timeline.js +506 -0
  70. package/dist/components/metric-cluster/index.js +6 -0
  71. package/dist/components/metric-cluster/metric-cluster.js +96 -0
  72. package/dist/components/model-comparison/index.js +12 -0
  73. package/dist/components/model-comparison/model-comparison.js +211 -0
  74. package/dist/components/multi-select-lasso/index.js +6 -0
  75. package/dist/components/multi-select-lasso/multi-select-lasso.js +76 -0
  76. package/dist/components/newsletter-signup/index.js +8 -0
  77. package/dist/components/newsletter-signup/newsletter-signup.js +269 -0
  78. package/dist/components/object-inspector/index.js +6 -0
  79. package/dist/components/object-inspector/object-inspector.js +136 -0
  80. package/dist/components/parallel-timeline/index.js +6 -0
  81. package/dist/components/parallel-timeline/parallel-timeline.js +251 -0
  82. package/dist/components/playback-ghost/index.js +6 -0
  83. package/dist/components/playback-ghost/playback-ghost.js +83 -0
  84. package/dist/components/policy-delivery-panel/index.js +6 -0
  85. package/dist/components/policy-delivery-panel/policy-delivery-panel.js +99 -0
  86. package/dist/components/presence-stack/index.js +6 -0
  87. package/dist/components/presence-stack/presence-stack.js +108 -0
  88. package/dist/components/presence-sync-indicator/index.js +6 -0
  89. package/dist/components/presence-sync-indicator/presence-sync-indicator.js +73 -0
  90. package/dist/components/pricing-table/index.js +8 -0
  91. package/dist/components/pricing-table/pricing-table.js +247 -0
  92. package/dist/components/primary-source-viewer/index.js +26 -0
  93. package/dist/components/primary-source-viewer/primary-source-viewer.js +439 -0
  94. package/dist/components/prompt-templates/index.js +6 -0
  95. package/dist/components/prompt-templates/prompt-templates.js +403 -0
  96. package/dist/components/property-section/index.js +6 -0
  97. package/dist/components/property-section/property-section.js +101 -0
  98. package/dist/components/relationship-inspector/index.js +6 -0
  99. package/dist/components/relationship-inspector/relationship-inspector.js +102 -0
  100. package/dist/components/route-map/index.js +6 -0
  101. package/dist/components/route-map/route-map.js +339 -0
  102. package/dist/components/routing-assignment-panel/index.js +6 -0
  103. package/dist/components/routing-assignment-panel/routing-assignment-panel.js +122 -0
  104. package/dist/components/run-timeline/index.js +6 -0
  105. package/dist/components/run-timeline/run-timeline.js +221 -0
  106. package/dist/components/runtime-overview-panel/index.js +6 -0
  107. package/dist/components/runtime-overview-panel/runtime-overview-panel.js +89 -0
  108. package/dist/components/selection-halo/index.js +6 -0
  109. package/dist/components/selection-halo/selection-halo.js +72 -0
  110. package/dist/components/selection-presence/index.js +6 -0
  111. package/dist/components/selection-presence/selection-presence.js +50 -0
  112. package/dist/components/snap-guides/index.js +6 -0
  113. package/dist/components/snap-guides/snap-guides.js +45 -0
  114. package/dist/components/state-badge-overlay/index.js +6 -0
  115. package/dist/components/state-badge-overlay/state-badge-overlay.js +90 -0
  116. package/dist/components/sticky-metric/index.js +6 -0
  117. package/dist/components/sticky-metric/sticky-metric.js +83 -0
  118. package/dist/components/story-map/index.js +8 -0
  119. package/dist/components/story-map/story-map.js +414 -0
  120. package/dist/components/thread-bubble/index.js +6 -0
  121. package/dist/components/thread-bubble/thread-bubble.js +85 -0
  122. package/dist/components/threshold-ring/index.js +6 -0
  123. package/dist/components/threshold-ring/threshold-ring.js +160 -0
  124. package/dist/components/timeline/index.js +12 -0
  125. package/dist/components/timeline/timeline.js +239 -0
  126. package/dist/components/timeline-scrubber/index.js +6 -0
  127. package/dist/components/timeline-scrubber/timeline-scrubber.js +179 -0
  128. package/dist/components/transaction-list/index.js +14 -0
  129. package/dist/components/transaction-list/transaction-list.js +226 -0
  130. package/dist/components/tree-view/index.js +6 -0
  131. package/dist/components/tree-view/tree-view.js +298 -0
  132. package/dist/components/viewport-bookmarks/index.js +6 -0
  133. package/dist/components/viewport-bookmarks/viewport-bookmarks.js +116 -0
  134. package/dist/components/world-breadcrumbs/index.js +6 -0
  135. package/dist/components/world-breadcrumbs/world-breadcrumbs.js +114 -0
  136. package/dist/index.d.ts +7135 -141
  137. package/package.json +1 -1
@@ -0,0 +1,93 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { forwardRef } from "react";
4
+ import { cn } from "../../lib/utils";
5
+ const SEVERITY_STROKE = {
6
+ error: "stroke-red-500",
7
+ info: "stroke-blue-500",
8
+ warn: "stroke-amber-500"
9
+ };
10
+ const SEVERITY_FILL = {
11
+ error: "fill-red-500/20",
12
+ info: "fill-blue-500/20",
13
+ warn: "fill-amber-500/20"
14
+ };
15
+ const SEVERITY_LABEL = {
16
+ error: "Error",
17
+ info: "Info",
18
+ warn: "Warning"
19
+ };
20
+ const safeRadius = (value) => value < 6 ? 6 : value;
21
+ const AlertPulse = forwardRef(
22
+ (props, ref) => {
23
+ const {
24
+ className,
25
+ cx,
26
+ cy,
27
+ labels,
28
+ radius = 36,
29
+ reducedMotion = false,
30
+ severity = "warn",
31
+ ...rest
32
+ } = props;
33
+ const r = safeRadius(radius);
34
+ const ariaLabel = labels?.region ?? SEVERITY_LABEL[severity];
35
+ const size = r * 2 + 24;
36
+ return /* @__PURE__ */ jsxs(
37
+ "svg",
38
+ {
39
+ "aria-label": ariaLabel,
40
+ className: cn(
41
+ "pointer-events-none absolute z-20 overflow-visible",
42
+ className
43
+ ),
44
+ "data-alert-pulse": true,
45
+ "data-alert-severity": severity,
46
+ height: size,
47
+ ref,
48
+ role: "img",
49
+ style: {
50
+ left: cx - size / 2,
51
+ top: cy - size / 2
52
+ },
53
+ width: size,
54
+ ...rest,
55
+ children: [
56
+ /* @__PURE__ */ jsx(
57
+ "circle",
58
+ {
59
+ className: cn("origin-center", SEVERITY_STROKE[severity]),
60
+ cx: size / 2,
61
+ cy: size / 2,
62
+ fill: "none",
63
+ r,
64
+ strokeOpacity: 0.7,
65
+ strokeWidth: 2
66
+ }
67
+ ),
68
+ /* @__PURE__ */ jsx(
69
+ "circle",
70
+ {
71
+ className: cn(
72
+ "origin-center",
73
+ SEVERITY_STROKE[severity],
74
+ SEVERITY_FILL[severity],
75
+ reducedMotion ? null : "animate-ping"
76
+ ),
77
+ cx: size / 2,
78
+ cy: size / 2,
79
+ "data-alert-pulse-ring": true,
80
+ r,
81
+ strokeOpacity: 0.4,
82
+ strokeWidth: 2
83
+ }
84
+ )
85
+ ]
86
+ }
87
+ );
88
+ }
89
+ );
90
+ AlertPulse.displayName = "AlertPulse";
91
+ export {
92
+ AlertPulse
93
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ AlertPulse
3
+ } from "./alert-pulse";
4
+ export {
5
+ AlertPulse
6
+ };
@@ -0,0 +1,367 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import {
4
+ forwardRef,
5
+ useCallback,
6
+ useId,
7
+ useMemo,
8
+ useState
9
+ } from "react";
10
+ import { cn } from "../../lib/utils";
11
+ import { Button } from "../button/button";
12
+ import { Input } from "../input/input";
13
+ import { Switch } from "../switch/switch";
14
+ const CENTS_PER_UNIT = 100;
15
+ const DEFAULT_LOCALE = "en-US";
16
+ const DEFAULT_CURRENCY = "USD";
17
+ const DEFAULT_STEP_CENTS = 100;
18
+ const DEFAULT_LABELS = {
19
+ disabledFallback: "Auto-reload is unavailable for this account.",
20
+ heading: "Auto-reload",
21
+ helper: "Automatically reload credits when balance is low.",
22
+ reloadHelper: "Amount to add when the threshold is hit.",
23
+ reloadLabel: "Reload amount",
24
+ save: "Save settings",
25
+ saving: "Saving\u2026",
26
+ thresholdHelper: "Reload when the balance drops below this.",
27
+ thresholdLabel: "Threshold"
28
+ };
29
+ function centsToValue(cents) {
30
+ return (cents / CENTS_PER_UNIT).toFixed(2);
31
+ }
32
+ function valueToCents(value) {
33
+ const parsed = Number.parseFloat(value);
34
+ if (Number.isNaN(parsed)) return 0;
35
+ return Math.round(parsed * CENTS_PER_UNIT);
36
+ }
37
+ function getCurrencySymbol(locale, currency) {
38
+ const formatted = new Intl.NumberFormat(locale, {
39
+ currency,
40
+ style: "currency"
41
+ }).format(0);
42
+ const symbol = formatted.replaceAll(/[\d\s,.]/g, "");
43
+ return symbol.length > 0 ? symbol : currency;
44
+ }
45
+ function ReloadFormFields({
46
+ currencyDisplay,
47
+ isSaving,
48
+ labels,
49
+ maxAmountCents,
50
+ minAmountCents,
51
+ onSave,
52
+ reloadAmount,
53
+ reloadAmountId,
54
+ setReloadAmount,
55
+ setThreshold,
56
+ stepCents,
57
+ threshold,
58
+ thresholdId
59
+ }) {
60
+ const handleThreshold = useCallback(
61
+ (event) => {
62
+ setThreshold(valueToCents(event.target.value));
63
+ },
64
+ [setThreshold]
65
+ );
66
+ const handleReload = useCallback(
67
+ (event) => {
68
+ setReloadAmount(valueToCents(event.target.value));
69
+ },
70
+ [setReloadAmount]
71
+ );
72
+ const step = (stepCents / CENTS_PER_UNIT).toFixed(2);
73
+ const min = (minAmountCents / CENTS_PER_UNIT).toFixed(2);
74
+ const max = maxAmountCents === void 0 ? void 0 : (maxAmountCents / CENTS_PER_UNIT).toFixed(2);
75
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
76
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2", children: [
77
+ /* @__PURE__ */ jsx(
78
+ NumericField,
79
+ {
80
+ currencyDisplay,
81
+ helper: labels.thresholdHelper,
82
+ id: thresholdId,
83
+ label: labels.thresholdLabel,
84
+ max,
85
+ min,
86
+ onChange: handleThreshold,
87
+ step,
88
+ value: centsToValue(threshold)
89
+ }
90
+ ),
91
+ /* @__PURE__ */ jsx(
92
+ NumericField,
93
+ {
94
+ currencyDisplay,
95
+ helper: labels.reloadHelper,
96
+ id: reloadAmountId,
97
+ label: labels.reloadLabel,
98
+ max,
99
+ min,
100
+ onChange: handleReload,
101
+ step,
102
+ value: centsToValue(reloadAmount)
103
+ }
104
+ )
105
+ ] }),
106
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, { disabled: isSaving, onClick: onSave, type: "button", children: isSaving ? labels.saving : labels.save }) })
107
+ ] });
108
+ }
109
+ function NumericField({
110
+ currencyDisplay,
111
+ helper,
112
+ id,
113
+ label,
114
+ max,
115
+ min,
116
+ onChange,
117
+ step,
118
+ value
119
+ }) {
120
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
121
+ /* @__PURE__ */ jsxs("label", { className: "text-sm font-medium text-foreground", htmlFor: id, children: [
122
+ label,
123
+ " (",
124
+ currencyDisplay,
125
+ ")"
126
+ ] }),
127
+ /* @__PURE__ */ jsx(
128
+ Input,
129
+ {
130
+ id,
131
+ inputMode: "decimal",
132
+ max,
133
+ min,
134
+ onChange,
135
+ step,
136
+ type: "number",
137
+ value
138
+ }
139
+ ),
140
+ helper ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: helper }) : null
141
+ ] });
142
+ }
143
+ function ToggleHeader({
144
+ enabled,
145
+ heading,
146
+ helper,
147
+ id,
148
+ onCheckedChange
149
+ }) {
150
+ const helperId = `${id}-helper`;
151
+ return /* @__PURE__ */ jsxs("header", { className: "flex items-start justify-between gap-3", children: [
152
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
153
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-foreground", id, children: heading }),
154
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", id: helperId, children: helper })
155
+ ] }),
156
+ /* @__PURE__ */ jsx(
157
+ Switch,
158
+ {
159
+ "aria-describedby": helperId,
160
+ "aria-labelledby": id,
161
+ checked: enabled,
162
+ onCheckedChange
163
+ }
164
+ )
165
+ ] });
166
+ }
167
+ function useAutoReloadController(options) {
168
+ const {
169
+ defaultEnabled,
170
+ defaultReloadAmountCents,
171
+ defaultThresholdCents,
172
+ enabled: controlledEnabled,
173
+ onToggle,
174
+ reloadAmountCents: controlledReload,
175
+ thresholdCents: controlledThreshold
176
+ } = options;
177
+ const [uncontrolledEnabled, setUncontrolledEnabled] = useState(defaultEnabled);
178
+ const [threshold, setThreshold] = useState(defaultThresholdCents);
179
+ const [reloadAmount, setReloadAmount] = useState(defaultReloadAmountCents);
180
+ const enabled = controlledEnabled ?? uncontrolledEnabled;
181
+ const handleToggle = useCallback(
182
+ (next) => {
183
+ if (controlledEnabled === void 0) setUncontrolledEnabled(next);
184
+ onToggle?.(next);
185
+ },
186
+ [controlledEnabled, onToggle]
187
+ );
188
+ return {
189
+ enabled,
190
+ handleToggle,
191
+ reloadAmount: controlledReload ?? reloadAmount,
192
+ setReloadAmount,
193
+ setThreshold,
194
+ threshold: controlledThreshold ?? threshold
195
+ };
196
+ }
197
+ const DisabledBanner = forwardRef(
198
+ ({ className, message, ...rest }, ref) => /* @__PURE__ */ jsx(
199
+ "div",
200
+ {
201
+ "aria-disabled": "true",
202
+ className: cn(
203
+ "flex items-start gap-3 rounded-2xl border border-dashed border-border bg-muted/30 p-4 text-sm text-muted-foreground",
204
+ className
205
+ ),
206
+ ref,
207
+ ...rest,
208
+ children: message
209
+ }
210
+ )
211
+ );
212
+ DisabledBanner.displayName = "AutoReload.DisabledBanner";
213
+ const ActivePanel = forwardRef(
214
+ (props, ref) => {
215
+ const {
216
+ className,
217
+ controller,
218
+ currencyDisplay,
219
+ isSaving,
220
+ labels,
221
+ maxAmountCents,
222
+ minAmountCents,
223
+ onSave,
224
+ reloadAmountId,
225
+ stepCents,
226
+ thresholdId,
227
+ toggleId,
228
+ ...rest
229
+ } = props;
230
+ return /* @__PURE__ */ jsxs(
231
+ "div",
232
+ {
233
+ className: cn(
234
+ "flex flex-col gap-4 rounded-2xl border bg-background p-4",
235
+ className
236
+ ),
237
+ ref,
238
+ ...rest,
239
+ children: [
240
+ /* @__PURE__ */ jsx(
241
+ ToggleHeader,
242
+ {
243
+ enabled: controller.enabled,
244
+ heading: labels.heading,
245
+ helper: labels.helper,
246
+ id: toggleId,
247
+ onCheckedChange: controller.handleToggle
248
+ }
249
+ ),
250
+ controller.enabled ? /* @__PURE__ */ jsx(
251
+ ReloadFormFields,
252
+ {
253
+ currencyDisplay,
254
+ isSaving,
255
+ labels,
256
+ maxAmountCents,
257
+ minAmountCents,
258
+ onSave,
259
+ reloadAmount: controller.reloadAmount,
260
+ reloadAmountId,
261
+ setReloadAmount: controller.setReloadAmount,
262
+ setThreshold: controller.setThreshold,
263
+ stepCents,
264
+ threshold: controller.threshold,
265
+ thresholdId
266
+ }
267
+ ) : null
268
+ ]
269
+ }
270
+ );
271
+ }
272
+ );
273
+ ActivePanel.displayName = "AutoReload.ActivePanel";
274
+ function useAutoReloadInternals(props) {
275
+ const {
276
+ currency = DEFAULT_CURRENCY,
277
+ currencySymbol,
278
+ defaultEnabled = false,
279
+ defaultReloadAmountCents = 2e3,
280
+ defaultThresholdCents = 1e3,
281
+ enabled: controlledEnabled,
282
+ labels,
283
+ locale = DEFAULT_LOCALE,
284
+ onSave,
285
+ onToggle,
286
+ reloadAmountCents: controlledReload,
287
+ thresholdCents: controlledThreshold
288
+ } = props;
289
+ const resolvedLabels = useMemo(
290
+ () => ({ ...DEFAULT_LABELS, ...labels }),
291
+ [labels]
292
+ );
293
+ const toggleId = useId();
294
+ const thresholdId = useId();
295
+ const reloadAmountId = useId();
296
+ const controller = useAutoReloadController({
297
+ defaultEnabled,
298
+ defaultReloadAmountCents,
299
+ defaultThresholdCents,
300
+ enabled: controlledEnabled,
301
+ onToggle,
302
+ reloadAmountCents: controlledReload,
303
+ thresholdCents: controlledThreshold
304
+ });
305
+ const currencyDisplay = currencySymbol ?? getCurrencySymbol(locale, currency);
306
+ const handleSave = useCallback(() => {
307
+ onSave?.({
308
+ reloadAmountCents: controller.reloadAmount,
309
+ thresholdCents: controller.threshold
310
+ });
311
+ }, [controller.reloadAmount, controller.threshold, onSave]);
312
+ return {
313
+ controller,
314
+ currencyDisplay,
315
+ handleSave,
316
+ reloadAmountId,
317
+ resolvedLabels,
318
+ thresholdId,
319
+ toggleId
320
+ };
321
+ }
322
+ const AutoReload = forwardRef(
323
+ (props, ref) => {
324
+ const {
325
+ className,
326
+ disabled = false,
327
+ disabledMessage,
328
+ isSaving = false,
329
+ maxAmountCents,
330
+ minAmountCents = 100,
331
+ stepCents = DEFAULT_STEP_CENTS
332
+ } = props;
333
+ const internals = useAutoReloadInternals(props);
334
+ if (disabled) {
335
+ return /* @__PURE__ */ jsx(
336
+ DisabledBanner,
337
+ {
338
+ className,
339
+ message: disabledMessage ?? internals.resolvedLabels.disabledFallback,
340
+ ref
341
+ }
342
+ );
343
+ }
344
+ return /* @__PURE__ */ jsx(
345
+ ActivePanel,
346
+ {
347
+ className,
348
+ controller: internals.controller,
349
+ currencyDisplay: internals.currencyDisplay,
350
+ isSaving,
351
+ labels: internals.resolvedLabels,
352
+ maxAmountCents,
353
+ minAmountCents,
354
+ onSave: internals.handleSave,
355
+ ref,
356
+ reloadAmountId: internals.reloadAmountId,
357
+ stepCents,
358
+ thresholdId: internals.thresholdId,
359
+ toggleId: internals.toggleId
360
+ }
361
+ );
362
+ }
363
+ );
364
+ AutoReload.displayName = "AutoReload";
365
+ export {
366
+ AutoReload
367
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ AutoReload
3
+ } from "./auto-reload";
4
+ export {
5
+ AutoReload
6
+ };
@@ -0,0 +1,155 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import {
4
+ forwardRef,
5
+ useCallback,
6
+ useState,
7
+ useSyncExternalStore
8
+ } from "react";
9
+ import { Slot } from "@radix-ui/react-slot";
10
+ import { cva } from "class-variance-authority";
11
+ import { X } from "lucide-react";
12
+ import { cn } from "../../lib/utils";
13
+ const bannerVariants = cva(
14
+ "flex w-full items-start gap-3 border-b px-4 py-3 text-sm transition-all motion-safe:animate-in motion-safe:slide-in-from-top-1",
15
+ {
16
+ defaultVariants: {
17
+ variant: "info"
18
+ },
19
+ variants: {
20
+ variant: {
21
+ destructive: "border-destructive/50 bg-destructive/10 text-destructive dark:border-destructive [&_svg]:text-destructive",
22
+ info: "border-border bg-muted text-foreground [&_svg]:text-muted-foreground",
23
+ success: "border-emerald-500/40 bg-emerald-500/10 text-emerald-900 dark:text-emerald-200 [&_svg]:text-emerald-600 dark:[&_svg]:text-emerald-300",
24
+ warning: "border-amber-500/40 bg-amber-500/10 text-amber-900 dark:text-amber-200 [&_svg]:text-amber-600 dark:[&_svg]:text-amber-300"
25
+ }
26
+ }
27
+ }
28
+ );
29
+ const URGENT_VARIANTS = /* @__PURE__ */ new Set([
30
+ "destructive",
31
+ "warning"
32
+ ]);
33
+ const STORAGE_PREFIX = "vllnt-ui:banner-dismissed:";
34
+ function safeStorageGet(key) {
35
+ if (typeof window === "undefined") return null;
36
+ try {
37
+ return window.localStorage.getItem(key);
38
+ } catch {
39
+ return null;
40
+ }
41
+ }
42
+ function safeStorageSet(key, value) {
43
+ if (typeof window === "undefined") return;
44
+ try {
45
+ window.localStorage.setItem(key, value);
46
+ } catch {
47
+ return;
48
+ }
49
+ }
50
+ function subscribeToStorage(callback) {
51
+ if (typeof window === "undefined") {
52
+ return () => {
53
+ return;
54
+ };
55
+ }
56
+ window.addEventListener("storage", callback);
57
+ return () => {
58
+ window.removeEventListener("storage", callback);
59
+ };
60
+ }
61
+ function usePersistedDismissed(storageKey) {
62
+ const getClientSnapshot = useCallback(() => {
63
+ if (!storageKey) return false;
64
+ return safeStorageGet(storageKey) === "1";
65
+ }, [storageKey]);
66
+ const getServerSnapshot = useCallback(() => false, []);
67
+ return useSyncExternalStore(
68
+ subscribeToStorage,
69
+ getClientSnapshot,
70
+ getServerSnapshot
71
+ );
72
+ }
73
+ const Banner = forwardRef(
74
+ ({
75
+ children,
76
+ className,
77
+ dismissible = false,
78
+ dismissLabel = "Dismiss",
79
+ icon,
80
+ id,
81
+ onDismiss,
82
+ persistDismissal = false,
83
+ role: roleOverride,
84
+ variant,
85
+ ...rest
86
+ }, ref) => {
87
+ const storageKey = persistDismissal && id ? `${STORAGE_PREFIX}${id}` : void 0;
88
+ const persistedDismissed = usePersistedDismissed(storageKey);
89
+ const [locallyDismissed, setLocallyDismissed] = useState(false);
90
+ const handleDismiss = useCallback(() => {
91
+ setLocallyDismissed(true);
92
+ if (storageKey) safeStorageSet(storageKey, "1");
93
+ onDismiss?.();
94
+ }, [onDismiss, storageKey]);
95
+ if (locallyDismissed || persistedDismissed) return null;
96
+ const resolvedVariant = variant ?? "info";
97
+ const role = roleOverride ?? (URGENT_VARIANTS.has(resolvedVariant) ? "alert" : "status");
98
+ return /* @__PURE__ */ jsxs(
99
+ "div",
100
+ {
101
+ className: cn(bannerVariants({ variant }), className),
102
+ id,
103
+ ref,
104
+ role,
105
+ ...rest,
106
+ children: [
107
+ icon ? /* @__PURE__ */ jsx(
108
+ "span",
109
+ {
110
+ "aria-hidden": "true",
111
+ className: "mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center [&>svg]:h-4 [&>svg]:w-4",
112
+ children: icon
113
+ }
114
+ ) : null,
115
+ /* @__PURE__ */ jsx("div", { className: "flex min-w-0 flex-1 flex-wrap items-center gap-x-3 gap-y-1", children }),
116
+ dismissible ? /* @__PURE__ */ jsx(
117
+ "button",
118
+ {
119
+ "aria-label": dismissLabel,
120
+ className: "ml-auto inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-md opacity-70 transition-colors hover:bg-foreground/10 hover:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
121
+ onClick: handleDismiss,
122
+ type: "button",
123
+ children: /* @__PURE__ */ jsx(X, { "aria-hidden": "true", className: "h-4 w-4" })
124
+ }
125
+ ) : null
126
+ ]
127
+ }
128
+ );
129
+ }
130
+ );
131
+ Banner.displayName = "Banner";
132
+ const BannerAction = forwardRef(
133
+ ({ asChild = false, children, className, type, ...rest }, ref) => {
134
+ const Comp = asChild ? Slot : "button";
135
+ const buttonProps = asChild ? rest : { type: type ?? "button", ...rest };
136
+ return /* @__PURE__ */ jsx(
137
+ Comp,
138
+ {
139
+ className: cn(
140
+ "inline-flex h-7 items-center justify-center rounded-md border border-foreground/20 bg-transparent px-3 text-xs font-medium underline-offset-4 transition-colors hover:bg-foreground/10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
141
+ className
142
+ ),
143
+ ref,
144
+ ...buttonProps,
145
+ children
146
+ }
147
+ );
148
+ }
149
+ );
150
+ BannerAction.displayName = "BannerAction";
151
+ export {
152
+ Banner,
153
+ BannerAction,
154
+ bannerVariants
155
+ };
@@ -0,0 +1,10 @@
1
+ import {
2
+ Banner,
3
+ BannerAction,
4
+ bannerVariants
5
+ } from "./banner";
6
+ export {
7
+ Banner,
8
+ BannerAction,
9
+ bannerVariants
10
+ };