@vllnt/ui 0.2.0 → 0.2.1-canary.4abeac1

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 (66) hide show
  1. package/CHANGELOG.md +12 -1
  2. package/README.md +27 -12
  3. package/dist/components/activity-log/activity-log.js +1 -0
  4. package/dist/components/anchor-port/anchor-port.js +51 -0
  5. package/dist/components/anchor-port/index.js +4 -0
  6. package/dist/components/animated-text/animated-text.js +1 -0
  7. package/dist/components/bottom-bar/bottom-bar.js +25 -0
  8. package/dist/components/bottom-bar/index.js +4 -0
  9. package/dist/components/canvas-shell/canvas-foundation-demo.js +183 -0
  10. package/dist/components/canvas-shell/canvas-shell-route-config.js +0 -0
  11. package/dist/components/canvas-shell/canvas-shell.js +261 -0
  12. package/dist/components/canvas-shell/index.js +4 -0
  13. package/dist/components/canvas-view/canvas-view.js +461 -0
  14. package/dist/components/canvas-view/index.js +6 -0
  15. package/dist/components/chart/area-chart.js +1 -0
  16. package/dist/components/chart/line-chart.js +1 -0
  17. package/dist/components/chat-dock-section/chat-dock-section.js +56 -0
  18. package/dist/components/chat-dock-section/index.js +6 -0
  19. package/dist/components/checklist/checklist.js +7 -0
  20. package/dist/components/checklist/index.js +3 -1
  21. package/dist/components/connector-edge/connector-edge.js +66 -0
  22. package/dist/components/connector-edge/index.js +6 -0
  23. package/dist/components/conversation-thread/conversation-thread.js +348 -0
  24. package/dist/components/conversation-thread/index.js +20 -0
  25. package/dist/components/curriculum/curriculum.js +349 -0
  26. package/dist/components/curriculum/index.js +10 -0
  27. package/dist/components/data-list/data-list.js +1 -0
  28. package/dist/components/edge-label/edge-label.js +26 -0
  29. package/dist/components/edge-label/index.js +4 -0
  30. package/dist/components/form/form.js +432 -0
  31. package/dist/components/form/index.js +20 -0
  32. package/dist/components/glass-panel/glass-panel.js +21 -0
  33. package/dist/components/glass-panel/index.js +4 -0
  34. package/dist/components/group-hull/group-hull.js +29 -0
  35. package/dist/components/group-hull/index.js +4 -0
  36. package/dist/components/index.js +136 -0
  37. package/dist/components/left-rail/index.js +4 -0
  38. package/dist/components/left-rail/left-rail.js +25 -0
  39. package/dist/components/mini-map-panel/index.js +6 -0
  40. package/dist/components/mini-map-panel/mini-map-panel.js +74 -0
  41. package/dist/components/multi-select/index.js +6 -0
  42. package/dist/components/multi-select/multi-select.js +258 -0
  43. package/dist/components/object-card/index.js +6 -0
  44. package/dist/components/object-card/object-card.js +126 -0
  45. package/dist/components/object-handle/index.js +4 -0
  46. package/dist/components/object-handle/object-handle.js +38 -0
  47. package/dist/components/overview-board/index.js +8 -0
  48. package/dist/components/overview-board/overview-board.js +127 -0
  49. package/dist/components/progress-tracker/index.js +20 -0
  50. package/dist/components/progress-tracker/progress-tracker.js +527 -0
  51. package/dist/components/right-dock/index.js +4 -0
  52. package/dist/components/right-dock/right-dock.js +28 -0
  53. package/dist/components/segmented-control/index.js +12 -0
  54. package/dist/components/segmented-control/segmented-control.js +61 -0
  55. package/dist/components/spinner/unicode-spinner.js +1 -0
  56. package/dist/components/tags-input/index.js +4 -0
  57. package/dist/components/tags-input/tags-input.js +178 -0
  58. package/dist/components/top-bar/index.js +4 -0
  59. package/dist/components/top-bar/top-bar.js +31 -0
  60. package/dist/components/usage-breakdown/usage-breakdown.js +1 -0
  61. package/dist/components/workspace-switcher/index.js +6 -0
  62. package/dist/components/workspace-switcher/workspace-switcher.js +61 -0
  63. package/dist/components/zoom-hud/index.js +4 -0
  64. package/dist/components/zoom-hud/zoom-hud.js +61 -0
  65. package/dist/index.d.ts +686 -5
  66. package/package.json +7 -3
@@ -62,6 +62,26 @@ import { Label } from "./label";
62
62
  import { NumberInput } from "./number-input";
63
63
  import { PasswordInput } from "./password-input";
64
64
  import { Switch } from "./switch";
65
+ import {
66
+ Form,
67
+ FormControl,
68
+ FormDescription,
69
+ FormField,
70
+ FormItem,
71
+ FormLabel,
72
+ FormMessage,
73
+ useFormField
74
+ } from "./form";
75
+ import {
76
+ MultiSelect
77
+ } from "./multi-select";
78
+ import { TagsInput } from "./tags-input";
79
+ import {
80
+ SegmentedControl,
81
+ SegmentedControlItem,
82
+ segmentedControlItemVariants,
83
+ segmentedControlVariants
84
+ } from "./segmented-control";
65
85
  import {
66
86
  toast,
67
87
  Toast,
@@ -275,13 +295,35 @@ import {
275
295
  } from "./world-clock-bar";
276
296
  import { CodeBlock } from "./code-block";
277
297
  import { MDXContent } from "./mdx-content";
298
+ import {
299
+ CanvasShell
300
+ } from "./canvas-shell";
301
+ import {
302
+ CanvasView
303
+ } from "./canvas-view";
304
+ import { BottomBar } from "./bottom-bar";
305
+ import {
306
+ ChatDockSection
307
+ } from "./chat-dock-section";
308
+ import { GlassPanel } from "./glass-panel";
309
+ import { LeftRail } from "./left-rail";
310
+ import {
311
+ MiniMapPanel
312
+ } from "./mini-map-panel";
313
+ import {
314
+ OverviewBoard,
315
+ OverviewCard
316
+ } from "./overview-board";
278
317
  import {
279
318
  NavbarSaas,
280
319
  useMobile
281
320
  } from "./navbar-saas";
321
+ import { RightDock } from "./right-dock";
282
322
  import { Sidebar } from "./sidebar";
283
323
  import { SidebarProvider, useSidebar } from "./sidebar-provider";
284
324
  import { TableOfContents } from "./table-of-contents";
325
+ import { TopBar } from "./top-bar";
326
+ import { ZoomHUD } from "./zoom-hud";
285
327
  import {
286
328
  ActivityLog
287
329
  } from "./activity-log";
@@ -384,7 +426,25 @@ import {
384
426
  Prerequisites,
385
427
  Summary
386
428
  } from "./learning-objectives";
429
+ import {
430
+ Curriculum,
431
+ CurriculumLesson,
432
+ CurriculumModule
433
+ } from "./curriculum";
387
434
  import { ProgressBar } from "./progress-bar";
435
+ import {
436
+ ProgressCard
437
+ } from "./progress-card";
438
+ import {
439
+ ProgressTracker,
440
+ ProgressTrackerBadge,
441
+ ProgressTrackerModule,
442
+ ProgressTrackerModules,
443
+ ProgressTrackerOverview,
444
+ ProgressTrackerStat,
445
+ ProgressTrackerStats,
446
+ useProgressTrackerContext
447
+ } from "./progress-tracker";
388
448
  import {
389
449
  CommonMistake,
390
450
  ProTip
@@ -459,6 +519,9 @@ import {
459
519
  import {
460
520
  ViewSwitcher
461
521
  } from "./view-switcher";
522
+ import {
523
+ WorkspaceSwitcher
524
+ } from "./workspace-switcher";
462
525
  import {
463
526
  FlowControls,
464
527
  FlowDiagram,
@@ -466,6 +529,26 @@ import {
466
529
  FlowFullscreen,
467
530
  useFlowDiagram
468
531
  } from "./flow-diagram";
532
+ import { AnchorPort } from "./anchor-port";
533
+ import {
534
+ ConnectorEdge
535
+ } from "./connector-edge";
536
+ import { EdgeLabel } from "./edge-label";
537
+ import { GroupHull } from "./group-hull";
538
+ import {
539
+ ObjectCard
540
+ } from "./object-card";
541
+ import { ObjectHandle } from "./object-handle";
542
+ import {
543
+ ConversationEmpty,
544
+ ConversationHeader,
545
+ ConversationLoading,
546
+ ConversationMessages,
547
+ ConversationScrollButton,
548
+ ConversationSuggestions,
549
+ ConversationThread,
550
+ ConversationTitle
551
+ } from "./conversation-thread";
469
552
  import { InlineInput } from "./inline-input";
470
553
  import {
471
554
  ModelSelector
@@ -498,6 +581,7 @@ export {
498
581
  AlertDialogTitle,
499
582
  AlertDialogTrigger,
500
583
  AlertTitle,
584
+ AnchorPort,
501
585
  AnimatedText,
502
586
  Annotation,
503
587
  AreaChart,
@@ -511,11 +595,14 @@ export {
511
595
  BeforeAfter,
512
596
  BlogCard,
513
597
  BorderBeam,
598
+ BottomBar,
514
599
  Breadcrumb,
515
600
  Button,
516
601
  Calendar,
517
602
  Callout,
518
603
  CandlestickChart,
604
+ CanvasShell,
605
+ CanvasView,
519
606
  Card,
520
607
  CardContent,
521
608
  CardDescription,
@@ -528,6 +615,7 @@ export {
528
615
  CarouselNext,
529
616
  CarouselPrevious,
530
617
  CategoryFilter,
618
+ ChatDockSection,
531
619
  Checkbox,
532
620
  Checklist,
533
621
  CodeBlock,
@@ -548,6 +636,7 @@ export {
548
636
  CommonMistake,
549
637
  Comparison,
550
638
  CompletionDialog,
639
+ ConnectorEdge,
551
640
  ContentCard,
552
641
  ContentIntro,
553
642
  ContextMenu,
@@ -565,9 +654,20 @@ export {
565
654
  ContextMenuSubContent,
566
655
  ContextMenuSubTrigger,
567
656
  ContextMenuTrigger,
657
+ ConversationEmpty,
658
+ ConversationHeader,
659
+ ConversationLoading,
660
+ ConversationMessages,
661
+ ConversationScrollButton,
662
+ ConversationSuggestions,
663
+ ConversationThread,
664
+ ConversationTitle,
568
665
  CookieConsent,
569
666
  CountdownTimer,
570
667
  CreditBadge,
668
+ Curriculum,
669
+ CurriculumLesson,
670
+ CurriculumModule,
571
671
  DataList,
572
672
  DataListItem,
573
673
  DataListLabel,
@@ -609,6 +709,7 @@ export {
609
709
  DropdownMenuSubContent,
610
710
  DropdownMenuSubTrigger,
611
711
  DropdownMenuTrigger,
712
+ EdgeLabel,
612
713
  Exercise,
613
714
  FAQ,
614
715
  FAQItem,
@@ -621,7 +722,16 @@ export {
621
722
  FlowDiagram,
622
723
  FlowErrorBoundary,
623
724
  FlowFullscreen,
725
+ Form,
726
+ FormControl,
727
+ FormDescription,
728
+ FormField,
729
+ FormItem,
730
+ FormLabel,
731
+ FormMessage,
732
+ GlassPanel,
624
733
  Glossary,
734
+ GroupHull,
625
735
  Highlight,
626
736
  HorizontalScrollRow,
627
737
  HoverCard,
@@ -638,6 +748,7 @@ export {
638
748
  Label,
639
749
  LangProvider,
640
750
  LearningObjectives,
751
+ LeftRail,
641
752
  LineChart,
642
753
  LiveFeed,
643
754
  MDXContent,
@@ -660,7 +771,9 @@ export {
660
771
  MenubarSubTrigger,
661
772
  MenubarTrigger,
662
773
  MetricGauge,
774
+ MiniMapPanel,
663
775
  ModelSelector,
776
+ MultiSelect,
664
777
  NavbarSaas,
665
778
  NavigationMenu,
666
779
  NavigationMenuContent,
@@ -672,7 +785,11 @@ export {
672
785
  NavigationMenuViewport,
673
786
  NumberInput,
674
787
  NumberTicker,
788
+ ObjectCard,
789
+ ObjectHandle,
675
790
  OrderBook,
791
+ OverviewBoard,
792
+ OverviewCard,
676
793
  Pagination,
677
794
  PasswordInput,
678
795
  PlanBadge,
@@ -684,6 +801,14 @@ export {
684
801
  ProTip,
685
802
  ProfileSection,
686
803
  ProgressBar,
804
+ ProgressCard,
805
+ ProgressTracker,
806
+ ProgressTrackerBadge,
807
+ ProgressTrackerModule,
808
+ ProgressTrackerModules,
809
+ ProgressTrackerOverview,
810
+ ProgressTrackerStat,
811
+ ProgressTrackerStats,
687
812
  Quiz,
688
813
  RadioGroup,
689
814
  RadioGroupItem,
@@ -691,12 +816,15 @@ export {
691
816
  ResizableHandle,
692
817
  ResizablePanel,
693
818
  ResizablePanelGroup,
819
+ RightDock,
694
820
  RoleBadge,
695
821
  ScopeSelector,
696
822
  ScrollArea,
697
823
  ScrollBar,
698
824
  SearchBar,
699
825
  SearchDialog,
826
+ SegmentedControl,
827
+ SegmentedControlItem,
700
828
  Select,
701
829
  SelectContent,
702
830
  SelectGroup,
@@ -756,6 +884,7 @@ export {
756
884
  TabsContent,
757
885
  TabsList,
758
886
  TabsTrigger,
887
+ TagsInput,
759
888
  Terminal,
760
889
  Textarea,
761
890
  ThemeProvider,
@@ -775,6 +904,7 @@ export {
775
904
  TooltipContent,
776
905
  TooltipProvider,
777
906
  TooltipTrigger,
907
+ TopBar,
778
908
  Tour,
779
909
  TruncatedText,
780
910
  TutorialCard,
@@ -788,7 +918,9 @@ export {
788
918
  ViewSwitcher,
789
919
  WalletCard,
790
920
  Watchlist,
921
+ WorkspaceSwitcher,
791
922
  WorldClockBar,
923
+ ZoomHUD,
792
924
  alertVariants,
793
925
  avatarGroupVariants,
794
926
  avatarItemVariants,
@@ -800,13 +932,17 @@ export {
800
932
  dotVariants,
801
933
  mdxComponents,
802
934
  navigationMenuTriggerStyle,
935
+ segmentedControlItemVariants,
936
+ segmentedControlVariants,
803
937
  severityBadgeVariants,
804
938
  statCardVariants,
805
939
  statusIndicatorVariants,
806
940
  toast,
807
941
  toggleVariants,
808
942
  useFlowDiagram,
943
+ useFormField,
809
944
  useMobile,
945
+ useProgressTrackerContext,
810
946
  useSidebar,
811
947
  useSocialFab
812
948
  };
@@ -0,0 +1,4 @@
1
+ import { LeftRail } from "./left-rail";
2
+ export {
3
+ LeftRail
4
+ };
@@ -0,0 +1,25 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ import { cn } from "../../lib/utils";
4
+ const LeftRail = forwardRef(
5
+ ({ children, className, footer, title, ...props }, ref) => /* @__PURE__ */ jsxs(
6
+ "aside",
7
+ {
8
+ className: cn(
9
+ "flex h-full w-[4.5rem] shrink-0 flex-col items-center gap-3 border-r border-border bg-background px-2 py-3",
10
+ className
11
+ ),
12
+ ref,
13
+ ...props,
14
+ children: [
15
+ title ? /* @__PURE__ */ jsx("div", { className: "flex min-h-9 items-center text-[11px] font-medium uppercase tracking-[0.24em] text-muted-foreground", children: title }) : null,
16
+ /* @__PURE__ */ jsx("div", { className: "flex w-full flex-1 flex-col items-center gap-2", children }),
17
+ footer ? /* @__PURE__ */ jsx("div", { className: "flex w-full flex-col items-center gap-2", children: footer }) : null
18
+ ]
19
+ }
20
+ )
21
+ );
22
+ LeftRail.displayName = "LeftRail";
23
+ export {
24
+ LeftRail
25
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ MiniMapPanel
3
+ } from "./mini-map-panel";
4
+ export {
5
+ MiniMapPanel
6
+ };
@@ -0,0 +1,74 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ import { cn } from "../../lib/utils";
4
+ const MiniMapPanel = forwardRef(
5
+ ({ className, markers = [], title = "Overview", viewport, world, ...props }, ref) => {
6
+ const viewportWidth = Math.max(
7
+ viewport.width / viewport.zoom / world.width * 100,
8
+ 8
9
+ );
10
+ const viewportHeight = Math.max(
11
+ viewport.height / viewport.zoom / world.height * 100,
12
+ 8
13
+ );
14
+ const viewportLeft = Math.min(
15
+ Math.max(viewport.x / world.width * 100, 0),
16
+ 100 - viewportWidth
17
+ );
18
+ const viewportTop = Math.min(
19
+ Math.max(viewport.y / world.height * 100, 0),
20
+ 100 - viewportHeight
21
+ );
22
+ return /* @__PURE__ */ jsxs(
23
+ "div",
24
+ {
25
+ className: cn(
26
+ "w-52 rounded-sm border border-border bg-background p-3 font-mono",
27
+ className
28
+ ),
29
+ ref,
30
+ ...props,
31
+ children: [
32
+ /* @__PURE__ */ jsx("div", { className: "mb-3 flex items-center justify-between", children: /* @__PURE__ */ jsxs("div", { children: [
33
+ /* @__PURE__ */ jsx("div", { className: "text-xs font-medium uppercase tracking-[0.24em] text-muted-foreground", children: title }),
34
+ /* @__PURE__ */ jsxs("div", { className: "mt-1 text-xs text-muted-foreground", children: [
35
+ "Zoom ",
36
+ Math.round(viewport.zoom * 100),
37
+ "%"
38
+ ] })
39
+ ] }) }),
40
+ /* @__PURE__ */ jsxs("div", { className: "relative aspect-[4/3] overflow-hidden rounded-sm border border-border bg-background", children: [
41
+ markers.map((marker) => /* @__PURE__ */ jsx(
42
+ "div",
43
+ {
44
+ className: "absolute size-1.5 -translate-x-1/2 -translate-y-1/2 bg-foreground",
45
+ style: {
46
+ left: `${marker.x / world.width * 100}%`,
47
+ top: `${marker.y / world.height * 100}%`
48
+ },
49
+ title: marker.label
50
+ },
51
+ marker.id
52
+ )),
53
+ /* @__PURE__ */ jsx(
54
+ "div",
55
+ {
56
+ className: "absolute border border-foreground/80 bg-transparent",
57
+ style: {
58
+ height: `${viewportHeight}%`,
59
+ left: `${viewportLeft}%`,
60
+ top: `${viewportTop}%`,
61
+ width: `${viewportWidth}%`
62
+ }
63
+ }
64
+ )
65
+ ] })
66
+ ]
67
+ }
68
+ );
69
+ }
70
+ );
71
+ MiniMapPanel.displayName = "MiniMapPanel";
72
+ export {
73
+ MiniMapPanel
74
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ MultiSelect
3
+ } from "./multi-select";
4
+ export {
5
+ MultiSelect
6
+ };
@@ -0,0 +1,258 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { Check, ChevronDown } from "lucide-react";
5
+ import { cn } from "../../lib/utils";
6
+ import { Badge } from "../badge";
7
+ import { Button } from "../button";
8
+ import {
9
+ Command,
10
+ CommandEmpty,
11
+ CommandGroup,
12
+ CommandInput,
13
+ CommandItem,
14
+ CommandList
15
+ } from "../command";
16
+ import { Popover, PopoverContent, PopoverTrigger } from "../popover";
17
+ function getUniqueValues(values) {
18
+ return values.filter((value, index) => values.indexOf(value) === index);
19
+ }
20
+ function shouldOpenFromKey(key) {
21
+ return key === " " || key === "ArrowDown" || key === "Enter";
22
+ }
23
+ function TriggerContent({ placeholder, selectedOptions }) {
24
+ if (selectedOptions.length === 0) {
25
+ return /* @__PURE__ */ jsx("span", { children: placeholder });
26
+ }
27
+ return /* @__PURE__ */ jsx(Fragment, { children: selectedOptions.map((option) => /* @__PURE__ */ jsx(Badge, { className: "max-w-full", variant: "secondary", children: /* @__PURE__ */ jsx("span", { className: "truncate", children: option.label }) }, option.value)) });
28
+ }
29
+ function OptionList({
30
+ disabled,
31
+ emptyText,
32
+ onSelect,
33
+ options,
34
+ searchable,
35
+ searchPlaceholder,
36
+ selectedValues
37
+ }) {
38
+ return /* @__PURE__ */ jsxs(Command, { children: [
39
+ searchable ? /* @__PURE__ */ jsx(CommandInput, { placeholder: searchPlaceholder }) : null,
40
+ /* @__PURE__ */ jsxs(CommandList, { "aria-multiselectable": "true", children: [
41
+ /* @__PURE__ */ jsx(CommandEmpty, { children: emptyText }),
42
+ /* @__PURE__ */ jsx(CommandGroup, { children: /* @__PURE__ */ jsx("div", { children: options.map((option) => {
43
+ const isSelected = selectedValues.includes(option.value);
44
+ return /* @__PURE__ */ jsxs(
45
+ CommandItem,
46
+ {
47
+ "aria-disabled": option.disabled || void 0,
48
+ "aria-selected": isSelected,
49
+ className: "gap-2",
50
+ disabled: disabled || option.disabled,
51
+ onSelect: () => {
52
+ onSelect(option.value);
53
+ },
54
+ role: "option",
55
+ value: option.label,
56
+ children: [
57
+ /* @__PURE__ */ jsx(
58
+ "span",
59
+ {
60
+ className: cn(
61
+ "flex h-4 w-4 items-center justify-center rounded-sm border border-input bg-background text-primary transition-opacity",
62
+ isSelected ? "opacity-100" : "opacity-50"
63
+ ),
64
+ children: isSelected ? /* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5" }) : null
65
+ }
66
+ ),
67
+ /* @__PURE__ */ jsx("span", { className: "flex-1", children: option.label })
68
+ ]
69
+ },
70
+ option.value
71
+ );
72
+ }) }) })
73
+ ] })
74
+ ] });
75
+ }
76
+ function MultiSelectContent({
77
+ contentId,
78
+ disabled,
79
+ emptyText,
80
+ onSelect,
81
+ options,
82
+ searchable,
83
+ searchPlaceholder,
84
+ selectedValues
85
+ }) {
86
+ return /* @__PURE__ */ jsx(
87
+ PopoverContent,
88
+ {
89
+ align: "start",
90
+ className: "w-[var(--radix-popover-trigger-width)] p-0",
91
+ id: contentId,
92
+ children: /* @__PURE__ */ jsx(
93
+ OptionList,
94
+ {
95
+ disabled,
96
+ emptyText,
97
+ onSelect,
98
+ options,
99
+ searchable,
100
+ searchPlaceholder,
101
+ selectedValues
102
+ }
103
+ )
104
+ }
105
+ );
106
+ }
107
+ function useMultiSelectState({
108
+ defaultValue,
109
+ onOpenChange,
110
+ onValueChange,
111
+ value
112
+ }) {
113
+ const [open, setOpen] = React.useState(false);
114
+ const [uncontrolledValue, setUncontrolledValue] = React.useState(
115
+ () => getUniqueValues(defaultValue)
116
+ );
117
+ const isControlled = value !== void 0;
118
+ const selectedValues = React.useMemo(
119
+ () => getUniqueValues(value ?? uncontrolledValue),
120
+ [uncontrolledValue, value]
121
+ );
122
+ const setSelectedValues = React.useCallback(
123
+ (nextValue) => {
124
+ const uniqueValues = getUniqueValues(nextValue);
125
+ if (!isControlled) {
126
+ setUncontrolledValue(uniqueValues);
127
+ }
128
+ onValueChange?.(uniqueValues);
129
+ },
130
+ [isControlled, onValueChange]
131
+ );
132
+ const handleOpenChange = React.useCallback(
133
+ (nextOpen) => {
134
+ setOpen(nextOpen);
135
+ onOpenChange?.(nextOpen);
136
+ },
137
+ [onOpenChange]
138
+ );
139
+ return {
140
+ handleOpenChange,
141
+ open,
142
+ selectedValues,
143
+ setSelectedValues
144
+ };
145
+ }
146
+ const MultiSelectTrigger = React.forwardRef(
147
+ ({
148
+ className,
149
+ contentId,
150
+ disabled = false,
151
+ onKeyDown,
152
+ open,
153
+ placeholder = "Select options",
154
+ selectedOptions,
155
+ ...props
156
+ }, ref) => /* @__PURE__ */ jsxs(
157
+ Button,
158
+ {
159
+ "aria-controls": contentId,
160
+ "aria-expanded": open,
161
+ "aria-haspopup": "listbox",
162
+ className: cn(
163
+ "min-h-10 w-full justify-between px-3 py-2 text-sm font-normal",
164
+ selectedOptions.length === 0 && "text-muted-foreground",
165
+ className
166
+ ),
167
+ disabled,
168
+ onKeyDown,
169
+ ref,
170
+ role: "combobox",
171
+ type: "button",
172
+ variant: "outline",
173
+ ...props,
174
+ children: [
175
+ /* @__PURE__ */ jsx("span", { className: "flex min-w-0 flex-1 flex-wrap items-center gap-1 text-left", children: /* @__PURE__ */ jsx(
176
+ TriggerContent,
177
+ {
178
+ placeholder,
179
+ selectedOptions
180
+ }
181
+ ) }),
182
+ /* @__PURE__ */ jsx(ChevronDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })
183
+ ]
184
+ }
185
+ )
186
+ );
187
+ MultiSelectTrigger.displayName = "MultiSelectTrigger";
188
+ const MultiSelect = React.forwardRef(
189
+ ({
190
+ defaultValue = [],
191
+ emptyText = "No options found.",
192
+ onKeyDown,
193
+ onOpenChange,
194
+ onValueChange,
195
+ options,
196
+ searchable = false,
197
+ searchPlaceholder = "Search options...",
198
+ value,
199
+ ...props
200
+ }, ref) => {
201
+ const contentId = React.useId();
202
+ const { handleOpenChange, open, selectedValues, setSelectedValues } = useMultiSelectState({ defaultValue, onOpenChange, onValueChange, value });
203
+ const selectedOptions = React.useMemo(
204
+ () => options.filter((option) => selectedValues.includes(option.value)),
205
+ [options, selectedValues]
206
+ );
207
+ const handleSelect = React.useCallback(
208
+ (nextValue) => {
209
+ const nextSelectedValues = selectedValues.includes(nextValue) ? selectedValues.filter((valueItem) => valueItem !== nextValue) : [...selectedValues, nextValue];
210
+ setSelectedValues(nextSelectedValues);
211
+ },
212
+ [selectedValues, setSelectedValues]
213
+ );
214
+ const handleTriggerKeyDown = React.useCallback(
215
+ (event) => {
216
+ onKeyDown?.(event);
217
+ if (event.defaultPrevented || props.disabled) {
218
+ return;
219
+ }
220
+ if (shouldOpenFromKey(event.key)) {
221
+ event.preventDefault();
222
+ handleOpenChange(true);
223
+ }
224
+ },
225
+ [handleOpenChange, onKeyDown, props.disabled]
226
+ );
227
+ return /* @__PURE__ */ jsxs(Popover, { onOpenChange: handleOpenChange, open, children: [
228
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
229
+ MultiSelectTrigger,
230
+ {
231
+ ...props,
232
+ contentId,
233
+ onKeyDown: handleTriggerKeyDown,
234
+ open,
235
+ ref,
236
+ selectedOptions
237
+ }
238
+ ) }),
239
+ /* @__PURE__ */ jsx(
240
+ MultiSelectContent,
241
+ {
242
+ contentId,
243
+ disabled: props.disabled || false,
244
+ emptyText,
245
+ onSelect: handleSelect,
246
+ options,
247
+ searchable,
248
+ searchPlaceholder,
249
+ selectedValues
250
+ }
251
+ )
252
+ ] });
253
+ }
254
+ );
255
+ MultiSelect.displayName = "MultiSelect";
256
+ export {
257
+ MultiSelect
258
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ ObjectCard
3
+ } from "./object-card";
4
+ export {
5
+ ObjectCard
6
+ };