@cube-dev/ui-kit 0.131.0 → 0.133.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 (442) hide show
  1. package/dist/CHANGELOG.md +32 -0
  2. package/dist/_internal/hooks/use-chained-callback.js +1 -1
  3. package/dist/_internal/hooks/use-debounced-value.js +1 -1
  4. package/dist/_internal/hooks/use-deprecation-warning.js +1 -1
  5. package/dist/_internal/hooks/use-event.js +1 -1
  6. package/dist/_internal/hooks/use-is-first-render.js +1 -1
  7. package/dist/_internal/hooks/use-sync-ref.js +1 -1
  8. package/dist/_internal/hooks/use-timer/timer.js +1 -1
  9. package/dist/_internal/hooks/use-timer/use-timer.js +1 -1
  10. package/dist/_internal/hooks/use-warn.js +1 -1
  11. package/dist/components/Block.js +1 -1
  12. package/dist/components/CollectionItem.js +1 -1
  13. package/dist/components/GlobalStyles.js +1 -1
  14. package/dist/components/GridProvider.js +1 -1
  15. package/dist/components/HiddenInput.js +1 -1
  16. package/dist/components/Root.js +1 -1
  17. package/dist/components/actions/Action/Action.js +1 -1
  18. package/dist/components/actions/Banner/Banner.js +1 -1
  19. package/dist/components/actions/Button/Button.js +1 -1
  20. package/dist/components/actions/ButtonGroup/ButtonGroup.js +1 -1
  21. package/dist/components/actions/ButtonSplit/ButtonSplit.js +1 -1
  22. package/dist/components/actions/ButtonSplit/context.js +1 -1
  23. package/dist/components/actions/CommandMenu/CommandMenu.js +1 -1
  24. package/dist/components/actions/CommandMenu/styled.js +1 -1
  25. package/dist/components/actions/ItemAction/ItemAction.js +1 -1
  26. package/dist/components/actions/ItemActionContext.js +1 -1
  27. package/dist/components/actions/ItemButton/ItemButton.js +1 -1
  28. package/dist/components/actions/Link/Link.js +1 -1
  29. package/dist/components/actions/Menu/Menu.js +1 -1
  30. package/dist/components/actions/Menu/MenuItem.js +1 -1
  31. package/dist/components/actions/Menu/MenuSection.js +1 -1
  32. package/dist/components/actions/Menu/MenuTrigger.js +1 -1
  33. package/dist/components/actions/Menu/SubMenuTrigger.js +1 -1
  34. package/dist/components/actions/Menu/SubmenuTriggerContext.js +1 -1
  35. package/dist/components/actions/Menu/context.js +1 -1
  36. package/dist/components/actions/Menu/styled.js +1 -1
  37. package/dist/components/actions/index.js +1 -1
  38. package/dist/components/actions/use-action.js +1 -1
  39. package/dist/components/actions/use-anchored-menu.js +1 -1
  40. package/dist/components/actions/use-context-menu.js +1 -1
  41. package/dist/components/content/ActiveZone/ActiveZone.js +1 -1
  42. package/dist/components/content/Alert/Alert.js +1 -1
  43. package/dist/components/content/Alert/use-alert.js +1 -1
  44. package/dist/components/content/Avatar/Avatar.js +1 -1
  45. package/dist/components/content/Badge/Badge.js +1 -1
  46. package/dist/components/content/Card/Card.js +1 -1
  47. package/dist/components/content/Content.js +1 -1
  48. package/dist/components/content/CopyPasteBlock/CopyPasteBlock.js +1 -1
  49. package/dist/components/content/CopySnippet/CopySnippet.js +1 -1
  50. package/dist/components/content/Disclosure/Disclosure.js +1 -1
  51. package/dist/components/content/Divider.js +1 -1
  52. package/dist/components/content/Footer.js +1 -1
  53. package/dist/components/content/Header.js +1 -1
  54. package/dist/components/content/HotKeys/HotKeys.js +1 -1
  55. package/dist/components/content/Item/Item.js +1 -1
  56. package/dist/components/content/ItemBadge/ItemBadge.js +1 -1
  57. package/dist/components/content/ItemCard/ItemCard.js +1 -1
  58. package/dist/components/content/Layout/GridLayout.js +1 -1
  59. package/dist/components/content/Layout/Layout.js +1 -1
  60. package/dist/components/content/Layout/LayoutBlock.js +1 -1
  61. package/dist/components/content/Layout/LayoutCenter.js +1 -1
  62. package/dist/components/content/Layout/LayoutContainer.js +1 -1
  63. package/dist/components/content/Layout/LayoutContent.js +1 -1
  64. package/dist/components/content/Layout/LayoutContext.js +1 -1
  65. package/dist/components/content/Layout/LayoutFlex.js +1 -1
  66. package/dist/components/content/Layout/LayoutFooter.js +1 -1
  67. package/dist/components/content/Layout/LayoutGrid.js +1 -1
  68. package/dist/components/content/Layout/LayoutHeader.js +1 -1
  69. package/dist/components/content/Layout/LayoutPane.js +1 -1
  70. package/dist/components/content/Layout/LayoutPanel.js +1 -1
  71. package/dist/components/content/Layout/LayoutPanelHeader.js +1 -1
  72. package/dist/components/content/Layout/LayoutToolbar.js +1 -1
  73. package/dist/components/content/Layout/hooks/useTinyScrollbar.js +1 -1
  74. package/dist/components/content/Layout/index.js +1 -1
  75. package/dist/components/content/Layout/utils.js +1 -1
  76. package/dist/components/content/Paragraph.js +1 -1
  77. package/dist/components/content/Placeholder/Placeholder.js +1 -1
  78. package/dist/components/content/PrismCode/PrismCode.js +1 -1
  79. package/dist/components/content/PrismCode/prismSetup.js +1 -1
  80. package/dist/components/content/PrismDiffCode/PrismDiffCode.js +1 -1
  81. package/dist/components/content/Result/Result.js +1 -1
  82. package/dist/components/content/Skeleton/Skeleton.js +1 -1
  83. package/dist/components/content/Tag/Tag.js +1 -1
  84. package/dist/components/content/Text.js +1 -1
  85. package/dist/components/content/TextItem/TextItem.js +1 -1
  86. package/dist/components/content/Title.js +1 -1
  87. package/dist/components/content/Tree/Tree.js +60 -45
  88. package/dist/components/content/Tree/Tree.js.map +1 -1
  89. package/dist/components/content/Tree/TreeNode.js +90 -20
  90. package/dist/components/content/Tree/TreeNode.js.map +1 -1
  91. package/dist/components/content/Tree/index.d.ts +1 -1
  92. package/dist/components/content/Tree/styled.js +26 -4
  93. package/dist/components/content/Tree/styled.js.map +1 -1
  94. package/dist/components/content/Tree/tree-index.js +1 -1
  95. package/dist/components/content/Tree/types.d.ts +67 -1
  96. package/dist/components/content/Tree/use-checkbox-tree.js +1 -1
  97. package/dist/components/content/Tree/use-load-data.js +1 -1
  98. package/dist/components/content/highlightText.js +1 -1
  99. package/dist/components/content/use-auto-tooltip.js +1 -1
  100. package/dist/components/fields/Checkbox/Checkbox.js +1 -1
  101. package/dist/components/fields/Checkbox/CheckboxGroup.js +1 -1
  102. package/dist/components/fields/Checkbox/context.js +1 -1
  103. package/dist/components/fields/ComboBox/ComboBox.js +1 -1
  104. package/dist/components/fields/DatePicker/DateInput.js +1 -1
  105. package/dist/components/fields/DatePicker/DateInputBase.js +1 -1
  106. package/dist/components/fields/DatePicker/DatePicker.js +1 -1
  107. package/dist/components/fields/DatePicker/DatePickerButton.js +1 -1
  108. package/dist/components/fields/DatePicker/DatePickerElement.js +1 -1
  109. package/dist/components/fields/DatePicker/DatePickerInput.js +1 -1
  110. package/dist/components/fields/DatePicker/DatePickerSegment.js +1 -1
  111. package/dist/components/fields/DatePicker/DateRangePicker.js +1 -1
  112. package/dist/components/fields/DatePicker/DateRangeSeparatedPicker.js +1 -1
  113. package/dist/components/fields/DatePicker/TimeInput.js +1 -1
  114. package/dist/components/fields/DatePicker/intl.js +1 -1
  115. package/dist/components/fields/DatePicker/parseDate.js +1 -1
  116. package/dist/components/fields/DatePicker/props.js +1 -1
  117. package/dist/components/fields/DatePicker/utils.js +1 -1
  118. package/dist/components/fields/FileInput/FileInput.js +1 -1
  119. package/dist/components/fields/FilterListBox/FilterListBox.js +5 -3
  120. package/dist/components/fields/FilterListBox/FilterListBox.js.map +1 -1
  121. package/dist/components/fields/FilterPicker/FilterPicker.js +4 -2
  122. package/dist/components/fields/FilterPicker/FilterPicker.js.map +1 -1
  123. package/dist/components/fields/Input/Input.js +1 -1
  124. package/dist/components/fields/ListBox/DraggableListBox.js +24 -0
  125. package/dist/components/fields/ListBox/DraggableListBox.js.map +1 -0
  126. package/dist/components/fields/ListBox/ListBox.d.ts +11 -0
  127. package/dist/components/fields/ListBox/ListBox.js +153 -38
  128. package/dist/components/fields/ListBox/ListBox.js.map +1 -1
  129. package/dist/components/fields/NumberInput/NumberInput.js +1 -1
  130. package/dist/components/fields/NumberInput/StepButton.js +1 -1
  131. package/dist/components/fields/PasswordInput/PasswordInput.js +1 -1
  132. package/dist/components/fields/Picker/Picker.js +1 -1
  133. package/dist/components/fields/RadioGroup/Radio.js +1 -1
  134. package/dist/components/fields/RadioGroup/RadioGroup.js +1 -1
  135. package/dist/components/fields/RadioGroup/context.js +1 -1
  136. package/dist/components/fields/SearchInput/SearchInput.js +1 -1
  137. package/dist/components/fields/Select/Select.js +1 -1
  138. package/dist/components/fields/Slider/Gradation.js +1 -1
  139. package/dist/components/fields/Slider/HueSlider.js +1 -1
  140. package/dist/components/fields/Slider/RangeSlider.js +1 -1
  141. package/dist/components/fields/Slider/Slider.js +1 -1
  142. package/dist/components/fields/Slider/SliderBase.js +1 -1
  143. package/dist/components/fields/Slider/SliderThumb.js +1 -1
  144. package/dist/components/fields/Slider/SliderTrack.js +1 -1
  145. package/dist/components/fields/Slider/elements.js +1 -1
  146. package/dist/components/fields/Slider/index.js +1 -1
  147. package/dist/components/fields/Switch/Switch.js +1 -1
  148. package/dist/components/fields/TextArea/TextArea.js +1 -1
  149. package/dist/components/fields/TextInput/TextInput.js +1 -1
  150. package/dist/components/fields/TextInput/TextInputBase.js +1 -1
  151. package/dist/components/fields/TextInputMapper/TextInputMapper.js +1 -1
  152. package/dist/components/form/FieldWrapper/FieldWrapper.js +1 -1
  153. package/dist/components/form/FieldWrapper/extract-field-wrapper-props.js +1 -1
  154. package/dist/components/form/Form/Field.js +1 -1
  155. package/dist/components/form/Form/Form.js +1 -1
  156. package/dist/components/form/Form/ResetButton/ResetButton.js +1 -1
  157. package/dist/components/form/Form/SubmitButton/SubmitButton.js +1 -1
  158. package/dist/components/form/Form/SubmitError.js +1 -1
  159. package/dist/components/form/Form/index.js +1 -1
  160. package/dist/components/form/Form/use-field/use-field-props.js +1 -1
  161. package/dist/components/form/Form/use-field/use-field.js +1 -1
  162. package/dist/components/form/Form/use-form.js +1 -1
  163. package/dist/components/form/Form/validation.js +1 -1
  164. package/dist/components/form/Label.js +1 -1
  165. package/dist/components/form/wrapper.js +1 -1
  166. package/dist/components/helpers/DisplayTransition/DisplayTransition.js +1 -1
  167. package/dist/components/helpers/IconSwitch/IconSwitch.js +1 -1
  168. package/dist/components/layout/Flex.js +1 -1
  169. package/dist/components/layout/Flow.js +1 -1
  170. package/dist/components/layout/Grid.js +1 -1
  171. package/dist/components/layout/Panel.js +1 -1
  172. package/dist/components/layout/Prefix.js +1 -1
  173. package/dist/components/layout/ResizablePanel.js +1 -1
  174. package/dist/components/layout/Space.js +1 -1
  175. package/dist/components/layout/Suffix.js +1 -1
  176. package/dist/components/navigation/Tabs/DraggableTabList.js +11 -60
  177. package/dist/components/navigation/Tabs/DraggableTabList.js.map +1 -1
  178. package/dist/components/navigation/Tabs/EditableTitle.js +1 -1
  179. package/dist/components/navigation/Tabs/TabButton.js +3 -10
  180. package/dist/components/navigation/Tabs/TabButton.js.map +1 -1
  181. package/dist/components/navigation/Tabs/TabDropIndicator.js +1 -1
  182. package/dist/components/navigation/Tabs/TabPanel.js +1 -1
  183. package/dist/components/navigation/Tabs/TabPicker.js +4 -2
  184. package/dist/components/navigation/Tabs/TabPicker.js.map +1 -1
  185. package/dist/components/navigation/Tabs/Tabs.js +4 -2
  186. package/dist/components/navigation/Tabs/Tabs.js.map +1 -1
  187. package/dist/components/navigation/Tabs/TabsAction.js +1 -1
  188. package/dist/components/navigation/Tabs/TabsContext.js +1 -1
  189. package/dist/components/navigation/Tabs/styled.js +1 -1
  190. package/dist/components/navigation/Tabs/types.d.ts +2 -0
  191. package/dist/components/navigation/Tabs/types.js +1 -1
  192. package/dist/components/navigation/Tabs/types.js.map +1 -1
  193. package/dist/components/navigation/Tabs/use-tab-editing.js +1 -1
  194. package/dist/components/navigation/Tabs/use-tab-indicator.js +1 -1
  195. package/dist/components/organisms/FileTabs/FileTabs.js +1 -1
  196. package/dist/components/organisms/StatsCard/StatsCard.js +1 -1
  197. package/dist/components/other/Calendar/Calendar.js +1 -1
  198. package/dist/components/other/Calendar/CalendarCell.js +1 -1
  199. package/dist/components/other/Calendar/CalendarGrid.js +1 -1
  200. package/dist/components/other/Calendar/RangeCalendar.js +1 -1
  201. package/dist/components/other/CloudLogo/CloudLogo.js +1 -1
  202. package/dist/components/overlays/AlertDialog/AlertDialog.js +1 -1
  203. package/dist/components/overlays/AlertDialog/AlertDialogApiProvider.js +1 -1
  204. package/dist/components/overlays/AlertDialog/AlertDialogZone.js +1 -1
  205. package/dist/components/overlays/Dialog/Dialog.js +1 -1
  206. package/dist/components/overlays/Dialog/DialogContainer.js +1 -1
  207. package/dist/components/overlays/Dialog/DialogForm.js +1 -1
  208. package/dist/components/overlays/Dialog/DialogTrigger.js +1 -1
  209. package/dist/components/overlays/Dialog/context.js +1 -1
  210. package/dist/components/overlays/Dialog/use-dialog-container.js +1 -1
  211. package/dist/components/overlays/Modal/Modal.js +1 -1
  212. package/dist/components/overlays/Modal/OpenTransitionContext.js +1 -1
  213. package/dist/components/overlays/Modal/Overlay.js +1 -1
  214. package/dist/components/overlays/Modal/Popover.js +1 -1
  215. package/dist/components/overlays/Modal/Tray.js +1 -1
  216. package/dist/components/overlays/Modal/Underlay.js +1 -1
  217. package/dist/components/overlays/Notifications/Notification.js +1 -1
  218. package/dist/components/overlays/Notifications/NotificationAction.js +1 -1
  219. package/dist/components/overlays/Notifications/NotificationCard.js +1 -1
  220. package/dist/components/overlays/Notifications/NotificationContext.js +1 -1
  221. package/dist/components/overlays/Notifications/NotificationItem.js +1 -1
  222. package/dist/components/overlays/Notifications/OverlayContainer.js +1 -1
  223. package/dist/components/overlays/Notifications/OverlayProvider.js +1 -1
  224. package/dist/components/overlays/Notifications/PersistentNotificationsList.js +1 -1
  225. package/dist/components/overlays/Notifications/dismissed-storage.js +1 -1
  226. package/dist/components/overlays/Notifications/format-relative-time.js +1 -1
  227. package/dist/components/overlays/Notifications/index.js +1 -1
  228. package/dist/components/overlays/Notifications/use-notification-state.js +1 -1
  229. package/dist/components/overlays/Notifications/use-notifications.js +1 -1
  230. package/dist/components/overlays/Notifications/use-overlay-timers.js +1 -1
  231. package/dist/components/overlays/Notifications/use-persistent-notifications.js +1 -1
  232. package/dist/components/overlays/Notifications/use-persistent-state.js +1 -1
  233. package/dist/components/overlays/Notifications/use-toast-state.js +1 -1
  234. package/dist/components/overlays/Toast/ToastItem.js +1 -1
  235. package/dist/components/overlays/Toast/index.js +1 -1
  236. package/dist/components/overlays/Toast/useProgressToast.js +1 -1
  237. package/dist/components/overlays/Toast/useToast.js +1 -1
  238. package/dist/components/overlays/Tooltip/Tooltip.js +1 -1
  239. package/dist/components/overlays/Tooltip/TooltipProvider.js +1 -1
  240. package/dist/components/overlays/Tooltip/TooltipTrigger.js +1 -1
  241. package/dist/components/overlays/Tooltip/context.js +1 -1
  242. package/dist/components/portal/Portal.js +1 -1
  243. package/dist/components/portal/PortalProvider.js +1 -1
  244. package/dist/components/portal/usePortal.js +1 -1
  245. package/dist/components/shared/DraggableCollection.js +142 -0
  246. package/dist/components/shared/DraggableCollection.js.map +1 -0
  247. package/dist/components/shared/InvalidIcon.js +1 -1
  248. package/dist/components/shared/ValidIcon.js +1 -1
  249. package/dist/components/status/LoadingAnimation/LoadingAnimation.js +1 -1
  250. package/dist/components/status/Spin/Cube.js +1 -1
  251. package/dist/components/status/Spin/InternalSpinner.js +1 -1
  252. package/dist/components/status/Spin/Spin.js +1 -1
  253. package/dist/components/status/Spin/SpinsContainer.js +1 -1
  254. package/dist/data/item-themes.js +1 -1
  255. package/dist/data/themes.js +1 -1
  256. package/dist/icons/AdjustmentsHorizontalIcon.js +1 -1
  257. package/dist/icons/AdjustmentsIcon.js +1 -1
  258. package/dist/icons/AiIcon.js +1 -1
  259. package/dist/icons/AreaChartIcon.js +1 -1
  260. package/dist/icons/BackwardIcon.js +1 -1
  261. package/dist/icons/BarChartIcon.js +1 -1
  262. package/dist/icons/BellFilledIcon.js +1 -1
  263. package/dist/icons/BellIcon.js +1 -1
  264. package/dist/icons/BooleanIcon.js +1 -1
  265. package/dist/icons/CalendarEditIcon.js +1 -1
  266. package/dist/icons/CalendarIcon.js +1 -1
  267. package/dist/icons/CaretDownIcon.js +1 -1
  268. package/dist/icons/CaretUpIcon.js +1 -1
  269. package/dist/icons/ChartAreaStackedIcon.js +1 -1
  270. package/dist/icons/ChartAreaStackedPercentageIcon.js +1 -1
  271. package/dist/icons/ChartBarGroupedHorizontalIcon.js +1 -1
  272. package/dist/icons/ChartBarGroupedIcon.js +1 -1
  273. package/dist/icons/ChartBarHorizontalIcon.js +1 -1
  274. package/dist/icons/ChartBarLineIcon.js +1 -1
  275. package/dist/icons/ChartBarStackedHorizontalIcon.js +1 -1
  276. package/dist/icons/ChartBarStackedIcon.js +1 -1
  277. package/dist/icons/ChartBarStackedPercentageHorizontalIcon.js +1 -1
  278. package/dist/icons/ChartBarStackedPercentageIcon.js +1 -1
  279. package/dist/icons/ChartBoxPlot2Icon.js +1 -1
  280. package/dist/icons/ChartBoxPlotIcon.js +1 -1
  281. package/dist/icons/ChartBubbleIcon.js +1 -1
  282. package/dist/icons/ChartDonut2Icon.js +1 -1
  283. package/dist/icons/ChartFunnelIcon.js +1 -1
  284. package/dist/icons/ChartHeatmapIcon.js +1 -1
  285. package/dist/icons/ChartKPIIcon.js +1 -1
  286. package/dist/icons/ChartPie2Icon.js +1 -1
  287. package/dist/icons/ChartScatterIcon.js +1 -1
  288. package/dist/icons/CheckCircleFilledIcon.js +1 -1
  289. package/dist/icons/CheckCircleIcon.js +1 -1
  290. package/dist/icons/CheckIcon.js +1 -1
  291. package/dist/icons/CircleFilledIcon.js +1 -1
  292. package/dist/icons/ClearIcon.js +1 -1
  293. package/dist/icons/CloseCircleFilledIcon.js +1 -1
  294. package/dist/icons/CloseCircleIcon.js +1 -1
  295. package/dist/icons/CloseIcon.js +1 -1
  296. package/dist/icons/CodeIcon.js +1 -1
  297. package/dist/icons/ColumnTotalIcon.js +1 -1
  298. package/dist/icons/CopyIcon.js +1 -1
  299. package/dist/icons/CountIcon.js +1 -1
  300. package/dist/icons/CubeIcon.js +1 -1
  301. package/dist/icons/CubePauseIcon.js +1 -1
  302. package/dist/icons/CubePlayIcon.js +1 -1
  303. package/dist/icons/CurrencyDollarIcon.js +1 -1
  304. package/dist/icons/DangerIcon.js +1 -1
  305. package/dist/icons/DashboardIcon.js +1 -1
  306. package/dist/icons/DatabaseIcon.js +1 -1
  307. package/dist/icons/DecimalDecreaseIcon.js +1 -1
  308. package/dist/icons/DecimalIncreaseIcon.js +1 -1
  309. package/dist/icons/DirectionIcon.js +1 -1
  310. package/dist/icons/DonutIcon.js +1 -1
  311. package/dist/icons/DownIcon.js +1 -1
  312. package/dist/icons/EditIcon.js +1 -1
  313. package/dist/icons/ExclamationCircleFilledIcon.js +1 -1
  314. package/dist/icons/ExclamationCircleIcon.js +1 -1
  315. package/dist/icons/ExclamationIcon.js +1 -1
  316. package/dist/icons/EyeIcon.js +1 -1
  317. package/dist/icons/EyeInvisibleIcon.js +1 -1
  318. package/dist/icons/FilterIcon.js +1 -1
  319. package/dist/icons/FolderFilledIcon.js +1 -1
  320. package/dist/icons/FolderIcon.js +1 -1
  321. package/dist/icons/FolderOpenFilledIcon.js +1 -1
  322. package/dist/icons/FolderOpenIcon.js +1 -1
  323. package/dist/icons/ForwardIcon.js +1 -1
  324. package/dist/icons/GripVerticalIcon.d.ts +12 -0
  325. package/dist/icons/GripVerticalIcon.js +11 -0
  326. package/dist/icons/GripVerticalIcon.js.map +1 -0
  327. package/dist/icons/HierarchyIcon.js +1 -1
  328. package/dist/icons/HierarchyOpenIcon.js +1 -1
  329. package/dist/icons/Icon.js +1 -1
  330. package/dist/icons/InfoCircleIcon.js +1 -1
  331. package/dist/icons/InfoIcon.js +1 -1
  332. package/dist/icons/KeyIcon.js +1 -1
  333. package/dist/icons/LeftIcon.js +1 -1
  334. package/dist/icons/LineChartIcon.js +1 -1
  335. package/dist/icons/LoadingIcon.js +1 -1
  336. package/dist/icons/LockFilledIcon.js +1 -1
  337. package/dist/icons/LockIcon.js +1 -1
  338. package/dist/icons/MoreIcon.js +1 -1
  339. package/dist/icons/NotAllowedIcon.js +1 -1
  340. package/dist/icons/Number123Icon.js +1 -1
  341. package/dist/icons/NumberIcon.js +1 -1
  342. package/dist/icons/PauseCircleFilledIcon.js +1 -1
  343. package/dist/icons/PauseCircleIcon.js +1 -1
  344. package/dist/icons/PauseIcon.js +1 -1
  345. package/dist/icons/PercentageIcon.js +1 -1
  346. package/dist/icons/PieChartIcon.js +1 -1
  347. package/dist/icons/PlayCircleIcon.js +1 -1
  348. package/dist/icons/PlayIcon.js +1 -1
  349. package/dist/icons/PlusIcon.js +1 -1
  350. package/dist/icons/ProgressBarIcon.js +1 -1
  351. package/dist/icons/ReloadIcon.js +1 -1
  352. package/dist/icons/ReportIcon.js +1 -1
  353. package/dist/icons/ReturnIcon.js +1 -1
  354. package/dist/icons/RightIcon.js +1 -1
  355. package/dist/icons/RowTotalsIcon.js +1 -1
  356. package/dist/icons/SchemeIcon.js +1 -1
  357. package/dist/icons/SearchIcon.js +1 -1
  358. package/dist/icons/SemanticQueryIcon.js +1 -1
  359. package/dist/icons/SettingsIcon.js +1 -1
  360. package/dist/icons/ShieldFilledIcon.js +1 -1
  361. package/dist/icons/ShieldIcon.js +1 -1
  362. package/dist/icons/SlashIcon.js +1 -1
  363. package/dist/icons/SparklesIcon.js +1 -1
  364. package/dist/icons/SqlIcon.js +1 -1
  365. package/dist/icons/StatsIcon.js +1 -1
  366. package/dist/icons/StopIcon.js +1 -1
  367. package/dist/icons/StringIcon.js +1 -1
  368. package/dist/icons/SubtotalsIcon.js +1 -1
  369. package/dist/icons/SwitchIcon.js +1 -1
  370. package/dist/icons/TableIcon.js +1 -1
  371. package/dist/icons/ThumbsDownIcon.js +1 -1
  372. package/dist/icons/ThumbsUpIcon.js +1 -1
  373. package/dist/icons/ThunderboltCrossedIcon.js +1 -1
  374. package/dist/icons/ThunderboltFilledIcon.js +1 -1
  375. package/dist/icons/ThunderboltIcon.js +1 -1
  376. package/dist/icons/TimeIcon.js +1 -1
  377. package/dist/icons/TrashIcon.js +1 -1
  378. package/dist/icons/UnlockIcon.js +1 -1
  379. package/dist/icons/UpIcon.js +1 -1
  380. package/dist/icons/UserGroupIcon.js +1 -1
  381. package/dist/icons/UserIcon.js +1 -1
  382. package/dist/icons/UserLockIcon.js +1 -1
  383. package/dist/icons/ViewIcon.js +1 -1
  384. package/dist/icons/WarningFilledIcon.js +1 -1
  385. package/dist/icons/WarningIcon.js +1 -1
  386. package/dist/icons/index.d.ts +1 -0
  387. package/dist/icons/wrap-icon.js +1 -1
  388. package/dist/index.d.ts +3 -2
  389. package/dist/index.js +3 -2
  390. package/dist/index.js.map +1 -1
  391. package/dist/provider.js +1 -1
  392. package/dist/providers/TrackingProvider.js +1 -1
  393. package/dist/providers/navigationAdapter.default.js +1 -1
  394. package/dist/tokens/base.js +1 -1
  395. package/dist/tokens/colors.js +1 -1
  396. package/dist/tokens/index.js +1 -1
  397. package/dist/tokens/layout.js +1 -1
  398. package/dist/tokens/shadows.js +1 -1
  399. package/dist/tokens/sizes.js +1 -1
  400. package/dist/tokens/spacing.js +1 -1
  401. package/dist/tokens/typography.js +1 -1
  402. package/dist/utils/ResizeSensor.js +1 -1
  403. package/dist/utils/is-dev-env.js +1 -1
  404. package/dist/utils/modules.js +1 -1
  405. package/dist/utils/promise.js +1 -1
  406. package/dist/utils/raf.js +1 -1
  407. package/dist/utils/random.js +1 -1
  408. package/dist/utils/range.js +1 -1
  409. package/dist/utils/react/RenderCache.js +1 -1
  410. package/dist/utils/react/Slots.js +1 -1
  411. package/dist/utils/react/chain.js +1 -1
  412. package/dist/utils/react/forwardRefWithGenerics.js +1 -1
  413. package/dist/utils/react/index.js +1 -1
  414. package/dist/utils/react/interactions.js +1 -1
  415. package/dist/utils/react/isTextOnly.js +1 -1
  416. package/dist/utils/react/mapProps.js +1 -1
  417. package/dist/utils/react/mergeProps.js +1 -1
  418. package/dist/utils/react/nullableValue.js +1 -1
  419. package/dist/utils/react/resolveIcon.js +1 -1
  420. package/dist/utils/react/sharedStore.js +1 -1
  421. package/dist/utils/react/useCombinedRefs.js +1 -1
  422. package/dist/utils/react/useControlledFocusVisible.js +1 -1
  423. package/dist/utils/react/useEventBus.js +1 -1
  424. package/dist/utils/react/useId.js +1 -1
  425. package/dist/utils/react/useIsDarwin.js +1 -1
  426. package/dist/utils/react/useKeySymbols.js +1 -1
  427. package/dist/utils/react/useLayoutEffect.js +1 -1
  428. package/dist/utils/react/useLocalStorage.js +1 -1
  429. package/dist/utils/react/useMergeStyles.js +1 -1
  430. package/dist/utils/react/useQaProps.js +1 -1
  431. package/dist/utils/react/useViewportSize.js +1 -1
  432. package/dist/utils/react/wrapNodeIfPlain.js +1 -1
  433. package/dist/utils/selection.js +1 -1
  434. package/dist/utils/styles.js +1 -1
  435. package/dist/utils/tree.js +1 -1
  436. package/dist/utils/warnings.js +1 -1
  437. package/dist/version.js +2 -2
  438. package/docs/components/content/Tree.md +115 -32
  439. package/docs/components/fields/FilterPicker.md +27 -0
  440. package/docs/components/fields/ListBox.md +33 -0
  441. package/docs/components/navigation/Tabs.md +127 -51
  442. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.131.0 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.133.0 | Cube Dev Team */
2
2
  import { extractStyles } from "../../utils/styles.js";
3
3
  import { _Text } from "./Text.js";
4
4
  import { CONTAINER_STYLES, TEXT_STYLES } from "@tenphi/tasty";
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.131.0 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.133.0 | Cube Dev Team */
2
2
  import { extractStyles } from "../../../utils/styles.js";
3
3
  import { CONTAINER_STYLES, filterBaseProps, keyframes, tasty } from "@tenphi/tasty";
4
4
  import { forwardRef } from "react";
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.131.0 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.133.0 | Cube Dev Team */
2
2
  import { RendererPrism, ensureYamlSqlExtensions } from "./prismSetup.js";
3
3
  import { CONTAINER_STYLES, tasty } from "@tenphi/tasty";
4
4
  import { forwardRef } from "react";
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.131.0 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.133.0 | Cube Dev Team */
2
2
  import { Prism as RendererPrism } from "prism-react-renderer";
3
3
 
4
4
  //#region src/components/content/PrismCode/prismSetup.tsx
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.131.0 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.133.0 | Cube Dev Team */
2
2
  import { _PrismCode } from "../PrismCode/PrismCode.js";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
  import { diffLines } from "diff";
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.131.0 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.133.0 | Cube Dev Team */
2
2
  import { extractStyles } from "../../../utils/styles.js";
3
3
  import { mergeProps } from "../../../utils/react/mergeProps.js";
4
4
  import { wrapNodeIfPlain } from "../../../utils/react/wrapNodeIfPlain.js";
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.131.0 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.133.0 | Cube Dev Team */
2
2
  import { Space } from "../../layout/Space.js";
3
3
  import { Grid } from "../../layout/Grid.js";
4
4
  import { Flow } from "../../layout/Flow.js";
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.131.0 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.133.0 | Cube Dev Team */
2
2
  import { _Item } from "../Item/Item.js";
3
3
  import { CloseIcon } from "../../../icons/CloseIcon.js";
4
4
  import { tasty } from "@tenphi/tasty";
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.131.0 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.133.0 | Cube Dev Team */
2
2
  import { extractStyles } from "../../utils/styles.js";
3
3
  import { useSlotProps } from "../../utils/react/Slots.js";
4
4
  import { BASE_STYLES, COLOR_STYLES, TEXT_STYLES, filterBaseProps, tasty } from "@tenphi/tasty";
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.131.0 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.133.0 | Cube Dev Team */
2
2
  import { extractStyles } from "../../../utils/styles.js";
3
3
  import { TEXT_PROP_MAP, _Text } from "../Text.js";
4
4
  import { highlightText } from "../highlightText.js";
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.131.0 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.133.0 | Cube Dev Team */
2
2
  import { extractStyles } from "../../utils/styles.js";
3
3
  import { useSlotProps } from "../../utils/react/Slots.js";
4
4
  import { TEXT_PROP_MAP } from "./Text.js";
@@ -1,10 +1,9 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.131.0 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.133.0 | Cube Dev Team */
2
2
  import { extractStyles } from "../../../utils/styles.js";
3
- import { mergeProps as mergeProps$1 } from "../../../utils/react/mergeProps.js";
4
3
  import { mergeRefs } from "../../../utils/react/useCombinedRefs.js";
5
4
  import { useEvent } from "../../../_internal/hooks/use-event.js";
6
5
  import { SIZES, SIZE_NAME_TO_KEY } from "../../../tokens/sizes.js";
7
- import { TreeElement } from "./styled.js";
6
+ import { TreeElement, TreeScrollContainer } from "./styled.js";
8
7
  import { buildTreeIndex } from "./tree-index.js";
9
8
  import { TreeNode } from "./TreeNode.js";
10
9
  import { useCheckboxTree } from "./use-checkbox-tree.js";
@@ -76,9 +75,10 @@ function resolveSelectionMode(selectionMode, isSelectable) {
76
75
  return "single";
77
76
  }
78
77
  function TreeBase(props, ref) {
79
- const { treeData, isCheckable = false, isSelectable, selectionMode: selectionModeProp, size = "medium", shape = "default", containerPadding = 4, isDisabled = false, defaultExpandedKeys, expandedKeys, autoExpandParent = false, defaultCheckedKeys, checkedKeys, defaultSelectedKeys, selectedKeys, height, loadData, onExpand, onCheck, onSelect, itemProps, rowStyles, ariaLabel, qa, ...otherProps } = props;
78
+ const { treeData, isCheckable = false, isSelectable, selectionMode: selectionModeProp, size = "medium", shape = "default", containerPadding = 4, isDisabled = false, defaultExpandedKeys, expandedKeys, autoExpandParent = false, defaultCheckedKeys, checkedKeys, defaultSelectedKeys, selectedKeys, height, loadData, onExpand, onCheck, onSelect, itemProps, rowStyles, ariaLabel, qa, menu: treeMenu, contextMenu: treeContextMenu, onAction: treeOnAction, menuTriggerProps, menuProps, ...otherProps } = props;
80
79
  const baseStyles = extractStyles(otherProps, OUTER_STYLES);
81
80
  const treeRef = useRef(null);
81
+ const scrollRef = useRef(null);
82
82
  const treeIndex = useMemo(() => buildTreeIndex(treeData), [treeData]);
83
83
  const nodesByKey = treeIndex.byKey;
84
84
  const parentOf = treeIndex.parentOf;
@@ -217,7 +217,7 @@ function TreeBase(props, ref) {
217
217
  visibleNodesRef.current = visibleNodes;
218
218
  const rowVirtualizer = useVirtualizer({
219
219
  count: visibleNodes.length,
220
- getScrollElement: () => treeRef.current,
220
+ getScrollElement: () => scrollRef.current,
221
221
  getItemKey: (index) => {
222
222
  return visibleNodesRef.current[index]?.key ?? index;
223
223
  },
@@ -227,18 +227,19 @@ function TreeBase(props, ref) {
227
227
  paddingStart: containerPadding,
228
228
  paddingEnd: containerPadding
229
229
  });
230
- const containerStyle = useMemo(() => {
231
- const style = {
232
- position: "relative",
233
- height: `${rowVirtualizer.getTotalSize()}px`
234
- };
235
- if (height != null) style["--tree-height"] = `${height}px`;
236
- return style;
237
- }, [rowVirtualizer.getTotalSize(), height]);
230
+ const treeStyle = useMemo(() => {
231
+ if (height == null) return void 0;
232
+ return { ["--tree-height"]: `${height}px` };
233
+ }, [height]);
234
+ const sizerStyle = useMemo(() => ({
235
+ position: "relative",
236
+ width: "100%",
237
+ height: `${rowVirtualizer.getTotalSize()}px`
238
+ }), [rowVirtualizer.getTotalSize()]);
238
239
  useLayoutEffect(() => {
239
240
  const focusedKey = state.selectionManager.focusedKey;
240
241
  if (focusedKey == null) return;
241
- const scrollElement = treeRef.current;
242
+ const scrollElement = scrollRef.current;
242
243
  if (!scrollElement) return;
243
244
  const row = scrollElement.querySelector(`[data-qa-key="${CSS.escape(String(focusedKey))}"]`);
244
245
  if (!row || typeof row.scrollIntoView !== "function") return;
@@ -248,41 +249,55 @@ function TreeBase(props, ref) {
248
249
  "has-height": height != null,
249
250
  shape
250
251
  }), [height, shape]);
252
+ const mergedScrollRef = useMemo(() => mergeRefs(ref, scrollRef), [ref, scrollRef]);
251
253
  return /* @__PURE__ */ jsx(TreeElement, {
252
- ...mergeProps$1(gridProps, { ref: useMemo(() => mergeRefs(ref, treeRef), [ref, treeRef]) }),
254
+ ...gridProps,
255
+ ref: treeRef,
253
256
  qa: qa ?? "Tree",
254
257
  mods,
255
258
  styles: baseStyles,
256
- style: containerStyle,
257
- children: rowVirtualizer.getVirtualItems().map((virtualItem) => {
258
- const node = visibleNodes[virtualItem.index];
259
- if (!node) return null;
260
- const keyStr = String(node.key);
261
- const data = nodesByKey.get(keyStr);
262
- if (!data) return null;
263
- return /* @__PURE__ */ jsx(TreeNode, {
264
- node,
265
- data,
266
- state,
267
- isCheckable,
268
- isExpanded: state.expandedKeys.has(node.key),
269
- isChecked: checkbox.checkedSet.has(keyStr),
270
- isIndeterminate: checkbox.halfCheckedSet.has(keyStr),
271
- isLoading: loadDataController.loadingKeys.has(keyStr),
272
- size,
273
- itemProps,
274
- rowStyles,
275
- virtualStyle: {
276
- position: "absolute",
277
- top: 0,
278
- left: containerPadding,
279
- right: containerPadding,
280
- transform: `translateY(${virtualItem.start}px)`
281
- },
282
- virtualRef: rowVirtualizer.measureElement,
283
- virtualIndex: virtualItem.index,
284
- onToggleChecked: checkbox.toggle
285
- }, node.key);
259
+ style: treeStyle,
260
+ children: /* @__PURE__ */ jsx(TreeScrollContainer, {
261
+ ref: mergedScrollRef,
262
+ children: /* @__PURE__ */ jsx("div", {
263
+ role: "presentation",
264
+ style: sizerStyle,
265
+ children: rowVirtualizer.getVirtualItems().map((virtualItem) => {
266
+ const node = visibleNodes[virtualItem.index];
267
+ if (!node) return null;
268
+ const keyStr = String(node.key);
269
+ const data = nodesByKey.get(keyStr);
270
+ if (!data) return null;
271
+ return /* @__PURE__ */ jsx(TreeNode, {
272
+ node,
273
+ data,
274
+ state,
275
+ isCheckable,
276
+ isExpanded: state.expandedKeys.has(node.key),
277
+ isChecked: checkbox.checkedSet.has(keyStr),
278
+ isIndeterminate: checkbox.halfCheckedSet.has(keyStr),
279
+ isLoading: loadDataController.loadingKeys.has(keyStr),
280
+ size,
281
+ itemProps,
282
+ rowStyles,
283
+ virtualStyle: {
284
+ position: "absolute",
285
+ top: 0,
286
+ left: containerPadding,
287
+ right: containerPadding,
288
+ transform: `translateY(${virtualItem.start}px)`
289
+ },
290
+ virtualRef: rowVirtualizer.measureElement,
291
+ virtualIndex: virtualItem.index,
292
+ menu: treeMenu,
293
+ contextMenu: treeContextMenu,
294
+ menuTriggerProps,
295
+ menuProps,
296
+ onToggleChecked: checkbox.toggle,
297
+ onAction: treeOnAction
298
+ }, node.key);
299
+ })
300
+ })
286
301
  })
287
302
  });
288
303
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Tree.js","names":["mergeProps"],"sources":["../../../../src/components/content/Tree/Tree.tsx"],"sourcesContent":["import { useVirtualizer } from '@tanstack/react-virtual';\nimport { OUTER_STYLES } from '@tenphi/tasty';\nimport { forwardRef, useLayoutEffect, useMemo, useRef } from 'react';\nimport { useTree } from 'react-aria';\nimport { Item, useTreeState } from 'react-stately';\n\nimport { useEvent } from '../../../_internal/hooks';\nimport { SIZE_NAME_TO_KEY, SIZES } from '../../../tokens/sizes';\nimport { mergeProps, mergeRefs } from '../../../utils/react';\nimport { extractStyles } from '../../../utils/styles';\n\nimport { TreeElement } from './styled';\nimport { buildTreeIndex } from './tree-index';\nimport { TreeNode } from './TreeNode';\nimport { useCheckboxTree } from './use-checkbox-tree';\nimport { useLoadData } from './use-load-data';\n\nimport type { Key, Node, Selection } from '@react-types/shared';\nimport type {\n CSSProperties,\n ForwardedRef,\n ReactElement,\n ReactNode,\n} from 'react';\nimport type {\n CubeTreeNodeData,\n CubeTreeProps,\n TreeOnExpandInfo,\n TreeOnSelectInfo,\n TreeSelectionMode,\n} from './types';\n\n/**\n * Render an `<Item>` for React Stately's collection builder.\n *\n * The visible content is rendered by `TreeNode` via `nodesByKey`,\n * so `<Item>`'s body is only used by Stately for the collection\n * (`textValue` for keyboard nav, `childItems` for nested traversal).\n */\nfunction renderItem(node: CubeTreeNodeData): ReactElement {\n const textValue =\n typeof node.title === 'string' ? node.title : String(node.key);\n return (\n <Item\n key={node.key}\n textValue={textValue}\n childItems={node.children as CubeTreeNodeData[] | undefined}\n >\n {node.title as ReactNode}\n </Item>\n );\n}\n\nfunction collectDisabledKeys(\n treeData: CubeTreeNodeData[],\n treeIsDisabled: boolean,\n): string[] {\n const keys: string[] = [];\n const visit = (nodes: CubeTreeNodeData[]) => {\n for (const node of nodes) {\n if (treeIsDisabled || node.isDisabled) keys.push(node.key);\n if (node.children) visit(node.children);\n }\n };\n visit(treeData);\n return keys;\n}\n\n/** Expand the supplied keys with all of their ancestor keys. */\nfunction expandWithParents(\n keys: string[] | undefined,\n parentOf: Map<string, string | null>,\n): string[] | undefined {\n if (!keys || keys.length === 0) return keys;\n const set = new Set<string>(keys);\n for (const key of keys) {\n let parent = parentOf.get(key);\n while (parent) {\n set.add(parent);\n parent = parentOf.get(parent);\n }\n }\n return Array.from(set);\n}\n\n/**\n * Diff two key sets to find the single key that was added or removed.\n * Returns `null` when both sets are equal.\n */\nfunction findToggledKey(\n previous: Set<Key>,\n next: Set<Key>,\n): { key: Key; added: boolean } | null {\n for (const k of next) {\n if (!previous.has(k)) return { key: k, added: true };\n }\n for (const k of previous) {\n if (!next.has(k)) return { key: k, added: false };\n }\n return null;\n}\n\nfunction resolveSelectionMode(\n selectionMode: TreeSelectionMode | undefined,\n isSelectable: boolean | undefined,\n): TreeSelectionMode {\n if (selectionMode != null) return selectionMode;\n if (isSelectable === false) return 'none';\n return 'single';\n}\n\nfunction TreeBase(props: CubeTreeProps, ref: ForwardedRef<HTMLDivElement>) {\n const {\n treeData,\n isCheckable = false,\n isSelectable,\n selectionMode: selectionModeProp,\n size = 'medium',\n shape = 'default',\n containerPadding = 4,\n isDisabled = false,\n defaultExpandedKeys,\n expandedKeys,\n autoExpandParent = false,\n defaultCheckedKeys,\n checkedKeys,\n defaultSelectedKeys,\n selectedKeys,\n height,\n loadData,\n onExpand,\n onCheck,\n onSelect,\n itemProps,\n rowStyles,\n ariaLabel,\n qa,\n ...otherProps\n } = props;\n\n const baseStyles = extractStyles(otherProps, OUTER_STYLES);\n\n const treeRef = useRef<HTMLDivElement>(null);\n\n const treeIndex = useMemo(() => buildTreeIndex(treeData), [treeData]);\n const nodesByKey = treeIndex.byKey;\n const parentOf = treeIndex.parentOf;\n\n const disabledKeys = useMemo(\n () => collectDisabledKeys(treeData, isDisabled),\n [treeData, isDisabled],\n );\n\n const selectionMode = resolveSelectionMode(selectionModeProp, isSelectable);\n\n const effectiveExpandedKeys = useMemo(\n () =>\n autoExpandParent\n ? expandWithParents(expandedKeys, parentOf)\n : expandedKeys,\n [autoExpandParent, expandedKeys, parentOf],\n );\n\n const effectiveDefaultExpandedKeys = useMemo(\n () =>\n autoExpandParent\n ? expandWithParents(defaultExpandedKeys, parentOf)\n : defaultExpandedKeys,\n [autoExpandParent, defaultExpandedKeys, parentOf],\n );\n\n const checkbox = useCheckboxTree({\n treeData,\n index: treeIndex,\n isCheckable,\n defaultCheckedKeys,\n checkedKeys,\n onCheck,\n });\n\n const loadDataController = useLoadData({\n nodesByKey,\n loadData,\n initialExpandedKeys: effectiveExpandedKeys ?? effectiveDefaultExpandedKeys,\n });\n\n /**\n * In controlled mode, `previous` is read from `effectiveExpandedKeys`;\n * in uncontrolled mode this ref is the only source. Initialized from\n * the *effective* (ancestor-expanded) keys so the first toggle diffs\n * correctly.\n */\n const previousExpandedRef = useRef<Set<Key>>(\n new Set<Key>(effectiveExpandedKeys ?? effectiveDefaultExpandedKeys ?? []),\n );\n\n const handleExpandedChange = useEvent((nextSet: Set<Key>) => {\n loadDataController.onExpandedChanged(nextSet);\n\n const previous =\n expandedKeys !== undefined\n ? new Set<Key>(effectiveExpandedKeys ?? [])\n : previousExpandedRef.current;\n previousExpandedRef.current = new Set<Key>(nextSet);\n\n if (!onExpand) return;\n\n const toggled = findToggledKey(previous, nextSet);\n if (!toggled) return;\n\n const node = nodesByKey.get(String(toggled.key));\n if (!node) return;\n\n const info: TreeOnExpandInfo = {\n expanded: toggled.added,\n node,\n };\n onExpand(Array.from(nextSet), info);\n });\n\n /**\n * Same pattern as `previousExpandedRef`: in controlled mode we read\n * from `selectedKeys`; in uncontrolled mode this ref tracks state.\n */\n const previousSelectionRef = useRef<Set<Key>>(\n new Set<Key>(selectedKeys ?? defaultSelectedKeys ?? []),\n );\n\n /**\n * `useEvent` captures the closure lazily, so `state` (declared below\n * `ariaProps` / `useTreeState`) is safely accessible at call time.\n */\n const handleSelectionChange = useEvent((selection: Selection) => {\n if (!onSelect) return;\n let arr: Key[];\n if (selection === 'all') {\n // `nodesByKey` contains the full tree; use the collection's visible\n // keys so we don't leak keys under collapsed parents.\n arr = [];\n for (const key of state.collection.getKeys()) {\n const node = state.collection.getItem(key);\n if (node && node.type === 'item') arr.push(key);\n }\n } else {\n arr = Array.from(selection);\n }\n\n const nextSet = new Set<Key>(arr);\n const previous =\n selectedKeys !== undefined\n ? new Set<Key>(selectedKeys ?? [])\n : previousSelectionRef.current;\n previousSelectionRef.current = nextSet;\n\n const toggled = findToggledKey(previous, nextSet);\n if (!toggled) return;\n\n const node = nodesByKey.get(String(toggled.key));\n if (!node) return;\n\n const selectedNodes = arr\n .map((k) => nodesByKey.get(String(k)))\n .filter((n): n is CubeTreeNodeData => !!n);\n\n const info: TreeOnSelectInfo = {\n selected: toggled.added,\n node,\n selectedNodes,\n };\n\n onSelect(arr, info);\n });\n\n const hasOnSelect = onSelect != null;\n\n const ariaProps = useMemo(\n () => ({\n selectionMode,\n selectedKeys,\n defaultSelectedKeys,\n onSelectionChange:\n hasOnSelect && selectionMode !== 'none'\n ? handleSelectionChange\n : undefined,\n expandedKeys: effectiveExpandedKeys,\n defaultExpandedKeys: effectiveDefaultExpandedKeys,\n onExpandedChange: handleExpandedChange,\n disabledKeys,\n disabledBehavior: 'all' as const,\n items: treeData,\n children: renderItem as any,\n 'aria-label': ariaLabel ?? 'Tree',\n }),\n [\n selectionMode,\n selectedKeys,\n defaultSelectedKeys,\n hasOnSelect,\n handleSelectionChange,\n effectiveExpandedKeys,\n effectiveDefaultExpandedKeys,\n handleExpandedChange,\n disabledKeys,\n treeData,\n ariaLabel,\n ],\n );\n\n const baseState = useTreeState<CubeTreeNodeData>(ariaProps);\n\n // The legacy `TreeCollection` from `useTreeState` lacks `getChildren`,\n // but `useTree` calls it for nested rows. Derive a patched state.\n // TODO: Remove this patch when upgrading to a react-stately version\n // that ships `getChildren` on TreeCollection natively.\n const state = useMemo(() => {\n const collection = baseState.collection;\n if (typeof (collection as any).getChildren === 'function') {\n return baseState;\n }\n const patched = Object.create(collection);\n patched.getChildren = (key: Key): Iterable<Node<CubeTreeNodeData>> => {\n const node = collection.getItem(key);\n return node ? Array.from(node.childNodes) : [];\n };\n return { ...baseState, collection: patched };\n }, [baseState]);\n\n const { gridProps } = useTree(ariaProps, state, treeRef);\n\n const visibleNodes: Node<CubeTreeNodeData>[] = useMemo(() => {\n const out: Node<CubeTreeNodeData>[] = [];\n for (const key of state.collection.getKeys()) {\n const node = state.collection.getItem(key);\n if (node && node.type === 'item') out.push(node);\n }\n return out;\n }, [state.collection]);\n\n const visibleNodesRef = useRef(visibleNodes);\n visibleNodesRef.current = visibleNodes;\n\n // ----- Virtualization -----\n const rowVirtualizer = useVirtualizer({\n count: visibleNodes.length,\n getScrollElement: () => treeRef.current,\n getItemKey: (index: number) => {\n const node = visibleNodesRef.current[index];\n return node?.key ?? index;\n },\n estimateSize: () => SIZES[SIZE_NAME_TO_KEY[size]],\n gap: 1,\n overscan: 10,\n paddingStart: containerPadding,\n paddingEnd: containerPadding,\n });\n\n const containerStyle = useMemo<CSSProperties>(() => {\n const style: CSSProperties = {\n position: 'relative',\n height: `${rowVirtualizer.getTotalSize()}px`,\n };\n if (height != null) {\n (style as any)['--tree-height'] = `${height}px`;\n }\n return style;\n }, [rowVirtualizer.getTotalSize(), height]);\n\n // Keep focused node visible during keyboard navigation.\n useLayoutEffect(() => {\n const focusedKey = state.selectionManager.focusedKey;\n if (focusedKey == null) return;\n\n const scrollElement = treeRef.current;\n if (!scrollElement) return;\n\n const row = scrollElement.querySelector(\n `[data-qa-key=\"${CSS.escape(String(focusedKey))}\"]`,\n ) as HTMLElement | null;\n if (!row || typeof row.scrollIntoView !== 'function') return;\n\n row.scrollIntoView({ block: 'nearest' });\n }, [state.selectionManager.focusedKey]);\n\n const mods = useMemo(\n () => ({\n 'has-height': height != null,\n shape,\n }),\n [height, shape],\n );\n\n // Both `useTree` and the consumer need the same DOM node.\n const mergedRef = useMemo(() => mergeRefs(ref, treeRef), [ref, treeRef]);\n\n const elementProps = mergeProps(gridProps, {\n ref: mergedRef,\n });\n\n return (\n <TreeElement\n {...elementProps}\n qa={qa ?? 'Tree'}\n mods={mods}\n styles={baseStyles}\n style={containerStyle}\n >\n {rowVirtualizer.getVirtualItems().map((virtualItem) => {\n const node = visibleNodes[virtualItem.index];\n if (!node) return null;\n const keyStr = String(node.key);\n const data = nodesByKey.get(keyStr);\n if (!data) return null;\n return (\n <TreeNode\n key={node.key}\n node={node}\n data={data}\n state={state}\n isCheckable={isCheckable}\n isExpanded={state.expandedKeys.has(node.key)}\n isChecked={checkbox.checkedSet.has(keyStr)}\n isIndeterminate={checkbox.halfCheckedSet.has(keyStr)}\n isLoading={loadDataController.loadingKeys.has(keyStr)}\n size={size}\n itemProps={itemProps}\n rowStyles={rowStyles}\n virtualStyle={{\n position: 'absolute',\n top: 0,\n left: containerPadding,\n right: containerPadding,\n transform: `translateY(${virtualItem.start}px)`,\n }}\n virtualRef={rowVirtualizer.measureElement}\n virtualIndex={virtualItem.index}\n onToggleChecked={checkbox.toggle}\n />\n );\n })}\n </TreeElement>\n );\n}\n\nconst _Tree = forwardRef(TreeBase);\n_Tree.displayName = 'Tree';\n\n/**\n * Hierarchical data display with optional checkboxes, single/multi\n * selection, async lazy loading, and keyboard navigation.\n *\n * Built on `useTree` / `useTreeState` (React Aria + React Stately) and\n * styled with Tasty.\n *\n * @example\n * ```tsx\n * <Tree\n * treeData={data}\n * isCheckable\n * selectionMode=\"none\"\n * defaultExpandedKeys={['root']}\n * onCheck={(keys) => console.log(keys)}\n * />\n * ```\n */\nexport const Tree = _Tree;\n"],"mappings":"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"}
1
+ {"version":3,"file":"Tree.js","names":[],"sources":["../../../../src/components/content/Tree/Tree.tsx"],"sourcesContent":["import { useVirtualizer } from '@tanstack/react-virtual';\nimport { OUTER_STYLES } from '@tenphi/tasty';\nimport { forwardRef, useLayoutEffect, useMemo, useRef } from 'react';\nimport { useTree } from 'react-aria';\nimport { Item, useTreeState } from 'react-stately';\n\nimport { useEvent } from '../../../_internal/hooks';\nimport { SIZE_NAME_TO_KEY, SIZES } from '../../../tokens/sizes';\nimport { mergeRefs } from '../../../utils/react';\nimport { extractStyles } from '../../../utils/styles';\n\nimport { TreeElement, TreeScrollContainer } from './styled';\nimport { buildTreeIndex } from './tree-index';\nimport { TreeNode } from './TreeNode';\nimport { useCheckboxTree } from './use-checkbox-tree';\nimport { useLoadData } from './use-load-data';\n\nimport type { Key, Node, Selection } from '@react-types/shared';\nimport type {\n CSSProperties,\n ForwardedRef,\n ReactElement,\n ReactNode,\n} from 'react';\nimport type {\n CubeTreeNodeData,\n CubeTreeProps,\n TreeOnExpandInfo,\n TreeOnSelectInfo,\n TreeSelectionMode,\n} from './types';\n\n/**\n * Render an `<Item>` for React Stately's collection builder.\n *\n * The visible content is rendered by `TreeNode` via `nodesByKey`,\n * so `<Item>`'s body is only used by Stately for the collection\n * (`textValue` for keyboard nav, `childItems` for nested traversal).\n */\nfunction renderItem(node: CubeTreeNodeData): ReactElement {\n const textValue =\n typeof node.title === 'string' ? node.title : String(node.key);\n return (\n <Item\n key={node.key}\n textValue={textValue}\n childItems={node.children as CubeTreeNodeData[] | undefined}\n >\n {node.title as ReactNode}\n </Item>\n );\n}\n\nfunction collectDisabledKeys(\n treeData: CubeTreeNodeData[],\n treeIsDisabled: boolean,\n): string[] {\n const keys: string[] = [];\n const visit = (nodes: CubeTreeNodeData[]) => {\n for (const node of nodes) {\n if (treeIsDisabled || node.isDisabled) keys.push(node.key);\n if (node.children) visit(node.children);\n }\n };\n visit(treeData);\n return keys;\n}\n\n/** Expand the supplied keys with all of their ancestor keys. */\nfunction expandWithParents(\n keys: string[] | undefined,\n parentOf: Map<string, string | null>,\n): string[] | undefined {\n if (!keys || keys.length === 0) return keys;\n const set = new Set<string>(keys);\n for (const key of keys) {\n let parent = parentOf.get(key);\n while (parent) {\n set.add(parent);\n parent = parentOf.get(parent);\n }\n }\n return Array.from(set);\n}\n\n/**\n * Diff two key sets to find the single key that was added or removed.\n * Returns `null` when both sets are equal.\n */\nfunction findToggledKey(\n previous: Set<Key>,\n next: Set<Key>,\n): { key: Key; added: boolean } | null {\n for (const k of next) {\n if (!previous.has(k)) return { key: k, added: true };\n }\n for (const k of previous) {\n if (!next.has(k)) return { key: k, added: false };\n }\n return null;\n}\n\nfunction resolveSelectionMode(\n selectionMode: TreeSelectionMode | undefined,\n isSelectable: boolean | undefined,\n): TreeSelectionMode {\n if (selectionMode != null) return selectionMode;\n if (isSelectable === false) return 'none';\n return 'single';\n}\n\nfunction TreeBase(props: CubeTreeProps, ref: ForwardedRef<HTMLDivElement>) {\n const {\n treeData,\n isCheckable = false,\n isSelectable,\n selectionMode: selectionModeProp,\n size = 'medium',\n shape = 'default',\n containerPadding = 4,\n isDisabled = false,\n defaultExpandedKeys,\n expandedKeys,\n autoExpandParent = false,\n defaultCheckedKeys,\n checkedKeys,\n defaultSelectedKeys,\n selectedKeys,\n height,\n loadData,\n onExpand,\n onCheck,\n onSelect,\n itemProps,\n rowStyles,\n ariaLabel,\n qa,\n menu: treeMenu,\n contextMenu: treeContextMenu,\n onAction: treeOnAction,\n menuTriggerProps,\n menuProps,\n ...otherProps\n } = props;\n\n const baseStyles = extractStyles(otherProps, OUTER_STYLES);\n\n const treeRef = useRef<HTMLDivElement>(null);\n const scrollRef = useRef<HTMLDivElement>(null);\n\n const treeIndex = useMemo(() => buildTreeIndex(treeData), [treeData]);\n const nodesByKey = treeIndex.byKey;\n const parentOf = treeIndex.parentOf;\n\n const disabledKeys = useMemo(\n () => collectDisabledKeys(treeData, isDisabled),\n [treeData, isDisabled],\n );\n\n const selectionMode = resolveSelectionMode(selectionModeProp, isSelectable);\n\n const effectiveExpandedKeys = useMemo(\n () =>\n autoExpandParent\n ? expandWithParents(expandedKeys, parentOf)\n : expandedKeys,\n [autoExpandParent, expandedKeys, parentOf],\n );\n\n const effectiveDefaultExpandedKeys = useMemo(\n () =>\n autoExpandParent\n ? expandWithParents(defaultExpandedKeys, parentOf)\n : defaultExpandedKeys,\n [autoExpandParent, defaultExpandedKeys, parentOf],\n );\n\n const checkbox = useCheckboxTree({\n treeData,\n index: treeIndex,\n isCheckable,\n defaultCheckedKeys,\n checkedKeys,\n onCheck,\n });\n\n const loadDataController = useLoadData({\n nodesByKey,\n loadData,\n initialExpandedKeys: effectiveExpandedKeys ?? effectiveDefaultExpandedKeys,\n });\n\n /**\n * In controlled mode, `previous` is read from `effectiveExpandedKeys`;\n * in uncontrolled mode this ref is the only source. Initialized from\n * the *effective* (ancestor-expanded) keys so the first toggle diffs\n * correctly.\n */\n const previousExpandedRef = useRef<Set<Key>>(\n new Set<Key>(effectiveExpandedKeys ?? effectiveDefaultExpandedKeys ?? []),\n );\n\n const handleExpandedChange = useEvent((nextSet: Set<Key>) => {\n loadDataController.onExpandedChanged(nextSet);\n\n const previous =\n expandedKeys !== undefined\n ? new Set<Key>(effectiveExpandedKeys ?? [])\n : previousExpandedRef.current;\n previousExpandedRef.current = new Set<Key>(nextSet);\n\n if (!onExpand) return;\n\n const toggled = findToggledKey(previous, nextSet);\n if (!toggled) return;\n\n const node = nodesByKey.get(String(toggled.key));\n if (!node) return;\n\n const info: TreeOnExpandInfo = {\n expanded: toggled.added,\n node,\n };\n onExpand(Array.from(nextSet), info);\n });\n\n /**\n * Same pattern as `previousExpandedRef`: in controlled mode we read\n * from `selectedKeys`; in uncontrolled mode this ref tracks state.\n */\n const previousSelectionRef = useRef<Set<Key>>(\n new Set<Key>(selectedKeys ?? defaultSelectedKeys ?? []),\n );\n\n /**\n * `useEvent` captures the closure lazily, so `state` (declared below\n * `ariaProps` / `useTreeState`) is safely accessible at call time.\n */\n const handleSelectionChange = useEvent((selection: Selection) => {\n if (!onSelect) return;\n let arr: Key[];\n if (selection === 'all') {\n // `nodesByKey` contains the full tree; use the collection's visible\n // keys so we don't leak keys under collapsed parents.\n arr = [];\n for (const key of state.collection.getKeys()) {\n const node = state.collection.getItem(key);\n if (node && node.type === 'item') arr.push(key);\n }\n } else {\n arr = Array.from(selection);\n }\n\n const nextSet = new Set<Key>(arr);\n const previous =\n selectedKeys !== undefined\n ? new Set<Key>(selectedKeys ?? [])\n : previousSelectionRef.current;\n previousSelectionRef.current = nextSet;\n\n const toggled = findToggledKey(previous, nextSet);\n if (!toggled) return;\n\n const node = nodesByKey.get(String(toggled.key));\n if (!node) return;\n\n const selectedNodes = arr\n .map((k) => nodesByKey.get(String(k)))\n .filter((n): n is CubeTreeNodeData => !!n);\n\n const info: TreeOnSelectInfo = {\n selected: toggled.added,\n node,\n selectedNodes,\n };\n\n onSelect(arr, info);\n });\n\n const hasOnSelect = onSelect != null;\n\n const ariaProps = useMemo(\n () => ({\n selectionMode,\n selectedKeys,\n defaultSelectedKeys,\n onSelectionChange:\n hasOnSelect && selectionMode !== 'none'\n ? handleSelectionChange\n : undefined,\n expandedKeys: effectiveExpandedKeys,\n defaultExpandedKeys: effectiveDefaultExpandedKeys,\n onExpandedChange: handleExpandedChange,\n disabledKeys,\n disabledBehavior: 'all' as const,\n items: treeData,\n children: renderItem as any,\n 'aria-label': ariaLabel ?? 'Tree',\n }),\n [\n selectionMode,\n selectedKeys,\n defaultSelectedKeys,\n hasOnSelect,\n handleSelectionChange,\n effectiveExpandedKeys,\n effectiveDefaultExpandedKeys,\n handleExpandedChange,\n disabledKeys,\n treeData,\n ariaLabel,\n ],\n );\n\n const baseState = useTreeState<CubeTreeNodeData>(ariaProps);\n\n // The legacy `TreeCollection` from `useTreeState` lacks `getChildren`,\n // but `useTree` calls it for nested rows. Derive a patched state.\n // TODO: Remove this patch when upgrading to a react-stately version\n // that ships `getChildren` on TreeCollection natively.\n const state = useMemo(() => {\n const collection = baseState.collection;\n if (typeof (collection as any).getChildren === 'function') {\n return baseState;\n }\n const patched = Object.create(collection);\n patched.getChildren = (key: Key): Iterable<Node<CubeTreeNodeData>> => {\n const node = collection.getItem(key);\n return node ? Array.from(node.childNodes) : [];\n };\n return { ...baseState, collection: patched };\n }, [baseState]);\n\n const { gridProps } = useTree(ariaProps, state, treeRef);\n\n const visibleNodes: Node<CubeTreeNodeData>[] = useMemo(() => {\n const out: Node<CubeTreeNodeData>[] = [];\n for (const key of state.collection.getKeys()) {\n const node = state.collection.getItem(key);\n if (node && node.type === 'item') out.push(node);\n }\n return out;\n }, [state.collection]);\n\n const visibleNodesRef = useRef(visibleNodes);\n visibleNodesRef.current = visibleNodes;\n\n // ----- Virtualization -----\n const rowVirtualizer = useVirtualizer({\n count: visibleNodes.length,\n getScrollElement: () => scrollRef.current,\n getItemKey: (index: number) => {\n const node = visibleNodesRef.current[index];\n return node?.key ?? index;\n },\n estimateSize: () => SIZES[SIZE_NAME_TO_KEY[size]],\n gap: 1,\n overscan: 10,\n paddingStart: containerPadding,\n paddingEnd: containerPadding,\n });\n\n const treeStyle = useMemo<CSSProperties | undefined>(() => {\n if (height == null) return undefined;\n return { ['--tree-height' as keyof CSSProperties]: `${height}px` };\n }, [height]);\n\n const sizerStyle = useMemo<CSSProperties>(\n () => ({\n position: 'relative',\n width: '100%',\n height: `${rowVirtualizer.getTotalSize()}px`,\n }),\n [rowVirtualizer.getTotalSize()],\n );\n\n // Keep focused node visible during keyboard navigation.\n useLayoutEffect(() => {\n const focusedKey = state.selectionManager.focusedKey;\n if (focusedKey == null) return;\n\n const scrollElement = scrollRef.current;\n if (!scrollElement) return;\n\n const row = scrollElement.querySelector(\n `[data-qa-key=\"${CSS.escape(String(focusedKey))}\"]`,\n ) as HTMLElement | null;\n if (!row || typeof row.scrollIntoView !== 'function') return;\n\n row.scrollIntoView({ block: 'nearest' });\n }, [state.selectionManager.focusedKey]);\n\n const mods = useMemo(\n () => ({\n 'has-height': height != null,\n shape,\n }),\n [height, shape],\n );\n\n // The forwarded ref points at the inner scroll container so\n // consumers can drive `scrollTop` directly. `treeRef` (used by\n // `useTree` for keyboard handling and as the role=\"treegrid\"\n // anchor) stays internal on `TreeElement`.\n const mergedScrollRef = useMemo(\n () => mergeRefs(ref, scrollRef),\n [ref, scrollRef],\n );\n\n return (\n <TreeElement\n {...gridProps}\n ref={treeRef}\n qa={qa ?? 'Tree'}\n mods={mods}\n styles={baseStyles}\n style={treeStyle}\n >\n <TreeScrollContainer ref={mergedScrollRef}>\n <div role=\"presentation\" style={sizerStyle}>\n {rowVirtualizer.getVirtualItems().map((virtualItem) => {\n const node = visibleNodes[virtualItem.index];\n if (!node) return null;\n const keyStr = String(node.key);\n const data = nodesByKey.get(keyStr);\n if (!data) return null;\n return (\n <TreeNode\n key={node.key}\n node={node}\n data={data}\n state={state}\n isCheckable={isCheckable}\n isExpanded={state.expandedKeys.has(node.key)}\n isChecked={checkbox.checkedSet.has(keyStr)}\n isIndeterminate={checkbox.halfCheckedSet.has(keyStr)}\n isLoading={loadDataController.loadingKeys.has(keyStr)}\n size={size}\n itemProps={itemProps}\n rowStyles={rowStyles}\n virtualStyle={{\n position: 'absolute',\n top: 0,\n left: containerPadding,\n right: containerPadding,\n transform: `translateY(${virtualItem.start}px)`,\n }}\n virtualRef={rowVirtualizer.measureElement}\n virtualIndex={virtualItem.index}\n menu={treeMenu}\n contextMenu={treeContextMenu}\n menuTriggerProps={menuTriggerProps}\n menuProps={menuProps}\n onToggleChecked={checkbox.toggle}\n onAction={treeOnAction}\n />\n );\n })}\n </div>\n </TreeScrollContainer>\n </TreeElement>\n );\n}\n\nconst _Tree = forwardRef(TreeBase);\n_Tree.displayName = 'Tree';\n\n/**\n * Hierarchical data display with optional checkboxes, single/multi\n * selection, async lazy loading, and keyboard navigation.\n *\n * Built on `useTree` / `useTreeState` (React Aria + React Stately) and\n * styled with Tasty.\n *\n * @example\n * ```tsx\n * <Tree\n * treeData={data}\n * isCheckable\n * selectionMode=\"none\"\n * defaultExpandedKeys={['root']}\n * onCheck={(keys) => console.log(keys)}\n * />\n * ```\n */\nexport const Tree = _Tree;\n"],"mappings":"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"}
@@ -1,12 +1,17 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.131.0 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.133.0 | Cube Dev Team */
2
2
  import { mergeProps as mergeProps$1 } from "../../../utils/react/mergeProps.js";
3
3
  import { mergeRefs } from "../../../utils/react/useCombinedRefs.js";
4
4
  import { useEvent } from "../../../_internal/hooks/use-event.js";
5
5
  import { LoadingIcon } from "../../../icons/LoadingIcon.js";
6
+ import { ItemAction } from "../../actions/ItemAction/ItemAction.js";
6
7
  import { DirectionIcon } from "../../../icons/DirectionIcon.js";
8
+ import { MoreIcon } from "../../../icons/MoreIcon.js";
9
+ import { _MenuTrigger } from "../../actions/Menu/MenuTrigger.js";
10
+ import { __Menu } from "../../actions/Menu/Menu.js";
11
+ import { useContextMenu } from "../../actions/use-context-menu.js";
7
12
  import { TreeNodeCheckboxWrapper, TreeNodeRow, TreeNodeToggle, TreeNodeTogglePlaceholder, TreeRowItem } from "./styled.js";
8
13
  import { __Checkbox } from "../../fields/Checkbox/Checkbox.js";
9
- import { memo, useMemo, useRef } from "react";
14
+ import { Children, memo, useMemo, useRef, useState } from "react";
10
15
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
11
16
  import { useHover, useTreeItem } from "react-aria";
12
17
 
@@ -14,10 +19,14 @@ import { useHover, useTreeItem } from "react-aria";
14
19
  const stopPropagation = (e) => {
15
20
  e.stopPropagation();
16
21
  };
22
+ /** Check whether a `menu` ReactNode actually contains anything. */
23
+ function isMenuEmpty(menu) {
24
+ if (menu === null || menu === void 0 || menu === false) return true;
25
+ return Children.toArray(menu).length === 0;
26
+ }
17
27
  function TreeNodeInner(props) {
18
- const { node, data, state, isCheckable, isExpanded, isIndeterminate, isChecked, isLoading, onToggleChecked, size, itemProps, rowStyles, virtualStyle, virtualRef, virtualIndex } = props;
28
+ const { node, data, state, isCheckable, isExpanded, isIndeterminate, isChecked, isLoading, onToggleChecked, size, itemProps, rowStyles, virtualStyle, virtualRef, virtualIndex, menu: treeMenu, contextMenu: treeContextMenu, onAction: treeOnAction, menuTriggerProps, menuProps } = props;
19
29
  const rowRef = useRef(null);
20
- const combinedRef = useMemo(() => virtualRef ? mergeRefs(rowRef, virtualRef) : rowRef, [virtualRef]);
21
30
  const { rowProps, gridCellProps, expandButtonProps, isPressed } = useTreeItem({ node }, state, rowRef);
22
31
  const isDisabled = state.disabledKeys.has(node.key);
23
32
  const isSelected = state.selectionManager.isSelected(node.key);
@@ -25,6 +34,31 @@ function TreeNodeInner(props) {
25
34
  const isFocused = state.selectionManager.isFocused && state.selectionManager.focusedKey === node.key;
26
35
  const isLeaf = data.isLeaf === true || data.isLeaf !== false && !node.hasChildNodes;
27
36
  const isRowCheckable = isCheckable && data.isCheckable !== false;
37
+ const nodeState = {
38
+ isExpanded,
39
+ isSelected,
40
+ isChecked,
41
+ isIndeterminate,
42
+ isLeaf
43
+ };
44
+ const effectiveMenuChildren = data.menu === null ? null : data.menu !== void 0 ? data.menu : typeof treeMenu === "function" ? treeMenu(data, nodeState) : treeMenu ?? null;
45
+ const hasMenu = !isMenuEmpty(effectiveMenuChildren);
46
+ const effectiveContextMenu = data.contextMenu ?? treeContextMenu ?? false;
47
+ const menuExposed = hasMenu && (effectiveContextMenu === true || effectiveContextMenu === "context-only");
48
+ const contextMenuOnly = effectiveContextMenu === "context-only";
49
+ const [isMenuOpen, setIsMenuOpen] = useState(false);
50
+ const handleMenuAction = useEvent((action) => {
51
+ const actionStr = String(action);
52
+ const normalizedAction = actionStr.startsWith(".$") ? actionStr.slice(2) : actionStr;
53
+ data.onAction?.(normalizedAction);
54
+ treeOnAction?.(normalizedAction, node.key);
55
+ menuProps?.onAction?.(normalizedAction);
56
+ });
57
+ const rowContextMenu = useContextMenu(__Menu, { placement: "bottom start" }, {
58
+ ...menuProps,
59
+ onAction: handleMenuAction,
60
+ children: effectiveMenuChildren
61
+ });
28
62
  const handleCheckboxChange = useEvent(() => {
29
63
  onToggleChecked(String(node.key));
30
64
  });
@@ -32,7 +66,20 @@ function TreeNodeInner(props) {
32
66
  if (e.key === " " && isRowCheckable && !isDisabled && !data.isCheckboxDisabled) {
33
67
  e.preventDefault();
34
68
  onToggleChecked(String(node.key));
69
+ return false;
70
+ }
71
+ if (e.key === "F10" && e.shiftKey && menuExposed) {
72
+ e.preventDefault();
73
+ e.stopPropagation();
74
+ if (contextMenuOnly) rowContextMenu.open();
75
+ else setIsMenuOpen(true);
76
+ return true;
35
77
  }
78
+ return false;
79
+ });
80
+ const composedKeyDown = useEvent((e) => {
81
+ if (handleKeyDown(e)) return;
82
+ rowProps.onKeyDown?.(e);
36
83
  });
37
84
  const sharedMods = useMemo(() => ({
38
85
  checked: isChecked,
@@ -40,14 +87,16 @@ function TreeNodeInner(props) {
40
87
  expanded: isExpanded,
41
88
  loading: isLoading,
42
89
  leaf: isLeaf,
43
- "has-checkbox": isRowCheckable
90
+ "has-checkbox": isRowCheckable,
91
+ "has-menu": menuExposed
44
92
  }), [
45
93
  isChecked,
46
94
  isIndeterminate,
47
95
  isExpanded,
48
96
  isLoading,
49
97
  isLeaf,
50
- isRowCheckable
98
+ isRowCheckable,
99
+ menuExposed
51
100
  ]);
52
101
  const rowMods = useMemo(() => ({
53
102
  ...sharedMods,
@@ -69,10 +118,11 @@ function TreeNodeInner(props) {
69
118
  ...virtualStyle
70
119
  }), [node.level, virtualStyle]);
71
120
  const ariaChecked = isRowCheckable ? isIndeterminate ? "mixed" : isChecked ? "true" : "false" : void 0;
72
- const finalRowProps = mergeProps$1(rowProps, hoverProps, {
121
+ const finalRowProps = {
122
+ ...mergeProps$1(rowProps, hoverProps),
73
123
  "aria-checked": ariaChecked,
74
- onKeyDown: handleKeyDown
75
- });
124
+ onKeyDown: composedKeyDown
125
+ };
76
126
  const toggleNode = isLeaf ? /* @__PURE__ */ jsx(TreeNodeTogglePlaceholder, {
77
127
  "aria-hidden": true,
78
128
  "data-element": "Toggle"
@@ -95,23 +145,42 @@ function TreeNodeInner(props) {
95
145
  onChange: handleCheckboxChange
96
146
  })
97
147
  }) : null;
98
- const { prefix: userPrefix, ...restUserProps } = (typeof itemProps === "function" ? itemProps(data, {
99
- isExpanded,
100
- isSelected,
101
- isChecked,
102
- isIndeterminate,
103
- isLeaf
104
- }) : itemProps) ?? {};
148
+ const { prefix: userPrefix, actions: userActions, ...restUserProps } = (typeof itemProps === "function" ? itemProps(data, nodeState) : itemProps) ?? {};
105
149
  const composedPrefix = checkboxNode || userPrefix ? /* @__PURE__ */ jsxs(Fragment$1, { children: [checkboxNode, userPrefix] }) : null;
106
- return /* @__PURE__ */ jsx(TreeNodeRow, {
150
+ const menuAction = menuExposed && !contextMenuOnly ? /* @__PURE__ */ jsxs(_MenuTrigger, {
151
+ isOpen: isMenuOpen,
152
+ onOpenChange: setIsMenuOpen,
153
+ children: [/* @__PURE__ */ jsx(ItemAction, {
154
+ tabIndex: -1,
155
+ icon: /* @__PURE__ */ jsx(MoreIcon, {}),
156
+ "aria-label": "Actions",
157
+ ...menuTriggerProps
158
+ }), /* @__PURE__ */ jsx(__Menu, {
159
+ ...menuProps,
160
+ onAction: handleMenuAction,
161
+ children: effectiveMenuChildren
162
+ })]
163
+ }) : null;
164
+ const composedActions = userActions || menuAction ? /* @__PURE__ */ jsxs(Fragment$1, { children: [userActions, menuAction] }) : void 0;
165
+ const refs = useMemo(() => {
166
+ const list = [rowRef];
167
+ if (virtualRef) list.push(virtualRef);
168
+ if (menuExposed) list.push(rowContextMenu.targetRef);
169
+ return mergeRefs(...list);
170
+ }, [
171
+ virtualRef,
172
+ menuExposed,
173
+ rowContextMenu.targetRef
174
+ ]);
175
+ return /* @__PURE__ */ jsxs(TreeNodeRow, {
107
176
  ...finalRowProps,
108
- ref: combinedRef,
177
+ ref: refs,
109
178
  mods: rowMods,
110
179
  style: rowStyle,
111
180
  "data-element": "Row",
112
181
  "data-qa-key": String(node.key),
113
182
  "data-index": virtualIndex,
114
- children: /* @__PURE__ */ jsx(TreeRowItem, {
183
+ children: [/* @__PURE__ */ jsx(TreeRowItem, {
115
184
  ...gridCellProps,
116
185
  ...restUserProps,
117
186
  size,
@@ -120,9 +189,10 @@ function TreeNodeInner(props) {
120
189
  mods: itemMods,
121
190
  icon: toggleNode,
122
191
  prefix: composedPrefix,
192
+ actions: composedActions,
123
193
  styles: rowStyles,
124
194
  children: data.title
125
- })
195
+ }), menuExposed && rowContextMenu.rendered]
126
196
  });
127
197
  }
128
198
  const TreeNode = memo(TreeNodeInner);
@@ -1 +1 @@
1
- {"version":3,"file":"TreeNode.js","names":["mergeProps","Checkbox"],"sources":["../../../../src/components/content/Tree/TreeNode.tsx"],"sourcesContent":["import { memo, useMemo, useRef } from 'react';\nimport { useHover, useTreeItem } from 'react-aria';\n\nimport { useEvent } from '../../../_internal/hooks';\nimport { DirectionIcon, LoadingIcon } from '../../../icons';\nimport { mergeProps, mergeRefs } from '../../../utils/react';\nimport { Checkbox } from '../../fields/Checkbox/Checkbox';\n\nimport {\n TreeNodeCheckboxWrapper,\n TreeNodeRow,\n TreeNodeToggle,\n TreeNodeTogglePlaceholder,\n TreeRowItem,\n} from './styled';\n\nimport type { Node } from '@react-types/shared';\nimport type { Styles } from '@tenphi/tasty';\nimport type { CSSProperties, KeyboardEvent, SyntheticEvent } from 'react';\nimport type { TreeState } from 'react-stately';\nimport type { CubeTreeNodeData, TreeItemProps, TreeNodeState } from './types';\n\nconst stopPropagation = (e: SyntheticEvent) => {\n e.stopPropagation();\n};\n\nexport interface TreeNodeProps {\n node: Node<CubeTreeNodeData>;\n /** The original `CubeTreeNodeData` for this row, looked up by key. */\n data: CubeTreeNodeData;\n state: TreeState<CubeTreeNodeData>;\n\n /** Whether the tree as a whole renders checkboxes. */\n isCheckable: boolean;\n /** Whether this row is currently expanded. */\n isExpanded: boolean;\n /** Whether the row is in an indeterminate (half-checked) state. */\n isIndeterminate: boolean;\n /** Whether the row is fully checked. */\n isChecked: boolean;\n /** Whether `loadData` is currently fetching this row's children. */\n isLoading: boolean;\n\n /** Toggle this row's checkbox (cascades). */\n onToggleChecked: (key: string) => void;\n\n /** Row size passed to the underlying Item. */\n size?: string;\n\n /** Per-node Item customization (static object or callback). */\n itemProps?:\n | TreeItemProps\n | ((data: CubeTreeNodeData, state: TreeNodeState) => TreeItemProps);\n\n /** Styles applied to the visible row (`TreeRowItem`). */\n rowStyles?: Styles;\n\n /** Inline style for virtualizer absolute positioning. */\n virtualStyle?: CSSProperties;\n /** Ref callback from `@tanstack/react-virtual` to measure row height. */\n virtualRef?: (element: HTMLElement | null) => void;\n /** Virtual index for `data-index` attribute. */\n virtualIndex?: number;\n}\n\nfunction TreeNodeInner(props: TreeNodeProps) {\n const {\n node,\n data,\n state,\n isCheckable,\n isExpanded,\n isIndeterminate,\n isChecked,\n isLoading,\n onToggleChecked,\n size,\n itemProps,\n rowStyles,\n virtualStyle,\n virtualRef,\n virtualIndex,\n } = props;\n\n const rowRef = useRef<HTMLDivElement>(null);\n const combinedRef = useMemo(\n () => (virtualRef ? mergeRefs(rowRef, virtualRef) : rowRef),\n [virtualRef],\n );\n\n const { rowProps, gridCellProps, expandButtonProps, isPressed } = useTreeItem(\n { node },\n state,\n rowRef,\n );\n\n const isDisabled = state.disabledKeys.has(node.key);\n const isSelected = state.selectionManager.isSelected(node.key);\n\n // `useTreeItem` doesn't track hover; we need it for the `hovered` mod.\n const { hoverProps, isHovered } = useHover({ isDisabled });\n // React Aria's treegrid uses roving tabindex, so no `data-focused`\n // attribute lands on the row — mirror it as a mod manually.\n const isFocused =\n state.selectionManager.isFocused &&\n state.selectionManager.focusedKey === node.key;\n // For lazy rows with no children yet, still render a toggle unless\n // explicitly marked as leaf.\n const isLeaf =\n data.isLeaf === true || (data.isLeaf !== false && !node.hasChildNodes);\n const isRowCheckable = isCheckable && data.isCheckable !== false;\n\n const handleCheckboxChange = useEvent(() => {\n onToggleChecked(String(node.key));\n });\n\n const handleKeyDown = useEvent((e: KeyboardEvent) => {\n if (\n e.key === ' ' &&\n isRowCheckable &&\n !isDisabled &&\n !data.isCheckboxDisabled\n ) {\n e.preventDefault();\n onToggleChecked(String(node.key));\n }\n });\n\n const sharedMods = useMemo(\n () => ({\n checked: isChecked,\n indeterminate: isIndeterminate,\n expanded: isExpanded,\n loading: isLoading,\n leaf: isLeaf,\n 'has-checkbox': isRowCheckable,\n }),\n [isChecked, isIndeterminate, isExpanded, isLoading, isLeaf, isRowCheckable],\n );\n\n const rowMods = useMemo(\n () => ({ ...sharedMods, disabled: isDisabled }),\n [sharedMods, isDisabled],\n );\n\n const itemMods = useMemo(\n () => ({\n ...sharedMods,\n focused: isFocused,\n hovered: isHovered,\n pressed: isPressed,\n }),\n [sharedMods, isFocused, isHovered, isPressed],\n );\n\n const rowStyle = useMemo<CSSProperties>(\n () => ({\n ['--tree-level' as keyof CSSProperties]: String(node.level ?? 0),\n ...virtualStyle,\n }),\n [node.level, virtualStyle],\n );\n\n // Only emit `aria-checked` when the tree is in checkable mode.\n const ariaChecked: 'mixed' | 'true' | 'false' | undefined = isRowCheckable\n ? isIndeterminate\n ? 'mixed'\n : isChecked\n ? 'true'\n : 'false'\n : undefined;\n\n const finalRowProps = mergeProps(rowProps, hoverProps, {\n 'aria-checked': ariaChecked,\n onKeyDown: handleKeyDown,\n });\n\n // Leaf rows get a placeholder so sibling indents align.\n const toggleNode = isLeaf ? (\n <TreeNodeTogglePlaceholder aria-hidden data-element=\"Toggle\" />\n ) : (\n <TreeNodeToggle {...expandButtonProps} tabIndex={-1} data-element=\"Toggle\">\n {isLoading ? (\n <LoadingIcon />\n ) : (\n <DirectionIcon to={isExpanded ? 'bottom' : 'right'} />\n )}\n </TreeNodeToggle>\n );\n\n const checkboxNode = isRowCheckable ? (\n <TreeNodeCheckboxWrapper\n data-element=\"Checkbox\"\n role=\"presentation\"\n onClick={stopPropagation}\n onKeyDown={stopPropagation}\n >\n <Checkbox\n isSelected={isChecked}\n isIndeterminate={isIndeterminate}\n isDisabled={isDisabled || data.isCheckboxDisabled}\n aria-label={\n typeof data.title === 'string' ? data.title : String(node.key)\n }\n // @ts-expect-error AriaCheckboxProps loses `onChange` where InputDOMProps overlaps (react-types).\n onChange={handleCheckboxChange}\n />\n </TreeNodeCheckboxWrapper>\n ) : null;\n\n const nodeState: TreeNodeState = {\n isExpanded,\n isSelected,\n isChecked,\n isIndeterminate,\n isLeaf,\n };\n const resolvedItemProps =\n typeof itemProps === 'function' ? itemProps(data, nodeState) : itemProps;\n const { prefix: userPrefix, ...restUserProps } = resolvedItemProps ?? {};\n\n const composedPrefix =\n checkboxNode || userPrefix ? (\n <>\n {checkboxNode}\n {userPrefix}\n </>\n ) : null;\n\n return (\n <TreeNodeRow\n {...finalRowProps}\n ref={combinedRef}\n mods={rowMods}\n style={rowStyle}\n data-element=\"Row\"\n data-qa-key={String(node.key)}\n data-index={virtualIndex}\n >\n <TreeRowItem\n {...gridCellProps}\n {...restUserProps}\n size={size}\n isSelected={isSelected}\n isDisabled={isDisabled}\n mods={itemMods}\n icon={toggleNode}\n prefix={composedPrefix}\n styles={rowStyles}\n >\n {data.title}\n </TreeRowItem>\n </TreeNodeRow>\n );\n}\n\nexport const TreeNode = memo(TreeNodeInner);\n"],"mappings":"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"}
1
+ {"version":3,"file":"TreeNode.js","names":["Menu","mergeProps","Checkbox","MenuTrigger"],"sources":["../../../../src/components/content/Tree/TreeNode.tsx"],"sourcesContent":["import { Children, memo, useMemo, useRef, useState } from 'react';\nimport { useHover, useTreeItem } from 'react-aria';\n\nimport { useEvent } from '../../../_internal/hooks';\nimport { DirectionIcon, LoadingIcon, MoreIcon } from '../../../icons';\nimport { mergeProps, mergeRefs } from '../../../utils/react';\nimport { CubeItemActionProps, ItemAction } from '../../actions/ItemAction';\nimport { CubeMenuProps, Menu, MenuTrigger } from '../../actions/Menu';\nimport { useContextMenu } from '../../actions/use-context-menu';\nimport { Checkbox } from '../../fields/Checkbox/Checkbox';\n\nimport {\n TreeNodeCheckboxWrapper,\n TreeNodeRow,\n TreeNodeToggle,\n TreeNodeTogglePlaceholder,\n TreeRowItem,\n} from './styled';\n\nimport type { Key, Node } from '@react-types/shared';\nimport type { Styles } from '@tenphi/tasty';\nimport type {\n CSSProperties,\n KeyboardEvent,\n ReactNode,\n Ref,\n SyntheticEvent,\n} from 'react';\nimport type { TreeState } from 'react-stately';\nimport type {\n CubeTreeNodeData,\n TreeContextMenu,\n TreeItemProps,\n TreeNodeState,\n} from './types';\n\nconst stopPropagation = (e: SyntheticEvent) => {\n e.stopPropagation();\n};\n\n/** Check whether a `menu` ReactNode actually contains anything. */\nfunction isMenuEmpty(menu: ReactNode): boolean {\n if (menu === null || menu === undefined || menu === false) return true;\n return Children.toArray(menu).length === 0;\n}\n\nexport interface TreeNodeProps {\n node: Node<CubeTreeNodeData>;\n /** The original `CubeTreeNodeData` for this row, looked up by key. */\n data: CubeTreeNodeData;\n state: TreeState<CubeTreeNodeData>;\n\n /** Whether the tree as a whole renders checkboxes. */\n isCheckable: boolean;\n /** Whether this row is currently expanded. */\n isExpanded: boolean;\n /** Whether the row is in an indeterminate (half-checked) state. */\n isIndeterminate: boolean;\n /** Whether the row is fully checked. */\n isChecked: boolean;\n /** Whether `loadData` is currently fetching this row's children. */\n isLoading: boolean;\n\n /** Toggle this row's checkbox (cascades). */\n onToggleChecked: (key: string) => void;\n\n /** Row size passed to the underlying Item. */\n size?: string;\n\n /** Per-node Item customization (static object or callback). */\n itemProps?:\n | TreeItemProps\n | ((data: CubeTreeNodeData, state: TreeNodeState) => TreeItemProps);\n\n /** Styles applied to the visible row (`TreeRowItem`). */\n rowStyles?: Styles;\n\n /** Inline style for virtualizer absolute positioning. */\n virtualStyle?: CSSProperties;\n /** Ref callback from `@tanstack/react-virtual` to measure row height. */\n virtualRef?: (element: HTMLElement | null) => void;\n /** Virtual index for `data-index` attribute. */\n virtualIndex?: number;\n\n /** Tree-wide menu default (resolved against `data.menu`). */\n menu?:\n | ReactNode\n | ((data: CubeTreeNodeData, state: TreeNodeState) => ReactNode | null);\n /** Tree-wide `contextMenu` default. */\n contextMenu?: TreeContextMenu;\n /** Tree-wide `onAction` callback. */\n onAction?: (action: string, key: Key) => void;\n /** Forwarded to every per-row `MenuTrigger`. */\n menuTriggerProps?: Partial<CubeItemActionProps>;\n /** Forwarded to every per-row `Menu`. */\n menuProps?: Partial<CubeMenuProps<object>>;\n}\n\nfunction TreeNodeInner(props: TreeNodeProps) {\n const {\n node,\n data,\n state,\n isCheckable,\n isExpanded,\n isIndeterminate,\n isChecked,\n isLoading,\n onToggleChecked,\n size,\n itemProps,\n rowStyles,\n virtualStyle,\n virtualRef,\n virtualIndex,\n menu: treeMenu,\n contextMenu: treeContextMenu,\n onAction: treeOnAction,\n menuTriggerProps,\n menuProps,\n } = props;\n\n const rowRef = useRef<HTMLDivElement>(null);\n\n const { rowProps, gridCellProps, expandButtonProps, isPressed } = useTreeItem(\n { node },\n state,\n rowRef,\n );\n\n const isDisabled = state.disabledKeys.has(node.key);\n const isSelected = state.selectionManager.isSelected(node.key);\n\n // `useTreeItem` doesn't track hover; we need it for the `hovered` mod.\n const { hoverProps, isHovered } = useHover({ isDisabled });\n // React Aria's treegrid uses roving tabindex, so no `data-focused`\n // attribute lands on the row — mirror it as a mod manually.\n const isFocused =\n state.selectionManager.isFocused &&\n state.selectionManager.focusedKey === node.key;\n // For lazy rows with no children yet, still render a toggle unless\n // explicitly marked as leaf.\n const isLeaf =\n data.isLeaf === true || (data.isLeaf !== false && !node.hasChildNodes);\n const isRowCheckable = isCheckable && data.isCheckable !== false;\n\n const nodeState: TreeNodeState = {\n isExpanded,\n isSelected,\n isChecked,\n isIndeterminate,\n isLeaf,\n };\n\n // ---- Menu resolution (per-node override > tree-level) --------------------\n\n const effectiveMenuChildren: ReactNode =\n data.menu === null\n ? null\n : data.menu !== undefined\n ? data.menu\n : typeof treeMenu === 'function'\n ? treeMenu(data, nodeState)\n : treeMenu ?? null;\n const hasMenu = !isMenuEmpty(effectiveMenuChildren);\n\n const effectiveContextMenu: TreeContextMenu =\n data.contextMenu ?? treeContextMenu ?? false;\n // The menu is exposed only when the consumer opts in via\n // `contextMenu`. When `contextMenu` is `false` (default) we render\n // nothing, even if `menu` is provided — this matches the plan and\n // keeps default rows visually clean.\n const menuExposed =\n hasMenu &&\n (effectiveContextMenu === true || effectiveContextMenu === 'context-only');\n const contextMenuOnly = effectiveContextMenu === 'context-only';\n\n // Controlled state for menu trigger (enables keyboard opening with Shift+F10)\n const [isMenuOpen, setIsMenuOpen] = useState(false);\n\n const handleMenuAction = useEvent((action: Key) => {\n // Strip the \".$\" prefix that React adds via Children.toArray/map.\n const actionStr = String(action);\n const normalizedAction = actionStr.startsWith('.$')\n ? actionStr.slice(2)\n : actionStr;\n data.onAction?.(normalizedAction);\n treeOnAction?.(normalizedAction, node.key);\n // Forward to the consumer-supplied `menuProps.onAction` so users\n // who pass extra `Menu` props through `menuProps` still receive\n // the action stream alongside the tree-level callback.\n menuProps?.onAction?.(normalizedAction);\n });\n\n const rowContextMenu = useContextMenu<HTMLDivElement, CubeMenuProps<object>>(\n Menu,\n { placement: 'bottom start' },\n {\n ...menuProps,\n onAction: handleMenuAction,\n children: effectiveMenuChildren,\n },\n );\n\n // ---- Checkbox ------------------------------------------------------------\n\n const handleCheckboxChange = useEvent(() => {\n onToggleChecked(String(node.key));\n });\n\n // ---- Keyboard ------------------------------------------------------------\n\n // Composed keydown handler. Runs BEFORE `rowProps.onKeyDown` from\n // `useTreeItem` so we can short-circuit the default react-aria\n // behavior for our own shortcuts (Shift+F10 menu open, Space\n // checkbox toggle). Returns `true` when the event was handled and\n // react-aria's keydown must NOT run; returns `false` to chain to\n // react-aria's handler.\n const handleKeyDown = useEvent((e: KeyboardEvent) => {\n // Space toggles the checkbox first when checkable. We DON'T claim\n // the event (return `false`) so react-aria's onKeyDown still runs\n // afterwards and the focused row also selects — matching the\n // pre-refactor behavior when handlers were chained via\n // `mergeProps`. `preventDefault` is kept to suppress page scroll.\n if (\n e.key === ' ' &&\n isRowCheckable &&\n !isDisabled &&\n !data.isCheckboxDisabled\n ) {\n e.preventDefault();\n onToggleChecked(String(node.key));\n return false;\n }\n\n // Shift+F10 opens the row menu (standard accessibility shortcut).\n if (e.key === 'F10' && e.shiftKey && menuExposed) {\n e.preventDefault();\n e.stopPropagation();\n if (contextMenuOnly) {\n rowContextMenu.open();\n } else {\n setIsMenuOpen(true);\n }\n return true;\n }\n\n return false;\n });\n\n // Wrapper that delegates to react-aria's default keydown only when\n // our handler did not claim the event. Replaces (rather than\n // chains with) `rowProps.onKeyDown` so the order of handlers is\n // strictly: our shortcuts → react-aria default.\n const composedKeyDown = useEvent((e: KeyboardEvent<HTMLDivElement>) => {\n if (handleKeyDown(e)) return;\n rowProps.onKeyDown?.(e as unknown as globalThis.KeyboardEvent);\n });\n\n // ---- Mods ----------------------------------------------------------------\n\n const sharedMods = useMemo(\n () => ({\n checked: isChecked,\n indeterminate: isIndeterminate,\n expanded: isExpanded,\n loading: isLoading,\n leaf: isLeaf,\n 'has-checkbox': isRowCheckable,\n 'has-menu': menuExposed,\n }),\n [\n isChecked,\n isIndeterminate,\n isExpanded,\n isLoading,\n isLeaf,\n isRowCheckable,\n menuExposed,\n ],\n );\n\n const rowMods = useMemo(\n () => ({ ...sharedMods, disabled: isDisabled }),\n [sharedMods, isDisabled],\n );\n\n const itemMods = useMemo(\n () => ({\n ...sharedMods,\n focused: isFocused,\n hovered: isHovered,\n pressed: isPressed,\n }),\n [sharedMods, isFocused, isHovered, isPressed],\n );\n\n const rowStyle = useMemo<CSSProperties>(\n () => ({\n ['--tree-level' as keyof CSSProperties]: String(node.level ?? 0),\n ...virtualStyle,\n }),\n [node.level, virtualStyle],\n );\n\n // Only emit `aria-checked` when the tree is in checkable mode.\n const ariaChecked: 'mixed' | 'true' | 'false' | undefined = isRowCheckable\n ? isIndeterminate\n ? 'mixed'\n : isChecked\n ? 'true'\n : 'false'\n : undefined;\n\n // ---- Compose row props ---------------------------------------------------\n\n // Merge react-aria + hover props but EXCLUDE `onKeyDown` from the\n // chain — `composedKeyDown` already wraps `rowProps.onKeyDown` and\n // must run first so our Shift+F10 / Space-checkbox shortcuts can\n // short-circuit the default react-aria behavior.\n const finalRowProps = {\n ...mergeProps(rowProps, hoverProps),\n 'aria-checked': ariaChecked,\n onKeyDown: composedKeyDown,\n };\n\n // ---- Toggle (chevron) and checkbox slots --------------------------------\n\n // Leaf rows get a placeholder so sibling indents align.\n const toggleNode = isLeaf ? (\n <TreeNodeTogglePlaceholder aria-hidden data-element=\"Toggle\" />\n ) : (\n <TreeNodeToggle {...expandButtonProps} tabIndex={-1} data-element=\"Toggle\">\n {isLoading ? (\n <LoadingIcon />\n ) : (\n <DirectionIcon to={isExpanded ? 'bottom' : 'right'} />\n )}\n </TreeNodeToggle>\n );\n\n const checkboxNode = isRowCheckable ? (\n <TreeNodeCheckboxWrapper\n data-element=\"Checkbox\"\n role=\"presentation\"\n onClick={stopPropagation}\n onKeyDown={stopPropagation}\n >\n <Checkbox\n isSelected={isChecked}\n isIndeterminate={isIndeterminate}\n isDisabled={isDisabled || data.isCheckboxDisabled}\n aria-label={\n typeof data.title === 'string' ? data.title : String(node.key)\n }\n // @ts-expect-error AriaCheckboxProps loses `onChange` where InputDOMProps overlaps (react-types).\n onChange={handleCheckboxChange}\n />\n </TreeNodeCheckboxWrapper>\n ) : null;\n\n // ---- Resolve user-supplied per-node Item props --------------------------\n\n const resolvedItemProps =\n typeof itemProps === 'function' ? itemProps(data, nodeState) : itemProps;\n const {\n prefix: userPrefix,\n actions: userActions,\n ...restUserProps\n } = resolvedItemProps ?? {};\n\n const composedPrefix =\n checkboxNode || userPrefix ? (\n <>\n {checkboxNode}\n {userPrefix}\n </>\n ) : null;\n\n // ---- Built-in overflow `⋮` action ---------------------------------------\n\n const menuAction =\n menuExposed && !contextMenuOnly ? (\n <MenuTrigger isOpen={isMenuOpen} onOpenChange={setIsMenuOpen}>\n <ItemAction\n tabIndex={-1}\n icon={<MoreIcon />}\n aria-label=\"Actions\"\n {...menuTriggerProps}\n />\n <Menu {...menuProps} onAction={handleMenuAction}>\n {effectiveMenuChildren}\n </Menu>\n </MenuTrigger>\n ) : null;\n\n // Compose with user-supplied actions (user actions render first).\n const composedActions =\n userActions || menuAction ? (\n <>\n {userActions}\n {menuAction}\n </>\n ) : undefined;\n\n // ---- Refs / context-menu wiring -----------------------------------------\n\n // When the context menu is enabled for this row, attach the hook's\n // `targetRef` to the row so right-clicks land on the correct anchor.\n const refs = useMemo(() => {\n const list: Ref<HTMLDivElement>[] = [rowRef];\n if (virtualRef) list.push(virtualRef);\n if (menuExposed) list.push(rowContextMenu.targetRef);\n return mergeRefs(...list);\n }, [virtualRef, menuExposed, rowContextMenu.targetRef]);\n\n return (\n <TreeNodeRow\n {...finalRowProps}\n ref={refs}\n mods={rowMods}\n style={rowStyle}\n data-element=\"Row\"\n data-qa-key={String(node.key)}\n data-index={virtualIndex}\n >\n <TreeRowItem\n {...gridCellProps}\n {...restUserProps}\n size={size}\n isSelected={isSelected}\n isDisabled={isDisabled}\n mods={itemMods}\n icon={toggleNode}\n prefix={composedPrefix}\n actions={composedActions}\n styles={rowStyles}\n >\n {data.title}\n </TreeRowItem>\n {menuExposed && rowContextMenu.rendered}\n </TreeNodeRow>\n );\n}\n\nexport const TreeNode = memo(TreeNodeInner);\n"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
1
 
2
- import { CubeTreeNodeData, CubeTreeProps, TreeLoadDataNode, TreeOnCheckInfo, TreeOnExpandInfo, TreeOnSelectInfo, TreeSelectionMode } from "./types.js";
2
+ import { CubeTreeNodeData, CubeTreeProps, TreeContextMenu, TreeLoadDataNode, TreeNodeState, TreeOnCheckInfo, TreeOnExpandInfo, TreeOnSelectInfo, TreeSelectionMode } from "./types.js";
3
3
  import { Tree } from "./Tree.js";