torch-glare 2.3.0 → 2.4.1

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 (264) hide show
  1. package/README.md +8 -0
  2. package/apps/lib/components/ActionButton.tsx +7 -12
  3. package/apps/lib/components/ActionsGroup.tsx +4 -15
  4. package/apps/lib/components/AlertDialog.tsx +173 -191
  5. package/apps/lib/components/Avatar.tsx +13 -16
  6. package/apps/lib/components/Badge.tsx +7 -3
  7. package/apps/lib/components/BadgeField.tsx +76 -71
  8. package/apps/lib/components/Breadcrumb.tsx +49 -85
  9. package/apps/lib/components/Button.tsx +20 -19
  10. package/apps/lib/components/ButtonGroup.tsx +31 -41
  11. package/apps/lib/components/Calendar.tsx +51 -29
  12. package/apps/lib/components/Card.tsx +2 -13
  13. package/apps/lib/components/ChartBlockTool.ts +17 -52
  14. package/apps/lib/components/Checkbox.tsx +9 -16
  15. package/apps/lib/components/ContextMenu.tsx +110 -106
  16. package/apps/lib/components/CountBadge.tsx +4 -6
  17. package/apps/lib/components/DataTable.tsx +196 -216
  18. package/apps/lib/components/DataViews/DataViewRadio.tsx +10 -8
  19. package/apps/lib/components/DataViews/DataViewsConfigPanel.tsx +21 -55
  20. package/apps/lib/components/DataViews/DataViewsHeader.tsx +1 -3
  21. package/apps/lib/components/DataViews/DataViewsLayout.tsx +5 -12
  22. package/apps/lib/components/DataViews/FilterPanel.tsx +173 -150
  23. package/apps/lib/components/DataViews/HeaderSearch.tsx +1 -5
  24. package/apps/lib/components/DataViews/InboxView.tsx +22 -68
  25. package/apps/lib/components/DataViews/InboxViewCard.tsx +68 -77
  26. package/apps/lib/components/DataViews/KanbanView.tsx +8 -25
  27. package/apps/lib/components/DataViews/PanelControls.tsx +3 -13
  28. package/apps/lib/components/DataViews/SettingsPanel.tsx +83 -89
  29. package/apps/lib/components/DataViews/TableView.tsx +8 -28
  30. package/apps/lib/components/DataViews/TreeView.tsx +12 -40
  31. package/apps/lib/components/DataViews/badgeAdapter.ts +32 -28
  32. package/apps/lib/components/DataViews/fieldRenderers.tsx +106 -141
  33. package/apps/lib/components/DataViews/filters/DatePickerRangeFilter.tsx +87 -0
  34. package/apps/lib/components/DataViews/filters/DateRangePopover.tsx +39 -32
  35. package/apps/lib/components/DataViews/filters/PresetChips.tsx +15 -15
  36. package/apps/lib/components/DataViews/filters/RangeSliderWithInputs.tsx +69 -58
  37. package/apps/lib/components/DataViews/index.ts +26 -26
  38. package/apps/lib/components/DataViews/tree/TreeDrawer.tsx +12 -16
  39. package/apps/lib/components/DataViews/tree/TreeSidebar.tsx +28 -31
  40. package/apps/lib/components/DataViews/types.ts +111 -114
  41. package/apps/lib/components/DatePicker.tsx +198 -191
  42. package/apps/lib/components/Dialog.tsx +92 -105
  43. package/apps/lib/components/Divider.tsx +21 -24
  44. package/apps/lib/components/Drawer.tsx +79 -139
  45. package/apps/lib/components/DropdownMenu.tsx +144 -181
  46. package/apps/lib/components/FieldHint.tsx +4 -11
  47. package/apps/lib/components/Form.tsx +146 -155
  48. package/apps/lib/components/FormStepper.tsx +9 -39
  49. package/apps/lib/components/HeaderBar.tsx +119 -0
  50. package/apps/lib/components/ImageAttachment.tsx +111 -73
  51. package/apps/lib/components/InnerLabelField.tsx +20 -16
  52. package/apps/lib/components/Input.tsx +171 -172
  53. package/apps/lib/components/InputField.tsx +44 -45
  54. package/apps/lib/components/InputOTP.tsx +68 -69
  55. package/apps/lib/components/Label.tsx +31 -35
  56. package/apps/lib/components/LabelField.tsx +4 -5
  57. package/apps/lib/components/LabeledCheckBox.tsx +8 -12
  58. package/apps/lib/components/LabeledRadio.tsx +7 -5
  59. package/apps/lib/components/LinkButton.tsx +2 -9
  60. package/apps/lib/components/LoginButton.tsx +4 -9
  61. package/apps/lib/components/PasswordLevel.tsx +5 -5
  62. package/apps/lib/components/Popover.tsx +15 -33
  63. package/apps/lib/components/ProfileMenu.tsx +67 -72
  64. package/apps/lib/components/Radio.tsx +1 -5
  65. package/apps/lib/components/RadioCard.tsx +9 -28
  66. package/apps/lib/components/ScrollArea.tsx +45 -43
  67. package/apps/lib/components/SearchField.tsx +49 -39
  68. package/apps/lib/components/SearchableSelect.tsx +46 -52
  69. package/apps/lib/components/SearchableTable.tsx +199 -219
  70. package/apps/lib/components/SearchableTree.tsx +469 -0
  71. package/apps/lib/components/SearchableTreeDialog.tsx +493 -0
  72. package/apps/lib/components/SectionBlock.tsx +4 -16
  73. package/apps/lib/components/Select.tsx +53 -80
  74. package/apps/lib/components/SimpleSelect.tsx +196 -187
  75. package/apps/lib/components/Skeleton.tsx +9 -12
  76. package/apps/lib/components/SlideDatePicker.tsx +215 -166
  77. package/apps/lib/components/SpinLoading.tsx +33 -49
  78. package/apps/lib/components/Stepper.tsx +13 -56
  79. package/apps/lib/components/Switch.tsx +8 -10
  80. package/apps/lib/components/TabFormItem.tsx +3 -12
  81. package/apps/lib/components/TabSwitch.tsx +7 -34
  82. package/apps/lib/components/Table.tsx +60 -75
  83. package/apps/lib/components/TableDnDWrapper.ts +15 -48
  84. package/apps/lib/components/TextEditor.tsx +93 -104
  85. package/apps/lib/components/Textarea.tsx +8 -12
  86. package/apps/lib/components/Timeline.tsx +21 -41
  87. package/apps/lib/components/Toast.tsx +83 -83
  88. package/apps/lib/components/Toggle.tsx +112 -114
  89. package/apps/lib/components/ToggleButton.tsx +1 -1
  90. package/apps/lib/components/Tooltip.tsx +24 -19
  91. package/apps/lib/components/TransparentLabel.tsx +61 -62
  92. package/apps/lib/components/TreeDropDown.tsx +86 -52
  93. package/apps/lib/components/TreeFolder/TreeFolder.tsx +15 -48
  94. package/apps/lib/components/TreeFolder/TreeFolderBreadcrumb.tsx +16 -21
  95. package/apps/lib/components/TreeFolder/TreeFolderRow.tsx +9 -20
  96. package/apps/lib/components/TreeFolder/TreeFolderStyles.tsx +3 -3
  97. package/apps/lib/components/TreeFolder/icons.tsx +14 -17
  98. package/apps/lib/components/TreeFolder/index.ts +15 -8
  99. package/apps/lib/components/TreeFolder/treeFolderUtils.ts +47 -52
  100. package/apps/lib/components/TreeFolder/types.ts +32 -32
  101. package/apps/lib/components/TreeFolder/useTreeFolderDnD.ts +117 -123
  102. package/apps/lib/hooks/useActiveTreeItem.ts +52 -55
  103. package/apps/lib/hooks/useClickOutside.ts +21 -20
  104. package/apps/lib/hooks/useDataViewsState.ts +86 -80
  105. package/apps/lib/hooks/useIsMobile.ts +12 -12
  106. package/apps/lib/hooks/useResize.ts +54 -65
  107. package/apps/lib/hooks/useTagSelection.ts +201 -201
  108. package/apps/lib/layouts/CNLayout.tsx +181 -140
  109. package/apps/lib/layouts/DataViewCard.tsx +4 -18
  110. package/apps/lib/layouts/FieldSection.tsx +2 -6
  111. package/apps/lib/layouts/TreeSubLayout.tsx +24 -38
  112. package/apps/lib/providers/ThemeProvider.tsx +8 -23
  113. package/apps/lib/registry.json +1004 -0
  114. package/apps/lib/tsconfig.json +9 -0
  115. package/apps/lib/utils/cn.ts +1 -1
  116. package/apps/lib/utils/dataViews/columnUtils.ts +46 -44
  117. package/apps/lib/utils/dataViews/fieldUtils.ts +70 -71
  118. package/apps/lib/utils/dataViews/nestedDataUtils.tsx +129 -122
  119. package/apps/lib/utils/dataViews/pathUtils.ts +74 -67
  120. package/apps/lib/utils/dataViews/rangeUtils.ts +121 -112
  121. package/apps/lib/utils/dataViews/treeUtils.ts +204 -211
  122. package/apps/lib/utils/dateFormat.ts +64 -54
  123. package/apps/lib/utils/markdownParser.ts +2 -7
  124. package/apps/lib/utils/resize.ts +21 -25
  125. package/apps/lib/utils/types.ts +13 -13
  126. package/dist/bin/index.js +8 -2
  127. package/dist/bin/index.js.map +1 -1
  128. package/dist/src/shared/getAvailableFiles.d.ts.map +1 -1
  129. package/dist/src/shared/getAvailableFiles.js +6 -1
  130. package/dist/src/shared/getAvailableFiles.js.map +1 -1
  131. package/dist/src/shared/loadRegistry.d.ts +7 -0
  132. package/dist/src/shared/loadRegistry.d.ts.map +1 -0
  133. package/dist/src/shared/loadRegistry.js +31 -0
  134. package/dist/src/shared/loadRegistry.js.map +1 -0
  135. package/dist/src/shared/resolveInstallPlan.d.ts +12 -0
  136. package/dist/src/shared/resolveInstallPlan.d.ts.map +1 -0
  137. package/dist/src/shared/resolveInstallPlan.js +39 -0
  138. package/dist/src/shared/resolveInstallPlan.js.map +1 -0
  139. package/dist/src/types/main.d.ts +24 -0
  140. package/dist/src/types/main.d.ts.map +1 -1
  141. package/docs/README.md +10 -2
  142. package/docs/components/action-button.md +30 -24
  143. package/docs/components/actions-group.md +26 -20
  144. package/docs/components/alert-dialog.md +45 -45
  145. package/docs/components/avatar.md +6 -2
  146. package/docs/components/badge-field.md +6 -2
  147. package/docs/components/badge.md +7 -1
  148. package/docs/components/breadcrumb.md +15 -40
  149. package/docs/components/button-group.md +13 -10
  150. package/docs/components/button.md +58 -33
  151. package/docs/components/calendar.md +26 -19
  152. package/docs/components/card.md +19 -16
  153. package/docs/components/chart-block-tool.md +128 -0
  154. package/docs/components/checkbox.md +16 -8
  155. package/docs/components/cn-layout.md +7 -1
  156. package/docs/components/context-menu.md +47 -24
  157. package/docs/components/count-badge.md +7 -1
  158. package/docs/components/data-table.md +45 -33
  159. package/docs/components/data-views-config-panel.md +18 -14
  160. package/docs/components/data-views-layout.md +20 -17
  161. package/docs/components/date-picker.md +30 -23
  162. package/docs/components/dialog.md +43 -42
  163. package/docs/components/divider.md +10 -4
  164. package/docs/components/drawer.md +8 -33
  165. package/docs/components/dropdown-menu.md +51 -32
  166. package/docs/components/field-hint.md +37 -25
  167. package/docs/components/field-section.md +9 -3
  168. package/docs/components/form-stepper.md +6 -0
  169. package/docs/components/form.md +17 -20
  170. package/docs/components/header-bar.md +187 -0
  171. package/docs/components/image-attachment.md +33 -41
  172. package/docs/components/inbox-view.md +16 -5
  173. package/docs/components/inner-label-field.md +34 -24
  174. package/docs/components/input-field.md +18 -10
  175. package/docs/components/input-otp.md +14 -11
  176. package/docs/components/input.md +22 -16
  177. package/docs/components/kanban-view.md +15 -5
  178. package/docs/components/label-field.md +32 -22
  179. package/docs/components/label.md +43 -32
  180. package/docs/components/labeled-check-box.md +16 -8
  181. package/docs/components/labeled-radio.md +18 -11
  182. package/docs/components/link-button.md +7 -1
  183. package/docs/components/login-button.md +8 -2
  184. package/docs/components/password-level.md +37 -24
  185. package/docs/components/popover.md +26 -23
  186. package/docs/components/profile-menu.md +38 -27
  187. package/docs/components/radio-card.md +16 -9
  188. package/docs/components/radio.md +16 -8
  189. package/docs/components/scroll-area.md +6 -2
  190. package/docs/components/search-field.md +14 -6
  191. package/docs/components/searchable-select.md +19 -14
  192. package/docs/components/searchable-table.md +60 -41
  193. package/docs/components/searchable-tree-dialog.md +190 -0
  194. package/docs/components/searchable-tree.md +200 -0
  195. package/docs/components/section-block.md +130 -4
  196. package/docs/components/select.md +23 -18
  197. package/docs/components/simple-select.md +14 -10
  198. package/docs/components/skeleton.md +43 -33
  199. package/docs/components/slide-date-picker.md +37 -29
  200. package/docs/components/spin-loading.md +32 -23
  201. package/docs/components/stepper.md +6 -0
  202. package/docs/components/switch.md +14 -6
  203. package/docs/components/tab-form-item.md +7 -1
  204. package/docs/components/tab-switch.md +13 -6
  205. package/docs/components/table-dnd-wrapper.md +105 -0
  206. package/docs/components/table-view.md +15 -5
  207. package/docs/components/table.md +28 -28
  208. package/docs/components/text-editor.md +19 -13
  209. package/docs/components/textarea.md +15 -7
  210. package/docs/components/timeline.md +6 -0
  211. package/docs/components/toast.md +35 -26
  212. package/docs/components/toggle-button.md +24 -21
  213. package/docs/components/toggle.md +23 -15
  214. package/docs/components/tooltip.md +42 -30
  215. package/docs/components/transparent-label.md +29 -20
  216. package/docs/components/tree-drop-down.md +31 -23
  217. package/docs/components/tree-sub-layout.md +6 -2
  218. package/docs/components/tree-view.md +16 -5
  219. package/docs/explanation/architecture.md +54 -0
  220. package/docs/explanation/design-system.md +52 -0
  221. package/docs/how-to/data-views-from-backend-response.md +7 -4
  222. package/docs/how-to/guides.md +24 -18
  223. package/docs/migration/changelog.md +38 -0
  224. package/docs/reference/cli.md +87 -0
  225. package/docs/reference/components.md +11 -12
  226. package/docs/reference/hooks.md +8 -8
  227. package/docs/reference/providers.md +22 -22
  228. package/docs/reference/tailwind-plugins.md +2 -2
  229. package/docs/reference/theme.md +85 -0
  230. package/docs/reference/types.md +4 -4
  231. package/docs/reference/utilities.md +19 -26
  232. package/docs/tutorials/building-first-form.md +20 -13
  233. package/docs/tutorials/component-composition.md +34 -50
  234. package/docs/tutorials/getting-started.md +2 -2
  235. package/docs/tutorials/theming-basics.md +13 -10
  236. package/package.json +31 -3
  237. package/dist/src/commands/block.d.ts +0 -5
  238. package/dist/src/commands/block.d.ts.map +0 -1
  239. package/dist/src/commands/block.js +0 -255
  240. package/dist/src/commands/block.js.map +0 -1
  241. package/dist/src/shared/configureFonts.d.ts +0 -6
  242. package/dist/src/shared/configureFonts.d.ts.map +0 -1
  243. package/dist/src/shared/configureFonts.js +0 -106
  244. package/dist/src/shared/configureFonts.js.map +0 -1
  245. package/dist/src/shared/configureGlobalCss.d.ts +0 -6
  246. package/dist/src/shared/configureGlobalCss.d.ts.map +0 -1
  247. package/dist/src/shared/configureGlobalCss.js +0 -154
  248. package/dist/src/shared/configureGlobalCss.js.map +0 -1
  249. package/dist/src/shared/configureTailwind.d.ts +0 -7
  250. package/dist/src/shared/configureTailwind.d.ts.map +0 -1
  251. package/dist/src/shared/configureTailwind.js +0 -163
  252. package/dist/src/shared/configureTailwind.js.map +0 -1
  253. package/dist/src/shared/detectFramework.d.ts +0 -23
  254. package/dist/src/shared/detectFramework.d.ts.map +0 -1
  255. package/dist/src/shared/detectFramework.js +0 -119
  256. package/dist/src/shared/detectFramework.js.map +0 -1
  257. package/dist/src/shared/installBaseUtils.d.ts +0 -5
  258. package/dist/src/shared/installBaseUtils.d.ts.map +0 -1
  259. package/dist/src/shared/installBaseUtils.js +0 -79
  260. package/dist/src/shared/installBaseUtils.js.map +0 -1
  261. package/dist/src/shared/resolveAliases.d.ts +0 -24
  262. package/dist/src/shared/resolveAliases.d.ts.map +0 -1
  263. package/dist/src/shared/resolveAliases.js +0 -98
  264. package/dist/src/shared/resolveAliases.js.map +0 -1
@@ -1,69 +1,103 @@
1
- 'use client'
1
+ "use client";
2
2
  import { cn } from "../utils/cn";
3
3
  import { cva, VariantProps } from "class-variance-authority";
4
4
  import { HTMLAttributes, ReactNode, useEffect, useState } from "react";
5
5
 
6
- const TreeDropDownVariants = cva(["cursor-pointer flex px-[6px] h-[40px] gap-2 justify-start items-center w-full",
6
+ const TreeDropDownVariants = cva(
7
+ [
8
+ "cursor-pointer flex px-[6px] h-[40px] gap-2 justify-start items-center w-full",
7
9
  "text-content-system-global-primary border-l-[2px] rtl:border-r-[2px] border-transparent outline-none",
8
10
  "hover:bg-white-alpha-075 hover:border-black-300 hover:text-content-system-action-primary-hover hover:gap-[14px]",
9
11
  "rounded-r-[4px] text-start whitespace-nowrap transition-all duration-150 ease-in-out",
10
- ], {
12
+ ],
13
+ {
11
14
  variants: {
12
- variant: {
13
- secondary: "",
14
- default: ""
15
- },
16
- active: {
17
- true: "hover:gap-[8px]"
18
- }
15
+ variant: {
16
+ secondary: "",
17
+ default: "",
18
+ },
19
+ active: {
20
+ true: "hover:gap-[8px]",
21
+ },
19
22
  },
20
23
  compoundVariants: [
21
- {
22
- active: true,
23
- variant: "default",
24
- className: [
25
- "bg-background-system-action-primary-hover border-border-system-action-primary-hover [&_button]:bg-purple-alpha-15 hover:bg-background-system-action-primary-hover hover:border-border-system-action-primary-hover",
26
- ]
27
- },
28
- {
29
- active: true,
30
- variant: "secondary",
31
- className: [
32
- "bg-wavy-navy-1000 border-border-system-action-field-hover-selected [&_button]:bg-blue-sparkle-alpha-15 hover:bg-wavy-navy-1000 hover:border-border-system-action-field-hover-selected",
33
- ]
34
- }
24
+ {
25
+ active: true,
26
+ variant: "default",
27
+ className: [
28
+ "bg-background-system-action-primary-hover border-border-system-action-primary-hover [&_button]:bg-purple-alpha-15 hover:bg-background-system-action-primary-hover hover:border-border-system-action-primary-hover",
29
+ ],
30
+ },
31
+ {
32
+ active: true,
33
+ variant: "secondary",
34
+ className: [
35
+ "bg-wavy-navy-1000 border-border-system-action-field-hover-selected [&_button]:bg-blue-sparkle-alpha-15 hover:bg-wavy-navy-1000 hover:border-border-system-action-field-hover-selected",
36
+ ],
37
+ },
35
38
  ],
36
- defaultVariants: {},//
37
-
38
- });
39
+ defaultVariants: {}, //
40
+ },
41
+ );
39
42
 
40
43
  interface Props extends HTMLAttributes<HTMLDivElement>, VariantProps<typeof TreeDropDownVariants> {
41
- theme?: "dark" | "light" | "default";
42
- treeLabel: ReactNode;
43
- open?: boolean;
44
- variant?: "secondary" | "default";
45
- childrenContainerClassName?: string
44
+ theme?: "dark" | "light" | "default";
45
+ treeLabel: ReactNode;
46
+ open?: boolean;
47
+ variant?: "secondary" | "default";
48
+ childrenContainerClassName?: string;
46
49
  }
47
50
 
48
- export const TreeDropDown = ({ childrenContainerClassName, className, variant = "secondary", treeLabel, open, theme, ...props }: Props) => {
49
- const [isActive, setIsActive] = useState(open);
50
- useEffect(() => {
51
- setIsActive(open)
52
- }, [open])
53
- return (
54
- <div {...props} className={cn("flex h-fit flex-col transition-all ease-in-out duration-500",)}>
55
- <div onClick={() => setIsActive(!isActive)} data-theme={theme} className={cn(TreeDropDownVariants({ variant, active: isActive }), className)}>
56
- <button className={cn("cursor-pointer outline-none border-none flex-0 leading-0 transition-transform ease-in-out flex justify-center items-center bg-background-system-body-tertiary h-[28px] w-[28px] rounded-full text-[20px] text-content-system-global-primary", { "rotate-180": isActive })}>
57
- <i className={cn("leading-none ri-arrow-down-s-line ")}></i>
58
- </button>
59
- <div className={cn("text-content-system-global-primary typography-body-medium-medium transition-all ease-in-out duration-100 flex-1 cursor-pointer")}>{treeLabel}</div>
60
- </div>
61
- <div className={cn("mt-0 pl-[22px] relative overflow-auto scrollbar-hide transition-all duration-500 ease-in-out", {
62
- "max-h-[20000px] mt-1": isActive, "max-h-0": !isActive,
63
- })}>
64
- <span className="h-full w-[1px] bg-border-system-global-primary absolute left-[21px] top-0 rounded-sm z-10" />
65
- <div className={cn("h-full flex flex-col gap-1 w-full", childrenContainerClassName)}>{props.children}</div>
66
- </div>
51
+ export const TreeDropDown = ({
52
+ childrenContainerClassName,
53
+ className,
54
+ variant = "secondary",
55
+ treeLabel,
56
+ open,
57
+ theme,
58
+ ...props
59
+ }: Props) => {
60
+ const [isActive, setIsActive] = useState(open);
61
+ useEffect(() => {
62
+ setIsActive(open);
63
+ }, [open]);
64
+ return (
65
+ <div {...props} className={cn("flex h-fit flex-col transition-all ease-in-out duration-500")}>
66
+ <div
67
+ onClick={() => setIsActive(!isActive)}
68
+ data-theme={theme}
69
+ className={cn(TreeDropDownVariants({ variant, active: isActive }), className)}
70
+ >
71
+ <button
72
+ className={cn(
73
+ "cursor-pointer outline-none border-none flex-0 leading-0 transition-transform ease-in-out flex justify-center items-center bg-background-system-body-tertiary h-[28px] w-[28px] rounded-full text-[20px] text-content-system-global-primary",
74
+ { "rotate-180": isActive },
75
+ )}
76
+ >
77
+ <i className={cn("leading-none ri-arrow-down-s-line ")}></i>
78
+ </button>
79
+ <div
80
+ className={cn(
81
+ "text-content-system-global-primary typography-body-medium-medium transition-all ease-in-out duration-100 flex-1 cursor-pointer",
82
+ )}
83
+ >
84
+ {treeLabel}
85
+ </div>
86
+ </div>
87
+ <div
88
+ className={cn(
89
+ "mt-0 pl-[22px] relative overflow-auto scrollbar-hide transition-all duration-500 ease-in-out",
90
+ {
91
+ "max-h-[20000px] mt-1": isActive,
92
+ "max-h-0": !isActive,
93
+ },
94
+ )}
95
+ >
96
+ <span className="h-full w-[1px] bg-border-system-global-primary absolute left-[21px] top-0 rounded-sm z-10" />
97
+ <div className={cn("h-full flex flex-col gap-1 w-full", childrenContainerClassName)}>
98
+ {props.children}
67
99
  </div>
68
- );
100
+ </div>
101
+ </div>
102
+ );
69
103
  };
@@ -14,13 +14,7 @@ import type { Themes } from "../../utils/types";
14
14
  import { TreeFolderBreadcrumb } from "./TreeFolderBreadcrumb";
15
15
  import { TreeFolderRow } from "./TreeFolderRow";
16
16
  import { TreeFolderStyles } from "./TreeFolderStyles";
17
- import {
18
- applyMove,
19
- descendantIds,
20
- findNode,
21
- findPath,
22
- toBreadcrumb,
23
- } from "./treeFolderUtils";
17
+ import { applyMove, descendantIds, findNode, findPath, toBreadcrumb } from "./treeFolderUtils";
24
18
  import type {
25
19
  TreeFolderIconResolver,
26
20
  TreeFolderMoveArgs,
@@ -85,21 +79,14 @@ function rootIds(nodes: TreeFolderNode[]): string[] {
85
79
  return nodes.map((n) => n.id);
86
80
  }
87
81
 
88
- function flattenVisible(
89
- data: TreeFolderNode[],
90
- expanded: Set<string>,
91
- ): TreeFolderVisibleRow[] {
82
+ function flattenVisible(data: TreeFolderNode[], expanded: Set<string>): TreeFolderVisibleRow[] {
92
83
  const out: TreeFolderVisibleRow[] = [];
93
84
  // `ancestorHasMore` tracks, for each open ancestor depth on the descent
94
85
  // path, whether that ancestor still has more siblings to render. We push
95
86
  // before descending and pop on the way back up; each row snapshots the
96
87
  // current state so its connector gutters know which verticals to draw.
97
88
  const ancestorHasMore: boolean[] = [];
98
- const walk = (
99
- nodes: TreeFolderNode[],
100
- level: number,
101
- parentId: string | null,
102
- ) => {
89
+ const walk = (nodes: TreeFolderNode[], level: number, parentId: string | null) => {
103
90
  nodes.forEach((node, idx) => {
104
91
  const isInternal = !!(node.children && node.children.length > 0);
105
92
  const isOpen = isInternal && expanded.has(node.id);
@@ -156,11 +143,8 @@ export const TreeFolder = forwardRef<TreeFolderHandle, TreeFolderProps>(
156
143
  const scrollRef = useRef<HTMLDivElement | null>(null);
157
144
 
158
145
  // ---- Selection state ----
159
- const [internalSelected, setInternalSelected] = useState<string | null>(
160
- defaultSelectedId,
161
- );
162
- const selectedId =
163
- controlledSelected !== undefined ? controlledSelected : internalSelected;
146
+ const [internalSelected, setInternalSelected] = useState<string | null>(defaultSelectedId);
147
+ const selectedId = controlledSelected !== undefined ? controlledSelected : internalSelected;
164
148
  const isSelectionControlled = controlledSelected !== undefined;
165
149
 
166
150
  // ---- Expansion state ----
@@ -175,10 +159,7 @@ export const TreeFolder = forwardRef<TreeFolderHandle, TreeFolderProps>(
175
159
  const expandedSet = useMemo(() => new Set(expandedIds), [expandedIds]);
176
160
 
177
161
  // ---- Visible rows ----
178
- const visibleRows = useMemo(
179
- () => flattenVisible(data, expandedSet),
180
- [data, expandedSet],
181
- );
162
+ const visibleRows = useMemo(() => flattenVisible(data, expandedSet), [data, expandedSet]);
182
163
  const rowsById = useMemo(() => {
183
164
  const m = new Map<string, TreeFolderVisibleRow>();
184
165
  for (const r of visibleRows) m.set(r.node.id, r);
@@ -244,9 +225,7 @@ export const TreeFolder = forwardRef<TreeFolderHandle, TreeFolderProps>(
244
225
  );
245
226
 
246
227
  const scrollToId = useCallback((id: string) => {
247
- const el = scrollRef.current?.querySelector<HTMLElement>(
248
- `[data-row-id="${CSS.escape(id)}"]`,
249
- );
228
+ const el = scrollRef.current?.querySelector<HTMLElement>(`[data-row-id="${CSS.escape(id)}"]`);
250
229
  el?.scrollIntoView({ block: "nearest", behavior: "smooth" });
251
230
  }, []);
252
231
 
@@ -299,9 +278,7 @@ export const TreeFolder = forwardRef<TreeFolderHandle, TreeFolderProps>(
299
278
  );
300
279
 
301
280
  const isEmpty = data.length === 0;
302
- const stripStyle = contentMinWidth
303
- ? { minWidth: contentMinWidth }
304
- : undefined;
281
+ const stripStyle = contentMinWidth ? { minWidth: contentMinWidth } : undefined;
305
282
 
306
283
  return (
307
284
  <div
@@ -333,11 +310,7 @@ export const TreeFolder = forwardRef<TreeFolderHandle, TreeFolderProps>(
333
310
  )}
334
311
 
335
312
  <TreeFolderStyles />
336
- <div
337
- ref={scrollRef}
338
- role="tree"
339
- className="tf-scroll flex-1 min-h-0 overflow-auto"
340
- >
313
+ <div ref={scrollRef} role="tree" className="tf-scroll flex-1 min-h-0 overflow-auto">
341
314
  {isEmpty ? (
342
315
  (emptyState ?? (
343
316
  <div className="text-xs text-content-presentation-global-tertiary p-3">
@@ -350,8 +323,7 @@ export const TreeFolder = forwardRef<TreeFolderHandle, TreeFolderProps>(
350
323
  const prevRow = visibleRows[idx - 1];
351
324
  const nextRow = visibleRows[idx + 1];
352
325
  const isSelected = selectedId === row.node.id;
353
- const isDescendant =
354
- isDescendantOfSelected(row.node.id) && !isSelected;
326
+ const isDescendant = isDescendantOfSelected(row.node.id) && !isSelected;
355
327
  const inBand = isSelected || isDescendant;
356
328
 
357
329
  // Neighbour-aware band rounding: a row is "in-band" if it's the selected
@@ -359,24 +331,19 @@ export const TreeFolder = forwardRef<TreeFolderHandle, TreeFolderProps>(
359
331
  const prevInBand =
360
332
  inBand &&
361
333
  !!prevRow &&
362
- (prevRow.node.id === selectedId ||
363
- descendantIdSet.has(prevRow.node.id));
334
+ (prevRow.node.id === selectedId || descendantIdSet.has(prevRow.node.id));
364
335
  const nextInBand =
365
336
  inBand &&
366
337
  !!nextRow &&
367
- (nextRow.node.id === selectedId ||
368
- descendantIdSet.has(nextRow.node.id));
338
+ (nextRow.node.id === selectedId || descendantIdSet.has(nextRow.node.id));
369
339
 
370
340
  const isDragging = dragIdSet.has(row.node.id);
371
341
  const isDropTargetInside =
372
- dropTarget?.rowId === row.node.id &&
373
- dropTarget.position === "inside";
342
+ dropTarget?.rowId === row.node.id && dropTarget.position === "inside";
374
343
  const isDropBefore =
375
- dropTarget?.rowId === row.node.id &&
376
- dropTarget.position === "before";
344
+ dropTarget?.rowId === row.node.id && dropTarget.position === "before";
377
345
  const isDropAfter =
378
- dropTarget?.rowId === row.node.id &&
379
- dropTarget.position === "after";
346
+ dropTarget?.rowId === row.node.id && dropTarget.position === "after";
380
347
 
381
348
  return (
382
349
  <TreeFolderRow
@@ -1,22 +1,17 @@
1
- "use client"
1
+ "use client";
2
2
 
3
- import { ChevronRight } from "lucide-react"
4
- import { cn } from "../../utils/cn"
5
- import type { TreeFolderBreadcrumb as BreadcrumbItems } from "./types"
3
+ import { ChevronRight } from "lucide-react";
4
+ import { cn } from "../../utils/cn";
5
+ import type { TreeFolderBreadcrumb as BreadcrumbItems } from "./types";
6
6
 
7
7
  type Props = {
8
- items: BreadcrumbItems
9
- onSelect?: (id: string) => void
10
- className?: string
11
- maxItems?: number
12
- }
8
+ items: BreadcrumbItems;
9
+ onSelect?: (id: string) => void;
10
+ className?: string;
11
+ maxItems?: number;
12
+ };
13
13
 
14
- export function TreeFolderBreadcrumb({
15
- items,
16
- onSelect,
17
- className,
18
- maxItems = 4,
19
- }: Props) {
14
+ export function TreeFolderBreadcrumb({ items, onSelect, className, maxItems = 4 }: Props) {
20
15
  if (items.length === 0) {
21
16
  return (
22
17
  <div
@@ -27,13 +22,13 @@ export function TreeFolderBreadcrumb({
27
22
  >
28
23
  No selection
29
24
  </div>
30
- )
25
+ );
31
26
  }
32
27
 
33
28
  const display =
34
29
  items.length > maxItems
35
30
  ? [items[0], { id: "__ellipsis", name: "…" }, ...items.slice(-(maxItems - 2))]
36
- : items
31
+ : items;
37
32
 
38
33
  return (
39
34
  <nav
@@ -45,8 +40,8 @@ export function TreeFolderBreadcrumb({
45
40
  >
46
41
  <ol className="flex items-center gap-1 min-w-0 flex-1">
47
42
  {display.map((item, idx) => {
48
- const isLast = idx === display.length - 1
49
- const isEllipsis = item.id === "__ellipsis"
43
+ const isLast = idx === display.length - 1;
44
+ const isEllipsis = item.id === "__ellipsis";
50
45
  return (
51
46
  <li key={`${item.id}-${idx}`} className="flex items-center gap-1 min-w-0">
52
47
  {idx > 0 && (
@@ -72,9 +67,9 @@ export function TreeFolderBreadcrumb({
72
67
  </button>
73
68
  )}
74
69
  </li>
75
- )
70
+ );
76
71
  })}
77
72
  </ol>
78
73
  </nav>
79
- )
74
+ );
80
75
  }
@@ -4,7 +4,7 @@ import { ChevronRight, ChevronDown, GripVertical } from "lucide-react";
4
4
  import type { DragEvent } from "react";
5
5
  import { cn } from "../../utils/cn";
6
6
  import { resolveIcon } from "./icons";
7
- import type { TreeFolderIconResolver, TreeFolderVisibleRow } from "./types";
7
+ import type { TreeFolderIconResolver, TreeFolderNode, TreeFolderVisibleRow } from "./types";
8
8
 
9
9
  export type TreeFolderRowDragHandlers = {
10
10
  draggable: boolean;
@@ -70,8 +70,7 @@ export function TreeFolderRow({
70
70
  // they read as "members of the selected group" without competing with the
71
71
  // selection itself. Rows stand alone — no neighbor-aware joining anymore.
72
72
  const showSelected = isSelected && !willReceiveDrop;
73
- const showChildOfSelected =
74
- inSubtreeOfSelected && !isSelected && !willReceiveDrop;
73
+ const showChildOfSelected = inSubtreeOfSelected && !isSelected && !willReceiveDrop;
75
74
  // A row is "in the selection group" if it's the selected node itself or a
76
75
  // descendant tinted by it. Neighbor-aware rounding then merges adjacent rows
77
76
  // into one continuous pill instead of stacked individual chips.
@@ -102,9 +101,7 @@ export function TreeFolderRow({
102
101
  // Token isn't exposed as channels, so Tailwind's /alpha modifier doesn't
103
102
  // work on it — paint the descendant tint with the same hex at 30% alpha.
104
103
  showChildOfSelected && "bg-[#005ECC]/30",
105
- inAncestorChain &&
106
- !inGroup &&
107
- "bg-background-presentation-state-information-secondary",
104
+ inAncestorChain && !inGroup && "bg-background-presentation-state-information-secondary",
108
105
  willReceiveDrop && "bg-background-presentation-state-information-primary",
109
106
  );
110
107
 
@@ -155,9 +152,7 @@ export function TreeFolderRow({
155
152
  <GripVertical
156
153
  className={cn(
157
154
  "w-3.5 h-3.5",
158
- showSelected
159
- ? "text-white/80"
160
- : "text-content-presentation-global-tertiary",
155
+ showSelected ? "text-white/80" : "text-content-presentation-global-tertiary",
161
156
  )}
162
157
  />
163
158
  </span>
@@ -228,9 +223,7 @@ export function TreeFolderRow({
228
223
  <span
229
224
  className={cn(
230
225
  "shrink-0 w-4 h-4 flex items-center justify-center",
231
- showSelected
232
- ? "text-white/90"
233
- : "text-content-presentation-global-tertiary",
226
+ showSelected ? "text-white/90" : "text-content-presentation-global-tertiary",
234
227
  )}
235
228
  aria-hidden
236
229
  >
@@ -245,9 +238,7 @@ export function TreeFolderRow({
245
238
  <span
246
239
  className={cn(
247
240
  "shrink-0 text-xs tabular-nums",
248
- showSelected
249
- ? "text-white/80"
250
- : "text-content-presentation-global-tertiary",
241
+ showSelected ? "text-white/80" : "text-content-presentation-global-tertiary",
251
242
  )}
252
243
  >
253
244
  ({countDescendants(node)})
@@ -348,16 +339,14 @@ function TreeConnectors({
348
339
  return <>{segments}</>;
349
340
  }
350
341
 
351
- function countDescendants(node: {
352
- children?: { children?: any[] }[] | null;
353
- }): number {
342
+ function countDescendants(node: { children?: TreeFolderNode[] | null }): number {
354
343
  if (!node.children) return 0;
355
344
  let n = 0;
356
- const stack: any[] = [...node.children];
345
+ const stack: TreeFolderNode[] = [...node.children];
357
346
  while (stack.length) {
358
347
  n++;
359
348
  const top = stack.pop();
360
- if (top.children) for (const c of top.children) stack.push(c);
349
+ if (top?.children) for (const c of top.children) stack.push(c);
361
350
  }
362
351
  return n;
363
352
  }
@@ -1,4 +1,4 @@
1
- "use client"
1
+ "use client";
2
2
 
3
3
  /**
4
4
  * Component-scoped CSS for TreeFolder. Rendered once by TreeFolder itself so
@@ -47,7 +47,7 @@ const CSS = `
47
47
  background: rgba(0, 0, 0, 0.35);
48
48
  background-clip: content-box;
49
49
  }
50
- `
50
+ `;
51
51
 
52
52
  /**
53
53
  * Renders a single <style> tag containing TreeFolder's scoped CSS.
@@ -56,5 +56,5 @@ const CSS = `
56
56
  * keeps just one DOM node when it can.
57
57
  */
58
58
  export function TreeFolderStyles() {
59
- return <style id="torch-treefolder-styles" dangerouslySetInnerHTML={{ __html: CSS }} />
59
+ return <style id="torch-treefolder-styles" dangerouslySetInnerHTML={{ __html: CSS }} />;
60
60
  }
@@ -1,4 +1,4 @@
1
- "use client"
1
+ "use client";
2
2
 
3
3
  import {
4
4
  Folder,
@@ -14,14 +14,11 @@ import {
14
14
  Link as LinkIcon,
15
15
  Square,
16
16
  LayoutGrid,
17
- } from "lucide-react"
18
- import type { ReactNode } from "react"
19
- import type { TreeFolderIconResolver, TreeFolderNode } from "./types"
17
+ } from "lucide-react";
18
+ import type { ReactNode } from "react";
19
+ import type { TreeFolderIconResolver, TreeFolderNode } from "./types";
20
20
 
21
- export const defaultIconRegistry: Record<
22
- string,
23
- (state: { isOpen: boolean }) => ReactNode
24
- > = {
21
+ export const defaultIconRegistry: Record<string, (state: { isOpen: boolean }) => ReactNode> = {
25
22
  folder: ({ isOpen }) =>
26
23
  isOpen ? <FolderOpen className="w-3.5 h-3.5" /> : <Folder className="w-3.5 h-3.5" />,
27
24
  file: () => <File className="w-3.5 h-3.5" />,
@@ -35,19 +32,19 @@ export const defaultIconRegistry: Record<
35
32
  link: () => <LinkIcon className="w-3.5 h-3.5" />,
36
33
  section: () => <LayoutGrid className="w-3.5 h-3.5" />,
37
34
  container: () => <Square className="w-3.5 h-3.5" />,
38
- }
35
+ };
39
36
 
40
37
  export function defaultIconFor(
41
38
  node: TreeFolderNode,
42
39
  state: { isOpen: boolean; isInternal: boolean; isSelected: boolean },
43
40
  ): ReactNode {
44
- if (node.icon !== undefined) return node.icon
45
- const type = node.type ?? (state.isInternal ? "folder" : "file")
46
- const resolver = defaultIconRegistry[type]
47
- if (resolver) return resolver({ isOpen: state.isOpen })
41
+ if (node.icon !== undefined) return node.icon;
42
+ const type = node.type ?? (state.isInternal ? "folder" : "file");
43
+ const resolver = defaultIconRegistry[type];
44
+ if (resolver) return resolver({ isOpen: state.isOpen });
48
45
  return state.isInternal
49
46
  ? defaultIconRegistry.folder({ isOpen: state.isOpen })
50
- : defaultIconRegistry.file({ isOpen: state.isOpen })
47
+ : defaultIconRegistry.file({ isOpen: state.isOpen });
51
48
  }
52
49
 
53
50
  export function resolveIcon(
@@ -56,8 +53,8 @@ export function resolveIcon(
56
53
  state: { isOpen: boolean; isInternal: boolean; isSelected: boolean },
57
54
  ): ReactNode {
58
55
  if (iconFor) {
59
- const custom = iconFor(node, state)
60
- if (custom !== undefined && custom !== null) return custom
56
+ const custom = iconFor(node, state);
57
+ if (custom !== undefined && custom !== null) return custom;
61
58
  }
62
- return defaultIconFor(node, state)
59
+ return defaultIconFor(node, state);
63
60
  }
@@ -1,10 +1,17 @@
1
- export { TreeFolder } from "./TreeFolder"
2
- export type { TreeFolderHandle, TreeFolderProps } from "./TreeFolder"
3
- export { TreeFolderRow } from "./TreeFolderRow"
4
- export type { TreeFolderRowProps, TreeFolderRowDragHandlers } from "./TreeFolderRow"
5
- export { TreeFolderBreadcrumb } from "./TreeFolderBreadcrumb"
6
- export { defaultIconRegistry, defaultIconFor } from "./icons"
7
- export { applyMove, findPath, findNode, isAncestor, descendantIds, toBreadcrumb } from "./treeFolderUtils"
1
+ export { TreeFolder } from "./TreeFolder";
2
+ export type { TreeFolderHandle, TreeFolderProps } from "./TreeFolder";
3
+ export { TreeFolderRow } from "./TreeFolderRow";
4
+ export type { TreeFolderRowProps, TreeFolderRowDragHandlers } from "./TreeFolderRow";
5
+ export { TreeFolderBreadcrumb } from "./TreeFolderBreadcrumb";
6
+ export { defaultIconRegistry, defaultIconFor } from "./icons";
7
+ export {
8
+ applyMove,
9
+ findPath,
10
+ findNode,
11
+ isAncestor,
12
+ descendantIds,
13
+ toBreadcrumb,
14
+ } from "./treeFolderUtils";
8
15
  export type {
9
16
  TreeFolderNode,
10
17
  TreeFolderNodeType,
@@ -14,4 +21,4 @@ export type {
14
21
  TreeFolderDropPosition,
15
22
  TreeFolderDropTarget,
16
23
  TreeFolderBreadcrumb as TreeFolderBreadcrumbItems,
17
- } from "./types"
24
+ } from "./types";