@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,66 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useState } from "react";
4
+ import { RefreshCcw } from "lucide-react";
5
+ import { cn } from "../../lib/utils";
6
+ import { Badge } from "../badge";
7
+ import { Button } from "../button";
8
+ import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "../card";
9
+ function Flashcard({
10
+ answer,
11
+ category,
12
+ className,
13
+ defaultFlipped = false,
14
+ hint,
15
+ onFlipChange,
16
+ question,
17
+ title = "Flashcard"
18
+ }) {
19
+ const [flipped, setFlipped] = useState(defaultFlipped);
20
+ const toggleFlipped = () => {
21
+ const nextValue = !flipped;
22
+ setFlipped(nextValue);
23
+ onFlipChange?.(nextValue);
24
+ };
25
+ return /* @__PURE__ */ jsxs(
26
+ Card,
27
+ {
28
+ className: cn(
29
+ "my-6 overflow-hidden border-primary/20 bg-gradient-to-br from-card to-primary/5",
30
+ className
31
+ ),
32
+ children: [
33
+ /* @__PURE__ */ jsxs(CardHeader, { className: "flex flex-row items-center justify-between gap-3 border-b bg-background/80", children: [
34
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
35
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
36
+ /* @__PURE__ */ jsx(Badge, { variant: "secondary", children: "Study" }),
37
+ category ? /* @__PURE__ */ jsx(Badge, { variant: "outline", children: category }) : null
38
+ ] }),
39
+ /* @__PURE__ */ jsx(CardTitle, { children: title })
40
+ ] }),
41
+ /* @__PURE__ */ jsxs(Button, { onClick: toggleFlipped, size: "sm", variant: "outline", children: [
42
+ /* @__PURE__ */ jsx(RefreshCcw, { className: "mr-2 h-4 w-4" }),
43
+ "Flip"
44
+ ] })
45
+ ] }),
46
+ /* @__PURE__ */ jsxs(CardContent, { className: "space-y-4 p-6", children: [
47
+ /* @__PURE__ */ jsxs("div", { className: "min-h-40 rounded-xl border bg-background p-6 shadow-sm", children: [
48
+ /* @__PURE__ */ jsx("p", { className: "mb-2 text-xs font-medium uppercase tracking-[0.2em] text-muted-foreground", children: flipped ? "Answer" : "Prompt" }),
49
+ /* @__PURE__ */ jsx("div", { className: "text-base text-foreground [&>p]:mb-3", children: flipped ? answer : question })
50
+ ] }),
51
+ hint ? /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground", children: [
52
+ "Hint: ",
53
+ hint
54
+ ] }) : null
55
+ ] }),
56
+ /* @__PURE__ */ jsxs(CardFooter, { className: "justify-between border-t bg-background/80 px-6 py-4", children: [
57
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: flipped ? "Use this side to check your recall." : "Try answering before flipping the card." }),
58
+ /* @__PURE__ */ jsx(Button, { onClick: toggleFlipped, variant: "ghost", children: flipped ? "Show prompt" : "Reveal answer" })
59
+ ] })
60
+ ]
61
+ }
62
+ );
63
+ }
64
+ export {
65
+ Flashcard
66
+ };
@@ -0,0 +1,4 @@
1
+ import { Flashcard } from "./flashcard";
2
+ export {
3
+ Flashcard
4
+ };
@@ -24,6 +24,8 @@ import {
24
24
  CommandSeparator,
25
25
  CommandShortcut
26
26
  } from "./command";
27
+ import { Combobox } from "./combobox";
28
+ import { DatePicker } from "./date-picker";
27
29
  import {
28
30
  Dialog,
29
31
  DialogClose,
@@ -55,7 +57,10 @@ import {
55
57
  } from "./dropdown-menu";
56
58
  import { Input } from "./input";
57
59
  import { Checkbox } from "./checkbox";
60
+ import { FileUpload } from "./file-upload";
58
61
  import { Label } from "./label";
62
+ import { NumberInput } from "./number-input";
63
+ import { PasswordInput } from "./password-input";
59
64
  import { Switch } from "./switch";
60
65
  import {
61
66
  toast,
@@ -66,6 +71,19 @@ import {
66
71
  Toaster,
67
72
  ToastTitle
68
73
  } from "./toast";
74
+ import { AIChatInput } from "./ai-chat-input";
75
+ import {
76
+ AIMessageBubble
77
+ } from "./ai-message-bubble";
78
+ import {
79
+ AISourceCitation
80
+ } from "./ai-source-citation";
81
+ import {
82
+ AIStreamingText
83
+ } from "./ai-streaming-text";
84
+ import {
85
+ AIToolCallDisplay
86
+ } from "./ai-tool-call-display";
69
87
  import { Textarea } from "./textarea";
70
88
  import {
71
89
  Select,
@@ -185,6 +203,17 @@ import {
185
203
  navigationMenuTriggerStyle,
186
204
  NavigationMenuViewport
187
205
  } from "./navigation-menu";
206
+ import {
207
+ DataTable
208
+ } from "./data-table";
209
+ import {
210
+ DataList,
211
+ DataListItem,
212
+ dataListItemVariants,
213
+ DataListLabel,
214
+ DataListValue,
215
+ dataListVariants
216
+ } from "./data-list";
188
217
  import {
189
218
  Table,
190
219
  TableBody,
@@ -196,9 +225,20 @@ import {
196
225
  TableRow
197
226
  } from "./table";
198
227
  import { Avatar, AvatarFallback, AvatarImage } from "./avatar";
228
+ import {
229
+ AvatarGroup,
230
+ avatarGroupVariants,
231
+ avatarItemVariants
232
+ } from "./avatar-group";
199
233
  import { Skeleton } from "./skeleton";
200
234
  import { Separator } from "./separator";
201
235
  import { Alert, AlertDescription, AlertTitle, alertVariants } from "./alert";
236
+ import { StatCard, statCardVariants } from "./stat-card";
237
+ import {
238
+ dotVariants,
239
+ StatusIndicator,
240
+ statusIndicatorVariants
241
+ } from "./status-indicator";
202
242
  import { AspectRatio } from "./aspect-ratio";
203
243
  import { ScrollArea, ScrollBar } from "./scroll-area";
204
244
  import {
@@ -218,8 +258,21 @@ import {
218
258
  CarouselNext,
219
259
  CarouselPrevious
220
260
  } from "./carousel";
261
+ import { BorderBeam } from "./border-beam";
262
+ import {
263
+ ActivityHeatmap
264
+ } from "./activity-heatmap";
221
265
  import { Calendar } from "./calendar";
222
- import { Spinner } from "./spinner";
266
+ import { CountdownTimer } from "./countdown-timer";
267
+ import { Marquee } from "./marquee";
268
+ import { NumberTicker } from "./number-ticker";
269
+ import {
270
+ Spinner,
271
+ UnicodeSpinner
272
+ } from "./spinner";
273
+ import {
274
+ WorldClockBar
275
+ } from "./world-clock-bar";
223
276
  import { CodeBlock } from "./code-block";
224
277
  import { MDXContent } from "./mdx-content";
225
278
  import {
@@ -229,10 +282,19 @@ import {
229
282
  import { Sidebar } from "./sidebar";
230
283
  import { SidebarProvider, useSidebar } from "./sidebar-provider";
231
284
  import { TableOfContents } from "./table-of-contents";
285
+ import {
286
+ ActivityLog
287
+ } from "./activity-log";
232
288
  import { BlogCard, ContentCard } from "./blog-card";
233
289
  import { CategoryFilter } from "./category-filter";
234
290
  import { Pagination } from "./pagination";
235
291
  import { SearchBar } from "./search-bar";
292
+ import {
293
+ ScopeSelector
294
+ } from "./scope-selector";
295
+ import {
296
+ UsageBreakdown
297
+ } from "./usage-breakdown";
236
298
  import {
237
299
  ShareSection
238
300
  } from "./share-section";
@@ -240,10 +302,53 @@ import { SearchDialog } from "./search-dialog";
240
302
  import { LangProvider } from "./lang-provider";
241
303
  import { ThemeProvider } from "./theme-provider";
242
304
  import { ThemeToggle } from "./theme-toggle";
305
+ import {
306
+ CandlestickChart
307
+ } from "./candlestick-chart";
308
+ import {
309
+ CreditBadge
310
+ } from "./credit-badge";
311
+ import {
312
+ MarketTreemap
313
+ } from "./market-treemap";
314
+ import {
315
+ OrderBook
316
+ } from "./order-book";
243
317
  import { ProfileSection } from "./profile-section";
318
+ import {
319
+ PlanBadge
320
+ } from "./plan-badge";
321
+ import {
322
+ RoleBadge
323
+ } from "./role-badge";
324
+ import {
325
+ SparklineGrid
326
+ } from "./sparkline-grid";
327
+ import {
328
+ SubscriptionCard
329
+ } from "./subscription-card";
244
330
  import { TLDRSection } from "./tldr-section";
331
+ import {
332
+ TickerTape
333
+ } from "./ticker-tape";
334
+ import { WalletCard } from "./wallet-card";
335
+ import {
336
+ Watchlist
337
+ } from "./watchlist";
245
338
  import { BarChart, LineChart } from "./chart";
246
339
  import { AreaChart } from "./chart";
340
+ import { LiveFeed } from "./live-feed";
341
+ import {
342
+ MetricGauge
343
+ } from "./metric-gauge";
344
+ import {
345
+ SeverityBadge,
346
+ severityBadgeVariants
347
+ } from "./severity-badge";
348
+ import {
349
+ StatusBoard
350
+ } from "./status-board";
351
+ import { AnimatedText } from "./animated-text";
247
352
  import { TruncatedText } from "./truncated-text";
248
353
  import {
249
354
  Accordion,
@@ -252,6 +357,10 @@ import {
252
357
  AccordionTrigger
253
358
  } from "./accordion";
254
359
  import { Callout } from "./callout";
360
+ import {
361
+ Annotation,
362
+ Highlight
363
+ } from "./annotation";
255
364
  import {
256
365
  Checklist
257
366
  } from "./checklist";
@@ -265,6 +374,7 @@ import {
265
374
  } from "./comparison";
266
375
  import { Exercise } from "./exercise";
267
376
  import { FAQ, FAQItem } from "./faq";
377
+ import { Flashcard } from "./flashcard";
268
378
  import {
269
379
  Glossary,
270
380
  KeyConcept
@@ -280,10 +390,12 @@ import {
280
390
  ProTip
281
391
  } from "./pro-tip";
282
392
  import { Quiz } from "./quiz";
393
+ import { Rating } from "./rating";
283
394
  import {
284
395
  Step,
285
396
  StepByStep
286
397
  } from "./step-by-step";
398
+ import { Stepper } from "./stepper";
287
399
  import {
288
400
  Tabs,
289
401
  TabsContent,
@@ -311,6 +423,7 @@ import {
311
423
  mdxComponents,
312
424
  TutorialMDX
313
425
  } from "./tutorial-mdx";
426
+ import { Tour } from "./tour";
314
427
  import {
315
428
  CompletionDialog
316
429
  } from "./completion-dialog";
@@ -360,10 +473,17 @@ import {
360
473
  import { SidebarToggle } from "./sidebar-toggle";
361
474
  import { ThinkingBlock } from "./thinking-block";
362
475
  export {
476
+ AIChatInput,
477
+ AIMessageBubble,
478
+ AISourceCitation,
479
+ AIStreamingText,
480
+ AIToolCallDisplay,
363
481
  Accordion,
364
482
  AccordionContent,
365
483
  AccordionItem,
366
484
  AccordionTrigger,
485
+ ActivityHeatmap,
486
+ ActivityLog,
367
487
  Alert,
368
488
  AlertDescription,
369
489
  AlertDialog,
@@ -378,19 +498,24 @@ export {
378
498
  AlertDialogTitle,
379
499
  AlertDialogTrigger,
380
500
  AlertTitle,
501
+ AnimatedText,
502
+ Annotation,
381
503
  AreaChart,
382
504
  AspectRatio,
383
505
  Avatar,
384
506
  AvatarFallback,
507
+ AvatarGroup,
385
508
  AvatarImage,
386
509
  Badge,
387
510
  BarChart,
388
511
  BeforeAfter,
389
512
  BlogCard,
513
+ BorderBeam,
390
514
  Breadcrumb,
391
515
  Button,
392
516
  Calendar,
393
517
  Callout,
518
+ CandlestickChart,
394
519
  Card,
395
520
  CardContent,
396
521
  CardDescription,
@@ -410,6 +535,7 @@ export {
410
535
  Collapsible,
411
536
  CollapsibleContent,
412
537
  CollapsibleTrigger,
538
+ Combobox,
413
539
  Command,
414
540
  CommandDialog,
415
541
  CommandEmpty,
@@ -440,6 +566,14 @@ export {
440
566
  ContextMenuSubTrigger,
441
567
  ContextMenuTrigger,
442
568
  CookieConsent,
569
+ CountdownTimer,
570
+ CreditBadge,
571
+ DataList,
572
+ DataListItem,
573
+ DataListLabel,
574
+ DataListValue,
575
+ DataTable,
576
+ DatePicker,
443
577
  Dialog,
444
578
  DialogClose,
445
579
  DialogContent,
@@ -479,13 +613,16 @@ export {
479
613
  FAQ,
480
614
  FAQItem,
481
615
  FileTree,
616
+ FileUpload,
482
617
  FilterBar,
618
+ Flashcard,
483
619
  FloatingActionButton,
484
620
  FlowControls,
485
621
  FlowDiagram,
486
622
  FlowErrorBoundary,
487
623
  FlowFullscreen,
488
624
  Glossary,
625
+ Highlight,
489
626
  HorizontalScrollRow,
490
627
  HoverCard,
491
628
  HoverCardContent,
@@ -502,7 +639,10 @@ export {
502
639
  LangProvider,
503
640
  LearningObjectives,
504
641
  LineChart,
642
+ LiveFeed,
505
643
  MDXContent,
644
+ MarketTreemap,
645
+ Marquee,
506
646
  Menubar,
507
647
  MenubarCheckboxItem,
508
648
  MenubarContent,
@@ -519,6 +659,7 @@ export {
519
659
  MenubarSubContent,
520
660
  MenubarSubTrigger,
521
661
  MenubarTrigger,
662
+ MetricGauge,
522
663
  ModelSelector,
523
664
  NavbarSaas,
524
665
  NavigationMenu,
@@ -529,7 +670,12 @@ export {
529
670
  NavigationMenuList,
530
671
  NavigationMenuTrigger,
531
672
  NavigationMenuViewport,
673
+ NumberInput,
674
+ NumberTicker,
675
+ OrderBook,
532
676
  Pagination,
677
+ PasswordInput,
678
+ PlanBadge,
533
679
  Popover,
534
680
  PopoverAnchor,
535
681
  PopoverContent,
@@ -541,9 +687,12 @@ export {
541
687
  Quiz,
542
688
  RadioGroup,
543
689
  RadioGroupItem,
690
+ Rating,
544
691
  ResizableHandle,
545
692
  ResizablePanel,
546
693
  ResizablePanelGroup,
694
+ RoleBadge,
695
+ ScopeSelector,
547
696
  ScrollArea,
548
697
  ScrollBar,
549
698
  SearchBar,
@@ -559,6 +708,7 @@ export {
559
708
  SelectTrigger,
560
709
  SelectValue,
561
710
  Separator,
711
+ SeverityBadge,
562
712
  ShareDialog,
563
713
  ShareSection,
564
714
  Sheet,
@@ -579,10 +729,16 @@ export {
579
729
  Slider,
580
730
  Slideshow,
581
731
  SocialFAB,
732
+ SparklineGrid,
582
733
  Spinner,
734
+ StatCard,
735
+ StatusBoard,
736
+ StatusIndicator,
583
737
  Step,
584
738
  StepByStep,
585
739
  StepNavigation,
740
+ Stepper,
741
+ SubscriptionCard,
586
742
  Summary,
587
743
  Switch,
588
744
  TLDRSection,
@@ -605,6 +761,7 @@ export {
605
761
  ThemeProvider,
606
762
  ThemeToggle,
607
763
  ThinkingBlock,
764
+ TickerTape,
608
765
  Toast,
609
766
  ToastAction,
610
767
  ToastClose,
@@ -618,20 +775,34 @@ export {
618
775
  TooltipContent,
619
776
  TooltipProvider,
620
777
  TooltipTrigger,
778
+ Tour,
621
779
  TruncatedText,
622
780
  TutorialCard,
623
781
  TutorialComplete,
624
782
  TutorialFilters,
625
783
  TutorialIntroContent,
626
784
  TutorialMDX,
785
+ UnicodeSpinner,
786
+ UsageBreakdown,
627
787
  VideoEmbed,
628
788
  ViewSwitcher,
789
+ WalletCard,
790
+ Watchlist,
791
+ WorldClockBar,
629
792
  alertVariants,
793
+ avatarGroupVariants,
794
+ avatarItemVariants,
630
795
  badgeVariants,
631
796
  buttonVariants,
632
797
  cookieConsentVariants,
798
+ dataListItemVariants,
799
+ dataListVariants,
800
+ dotVariants,
633
801
  mdxComponents,
634
802
  navigationMenuTriggerStyle,
803
+ severityBadgeVariants,
804
+ statCardVariants,
805
+ statusIndicatorVariants,
635
806
  toast,
636
807
  toggleVariants,
637
808
  useFlowDiagram,
@@ -0,0 +1,4 @@
1
+ import { LiveFeed } from "./live-feed";
2
+ export {
3
+ LiveFeed
4
+ };
@@ -0,0 +1,168 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { cn } from "../../lib/utils";
5
+ import { Badge } from "../badge";
6
+ import {
7
+ Card,
8
+ CardContent,
9
+ CardDescription,
10
+ CardHeader,
11
+ CardTitle
12
+ } from "../card";
13
+ import {
14
+ SeverityBadge
15
+ } from "../severity-badge/severity-badge";
16
+ const SECOND_MS = 1e3;
17
+ const MINUTE_MS = 60 * SECOND_MS;
18
+ const HOUR_MS = 60 * MINUTE_MS;
19
+ const DAY_MS = 24 * HOUR_MS;
20
+ function normalizeDate(input) {
21
+ if (input instanceof Date) {
22
+ return new Date(input.getTime());
23
+ }
24
+ return new Date(input);
25
+ }
26
+ function useLiveDate(now, tickMs) {
27
+ const fixedNow = React.useMemo(
28
+ () => now ? normalizeDate(now) : void 0,
29
+ [now]
30
+ );
31
+ const [liveNow, setLiveNow] = React.useState(fixedNow ?? /* @__PURE__ */ new Date());
32
+ React.useEffect(() => {
33
+ if (fixedNow) {
34
+ setLiveNow(fixedNow);
35
+ return;
36
+ }
37
+ const interval = window.setInterval(() => {
38
+ setLiveNow(/* @__PURE__ */ new Date());
39
+ }, tickMs);
40
+ return () => {
41
+ window.clearInterval(interval);
42
+ };
43
+ }, [fixedNow, tickMs]);
44
+ return liveNow;
45
+ }
46
+ function formatRelative(eventDate, now) {
47
+ const deltaMs = now.getTime() - eventDate.getTime();
48
+ if (deltaMs < 5 * SECOND_MS) {
49
+ return "just now";
50
+ }
51
+ if (deltaMs < MINUTE_MS) {
52
+ return `${Math.floor(deltaMs / SECOND_MS)}s ago`;
53
+ }
54
+ if (deltaMs < HOUR_MS) {
55
+ return `${Math.floor(deltaMs / MINUTE_MS)}m ago`;
56
+ }
57
+ if (deltaMs < DAY_MS) {
58
+ return `${Math.floor(deltaMs / HOUR_MS)}h ago`;
59
+ }
60
+ if (deltaMs < 7 * DAY_MS) {
61
+ return `${Math.floor(deltaMs / DAY_MS)}d ago`;
62
+ }
63
+ return new Intl.DateTimeFormat("en-US", {
64
+ day: "numeric",
65
+ month: "short"
66
+ }).format(eventDate);
67
+ }
68
+ function formatAbsolute(eventDate) {
69
+ return new Intl.DateTimeFormat("en-US", {
70
+ hour: "numeric",
71
+ minute: "2-digit",
72
+ month: "short",
73
+ second: "2-digit"
74
+ }).format(eventDate);
75
+ }
76
+ function sortEventsDesc(events) {
77
+ return [...events].sort(
78
+ (a, b) => normalizeDate(b.timestamp).getTime() - normalizeDate(a.timestamp).getTime()
79
+ );
80
+ }
81
+ function LiveFeedRow({
82
+ event,
83
+ isLatest,
84
+ now
85
+ }) {
86
+ const eventDate = normalizeDate(event.timestamp);
87
+ return /* @__PURE__ */ jsxs("li", { className: "flex gap-3 border-b border-border/60 py-3 last:border-b-0", children: [
88
+ /* @__PURE__ */ jsx("div", { className: "pt-1", children: /* @__PURE__ */ jsx(
89
+ SeverityBadge,
90
+ {
91
+ level: event.severity,
92
+ pulse: isLatest ? event.severity === "critical" : void 0,
93
+ tone: "soft"
94
+ }
95
+ ) }),
96
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
97
+ /* @__PURE__ */ jsxs("div", { className: "flex items-baseline justify-between gap-2", children: [
98
+ /* @__PURE__ */ jsx("p", { className: "truncate text-sm font-medium", children: event.title }),
99
+ /* @__PURE__ */ jsx(
100
+ "time",
101
+ {
102
+ className: "whitespace-nowrap text-xs text-muted-foreground",
103
+ dateTime: eventDate.toISOString(),
104
+ title: formatAbsolute(eventDate),
105
+ children: formatRelative(eventDate, now)
106
+ }
107
+ )
108
+ ] }),
109
+ event.message ? /* @__PURE__ */ jsx("p", { className: "mt-0.5 text-sm text-muted-foreground", children: event.message }) : null,
110
+ event.source ? /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs uppercase tracking-[0.14em] text-muted-foreground", children: event.source }) : null
111
+ ] })
112
+ ] });
113
+ }
114
+ const LiveFeed = React.forwardRef(
115
+ ({
116
+ className,
117
+ description,
118
+ emptyLabel = "No events yet",
119
+ events,
120
+ maxItems = 50,
121
+ now,
122
+ tickMs = 3e4,
123
+ title = "Live feed",
124
+ ...props
125
+ }, ref) => {
126
+ const liveNow = useLiveDate(now, tickMs);
127
+ const visibleEvents = React.useMemo(
128
+ () => sortEventsDesc(events).slice(0, maxItems),
129
+ [events, maxItems]
130
+ );
131
+ return /* @__PURE__ */ jsxs(Card, { className: cn("shadow-sm", className), ref, ...props, children: [
132
+ /* @__PURE__ */ jsxs(CardHeader, { className: "flex flex-row items-start justify-between gap-3 space-y-0 pb-3", children: [
133
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
134
+ /* @__PURE__ */ jsx(CardTitle, { className: "text-base", children: title }),
135
+ description ? /* @__PURE__ */ jsx(CardDescription, { children: description }) : null
136
+ ] }),
137
+ /* @__PURE__ */ jsxs(Badge, { variant: "outline", children: [
138
+ /* @__PURE__ */ jsxs(
139
+ "span",
140
+ {
141
+ "aria-hidden": "true",
142
+ className: "relative mr-1.5 inline-flex h-2 w-2",
143
+ children: [
144
+ /* @__PURE__ */ jsx("span", { className: "absolute inline-flex h-2 w-2 animate-ping rounded-full bg-emerald-500 opacity-70" }),
145
+ /* @__PURE__ */ jsx("span", { className: "relative inline-flex h-2 w-2 rounded-full bg-emerald-500" })
146
+ ]
147
+ }
148
+ ),
149
+ " ",
150
+ "Live"
151
+ ] })
152
+ ] }),
153
+ /* @__PURE__ */ jsx(CardContent, { className: "pt-0", children: visibleEvents.length === 0 ? /* @__PURE__ */ jsx("div", { className: "py-8 text-center text-sm text-muted-foreground", children: emptyLabel }) : /* @__PURE__ */ jsx("ul", { className: "max-h-[360px] divide-y divide-border/60 overflow-y-auto", children: visibleEvents.map((event, index) => /* @__PURE__ */ jsx(
154
+ LiveFeedRow,
155
+ {
156
+ event,
157
+ isLatest: index === 0,
158
+ now: liveNow
159
+ },
160
+ event.id
161
+ )) }) })
162
+ ] });
163
+ }
164
+ );
165
+ LiveFeed.displayName = "LiveFeed";
166
+ export {
167
+ LiveFeed
168
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ MarketTreemap
3
+ } from "./market-treemap";
4
+ export {
5
+ MarketTreemap
6
+ };