@rebasepro/ui 0.6.1 → 0.7.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 (52) hide show
  1. package/dist/icons/index.d.ts +1 -1
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.es.js +2058 -16
  4. package/dist/index.es.js.map +1 -1
  5. package/dist/styles.d.ts +1 -1
  6. package/dist/views/CardView.d.ts +32 -0
  7. package/dist/views/CollectionView/CollectionCardView.d.ts +30 -0
  8. package/dist/views/CollectionView/CollectionKanbanView.d.ts +31 -0
  9. package/dist/views/CollectionView/CollectionListView.d.ts +30 -0
  10. package/dist/views/CollectionView/CollectionTableView.d.ts +37 -0
  11. package/dist/views/CollectionView/CollectionView.d.ts +121 -0
  12. package/dist/views/CollectionView/CollectionViewToolbar.d.ts +31 -0
  13. package/dist/views/CollectionView/CollectionViewTypes.d.ts +106 -0
  14. package/dist/views/CollectionView/DefaultCellRenderer.d.ts +9 -0
  15. package/dist/views/CollectionView/index.d.ts +24 -0
  16. package/dist/views/CollectionView/utils.d.ts +5 -0
  17. package/dist/views/Kanban/Board.d.ts +3 -0
  18. package/dist/views/Kanban/BoardColumn.d.ts +20 -0
  19. package/dist/views/Kanban/BoardColumnTitle.d.ts +8 -0
  20. package/dist/views/Kanban/BoardSortableList.d.ts +14 -0
  21. package/dist/views/Kanban/board_types.d.ts +61 -0
  22. package/dist/views/Kanban/index.d.ts +5 -0
  23. package/dist/views/KanbanView.d.ts +24 -0
  24. package/dist/views/ListView.d.ts +40 -0
  25. package/dist/views/TableView.d.ts +6 -0
  26. package/dist/views/index.d.ts +5 -0
  27. package/package.json +1 -1
  28. package/src/components/Sheet.tsx +8 -4
  29. package/src/icons/index.ts +3 -0
  30. package/src/index.ts +2 -0
  31. package/src/styles.ts +1 -1
  32. package/src/views/CardView.tsx +281 -0
  33. package/src/views/CollectionView/CollectionCardView.tsx +270 -0
  34. package/src/views/CollectionView/CollectionKanbanView.tsx +251 -0
  35. package/src/views/CollectionView/CollectionListView.tsx +245 -0
  36. package/src/views/CollectionView/CollectionTableView.tsx +229 -0
  37. package/src/views/CollectionView/CollectionView.tsx +388 -0
  38. package/src/views/CollectionView/CollectionViewToolbar.tsx +229 -0
  39. package/src/views/CollectionView/CollectionViewTypes.ts +137 -0
  40. package/src/views/CollectionView/DefaultCellRenderer.tsx +404 -0
  41. package/src/views/CollectionView/index.ts +44 -0
  42. package/src/views/CollectionView/utils.ts +14 -0
  43. package/src/views/Kanban/Board.tsx +421 -0
  44. package/src/views/Kanban/BoardColumn.tsx +135 -0
  45. package/src/views/Kanban/BoardColumnTitle.tsx +47 -0
  46. package/src/views/Kanban/BoardSortableList.tsx +170 -0
  47. package/src/views/Kanban/board_types.ts +70 -0
  48. package/src/views/Kanban/index.tsx +5 -0
  49. package/src/views/KanbanView.tsx +32 -0
  50. package/src/views/ListView.tsx +281 -0
  51. package/src/views/TableView.tsx +7 -0
  52. package/src/views/index.ts +5 -0
package/dist/index.es.js CHANGED
@@ -1,11 +1,11 @@
1
1
  "use client";
2
2
  import * as React$1 from "react";
3
- import React, { Children, createContext, createRef, forwardRef, useCallback, useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
3
+ import React, { Children, createContext, createRef, forwardRef, memo, useCallback, useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
4
4
  import { clsx } from "clsx";
5
5
  import { twMerge } from "tailwind-merge";
6
6
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
7
  import * as Collapsible from "@radix-ui/react-collapsible";
8
- import { AlertCircleIcon, AlertCircleIcon as AlertCircleIcon$1, AlertTriangleIcon, AlignLeftIcon, AppWindow, ArrowDownToLineIcon, ArrowLeftIcon, ArrowLeftIcon as ArrowLeftIcon$1, ArrowRightFromLineIcon, ArrowRightIcon, ArrowRightToLineIcon, ArrowUpIcon, ArrowUpToLineIcon, BoldIcon, BookOpenIcon, CalendarIcon, CalendarIcon as CalendarIcon$1, CheckCircleIcon, CheckIcon, CheckIcon as CheckIcon$1, CheckSquareIcon, ChevronDownIcon, ChevronDownIcon as ChevronDownIcon$1, ChevronLeftIcon, ChevronLeftIcon as ChevronLeftIcon$1, ChevronRightIcon, ChevronRightIcon as ChevronRightIcon$1, ChevronUpIcon, ChevronUpIcon as ChevronUpIcon$1, ChevronsLeftIcon, ChevronsRightIcon, ChevronsUpDownIcon, CircleIcon, CircleUserIcon, CodeIcon, ColumnsIcon, CopyIcon, DatabaseIcon, DownloadIcon, ExternalLinkIcon, EyeIcon, EyeOffIcon, FileIcon, FileSearchIcon, FileTextIcon, FilterIcon, FilterIcon as FilterIcon$1, FilterXIcon, FlagIcon, FolderIcon, FolderPlusIcon, FolderUpIcon, FunctionSquareIcon, GitBranchIcon, GlobeIcon, HashIcon, Heading1Icon, Heading2Icon, Heading3Icon, HelpCircleIcon, HistoryIcon, HomeIcon, ImageIcon, ImageOffIcon, InfoIcon, ItalicIcon, KanbanIcon, KeyIcon, KeyRoundIcon, LanguagesIcon, LayoutGridIcon, LinkIcon, ListIcon, ListOrderedIcon, LoaderIcon, LogOutIcon, MailIcon, Maximize2Icon, MenuIcon, MinusCircleIcon, MinusIcon, MinusIcon as MinusIcon$1, MoonIcon, MoreVerticalIcon, Music2Icon, PanelLeftIcon, PauseIcon, PencilIcon, PhoneIcon, PlayIcon, PlusIcon, QuoteIcon, RefreshCcwIcon, RefreshCwIcon, RefreshCwIcon as RefreshCwIcon$1, RepeatIcon, Rows3Icon, SaveIcon, SearchIcon, SearchIcon as SearchIcon$1, SendIcon, SettingsIcon, ShieldAlertIcon, ShieldIcon, ShoppingCartIcon, SlidersHorizontalIcon, SquareIcon, StarIcon, StrikethroughIcon, SunIcon, SunMoonIcon, TableIcon, TagIcon, TerminalIcon, TextIcon, Trash2Icon, TypeIcon, UnderlineIcon, UndoIcon, UploadCloudIcon, UploadIcon, UserCheckIcon, UserIcon, VideoIcon, VoteIcon, Wand2Icon, XCircleIcon, XIcon, XIcon as XIcon$1, icons as lucideIcons } from "lucide-react";
8
+ import { AlertCircleIcon, AlertCircleIcon as AlertCircleIcon$1, AlertTriangleIcon, AlignLeftIcon, AppWindow, ArrowDownToLineIcon, ArrowLeftIcon, ArrowLeftIcon as ArrowLeftIcon$1, ArrowRightFromLineIcon, ArrowRightIcon, ArrowRightToLineIcon, ArrowUpIcon, ArrowUpToLineIcon, BoldIcon, BookOpenIcon, CalendarIcon, CalendarIcon as CalendarIcon$1, CheckCircleIcon, CheckIcon, CheckIcon as CheckIcon$1, CheckSquareIcon, ChevronDownIcon, ChevronDownIcon as ChevronDownIcon$1, ChevronLeftIcon, ChevronLeftIcon as ChevronLeftIcon$1, ChevronRightIcon, ChevronRightIcon as ChevronRightIcon$1, ChevronUpIcon, ChevronUpIcon as ChevronUpIcon$1, ChevronsLeftIcon, ChevronsRightIcon, ChevronsUpDownIcon, CircleIcon, CircleUserIcon, CodeIcon, ColumnsIcon, CopyIcon, DatabaseIcon, DownloadIcon, ExternalLinkIcon, EyeIcon, EyeOffIcon, FileIcon, FileSearchIcon, FileTextIcon, FilterIcon, FilterIcon as FilterIcon$1, FilterXIcon, FlagIcon, FolderIcon, FolderPlusIcon, FolderUpIcon, FunctionSquareIcon, GitBranchIcon, GlobeIcon, HashIcon, Heading1Icon, Heading2Icon, Heading3Icon, HelpCircleIcon, HistoryIcon, HomeIcon, ImageIcon, ImageIcon as ImageIcon$1, ImageOffIcon, InfoIcon, ItalicIcon, Kanban, KanbanIcon, KeyIcon, KeyRoundIcon, LanguagesIcon, LayoutGrid, LayoutGridIcon, LayoutList, Link2Icon, LinkIcon, ListIcon, ListOrderedIcon, LoaderIcon, LockIcon, LogOutIcon, MailIcon, Maximize2Icon, MenuIcon, MinusCircleIcon, MinusIcon, MinusIcon as MinusIcon$1, MoonIcon, MoreVerticalIcon, Music2Icon, PanelLeftIcon, PauseIcon, PencilIcon, PhoneIcon, PlayIcon, PlusIcon, QuoteIcon, RefreshCcwIcon, RefreshCwIcon, RefreshCwIcon as RefreshCwIcon$1, RepeatIcon, Rows3Icon, SaveIcon, SearchIcon, SearchIcon as SearchIcon$1, SendIcon, Settings2, SettingsIcon, ShieldAlertIcon, ShieldIcon, ShoppingCartIcon, SlidersHorizontalIcon, SquareIcon, StarIcon, StrikethroughIcon, SunIcon, SunMoonIcon, Table2, TableIcon, TagIcon, TerminalIcon, TextIcon, Trash2Icon, TypeIcon, UnderlineIcon, UndoIcon, UploadCloudIcon, UploadIcon, UserCheckIcon, UserIcon, UserPlus, VideoIcon, VoteIcon, Wand2Icon, XCircleIcon, XIcon, XIcon as XIcon$1, icons as lucideIcons } from "lucide-react";
9
9
  import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
10
10
  import * as TooltipPrimitive from "@radix-ui/react-tooltip";
11
11
  import * as DialogPrimitive from "@radix-ui/react-dialog";
@@ -23,13 +23,15 @@ import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
23
23
  import * as SelectPrimitive from "@radix-ui/react-select";
24
24
  import * as SliderPrimitive from "@radix-ui/react-slider";
25
25
  import * as ReactDOM from "react-dom";
26
+ import { createPortal } from "react-dom";
26
27
  import * as TabsPrimitive from "@radix-ui/react-tabs";
27
28
  import { FixedSizeList } from "react-window";
28
29
  import useMeasure from "react-use-measure";
29
- import { SortableContext, arrayMove, horizontalListSortingStrategy, useSortable } from "@dnd-kit/sortable";
30
- import { DndContext, PointerSensor, closestCenter, useSensor, useSensors } from "@dnd-kit/core";
30
+ import { SortableContext, arrayMove, horizontalListSortingStrategy, useSortable, verticalListSortingStrategy } from "@dnd-kit/sortable";
31
+ import { DndContext, DragOverlay, PointerSensor, closestCenter, useDroppable, useSensor, useSensors } from "@dnd-kit/core";
31
32
  import * as Portal from "@radix-ui/react-portal";
32
33
  import { Slot } from "@radix-ui/react-slot";
34
+ import { CSS } from "@dnd-kit/utilities";
33
35
  //#region src/util/cls.ts
34
36
  function cls(...classes) {
35
37
  return twMerge(clsx(classes));
@@ -192,7 +194,7 @@ var fieldBackgroundMixin = "bg-surface-accent-200/50 dark:bg-black/30";
192
194
  var fieldBackgroundInvisibleMixin = "bg-surface-accent-200/0 dark:bg-black/0";
193
195
  var fieldBackgroundDisabledMixin = "bg-surface-accent-200/50 dark:bg-black/20";
194
196
  var fieldBackgroundHoverMixin = "hover:bg-surface-accent-200/70 hover:dark:bg-black/50";
195
- var defaultBorderMixin = "border-surface-200 dark:border-surface-700 ";
197
+ var defaultBorderMixin = "border-surface-200 dark:border-surface-700/60 ";
196
198
  var paperMixin = "bg-white rounded-lg dark:bg-surface-900 border border-surface-200 dark:border-surface-700";
197
199
  var cardMixin = "bg-white dark:bg-surface-900 rounded-lg border border-surface-200 dark:border-surface-700";
198
200
  var cardClickableMixin = "hover:bg-primary/5 dark:hover:bg-primary/5 cursor-pointer transition-colors duration-150";
@@ -1609,7 +1611,7 @@ function ExpandablePanel({ title, children, invisible = false, expanded, onExpan
1609
1611
  if (expanded !== void 0) setOpen(expanded);
1610
1612
  }, [expanded]);
1611
1613
  return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(Collapsible.Root, {
1612
- className: cls(!invisible && "border-surface-200 dark:border-surface-700 border", "rounded-lg", "w-full", className),
1614
+ className: cls(!invisible && "border-surface-200 dark:border-surface-700/60 border", "rounded-lg", "w-full", className),
1613
1615
  open,
1614
1616
  onOpenChange: (updatedOpen) => {
1615
1617
  onExpandedChange?.(updatedOpen);
@@ -1618,7 +1620,7 @@ function ExpandablePanel({ title, children, invisible = false, expanded, onExpan
1618
1620
  children: [/* @__PURE__ */ jsx(Collapsible.Trigger, {
1619
1621
  asChild: true,
1620
1622
  children: /* @__PURE__ */ jsxs("div", {
1621
- className: cls("rounded-t flex items-center justify-between w-full min-h-[52px]", "hover:bg-surface-accent-200 hover:bg-opacity-40 hover:bg-surface-accent-200/40 dark:hover:bg-surface-800 dark:hover:bg-opacity-40 dark:hover:bg-surface-800/40 active:bg-surface-accent-300/50 dark:active:bg-surface-700/50", invisible ? "border-b px-2" : "p-4", open ? "py-6" : "py-4", "transition-all duration-200", invisible && "border-surface-200 dark:border-surface-700 ", asField && "bg-surface-accent-200/50 dark:bg-black/30", titleClassName, "cursor-pointer"),
1623
+ className: cls("rounded-t flex items-center justify-between w-full min-h-[52px]", "hover:bg-surface-accent-200 hover:bg-opacity-40 hover:bg-surface-accent-200/40 dark:hover:bg-surface-800 dark:hover:bg-opacity-40 dark:hover:bg-surface-800/40 active:bg-surface-accent-300/50 dark:active:bg-surface-700/50", invisible ? "border-b px-2" : "p-4", open ? "py-6" : "py-4", "transition-all duration-200", invisible && "border-surface-200 dark:border-surface-700/60 ", asField && "bg-surface-accent-200/50 dark:bg-black/30", titleClassName, "cursor-pointer"),
1622
1624
  role: "button",
1623
1625
  tabIndex: 0,
1624
1626
  "aria-expanded": open,
@@ -2292,7 +2294,7 @@ function ResizablePanels({ firstPanel, secondPanel, showFirstPanel = true, showS
2292
2294
  children: firstPanel
2293
2295
  }),
2294
2296
  !stacked && showFirstPanel && showSecondPanel && /* @__PURE__ */ jsx("div", {
2295
- className: cls("relative z-10 flex flex-shrink-0 items-center justify-center", "border-surface-200 dark:border-surface-700 ", isHorizontal ? "border-l w-px h-full cursor-col-resize" : "border-t h-px w-full cursor-row-resize"),
2297
+ className: cls("relative z-10 flex flex-shrink-0 items-center justify-center", "border-surface-200 dark:border-surface-700/60 ", isHorizontal ? "border-l w-px h-full cursor-col-resize" : "border-t h-px w-full cursor-row-resize"),
2296
2298
  onMouseDown: handleResizeStart,
2297
2299
  children: /* @__PURE__ */ jsx("div", {
2298
2300
  className: cls("absolute flex items-center justify-center group", isHorizontal ? "w-4 h-full cursor-col-resize top-0" : "h-4 w-full cursor-row-resize left-0"),
@@ -2574,6 +2576,7 @@ Slider.displayName = "Slider";
2574
2576
  //#region src/components/Sheet.tsx
2575
2577
  var Sheet = ({ children, side = "right", title, modal = true, includeBackgroundOverlay = true, open, onOpenChange, onPointerDownOutside, onInteractOutside, transparent, className, style, overlayClassName, overlayZIndex = "z-50", overlayStyle, portalContainer, ...props }) => {
2576
2578
  const [displayed, setDisplayed] = useState(false);
2579
+ const [contentEl, setContentEl] = useState(null);
2577
2580
  const contextContainer = usePortalContainer();
2578
2581
  const finalContainer = portalContainer ?? contextContainer ?? void 0;
2579
2582
  useEffect(() => {
@@ -2605,17 +2608,19 @@ var Sheet = ({ children, side = "right", title, modal = true, includeBackgroundO
2605
2608
  style: overlayStyle
2606
2609
  }), /* @__PURE__ */ jsxs(DialogPrimitive.Content, {
2607
2610
  ...props,
2608
- onFocusCapture: (event) => event.preventDefault(),
2611
+ ref: setContentEl,
2612
+ onOpenAutoFocus: (event) => event.preventDefault(),
2609
2613
  onPointerDownOutside,
2610
2614
  onInteractOutside,
2611
2615
  className: cls("outline-none", borderClass[side], defaultBorderMixin, "transform-gpu", "will-change-transform", "text-surface-accent-900 dark:text-white", "fixed transform z-50 transition-[transform,opacity] ease-in-out", !displayed ? "duration-150" : "duration-100", "outline-none focus:outline-none focus-visible:outline-none focus-visible:ring-0 focus:ring-0", transparent ? "" : "shadow-md bg-white dark:bg-surface-900", side === "top" || side === "bottom" ? "w-full" : "h-full", side === "left" || side === "top" ? "left-0 top-0" : "right-0 bottom-0", displayed && open ? "opacity-100" : "opacity-50", !displayed || !open ? transformValue[side] : "", className),
2612
2616
  style,
2613
2617
  children: [/* @__PURE__ */ jsx(DialogPrimitive.Title, {
2614
- autoFocus: true,
2615
- tabIndex: 0,
2616
2618
  className: "sr-only outline-none focus:outline-none focus-visible:outline-none focus-visible:ring-0 focus:ring-0",
2617
2619
  children: title ?? "Sheet"
2618
- }), children]
2620
+ }), /* @__PURE__ */ jsx(PortalContainerProvider, {
2621
+ container: contentEl,
2622
+ children
2623
+ })]
2619
2624
  })]
2620
2625
  })
2621
2626
  });
@@ -2936,7 +2941,7 @@ function Tabs({ value, onValueChange, className, innerClassName, variant = "stan
2936
2941
  disabled: !showLeftScroll,
2937
2942
  "aria-label": "Scroll tabs left",
2938
2943
  onClick: () => scroll("left"),
2939
- className: cls("absolute left-0 top-1/2 -translate-y-1/2 z-10 flex items-center justify-center rounded-md transition-all h-8 w-6", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-surface-400", !showLeftScroll ? "pointer-events-none opacity-0" : "text-surface-600 dark:text-surface-400 hover:bg-surface-200 dark:hover:bg-surface-800", "bg-surface-50 dark:bg-surface-900 border shadow-sm", "border-surface-200 dark:border-surface-700 "),
2944
+ className: cls("absolute left-0 top-1/2 -translate-y-1/2 z-10 flex items-center justify-center rounded-md transition-all h-8 w-6", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-surface-400", !showLeftScroll ? "pointer-events-none opacity-0" : "text-surface-600 dark:text-surface-400 hover:bg-surface-200 dark:hover:bg-surface-800", "bg-surface-50 dark:bg-surface-900 border shadow-sm", "border-surface-200 dark:border-surface-700/60 "),
2940
2945
  children: /* @__PURE__ */ jsx(ChevronLeftIcon$1, { size: iconSize.smallest })
2941
2946
  }),
2942
2947
  /* @__PURE__ */ jsx("div", {
@@ -2948,7 +2953,7 @@ function Tabs({ value, onValueChange, className, innerClassName, variant = "stan
2948
2953
  msOverflowStyle: "none"
2949
2954
  },
2950
2955
  children: /* @__PURE__ */ jsx(TabsPrimitive.List, {
2951
- className: cls(variant === "standard" && "inline-flex h-9 items-center justify-start rounded-md bg-surface-50 p-1 text-surface-600 dark:bg-surface-900 dark:text-surface-400 gap-2 border", variant === "standard" && "border-surface-200 dark:border-surface-700 ", variant === "boxy" && "flex items-center h-full", variant === "pill" && "flex items-center gap-0.5", innerClassName),
2956
+ className: cls(variant === "standard" && "inline-flex h-9 items-center justify-start rounded-md bg-surface-50 p-1 text-surface-600 dark:bg-surface-900 dark:text-surface-400 gap-2 border", variant === "standard" && "border-surface-200 dark:border-surface-700/60 ", variant === "boxy" && "flex items-center h-full", variant === "pill" && "flex items-center gap-0.5", innerClassName),
2952
2957
  children
2953
2958
  })
2954
2959
  }),
@@ -2957,7 +2962,7 @@ function Tabs({ value, onValueChange, className, innerClassName, variant = "stan
2957
2962
  disabled: !showRightScroll,
2958
2963
  "aria-label": "Scroll tabs right",
2959
2964
  onClick: () => scroll("right"),
2960
- className: cls("absolute right-0 top-1/2 -translate-y-1/2 z-10 flex items-center justify-center rounded-md transition-all h-8 w-6", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-surface-400", !showRightScroll ? "pointer-events-none opacity-0" : "text-surface-600 dark:text-surface-400 hover:bg-surface-200 dark:hover:bg-surface-800", "bg-surface-50 dark:bg-surface-900 border shadow-sm", "border-surface-200 dark:border-surface-700 "),
2965
+ className: cls("absolute right-0 top-1/2 -translate-y-1/2 z-10 flex items-center justify-center rounded-md transition-all h-8 w-6", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-surface-400", !showRightScroll ? "pointer-events-none opacity-0" : "text-surface-600 dark:text-surface-400 hover:bg-surface-200 dark:hover:bg-surface-800", "bg-surface-50 dark:bg-surface-900 border shadow-sm", "border-surface-200 dark:border-surface-700/60 "),
2961
2966
  children: /* @__PURE__ */ jsx(ChevronRightIcon$1, { size: iconSize.smallest })
2962
2967
  })
2963
2968
  ]
@@ -6089,6 +6094,2043 @@ function HandleIcon() {
6089
6094
  });
6090
6095
  }
6091
6096
  //#endregion
6092
- export { Alert, AlertCircleIcon, AlertTriangleIcon, AlignLeftIcon, AppWindow, ArrowDownToLineIcon, ArrowLeftIcon, ArrowRightFromLineIcon, ArrowRightIcon, ArrowRightToLineIcon, ArrowUpToLineIcon, Autocomplete, AutocompleteItem, Avatar, Badge, BoldIcon, BookOpenIcon, BooleanSwitch, BooleanSwitchWithLabel, Button, CHIP_COLORS, CalendarIcon, Card, CenteredView, CheckCircleIcon, CheckIcon, CheckSquareIcon, Checkbox, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, ChevronsLeftIcon, ChevronsRightIcon, ChevronsUpDownIcon, Chip, CircleIcon, CircleUserIcon, CircularProgress, CircularProgressCenter, CodeIcon, Collapse, ColorPicker, ColumnsIcon, Container, CopyIcon, DatabaseIcon, DateTimeField, DebouncedTextField, Dialog, DialogActions, DialogContent, DialogTitle, DownloadIcon, ErrorBoundary, ExpandablePanel, ExternalLinkIcon, EyeIcon, EyeOffIcon, FileIcon, FileSearchIcon, FileTextIcon, FileUpload, FilterChip, FilterIcon, FilterXIcon, FlagIcon, FolderIcon, FolderPlusIcon, FolderUpIcon, FunctionSquareIcon, GitBranchIcon, GitHubIcon, GlobeIcon, HandleIcon, HashIcon, Heading1Icon, Heading2Icon, Heading3Icon, HelpCircleIcon, HistoryIcon, HomeIcon, IconButton, ImageIcon, ImageOffIcon, InfoIcon, InfoLabel, InputLabel, ItalicIcon, KanbanIcon, KeyIcon, KeyRoundIcon, Label, LanguagesIcon, LayoutGridIcon, LinkIcon, ListIcon, ListOrderedIcon, LoaderIcon, LoadingButton, LogOutIcon, MailIcon, Markdown, Maximize2Icon, Menu, MenuIcon, MenuItem, Menubar, MenubarCheckboxItem, MenubarContent, MenubarItem, MenubarItemIndicator, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarSubTriggerIndicator, MenubarTrigger, MinusCircleIcon, MinusIcon, MoonIcon, MoreVerticalIcon, MultiSelect, MultiSelectContext, MultiSelectItem, Music2Icon, PanelLeftIcon, Paper, PauseIcon, PencilIcon, PhoneIcon, PlayIcon, PlusIcon, Popover, PopoverPrimitive, Portal, PortalContainerProvider, QuoteIcon, RadioGroup, RadioGroupItem, RefreshCcwIcon, RefreshCwIcon, RepeatIcon, ResizablePanels, Rows3Icon, SaveIcon, SearchBar, SearchIcon, Select, SelectGroup, SelectInputLabel, SelectItem, SendIcon, Separator, SettingsIcon, Sheet, ShieldIcon, ShoppingCartIcon, Skeleton, Slider, SlidersHorizontalIcon, Slot, SquareIcon, StarIcon, StrikethroughIcon, SunIcon, SunMoonIcon, Tab, Table, TableBody, TableCell, TableHeader, TableIcon, TableRow, Tabs, TagIcon, TerminalIcon, TextField, TextIcon, TextareaAutosize, ToggleButtonGroup, Tooltip, Trash2Icon, TypeIcon, Typography, UnderlineIcon, UndoIcon, UploadCloudIcon, UploadIcon, UserCheckIcon, UserIcon, VideoIcon, VirtualTable, VoteIcon, Wand2Icon, XCircleIcon, XIcon, cardClickableMixin, cardMixin, cardSelectedMixin, cls, colorClassesMapping, coolIconKeys, debounce, defaultBorderMixin, fieldBackgroundDisabledMixin, fieldBackgroundHoverMixin, fieldBackgroundInvisibleMixin, fieldBackgroundMixin, focusedClasses, focusedDisabled, focusedInvisibleMixin, getColorSchemeForKey, getColorSchemeForSeed, iconKeys, iconSize, keyToIconComponent, lucideIcons, paperMixin, useAutoComplete, useDebounceCallback, useDebounceValue, useDebouncedCallback, useInjectStyles, useOutsideAlerter, usePortalContainer };
6097
+ //#region src/views/ListView.tsx
6098
+ function getEstimatedRowHeight(size) {
6099
+ switch (size) {
6100
+ case "xs": return 44;
6101
+ case "s": return 52;
6102
+ case "m": return 64;
6103
+ case "l": return 76;
6104
+ case "xl": return 88;
6105
+ default: return 64;
6106
+ }
6107
+ }
6108
+ var OVERSCAN_COUNT = 8;
6109
+ var LOAD_MORE_THRESHOLD = 400;
6110
+ function getScrollParent$1(element) {
6111
+ let parent = element?.parentElement ?? null;
6112
+ while (parent) {
6113
+ const style = getComputedStyle(parent);
6114
+ if (style.overflowY === "auto" || style.overflowY === "scroll" || style.overflow === "auto" || style.overflow === "scroll") return parent;
6115
+ parent = parent.parentElement;
6116
+ }
6117
+ return document.documentElement;
6118
+ }
6119
+ function ListView({ data, dataLoading = false, noMoreToLoad = false, dataLoadingError, itemCount, setItemCount, pageSize = 50, paginationEnabled = true, onItemClick, selectedIds, highlightedIds, selectionEnabled = true, onSelectionChange, emptyComponent, size = "m", selectedEntityId, renderRow }) {
6120
+ const containerRef = useRef(null);
6121
+ const isLoadingMore = useRef(false);
6122
+ useEffect(() => {
6123
+ if (!dataLoading) isLoadingMore.current = false;
6124
+ }, [dataLoading]);
6125
+ const estimatedRowHeight = getEstimatedRowHeight(size);
6126
+ const [effectiveScrollTop, setEffectiveScrollTop] = useState(0);
6127
+ const [viewportHeight, setViewportHeight] = useState(800);
6128
+ const paginationStateRef = useRef({
6129
+ paginationEnabled,
6130
+ noMoreToLoad,
6131
+ itemCount,
6132
+ pageSize
6133
+ });
6134
+ useEffect(() => {
6135
+ paginationStateRef.current = {
6136
+ paginationEnabled,
6137
+ noMoreToLoad,
6138
+ itemCount,
6139
+ pageSize
6140
+ };
6141
+ }, [
6142
+ paginationEnabled,
6143
+ noMoreToLoad,
6144
+ itemCount,
6145
+ pageSize
6146
+ ]);
6147
+ useEffect(() => {
6148
+ const el = containerRef.current;
6149
+ if (!el) return;
6150
+ const scrollEl = getScrollParent$1(el);
6151
+ if (!scrollEl) return;
6152
+ let rafId = null;
6153
+ const update = () => {
6154
+ rafId = null;
6155
+ const scrollRect = scrollEl.getBoundingClientRect();
6156
+ const listTopRelative = el.getBoundingClientRect().top - scrollRect.top;
6157
+ setEffectiveScrollTop(Math.max(0, -listTopRelative));
6158
+ setViewportHeight(scrollRect.height);
6159
+ const { paginationEnabled: pe, noMoreToLoad: nm, itemCount: ic, pageSize: ps } = paginationStateRef.current;
6160
+ if (pe && !nm && !isLoadingMore.current && scrollEl.scrollHeight - scrollEl.scrollTop - scrollEl.clientHeight < LOAD_MORE_THRESHOLD) {
6161
+ isLoadingMore.current = true;
6162
+ setItemCount?.((ic ?? ps) + ps);
6163
+ }
6164
+ };
6165
+ const onScroll = () => {
6166
+ if (rafId === null) rafId = requestAnimationFrame(update);
6167
+ };
6168
+ scrollEl.addEventListener("scroll", onScroll, { passive: true });
6169
+ const ro = new ResizeObserver(() => update());
6170
+ ro.observe(scrollEl);
6171
+ update();
6172
+ return () => {
6173
+ scrollEl.removeEventListener("scroll", onScroll);
6174
+ ro.disconnect();
6175
+ if (rafId !== null) cancelAnimationFrame(rafId);
6176
+ };
6177
+ }, [setItemCount]);
6178
+ const totalHeight = data.length * estimatedRowHeight;
6179
+ const startIndex = Math.max(0, Math.floor(effectiveScrollTop / estimatedRowHeight) - OVERSCAN_COUNT);
6180
+ const endIndex = Math.min(data.length, Math.ceil((effectiveScrollTop + viewportHeight) / estimatedRowHeight) + OVERSCAN_COUNT);
6181
+ const visibleData = data.slice(startIndex, endIndex);
6182
+ const offsetY = startIndex * estimatedRowHeight;
6183
+ const footerHeight = dataLoading ? 48 : !dataLoading && noMoreToLoad && data.length > 0 ? 32 : 0;
6184
+ const isInitialLoading = dataLoading && data.length === 0;
6185
+ const isEmpty = !dataLoading && data.length === 0 && !dataLoadingError;
6186
+ const getItemId = useCallback((item) => {
6187
+ if (item && typeof item === "object" && "id" in item) {
6188
+ const id = item.id;
6189
+ return typeof id === "number" ? id : String(id);
6190
+ }
6191
+ return String(item);
6192
+ }, []);
6193
+ const borderMixinClass = "border-surface-200 dark:border-surface-800";
6194
+ return /* @__PURE__ */ jsx("div", {
6195
+ ref: containerRef,
6196
+ className: cls("w-full", selectedEntityId === void 0 && `rounded-lg overflow-hidden border ${borderMixinClass}`),
6197
+ children: dataLoadingError && data.length === 0 ? /* @__PURE__ */ jsx("div", {
6198
+ className: "flex items-center justify-center p-8",
6199
+ children: /* @__PURE__ */ jsxs(Typography, {
6200
+ className: "text-red-500",
6201
+ children: ["Error loading data: ", dataLoadingError.message]
6202
+ })
6203
+ }) : isInitialLoading ? /* @__PURE__ */ jsx("div", {
6204
+ className: "flex items-center justify-center py-12 px-8",
6205
+ children: /* @__PURE__ */ jsx(CircularProgress, { size: "small" })
6206
+ }) : isEmpty ? /* @__PURE__ */ jsx("div", {
6207
+ className: "w-full flex items-center justify-center py-12 px-8",
6208
+ children: emptyComponent ?? /* @__PURE__ */ jsx(Typography, {
6209
+ variant: "label",
6210
+ color: "secondary",
6211
+ children: "No entries found"
6212
+ })
6213
+ }) : /* @__PURE__ */ jsxs("div", {
6214
+ style: {
6215
+ height: totalHeight + footerHeight,
6216
+ position: "relative"
6217
+ },
6218
+ children: [
6219
+ /* @__PURE__ */ jsx("div", {
6220
+ style: {
6221
+ position: "absolute",
6222
+ top: offsetY,
6223
+ left: 0,
6224
+ right: 0
6225
+ },
6226
+ children: visibleData.map((item, i) => {
6227
+ const actualIndex = startIndex + i;
6228
+ const isLast = actualIndex === data.length - 1;
6229
+ const id = getItemId(item);
6230
+ const selected = selectedIds?.has(id) ?? false;
6231
+ const highlighted = highlightedIds?.has(id) ?? false;
6232
+ const handleClick = (e) => {
6233
+ if ((e.metaKey || e.ctrlKey) && selectionEnabled) {
6234
+ e.preventDefault();
6235
+ onSelectionChange?.(item, !selected);
6236
+ return;
6237
+ }
6238
+ onItemClick?.(item);
6239
+ };
6240
+ const handleSelectionChange = (val) => {
6241
+ onSelectionChange?.(item, val);
6242
+ };
6243
+ return /* @__PURE__ */ jsx(React.Fragment, { children: renderRow({
6244
+ item,
6245
+ index: actualIndex,
6246
+ style: { height: estimatedRowHeight },
6247
+ className: cls(!isLast && "border-b", !isLast && borderMixinClass),
6248
+ selected,
6249
+ highlighted,
6250
+ isLast,
6251
+ onClick: handleClick,
6252
+ onSelectionChange: handleSelectionChange
6253
+ }) }, id || actualIndex);
6254
+ })
6255
+ }),
6256
+ dataLoading && /* @__PURE__ */ jsx("div", {
6257
+ className: "flex items-center justify-center py-3",
6258
+ style: {
6259
+ position: "absolute",
6260
+ top: totalHeight,
6261
+ left: 0,
6262
+ right: 0
6263
+ },
6264
+ children: /* @__PURE__ */ jsx(CircularProgress, { size: "small" })
6265
+ }),
6266
+ !dataLoading && noMoreToLoad && data.length > 0 && /* @__PURE__ */ jsx("div", {
6267
+ className: "flex items-center justify-center py-2 dark:bg-surface-900",
6268
+ style: {
6269
+ position: "absolute",
6270
+ top: totalHeight,
6271
+ left: 0,
6272
+ right: 0
6273
+ },
6274
+ children: /* @__PURE__ */ jsxs(Typography, {
6275
+ variant: "caption",
6276
+ color: "secondary",
6277
+ children: [
6278
+ "All ",
6279
+ data.length,
6280
+ " entries loaded"
6281
+ ]
6282
+ })
6283
+ })
6284
+ ]
6285
+ })
6286
+ });
6287
+ }
6288
+ //#endregion
6289
+ //#region src/views/CardView.tsx
6290
+ function getGridColumnsClass(size) {
6291
+ switch (size) {
6292
+ case "xs": return "grid-cols-4 sm:grid-cols-5 md:grid-cols-6 lg:grid-cols-8 xl:grid-cols-10";
6293
+ case "s": return "grid-cols-3 sm:grid-cols-4 md:grid-cols-5 lg:grid-cols-6 xl:grid-cols-8";
6294
+ case "m": return "grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6";
6295
+ case "l": return "grid-cols-2 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-4";
6296
+ case "xl": return "grid-cols-1 sm:grid-cols-2 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-3";
6297
+ default: return "grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6";
6298
+ }
6299
+ }
6300
+ function getScrollParent(element) {
6301
+ if (!element) return null;
6302
+ let parent = element.parentElement;
6303
+ while (parent) {
6304
+ const overflowY = window.getComputedStyle(parent).overflowY;
6305
+ if (overflowY === "auto" || overflowY === "scroll") return parent;
6306
+ parent = parent.parentElement;
6307
+ }
6308
+ return document.documentElement;
6309
+ }
6310
+ function CardView({ data, dataLoading = false, noMoreToLoad = false, dataLoadingError, itemCount, setItemCount, pageSize = 50, paginationEnabled = true, onItemClick, selectedIds, highlightedIds, selectionEnabled = true, onSelectionChange, onScroll, initialScroll, size = "m", renderCard, emptyComponent }) {
6311
+ const containerRef = useRef(null);
6312
+ const hasRestoredScroll = useRef(false);
6313
+ const isLoadingMore = useRef(false);
6314
+ const paginationStateRef = useRef({
6315
+ paginationEnabled,
6316
+ noMoreToLoad,
6317
+ itemCount,
6318
+ pageSize
6319
+ });
6320
+ useEffect(() => {
6321
+ paginationStateRef.current = {
6322
+ paginationEnabled,
6323
+ noMoreToLoad,
6324
+ itemCount,
6325
+ pageSize
6326
+ };
6327
+ }, [
6328
+ paginationEnabled,
6329
+ noMoreToLoad,
6330
+ itemCount,
6331
+ pageSize
6332
+ ]);
6333
+ useEffect(() => {
6334
+ if (!dataLoading) isLoadingMore.current = false;
6335
+ }, [dataLoading]);
6336
+ useEffect(() => {
6337
+ const el = containerRef.current;
6338
+ if (!el) return;
6339
+ const scrollEl = getScrollParent(el);
6340
+ if (!scrollEl) return;
6341
+ let rafId = null;
6342
+ const update = () => {
6343
+ rafId = null;
6344
+ const { paginationEnabled: pe, noMoreToLoad: nm, itemCount: ic, pageSize: ps } = paginationStateRef.current;
6345
+ if (pe && !nm && !isLoadingMore.current && scrollEl.scrollHeight - scrollEl.scrollTop - scrollEl.clientHeight < 400) {
6346
+ isLoadingMore.current = true;
6347
+ setItemCount?.((ic ?? ps) + ps);
6348
+ }
6349
+ };
6350
+ const onScrollEvent = () => {
6351
+ if (rafId === null) rafId = requestAnimationFrame(update);
6352
+ };
6353
+ scrollEl.addEventListener("scroll", onScrollEvent, { passive: true });
6354
+ const ro = new ResizeObserver(() => update());
6355
+ ro.observe(scrollEl);
6356
+ update();
6357
+ return () => {
6358
+ scrollEl.removeEventListener("scroll", onScrollEvent);
6359
+ ro.disconnect();
6360
+ if (rafId !== null) cancelAnimationFrame(rafId);
6361
+ };
6362
+ }, [setItemCount]);
6363
+ useEffect(() => {
6364
+ if (!containerRef.current || !initialScroll || hasRestoredScroll.current || data.length === 0) return;
6365
+ const scrollEl = getScrollParent(containerRef.current);
6366
+ if (!scrollEl) return;
6367
+ let attempts = 0;
6368
+ const maxAttempts = 5;
6369
+ const tryRestore = () => {
6370
+ if (scrollEl.scrollHeight >= initialScroll || attempts >= maxAttempts) {
6371
+ scrollEl.scrollTop = initialScroll;
6372
+ hasRestoredScroll.current = true;
6373
+ } else {
6374
+ attempts++;
6375
+ requestAnimationFrame(tryRestore);
6376
+ }
6377
+ };
6378
+ requestAnimationFrame(tryRestore);
6379
+ }, [initialScroll, data.length]);
6380
+ const lastScrollOffset = useRef(0);
6381
+ useEffect(() => {
6382
+ const el = containerRef.current;
6383
+ if (!el || !onScroll) return;
6384
+ const scrollEl = getScrollParent(el);
6385
+ if (!scrollEl) return;
6386
+ const handleScroll = () => {
6387
+ const currentOffset = scrollEl.scrollTop;
6388
+ const direction = currentOffset > lastScrollOffset.current ? "forward" : "backward";
6389
+ lastScrollOffset.current = currentOffset;
6390
+ onScroll({
6391
+ scrollDirection: direction,
6392
+ scrollOffset: currentOffset,
6393
+ scrollUpdateWasRequested: false
6394
+ });
6395
+ };
6396
+ scrollEl.addEventListener("scroll", handleScroll, { passive: true });
6397
+ return () => scrollEl.removeEventListener("scroll", handleScroll);
6398
+ }, [onScroll]);
6399
+ const getItemId = useCallback((item) => {
6400
+ if (item && typeof item === "object" && "id" in item) {
6401
+ const id = item.id;
6402
+ return typeof id === "number" ? id : String(id);
6403
+ }
6404
+ return String(item);
6405
+ }, []);
6406
+ const gridColumnsClass = getGridColumnsClass(size);
6407
+ const isInitialLoading = dataLoading && data.length === 0 && !dataLoadingError;
6408
+ const isEmpty = !dataLoading && data.length === 0 && !dataLoadingError;
6409
+ return /* @__PURE__ */ jsx("div", {
6410
+ ref: containerRef,
6411
+ className: "w-full p-4",
6412
+ children: dataLoadingError && data.length === 0 ? /* @__PURE__ */ jsx("div", {
6413
+ className: "h-full flex items-center justify-center p-8",
6414
+ children: /* @__PURE__ */ jsxs(Typography, {
6415
+ className: "text-red-500",
6416
+ children: ["Error loading data: ", dataLoadingError.message]
6417
+ })
6418
+ }) : isInitialLoading ? /* @__PURE__ */ jsx("div", {
6419
+ className: "flex items-center justify-center py-12 px-8",
6420
+ children: /* @__PURE__ */ jsx(CircularProgress, { size: "small" })
6421
+ }) : isEmpty ? /* @__PURE__ */ jsx("div", {
6422
+ className: "w-full flex items-center justify-center py-12 px-8",
6423
+ children: emptyComponent ?? /* @__PURE__ */ jsx(Typography, {
6424
+ variant: "label",
6425
+ color: "secondary",
6426
+ children: "No entries found"
6427
+ })
6428
+ }) : /* @__PURE__ */ jsxs("div", {
6429
+ className: "max-w-7xl mx-auto",
6430
+ children: [/* @__PURE__ */ jsx("div", {
6431
+ className: cls("grid gap-4", gridColumnsClass),
6432
+ children: data.map((item, index) => {
6433
+ const id = getItemId(item);
6434
+ const selected = selectedIds?.has(id) ?? false;
6435
+ const highlighted = highlightedIds?.has(id) ?? false;
6436
+ const handleClick = (e) => {
6437
+ if ((e.metaKey || e.ctrlKey) && selectionEnabled) {
6438
+ e.preventDefault();
6439
+ onSelectionChange?.(item, !selected);
6440
+ return;
6441
+ }
6442
+ onItemClick?.(item);
6443
+ };
6444
+ const handleSelectionChange = (val) => {
6445
+ onSelectionChange?.(item, val);
6446
+ };
6447
+ return /* @__PURE__ */ jsx(React.Fragment, { children: renderCard(item, {
6448
+ selected,
6449
+ highlighted,
6450
+ onSelectionChange: handleSelectionChange,
6451
+ onClick: handleClick
6452
+ }) }, id || index);
6453
+ })
6454
+ }), /* @__PURE__ */ jsxs("div", {
6455
+ className: "flex items-center justify-center py-8",
6456
+ children: [dataLoading && /* @__PURE__ */ jsx(CircularProgress, { size: "small" }), !dataLoading && noMoreToLoad && data.length > 0 && /* @__PURE__ */ jsxs(Typography, {
6457
+ variant: "caption",
6458
+ color: "secondary",
6459
+ children: [
6460
+ "All ",
6461
+ data.length,
6462
+ " entries loaded"
6463
+ ]
6464
+ })]
6465
+ })]
6466
+ })
6467
+ });
6468
+ }
6469
+ //#endregion
6470
+ //#region src/views/Kanban/BoardSortableList.tsx
6471
+ function BoardSortableList({ columnId, items, ItemComponent, isDragging, isDragOverColumn, loading = false, hasMore = false, onLoadMore }) {
6472
+ const { setNodeRef } = useDroppable({
6473
+ id: columnId,
6474
+ data: { type: "ITEM-LIST" }
6475
+ });
6476
+ const sentinelRef = useRef(null);
6477
+ const isLoadingRef = useRef(loading);
6478
+ isLoadingRef.current = loading;
6479
+ const lastLoadTimeRef = useRef(0);
6480
+ useEffect(() => {
6481
+ if (!sentinelRef.current || !hasMore || !onLoadMore) return;
6482
+ const sentinel = sentinelRef.current;
6483
+ const observer = new IntersectionObserver((entries) => {
6484
+ const now = Date.now();
6485
+ if (entries[0].isIntersecting && hasMore && !isLoadingRef.current && now - lastLoadTimeRef.current > 500) {
6486
+ lastLoadTimeRef.current = now;
6487
+ onLoadMore();
6488
+ }
6489
+ }, { threshold: .1 });
6490
+ observer.observe(sentinel);
6491
+ const rect = sentinel.getBoundingClientRect();
6492
+ const containerRect = sentinel.parentElement?.getBoundingClientRect();
6493
+ if (containerRect && rect.top < containerRect.bottom && rect.bottom > containerRect.top) {
6494
+ const now = Date.now();
6495
+ if (hasMore && !isLoadingRef.current && now - lastLoadTimeRef.current > 500) {
6496
+ lastLoadTimeRef.current = now;
6497
+ onLoadMore();
6498
+ }
6499
+ }
6500
+ return () => observer.disconnect();
6501
+ }, [hasMore, onLoadMore]);
6502
+ return /* @__PURE__ */ jsx("div", {
6503
+ ref: setNodeRef,
6504
+ className: useMemo(() => cls("flex flex-col p-2 transition-opacity duration-100 transition-bg ease-linear w-full overflow-y-auto no-scrollbar flex-1 rounded-md", isDragging && isDragOverColumn ? "bg-surface-accent-200 dark:bg-surface-900" : isDragging ? "bg-surface-50 dark:bg-surface-900 hover:bg-surface-accent-100 dark:hover:bg-surface-800" : "bg-surface-50 dark:bg-surface-900"), [isDragging, isDragOverColumn]),
6505
+ style: { minHeight: 80 },
6506
+ children: /* @__PURE__ */ jsx(SortableContext, {
6507
+ items: items.map((i) => i.id),
6508
+ strategy: verticalListSortingStrategy,
6509
+ children: items.length === 0 && !loading ? /* @__PURE__ */ jsx("div", {
6510
+ className: "flex-1 flex items-center justify-center",
6511
+ children: /* @__PURE__ */ jsx("span", {
6512
+ className: "text-xs text-surface-400 dark:text-surface-500",
6513
+ children: "No items"
6514
+ })
6515
+ }) : /* @__PURE__ */ jsxs(Fragment, { children: [items.map((item, index) => /* @__PURE__ */ jsx(SortableItem, {
6516
+ item,
6517
+ index,
6518
+ columnId,
6519
+ ItemComponent
6520
+ }, item.id)), (loading || hasMore) && /* @__PURE__ */ jsx("div", {
6521
+ ref: sentinelRef,
6522
+ className: "flex items-center justify-center py-2 min-h-6",
6523
+ children: loading && /* @__PURE__ */ jsx(CircularProgress, { size: "smallest" })
6524
+ })] })
6525
+ })
6526
+ });
6527
+ }
6528
+ var SortableItem = memo(function SortableItem({ item, index, columnId, ItemComponent }) {
6529
+ const { setNodeRef, attributes, listeners, isDragging: isItemBeingDragged, transform, transition } = useSortable({
6530
+ id: item.id,
6531
+ data: {
6532
+ type: "ITEM",
6533
+ columnId
6534
+ }
6535
+ });
6536
+ return /* @__PURE__ */ jsx("div", {
6537
+ ref: setNodeRef,
6538
+ style: useMemo(() => ({
6539
+ transform: CSS.Transform.toString(transform),
6540
+ transition,
6541
+ zIndex: isItemBeingDragged ? 2 : 1,
6542
+ opacity: isItemBeingDragged ? 0 : 1
6543
+ }), [
6544
+ transform,
6545
+ transition,
6546
+ isItemBeingDragged
6547
+ ]),
6548
+ ...attributes,
6549
+ ...listeners,
6550
+ children: /* @__PURE__ */ jsx(ItemComponent, {
6551
+ item,
6552
+ isDragging: isItemBeingDragged,
6553
+ index
6554
+ })
6555
+ });
6556
+ });
6557
+ //#endregion
6558
+ //#region src/views/Kanban/BoardColumnTitle.tsx
6559
+ function BoardColumnTitle({ children, className, color, ...props }) {
6560
+ const colorScheme = useMemo(() => {
6561
+ if (!color) return void 0;
6562
+ if (typeof color === "string") return getColorSchemeForKey(color);
6563
+ return color;
6564
+ }, [color]);
6565
+ return /* @__PURE__ */ jsxs(Typography, {
6566
+ variant: "subtitle2",
6567
+ component: "h4",
6568
+ className: cls("py-3 px-3 transition-colors duration-200 flex-grow select-none relative outline-none focus:outline focus:outline-2 focus:outline-offset-2 flex items-center gap-3", className),
6569
+ ...props,
6570
+ children: [colorScheme && /* @__PURE__ */ jsx("div", {
6571
+ className: "w-3 h-3 rounded-full flex-shrink-0",
6572
+ style: { backgroundColor: colorScheme.darkColor ?? colorScheme.color }
6573
+ }), children]
6574
+ });
6575
+ }
6576
+ //#endregion
6577
+ //#region src/views/Kanban/BoardColumn.tsx
6578
+ var BoardColumn = memo(function BoardColumn({ id, title, items, ItemComponent, isDragging, isDragOverColumn, allowReorder = false, loading = false, hasMore = false, onLoadMore, onAddItem, totalCount, color, style }) {
6579
+ const { setNodeRef, attributes, listeners, isDragging: isColumnBeingDragged, transform, transition } = useSortable({
6580
+ id,
6581
+ data: { type: "COLUMN" },
6582
+ disabled: !allowReorder
6583
+ });
6584
+ const combinedStyle = useMemo(() => ({
6585
+ ...style,
6586
+ transform: CSS.Translate.toString(transform),
6587
+ transition,
6588
+ zIndex: isColumnBeingDragged ? 2 : 1
6589
+ }), [
6590
+ style,
6591
+ transform,
6592
+ transition,
6593
+ isColumnBeingDragged
6594
+ ]);
6595
+ const dragListeners = allowReorder ? listeners : {};
6596
+ const columnClassName = useMemo(() => cls("border h-full w-80 min-w-80 mx-2 flex flex-col rounded-md border-surface-200 dark:border-surface-800", isColumnBeingDragged ? "ring-2 ring-primary" : ""), [isColumnBeingDragged]);
6597
+ const headerClassName = useMemo(() => cls("flex items-center justify-between px-2 rounded-t-md transition-colors duration-200 ease-in-out", isColumnBeingDragged ? "bg-surface-100 dark:bg-surface-700" : "bg-surface-50 hover:bg-surface-100 dark:bg-surface-800 dark:hover:bg-surface-700", allowReorder ? "cursor-grab" : ""), [isColumnBeingDragged, allowReorder]);
6598
+ const itemIds = useMemo(() => items.map((i) => i.id), [items]);
6599
+ return /* @__PURE__ */ jsxs("div", {
6600
+ ref: setNodeRef,
6601
+ style: combinedStyle,
6602
+ ...attributes,
6603
+ className: columnClassName,
6604
+ children: [/* @__PURE__ */ jsxs("div", {
6605
+ ...dragListeners,
6606
+ className: headerClassName,
6607
+ children: [/* @__PURE__ */ jsxs("div", {
6608
+ className: "flex items-center gap-2",
6609
+ children: [/* @__PURE__ */ jsx(BoardColumnTitle, {
6610
+ "aria-label": `${title} item list`,
6611
+ color,
6612
+ children: title
6613
+ }), totalCount !== void 0 && /* @__PURE__ */ jsx("span", {
6614
+ className: "text-xs text-surface-500 dark:text-surface-400",
6615
+ children: totalCount
6616
+ })]
6617
+ }), onAddItem && /* @__PURE__ */ jsx(IconButton, {
6618
+ size: "small",
6619
+ onClick: (e) => {
6620
+ e.stopPropagation();
6621
+ onAddItem();
6622
+ },
6623
+ className: "opacity-60 hover:opacity-100",
6624
+ children: /* @__PURE__ */ jsx(PlusIcon, { size: iconSize.small })
6625
+ })]
6626
+ }), /* @__PURE__ */ jsx(SortableContext, {
6627
+ items: itemIds,
6628
+ strategy: verticalListSortingStrategy,
6629
+ children: /* @__PURE__ */ jsx(BoardSortableList, {
6630
+ columnId: id,
6631
+ items,
6632
+ ItemComponent,
6633
+ isDragging,
6634
+ isDragOverColumn,
6635
+ loading,
6636
+ hasMore,
6637
+ onLoadMore
6638
+ })
6639
+ })]
6640
+ });
6641
+ });
6642
+ //#endregion
6643
+ //#region src/views/Kanban/Board.tsx
6644
+ function Board({ data, columns: columnsProp, columnLabels, columnColors, className, assignColumn, allowColumnReorder = false, onColumnReorder, onItemsReorder, ItemComponent, columnLoadingState, onLoadMoreColumn, onAddItemToColumn, AddColumnComponent }) {
6645
+ const [activeItem, setActiveItem] = useState(null);
6646
+ const [activeColumn, setActiveColumn] = useState(null);
6647
+ const [isDragging, setIsDragging] = useState(false);
6648
+ const [dragOverColumnId, setDragOverColumnId] = useState(null);
6649
+ const grabOffsetRef = useRef({
6650
+ x: 0,
6651
+ y: 0
6652
+ });
6653
+ const [overlayPos, setOverlayPos] = useState(null);
6654
+ const handleMouseMove = useCallback((e) => {
6655
+ setOverlayPos({
6656
+ x: e.clientX - grabOffsetRef.current.x,
6657
+ y: e.clientY - grabOffsetRef.current.y
6658
+ });
6659
+ }, []);
6660
+ useEffect(() => {
6661
+ return () => {
6662
+ window.removeEventListener("mousemove", handleMouseMove);
6663
+ window.removeEventListener("pointermove", handleMouseMove);
6664
+ };
6665
+ }, [handleMouseMove]);
6666
+ const [itemMapState, setItemMapState] = useState(() => {
6667
+ const dataColumnMap = data.reduce((prev, item) => ({
6668
+ ...prev,
6669
+ [item.id]: assignColumn(item)
6670
+ }), {});
6671
+ return columnsProp.reduce((previous, column) => ({
6672
+ ...previous,
6673
+ [column]: data.filter((item) => dataColumnMap[item.id] === column)
6674
+ }), {});
6675
+ });
6676
+ const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 5 } }));
6677
+ useEffect(() => {
6678
+ if (isDragging) return;
6679
+ const dataColumnMap = data.reduce((prev, item) => ({
6680
+ ...prev,
6681
+ [item.id]: assignColumn(item)
6682
+ }), {});
6683
+ const newItemMap = columnsProp.reduce((previous, column) => ({
6684
+ ...previous,
6685
+ [column]: data.filter((item) => dataColumnMap[item.id] === column)
6686
+ }), {});
6687
+ setItemMapState((prevMap) => {
6688
+ let changed = false;
6689
+ for (const col of columnsProp) {
6690
+ const prevItems = prevMap[col] ?? [];
6691
+ const newItems = newItemMap[col] ?? [];
6692
+ if (prevItems.length !== newItems.length) {
6693
+ changed = true;
6694
+ continue;
6695
+ }
6696
+ for (let i = 0; i < prevItems.length; i++) if (prevItems[i].id !== newItems[i].id || prevItems[i].data !== newItems[i].data) {
6697
+ changed = true;
6698
+ break;
6699
+ }
6700
+ }
6701
+ if (!changed) return prevMap;
6702
+ const updated = {};
6703
+ for (const col of columnsProp) {
6704
+ const prevItems = prevMap[col] ?? [];
6705
+ const newItems = newItemMap[col] ?? [];
6706
+ const prevById = /* @__PURE__ */ new Map();
6707
+ for (const item of prevItems) prevById.set(item.id, item);
6708
+ updated[col] = newItems.map((newItem) => {
6709
+ const prev = prevById.get(newItem.id);
6710
+ if (prev && prev.data === newItem.data) return prev;
6711
+ return newItem;
6712
+ });
6713
+ }
6714
+ return updated;
6715
+ });
6716
+ }, [
6717
+ data,
6718
+ columnsProp,
6719
+ assignColumn
6720
+ ]);
6721
+ const findColumnByItemId = (id) => {
6722
+ return Object.keys(itemMapState).find((col) => itemMapState[col]?.some((i) => i.id === id));
6723
+ };
6724
+ const handleDragStart = (event) => {
6725
+ setIsDragging(true);
6726
+ setDragOverColumnId(null);
6727
+ const { active } = event;
6728
+ const activatorEvt = event.activatorEvent;
6729
+ if (activatorEvt) {
6730
+ const target = activatorEvt.target;
6731
+ const rect = (target.closest("[role='button']") ?? target).getBoundingClientRect();
6732
+ grabOffsetRef.current = {
6733
+ x: activatorEvt.clientX - rect.left,
6734
+ y: activatorEvt.clientY - rect.top
6735
+ };
6736
+ setOverlayPos({
6737
+ x: rect.left,
6738
+ y: rect.top
6739
+ });
6740
+ }
6741
+ window.addEventListener("mousemove", handleMouseMove);
6742
+ window.addEventListener("pointermove", handleMouseMove);
6743
+ if (active.data.current?.type === "COLUMN") {
6744
+ const columnId = active.id;
6745
+ const column = columnsProp.find((col) => String(col) === columnId);
6746
+ if (column) setActiveColumn(column);
6747
+ } else if (active.data.current?.type === "ITEM") {
6748
+ const columnId = findColumnByItemId(active.id);
6749
+ if (columnId) {
6750
+ const item = itemMapState[columnId]?.find((i) => i.id === active.id);
6751
+ setActiveItem(item || null);
6752
+ }
6753
+ }
6754
+ };
6755
+ const handleDragOver = (event) => {
6756
+ const { active, over } = event;
6757
+ if (!over) {
6758
+ setDragOverColumnId(null);
6759
+ return;
6760
+ }
6761
+ let currentHoveredColumnId = null;
6762
+ const overId = over.id;
6763
+ const overDataType = over.data.current?.type;
6764
+ if (overDataType === "ITEM-LIST" || overDataType === "COLUMN") currentHoveredColumnId = overId;
6765
+ else if (overDataType === "ITEM") currentHoveredColumnId = findColumnByItemId(overId) || null;
6766
+ else if (columnsProp.includes(overId)) currentHoveredColumnId = overId;
6767
+ setDragOverColumnId(currentHoveredColumnId);
6768
+ if (active.data.current?.type !== "ITEM") return;
6769
+ const activeId = active.id;
6770
+ const activeColumn = findColumnByItemId(activeId);
6771
+ let overColumnForMove = findColumnByItemId(overId);
6772
+ if (!overColumnForMove && overDataType === "ITEM-LIST") overColumnForMove = overId;
6773
+ if (!overColumnForMove && columnsProp.includes(overId)) overColumnForMove = overId;
6774
+ if (!activeColumn || !overColumnForMove) return;
6775
+ if (activeColumn === overColumnForMove) return;
6776
+ if (itemMapState[overColumnForMove]?.some((i) => i.id === activeId)) return;
6777
+ setItemMapState((currentMap) => {
6778
+ const activeItems = [...currentMap[activeColumn] || []];
6779
+ const overItems = [...currentMap[overColumnForMove] || []];
6780
+ const activeIndex = activeItems.findIndex((i) => i.id === activeId);
6781
+ if (activeIndex === -1) return currentMap;
6782
+ let overIndex;
6783
+ if (overDataType === "ITEM-LIST" || columnsProp.includes(overId) && !findColumnByItemId(overId)) overIndex = overItems.length;
6784
+ else {
6785
+ overIndex = overItems.findIndex((i) => i.id === overId);
6786
+ if (overIndex !== -1) {
6787
+ const modifier = (active.rect.current.translated?.top ?? 0) + (active.rect.current.translated?.height ?? 0) / 2 > (over?.rect.top ?? 0) + (over?.rect.height ?? 0) / 2 ? 1 : 0;
6788
+ overIndex = overIndex >= 0 ? overIndex + modifier : overItems.length;
6789
+ } else overIndex = overItems.length;
6790
+ }
6791
+ const newItemMap = { ...currentMap };
6792
+ const [moved] = activeItems.splice(activeIndex, 1);
6793
+ overItems.splice(overIndex, 0, moved);
6794
+ newItemMap[activeColumn] = activeItems;
6795
+ newItemMap[overColumnForMove] = overItems;
6796
+ return newItemMap;
6797
+ });
6798
+ };
6799
+ const handleDragEnd = (event) => {
6800
+ const { active, over } = event;
6801
+ window.removeEventListener("mousemove", handleMouseMove);
6802
+ window.removeEventListener("pointermove", handleMouseMove);
6803
+ setOverlayPos(null);
6804
+ setIsDragging(false);
6805
+ setActiveItem(null);
6806
+ setActiveColumn(null);
6807
+ setDragOverColumnId(null);
6808
+ if (!over) return;
6809
+ const activeId = active.id;
6810
+ const overId = over.id;
6811
+ if (active.data.current?.type === "COLUMN") {
6812
+ if (activeId !== overId) {
6813
+ const oldIndex = columnsProp.indexOf(activeId);
6814
+ const newIndex = columnsProp.indexOf(overId);
6815
+ if (oldIndex !== -1 && newIndex !== -1) {
6816
+ const reordered = arrayMove(columnsProp, oldIndex, newIndex);
6817
+ onColumnReorder?.(reordered);
6818
+ }
6819
+ }
6820
+ return;
6821
+ }
6822
+ const activeCol = findColumnByItemId(activeId);
6823
+ let overCol = findColumnByItemId(overId);
6824
+ if (!overCol) {
6825
+ if (over.data.current?.type === "ITEM-LIST" || columnsProp.includes(overId)) overCol = overId;
6826
+ }
6827
+ if (!activeCol || !overCol) return;
6828
+ const isSameColumn = activeCol === overCol;
6829
+ const activeItems = itemMapState[activeCol] || [];
6830
+ const overItems = itemMapState[overCol] || [];
6831
+ const activeIndex = activeItems.findIndex((i) => i.id === activeId);
6832
+ let overIndex;
6833
+ if (over.id === overCol) overIndex = overItems.length;
6834
+ else overIndex = overItems.findIndex((i) => i.id === overId);
6835
+ if (activeIndex === -1 || overIndex === -1) return;
6836
+ let finalItems = [];
6837
+ if (isSameColumn) finalItems = arrayMove(activeItems, activeIndex, overIndex);
6838
+ else {
6839
+ const newActiveItems = [...activeItems];
6840
+ const newOverItems = [...overItems];
6841
+ const [moved] = newActiveItems.splice(activeIndex, 1);
6842
+ newOverItems.splice(overIndex, 0, moved);
6843
+ finalItems = [...newActiveItems, ...newOverItems];
6844
+ }
6845
+ const fullFlattenedList = [];
6846
+ columnsProp.forEach((col) => {
6847
+ if (col === activeCol) if (isSameColumn) fullFlattenedList.push(...finalItems);
6848
+ else fullFlattenedList.push(...activeItems.filter((i) => i.id !== activeId));
6849
+ else if (col === overCol) {
6850
+ const newOverItems = [...overItems];
6851
+ const [moved] = [...activeItems].splice(activeIndex, 1);
6852
+ newOverItems.splice(overIndex, 0, moved);
6853
+ fullFlattenedList.push(...newOverItems);
6854
+ } else fullFlattenedList.push(...itemMapState[col] || []);
6855
+ });
6856
+ onItemsReorder?.(fullFlattenedList, {
6857
+ itemId: activeId,
6858
+ sourceColumn: activeCol,
6859
+ targetColumn: overCol
6860
+ });
6861
+ };
6862
+ return /* @__PURE__ */ jsxs(DndContext, {
6863
+ sensors,
6864
+ onDragStart: handleDragStart,
6865
+ onDragOver: handleDragOver,
6866
+ onDragEnd: handleDragEnd,
6867
+ children: [/* @__PURE__ */ jsxs("div", {
6868
+ className: cls("flex flex-row h-full w-full overflow-x-auto p-4 select-none items-start", className),
6869
+ children: [/* @__PURE__ */ jsx(SortableContext, {
6870
+ items: columnsProp,
6871
+ children: columnsProp.map((col, index) => {
6872
+ const colItems = itemMapState[col] || [];
6873
+ const loadingState = columnLoadingState?.[col];
6874
+ return /* @__PURE__ */ jsx(BoardColumn, {
6875
+ id: String(col),
6876
+ title: columnLabels?.[col] ?? String(col),
6877
+ items: colItems,
6878
+ index,
6879
+ ItemComponent,
6880
+ isDragging,
6881
+ isDragOverColumn: dragOverColumnId === String(col),
6882
+ allowReorder: allowColumnReorder,
6883
+ loading: loadingState?.loading,
6884
+ hasMore: loadingState?.hasMore,
6885
+ totalCount: loadingState?.totalCount,
6886
+ color: columnColors?.[col],
6887
+ onLoadMore: onLoadMoreColumn ? () => onLoadMoreColumn(col) : void 0,
6888
+ onAddItem: onAddItemToColumn ? () => onAddItemToColumn(col) : void 0
6889
+ }, String(col));
6890
+ })
6891
+ }), AddColumnComponent]
6892
+ }), typeof document !== "undefined" && createPortal(/* @__PURE__ */ jsx(DragOverlay, {
6893
+ dropAnimation: null,
6894
+ children: isDragging && activeItem && /* @__PURE__ */ jsx("div", {
6895
+ style: {
6896
+ position: "fixed",
6897
+ left: overlayPos?.x ?? 0,
6898
+ top: overlayPos?.y ?? 0,
6899
+ pointerEvents: "none",
6900
+ zIndex: 9999
6901
+ },
6902
+ children: /* @__PURE__ */ jsx(ItemComponent, {
6903
+ item: activeItem,
6904
+ isDragging: true,
6905
+ isClone: true
6906
+ })
6907
+ })
6908
+ }), document.body)]
6909
+ });
6910
+ }
6911
+ //#endregion
6912
+ //#region src/views/KanbanView.tsx
6913
+ function KanbanView(props) {
6914
+ return /* @__PURE__ */ jsx(Board, { ...props });
6915
+ }
6916
+ //#endregion
6917
+ //#region src/views/CollectionView/CollectionViewToolbar.tsx
6918
+ var VIEW_MODE_ICONS = {
6919
+ list: /* @__PURE__ */ jsx(LayoutList, { size: iconSize.small }),
6920
+ table: /* @__PURE__ */ jsx(Table2, { size: iconSize.small }),
6921
+ cards: /* @__PURE__ */ jsx(LayoutGrid, { size: iconSize.small }),
6922
+ kanban: /* @__PURE__ */ jsx(Kanban, { size: iconSize.small })
6923
+ };
6924
+ var VIEW_MODE_LABELS = {
6925
+ list: "List",
6926
+ table: "Table",
6927
+ cards: "Cards",
6928
+ kanban: "Board"
6929
+ };
6930
+ var SIZE_LABELS = {
6931
+ xs: "Extra Small",
6932
+ s: "Small",
6933
+ m: "Medium",
6934
+ l: "Large",
6935
+ xl: "Extra Large"
6936
+ };
6937
+ /**
6938
+ * Toolbar for the headless CollectionView.
6939
+ *
6940
+ * Renders a search bar, view mode toggle (popover with toggle button group),
6941
+ * optional size selector, optional kanban property selector, and action slots.
6942
+ *
6943
+ * @group Collection View
6944
+ */
6945
+ function CollectionViewToolbar({ viewMode, onViewModeChange, enabledViews = [
6946
+ "list",
6947
+ "table",
6948
+ "cards",
6949
+ "kanban"
6950
+ ], size = "m", onSizeChange, searchString, onSearchChange, loading, actionsStart, actionsEnd, compact, kanbanPropertyOptions, selectedKanbanProperty, onKanbanPropertyChange }) {
6951
+ const [popoverOpen, setPopoverOpen] = useState(false);
6952
+ const viewOptions = enabledViews.map((mode) => ({
6953
+ value: mode,
6954
+ label: VIEW_MODE_LABELS[mode],
6955
+ icon: VIEW_MODE_ICONS[mode]
6956
+ }));
6957
+ const handleViewModeChange = useCallback((mode) => {
6958
+ onViewModeChange?.(mode);
6959
+ }, [onViewModeChange]);
6960
+ const handleSizeChange = useCallback((value) => {
6961
+ onSizeChange?.(value);
6962
+ }, [onSizeChange]);
6963
+ const handleKanbanPropertyChange = useCallback((value) => {
6964
+ onKanbanPropertyChange?.(value);
6965
+ }, [onKanbanPropertyChange]);
6966
+ const showViewToggle = onViewModeChange && enabledViews.length > 1;
6967
+ const showSizeSelector = onSizeChange && viewMode !== "kanban";
6968
+ const showKanbanSelector = kanbanPropertyOptions && kanbanPropertyOptions.length > 0 && viewMode === "kanban" && onKanbanPropertyChange;
6969
+ const showPopover = showViewToggle || showSizeSelector || showKanbanSelector;
6970
+ return /* @__PURE__ */ jsxs("div", {
6971
+ className: cls("flex items-center gap-2 px-2 flex-shrink-0", "border-b border-surface-200 dark:border-surface-800", compact ? "py-0.5 gap-1" : "py-1"),
6972
+ children: [
6973
+ actionsStart,
6974
+ onSearchChange && /* @__PURE__ */ jsx(SearchBar, {
6975
+ onTextSearch: onSearchChange,
6976
+ size: "small",
6977
+ initialValue: searchString,
6978
+ loading,
6979
+ expandable: true
6980
+ }),
6981
+ /* @__PURE__ */ jsx("div", { className: "flex-1" }),
6982
+ actionsEnd,
6983
+ showPopover && /* @__PURE__ */ jsx(Popover, {
6984
+ open: popoverOpen,
6985
+ onOpenChange: setPopoverOpen,
6986
+ side: "bottom",
6987
+ align: "end",
6988
+ trigger: /* @__PURE__ */ jsx(IconButton, {
6989
+ size: "small",
6990
+ onClick: () => setPopoverOpen((prev) => !prev),
6991
+ children: /* @__PURE__ */ jsx(Settings2, { size: iconSize.small })
6992
+ }),
6993
+ children: /* @__PURE__ */ jsxs("div", {
6994
+ className: "p-3 min-w-[200px] flex flex-col gap-3",
6995
+ children: [
6996
+ showViewToggle && /* @__PURE__ */ jsxs("div", {
6997
+ className: "flex flex-col gap-1",
6998
+ children: [/* @__PURE__ */ jsx(Typography, {
6999
+ variant: "caption",
7000
+ color: "secondary",
7001
+ className: "font-medium uppercase tracking-wider",
7002
+ children: "View"
7003
+ }), /* @__PURE__ */ jsx(ToggleButtonGroup, {
7004
+ value: viewMode,
7005
+ onValueChange: handleViewModeChange,
7006
+ options: viewOptions
7007
+ })]
7008
+ }),
7009
+ showSizeSelector && /* @__PURE__ */ jsxs("div", {
7010
+ className: "flex flex-col gap-1",
7011
+ children: [/* @__PURE__ */ jsx(Typography, {
7012
+ variant: "caption",
7013
+ color: "secondary",
7014
+ className: "font-medium uppercase tracking-wider",
7015
+ children: "Size"
7016
+ }), /* @__PURE__ */ jsx(Select, {
7017
+ value: size,
7018
+ onValueChange: handleSizeChange,
7019
+ size: "small",
7020
+ children: Object.keys(SIZE_LABELS).map((sizeKey) => /* @__PURE__ */ jsx(SelectItem, {
7021
+ value: sizeKey,
7022
+ children: SIZE_LABELS[sizeKey]
7023
+ }, sizeKey))
7024
+ })]
7025
+ }),
7026
+ showKanbanSelector && /* @__PURE__ */ jsxs("div", {
7027
+ className: "flex flex-col gap-1",
7028
+ children: [/* @__PURE__ */ jsx(Typography, {
7029
+ variant: "caption",
7030
+ color: "secondary",
7031
+ className: "font-medium uppercase tracking-wider",
7032
+ children: "Group by"
7033
+ }), /* @__PURE__ */ jsx(Select, {
7034
+ value: selectedKanbanProperty,
7035
+ onValueChange: handleKanbanPropertyChange,
7036
+ size: "small",
7037
+ children: kanbanPropertyOptions.map((option) => /* @__PURE__ */ jsx(SelectItem, {
7038
+ value: option.key,
7039
+ children: option.label
7040
+ }, option.key))
7041
+ })]
7042
+ })
7043
+ ]
7044
+ })
7045
+ })
7046
+ ]
7047
+ });
7048
+ }
7049
+ //#endregion
7050
+ //#region src/views/CollectionView/DefaultCellRenderer.tsx
7051
+ /**
7052
+ * Resolve an enum key to its display label and optional color.
7053
+ */
7054
+ function resolveEnumLabel(enumValues, value) {
7055
+ if (!enumValues) return void 0;
7056
+ const key = String(value);
7057
+ if (enumValues instanceof Map) {
7058
+ const config = enumValues.get(value);
7059
+ if (!config) return void 0;
7060
+ if (typeof config === "string") return { label: config };
7061
+ return {
7062
+ label: config.label,
7063
+ color: config.color
7064
+ };
7065
+ }
7066
+ const config = enumValues[key];
7067
+ if (!config) return void 0;
7068
+ if (typeof config === "string") return { label: config };
7069
+ return {
7070
+ label: config.label,
7071
+ color: config.color
7072
+ };
7073
+ }
7074
+ /**
7075
+ * Format a date value using Intl.DateTimeFormat.
7076
+ */
7077
+ function formatDate(value, includeTime) {
7078
+ if (value == null) return "—";
7079
+ const date = value instanceof Date ? value : new Date(String(value));
7080
+ if (isNaN(date.getTime())) return String(value);
7081
+ const options = includeTime ? {
7082
+ year: "numeric",
7083
+ month: "short",
7084
+ day: "numeric",
7085
+ hour: "2-digit",
7086
+ minute: "2-digit"
7087
+ } : {
7088
+ year: "numeric",
7089
+ month: "short",
7090
+ day: "numeric"
7091
+ };
7092
+ return new Intl.DateTimeFormat(void 0, options).format(date);
7093
+ }
7094
+ /**
7095
+ * Type guard for geopoint-like objects.
7096
+ */
7097
+ function isGeoPoint(value) {
7098
+ if (typeof value !== "object" || value === null) return false;
7099
+ const obj = value;
7100
+ return typeof obj.lat === "number" && typeof obj.lng === "number";
7101
+ }
7102
+ /**
7103
+ * Default cell renderer for the headless CollectionView.
7104
+ * Handles all built-in property types without depending on any Rebase core types.
7105
+ *
7106
+ * @group Preview components
7107
+ */
7108
+ function DefaultCellRenderer({ row, propertyKey, property, value, size, width, height }) {
7109
+ if (value === null || value === void 0) return /* @__PURE__ */ jsx(Typography, {
7110
+ variant: "body2",
7111
+ color: "secondary",
7112
+ className: "px-1",
7113
+ children: "—"
7114
+ });
7115
+ if (property.Preview) {
7116
+ const PreviewComponent = property.Preview;
7117
+ return /* @__PURE__ */ jsx(PreviewComponent, {
7118
+ row,
7119
+ propertyKey,
7120
+ property,
7121
+ value,
7122
+ size,
7123
+ width,
7124
+ height
7125
+ });
7126
+ }
7127
+ switch (property.type) {
7128
+ case "string": return renderString(property, value);
7129
+ case "number": return renderNumber(property, value);
7130
+ case "boolean": return renderBoolean(value);
7131
+ case "date": return renderDate(property, value);
7132
+ case "array": return renderArray(property, value);
7133
+ case "map": return renderMap(value);
7134
+ case "reference":
7135
+ case "relation": return renderReference(value);
7136
+ case "geopoint": return renderGeopoint(value);
7137
+ default: return /* @__PURE__ */ jsx(Typography, {
7138
+ variant: "body2",
7139
+ color: "secondary",
7140
+ noWrap: true,
7141
+ className: "px-1",
7142
+ children: JSON.stringify(value)
7143
+ });
7144
+ }
7145
+ }
7146
+ function renderString(property, value) {
7147
+ const strValue = String(value);
7148
+ if (property.enum) {
7149
+ const resolved = resolveEnumLabel(property.enum, value);
7150
+ return /* @__PURE__ */ jsx(Chip, {
7151
+ size: "small",
7152
+ colorScheme: resolved?.color ? {
7153
+ color: resolved.color,
7154
+ text: "#fff"
7155
+ } : void 0,
7156
+ children: resolved?.label ?? strValue
7157
+ });
7158
+ }
7159
+ if (property.previewAsTag) return /* @__PURE__ */ jsx(Chip, {
7160
+ size: "small",
7161
+ children: strValue
7162
+ });
7163
+ if (property.url) return /* @__PURE__ */ jsx(Typography, {
7164
+ variant: "body2",
7165
+ noWrap: true,
7166
+ component: "a",
7167
+ href: typeof property.url === "string" ? property.url : strValue,
7168
+ target: "_blank",
7169
+ rel: "noopener noreferrer",
7170
+ className: cls("px-1 text-primary hover:underline cursor-pointer"),
7171
+ children: strValue
7172
+ });
7173
+ if (property.email) return /* @__PURE__ */ jsx(Typography, {
7174
+ variant: "body2",
7175
+ noWrap: true,
7176
+ component: "a",
7177
+ href: `mailto:${strValue}`,
7178
+ className: cls("px-1 text-primary hover:underline cursor-pointer"),
7179
+ children: strValue
7180
+ });
7181
+ if (property.markdown) return /* @__PURE__ */ jsx("div", {
7182
+ className: "px-1 max-h-[100px] overflow-hidden",
7183
+ children: /* @__PURE__ */ jsx(Markdown, {
7184
+ source: strValue,
7185
+ size: "small"
7186
+ })
7187
+ });
7188
+ if (property.storage) return /* @__PURE__ */ jsxs("div", {
7189
+ className: cls("px-1 flex items-center justify-center", "w-[40px] h-[40px] rounded overflow-hidden"),
7190
+ children: [strValue ? /* @__PURE__ */ jsx("img", {
7191
+ src: strValue,
7192
+ alt: "",
7193
+ className: "w-full h-full object-cover",
7194
+ onError: (e) => {
7195
+ const target = e.currentTarget;
7196
+ target.style.display = "none";
7197
+ const fallback = target.nextElementSibling;
7198
+ if (fallback instanceof HTMLElement) fallback.style.display = "flex";
7199
+ }
7200
+ }) : null, /* @__PURE__ */ jsx("div", {
7201
+ className: cls("w-full h-full items-center justify-center rounded", "bg-surface-100 dark:bg-surface-800 text-text-secondary dark:text-text-secondary-dark", strValue ? "hidden" : "flex"),
7202
+ children: /* @__PURE__ */ jsx(ImageIcon$1, { size: iconSize.small })
7203
+ })]
7204
+ });
7205
+ return /* @__PURE__ */ jsx(Tooltip, {
7206
+ title: strValue.length > 50 ? strValue : void 0,
7207
+ side: "bottom",
7208
+ children: /* @__PURE__ */ jsx(Typography, {
7209
+ variant: "body2",
7210
+ noWrap: true,
7211
+ className: "px-1",
7212
+ children: strValue
7213
+ })
7214
+ });
7215
+ }
7216
+ function renderNumber(property, value) {
7217
+ const numStr = String(value);
7218
+ if (property.enum) {
7219
+ const resolved = resolveEnumLabel(property.enum, value);
7220
+ return /* @__PURE__ */ jsx(Chip, {
7221
+ size: "small",
7222
+ colorScheme: resolved?.color ? {
7223
+ color: resolved.color,
7224
+ text: "#fff"
7225
+ } : void 0,
7226
+ children: resolved?.label ?? numStr
7227
+ });
7228
+ }
7229
+ return /* @__PURE__ */ jsx(Typography, {
7230
+ variant: "body2",
7231
+ noWrap: true,
7232
+ align: "right",
7233
+ className: "px-1 tabular-nums",
7234
+ children: numStr
7235
+ });
7236
+ }
7237
+ function renderBoolean(value) {
7238
+ return /* @__PURE__ */ jsx("div", {
7239
+ className: "px-1 flex items-center",
7240
+ children: /* @__PURE__ */ jsx(BooleanSwitch, {
7241
+ value: !!value,
7242
+ size: "small",
7243
+ disabled: true
7244
+ })
7245
+ });
7246
+ }
7247
+ function renderDate(property, value) {
7248
+ return /* @__PURE__ */ jsx(Typography, {
7249
+ variant: "body2",
7250
+ noWrap: true,
7251
+ className: "px-1 tabular-nums",
7252
+ children: formatDate(value, property.mode === "date_time")
7253
+ });
7254
+ }
7255
+ function renderArray(property, value) {
7256
+ if (!Array.isArray(value)) return /* @__PURE__ */ jsx(Typography, {
7257
+ variant: "body2",
7258
+ color: "secondary",
7259
+ className: "px-1",
7260
+ children: "—"
7261
+ });
7262
+ if (property.of?.enum && value.length > 0) return /* @__PURE__ */ jsx("div", {
7263
+ className: "px-1 flex flex-wrap gap-1 overflow-hidden",
7264
+ children: value.map((item, i) => {
7265
+ const resolved = resolveEnumLabel(property.of.enum, item);
7266
+ return /* @__PURE__ */ jsx(Chip, {
7267
+ size: "smallest",
7268
+ colorScheme: resolved?.color ? {
7269
+ color: resolved.color,
7270
+ text: "#fff"
7271
+ } : void 0,
7272
+ children: resolved?.label ?? String(item)
7273
+ }, i);
7274
+ })
7275
+ });
7276
+ if (value.length > 0 && value.every((item) => typeof item === "string")) return /* @__PURE__ */ jsx(Typography, {
7277
+ variant: "body2",
7278
+ noWrap: true,
7279
+ className: "px-1",
7280
+ children: value.join(", ")
7281
+ });
7282
+ return /* @__PURE__ */ jsxs(Typography, {
7283
+ variant: "body2",
7284
+ color: "secondary",
7285
+ className: "px-1",
7286
+ children: [
7287
+ value.length,
7288
+ " ",
7289
+ value.length === 1 ? "item" : "items"
7290
+ ]
7291
+ });
7292
+ }
7293
+ function renderMap(value) {
7294
+ if (typeof value !== "object" || value === null) return /* @__PURE__ */ jsx(Typography, {
7295
+ variant: "body2",
7296
+ color: "secondary",
7297
+ className: "px-1",
7298
+ children: "—"
7299
+ });
7300
+ const fieldCount = Object.keys(value).length;
7301
+ return /* @__PURE__ */ jsxs(Typography, {
7302
+ variant: "body2",
7303
+ color: "secondary",
7304
+ className: "px-1",
7305
+ children: [
7306
+ fieldCount,
7307
+ " ",
7308
+ fieldCount === 1 ? "field" : "fields"
7309
+ ]
7310
+ });
7311
+ }
7312
+ function renderReference(value) {
7313
+ return /* @__PURE__ */ jsx(Typography, {
7314
+ variant: "body2",
7315
+ noWrap: true,
7316
+ className: "px-1",
7317
+ children: String(value)
7318
+ });
7319
+ }
7320
+ function renderGeopoint(value) {
7321
+ if (isGeoPoint(value)) return /* @__PURE__ */ jsxs(Typography, {
7322
+ variant: "body2",
7323
+ noWrap: true,
7324
+ className: "px-1 tabular-nums",
7325
+ children: [
7326
+ value.lat.toFixed(6),
7327
+ ", ",
7328
+ value.lng.toFixed(6)
7329
+ ]
7330
+ });
7331
+ return /* @__PURE__ */ jsx(Typography, {
7332
+ variant: "body2",
7333
+ color: "secondary",
7334
+ className: "px-1",
7335
+ children: String(value)
7336
+ });
7337
+ }
7338
+ //#endregion
7339
+ //#region src/views/CollectionView/utils.ts
7340
+ /**
7341
+ * Traverse an object by dot-separated path.
7342
+ * Returns `undefined` if any segment is missing.
7343
+ */
7344
+ function getValueInPath(obj, path) {
7345
+ if (!obj) return void 0;
7346
+ const parts = path.split(".");
7347
+ let current = obj;
7348
+ for (const part of parts) {
7349
+ if (current === null || current === void 0 || typeof current !== "object") return void 0;
7350
+ current = current[part];
7351
+ }
7352
+ return current;
7353
+ }
7354
+ //#endregion
7355
+ //#region src/views/CollectionView/CollectionTableView.tsx
7356
+ var DEFAULT_COLUMN_WIDTHS = {
7357
+ string: 200,
7358
+ number: 140,
7359
+ date: 160,
7360
+ boolean: 120,
7361
+ array: 200,
7362
+ map: 200,
7363
+ reference: 200,
7364
+ relation: 200,
7365
+ geopoint: 180
7366
+ };
7367
+ var FALLBACK_COLUMN_WIDTH = 200;
7368
+ var SIZE_TO_ROW_HEIGHT = {
7369
+ xs: 36,
7370
+ s: 44,
7371
+ m: 52,
7372
+ l: 64,
7373
+ xl: 80
7374
+ };
7375
+ var SORTABLE_TYPES = new Set([
7376
+ "string",
7377
+ "number",
7378
+ "date"
7379
+ ]);
7380
+ var VIEW_SIZE_TO_RENDERER_SIZE = {
7381
+ xs: "tiny",
7382
+ s: "small",
7383
+ m: "medium",
7384
+ l: "large",
7385
+ xl: "large"
7386
+ };
7387
+ /**
7388
+ * Headless table view that wraps {@link VirtualTable}.
7389
+ *
7390
+ * Converts property configurations into virtual table columns and wires up
7391
+ * sorting, pagination, and cell rendering without coupling to any data layer.
7392
+ *
7393
+ * @group Collection View
7394
+ */
7395
+ function CollectionTableView({ dataController, properties, propertiesOrder, displayedColumnIds, onRowClick, cellRenderer, size = "m", emptyComponent, hoverRow = true, className, onColumnResize, onColumnsOrderChange }) {
7396
+ const columns = useMemo(() => {
7397
+ const order = propertiesOrder ?? Object.keys(properties);
7398
+ return (displayedColumnIds ? order.filter((key) => displayedColumnIds.includes(key)) : order.filter((key) => {
7399
+ const prop = properties[key];
7400
+ return prop && !prop.hideFromCollection;
7401
+ })).map((key) => {
7402
+ const prop = properties[key];
7403
+ if (!prop) return null;
7404
+ return {
7405
+ key,
7406
+ width: prop.columnWidth || DEFAULT_COLUMN_WIDTHS[prop.type] || FALLBACK_COLUMN_WIDTH,
7407
+ title: prop.name,
7408
+ sortable: SORTABLE_TYPES.has(prop.type),
7409
+ resizable: true
7410
+ };
7411
+ }).filter((col) => col !== null);
7412
+ }, [
7413
+ properties,
7414
+ propertiesOrder,
7415
+ displayedColumnIds
7416
+ ]);
7417
+ const rowHeight = SIZE_TO_ROW_HEIGHT[size];
7418
+ const rendererSize = VIEW_SIZE_TO_RENDERER_SIZE[size];
7419
+ const tableCellRenderer = useCallback((params) => {
7420
+ if (!params.rowData) return null;
7421
+ const propertyConfig = properties[params.column.key];
7422
+ if (!propertyConfig) return null;
7423
+ const value = getValueInPath(params.rowData, params.column.key);
7424
+ const cellProps = {
7425
+ row: params.rowData,
7426
+ propertyKey: params.column.key,
7427
+ property: propertyConfig,
7428
+ value,
7429
+ size: rendererSize,
7430
+ width: params.width
7431
+ };
7432
+ if (cellRenderer) {
7433
+ const custom = cellRenderer(cellProps);
7434
+ if (custom !== void 0) return /* @__PURE__ */ jsx("div", {
7435
+ className: "flex items-center h-full px-1 overflow-hidden",
7436
+ children: custom
7437
+ });
7438
+ }
7439
+ return /* @__PURE__ */ jsx("div", {
7440
+ className: "flex items-center h-full px-1 overflow-hidden",
7441
+ children: /* @__PURE__ */ jsx(DefaultCellRenderer, { ...cellProps })
7442
+ });
7443
+ }, [
7444
+ properties,
7445
+ cellRenderer,
7446
+ rendererSize
7447
+ ]);
7448
+ const handleRowClick = useCallback(({ rowData }) => {
7449
+ onRowClick?.(rowData);
7450
+ }, [onRowClick]);
7451
+ const handleEndReached = useCallback(() => {
7452
+ if (dataController.paginationEnabled && !dataController.noMoreToLoad) {
7453
+ const currentCount = dataController.itemCount ?? dataController.pageSize ?? 50;
7454
+ const pageSize = dataController.pageSize ?? 50;
7455
+ dataController.setItemCount?.(currentCount + pageSize);
7456
+ }
7457
+ }, [
7458
+ dataController.paginationEnabled,
7459
+ dataController.noMoreToLoad,
7460
+ dataController.itemCount,
7461
+ dataController.pageSize,
7462
+ dataController.setItemCount
7463
+ ]);
7464
+ const handleColumnResize = useCallback((params) => {
7465
+ onColumnResize?.({
7466
+ key: params.key,
7467
+ width: params.width
7468
+ });
7469
+ }, [onColumnResize]);
7470
+ const handleColumnsOrderChange = useCallback((newColumns) => {
7471
+ onColumnsOrderChange?.(newColumns.map((col) => col.key));
7472
+ }, [onColumnsOrderChange]);
7473
+ return /* @__PURE__ */ jsx(VirtualTable, {
7474
+ data: dataController.data,
7475
+ columns,
7476
+ cellRenderer: tableCellRenderer,
7477
+ rowHeight,
7478
+ sortBy: dataController.sortBy,
7479
+ onSortByUpdate: dataController.setSortBy,
7480
+ onRowClick: handleRowClick,
7481
+ onEndReached: handleEndReached,
7482
+ onColumnResize: handleColumnResize,
7483
+ onColumnsOrderChange: handleColumnsOrderChange,
7484
+ loading: dataController.loading,
7485
+ emptyComponent,
7486
+ error: dataController.error,
7487
+ hoverRow,
7488
+ className: cls("h-full", className),
7489
+ onScroll: dataController.onScroll,
7490
+ initialScroll: dataController.initialScroll
7491
+ });
7492
+ }
7493
+ //#endregion
7494
+ //#region src/views/CollectionView/CollectionCardView.tsx
7495
+ /**
7496
+ * Headless card grid view that wraps {@link CardView}.
7497
+ *
7498
+ * Renders each item as a card with an optional image, title,
7499
+ * preview properties, and selection support.
7500
+ *
7501
+ * @group Collection View
7502
+ */
7503
+ function CollectionCardView({ dataController, properties, propertiesOrder, idProperty = "id", titleProperty, onRowClick, cellRenderer, size = "m", selectionEnabled, selectionController, highlightedItems, emptyComponent, className }) {
7504
+ const order = useMemo(() => propertiesOrder ?? Object.keys(properties), [propertiesOrder, properties]);
7505
+ const titlePropertyKey = useMemo(() => {
7506
+ if (titleProperty) return titleProperty;
7507
+ for (const key of order) {
7508
+ const prop = properties[key];
7509
+ if (prop && prop.type === "string" && !prop.hideFromCollection && !prop.storage) return key;
7510
+ }
7511
+ return idProperty;
7512
+ }, [
7513
+ titleProperty,
7514
+ order,
7515
+ properties,
7516
+ idProperty
7517
+ ]);
7518
+ const imageProperty = useMemo(() => {
7519
+ for (const key of order) {
7520
+ const prop = properties[key];
7521
+ if (prop && prop.type === "string" && prop.storage) return key;
7522
+ }
7523
+ }, [order, properties]);
7524
+ const previewProperties = useMemo(() => {
7525
+ const result = [];
7526
+ for (const key of order) {
7527
+ if (key === titlePropertyKey || key === imageProperty) continue;
7528
+ const prop = properties[key];
7529
+ if (prop && !prop.hideFromCollection) {
7530
+ result.push({
7531
+ key,
7532
+ property: prop
7533
+ });
7534
+ if (result.length >= 3) break;
7535
+ }
7536
+ }
7537
+ return result;
7538
+ }, [
7539
+ order,
7540
+ properties,
7541
+ titlePropertyKey,
7542
+ imageProperty
7543
+ ]);
7544
+ const selectedIds = useMemo(() => {
7545
+ if (!selectionController?.selectedItems) return void 0;
7546
+ const ids = /* @__PURE__ */ new Set();
7547
+ for (const item of selectionController.selectedItems) {
7548
+ const id = getValueInPath(item, idProperty);
7549
+ if (id !== void 0 && id !== null) ids.add(id);
7550
+ }
7551
+ return ids;
7552
+ }, [selectionController?.selectedItems, idProperty]);
7553
+ const highlightedIds = useMemo(() => {
7554
+ if (!highlightedItems) return void 0;
7555
+ const ids = /* @__PURE__ */ new Set();
7556
+ for (const item of highlightedItems) {
7557
+ const id = getValueInPath(item, idProperty);
7558
+ if (id !== void 0 && id !== null) ids.add(id);
7559
+ }
7560
+ return ids;
7561
+ }, [highlightedItems, idProperty]);
7562
+ const handleSelectionChange = useCallback((item, selected) => {
7563
+ if (!selectionController) return;
7564
+ selectionController.setSelectedItems((prev) => {
7565
+ if (selected) return [...prev, item];
7566
+ const itemId = getValueInPath(item, idProperty);
7567
+ return prev.filter((existing) => {
7568
+ return getValueInPath(existing, idProperty) !== itemId;
7569
+ });
7570
+ });
7571
+ }, [selectionController, idProperty]);
7572
+ const renderCard = useCallback((item, extra) => {
7573
+ const titleValue = getValueInPath(item, titlePropertyKey);
7574
+ const imageValue = imageProperty ? getValueInPath(item, imageProperty) : void 0;
7575
+ const hasImage = typeof imageValue === "string" && imageValue.length > 0;
7576
+ return /* @__PURE__ */ jsxs(Card, {
7577
+ onClick: (e) => {
7578
+ if (e) extra.onClick(e);
7579
+ },
7580
+ className: cls("overflow-hidden relative", extra.selected && "bg-primary-bg/30 dark:bg-primary-bg/10 ring-1 ring-primary/75", extra.highlighted && !extra.selected && "ring-1 ring-primary/50"),
7581
+ children: [
7582
+ imageProperty && (hasImage ? /* @__PURE__ */ jsx("img", {
7583
+ src: imageValue,
7584
+ alt: "",
7585
+ className: "w-full h-32 object-cover rounded-t-lg"
7586
+ }) : /* @__PURE__ */ jsx("div", { className: cls("h-24 rounded-t-lg", "bg-surface-accent-200/50 dark:bg-black/30") })),
7587
+ selectionEnabled && /* @__PURE__ */ jsx("div", {
7588
+ className: "absolute top-2 right-2",
7589
+ onClick: (e) => e.stopPropagation(),
7590
+ children: /* @__PURE__ */ jsx(Checkbox, {
7591
+ checked: extra.selected,
7592
+ onCheckedChange: extra.onSelectionChange,
7593
+ size: "small"
7594
+ })
7595
+ }),
7596
+ /* @__PURE__ */ jsx(Typography, {
7597
+ variant: "subtitle2",
7598
+ noWrap: true,
7599
+ className: "px-3 pt-2 pb-1",
7600
+ children: String(titleValue ?? "")
7601
+ }),
7602
+ previewProperties.map(({ key, property }) => {
7603
+ const value = getValueInPath(item, key);
7604
+ if (cellRenderer) {
7605
+ const custom = cellRenderer({
7606
+ row: item,
7607
+ propertyKey: key,
7608
+ property,
7609
+ value,
7610
+ size: "small"
7611
+ });
7612
+ if (custom !== void 0) return /* @__PURE__ */ jsx("div", {
7613
+ className: "px-3 py-0.5",
7614
+ children: custom
7615
+ }, key);
7616
+ }
7617
+ return /* @__PURE__ */ jsx("div", {
7618
+ className: "px-3 py-0.5",
7619
+ children: /* @__PURE__ */ jsx(DefaultCellRenderer, {
7620
+ row: item,
7621
+ propertyKey: key,
7622
+ property,
7623
+ value,
7624
+ size: "small"
7625
+ })
7626
+ }, key);
7627
+ }),
7628
+ /* @__PURE__ */ jsx("div", { className: "pb-2" })
7629
+ ]
7630
+ });
7631
+ }, [
7632
+ titlePropertyKey,
7633
+ imageProperty,
7634
+ previewProperties,
7635
+ cellRenderer,
7636
+ selectionEnabled
7637
+ ]);
7638
+ return /* @__PURE__ */ jsx("div", {
7639
+ className: cls("w-full h-full overflow-auto", className),
7640
+ children: /* @__PURE__ */ jsx(CardView, {
7641
+ data: dataController.data,
7642
+ dataLoading: dataController.loading,
7643
+ noMoreToLoad: dataController.noMoreToLoad,
7644
+ dataLoadingError: dataController.error,
7645
+ itemCount: dataController.itemCount,
7646
+ setItemCount: dataController.setItemCount,
7647
+ pageSize: dataController.pageSize,
7648
+ paginationEnabled: dataController.paginationEnabled,
7649
+ onItemClick: onRowClick,
7650
+ selectedIds,
7651
+ highlightedIds,
7652
+ selectionEnabled: !!selectionEnabled,
7653
+ onSelectionChange: handleSelectionChange,
7654
+ size,
7655
+ renderCard,
7656
+ emptyComponent
7657
+ })
7658
+ });
7659
+ }
7660
+ //#endregion
7661
+ //#region src/views/CollectionView/CollectionListView.tsx
7662
+ /**
7663
+ * Headless list view that wraps {@link ListView}.
7664
+ *
7665
+ * Each row displays a title (bold), subtitle with 1–2 secondary property values,
7666
+ * and optional selection support.
7667
+ *
7668
+ * @group Collection View
7669
+ */
7670
+ function CollectionListView({ dataController, properties, propertiesOrder, idProperty = "id", titleProperty, onRowClick, cellRenderer, size = "m", selectionEnabled, selectionController, highlightedItems, emptyComponent, className }) {
7671
+ const order = useMemo(() => propertiesOrder ?? Object.keys(properties), [propertiesOrder, properties]);
7672
+ const titlePropertyKey = useMemo(() => {
7673
+ if (titleProperty) return titleProperty;
7674
+ for (const key of order) {
7675
+ const prop = properties[key];
7676
+ if (prop && prop.type === "string" && !prop.hideFromCollection && !prop.storage) return key;
7677
+ }
7678
+ return idProperty;
7679
+ }, [
7680
+ titleProperty,
7681
+ order,
7682
+ properties,
7683
+ idProperty
7684
+ ]);
7685
+ const subtitleProperties = useMemo(() => {
7686
+ const result = [];
7687
+ for (const key of order) {
7688
+ if (key === titlePropertyKey) continue;
7689
+ const prop = properties[key];
7690
+ if (prop && !prop.hideFromCollection) {
7691
+ result.push({
7692
+ key,
7693
+ property: prop
7694
+ });
7695
+ if (result.length >= 2) break;
7696
+ }
7697
+ }
7698
+ return result;
7699
+ }, [
7700
+ order,
7701
+ properties,
7702
+ titlePropertyKey
7703
+ ]);
7704
+ const selectedIds = useMemo(() => {
7705
+ if (!selectionController?.selectedItems) return void 0;
7706
+ const ids = /* @__PURE__ */ new Set();
7707
+ for (const item of selectionController.selectedItems) {
7708
+ const id = getValueInPath(item, idProperty);
7709
+ if (id !== void 0 && id !== null) ids.add(id);
7710
+ }
7711
+ return ids;
7712
+ }, [selectionController?.selectedItems, idProperty]);
7713
+ const highlightedIds = useMemo(() => {
7714
+ if (!highlightedItems) return void 0;
7715
+ const ids = /* @__PURE__ */ new Set();
7716
+ for (const item of highlightedItems) {
7717
+ const id = getValueInPath(item, idProperty);
7718
+ if (id !== void 0 && id !== null) ids.add(id);
7719
+ }
7720
+ return ids;
7721
+ }, [highlightedItems, idProperty]);
7722
+ const handleSelectionChange = useCallback((item, selected) => {
7723
+ if (!selectionController) return;
7724
+ selectionController.setSelectedItems((prev) => {
7725
+ if (selected) return [...prev, item];
7726
+ const itemId = getValueInPath(item, idProperty);
7727
+ return prev.filter((existing) => {
7728
+ return getValueInPath(existing, idProperty) !== itemId;
7729
+ });
7730
+ });
7731
+ }, [selectionController, idProperty]);
7732
+ const renderRow = useCallback((params) => {
7733
+ const { item, style, className: rowClassName, selected, highlighted, onClick, onSelectionChange } = params;
7734
+ const titleValue = getValueInPath(item, titlePropertyKey);
7735
+ return /* @__PURE__ */ jsxs("div", {
7736
+ style,
7737
+ className: cls("flex items-center gap-3 px-4 cursor-pointer", "hover:bg-surface-50 dark:hover:bg-surface-700", "transition-colors duration-100", selected && "bg-primary-50 dark:bg-primary-900/20", highlighted && "bg-surface-100 dark:bg-surface-800", rowClassName),
7738
+ onClick,
7739
+ children: [selectionEnabled && /* @__PURE__ */ jsx("div", {
7740
+ className: "flex-shrink-0",
7741
+ onClick: (e) => e.stopPropagation(),
7742
+ children: /* @__PURE__ */ jsx(Checkbox, {
7743
+ checked: selected,
7744
+ onCheckedChange: onSelectionChange,
7745
+ size: "small"
7746
+ })
7747
+ }), /* @__PURE__ */ jsxs("div", {
7748
+ className: "flex-1 min-w-0 py-1",
7749
+ children: [/* @__PURE__ */ jsx(Typography, {
7750
+ variant: "subtitle2",
7751
+ noWrap: true,
7752
+ children: String(titleValue ?? "")
7753
+ }), subtitleProperties.length > 0 && /* @__PURE__ */ jsx("div", {
7754
+ className: "flex items-center gap-2",
7755
+ children: subtitleProperties.map(({ key, property }) => {
7756
+ const value = getValueInPath(item, key);
7757
+ if (cellRenderer) {
7758
+ const custom = cellRenderer({
7759
+ row: item,
7760
+ propertyKey: key,
7761
+ property,
7762
+ value,
7763
+ size: "tiny"
7764
+ });
7765
+ if (custom !== void 0) return /* @__PURE__ */ jsx(React.Fragment, { children: custom }, key);
7766
+ }
7767
+ return /* @__PURE__ */ jsx(React.Fragment, { children: /* @__PURE__ */ jsx(DefaultCellRenderer, {
7768
+ row: item,
7769
+ propertyKey: key,
7770
+ property,
7771
+ value,
7772
+ size: "tiny"
7773
+ }) }, key);
7774
+ })
7775
+ })]
7776
+ })]
7777
+ });
7778
+ }, [
7779
+ titlePropertyKey,
7780
+ subtitleProperties,
7781
+ cellRenderer,
7782
+ selectionEnabled
7783
+ ]);
7784
+ return /* @__PURE__ */ jsx("div", {
7785
+ className: cls("w-full h-full overflow-auto", className),
7786
+ children: /* @__PURE__ */ jsx(ListView, {
7787
+ data: dataController.data,
7788
+ dataLoading: dataController.loading,
7789
+ noMoreToLoad: dataController.noMoreToLoad,
7790
+ dataLoadingError: dataController.error,
7791
+ itemCount: dataController.itemCount,
7792
+ setItemCount: dataController.setItemCount,
7793
+ pageSize: dataController.pageSize,
7794
+ paginationEnabled: dataController.paginationEnabled,
7795
+ onItemClick: onRowClick,
7796
+ selectedIds,
7797
+ highlightedIds,
7798
+ selectionEnabled: !!selectionEnabled,
7799
+ onSelectionChange: handleSelectionChange,
7800
+ size,
7801
+ renderRow,
7802
+ emptyComponent
7803
+ })
7804
+ });
7805
+ }
7806
+ //#endregion
7807
+ //#region src/views/CollectionView/CollectionKanbanView.tsx
7808
+ function getEnumLabel(enumConfig, key) {
7809
+ if (!enumConfig) return key;
7810
+ if (enumConfig instanceof Map) {
7811
+ const cfg = enumConfig.get(key);
7812
+ if (!cfg) return key;
7813
+ return typeof cfg === "string" ? cfg : cfg.label;
7814
+ }
7815
+ const cfg = enumConfig[key];
7816
+ if (!cfg) return key;
7817
+ return typeof cfg === "string" ? cfg : cfg.label;
7818
+ }
7819
+ /**
7820
+ * Headless kanban view that wraps {@link KanbanView}.
7821
+ *
7822
+ * Groups data by a kanban property's enum values into columns.
7823
+ * Each card displays a title and 1–2 preview properties.
7824
+ *
7825
+ * @group Collection View
7826
+ */
7827
+ function CollectionKanbanView({ dataController, properties, propertiesOrder, idProperty = "id", titleProperty, kanbanProperty, onRowClick, cellRenderer, emptyComponent, onRowCreate, className }) {
7828
+ const order = useMemo(() => propertiesOrder ?? Object.keys(properties), [propertiesOrder, properties]);
7829
+ const columns = useMemo(() => {
7830
+ const kanbanConfig = properties[kanbanProperty];
7831
+ if (kanbanConfig?.enum) {
7832
+ if (kanbanConfig.enum instanceof Map) return Array.from(kanbanConfig.enum.keys()).map(String);
7833
+ return Object.keys(kanbanConfig.enum);
7834
+ }
7835
+ const seen = /* @__PURE__ */ new Set();
7836
+ for (const row of dataController.data) {
7837
+ const val = getValueInPath(row, kanbanProperty);
7838
+ if (val !== null && val !== void 0) seen.add(String(val));
7839
+ }
7840
+ return Array.from(seen);
7841
+ }, [
7842
+ properties,
7843
+ kanbanProperty,
7844
+ dataController.data
7845
+ ]);
7846
+ const columnLabels = useMemo(() => {
7847
+ const kanbanConfig = properties[kanbanProperty];
7848
+ const labels = {};
7849
+ for (const col of columns) labels[col] = getEnumLabel(kanbanConfig?.enum, col);
7850
+ return labels;
7851
+ }, [
7852
+ properties,
7853
+ kanbanProperty,
7854
+ columns
7855
+ ]);
7856
+ const titlePropertyKey = useMemo(() => {
7857
+ if (titleProperty) return titleProperty;
7858
+ for (const key of order) {
7859
+ const prop = properties[key];
7860
+ if (prop && prop.type === "string" && !prop.hideFromCollection && !prop.storage) return key;
7861
+ }
7862
+ return idProperty;
7863
+ }, [
7864
+ titleProperty,
7865
+ order,
7866
+ properties,
7867
+ idProperty
7868
+ ]);
7869
+ const previewProperties = useMemo(() => {
7870
+ const result = [];
7871
+ for (const key of order) {
7872
+ if (key === titlePropertyKey || key === kanbanProperty) continue;
7873
+ const prop = properties[key];
7874
+ if (prop && !prop.hideFromCollection) {
7875
+ result.push({
7876
+ key,
7877
+ property: prop
7878
+ });
7879
+ if (result.length >= 2) break;
7880
+ }
7881
+ }
7882
+ return result;
7883
+ }, [
7884
+ order,
7885
+ properties,
7886
+ titlePropertyKey,
7887
+ kanbanProperty
7888
+ ]);
7889
+ const boardItems = useMemo(() => {
7890
+ return dataController.data.map((row, index) => {
7891
+ const id = getValueInPath(row, idProperty);
7892
+ return {
7893
+ id: id !== null && id !== void 0 ? String(id) : String(index),
7894
+ data: row
7895
+ };
7896
+ });
7897
+ }, [dataController.data, idProperty]);
7898
+ const assignColumn = useCallback((item) => {
7899
+ const val = getValueInPath(item.data, kanbanProperty);
7900
+ const strVal = val !== null && val !== void 0 ? String(val) : "";
7901
+ if (columns.includes(strVal)) return strVal;
7902
+ return columns[0] ?? "";
7903
+ }, [kanbanProperty, columns]);
7904
+ const ItemComponent = useMemo(() => {
7905
+ function KanbanCard(props) {
7906
+ const { item } = props;
7907
+ const titleValue = getValueInPath(item.data, titlePropertyKey);
7908
+ return /* @__PURE__ */ jsxs(Card, {
7909
+ onClick: () => onRowClick?.(item.data),
7910
+ className: cls("p-3", cardClickableMixin, props.isDragging && "bg-primary-bg/30 dark:bg-primary-bg/10 ring-1 ring-primary/75", props.isDragging && "shadow-lg opacity-75"),
7911
+ children: [/* @__PURE__ */ jsx(Typography, {
7912
+ variant: "subtitle2",
7913
+ noWrap: true,
7914
+ children: String(titleValue ?? "")
7915
+ }), previewProperties.map(({ key, property }) => {
7916
+ const value = getValueInPath(item.data, key);
7917
+ if (cellRenderer) {
7918
+ const custom = cellRenderer({
7919
+ row: item.data,
7920
+ propertyKey: key,
7921
+ property,
7922
+ value,
7923
+ size: "tiny"
7924
+ });
7925
+ if (custom !== void 0) return /* @__PURE__ */ jsx("div", {
7926
+ className: "mt-1",
7927
+ children: custom
7928
+ }, key);
7929
+ }
7930
+ return /* @__PURE__ */ jsx("div", {
7931
+ className: "mt-1",
7932
+ children: /* @__PURE__ */ jsx(DefaultCellRenderer, {
7933
+ row: item.data,
7934
+ propertyKey: key,
7935
+ property,
7936
+ value,
7937
+ size: "tiny"
7938
+ })
7939
+ }, key);
7940
+ })]
7941
+ });
7942
+ }
7943
+ return KanbanCard;
7944
+ }, [
7945
+ titlePropertyKey,
7946
+ previewProperties,
7947
+ cellRenderer,
7948
+ onRowClick
7949
+ ]);
7950
+ const handleAddItemToColumn = useCallback((column) => {
7951
+ onRowCreate?.({ [kanbanProperty]: column });
7952
+ }, [onRowCreate, kanbanProperty]);
7953
+ if (columns.length === 0 && !dataController.loading) return /* @__PURE__ */ jsx("div", {
7954
+ className: "flex items-center justify-center p-8",
7955
+ children: emptyComponent ?? /* @__PURE__ */ jsx(Typography, {
7956
+ variant: "body2",
7957
+ color: "secondary",
7958
+ children: "No columns available for kanban view."
7959
+ })
7960
+ });
7961
+ return /* @__PURE__ */ jsx(KanbanView, {
7962
+ columns,
7963
+ columnLabels,
7964
+ data: boardItems,
7965
+ assignColumn,
7966
+ ItemComponent,
7967
+ onAddItemToColumn: onRowCreate ? handleAddItemToColumn : void 0,
7968
+ className
7969
+ });
7970
+ }
7971
+ //#endregion
7972
+ //#region src/views/CollectionView/CollectionView.tsx
7973
+ var DEFAULT_ENABLED_VIEWS = [
7974
+ "list",
7975
+ "table",
7976
+ "cards",
7977
+ "kanban"
7978
+ ];
7979
+ /**
7980
+ * A data-agnostic collection view component that orchestrates table, card,
7981
+ * list, and kanban views — driven entirely by props.
7982
+ *
7983
+ * Zero imports from any entity or data layer. This component lives in
7984
+ * `@rebasepro/ui` and can be used with any data source.
7985
+ *
7986
+ * @example
7987
+ * ```tsx
7988
+ * import { CollectionView } from "@rebasepro/ui";
7989
+ *
7990
+ * <CollectionView
7991
+ * dataController={{ data: myRows, loading: false, noMoreToLoad: true }}
7992
+ * properties={{
7993
+ * name: { type: "string", name: "Name" },
7994
+ * email: { type: "string", name: "Email" },
7995
+ * }}
7996
+ * title="Contacts"
7997
+ * onRowClick={(row) => openDetail(row.id)}
7998
+ * />
7999
+ * ```
8000
+ *
8001
+ * @group Collection View
8002
+ */
8003
+ function CollectionView({ dataController, properties, propertiesOrder, displayedColumnIds, idProperty = "id", titleProperty, title, viewMode: viewModeProp, defaultViewMode = "list", enabledViews = DEFAULT_ENABLED_VIEWS, onViewModeChange: onViewModeChangeProp, size: sizeProp, defaultSize = "m", onSizeChange: onSizeChangeProp, kanbanProperty: kanbanPropertyProp, kanbanPropertyOptions, onKanbanPropertyChange: onKanbanPropertyChangeProp, onRowClick, onRowCreate, canCreate = true, selectionEnabled, selectionController, highlightedItems, onMultipleDelete, cellRenderer, emptyComponent, toolbarActionsStart, toolbarActionsEnd, hideToolbar, hoverRow = true, onColumnResize, onColumnsOrderChange, className }) {
8004
+ const [internalViewMode, setInternalViewMode] = useState(defaultViewMode);
8005
+ const viewMode = viewModeProp ?? internalViewMode;
8006
+ const onViewModeChange = useCallback((mode) => {
8007
+ setInternalViewMode(mode);
8008
+ onViewModeChangeProp?.(mode);
8009
+ }, [onViewModeChangeProp]);
8010
+ const [internalSize, setInternalSize] = useState(defaultSize);
8011
+ const size = sizeProp ?? internalSize;
8012
+ const onSizeChange = useCallback((s) => {
8013
+ setInternalSize(s);
8014
+ onSizeChangeProp?.(s);
8015
+ }, [onSizeChangeProp]);
8016
+ const [internalKanbanProperty, setInternalKanbanProperty] = useState(kanbanPropertyProp);
8017
+ const kanbanProperty = kanbanPropertyProp ?? internalKanbanProperty;
8018
+ const onKanbanPropertyChange = useCallback((property) => {
8019
+ setInternalKanbanProperty(property);
8020
+ onKanbanPropertyChangeProp?.(property);
8021
+ }, [onKanbanPropertyChangeProp]);
8022
+ const resolvedKanbanProperty = useMemo(() => {
8023
+ if (kanbanProperty) return kanbanProperty;
8024
+ const order = propertiesOrder ?? Object.keys(properties);
8025
+ for (const key of order) {
8026
+ const prop = properties[key];
8027
+ if (prop && prop.type === "string" && prop.enum) return key;
8028
+ }
8029
+ }, [
8030
+ kanbanProperty,
8031
+ properties,
8032
+ propertiesOrder
8033
+ ]);
8034
+ const resolvedKanbanPropertyOptions = useMemo(() => {
8035
+ if (kanbanPropertyOptions) return kanbanPropertyOptions;
8036
+ const options = [];
8037
+ const order = propertiesOrder ?? Object.keys(properties);
8038
+ for (const key of order) {
8039
+ const prop = properties[key];
8040
+ if (prop && prop.type === "string" && prop.enum) options.push({
8041
+ key,
8042
+ label: prop.name
8043
+ });
8044
+ }
8045
+ return options;
8046
+ }, [
8047
+ kanbanPropertyOptions,
8048
+ properties,
8049
+ propertiesOrder
8050
+ ]);
8051
+ const sharedProps = {
8052
+ dataController,
8053
+ properties,
8054
+ propertiesOrder,
8055
+ idProperty,
8056
+ titleProperty,
8057
+ onRowClick,
8058
+ cellRenderer,
8059
+ selectionEnabled,
8060
+ selectionController,
8061
+ highlightedItems,
8062
+ emptyComponent
8063
+ };
8064
+ function renderView() {
8065
+ switch (viewMode) {
8066
+ case "table": return /* @__PURE__ */ jsx(CollectionTableView, {
8067
+ ...sharedProps,
8068
+ displayedColumnIds,
8069
+ size,
8070
+ hoverRow,
8071
+ onColumnResize,
8072
+ onColumnsOrderChange
8073
+ });
8074
+ case "cards": return /* @__PURE__ */ jsx(CollectionCardView, {
8075
+ ...sharedProps,
8076
+ size
8077
+ });
8078
+ case "kanban": return resolvedKanbanProperty ? /* @__PURE__ */ jsx(CollectionKanbanView, {
8079
+ ...sharedProps,
8080
+ kanbanProperty: resolvedKanbanProperty,
8081
+ onRowCreate
8082
+ }) : /* @__PURE__ */ jsx("div", {
8083
+ className: "flex items-center justify-center p-8",
8084
+ children: /* @__PURE__ */ jsx(Typography, {
8085
+ variant: "body2",
8086
+ color: "secondary",
8087
+ children: "No enum property available for kanban grouping."
8088
+ })
8089
+ });
8090
+ default: return /* @__PURE__ */ jsx(CollectionListView, {
8091
+ ...sharedProps,
8092
+ size
8093
+ });
8094
+ }
8095
+ }
8096
+ return /* @__PURE__ */ jsxs("div", {
8097
+ className: cls("overflow-hidden h-full w-full rounded-md flex flex-col", "dark:bg-surface-800", className),
8098
+ children: [
8099
+ dataController.error && dataController.data.length > 0 && /* @__PURE__ */ jsx("div", {
8100
+ className: "flex items-center gap-4 px-4 py-2 bg-red-50 dark:bg-red-900/20 border-b border-red-200 dark:border-red-800 flex-shrink-0",
8101
+ children: /* @__PURE__ */ jsxs(Typography, {
8102
+ variant: "body2",
8103
+ className: "text-red-700 dark:text-red-300 flex-1",
8104
+ children: [
8105
+ /* @__PURE__ */ jsx("strong", { children: "Warning:" }),
8106
+ " ",
8107
+ dataController.error.message || "Failed to update data."
8108
+ ]
8109
+ })
8110
+ }),
8111
+ !hideToolbar && /* @__PURE__ */ jsx(CollectionViewToolbar, {
8112
+ viewMode,
8113
+ onViewModeChange: enabledViews.length > 1 ? onViewModeChange : void 0,
8114
+ enabledViews,
8115
+ size,
8116
+ onSizeChange,
8117
+ searchString: dataController.searchString,
8118
+ onSearchChange: dataController.setSearchString,
8119
+ loading: dataController.loading,
8120
+ actionsStart: toolbarActionsStart,
8121
+ actionsEnd: toolbarActionsEnd,
8122
+ kanbanPropertyOptions: viewMode === "kanban" ? resolvedKanbanPropertyOptions : void 0,
8123
+ selectedKanbanProperty: resolvedKanbanProperty,
8124
+ onKanbanPropertyChange
8125
+ }),
8126
+ /* @__PURE__ */ jsx("div", {
8127
+ className: "flex-1 overflow-hidden",
8128
+ children: renderView()
8129
+ })
8130
+ ]
8131
+ });
8132
+ }
8133
+ //#endregion
8134
+ export { Alert, AlertCircleIcon, AlertTriangleIcon, AlignLeftIcon, AppWindow, ArrowDownToLineIcon, ArrowLeftIcon, ArrowRightFromLineIcon, ArrowRightIcon, ArrowRightToLineIcon, ArrowUpToLineIcon, Autocomplete, AutocompleteItem, Avatar, Badge, BoldIcon, BookOpenIcon, BooleanSwitch, BooleanSwitchWithLabel, Button, CHIP_COLORS, CalendarIcon, Card, CardView, CenteredView, CheckCircleIcon, CheckIcon, CheckSquareIcon, Checkbox, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, ChevronsLeftIcon, ChevronsRightIcon, ChevronsUpDownIcon, Chip, CircleIcon, CircleUserIcon, CircularProgress, CircularProgressCenter, CodeIcon, Collapse, CollectionCardView, CollectionKanbanView, CollectionListView, CollectionTableView, CollectionView, CollectionViewToolbar, ColorPicker, ColumnsIcon, Container, CopyIcon, DatabaseIcon, DateTimeField, DebouncedTextField, DefaultCellRenderer, Dialog, DialogActions, DialogContent, DialogTitle, DownloadIcon, ErrorBoundary, ExpandablePanel, ExternalLinkIcon, EyeIcon, EyeOffIcon, FileIcon, FileSearchIcon, FileTextIcon, FileUpload, FilterChip, FilterIcon, FilterXIcon, FlagIcon, FolderIcon, FolderPlusIcon, FolderUpIcon, FunctionSquareIcon, GitBranchIcon, GitHubIcon, GlobeIcon, HandleIcon, HashIcon, Heading1Icon, Heading2Icon, Heading3Icon, HelpCircleIcon, HistoryIcon, HomeIcon, IconButton, ImageIcon, ImageOffIcon, InfoIcon, InfoLabel, InputLabel, ItalicIcon, KanbanIcon, KanbanView, KeyIcon, KeyRoundIcon, Label, LanguagesIcon, LayoutGridIcon, Link2Icon, LinkIcon, ListIcon, ListOrderedIcon, ListView, LoaderIcon, LoadingButton, LockIcon, LogOutIcon, MailIcon, Markdown, Maximize2Icon, Menu, MenuIcon, MenuItem, Menubar, MenubarCheckboxItem, MenubarContent, MenubarItem, MenubarItemIndicator, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarSubTriggerIndicator, MenubarTrigger, MinusCircleIcon, MinusIcon, MoonIcon, MoreVerticalIcon, MultiSelect, MultiSelectContext, MultiSelectItem, Music2Icon, PanelLeftIcon, Paper, PauseIcon, PencilIcon, PhoneIcon, PlayIcon, PlusIcon, Popover, PopoverPrimitive, Portal, PortalContainerProvider, QuoteIcon, RadioGroup, RadioGroupItem, RefreshCcwIcon, RefreshCwIcon, RepeatIcon, ResizablePanels, Rows3Icon, SaveIcon, SearchBar, SearchIcon, Select, SelectGroup, SelectInputLabel, SelectItem, SendIcon, Separator, SettingsIcon, Sheet, ShieldIcon, ShoppingCartIcon, Skeleton, Slider, SlidersHorizontalIcon, Slot, SquareIcon, StarIcon, StrikethroughIcon, SunIcon, SunMoonIcon, Tab, Table, TableBody, TableCell, TableHeader, TableIcon, TableRow, VirtualTable as TableView, VirtualTable, Tabs, TagIcon, TerminalIcon, TextField, TextIcon, TextareaAutosize, ToggleButtonGroup, Tooltip, Trash2Icon, TypeIcon, Typography, UnderlineIcon, UndoIcon, UploadCloudIcon, UploadIcon, UserCheckIcon, UserIcon, UserPlus, VideoIcon, VoteIcon, Wand2Icon, XCircleIcon, XIcon, cardClickableMixin, cardMixin, cardSelectedMixin, cls, colorClassesMapping, coolIconKeys, debounce, defaultBorderMixin, fieldBackgroundDisabledMixin, fieldBackgroundHoverMixin, fieldBackgroundInvisibleMixin, fieldBackgroundMixin, focusedClasses, focusedDisabled, focusedInvisibleMixin, getColorSchemeForKey, getColorSchemeForSeed, iconKeys, iconSize, keyToIconComponent, lucideIcons, paperMixin, useAutoComplete, useDebounceCallback, useDebounceValue, useDebouncedCallback, useInjectStyles, useOutsideAlerter, usePortalContainer };
6093
8135
 
6094
8136
  //# sourceMappingURL=index.es.js.map