@vuer-ai/vuer-uikit 0.0.47 → 0.0.49

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 (176) hide show
  1. package/dist/{chunk-IMIHCOOE.js → chunk-2FCKLHWA.js} +1 -1
  2. package/dist/chunk-53PX4SCN.js +61 -0
  3. package/dist/{chunk-UZFOWGVD.mjs → chunk-5CWWM4L7.mjs} +9 -2
  4. package/dist/chunk-7NHWT7CO.mjs +26 -0
  5. package/dist/{chunk-5VYIGLGB.mjs → chunk-AJKD26TR.mjs} +1 -1
  6. package/dist/{chunk-NSN3O6CZ.mjs → chunk-AQENEOV3.mjs} +2 -2
  7. package/dist/{chunk-NKNUMZJL.mjs → chunk-DDG2W6BX.mjs} +36 -27
  8. package/dist/{chunk-KDRYDUQT.js → chunk-DWK23X7J.js} +1 -0
  9. package/dist/{chunk-R3SHGA4V.js → chunk-EOTROHFU.js} +36 -27
  10. package/dist/chunk-GCIH5IMQ.mjs +118 -0
  11. package/dist/chunk-HOQHWWLY.mjs +37 -0
  12. package/dist/{chunk-AKBWNVRH.js → chunk-HYVF2TGW.js} +2 -2
  13. package/dist/{chunk-QQMHPZFI.js → chunk-JIRSHP3D.js} +9 -2
  14. package/dist/chunk-KYWKRMXK.js +48 -0
  15. package/dist/chunk-N6DZ364I.mjs +15 -0
  16. package/dist/chunk-NXTGTCPA.mjs +19 -0
  17. package/dist/{chunk-3WAI7WDK.mjs → chunk-PDXJXH4A.mjs} +1 -1
  18. package/dist/chunk-PF36CKO7.mjs +599 -0
  19. package/dist/{chunk-I5UCKLLT.mjs → chunk-PZ3FWTMB.mjs} +1 -1
  20. package/dist/chunk-QPQSH53G.js +17 -0
  21. package/dist/chunk-VAEPAW5L.js +126 -0
  22. package/dist/{chunk-M3S7NSGR.mjs → chunk-VSFCQCKQ.mjs} +2 -2
  23. package/dist/{chunk-YGSTPCLB.mjs → chunk-VSYSYSVQ.mjs} +47 -31
  24. package/dist/{chunk-BGXUSJT2.js → chunk-WEHNW5KY.js} +2 -2
  25. package/dist/{chunk-HE63LZKF.js → chunk-XBKQWS7J.js} +3 -3
  26. package/dist/chunk-YFPY5SLS.js +41 -0
  27. package/dist/{chunk-VEUXQSY3.js → chunk-YNKO5FOU.js} +47 -31
  28. package/dist/chunk-YOKGP5F7.js +624 -0
  29. package/dist/highlight-cursor/cursor-provider.js +2 -2
  30. package/dist/highlight-cursor/cursor-provider.mjs +1 -1
  31. package/dist/highlight-cursor/enhanced-components.d.mts +3 -3
  32. package/dist/highlight-cursor/enhanced-components.d.ts +3 -3
  33. package/dist/highlight-cursor/enhanced-components.js +10 -10
  34. package/dist/highlight-cursor/enhanced-components.mjs +5 -5
  35. package/dist/highlight-cursor/index.d.mts +3 -3
  36. package/dist/highlight-cursor/index.d.ts +3 -3
  37. package/dist/highlight-cursor/index.js +12 -12
  38. package/dist/highlight-cursor/index.mjs +6 -6
  39. package/dist/hooks/index.js +7 -7
  40. package/dist/hooks/index.mjs +2 -2
  41. package/dist/hooks/use-mobile.d.mts +3 -0
  42. package/dist/hooks/use-mobile.d.ts +3 -0
  43. package/dist/hooks/use-mobile.js +10 -0
  44. package/dist/hooks/use-mobile.mjs +1 -0
  45. package/dist/hooks/useDragSelect.js +2 -2
  46. package/dist/hooks/useDragSelect.mjs +1 -1
  47. package/dist/index.d.mts +9 -3
  48. package/dist/index.d.ts +9 -3
  49. package/dist/index.js +285 -139
  50. package/dist/index.mjs +28 -22
  51. package/dist/ui/avatar.js +2 -2
  52. package/dist/ui/avatar.mjs +2 -2
  53. package/dist/ui/badge.d.mts +2 -2
  54. package/dist/ui/badge.d.ts +2 -2
  55. package/dist/ui/badge.js +2 -2
  56. package/dist/ui/badge.mjs +2 -2
  57. package/dist/ui/button.d.mts +2 -2
  58. package/dist/ui/button.d.ts +2 -2
  59. package/dist/ui/button.js +8 -4
  60. package/dist/ui/button.mjs +3 -3
  61. package/dist/ui/card.js +2 -2
  62. package/dist/ui/card.mjs +2 -2
  63. package/dist/ui/checkbox.js +2 -2
  64. package/dist/ui/checkbox.mjs +2 -2
  65. package/dist/ui/collapsible.js +2 -2
  66. package/dist/ui/collapsible.mjs +2 -2
  67. package/dist/ui/drawer.js +2 -2
  68. package/dist/ui/drawer.mjs +2 -2
  69. package/dist/ui/dropdown.js +2 -2
  70. package/dist/ui/dropdown.mjs +2 -2
  71. package/dist/ui/form/CmInput.js +2 -2
  72. package/dist/ui/form/CmInput.mjs +2 -2
  73. package/dist/ui/form/DegInput.js +2 -2
  74. package/dist/ui/form/DegInput.mjs +2 -2
  75. package/dist/ui/form/EulerDegInput.js +2 -2
  76. package/dist/ui/form/EulerDegInput.mjs +2 -2
  77. package/dist/ui/form/EulerInput.js +2 -2
  78. package/dist/ui/form/EulerInput.mjs +2 -2
  79. package/dist/ui/form/EulerRadInput.js +2 -2
  80. package/dist/ui/form/EulerRadInput.mjs +2 -2
  81. package/dist/ui/form/InchInput.js +2 -2
  82. package/dist/ui/form/InchInput.mjs +2 -2
  83. package/dist/ui/form/IntInput.js +2 -2
  84. package/dist/ui/form/IntInput.mjs +2 -2
  85. package/dist/ui/form/KVectorInput.js +2 -2
  86. package/dist/ui/form/KVectorInput.mjs +2 -2
  87. package/dist/ui/form/NumberInput.js +2 -2
  88. package/dist/ui/form/NumberInput.mjs +2 -2
  89. package/dist/ui/form/QuaternionInput.js +2 -2
  90. package/dist/ui/form/QuaternionInput.mjs +2 -2
  91. package/dist/ui/form/RadInput.js +2 -2
  92. package/dist/ui/form/RadInput.mjs +2 -2
  93. package/dist/ui/form/TimeInput.js +2 -2
  94. package/dist/ui/form/TimeInput.mjs +2 -2
  95. package/dist/ui/form/Vec3Input.js +2 -2
  96. package/dist/ui/form/Vec3Input.mjs +2 -2
  97. package/dist/ui/form/VectorInput.js +2 -2
  98. package/dist/ui/form/VectorInput.mjs +2 -2
  99. package/dist/ui/form/index.js +17 -17
  100. package/dist/ui/form/index.mjs +5 -5
  101. package/dist/ui/index.d.mts +9 -3
  102. package/dist/ui/index.d.ts +9 -3
  103. package/dist/ui/index.js +270 -124
  104. package/dist/ui/index.mjs +26 -20
  105. package/dist/ui/input-numbers.js +2 -2
  106. package/dist/ui/input-numbers.mjs +2 -2
  107. package/dist/ui/input.d.mts +1 -1
  108. package/dist/ui/input.d.ts +1 -1
  109. package/dist/ui/input.js +2 -2
  110. package/dist/ui/input.mjs +2 -2
  111. package/dist/ui/layout.js +2 -2
  112. package/dist/ui/layout.mjs +2 -2
  113. package/dist/ui/modal.js +2 -2
  114. package/dist/ui/modal.mjs +2 -2
  115. package/dist/ui/pagination.d.mts +18 -0
  116. package/dist/ui/pagination.d.ts +18 -0
  117. package/dist/ui/pagination.js +43 -0
  118. package/dist/ui/pagination.mjs +10 -0
  119. package/dist/ui/popover.js +2 -2
  120. package/dist/ui/popover.mjs +2 -2
  121. package/dist/ui/radio-group.js +2 -2
  122. package/dist/ui/radio-group.mjs +2 -2
  123. package/dist/ui/resizable.d.mts +14 -0
  124. package/dist/ui/resizable.d.ts +14 -0
  125. package/dist/ui/resizable.js +25 -0
  126. package/dist/ui/resizable.mjs +8 -0
  127. package/dist/ui/select.d.mts +1 -1
  128. package/dist/ui/select.d.ts +1 -1
  129. package/dist/ui/select.js +2 -2
  130. package/dist/ui/select.mjs +2 -2
  131. package/dist/ui/separator.d.mts +7 -0
  132. package/dist/ui/separator.d.ts +7 -0
  133. package/dist/ui/separator.js +17 -0
  134. package/dist/ui/separator.mjs +8 -0
  135. package/dist/ui/sheet.js +2 -2
  136. package/dist/ui/sheet.mjs +2 -2
  137. package/dist/ui/sidebar.d.mts +75 -0
  138. package/dist/ui/sidebar.d.ts +75 -0
  139. package/dist/ui/sidebar.js +116 -0
  140. package/dist/ui/sidebar.mjs +15 -0
  141. package/dist/ui/skeleton.d.mts +6 -0
  142. package/dist/ui/skeleton.d.ts +6 -0
  143. package/dist/ui/skeleton.js +17 -0
  144. package/dist/ui/skeleton.mjs +8 -0
  145. package/dist/ui/slider.js +2 -2
  146. package/dist/ui/slider.mjs +2 -2
  147. package/dist/ui/switch.js +2 -2
  148. package/dist/ui/switch.mjs +2 -2
  149. package/dist/ui/tabs.js +2 -2
  150. package/dist/ui/tabs.mjs +2 -2
  151. package/dist/ui/textarea.js +2 -2
  152. package/dist/ui/textarea.mjs +2 -2
  153. package/dist/ui/timeline.js +5 -5
  154. package/dist/ui/timeline.mjs +4 -4
  155. package/dist/ui/toggle-group.js +2 -2
  156. package/dist/ui/toggle-group.mjs +2 -2
  157. package/dist/ui/toggle.js +2 -2
  158. package/dist/ui/toggle.mjs +2 -2
  159. package/dist/ui/tooltip.js +2 -2
  160. package/dist/ui/tooltip.mjs +2 -2
  161. package/dist/ui/tree-view-v2.d.mts +5 -1
  162. package/dist/ui/tree-view-v2.d.ts +5 -1
  163. package/dist/ui/tree-view-v2.js +4 -4
  164. package/dist/ui/tree-view-v2.mjs +3 -3
  165. package/dist/ui/tree-view.js +4 -4
  166. package/dist/ui/tree-view.mjs +3 -3
  167. package/dist/ui/version-badge.js +4 -4
  168. package/dist/ui/version-badge.mjs +3 -3
  169. package/package.json +2 -1
  170. package/src/hooks/useDragSelect.ts +12 -2
  171. package/src/ui/index.ts +1 -0
  172. package/src/ui/resizable.tsx +50 -0
  173. package/src/ui/sidebar.tsx +13 -13
  174. package/src/ui/tree-view-v2.tsx +47 -22
  175. /package/dist/{chunk-YQKZSWI6.js → chunk-GLGYNU3Q.js} +0 -0
  176. /package/dist/{chunk-4IXZRYYD.mjs → chunk-ZFWQLAQA.mjs} +0 -0
package/src/ui/index.ts CHANGED
@@ -31,6 +31,7 @@ export * from "./slider";
31
31
  export * from "./layout";
32
32
  export * from "./version-badge";
33
33
  export * from "./form";
34
+ export * from "./resizable";
34
35
 
35
36
  export * from "./theme";
36
37
  export * from "./drag-selectable";
@@ -0,0 +1,50 @@
1
+ import { GripVerticalIcon } from "lucide-react";
2
+ import * as React from "react";
3
+ import { ComponentProps } from "react";
4
+ import * as ResizablePrimitive from "react-resizable-panels";
5
+
6
+ import { cn } from "../hooks";
7
+
8
+ type ResizablePanelGroupProps = ComponentProps<typeof ResizablePrimitive.PanelGroup>;
9
+
10
+ function ResizablePanelGroup({ className, ...props }: Readonly<ResizablePanelGroupProps>) {
11
+ return (
12
+ <ResizablePrimitive.PanelGroup
13
+ data-slot="resizable-panel-group"
14
+ className={cn("flex h-full w-full data-[panel-group-direction=vertical]:flex-col", className)}
15
+ {...props}
16
+ />
17
+ );
18
+ }
19
+
20
+ type ComponentPropsProps = ComponentProps<typeof ResizablePrimitive.Panel>;
21
+
22
+ function ResizablePanel(props: Readonly<ComponentPropsProps>) {
23
+ return <ResizablePrimitive.Panel data-slot="resizable-panel" {...props} />;
24
+ }
25
+
26
+ interface ResizableHandleProps extends ComponentProps<typeof ResizablePrimitive.PanelResizeHandle> {
27
+ withHandle?: boolean;
28
+ }
29
+
30
+ function ResizableHandle({ withHandle, className, children, ...props }: ResizableHandleProps) {
31
+ return (
32
+ <ResizablePrimitive.PanelResizeHandle
33
+ data-slot="resizable-handle"
34
+ className={cn(
35
+ "bg-border focus-visible:ring-ring relative flex w-px items-center justify-center after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-offset-1 focus-visible:outline-hidden data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:translate-x-0 data-[panel-group-direction=vertical]:after:-translate-y-1/2 [&[data-panel-group-direction=vertical]>div]:rotate-90",
36
+ className,
37
+ )}
38
+ {...props}
39
+ >
40
+ {children}
41
+ {!children && withHandle && (
42
+ <div className="bg-border z-10 flex h-4 w-3 items-center justify-center rounded-xs border">
43
+ <GripVerticalIcon className="size-2.5" />
44
+ </div>
45
+ )}
46
+ </ResizablePrimitive.PanelResizeHandle>
47
+ );
48
+ }
49
+
50
+ export { ResizablePanelGroup, ResizablePanel, ResizableHandle };
@@ -221,7 +221,7 @@ function Sidebar({
221
221
  <div
222
222
  data-sidebar="sidebar"
223
223
  data-slot="sidebar-inner"
224
- className="bg-bg-primary liquid:liquid-bg group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:rounded-uk-lg flex h-full w-full flex-col group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm"
224
+ className="font-normal bg-bg-primary liquid:liquid-bg group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:rounded-uk-lg flex h-full w-full flex-col group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm"
225
225
  >
226
226
  {children}
227
227
  </div>
@@ -315,7 +315,7 @@ function SidebarHeader({ className, ...props }: ComponentProps<"div">) {
315
315
  <div
316
316
  data-slot="sidebar-header"
317
317
  data-sidebar="header"
318
- className={cn("px-lg flex flex-col", className)}
318
+ className={cn("text-uk-lg leading-uk-lg px-md flex flex-col", className)}
319
319
  {...props}
320
320
  />
321
321
  );
@@ -352,7 +352,7 @@ function SidebarContent({ className, ...props }: ComponentProps<"div">) {
352
352
  data-slot="sidebar-content"
353
353
  data-sidebar="content"
354
354
  className={cn(
355
- "px-lg lgflex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden",
355
+ "px-md lgflex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden",
356
356
  className,
357
357
  )}
358
358
  {...props}
@@ -383,7 +383,7 @@ function SidebarGroupLabel({
383
383
  data-slot="sidebar-group-label"
384
384
  data-sidebar="group-label"
385
385
  className={cn(
386
- "text-text-primary ring-sidebar-ring rounded-uk-md text-uk-md leading-uk-md flex h-[36px] shrink-0 items-center font-medium outline-hidden transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
386
+ "text-text-primary ring-sidebar-ring rounded-uk-md text-uk-md leading-uk-md flex h-[32px] shrink-0 items-center font-medium outline-hidden transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
387
387
  "group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0",
388
388
  className,
389
389
  )}
@@ -404,7 +404,7 @@ function SidebarGroupAction({
404
404
  data-slot="sidebar-group-action"
405
405
  data-sidebar="group-action"
406
406
  className={cn(
407
- "hover:bg-bg-secondary rounded-uk-md absolute top-[10px] right-0 flex aspect-square w-5 items-center justify-center p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
407
+ "hover:bg-bg-secondary rounded-uk-md absolute top-[6px] right-0 flex aspect-square w-5 items-center justify-center p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
408
408
  "after:absolute after:-inset-2 md:after:hidden",
409
409
  "group-data-[collapsible=icon]:hidden",
410
410
  className,
@@ -430,7 +430,7 @@ function SidebarMenu({ className, ...props }: ComponentProps<"ul">) {
430
430
  <ul
431
431
  data-slot="sidebar-menu"
432
432
  data-sidebar="menu"
433
- className={cn("gap-sm flex w-full min-w-0 flex-col", className)}
433
+ className={cn("gap-lg flex w-full min-w-0 flex-col", className)}
434
434
  style={{
435
435
  paddingLeft: "0px",
436
436
  marginBottom: "0px",
@@ -456,7 +456,7 @@ function SidebarMenuItem({ className, ...props }: ComponentProps<"li">) {
456
456
  }
457
457
 
458
458
  const sidebarMenuButtonVariants = cva(
459
- "peer/menu-button flex w-full items-center gap-md overflow-hidden rounde-uk-md text-left text-uk-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] text-text-primary focus-visible:ring-2 active:text-text-highlight disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 font-medium group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",
459
+ "peer/menu-button flex w-full items-center gap-md overflow-hidden rounde-uk-md text-left text-uk-lg leading-uk-lg outline-hidden ring-sidebar-ring transition-[width,height,padding] text-text-primary focus-visible:ring-2 active:text-text-highlight disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 font-medium group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg]:size-[16px] [&>svg]:shrink-0",
460
460
  {
461
461
  variants: {
462
462
  variant: {
@@ -464,9 +464,9 @@ const sidebarMenuButtonVariants = cva(
464
464
  outline: "",
465
465
  },
466
466
  size: {
467
- default: "h-[44px] text-uk-md",
468
- sm: "h-[40px] text-uk-sm",
469
- lg: "h-[48px] text-uk-lg group-data-[collapsible=icon]:p-0!",
467
+ default: "h-[32px] text-uk-lg leading-uk-lg",
468
+ sm: "h-[30px] text-uk-sm leading-uk-sm",
469
+ lg: "h-[36px] text-uk-lg leading-uk-lg group-data-[collapsible=icon]:p-0!",
470
470
  },
471
471
  },
472
472
  defaultVariants: {
@@ -542,7 +542,7 @@ function SidebarMenuAction({
542
542
  data-slot="sidebar-menu-action"
543
543
  data-sidebar="menu-action"
544
544
  className={cn(
545
- "hover:bg-bg-secondary rounded-uk-md absolute top-[14px] right-0 flex aspect-square w-5 items-center justify-center p-0 outline-hidden transition-transform [&>svg]:size-4 [&>svg]:shrink-0",
545
+ "hover:bg-bg-secondary rounded-uk-md absolute top-[6px] right-0 flex aspect-square w-5 items-center justify-center p-0 outline-hidden transition-transform [&>svg]:size-4 [&>svg]:shrink-0",
546
546
  "group-data-[collapsible=icon]:hidden",
547
547
  showOnHover &&
548
548
  "peer-data-[active=true]/menu-button:text-text-highlight group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 md:opacity-0",
@@ -559,7 +559,7 @@ function SidebarMenuBadge({ className, ...props }: ComponentProps<"div">) {
559
559
  data-slot="sidebar-menu-badge"
560
560
  data-sidebar="menu-badge"
561
561
  className={cn(
562
- "text-text-primary rounded-uk-md text-uk-sm pointer-events-none absolute top-[12px] right-0 flex min-w-5 items-center justify-center font-medium tabular-nums select-none",
562
+ "text-text-primary rounded-uk-md text-uk-sm pointer-events-none absolute top-[6px] right-0 flex min-w-5 items-center justify-center font-medium tabular-nums select-none",
563
563
  "group-data-[collapsible=icon]:hidden",
564
564
  className,
565
565
  )}
@@ -655,7 +655,7 @@ function SidebarMenuSubButton({
655
655
  data-size={size}
656
656
  data-active={isActive}
657
657
  className={cn(
658
- "text-text-primary ring-sidebar-ring hover:bg-bg-secondary hover:text-text-primary active:bg-bg-tertiary active:text-text-highlight [&>svg]:text-icon-primary gap-md rounded-uk-md px-lg flex h-[36px] min-w-0 -translate-x-px items-center overflow-hidden outline-hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-[14px] [&>svg]:shrink-0",
658
+ "text-text-primary ring-sidebar-ring hover:bg-bg-secondary hover:text-text-primary active:bg-bg-tertiary active:text-text-highlight [&>svg]:text-icon-primary gap-md rounded-uk-md px-lg flex h-[36px] min-w-0 -translate-x-px items-center overflow-hidden outline-hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-[16px] [&>svg]:shrink-0",
659
659
  size === "sm" && "text-uk-sm leading-uk-sm",
660
660
  size === "md" && "text-uk-md leading-uk-md",
661
661
  "group-data-[collapsible=icon]:hidden",
@@ -12,6 +12,7 @@ type TreeDataItem = {
12
12
  parentId: string | null;
13
13
  label: string;
14
14
  isCollapsible?: boolean;
15
+ actions?: ReactNode;
15
16
  [key: string]: unknown;
16
17
  };
17
18
 
@@ -25,6 +26,9 @@ type TreeViewProps<T extends TreeDataItem> = {
25
26
  onItemHover?: (id: string | null) => void;
26
27
  className?: string;
27
28
  hoveredId?: string | null;
29
+ isSelectable?: boolean;
30
+ selectedItemId?: string | null;
31
+ onSelectChange?: (id: string | null) => void;
28
32
  };
29
33
 
30
34
  /**
@@ -38,6 +42,9 @@ function TreeView<T extends TreeDataItem>({
38
42
  onItemHover,
39
43
  className,
40
44
  hoveredId,
45
+ isSelectable = false,
46
+ selectedItemId,
47
+ onSelectChange,
41
48
  }: TreeViewProps<T>) {
42
49
  const [expandedItems, setExpandedItems] = useState(() => {
43
50
  const initial = new Set<string>();
@@ -64,6 +71,12 @@ function TreeView<T extends TreeDataItem>({
64
71
  });
65
72
  };
66
73
 
74
+ const handleItemSelect = (id: string) => {
75
+ if (isSelectable && onSelectChange) {
76
+ onSelectChange(selectedItemId === id ? null : id);
77
+ }
78
+ };
79
+
67
80
  const childrenMap = useMemo(() => {
68
81
  const map = new Map<string | null, T[]>();
69
82
  data.forEach((item) => {
@@ -236,9 +249,11 @@ function TreeView<T extends TreeDataItem>({
236
249
  className={cn(
237
250
  "group relative flex h-[32px] cursor-pointer items-center",
238
251
  hoveredId === item.id && "bg-bg-secondary/80",
252
+ isSelectable && selectedItemId === item.id && "bg-brand-primary",
239
253
  )}
240
254
  onMouseEnter={() => onItemHover?.(item.id)}
241
255
  onMouseLeave={() => onItemHover?.(null)}
256
+ onClick={() => handleItemSelect(item.id)}
242
257
  >
243
258
  {/* Guide Lines */}
244
259
  <div className="absolute top-0 left-[-0.28rem] z-0 flex h-full items-center">
@@ -272,33 +287,43 @@ function TreeView<T extends TreeDataItem>({
272
287
  </div>
273
288
 
274
289
  <div
275
- className="text-uk-md z-10 flex w-full items-center gap-2 px-2 whitespace-nowrap"
290
+ className="text-uk-md z-10 flex w-full items-center justify-between px-2 whitespace-nowrap"
276
291
  style={{ paddingLeft: `${item.indent * 1.25 + 0.5}rem` }}
277
292
  >
278
- <div className="relative flex size-4 items-center justify-center">
279
- {item.isCollapsible && (
280
- <button
281
- onClick={() => toggleItem(item.id)}
282
- className="absolute z-20 flex cursor-pointer items-center justify-center opacity-0 transition-opacity group-hover:opacity-100"
283
- >
284
- <ChevronDown
285
- className={cn(
286
- "size-4 transition-transform",
287
- !expandedItems.has(item.id) && "-rotate-90",
288
- )}
289
- />
290
- </button>
291
- )}
292
- <div
293
- className={cn(
294
- "cursor-pointer transition-opacity",
295
- item.isCollapsible && "group-hover:opacity-0",
293
+ <div className="flex min-w-0 flex-1 items-center gap-2">
294
+ <div className="relative flex size-4 items-center justify-center">
295
+ {item.isCollapsible && (
296
+ <button
297
+ onClick={(e) => {
298
+ e.stopPropagation();
299
+ toggleItem(item.id);
300
+ }}
301
+ className="absolute z-20 flex cursor-pointer items-center justify-center opacity-0 transition-opacity group-hover:opacity-100"
302
+ >
303
+ <ChevronDown
304
+ className={cn(
305
+ "size-4 transition-transform",
306
+ !expandedItems.has(item.id) && "-rotate-90",
307
+ )}
308
+ />
309
+ </button>
296
310
  )}
297
- >
298
- {getIcon(item)}
311
+ <div
312
+ className={cn(
313
+ "cursor-pointer transition-opacity",
314
+ item.isCollapsible && "group-hover:opacity-0",
315
+ )}
316
+ >
317
+ {getIcon(item)}
318
+ </div>
299
319
  </div>
320
+ <span className="truncate">{renderLabel(item.label)}</span>
300
321
  </div>
301
- <span className="truncate">{renderLabel(item.label)}</span>
322
+ {item.actions && (
323
+ <div className="flex items-center gap-1" onClick={(e) => e.stopPropagation()}>
324
+ {item.actions}
325
+ </div>
326
+ )}
302
327
  </div>
303
328
  </div>
304
329
  ))}
File without changes
File without changes