@px-ui/ui 1.0.11 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (280) hide show
  1. package/dist/{avatar-cLlUF5Lz.d.ts → avatar-DTxH_yTY.d.ts} +6 -6
  2. package/dist/{avatar-cLlUF5Lz.d.ts.map → avatar-DTxH_yTY.d.ts.map} +1 -1
  3. package/dist/{avatar-a40DzPi3.js → avatar-DnDnGmSj.js} +4 -4
  4. package/dist/{avatar-a40DzPi3.js.map → avatar-DnDnGmSj.js.map} +1 -1
  5. package/dist/{button-BJ727apo.d.ts → button-Cfd9X6pX.d.ts} +6 -6
  6. package/dist/{button-BJ727apo.d.ts.map → button-Cfd9X6pX.d.ts.map} +1 -1
  7. package/dist/{button-Cp2S1spE.js → button-DnHwqwy0.js} +2 -2
  8. package/dist/{button-Cp2S1spE.js.map → button-DnHwqwy0.js.map} +1 -1
  9. package/dist/checkbox-CwkX29tL.js +22 -0
  10. package/dist/checkbox-CwkX29tL.js.map +1 -0
  11. package/dist/collapsible-DsrYXIW5.js +28 -0
  12. package/dist/collapsible-DsrYXIW5.js.map +1 -0
  13. package/dist/{combobox-Di5naqIR.js → combobox-5IAivvXw.js} +9 -9
  14. package/dist/{combobox-Di5naqIR.js.map → combobox-5IAivvXw.js.map} +1 -1
  15. package/dist/{combobox-B73nb6Tq.d.ts → combobox-BBMYGrI2.d.ts} +19 -19
  16. package/dist/{combobox-B73nb6Tq.d.ts.map → combobox-BBMYGrI2.d.ts.map} +1 -1
  17. package/dist/components/accordion.d.ts +5 -5
  18. package/dist/components/accordion.d.ts.map +1 -1
  19. package/dist/components/accordion.js +2 -2
  20. package/dist/components/alert-dialog.d.ts +14 -14
  21. package/dist/components/alert-dialog.d.ts.map +1 -1
  22. package/dist/components/alert-dialog.js +3 -3
  23. package/dist/components/alert.d.ts +5 -5
  24. package/dist/components/alert.js +2 -2
  25. package/dist/components/aspect-ratio.d.ts +2 -2
  26. package/dist/components/aspect-ratio.d.ts.map +1 -1
  27. package/dist/components/aspect-ratio.js +1 -1
  28. package/dist/components/attachment.d.ts +14 -14
  29. package/dist/components/attachment.js +3 -3
  30. package/dist/components/avatar-group.d.ts +4 -4
  31. package/dist/components/avatar-group.js +5 -5
  32. package/dist/components/avatar.d.ts +1 -1
  33. package/dist/components/avatar.js +3 -3
  34. package/dist/components/badge.d.ts +4 -4
  35. package/dist/components/badge.js +1 -1
  36. package/dist/components/breadcrumb.d.ts +7 -7
  37. package/dist/components/breadcrumb.js +2 -2
  38. package/dist/components/bubble.d.ts +7 -7
  39. package/dist/components/bubble.js +2 -2
  40. package/dist/components/button-group.d.ts +9 -9
  41. package/dist/components/button-group.d.ts.map +1 -1
  42. package/dist/components/button-group.js +2 -2
  43. package/dist/components/button.d.ts +1 -1
  44. package/dist/components/button.js +2 -2
  45. package/dist/components/calendar.d.ts +4 -4
  46. package/dist/components/calendar.d.ts.map +1 -1
  47. package/dist/components/calendar.js +3 -3
  48. package/dist/components/card.d.ts +8 -8
  49. package/dist/components/card.d.ts.map +1 -1
  50. package/dist/components/card.js +2 -2
  51. package/dist/components/carousel.d.ts +7 -7
  52. package/dist/components/carousel.d.ts.map +1 -1
  53. package/dist/components/carousel.js +3 -3
  54. package/dist/components/chart.d.ts +5 -5
  55. package/dist/components/chart.d.ts.map +1 -1
  56. package/dist/components/chart.js +2 -2
  57. package/dist/components/checkbox.d.ts +2 -2
  58. package/dist/components/checkbox.d.ts.map +1 -1
  59. package/dist/components/checkbox.js +3 -21
  60. package/dist/components/collapsible.d.ts +4 -4
  61. package/dist/components/collapsible.d.ts.map +1 -1
  62. package/dist/components/collapsible.js +3 -27
  63. package/dist/components/combobox.d.ts +2 -2
  64. package/dist/components/combobox.js +11 -11
  65. package/dist/components/command.d.ts +11 -11
  66. package/dist/components/command.js +7 -7
  67. package/dist/components/context-menu.d.ts +16 -16
  68. package/dist/components/context-menu.d.ts.map +1 -1
  69. package/dist/components/context-menu.js +2 -2
  70. package/dist/components/currency-select-field.d.ts +4 -4
  71. package/dist/components/currency-select-field.d.ts.map +1 -1
  72. package/dist/components/currency-select-field.js +12 -12
  73. package/dist/components/dialog.d.ts +11 -11
  74. package/dist/components/dialog.js +3 -3
  75. package/dist/components/direction.js +1 -1
  76. package/dist/components/drawer.d.ts +11 -11
  77. package/dist/components/drawer.js +2 -2
  78. package/dist/components/dropdown-menu.d.ts +1 -1
  79. package/dist/components/dropdown-menu.js +2 -2
  80. package/dist/components/editor-output.d.ts +87 -0
  81. package/dist/components/editor-output.d.ts.map +1 -0
  82. package/dist/components/editor-output.js +158 -0
  83. package/dist/components/editor-output.js.map +1 -0
  84. package/dist/components/empty.d.ts +7 -7
  85. package/dist/components/empty.js +3 -61
  86. package/dist/components/field.d.ts +16 -16
  87. package/dist/components/field.d.ts.map +1 -1
  88. package/dist/components/field.js +4 -4
  89. package/dist/components/file-upload-field.d.ts +3 -3
  90. package/dist/components/file-upload-field.js +6 -6
  91. package/dist/components/file-upload.d.ts +3 -3
  92. package/dist/components/file-upload.js +4 -4
  93. package/dist/components/hover-card.d.ts +4 -4
  94. package/dist/components/hover-card.js +1 -1
  95. package/dist/components/icon.d.ts +83 -0
  96. package/dist/components/icon.d.ts.map +1 -0
  97. package/dist/components/icon.js +188 -0
  98. package/dist/components/icon.js.map +1 -0
  99. package/dist/components/input-group.d.ts +11 -11
  100. package/dist/components/input-group.d.ts.map +1 -1
  101. package/dist/components/input-group.js +5 -5
  102. package/dist/components/input-otp.d.ts +5 -5
  103. package/dist/components/input-otp.js +2 -2
  104. package/dist/components/input.d.ts +1 -1
  105. package/dist/components/input.js +2 -2
  106. package/dist/components/item.d.ts +15 -15
  107. package/dist/components/item.d.ts.map +1 -1
  108. package/dist/components/item.js +3 -3
  109. package/dist/components/kbd.d.ts +3 -3
  110. package/dist/components/kbd.js +1 -1
  111. package/dist/components/label.d.ts +1 -1
  112. package/dist/components/label.js +2 -2
  113. package/dist/components/marker.d.ts +5 -5
  114. package/dist/components/marker.js +2 -2
  115. package/dist/components/menubar.d.ts +18 -18
  116. package/dist/components/menubar.d.ts.map +1 -1
  117. package/dist/components/menubar.js +8 -8
  118. package/dist/components/menubar.js.map +1 -1
  119. package/dist/components/message-scroller.d.ts +8 -8
  120. package/dist/components/message-scroller.js +3 -3
  121. package/dist/components/message.d.ts +7 -7
  122. package/dist/components/message.js +2 -2
  123. package/dist/components/native-select.d.ts +4 -4
  124. package/dist/components/native-select.js +2 -2
  125. package/dist/components/navigation-menu.d.ts +11 -11
  126. package/dist/components/navigation-menu.js +1 -1
  127. package/dist/components/pagination.d.ts +9 -9
  128. package/dist/components/pagination.js +3 -3
  129. package/dist/components/phone-input.d.ts +2 -2
  130. package/dist/components/phone-input.js +2 -2
  131. package/dist/components/popover.d.ts +7 -7
  132. package/dist/components/popover.js +2 -2
  133. package/dist/components/progress.d.ts +6 -6
  134. package/dist/components/progress.js +1 -1
  135. package/dist/components/radio-group.d.ts +3 -3
  136. package/dist/components/radio-group.js +1 -1
  137. package/dist/components/resizable.d.ts +4 -4
  138. package/dist/components/resizable.js +1 -1
  139. package/dist/components/rich-text-editor.d.ts +204 -0
  140. package/dist/components/rich-text-editor.d.ts.map +1 -0
  141. package/dist/components/rich-text-editor.js +359 -0
  142. package/dist/components/rich-text-editor.js.map +1 -0
  143. package/dist/components/scroll-area.d.ts +13 -3
  144. package/dist/components/scroll-area.d.ts.map +1 -1
  145. package/dist/components/scroll-area.js +3 -38
  146. package/dist/components/select.d.ts +10 -10
  147. package/dist/components/select.js +2 -2
  148. package/dist/components/separator.d.ts +1 -1
  149. package/dist/components/separator.js +2 -2
  150. package/dist/components/sheet.d.ts +9 -9
  151. package/dist/components/sheet.js +3 -3
  152. package/dist/components/sidebar.d.ts +26 -26
  153. package/dist/components/sidebar.js +9 -9
  154. package/dist/components/skeleton.d.ts +2 -2
  155. package/dist/components/skeleton.js +2 -2
  156. package/dist/components/slider.d.ts +2 -2
  157. package/dist/components/slider.js +1 -1
  158. package/dist/components/sortable-list.d.ts +153 -0
  159. package/dist/components/sortable-list.d.ts.map +1 -0
  160. package/dist/components/sortable-list.js +191 -0
  161. package/dist/components/sortable-list.js.map +1 -0
  162. package/dist/components/spinner.d.ts +2 -2
  163. package/dist/components/spinner.js +2 -2
  164. package/dist/components/stepper.d.ts +171 -0
  165. package/dist/components/stepper.d.ts.map +1 -0
  166. package/dist/components/stepper.js +281 -0
  167. package/dist/components/stepper.js.map +1 -0
  168. package/dist/components/switch.d.ts +2 -2
  169. package/dist/components/switch.js +1 -1
  170. package/dist/components/table.d.ts +9 -9
  171. package/dist/components/table.js +2 -2
  172. package/dist/components/tabs.d.ts +7 -7
  173. package/dist/components/tabs.js +1 -1
  174. package/dist/components/textarea.d.ts +2 -2
  175. package/dist/components/textarea.js +2 -2
  176. package/dist/components/toast.d.ts +1 -1
  177. package/dist/components/toast.js +2 -2
  178. package/dist/components/toggle-group.d.ts +4 -4
  179. package/dist/components/toggle-group.js +3 -3
  180. package/dist/components/toggle.d.ts +1 -1
  181. package/dist/components/toggle.js +2 -2
  182. package/dist/components/tooltip.d.ts +1 -1
  183. package/dist/components/tooltip.js +2 -2
  184. package/dist/components/tree-select.d.ts +192 -0
  185. package/dist/components/tree-select.d.ts.map +1 -0
  186. package/dist/components/tree-select.js +421 -0
  187. package/dist/components/tree-select.js.map +1 -0
  188. package/dist/{dialog-B3HhbIdv.js → dialog-DuGJUPQl.js} +4 -4
  189. package/dist/{dialog-B3HhbIdv.js.map → dialog-DuGJUPQl.js.map} +1 -1
  190. package/dist/{dropdown-menu-vwX--mgm.js → dropdown-menu-BWEfcvmP.js} +20 -20
  191. package/dist/{dropdown-menu-vwX--mgm.js.map → dropdown-menu-BWEfcvmP.js.map} +1 -1
  192. package/dist/{dropdown-menu-C6n_oYre.d.ts → dropdown-menu-DGgfWYrK.d.ts} +17 -17
  193. package/dist/{dropdown-menu-C6n_oYre.d.ts.map → dropdown-menu-DGgfWYrK.d.ts.map} +1 -1
  194. package/dist/empty-U4zrLmFU.js +62 -0
  195. package/dist/empty-U4zrLmFU.js.map +1 -0
  196. package/dist/{file-upload-CGfXHKPZ.d.ts → file-upload-BvAtAxLc.d.ts} +13 -13
  197. package/dist/{file-upload-CGfXHKPZ.d.ts.map → file-upload-BvAtAxLc.d.ts.map} +1 -1
  198. package/dist/{file-upload-B0fHdUBL.js → file-upload-DU5FAkHm.js} +5 -5
  199. package/dist/{file-upload-B0fHdUBL.js.map → file-upload-DU5FAkHm.js.map} +1 -1
  200. package/dist/hooks/use-async-options.d.ts +1 -1
  201. package/dist/hooks/use-async-options.js +1 -1
  202. package/dist/hooks/use-debounce.js +1 -1
  203. package/dist/hooks/use-file-upload.d.ts +1 -1
  204. package/dist/hooks/use-file-upload.js +1 -1
  205. package/dist/hooks/use-infinite-scroll.d.ts +1 -1
  206. package/dist/hooks/use-infinite-scroll.js +2 -2
  207. package/dist/hooks/use-intersection-observer.d.ts +1 -1
  208. package/dist/hooks/use-intersection-observer.js +1 -1
  209. package/dist/hooks/use-mobile.js +1 -1
  210. package/dist/{input-BtI3FvrB.d.ts → input-BExbcSu4.d.ts} +3 -3
  211. package/dist/input-BExbcSu4.d.ts.map +1 -0
  212. package/dist/{input-group-C78_1dEy.js → input-group-B5PMRYld.js} +6 -6
  213. package/dist/{input-group-C78_1dEy.js.map → input-group-B5PMRYld.js.map} +1 -1
  214. package/dist/{input-B-RCmrtR.js → input-jIoNIdLQ.js} +3 -3
  215. package/dist/{input-B-RCmrtR.js.map → input-jIoNIdLQ.js.map} +1 -1
  216. package/dist/label-BFg2hxuL.d.ts +11 -0
  217. package/dist/label-BFg2hxuL.d.ts.map +1 -0
  218. package/dist/{label-Cmlhz-uF.js → label-DsRhOKY_.js} +3 -3
  219. package/dist/{label-Cmlhz-uF.js.map → label-DsRhOKY_.js.map} +1 -1
  220. package/dist/lib/utils.js +1 -1
  221. package/dist/{popover-CsTnnBvx.js → popover-BGkU46G7.js} +3 -3
  222. package/dist/{popover-CsTnnBvx.js.map → popover-BGkU46G7.js.map} +1 -1
  223. package/dist/providers/px-ui-provider.d.ts +4 -4
  224. package/dist/providers/px-ui-provider.d.ts.map +1 -1
  225. package/dist/providers/px-ui-provider.js +4 -4
  226. package/dist/scroll-area-mNVMQ0Of.js +40 -0
  227. package/dist/scroll-area-mNVMQ0Of.js.map +1 -0
  228. package/dist/{separator-BQBOLUMc.js → separator-D0bew2D_.js} +2 -2
  229. package/dist/{separator-BQBOLUMc.js.map → separator-D0bew2D_.js.map} +1 -1
  230. package/dist/{separator-pyhTqgkN.d.ts → separator-Df76guaT.d.ts} +3 -3
  231. package/dist/{separator-pyhTqgkN.d.ts.map → separator-Df76guaT.d.ts.map} +1 -1
  232. package/dist/{sheet-Chg_afex.js → sheet-BB23q6wd.js} +4 -4
  233. package/dist/{sheet-Chg_afex.js.map → sheet-BB23q6wd.js.map} +1 -1
  234. package/dist/{skeleton-J879XBBA.js → skeleton-knxLhbA5.js} +2 -2
  235. package/dist/{skeleton-J879XBBA.js.map → skeleton-knxLhbA5.js.map} +1 -1
  236. package/dist/{spinner-C7yzrK_s.js → spinner-9MdgLDTZ.js} +2 -2
  237. package/dist/{spinner-C7yzrK_s.js.map → spinner-9MdgLDTZ.js.map} +1 -1
  238. package/dist/{textarea-CaHmr0re.js → textarea-hZg0gA8u.js} +3 -3
  239. package/dist/{textarea-CaHmr0re.js.map → textarea-hZg0gA8u.js.map} +1 -1
  240. package/dist/{toast-BrPEQywl.js → toast-BdxoP8vz.js} +4 -4
  241. package/dist/{toast-BrPEQywl.js.map → toast-BdxoP8vz.js.map} +1 -1
  242. package/dist/{toast-CSU7vJkV.d.ts → toast-C5FRpq1P.d.ts} +5 -5
  243. package/dist/{toast-CSU7vJkV.d.ts.map → toast-C5FRpq1P.d.ts.map} +1 -1
  244. package/dist/{toggle-CA4KsgWs.js → toggle-BZXrLBLK.js} +2 -2
  245. package/dist/{toggle-CA4KsgWs.js.map → toggle-BZXrLBLK.js.map} +1 -1
  246. package/dist/{toggle-gjMAPmkg.d.ts → toggle-CyTngkhT.d.ts} +6 -6
  247. package/dist/{toggle-gjMAPmkg.d.ts.map → toggle-CyTngkhT.d.ts.map} +1 -1
  248. package/dist/{tooltip-7bptiThf.d.ts → tooltip-CkX3CD71.d.ts} +6 -6
  249. package/dist/{tooltip-7bptiThf.d.ts.map → tooltip-CkX3CD71.d.ts.map} +1 -1
  250. package/dist/{tooltip-BhxGE3Gb.js → tooltip-Dsfn_zZD.js} +2 -2
  251. package/dist/{tooltip-BhxGE3Gb.js.map → tooltip-Dsfn_zZD.js.map} +1 -1
  252. package/dist/{use-async-options-rNdyxIrQ.d.ts → use-async-options-DdyHJxHh.d.ts} +1 -1
  253. package/dist/{use-async-options-rNdyxIrQ.d.ts.map → use-async-options-DdyHJxHh.d.ts.map} +1 -1
  254. package/dist/{use-async-options-CtB4wZrr.js → use-async-options-tueAuVs_.js} +1 -1
  255. package/dist/{use-async-options-CtB4wZrr.js.map → use-async-options-tueAuVs_.js.map} +1 -1
  256. package/dist/{use-debounce--Lv1ABSa.js → use-debounce-7gIeOwla.js} +1 -1
  257. package/dist/{use-debounce--Lv1ABSa.js.map → use-debounce-7gIeOwla.js.map} +1 -1
  258. package/dist/{use-file-upload-Cbb_9kTw.d.ts → use-file-upload-Bc7CyQ7O.d.ts} +1 -1
  259. package/dist/{use-file-upload-Cbb_9kTw.d.ts.map → use-file-upload-Bc7CyQ7O.d.ts.map} +1 -1
  260. package/dist/{use-file-upload-BbERd3Nw.js → use-file-upload-DQD1vY_Z.js} +1 -1
  261. package/dist/{use-file-upload-BbERd3Nw.js.map → use-file-upload-DQD1vY_Z.js.map} +1 -1
  262. package/dist/{use-infinite-scroll-CC_Guyvn.js → use-infinite-scroll-HpeMA2MK.js} +2 -2
  263. package/dist/{use-infinite-scroll-CC_Guyvn.js.map → use-infinite-scroll-HpeMA2MK.js.map} +1 -1
  264. package/dist/{use-intersection-observer-CgAaXczI.d.ts → use-intersection-observer-DNPextJs.d.ts} +1 -1
  265. package/dist/{use-intersection-observer-CgAaXczI.d.ts.map → use-intersection-observer-DNPextJs.d.ts.map} +1 -1
  266. package/dist/{use-intersection-observer-S0wsPmhF.js → use-intersection-observer-rlKEjyL1.js} +1 -1
  267. package/dist/{use-intersection-observer-S0wsPmhF.js.map → use-intersection-observer-rlKEjyL1.js.map} +1 -1
  268. package/dist/{use-mobile--NaMWuCj.js → use-mobile-DUqQzj2D.js} +1 -1
  269. package/dist/{use-mobile--NaMWuCj.js.map → use-mobile-DUqQzj2D.js.map} +1 -1
  270. package/dist/{utils-DeIaBj75.js → utils-DUlptRpf.js} +1 -1
  271. package/dist/{utils-DeIaBj75.js.map → utils-DUlptRpf.js.map} +1 -1
  272. package/package.json +60 -1
  273. package/dist/components/checkbox.js.map +0 -1
  274. package/dist/components/collapsible.js.map +0 -1
  275. package/dist/components/empty.js.map +0 -1
  276. package/dist/components/scroll-area.js.map +0 -1
  277. package/dist/input-BtI3FvrB.d.ts.map +0 -1
  278. package/dist/label-BnSHwOyi.d.ts +0 -11
  279. package/dist/label-BnSHwOyi.d.ts.map +0 -1
  280. /package/dist/{direction-ZS2Hta3v.js → direction-DFPbwDSF.js} +0 -0
@@ -0,0 +1,192 @@
1
+ import * as react_jsx_runtime297 from "react/jsx-runtime";
2
+ import * as React$1 from "react";
3
+
4
+ //#region src/components/tree-select.d.ts
5
+ /**
6
+ * A single node in the tree passed to {@link TreeSelect}.
7
+ */
8
+ interface TreeSelectNode {
9
+ /** Stable, unique identifier. Used as the selection key in `value`. */
10
+ id: string;
11
+ /** Human-readable label rendered on the row. */
12
+ label: React$1.ReactNode;
13
+ /** Plain-text label used for search matching. Falls back to `label` when it is a string. */
14
+ searchText?: string;
15
+ /** Optional child nodes. Presence of a non-empty array makes the row expandable. */
16
+ children?: TreeSelectNode[];
17
+ /** Disables the row's checkbox (and excludes it from parent propagation). */
18
+ disabled?: boolean;
19
+ }
20
+ /** Tri-state checked status for a node, per the active `selectionMode`. */
21
+ type TreeSelectCheckedState = "checked" | "unchecked" | "indeterminate";
22
+ /** How selecting a node affects the others. See {@link TreeSelectProps.selectionMode}. */
23
+ type TreeSelectSelectionMode = "cascade" | "leaf" | "independent";
24
+ /** Per-row context passed to {@link TreeSelectProps.renderNode}. */
25
+ interface TreeSelectNodeMeta {
26
+ /** Tri-state of this row under the active `selectionMode`. */
27
+ state: TreeSelectCheckedState;
28
+ /** 0-based depth (root rows are depth 0). */
29
+ depth: number;
30
+ /** Whether this (expandable) row is currently open. Always false for leaves. */
31
+ expanded: boolean;
32
+ /** Whether the row is disabled (the node itself, or the whole control). */
33
+ disabled: boolean;
34
+ /** Put this on your label text (`id={meta.labelId}`) to name the checkbox. */
35
+ labelId: string;
36
+ /** Toggle this row's selection; omit `next` to flip from the current state. */
37
+ toggle: (next?: boolean) => void;
38
+ }
39
+ interface TreeSelectProps extends Omit<React$1.ComponentProps<"div">, "onChange" | "defaultValue"> {
40
+ /** The tree of nodes to render. */
41
+ nodes: TreeSelectNode[];
42
+ /** Controlled selection — array of selected node `id`s. Pair with `onValueChange`. */
43
+ value?: string[];
44
+ /** Initial selection for the uncontrolled case. @default [] */
45
+ defaultValue?: string[];
46
+ /** Called whenever the selection changes, with the next array of selected `id`s. */
47
+ onValueChange?: (value: string[]) => void;
48
+ /**
49
+ * Render a search box that filters the tree. Matching nodes and their
50
+ * ancestors are kept; non-matching branches are hidden.
51
+ * @default false
52
+ */
53
+ searchable?: boolean;
54
+ /** Placeholder for the search input. @default "Search…" */
55
+ searchPlaceholder?: string;
56
+ /** Controlled search query. Pair with `onSearchChange`. */
57
+ search?: string;
58
+ /** Default search query for the uncontrolled case. @default "" */
59
+ defaultSearch?: string;
60
+ /** Called when the internal search query changes. */
61
+ onSearchChange?: (search: string) => void;
62
+ /**
63
+ * Maximum depth to render, 0-based (root nodes are depth 0). Nodes deeper
64
+ * than this are not rendered and are excluded from propagation/counts.
65
+ * Omit for unlimited depth.
66
+ */
67
+ maxDepth?: number;
68
+ /**
69
+ * How selecting a node affects the others.
70
+ * - `"cascade"` (default): selecting a parent selects all of its enabled
71
+ * descendants; a branch with a mix shows the indeterminate state. The
72
+ * selection includes both parent ids and leaf ids.
73
+ * - `"leaf"`: only leaf rows are selectable. A parent checkbox toggles its
74
+ * enabled leaves and reflects their tri-state, but parent ids never enter
75
+ * `value`, and counts are based on leaves.
76
+ * - `"independent"`: each node toggles only itself — no cascade and no
77
+ * indeterminate roll-up.
78
+ * @default "cascade"
79
+ */
80
+ selectionMode?: TreeSelectSelectionMode;
81
+ /**
82
+ * Show a summary line above the tree with the selected count.
83
+ * @default true
84
+ */
85
+ showSummary?: boolean;
86
+ /**
87
+ * Render a custom summary given the selected ids and the total selectable
88
+ * count. Overrides the default count text.
89
+ */
90
+ renderSummary?: (selectedCount: number, total: number) => React$1.ReactNode;
91
+ /**
92
+ * Render the row body (everything after the checkbox) yourself. You own the
93
+ * label markup — including click-to-toggle (call `meta.toggle()`) and naming
94
+ * the managed checkbox (put `id={meta.labelId}` on your label text, or rely
95
+ * on a string `label`/`searchText` as the fallback name). The chevron,
96
+ * checkbox, indentation, and expansion stay managed by the component.
97
+ */
98
+ renderNode?: (node: TreeSelectNode, meta: TreeSelectNodeMeta) => React$1.ReactNode;
99
+ /** Message shown when the tree has no nodes at all. @default "No items." */
100
+ emptyMessage?: React$1.ReactNode;
101
+ /** Message shown when a search query yields no matches. @default "No results found." */
102
+ noResultsMessage?: React$1.ReactNode;
103
+ /** Disable the entire control. */
104
+ disabled?: boolean;
105
+ /**
106
+ * Whether all branches start expanded (uncontrolled). Ignored when
107
+ * `expandedIds` or `defaultExpandedIds` is provided. @default false
108
+ */
109
+ defaultExpanded?: boolean;
110
+ /**
111
+ * Controlled set of expanded branch `id`s. Pair with `onExpandedChange`.
112
+ * Driving this lets a consumer implement expand-all / collapse-all or
113
+ * persist which branches are open.
114
+ */
115
+ expandedIds?: string[];
116
+ /** Initial expanded branch `id`s for the uncontrolled case. */
117
+ defaultExpandedIds?: string[];
118
+ /** Called when the set of expanded branch `id`s changes. */
119
+ onExpandedChange?: (expandedIds: string[]) => void;
120
+ /** Max height of the scroll viewport (any CSS length). @default "16rem" */
121
+ scrollHeight?: string | number;
122
+ /** Extra className for the scroll viewport wrapper. */
123
+ scrollClassName?: string;
124
+ }
125
+ /**
126
+ * A hierarchical, searchable tree multi-select with tri-state checkboxes.
127
+ *
128
+ * Selecting a parent selects all of its (enabled) descendants; clearing a
129
+ * parent clears them. A branch with a mix of selected and unselected
130
+ * descendants shows the indeterminate state. The selection is a flat array of
131
+ * node ids and works controlled (`value` + `onValueChange`) or uncontrolled
132
+ * (`defaultValue`). Expansion is likewise controllable (`expandedIds` +
133
+ * `onExpandedChange`) so consumers can implement expand-all / collapse-all.
134
+ *
135
+ * @example
136
+ * ```tsx
137
+ * const nodes = [
138
+ * {
139
+ * id: "fe",
140
+ * label: "Frontend",
141
+ * children: [
142
+ * { id: "react", label: "React" },
143
+ * { id: "vue", label: "Vue" },
144
+ * ],
145
+ * },
146
+ * { id: "be", label: "Backend", children: [{ id: "rails", label: "Rails" }] },
147
+ * ]
148
+ *
149
+ * function Example() {
150
+ * const [value, setValue] = React.useState<string[]>(["react"])
151
+ * return (
152
+ * <TreeSelect
153
+ * nodes={nodes}
154
+ * value={value}
155
+ * onValueChange={setValue}
156
+ * searchable
157
+ * maxDepth={1}
158
+ * />
159
+ * )
160
+ * }
161
+ * ```
162
+ */
163
+ declare function TreeSelect({
164
+ nodes,
165
+ value,
166
+ defaultValue,
167
+ onValueChange,
168
+ searchable,
169
+ searchPlaceholder,
170
+ search,
171
+ defaultSearch,
172
+ onSearchChange,
173
+ maxDepth,
174
+ selectionMode,
175
+ showSummary,
176
+ renderSummary,
177
+ renderNode,
178
+ emptyMessage,
179
+ noResultsMessage,
180
+ disabled,
181
+ defaultExpanded,
182
+ expandedIds,
183
+ defaultExpandedIds,
184
+ onExpandedChange,
185
+ scrollHeight,
186
+ scrollClassName,
187
+ className,
188
+ ...props
189
+ }: TreeSelectProps): react_jsx_runtime297.JSX.Element;
190
+ //#endregion
191
+ export { TreeSelect, TreeSelectCheckedState, TreeSelectNode, TreeSelectNodeMeta, TreeSelectProps, TreeSelectSelectionMode };
192
+ //# sourceMappingURL=tree-select.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree-select.d.ts","names":[],"sources":["../../src/components/tree-select.tsx"],"sourcesContent":[],"mappings":";;;;;;;AAiCiB,UAAA,cAAA,CAAc;EAcnB;EAIA,EAAA,EAAA,MAAA;EAGK;EAeA,KAAA,EAhCR,OAAA,CAAM,SAiCb;EAAa;EAEN,UAAA,CAAA,EAAA,MAAA;EAuCS;EAU0C,QAAM,CAAA,EAhFrD,cAgFqD,EAAA;EAQ5C;EAAsB,QAAA,CAAA,EAAA,OAAA;;;AAIvB,KAtFT,sBAAA,GAsFe,SAAA,GAAA,WAAA,GAAA,eAAA;;AA/Db,KAnBF,uBAAA,GAmBE,SAAA,GAAA,MAAA,GAAA,aAAA;AAohBd;AACE,UAriBe,kBAAA,CAqiBf;EACA;EACA,KAAA,EAriBO,sBAqiBP;EACA;EACA,KAAA,EAAA,MAAA;EACA;EACA,QAAA,EAAA,OAAA;EACA;EACA,QAAA,EAAA,OAAA;EACA;EACA,OAAA,EAAA,MAAA;EACA;EACA,MAAA,EAAA,CAAA,IAAA,CAAA,EAAA,OAAA,EAAA,GAAA,IAAA;;AAEA,UApiBe,eAAA,SACP,IAmiBR,CAniBa,OAAA,CAAM,cAmiBnB,CAAA,KAAA,CAAA,EAAA,UAAA,GAAA,cAAA,CAAA,CAAA;EACA;EACA,KAAA,EAniBO,cAmiBP,EAAA;EACA;EACA,KAAA,CAAA,EAAA,MAAA,EAAA;EACA;EACA,YAAA,CAAA,EAAA,MAAA,EAAA;EACA;EACA,aAAA,CAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,EAAA,GAAA,IAAA;EACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAngBgB;;;;;;;;;;4DAU0C,OAAA,CAAM;;;;;;;;sBAQ5C,sBAAsB,uBAAuB,OAAA,CAAM;;iBAExD,OAAA,CAAM;;qBAEF,OAAA,CAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqdX,UAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0Bb,kBAAe,oBAAA,CAAA,GAAA,CAAA"}
@@ -0,0 +1,421 @@
1
+ "use client";
2
+
3
+ import { t as cn } from "../utils-DUlptRpf.js";
4
+ import { t as Button } from "../button-DnHwqwy0.js";
5
+ import { t as Checkbox } from "../checkbox-CwkX29tL.js";
6
+ import { n as CollapsibleContent, r as CollapsibleTrigger, t as Collapsible } from "../collapsible-DsrYXIW5.js";
7
+ import "../input-jIoNIdLQ.js";
8
+ import "../textarea-hZg0gA8u.js";
9
+ import { i as InputGroupInput, n as InputGroupAddon, t as InputGroup } from "../input-group-B5PMRYld.js";
10
+ import { i as EmptyHeader, o as EmptyTitle, t as Empty } from "../empty-U4zrLmFU.js";
11
+ import { t as ScrollArea } from "../scroll-area-mNVMQ0Of.js";
12
+ import { ChevronRightIcon, SearchIcon } from "lucide-react";
13
+ import { jsx, jsxs } from "react/jsx-runtime";
14
+ import * as React$1 from "react";
15
+ import { cva } from "class-variance-authority";
16
+
17
+ //#region src/components/tree-select.tsx
18
+ /** Walk the tree honoring `maxDepth`, invoking `visit` with node + depth. */
19
+ function walk(nodes, maxDepth, visit, depth = 0) {
20
+ if (maxDepth !== void 0 && depth > maxDepth) return;
21
+ for (const node of nodes) {
22
+ visit(node, depth);
23
+ if (node.children?.length) walk(node.children, maxDepth, visit, depth + 1);
24
+ }
25
+ }
26
+ /** True when a node renders an expand/collapse affordance at the given depth. */
27
+ function isExpandable(node, depth, maxDepth) {
28
+ return Boolean(node.children?.length) && (maxDepth === void 0 || depth < maxDepth);
29
+ }
30
+ /**
31
+ * Returns the set of selectable (enabled) ids within the depth budget. In
32
+ * `"leaf"` mode only rendered-leaf rows are selectable; otherwise every enabled
33
+ * node is.
34
+ */
35
+ function collectSelectableIds(nodes, maxDepth, mode) {
36
+ const ids = /* @__PURE__ */ new Set();
37
+ walk(nodes, maxDepth, (node, depth) => {
38
+ if (node.disabled) return;
39
+ if (mode === "leaf" && isExpandable(node, depth, maxDepth)) return;
40
+ ids.add(node.id);
41
+ });
42
+ return ids;
43
+ }
44
+ /** Enabled rendered-leaf descendant ids of a node within the depth budget. */
45
+ function descendantLeafIds(node, depth, maxDepth) {
46
+ const out = [];
47
+ if (node.children?.length) walk(node.children, maxDepth, (n, d) => {
48
+ if (!n.disabled && !isExpandable(n, d, maxDepth)) out.push(n.id);
49
+ }, depth + 1);
50
+ return out;
51
+ }
52
+ /** Returns the ids of every expandable branch within the depth budget. */
53
+ function collectBranchIds(nodes, maxDepth) {
54
+ const ids = [];
55
+ walk(nodes, maxDepth, (node, depth) => {
56
+ if (isExpandable(node, depth, maxDepth)) ids.push(node.id);
57
+ });
58
+ return ids;
59
+ }
60
+ /** Enabled descendant ids of a node (excluding itself) within the depth budget. */
61
+ function descendantIds(node, depth, maxDepth) {
62
+ const out = [];
63
+ if (node.children?.length) walk(node.children, maxDepth, (n) => {
64
+ if (!n.disabled) out.push(n.id);
65
+ }, depth + 1);
66
+ return out;
67
+ }
68
+ function buildNodeIndex(nodes, maxDepth) {
69
+ const index = /* @__PURE__ */ new Map();
70
+ walk(nodes, maxDepth, (node, depth) => {
71
+ index.set(node.id, {
72
+ node,
73
+ depth
74
+ });
75
+ });
76
+ return index;
77
+ }
78
+ /**
79
+ * Compute the tri-state of every node in ONE bottom-up pass over the ORIGINAL
80
+ * (unfiltered) tree, keyed by id. Rows then look up their state in O(1), so a
81
+ * large tree no longer re-walks each branch's subtree on every render.
82
+ *
83
+ * Semantics depend on `mode`:
84
+ * - `"cascade"`: a branch is `checked` when every enabled descendant is
85
+ * selected (and the branch itself, when selectable, is selected),
86
+ * `unchecked` when none are, `indeterminate` otherwise. Disabled descendants
87
+ * are ignored, so a branch whose only unselected children are disabled still
88
+ * reads as checked.
89
+ * - `"leaf"`: a branch's state rolls up from its enabled leaf descendants only;
90
+ * the branch's own id is never considered selected.
91
+ * - `"independent"`: every node simply reflects its own selected state.
92
+ */
93
+ function buildCheckedStates(nodes, maxDepth, selected, mode) {
94
+ const states = /* @__PURE__ */ new Map();
95
+ const visit = (node, depth) => {
96
+ const selfIsLeaf = !isExpandable(node, depth, maxDepth);
97
+ let descEnabled = 0;
98
+ let descSelected = 0;
99
+ let descLeafEnabled = 0;
100
+ let descLeafSelected = 0;
101
+ if ((maxDepth === void 0 || depth < maxDepth) && node.children?.length) for (const child of node.children) {
102
+ const a = visit(child, depth + 1);
103
+ descEnabled += a.selfEnabled + a.descEnabled;
104
+ descSelected += a.selfSelected + a.descSelected;
105
+ descLeafEnabled += (a.selfIsLeaf ? a.selfEnabled : 0) + a.descLeafEnabled;
106
+ descLeafSelected += (a.selfIsLeaf ? a.selfSelected : 0) + a.descLeafSelected;
107
+ }
108
+ let state;
109
+ if (mode === "independent") state = selected.has(node.id) ? "checked" : "unchecked";
110
+ else if (mode === "leaf") if (selfIsLeaf) state = selected.has(node.id) ? "checked" : "unchecked";
111
+ else if (descLeafEnabled === 0 || descLeafSelected === 0) state = "unchecked";
112
+ else if (descLeafSelected === descLeafEnabled) state = "checked";
113
+ else state = "indeterminate";
114
+ else if (descEnabled === 0) state = selected.has(node.id) ? "checked" : "unchecked";
115
+ else {
116
+ const selfChecked = node.disabled ? true : selected.has(node.id);
117
+ if (descSelected === descEnabled && selfChecked) state = "checked";
118
+ else if (descSelected === 0 && !selected.has(node.id)) state = "unchecked";
119
+ else state = "indeterminate";
120
+ }
121
+ states.set(node.id, state);
122
+ return {
123
+ selfEnabled: node.disabled ? 0 : 1,
124
+ selfSelected: !node.disabled && selected.has(node.id) ? 1 : 0,
125
+ selfIsLeaf,
126
+ descEnabled,
127
+ descSelected,
128
+ descLeafEnabled,
129
+ descLeafSelected
130
+ };
131
+ };
132
+ for (const root of nodes) visit(root, 0);
133
+ return states;
134
+ }
135
+ function nodeSearchText(node) {
136
+ if (node.searchText) return node.searchText;
137
+ if (typeof node.label === "string") return node.label;
138
+ return "";
139
+ }
140
+ /**
141
+ * Filter the tree to nodes matching `query` plus their ancestors. A node is
142
+ * kept when it matches directly (in which case its original children are kept)
143
+ * or when any descendant matches.
144
+ */
145
+ function filterTree(nodes, query) {
146
+ if (!query.trim()) return nodes;
147
+ const q = query.trim().toLowerCase();
148
+ const recurse = (list) => {
149
+ const result = [];
150
+ for (const node of list) {
151
+ const selfMatch = nodeSearchText(node).toLowerCase().includes(q);
152
+ const keptChildren = node.children?.length ? recurse(node.children) : [];
153
+ if (selfMatch || keptChildren.length) result.push({
154
+ ...node,
155
+ children: keptChildren.length ? keptChildren : node.children
156
+ });
157
+ }
158
+ return result;
159
+ };
160
+ return recurse(nodes);
161
+ }
162
+ /** Shared row layout for both leaf and branch rows. */
163
+ const treeSelectRowVariants = cva("flex items-center gap-2 rounded-md py-1.5 pe-2 hover:bg-muted/50");
164
+ function TreeSelectRow({ node, depth, maxDepth, checkedStates, expanded, forceExpanded, disabled, onToggle, onExpandToggle, renderNode }) {
165
+ const labelId = React$1.useId();
166
+ const expandable = isExpandable(node, depth, maxDepth);
167
+ const state = checkedStates.get(node.id) ?? "unchecked";
168
+ const rowDisabled = disabled || Boolean(node.disabled);
169
+ const isOpen = expandable && (forceExpanded || expanded.has(node.id));
170
+ const accessibleName = nodeSearchText(node);
171
+ const meta = {
172
+ state,
173
+ depth,
174
+ expanded: isOpen,
175
+ disabled: rowDisabled,
176
+ labelId,
177
+ toggle: (next) => onToggle(node.id, next ?? state !== "checked")
178
+ };
179
+ const checkbox = /* @__PURE__ */ jsx(Checkbox, {
180
+ "data-slot": "tree-select-checkbox",
181
+ checked: state === "checked",
182
+ indeterminate: state === "indeterminate",
183
+ disabled: rowDisabled,
184
+ "aria-labelledby": labelId,
185
+ "aria-label": renderNode && accessibleName ? accessibleName : void 0,
186
+ onCheckedChange: (checked) => onToggle(node.id, checked)
187
+ });
188
+ const body = renderNode ? /* @__PURE__ */ jsx("div", {
189
+ className: "flex min-w-0 flex-1 items-center gap-2",
190
+ children: renderNode(node, meta)
191
+ }) : /* @__PURE__ */ jsx("span", {
192
+ id: labelId,
193
+ className: cn("min-w-0 flex-1 truncate text-sm", rowDisabled ? "opacity-50" : "cursor-pointer"),
194
+ onClick: rowDisabled ? void 0 : () => onToggle(node.id, state !== "checked"),
195
+ children: node.label
196
+ });
197
+ if (!expandable) return /* @__PURE__ */ jsxs("div", {
198
+ role: "treeitem",
199
+ "aria-selected": state === "checked",
200
+ "data-slot": "tree-select-item",
201
+ className: treeSelectRowVariants(),
202
+ style: { paddingInlineStart: `calc(${depth} * 1.5rem + 1.5rem)` },
203
+ children: [checkbox, body]
204
+ });
205
+ return /* @__PURE__ */ jsxs(Collapsible, {
206
+ open: isOpen,
207
+ onOpenChange: (open) => onExpandToggle(node.id, open),
208
+ "data-slot": "tree-select-branch",
209
+ render: /* @__PURE__ */ jsx("div", {
210
+ role: "treeitem",
211
+ "aria-selected": state === "checked",
212
+ "aria-expanded": isOpen
213
+ }),
214
+ children: [/* @__PURE__ */ jsxs("div", {
215
+ className: treeSelectRowVariants(),
216
+ style: { paddingInlineStart: `calc(${depth} * 1.5rem)` },
217
+ children: [
218
+ /* @__PURE__ */ jsx(CollapsibleTrigger, {
219
+ "data-slot": "tree-select-trigger",
220
+ disabled: forceExpanded,
221
+ "aria-label": "Toggle",
222
+ render: /* @__PURE__ */ jsx(Button, {
223
+ variant: "ghost",
224
+ size: "icon",
225
+ className: "group size-6 shrink-0 text-muted-foreground"
226
+ }),
227
+ children: /* @__PURE__ */ jsx(ChevronRightIcon, { className: "transition-transform duration-200 group-data-panel-open:rotate-90" })
228
+ }),
229
+ checkbox,
230
+ body
231
+ ]
232
+ }), /* @__PURE__ */ jsx(CollapsibleContent, {
233
+ role: "group",
234
+ children: node.children.map((child) => /* @__PURE__ */ jsx(TreeSelectRow, {
235
+ node: child,
236
+ depth: depth + 1,
237
+ maxDepth,
238
+ checkedStates,
239
+ expanded,
240
+ forceExpanded,
241
+ disabled,
242
+ onToggle,
243
+ onExpandToggle,
244
+ renderNode
245
+ }, child.id))
246
+ })]
247
+ });
248
+ }
249
+ /**
250
+ * A hierarchical, searchable tree multi-select with tri-state checkboxes.
251
+ *
252
+ * Selecting a parent selects all of its (enabled) descendants; clearing a
253
+ * parent clears them. A branch with a mix of selected and unselected
254
+ * descendants shows the indeterminate state. The selection is a flat array of
255
+ * node ids and works controlled (`value` + `onValueChange`) or uncontrolled
256
+ * (`defaultValue`). Expansion is likewise controllable (`expandedIds` +
257
+ * `onExpandedChange`) so consumers can implement expand-all / collapse-all.
258
+ *
259
+ * @example
260
+ * ```tsx
261
+ * const nodes = [
262
+ * {
263
+ * id: "fe",
264
+ * label: "Frontend",
265
+ * children: [
266
+ * { id: "react", label: "React" },
267
+ * { id: "vue", label: "Vue" },
268
+ * ],
269
+ * },
270
+ * { id: "be", label: "Backend", children: [{ id: "rails", label: "Rails" }] },
271
+ * ]
272
+ *
273
+ * function Example() {
274
+ * const [value, setValue] = React.useState<string[]>(["react"])
275
+ * return (
276
+ * <TreeSelect
277
+ * nodes={nodes}
278
+ * value={value}
279
+ * onValueChange={setValue}
280
+ * searchable
281
+ * maxDepth={1}
282
+ * />
283
+ * )
284
+ * }
285
+ * ```
286
+ */
287
+ function TreeSelect({ nodes, value, defaultValue = [], onValueChange, searchable = false, searchPlaceholder = "Search…", search, defaultSearch = "", onSearchChange, maxDepth, selectionMode = "cascade", showSummary = true, renderSummary, renderNode, emptyMessage = "No items.", noResultsMessage = "No results found.", disabled = false, defaultExpanded = false, expandedIds, defaultExpandedIds, onExpandedChange, scrollHeight = "16rem", scrollClassName, className, ...props }) {
288
+ const isControlled = value !== void 0;
289
+ const [internalValue, setInternalValue] = React$1.useState(defaultValue);
290
+ const currentValue = isControlled ? value : internalValue;
291
+ const selected = React$1.useMemo(() => new Set(currentValue), [currentValue]);
292
+ const setValue = React$1.useCallback((next) => {
293
+ if (!isControlled) setInternalValue(next);
294
+ onValueChange?.(next);
295
+ }, [isControlled, onValueChange]);
296
+ const searchControlled = search !== void 0;
297
+ const [internalSearch, setInternalSearch] = React$1.useState(defaultSearch);
298
+ const currentSearch = searchControlled ? search : internalSearch;
299
+ const setSearch = React$1.useCallback((next) => {
300
+ if (!searchControlled) setInternalSearch(next);
301
+ onSearchChange?.(next);
302
+ }, [searchControlled, onSearchChange]);
303
+ const expansionControlled = expandedIds !== void 0;
304
+ const [internalExpanded, setInternalExpanded] = React$1.useState(() => {
305
+ if (defaultExpandedIds) return defaultExpandedIds;
306
+ if (defaultExpanded) return collectBranchIds(nodes, maxDepth);
307
+ return [];
308
+ });
309
+ const currentExpanded = expansionControlled ? expandedIds : internalExpanded;
310
+ const expanded = React$1.useMemo(() => new Set(currentExpanded), [currentExpanded]);
311
+ const setExpanded = React$1.useCallback((next) => {
312
+ if (!expansionControlled) setInternalExpanded(next);
313
+ onExpandedChange?.(next);
314
+ }, [expansionControlled, onExpandedChange]);
315
+ const handleExpandToggle = React$1.useCallback((id, open) => {
316
+ const next = new Set(expanded);
317
+ if (open) next.add(id);
318
+ else next.delete(id);
319
+ setExpanded(Array.from(next));
320
+ }, [expanded, setExpanded]);
321
+ const selectableIds = React$1.useMemo(() => collectSelectableIds(nodes, maxDepth, selectionMode), [
322
+ nodes,
323
+ maxDepth,
324
+ selectionMode
325
+ ]);
326
+ const nodeIndex = React$1.useMemo(() => buildNodeIndex(nodes, maxDepth), [nodes, maxDepth]);
327
+ const checkedStates = React$1.useMemo(() => buildCheckedStates(nodes, maxDepth, selected, selectionMode), [
328
+ nodes,
329
+ maxDepth,
330
+ selected,
331
+ selectionMode
332
+ ]);
333
+ const selectedCount = React$1.useMemo(() => currentValue.filter((id) => selectableIds.has(id)).length, [currentValue, selectableIds]);
334
+ const filteredNodes = React$1.useMemo(() => searchable ? filterTree(nodes, currentSearch) : nodes, [
335
+ searchable,
336
+ nodes,
337
+ currentSearch
338
+ ]);
339
+ const hasQuery = searchable && currentSearch.trim().length > 0;
340
+ const handleToggle = React$1.useCallback((id, next) => {
341
+ const ids = new Set(selected);
342
+ const entry = nodeIndex.get(id);
343
+ let affected;
344
+ if (!entry || selectionMode === "independent") affected = [id];
345
+ else if (selectionMode === "leaf") affected = isExpandable(entry.node, entry.depth, maxDepth) ? descendantLeafIds(entry.node, entry.depth, maxDepth) : [entry.node.id];
346
+ else affected = [entry.node.id, ...descendantIds(entry.node, entry.depth, maxDepth)];
347
+ for (const target of affected) {
348
+ if (!selectableIds.has(target)) continue;
349
+ if (next) ids.add(target);
350
+ else ids.delete(target);
351
+ }
352
+ setValue(Array.from(ids));
353
+ }, [
354
+ selected,
355
+ maxDepth,
356
+ selectableIds,
357
+ nodeIndex,
358
+ setValue,
359
+ selectionMode
360
+ ]);
361
+ const summaryNode = showSummary ? renderSummary ? renderSummary(selectedCount, selectableIds.size) : `${selectedCount} of ${selectableIds.size} selected` : null;
362
+ const isEmpty = filteredNodes.length === 0;
363
+ const emptyText = hasQuery ? noResultsMessage : emptyMessage;
364
+ return /* @__PURE__ */ jsxs("div", {
365
+ "data-slot": "tree-select",
366
+ "data-disabled": disabled || void 0,
367
+ className: cn("flex flex-col gap-2", disabled && "pointer-events-none opacity-60", className),
368
+ ...props,
369
+ children: [
370
+ searchable && /* @__PURE__ */ jsxs(InputGroup, {
371
+ "data-slot": "tree-select-search",
372
+ children: [/* @__PURE__ */ jsx(InputGroupAddon, { children: /* @__PURE__ */ jsx(SearchIcon, { "data-icon": "inline-start" }) }), /* @__PURE__ */ jsx(InputGroupInput, {
373
+ type: "search",
374
+ value: currentSearch,
375
+ disabled,
376
+ placeholder: searchPlaceholder,
377
+ "aria-label": searchPlaceholder,
378
+ onChange: (event) => setSearch(event.target.value)
379
+ })]
380
+ }),
381
+ summaryNode != null && /* @__PURE__ */ jsx("div", {
382
+ "data-slot": "tree-select-summary",
383
+ className: "text-xs text-muted-foreground",
384
+ children: summaryNode
385
+ }),
386
+ /* @__PURE__ */ jsx(ScrollArea, {
387
+ "data-slot": "tree-select-scroll",
388
+ className: cn("rounded-md border border-input", scrollClassName),
389
+ viewportProps: { style: { maxHeight: scrollHeight } },
390
+ children: /* @__PURE__ */ jsx("div", {
391
+ role: "tree",
392
+ "aria-multiselectable": true,
393
+ className: "p-1",
394
+ children: isEmpty ? /* @__PURE__ */ jsx(Empty, {
395
+ "data-slot": "tree-select-empty",
396
+ className: "border-0 p-6",
397
+ children: /* @__PURE__ */ jsx(EmptyHeader, { children: /* @__PURE__ */ jsx(EmptyTitle, {
398
+ className: "text-sm font-normal text-muted-foreground",
399
+ children: emptyText
400
+ }) })
401
+ }) : filteredNodes.map((node) => /* @__PURE__ */ jsx(TreeSelectRow, {
402
+ node,
403
+ depth: 0,
404
+ maxDepth,
405
+ checkedStates,
406
+ expanded,
407
+ forceExpanded: hasQuery,
408
+ disabled,
409
+ onToggle: handleToggle,
410
+ onExpandToggle: handleExpandToggle,
411
+ renderNode
412
+ }, node.id))
413
+ })
414
+ })
415
+ ]
416
+ });
417
+ }
418
+
419
+ //#endregion
420
+ export { TreeSelect };
421
+ //# sourceMappingURL=tree-select.js.map