torch-glare 2.4.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 +1 -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 +97 -96
  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 +1 -6
  19. package/apps/lib/components/DataViews/DataViewsConfigPanel.tsx +13 -47
  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 +155 -149
  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 +30 -23
  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 +104 -115
  41. package/apps/lib/components/DatePicker.tsx +198 -196
  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 +131 -171
  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 +1 -9
  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 +8 -14
  69. package/apps/lib/components/SearchableTable.tsx +108 -118
  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 +18 -25
  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 +15 -11
  160. package/docs/components/data-views-layout.md +13 -16
  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 +25 -34
  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 +6 -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 +18 -13
  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 +12 -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 +6 -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
@@ -0,0 +1,190 @@
1
+ ---
2
+ title: SearchableTreeDialog
3
+ description: Searchable tree-select presented in a modal dialog — a trigger opens a dialog containing a searchable hierarchical tree, with client or server-side search
4
+ group: Inputs
5
+ keywords: [searchable-tree-dialog, tree, tree-select, dialog, modal, hierarchy, search, async]
6
+ ---
7
+
8
+ # SearchableTreeDialog
9
+
10
+ > A searchable tree-select that opens in a modal **Dialog** instead of a popover. A trigger
11
+ > field opens a dialog containing a search input and a hierarchical tree of nodes, filtered as
12
+ > you type. Accepts nested data (via `getNodeChildren`) or a flat list it nests for you (via
13
+ > `parentIdKey`). Supports local filtering or debounced server-side search, optional folder
14
+ > selection, and controlled selection. Use it instead of [SearchableTree](./searchable-tree.md)
15
+ > when the tree is large or you want a focused, full-screen-friendly selection surface.
16
+
17
+ ## Installation
18
+
19
+ TORCH Glare is a copy-in library: the CLI copies this component's source into your project
20
+ (you do **not** install it from the npm package). Run `init` once, then `add`:
21
+
22
+ ```bash
23
+ npx torch-glare@latest init
24
+ npx torch-glare@latest add SearchableTreeDialog
25
+ ```
26
+
27
+ The CLI also copies its internal dependencies: `Button`, `Dialog`, `Input`, and the
28
+ `cn`/`types` utils.
29
+
30
+ ## Import
31
+
32
+ ```typescript
33
+ import { SearchableTreeDialog } from "@/components/SearchableTreeDialog";
34
+ ```
35
+
36
+ ## Quick Examples
37
+
38
+ ### Basic Usage (nested data)
39
+
40
+ ```tsx
41
+ import { SearchableTreeDialog } from "@/components/SearchableTreeDialog";
42
+
43
+ type Node = { id: string; name: string; children?: Node[] };
44
+
45
+ const data: Node[] = [
46
+ {
47
+ id: "eng",
48
+ name: "Engineering",
49
+ children: [
50
+ { id: "fe", name: "Frontend" },
51
+ { id: "be", name: "Backend" },
52
+ ],
53
+ },
54
+ { id: "design", name: "Design" },
55
+ ];
56
+
57
+ export function DepartmentPicker() {
58
+ const [value, setValue] = useState<Node | null>(null);
59
+
60
+ return (
61
+ <SearchableTreeDialog
62
+ nodes={data}
63
+ getNodeId={(n) => n.id}
64
+ getNodeLabel={(n) => n.name}
65
+ getNodeChildren={(n) => n.children}
66
+ value={value}
67
+ onSelect={setValue}
68
+ placeholder="Select a department"
69
+ searchPlaceholder="Search departments…"
70
+ title="Departments"
71
+ size="M"
72
+ />
73
+ );
74
+ }
75
+ ```
76
+
77
+ ### Flat data (built from a parent id)
78
+
79
+ ```tsx
80
+ type Row = { id: string; label: string; parentId: string | null };
81
+
82
+ const rows: Row[] = [
83
+ { id: "1", label: "Company", parentId: null },
84
+ { id: "2", label: "Sales", parentId: "1" },
85
+ { id: "3", label: "EMEA", parentId: "2" },
86
+ ];
87
+
88
+ <SearchableTreeDialog
89
+ nodes={rows}
90
+ parentIdKey="parentId"
91
+ getNodeId={(r) => r.id}
92
+ getNodeLabel={(r) => r.label}
93
+ onSelect={(r) => console.log(r.id)}
94
+ />;
95
+ ```
96
+
97
+ ### Server-side search
98
+
99
+ ```tsx
100
+ <SearchableTreeDialog
101
+ nodes={results}
102
+ getNodeId={(n) => n.id}
103
+ getNodeLabel={(n) => n.name}
104
+ getNodeChildren={(n) => n.children}
105
+ filterClientSide={false}
106
+ onSearchChange={(query) => fetchNodes(query)}
107
+ loading={isFetching}
108
+ searchDebounceMs={300}
109
+ />
110
+ ```
111
+
112
+ ## API Reference
113
+
114
+ ### Props
115
+
116
+ | Prop | Type | Default | Description |
117
+ |------|------|---------|-------------|
118
+ | `nodes` | `T[]` | — | Tree data. Nested by default; treated as a flat list when `parentIdKey` is set. |
119
+ | `getNodeId` | `(node: T) => string` | — | Returns a stable unique id for a node. |
120
+ | `getNodeLabel` | `(node: T) => ReactNode` | — | Returns a node's display label. |
121
+ | `getNodeChildren` | `(node: T) => T[] \| undefined` | — | Returns a node's children (nested mode). Ignored when `parentIdKey` is set. |
122
+ | `parentIdKey` | `keyof T & string` | — | When set, `nodes` is a FLAT list and the tree is built from this parent-id key. |
123
+ | `value` | `T \| null` | — | Controlled selected node. |
124
+ | `onSelect` | `(node: T) => void` | — | Called when a node is selected. |
125
+ | `getSearchText` | `(node: T) => string` | `String(getNodeLabel(node))` | Plain text used for search matching. |
126
+ | `placeholder` | `string` | — | Trigger placeholder shown until a node is selected. |
127
+ | `searchPlaceholder` | `string` | — | Placeholder for the search input inside the dialog. |
128
+ | `title` | `string` | — | Label shown on the dialog's search field. |
129
+ | `size` | `"XS" \| "S" \| "M"` | `"M"` | Trigger size. |
130
+ | `variant` | `"SystemStyle" \| "PresentationStyle"` | `"PresentationStyle"` | Visual style. `SystemStyle` is reserved for internal library system surfaces. |
131
+ | `icon` | `ReactNode` | — | Leading icon in the trigger. |
132
+ | `theme` | `Themes` | — | `"dark" \| "light" \| "default"`. |
133
+ | `dir` | `string` | — | Text direction. |
134
+ | `className` | `string` | — | Extra classes for the trigger. |
135
+ | `defaultExpanded` | `boolean` | `true` | Expand every node when the dialog opens. |
136
+ | `selectableFolders` | `boolean` | `false` | When true, folder nodes are selectable too; otherwise folders only expand/collapse. |
137
+ | `filterClientSide` | `boolean` | `true` | Filter locally. Set `false` for server-side search. |
138
+ | `onSearchChange` | `(query: string) => void` | — | Debounced as the user types — refetch your data here (server search). |
139
+ | `searchDebounceMs` | `number` | `300` | Debounce for `onSearchChange`. |
140
+ | `loading` | `boolean` | `false` | Whether a fetch is in flight; shows a loading indicator. |
141
+
142
+ ### TypeScript
143
+
144
+ ```typescript
145
+ import { ReactNode } from "react";
146
+ import { Themes } from "@/utils/types";
147
+
148
+ interface SearchableTreeDialogProps<T> {
149
+ nodes: T[];
150
+ getNodeId: (node: T) => string;
151
+ getNodeLabel: (node: T) => ReactNode;
152
+ getNodeChildren?: (node: T) => T[] | undefined;
153
+ parentIdKey?: keyof T & string;
154
+ value?: T | null;
155
+ onSelect?: (node: T) => void;
156
+ getSearchText?: (node: T) => string;
157
+ placeholder?: string;
158
+ searchPlaceholder?: string;
159
+ title?: string;
160
+ size?: "XS" | "S" | "M";
161
+ variant?: "SystemStyle" | "PresentationStyle";
162
+ icon?: ReactNode;
163
+ theme?: Themes;
164
+ dir?: string;
165
+ className?: string;
166
+ defaultExpanded?: boolean;
167
+ selectableFolders?: boolean;
168
+ filterClientSide?: boolean;
169
+ onSearchChange?: (query: string) => void;
170
+ searchDebounceMs?: number;
171
+ loading?: boolean;
172
+ }
173
+
174
+ export function SearchableTreeDialog<T>(props: SearchableTreeDialogProps<T>): JSX.Element;
175
+ ```
176
+
177
+ ## Common Patterns
178
+
179
+ - **Dialog vs popover:** use `SearchableTreeDialog` for large trees or a focused modal
180
+ selection; use [SearchableTree](./searchable-tree.md) for an inline popover field.
181
+ - **Nested vs flat data:** provide `getNodeChildren` for nested data, or `parentIdKey` to nest
182
+ a flat list. Do not use both.
183
+ - **Async search:** set `filterClientSide={false}`, handle `onSearchChange` to fetch, and pass
184
+ `loading` while the request is in flight.
185
+
186
+ ## Related Components
187
+
188
+ - [SearchableTree](./searchable-tree.md) — the same tree-select on an inline Popover.
189
+ - [SearchableSelect](./searchable-select.md) — flat searchable single-select combobox.
190
+ - [Dialog](./dialog.md) — the modal surface this component builds on.
@@ -0,0 +1,200 @@
1
+ ---
2
+ title: SearchableTree
3
+ description: Searchable tree-select that opens on focus and filters hierarchical nodes as you type, on a Popover surface, with client or server-side search
4
+ group: Inputs
5
+ keywords: [searchable-tree, tree, tree-select, hierarchy, search, combobox, async, popover]
6
+ ---
7
+
8
+ # SearchableTree
9
+
10
+ > A searchable tree-select. It renders a field that opens a Popover containing a hierarchical
11
+ > tree of nodes and filters them as you type. Accepts either nested data (via `getNodeChildren`)
12
+ > or a flat list that it nests for you (via `parentIdKey`). Supports local filtering or
13
+ > debounced server-side search, optional folder selection, and controlled selection.
14
+
15
+ ## Installation
16
+
17
+ TORCH Glare is a copy-in library: the CLI copies this component's source into your project
18
+ (you do **not** install it from the npm package). Run `init` once, then `add`:
19
+
20
+ ```bash
21
+ npx torch-glare@latest init
22
+ npx torch-glare@latest add SearchableTree
23
+ ```
24
+
25
+ The CLI also copies its internal dependencies: `Button`, `Input`, `Popover`, the
26
+ `useClickOutside` hook, and the `cn`/`types` utils.
27
+
28
+ ## Import
29
+
30
+ ```typescript
31
+ import { SearchableTree } from "@/components/SearchableTree";
32
+ ```
33
+
34
+ ## Quick Examples
35
+
36
+ ### Basic Usage (nested data)
37
+
38
+ ```tsx
39
+ import { SearchableTree } from "@/components/SearchableTree";
40
+
41
+ type Node = { id: string; name: string; children?: Node[] };
42
+
43
+ const data: Node[] = [
44
+ {
45
+ id: "eng",
46
+ name: "Engineering",
47
+ children: [
48
+ { id: "fe", name: "Frontend" },
49
+ { id: "be", name: "Backend" },
50
+ ],
51
+ },
52
+ { id: "design", name: "Design" },
53
+ ];
54
+
55
+ export function DepartmentPicker() {
56
+ const [value, setValue] = useState<Node | null>(null);
57
+
58
+ return (
59
+ <SearchableTree
60
+ nodes={data}
61
+ getNodeId={(n) => n.id}
62
+ getNodeLabel={(n) => n.name}
63
+ getNodeChildren={(n) => n.children}
64
+ value={value}
65
+ onSelect={setValue}
66
+ placeholder="Select a department"
67
+ title="Departments"
68
+ size="M"
69
+ />
70
+ );
71
+ }
72
+ ```
73
+
74
+ ### Flat data (built from a parent id)
75
+
76
+ ```tsx
77
+ type Row = { id: string; label: string; parentId: string | null };
78
+
79
+ const rows: Row[] = [
80
+ { id: "1", label: "Company", parentId: null },
81
+ { id: "2", label: "Sales", parentId: "1" },
82
+ { id: "3", label: "EMEA", parentId: "2" },
83
+ ];
84
+
85
+ <SearchableTree
86
+ nodes={rows}
87
+ parentIdKey="parentId"
88
+ getNodeId={(r) => r.id}
89
+ getNodeLabel={(r) => r.label}
90
+ onSelect={(r) => console.log(r.id)}
91
+ />;
92
+ ```
93
+
94
+ ### Server-side search
95
+
96
+ ```tsx
97
+ <SearchableTree
98
+ nodes={results}
99
+ getNodeId={(n) => n.id}
100
+ getNodeLabel={(n) => n.name}
101
+ getNodeChildren={(n) => n.children}
102
+ filterClientSide={false}
103
+ onSearchChange={(query) => fetchNodes(query)}
104
+ loading={isFetching}
105
+ searchDebounceMs={300}
106
+ />
107
+ ```
108
+
109
+ ### Selectable folders
110
+
111
+ ```tsx
112
+ <SearchableTree
113
+ nodes={data}
114
+ getNodeId={(n) => n.id}
115
+ getNodeLabel={(n) => n.name}
116
+ getNodeChildren={(n) => n.children}
117
+ selectableFolders
118
+ onSelect={(n) => console.log(n.id)}
119
+ />
120
+ ```
121
+
122
+ ## API Reference
123
+
124
+ ### Props
125
+
126
+ | Prop | Type | Default | Description |
127
+ |------|------|---------|-------------|
128
+ | `nodes` | `T[]` | — | Tree data. Nested by default; treated as a flat list when `parentIdKey` is set. |
129
+ | `getNodeId` | `(node: T) => string` | — | Returns a stable unique id for a node. |
130
+ | `getNodeLabel` | `(node: T) => ReactNode` | — | Returns a node's display label. |
131
+ | `getNodeChildren` | `(node: T) => T[] \| undefined` | — | Returns a node's children (nested mode). Ignored when `parentIdKey` is set. |
132
+ | `parentIdKey` | `keyof T & string` | — | When set, `nodes` is a FLAT list and the tree is built from this parent-id key. |
133
+ | `value` | `T \| null` | — | Controlled selected node. |
134
+ | `onSelect` | `(node: T) => void` | — | Called when a node is selected. |
135
+ | `getSearchText` | `(node: T) => string` | `String(getNodeLabel(node))` | Plain text used for search matching. |
136
+ | `placeholder` | `string` | `"Select…"` | Field placeholder shown when nothing is selected. |
137
+ | `title` | `string` | `"Select an item"` | Section heading above the tree rows in the dropdown. |
138
+ | `size` | `"XS" \| "S" \| "M"` | `"M"` | Field size. |
139
+ | `variant` | `"SystemStyle" \| "PresentationStyle"` | `"PresentationStyle"` | Visual style. `SystemStyle` is reserved for internal library system surfaces. |
140
+ | `icon` | `ReactNode` | — | Leading icon in the field. |
141
+ | `theme` | `Themes` | — | `"dark" \| "light" \| "default"`. |
142
+ | `dir` | `string` | — | Text direction. |
143
+ | `className` | `string` | — | Extra classes for the field. |
144
+ | `defaultExpanded` | `boolean` | `true` | Expand every node when the dropdown opens. |
145
+ | `selectableFolders` | `boolean` | `false` | When true, folder nodes are selectable too; otherwise folders only expand/collapse. |
146
+ | `maxBodyHeight` | `number` | `320` | Max height (px) of the scrollable tree body before it scrolls. |
147
+ | `filterClientSide` | `boolean` | `true` | Filter locally. Set `false` for server-side search. |
148
+ | `onSearchChange` | `(query: string) => void` | — | Debounced as the user types — refetch your data here (server search). |
149
+ | `searchDebounceMs` | `number` | `300` | Debounce for `onSearchChange`. |
150
+ | `loading` | `boolean` | `false` | Whether a fetch is in flight; shows a loading indicator. |
151
+
152
+ ### TypeScript
153
+
154
+ ```typescript
155
+ import { ReactNode } from "react";
156
+ import { Themes } from "@/utils/types";
157
+
158
+ interface SearchableTreeProps<T> {
159
+ nodes: T[];
160
+ getNodeId: (node: T) => string;
161
+ getNodeLabel: (node: T) => ReactNode;
162
+ getNodeChildren?: (node: T) => T[] | undefined;
163
+ parentIdKey?: keyof T & string;
164
+ value?: T | null;
165
+ onSelect?: (node: T) => void;
166
+ getSearchText?: (node: T) => string;
167
+ placeholder?: string;
168
+ title?: string;
169
+ size?: "XS" | "S" | "M";
170
+ variant?: "SystemStyle" | "PresentationStyle";
171
+ icon?: ReactNode;
172
+ theme?: Themes;
173
+ dir?: string;
174
+ className?: string;
175
+ defaultExpanded?: boolean;
176
+ selectableFolders?: boolean;
177
+ maxBodyHeight?: number;
178
+ filterClientSide?: boolean;
179
+ onSearchChange?: (query: string) => void;
180
+ searchDebounceMs?: number;
181
+ loading?: boolean;
182
+ }
183
+
184
+ export function SearchableTree<T>(props: SearchableTreeProps<T>): JSX.Element;
185
+ ```
186
+
187
+ ## Common Patterns
188
+
189
+ - **Nested vs flat data:** provide `getNodeChildren` for already-nested data, or `parentIdKey`
190
+ to let the component nest a flat list for you. Do not use both.
191
+ - **Async search:** set `filterClientSide={false}` and handle `onSearchChange` to fetch from a
192
+ backend; pass `loading` while the request is in flight.
193
+ - **Folder selection:** by default only leaf nodes are selectable. Set `selectableFolders` to
194
+ allow selecting a folder node (clicking any node selects it and closes the dropdown).
195
+
196
+ ## Related Components
197
+
198
+ - [SearchableTreeDialog](./searchable-tree-dialog.md) — the same tree-select in a modal dialog.
199
+ - [SearchableSelect](./searchable-select.md) — flat searchable single-select combobox.
200
+ - [TreeDropDown](./tree-drop-down.md) — dropdown tree without search.
@@ -6,7 +6,7 @@ category: layout
6
6
  group: Layout & Containers
7
7
  tags: [layout, card, section, container, form, group]
8
8
  status: stable
9
- version: 1.1.22
9
+ version: 2.4.0
10
10
  dependencies:
11
11
  - "class-variance-authority": "^0.7.0"
12
12
  ---
@@ -17,14 +17,22 @@ dependencies:
17
17
 
18
18
  ## Installation
19
19
 
20
+ TORCH Glare is a copy-in library: the CLI copies this component's source into your project
21
+ (you do **not** install it from the npm package). Run `init` once, then `add`:
22
+
20
23
  ```bash
21
- npx torch-glare add SectionBlock
24
+ npx torch-glare@latest init
25
+ npx torch-glare@latest add SectionBlock
22
26
  ```
23
27
 
28
+ `add` also copies any components, hooks, and utilities that `SectionBlock` depends on.
29
+
24
30
  ## Import
25
31
 
26
- ```typescript
27
- import { SectionBlock, type SectionColor } from "@/components/SectionBlock";
32
+ Import from your project's local path — the alias configured in `glare.json` (e.g. `@/*`):
33
+
34
+ ```tsx
35
+ import { SectionBlock } from "@/components/SectionBlock";
28
36
  ```
29
37
 
30
38
  ## Basic Usage
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: Select
3
- version: 1.1.15
3
+ version: 2.4.0
4
4
  status: stable
5
5
  category: components/forms
6
6
  tags: [form, select, dropdown, accessible, radix-ui]
@@ -17,23 +17,22 @@ dependencies:
17
17
 
18
18
  ## Installation
19
19
 
20
+ TORCH Glare is a copy-in library: the CLI copies this component's source into your project
21
+ (you do **not** install it from the npm package). Run `init` once, then `add`:
22
+
20
23
  ```bash
21
- npm install torch-glare
24
+ npx torch-glare@latest init
25
+ npx torch-glare@latest add Select
22
26
  ```
23
27
 
28
+ `add` also copies any components, hooks, and utilities that `Select` depends on.
29
+
24
30
  ## Import
25
31
 
26
- ```typescript
27
- import {
28
- Select,
29
- SelectTrigger,
30
- SelectContent,
31
- SelectItem,
32
- SelectValue,
33
- SelectGroup,
34
- SelectLabel,
35
- SelectSeparator
36
- } from 'torch-glare/lib/components/Select'
32
+ Import from your project's local path — the alias configured in `glare.json` (e.g. `@/*`):
33
+
34
+ ```tsx
35
+ import { Select } from "@/components/Select";
37
36
  ```
38
37
 
39
38
  ## Quick Examples
@@ -47,7 +46,7 @@ import {
47
46
  SelectContent,
48
47
  SelectItem,
49
48
  SelectValue
50
- } from 'torch-glare/lib/components/Select'
49
+ } from '@/components/Select'
51
50
 
52
51
  function Example() {
53
52
  const [value, setValue] = useState('')
@@ -265,6 +264,9 @@ function Uncontrolled() {
265
264
  | Prop | Type | Default | Description |
266
265
  |------|------|---------|-------------|
267
266
  | `value` | `string` | - | Item value (required) |
267
+ | `variant` | `'Default' \| 'Warning' \| 'Negative' \| 'SystemStyle'` | `'Default'` | Visual variant |
268
+ | `size` | `'S' \| 'M'` | `'M'` | Item size |
269
+ | `active` | `boolean` | `false` | Renders the item in its selected/active style |
268
270
  | `disabled` | `boolean` | `false` | Disable item |
269
271
  | `className` | `string` | - | Additional CSS classes |
270
272
  | `children` | `React.ReactNode` | - | Item content |
@@ -272,7 +274,7 @@ function Uncontrolled() {
272
274
  ### TypeScript
273
275
 
274
276
  ```typescript
275
- import type { Themes } from 'torch-glare/lib/utils/types'
277
+ import type { Themes } from '@/utils/types'
276
278
 
277
279
  // Select component types
278
280
  interface SelectProps {
@@ -316,6 +318,9 @@ interface SelectContentProps {
316
318
  // Item types
317
319
  interface SelectItemProps {
318
320
  value: string
321
+ variant?: 'Default' | 'Warning' | 'Negative' | 'SystemStyle'
322
+ size?: 'S' | 'M'
323
+ active?: boolean
319
324
  disabled?: boolean
320
325
  className?: string
321
326
  children: React.ReactNode
@@ -363,8 +368,8 @@ function CountrySelect() {
363
368
  ### Form Integration
364
369
 
365
370
  ```typescript
366
- import { Form } from 'torch-glare/lib/components/Form'
367
- import { Label } from 'torch-glare/lib/components/Label'
371
+ import { Form } from '@/components/Form'
372
+ import { Label } from '@/components/Label'
368
373
 
369
374
  function FormSelect() {
370
375
  const [formData, setFormData] = useState({
@@ -464,7 +469,7 @@ function DynamicSelect() {
464
469
 
465
470
  ```typescript
466
471
  import { render, screen, fireEvent } from '@testing-library/react'
467
- import { Select, SelectTrigger, SelectContent, SelectItem, SelectValue } from 'torch-glare/lib/components/Select'
472
+ import { Select, SelectTrigger, SelectContent, SelectItem, SelectValue } from '@/components/Select'
468
473
 
469
474
  describe('Select', () => {
470
475
  it('opens dropdown on trigger click', () => {
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: SimpleSelect
3
- version: 1.1.15
3
+ version: 2.4.0
4
4
  status: stable
5
5
  category: components/forms
6
6
  tags: [form, select, dropdown, custom, system-style, accessible]
@@ -17,18 +17,22 @@ dependencies:
17
17
 
18
18
  ## Installation
19
19
 
20
+ TORCH Glare is a copy-in library: the CLI copies this component's source into your project
21
+ (you do **not** install it from the npm package). Run `init` once, then `add`:
22
+
20
23
  ```bash
21
- npm install torch-glare
24
+ npx torch-glare@latest init
25
+ npx torch-glare@latest add SimpleSelect
22
26
  ```
23
27
 
28
+ `add` also copies any components, hooks, and utilities that `SimpleSelect` depends on.
29
+
24
30
  ## Import
25
31
 
26
- ```typescript
27
- import {
28
- SimpleSelectValue,
29
- SimpleSelectItem,
30
- SimpleSelectDropDown
31
- } from 'torch-glare/lib/components/SimpleSelect'
32
+ Import from your project's local path — the alias configured in `glare.json` (e.g. `@/*`):
33
+
34
+ ```tsx
35
+ import { SimpleSelect } from "@/components/SimpleSelect";
32
36
  ```
33
37
 
34
38
  ## Quick Examples
@@ -36,7 +40,7 @@ import {
36
40
  ### Basic Usage
37
41
 
38
42
  ```typescript
39
- import { SimpleSelectValue, SimpleSelectItem } from 'torch-glare/lib/components/SimpleSelect'
43
+ import { SimpleSelectValue, SimpleSelectItem } from '@/components/SimpleSelect'
40
44
 
41
45
  function Example() {
42
46
  const [value, setValue] = useState('option1')
@@ -470,7 +474,7 @@ function DynamicSelect() {
470
474
 
471
475
  ```typescript
472
476
  import { render, screen, fireEvent } from '@testing-library/react'
473
- import { SimpleSelectValue, SimpleSelectItem } from 'torch-glare/lib/components/SimpleSelect'
477
+ import { SimpleSelectValue, SimpleSelectItem } from '@/components/SimpleSelect'
474
478
 
475
479
  describe('SimpleSelect', () => {
476
480
  it('opens dropdown on click', () => {