@cube-dev/ui-kit 0.144.0 → 0.145.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (464) hide show
  1. package/README.md +1 -1
  2. package/dist/CHANGELOG.md +19 -0
  3. package/dist/README.md +1 -1
  4. package/dist/_internal/hooks/use-chained-callback.js +1 -1
  5. package/dist/_internal/hooks/use-debounced-value.js +1 -1
  6. package/dist/_internal/hooks/use-deprecation-warning.js +1 -1
  7. package/dist/_internal/hooks/use-event.js +1 -1
  8. package/dist/_internal/hooks/use-is-first-render.js +1 -1
  9. package/dist/_internal/hooks/use-sync-ref.js +1 -1
  10. package/dist/_internal/hooks/use-timer/timer.js +1 -1
  11. package/dist/_internal/hooks/use-timer/use-timer.js +1 -1
  12. package/dist/_internal/hooks/use-warn.js +1 -1
  13. package/dist/components/Block.js +1 -1
  14. package/dist/components/CollectionItem.js +1 -1
  15. package/dist/components/GlobalStyles.js +1 -1
  16. package/dist/components/GridProvider.js +1 -1
  17. package/dist/components/HiddenInput.js +1 -1
  18. package/dist/components/Root.js +1 -1
  19. package/dist/components/actions/Action/Action.js +1 -1
  20. package/dist/components/actions/Banner/Banner.js +1 -1
  21. package/dist/components/actions/Button/Button.d.ts +0 -1
  22. package/dist/components/actions/Button/Button.js +1 -1
  23. package/dist/components/actions/ButtonGroup/ButtonGroup.js +1 -1
  24. package/dist/components/actions/ButtonSplit/ButtonSplit.js +1 -1
  25. package/dist/components/actions/ButtonSplit/context.js +1 -1
  26. package/dist/components/actions/CommandMenu/CommandMenu.js +1 -1
  27. package/dist/components/actions/CommandMenu/styled.js +1 -1
  28. package/dist/components/actions/ItemAction/ItemAction.js +1 -1
  29. package/dist/components/actions/ItemActionContext.js +1 -1
  30. package/dist/components/actions/ItemButton/ItemButton.js +1 -1
  31. package/dist/components/actions/Link/Link.js +1 -1
  32. package/dist/components/actions/Menu/Menu.js +1 -1
  33. package/dist/components/actions/Menu/MenuItem.js +1 -1
  34. package/dist/components/actions/Menu/MenuSection.js +1 -1
  35. package/dist/components/actions/Menu/MenuTrigger.js +1 -1
  36. package/dist/components/actions/Menu/SubMenuTrigger.js +1 -1
  37. package/dist/components/actions/Menu/SubmenuTriggerContext.js +1 -1
  38. package/dist/components/actions/Menu/context.js +1 -1
  39. package/dist/components/actions/Menu/styled.js +1 -1
  40. package/dist/components/actions/index.js +1 -1
  41. package/dist/components/actions/use-action.js +1 -1
  42. package/dist/components/actions/use-anchored-menu.js +1 -1
  43. package/dist/components/actions/use-context-menu.js +1 -1
  44. package/dist/components/content/ActiveZone/ActiveZone.js +1 -1
  45. package/dist/components/content/Alert/Alert.js +1 -1
  46. package/dist/components/content/Alert/use-alert.js +1 -1
  47. package/dist/components/content/Avatar/Avatar.js +1 -1
  48. package/dist/components/content/Badge/Badge.js +1 -1
  49. package/dist/components/content/Card/Card.js +1 -1
  50. package/dist/components/content/Content.js +1 -1
  51. package/dist/components/content/CopyPasteBlock/CopyPasteBlock.js +1 -1
  52. package/dist/components/content/CopySnippet/CopySnippet.js +1 -1
  53. package/dist/components/content/Disclosure/Disclosure.js +1 -1
  54. package/dist/components/content/Divider.js +1 -1
  55. package/dist/components/content/Footer.js +1 -1
  56. package/dist/components/content/Header.js +1 -1
  57. package/dist/components/content/HotKeys/HotKeys.js +1 -1
  58. package/dist/components/content/InlineInput/InlineInput.js +1 -1
  59. package/dist/components/content/Item/Item.js +1 -1
  60. package/dist/components/content/ItemBadge/ItemBadge.js +1 -1
  61. package/dist/components/content/ItemCard/ItemCard.js +1 -1
  62. package/dist/components/content/Layout/GridLayout.js +1 -1
  63. package/dist/components/content/Layout/Layout.js +1 -1
  64. package/dist/components/content/Layout/LayoutBlock.js +1 -1
  65. package/dist/components/content/Layout/LayoutCenter.js +1 -1
  66. package/dist/components/content/Layout/LayoutContainer.js +1 -1
  67. package/dist/components/content/Layout/LayoutContent.js +1 -1
  68. package/dist/components/content/Layout/LayoutContext.js +1 -1
  69. package/dist/components/content/Layout/LayoutFlex.js +1 -1
  70. package/dist/components/content/Layout/LayoutFooter.js +1 -1
  71. package/dist/components/content/Layout/LayoutGrid.js +1 -1
  72. package/dist/components/content/Layout/LayoutHeader.js +1 -1
  73. package/dist/components/content/Layout/LayoutPane.js +1 -1
  74. package/dist/components/content/Layout/LayoutPanel.js +1 -1
  75. package/dist/components/content/Layout/LayoutPanelHeader.js +1 -1
  76. package/dist/components/content/Layout/LayoutToolbar.js +1 -1
  77. package/dist/components/content/Layout/hooks/useTinyScrollbar.js +1 -1
  78. package/dist/components/content/Layout/index.js +1 -1
  79. package/dist/components/content/Layout/utils.js +1 -1
  80. package/dist/components/content/Paragraph.js +1 -1
  81. package/dist/components/content/Placeholder/Placeholder.js +1 -1
  82. package/dist/components/content/PrismCode/PrismCode.js +1 -1
  83. package/dist/components/content/PrismCode/prismSetup.js +1 -1
  84. package/dist/components/content/PrismDiffCode/PrismDiffCode.js +1 -1
  85. package/dist/components/content/Result/Result.js +1 -1
  86. package/dist/components/content/Skeleton/Skeleton.js +1 -1
  87. package/dist/components/content/Tag/Tag.js +1 -1
  88. package/dist/components/content/Text.js +1 -1
  89. package/dist/components/content/TextItem/TextItem.js +1 -1
  90. package/dist/components/content/Title.js +1 -1
  91. package/dist/components/content/Tree/Tree.js +1 -1
  92. package/dist/components/content/Tree/TreeNode.js +1 -1
  93. package/dist/components/content/Tree/styled.js +1 -1
  94. package/dist/components/content/Tree/tree-index.js +1 -1
  95. package/dist/components/content/Tree/use-checkbox-tree.js +1 -1
  96. package/dist/components/content/Tree/use-load-data.js +1 -1
  97. package/dist/components/content/highlightText.js +1 -1
  98. package/dist/components/content/use-auto-tooltip.js +1 -1
  99. package/dist/components/fields/Checkbox/Checkbox.js +1 -1
  100. package/dist/components/fields/Checkbox/CheckboxGroup.js +1 -1
  101. package/dist/components/fields/Checkbox/context.js +1 -1
  102. package/dist/components/fields/ComboBox/ComboBox.js +1 -1
  103. package/dist/components/fields/CommandTextArea/CommandTextArea.js +1 -1
  104. package/dist/components/fields/CommandTextArea/caretPosition.js +1 -1
  105. package/dist/components/fields/CommandTextArea/useCaretAnchor.js +1 -1
  106. package/dist/components/fields/DatePicker/DateInput.js +1 -1
  107. package/dist/components/fields/DatePicker/DateInputBase.js +1 -1
  108. package/dist/components/fields/DatePicker/DatePicker.js +1 -1
  109. package/dist/components/fields/DatePicker/DatePickerButton.js +1 -1
  110. package/dist/components/fields/DatePicker/DatePickerElement.js +1 -1
  111. package/dist/components/fields/DatePicker/DatePickerInput.js +1 -1
  112. package/dist/components/fields/DatePicker/DatePickerSegment.js +1 -1
  113. package/dist/components/fields/DatePicker/DateRangePicker.js +1 -1
  114. package/dist/components/fields/DatePicker/DateRangeSeparatedPicker.js +1 -1
  115. package/dist/components/fields/DatePicker/TimeInput.js +1 -1
  116. package/dist/components/fields/DatePicker/intl.js +1 -1
  117. package/dist/components/fields/DatePicker/parseDate.js +1 -1
  118. package/dist/components/fields/DatePicker/props.js +1 -1
  119. package/dist/components/fields/DatePicker/utils.js +1 -1
  120. package/dist/components/fields/FileInput/FileInput.js +1 -1
  121. package/dist/components/fields/FilterListBox/FilterListBox.js +1 -1
  122. package/dist/components/fields/FilterPicker/FilterPicker.js +1 -1
  123. package/dist/components/fields/Input/Input.js +1 -1
  124. package/dist/components/fields/ListBox/DraggableListBox.js +1 -1
  125. package/dist/components/fields/ListBox/ListBox.js +1 -1
  126. package/dist/components/fields/ListBoxPopover/ListBoxPopover.js +1 -1
  127. package/dist/components/fields/ListBoxPopover/index.d.ts +0 -1
  128. package/dist/components/fields/ListBoxPopover/listNavigation.js +1 -1
  129. package/dist/components/fields/ListBoxPopover/useCompositeFocus.js +1 -1
  130. package/dist/components/fields/NumberInput/NumberInput.js +1 -1
  131. package/dist/components/fields/NumberInput/StepButton.js +1 -1
  132. package/dist/components/fields/PasswordInput/PasswordInput.js +1 -1
  133. package/dist/components/fields/Picker/Picker.js +1 -1
  134. package/dist/components/fields/RadioGroup/Radio.js +1 -1
  135. package/dist/components/fields/RadioGroup/RadioGroup.js +1 -1
  136. package/dist/components/fields/RadioGroup/context.js +1 -1
  137. package/dist/components/fields/SearchInput/SearchInput.js +1 -1
  138. package/dist/components/fields/Select/Select.js +1 -1
  139. package/dist/components/fields/Slider/Gradation.js +1 -1
  140. package/dist/components/fields/Slider/HueSlider.js +1 -1
  141. package/dist/components/fields/Slider/RangeSlider.js +1 -1
  142. package/dist/components/fields/Slider/Slider.js +1 -1
  143. package/dist/components/fields/Slider/SliderBase.js +1 -1
  144. package/dist/components/fields/Slider/SliderThumb.js +1 -1
  145. package/dist/components/fields/Slider/SliderTrack.js +1 -1
  146. package/dist/components/fields/Slider/elements.js +1 -1
  147. package/dist/components/fields/Slider/index.js +1 -1
  148. package/dist/components/fields/Switch/Switch.js +1 -1
  149. package/dist/components/fields/TextArea/TextArea.js +1 -1
  150. package/dist/components/fields/TextInput/TextInput.js +1 -1
  151. package/dist/components/fields/TextInput/TextInputBase.js +1 -1
  152. package/dist/components/fields/TextInputMapper/TextInputMapper.js +1 -1
  153. package/dist/components/form/FieldWrapper/FieldWrapper.js +1 -1
  154. package/dist/components/form/FieldWrapper/extract-field-wrapper-props.js +1 -1
  155. package/dist/components/form/Form/Field.js +1 -1
  156. package/dist/components/form/Form/Form.js +1 -1
  157. package/dist/components/form/Form/ResetButton/ResetButton.js +1 -1
  158. package/dist/components/form/Form/SubmitButton/SubmitButton.js +1 -1
  159. package/dist/components/form/Form/SubmitError.js +1 -1
  160. package/dist/components/form/Form/index.js +1 -1
  161. package/dist/components/form/Form/use-field/use-field-props.js +1 -1
  162. package/dist/components/form/Form/use-field/use-field.js +1 -1
  163. package/dist/components/form/Form/use-form.js +1 -1
  164. package/dist/components/form/Form/validation.js +1 -1
  165. package/dist/components/form/Label.js +1 -1
  166. package/dist/components/form/wrapper.js +1 -1
  167. package/dist/components/helpers/DisplayTransition/DisplayTransition.js +1 -1
  168. package/dist/components/helpers/IconSwitch/IconSwitch.js +1 -1
  169. package/dist/components/layout/Board/Board.d.ts +24 -5
  170. package/dist/components/layout/Board/Board.js +84 -61
  171. package/dist/components/layout/Board/Board.js.map +1 -1
  172. package/dist/components/layout/Board/BoardProvider.js +1 -1
  173. package/dist/components/layout/Board/BoardResponsive.js +1 -1
  174. package/dist/components/layout/Board/Widget.d.ts +23 -3
  175. package/dist/components/layout/Board/Widget.js +28 -2
  176. package/dist/components/layout/Board/Widget.js.map +1 -1
  177. package/dist/components/layout/Board/WidgetHost.js +22 -13
  178. package/dist/components/layout/Board/WidgetHost.js.map +1 -1
  179. package/dist/components/layout/Board/board-context.js +12 -2
  180. package/dist/components/layout/Board/board-context.js.map +1 -1
  181. package/dist/components/layout/Board/board-store.js +2 -2
  182. package/dist/components/layout/Board/board-store.js.map +1 -1
  183. package/dist/components/layout/Board/grid-core/calculate.js +2 -2
  184. package/dist/components/layout/Board/grid-core/collision.js +1 -1
  185. package/dist/components/layout/Board/grid-core/compactors.js +1 -1
  186. package/dist/components/layout/Board/grid-core/constraints.js +1 -1
  187. package/dist/components/layout/Board/grid-core/layout.js +1 -1
  188. package/dist/components/layout/Board/grid-core/sort.js +1 -1
  189. package/dist/components/layout/Board/index.d.ts +1 -1
  190. package/dist/components/layout/Board/index.js +1 -1
  191. package/dist/components/layout/Board/responsive-utils.js +1 -1
  192. package/dist/components/layout/Board/use-board-layout.js +1 -1
  193. package/dist/components/layout/Board/use-board-registry.js +3 -2
  194. package/dist/components/layout/Board/use-board-registry.js.map +1 -1
  195. package/dist/components/layout/Flex.js +1 -1
  196. package/dist/components/layout/Flow.js +1 -1
  197. package/dist/components/layout/Grid.js +1 -1
  198. package/dist/components/layout/Panel.js +1 -1
  199. package/dist/components/layout/Prefix.js +1 -1
  200. package/dist/components/layout/ResizablePanel.js +1 -1
  201. package/dist/components/layout/Space.js +1 -1
  202. package/dist/components/layout/Suffix.js +1 -1
  203. package/dist/components/navigation/Tabs/DraggableTabList.js +1 -1
  204. package/dist/components/navigation/Tabs/TabButton.js +1 -1
  205. package/dist/components/navigation/Tabs/TabDropIndicator.js +1 -1
  206. package/dist/components/navigation/Tabs/TabPanel.js +1 -1
  207. package/dist/components/navigation/Tabs/TabPicker.js +1 -1
  208. package/dist/components/navigation/Tabs/Tabs.js +1 -1
  209. package/dist/components/navigation/Tabs/TabsAction.js +1 -1
  210. package/dist/components/navigation/Tabs/TabsContext.js +1 -1
  211. package/dist/components/navigation/Tabs/popover-placement.js +1 -1
  212. package/dist/components/navigation/Tabs/styled.js +1 -1
  213. package/dist/components/navigation/Tabs/types.js +1 -1
  214. package/dist/components/navigation/Tabs/use-tab-editing.js +1 -1
  215. package/dist/components/navigation/Tabs/use-tab-indicator.js +1 -1
  216. package/dist/components/organisms/FileTabs/FileTabs.js +1 -1
  217. package/dist/components/organisms/StatsCard/StatsCard.js +1 -1
  218. package/dist/components/other/Calendar/Calendar.js +1 -1
  219. package/dist/components/other/Calendar/CalendarCell.js +1 -1
  220. package/dist/components/other/Calendar/CalendarGrid.js +1 -1
  221. package/dist/components/other/Calendar/RangeCalendar.js +1 -1
  222. package/dist/components/other/CloudLogo/CloudLogo.js +1 -1
  223. package/dist/components/overlays/AlertDialog/AlertDialog.js +1 -1
  224. package/dist/components/overlays/AlertDialog/AlertDialogApiProvider.js +1 -1
  225. package/dist/components/overlays/AlertDialog/AlertDialogZone.js +1 -1
  226. package/dist/components/overlays/Dialog/Dialog.js +1 -1
  227. package/dist/components/overlays/Dialog/DialogContainer.js +1 -1
  228. package/dist/components/overlays/Dialog/DialogForm.js +1 -1
  229. package/dist/components/overlays/Dialog/DialogTrigger.js +1 -1
  230. package/dist/components/overlays/Dialog/context.js +1 -1
  231. package/dist/components/overlays/Dialog/use-dialog-container.js +1 -1
  232. package/dist/components/overlays/Modal/Modal.d.ts +1 -2
  233. package/dist/components/overlays/Modal/Modal.js +1 -1
  234. package/dist/components/overlays/Modal/OpenTransitionContext.js +1 -1
  235. package/dist/components/overlays/Modal/Overlay.d.ts +0 -1
  236. package/dist/components/overlays/Modal/Overlay.js +1 -1
  237. package/dist/components/overlays/Modal/Popover.js +1 -1
  238. package/dist/components/overlays/Modal/Tray.js +1 -1
  239. package/dist/components/overlays/Modal/Underlay.js +1 -1
  240. package/dist/components/overlays/Modal/types.d.ts +0 -1
  241. package/dist/components/overlays/Notifications/Notification.js +1 -1
  242. package/dist/components/overlays/Notifications/NotificationAction.js +1 -1
  243. package/dist/components/overlays/Notifications/NotificationCard.js +1 -1
  244. package/dist/components/overlays/Notifications/NotificationContext.d.ts +0 -2
  245. package/dist/components/overlays/Notifications/NotificationContext.js +1 -1
  246. package/dist/components/overlays/Notifications/NotificationItem.js +1 -1
  247. package/dist/components/overlays/Notifications/OverlayContainer.js +1 -1
  248. package/dist/components/overlays/Notifications/OverlayProvider.js +1 -1
  249. package/dist/components/overlays/Notifications/PersistentNotificationsList.js +1 -1
  250. package/dist/components/overlays/Notifications/dismissed-storage.js +1 -1
  251. package/dist/components/overlays/Notifications/format-relative-time.js +1 -1
  252. package/dist/components/overlays/Notifications/index.js +1 -1
  253. package/dist/components/overlays/Notifications/use-notification-state.js +1 -1
  254. package/dist/components/overlays/Notifications/use-notifications.js +1 -1
  255. package/dist/components/overlays/Notifications/use-overlay-timers.js +1 -1
  256. package/dist/components/overlays/Notifications/use-persistent-notifications.js +1 -1
  257. package/dist/components/overlays/Notifications/use-persistent-state.js +1 -1
  258. package/dist/components/overlays/Notifications/use-toast-state.js +1 -1
  259. package/dist/components/overlays/Toast/ToastItem.js +1 -1
  260. package/dist/components/overlays/Toast/index.js +1 -1
  261. package/dist/components/overlays/Toast/useProgressToast.js +1 -1
  262. package/dist/components/overlays/Toast/useToast.js +1 -1
  263. package/dist/components/overlays/Tooltip/Tooltip.js +1 -1
  264. package/dist/components/overlays/Tooltip/TooltipProvider.js +1 -1
  265. package/dist/components/overlays/Tooltip/TooltipTrigger.js +1 -1
  266. package/dist/components/overlays/Tooltip/context.js +1 -1
  267. package/dist/components/portal/Portal.js +1 -1
  268. package/dist/components/portal/PortalProvider.js +1 -1
  269. package/dist/components/portal/index.d.ts +0 -1
  270. package/dist/components/portal/usePortal.js +1 -1
  271. package/dist/components/shared/DraggableCollection.js +1 -1
  272. package/dist/components/shared/InvalidIcon.js +1 -1
  273. package/dist/components/shared/ValidIcon.js +1 -1
  274. package/dist/components/status/LoadingAnimation/LoadingAnimation.js +1 -1
  275. package/dist/components/status/Spin/Cube.js +1 -1
  276. package/dist/components/status/Spin/InternalSpinner.js +1 -1
  277. package/dist/components/status/Spin/Spin.js +1 -1
  278. package/dist/components/status/Spin/SpinsContainer.js +1 -1
  279. package/dist/data/item-themes.js +1 -1
  280. package/dist/data/themes.js +1 -1
  281. package/dist/icons/AdjustmentsHorizontalIcon.js +1 -1
  282. package/dist/icons/AdjustmentsIcon.js +1 -1
  283. package/dist/icons/AiIcon.js +1 -1
  284. package/dist/icons/AreaChartIcon.js +1 -1
  285. package/dist/icons/BackwardIcon.js +1 -1
  286. package/dist/icons/BarChartIcon.js +1 -1
  287. package/dist/icons/BellFilledIcon.js +1 -1
  288. package/dist/icons/BellIcon.js +1 -1
  289. package/dist/icons/BooleanIcon.js +1 -1
  290. package/dist/icons/CalendarEditIcon.js +1 -1
  291. package/dist/icons/CalendarIcon.js +1 -1
  292. package/dist/icons/CaretDownIcon.js +1 -1
  293. package/dist/icons/CaretUpIcon.js +1 -1
  294. package/dist/icons/ChartAreaStackedIcon.js +1 -1
  295. package/dist/icons/ChartAreaStackedPercentageIcon.js +1 -1
  296. package/dist/icons/ChartBarGroupedHorizontalIcon.js +1 -1
  297. package/dist/icons/ChartBarGroupedIcon.js +1 -1
  298. package/dist/icons/ChartBarHorizontalIcon.js +1 -1
  299. package/dist/icons/ChartBarLineIcon.js +1 -1
  300. package/dist/icons/ChartBarStackedHorizontalIcon.js +1 -1
  301. package/dist/icons/ChartBarStackedIcon.js +1 -1
  302. package/dist/icons/ChartBarStackedPercentageHorizontalIcon.js +1 -1
  303. package/dist/icons/ChartBarStackedPercentageIcon.js +1 -1
  304. package/dist/icons/ChartBoxPlot2Icon.js +1 -1
  305. package/dist/icons/ChartBoxPlotIcon.js +1 -1
  306. package/dist/icons/ChartBubbleIcon.js +1 -1
  307. package/dist/icons/ChartDonut2Icon.js +1 -1
  308. package/dist/icons/ChartFunnelIcon.js +1 -1
  309. package/dist/icons/ChartHeatmapIcon.js +1 -1
  310. package/dist/icons/ChartKPIIcon.js +1 -1
  311. package/dist/icons/ChartPie2Icon.js +1 -1
  312. package/dist/icons/ChartScatterIcon.js +1 -1
  313. package/dist/icons/CheckCircleFilledIcon.js +1 -1
  314. package/dist/icons/CheckCircleIcon.js +1 -1
  315. package/dist/icons/CheckIcon.js +1 -1
  316. package/dist/icons/CircleFilledIcon.js +1 -1
  317. package/dist/icons/ClearIcon.js +1 -1
  318. package/dist/icons/CloseCircleFilledIcon.js +1 -1
  319. package/dist/icons/CloseCircleIcon.js +1 -1
  320. package/dist/icons/CloseIcon.js +1 -1
  321. package/dist/icons/CodeIcon.js +1 -1
  322. package/dist/icons/ColumnTotalIcon.js +1 -1
  323. package/dist/icons/CopyIcon.js +1 -1
  324. package/dist/icons/CountIcon.js +1 -1
  325. package/dist/icons/CubeIcon.js +1 -1
  326. package/dist/icons/CubePauseIcon.js +1 -1
  327. package/dist/icons/CubePlayIcon.js +1 -1
  328. package/dist/icons/CurrencyDollarIcon.js +1 -1
  329. package/dist/icons/DangerIcon.js +1 -1
  330. package/dist/icons/DashboardIcon.js +1 -1
  331. package/dist/icons/DatabaseIcon.js +1 -1
  332. package/dist/icons/DecimalDecreaseIcon.js +1 -1
  333. package/dist/icons/DecimalIncreaseIcon.js +1 -1
  334. package/dist/icons/DirectionIcon.js +1 -1
  335. package/dist/icons/DonutIcon.js +1 -1
  336. package/dist/icons/DownIcon.js +1 -1
  337. package/dist/icons/EditIcon.js +1 -1
  338. package/dist/icons/ExclamationCircleFilledIcon.js +1 -1
  339. package/dist/icons/ExclamationCircleIcon.js +1 -1
  340. package/dist/icons/ExclamationIcon.js +1 -1
  341. package/dist/icons/EyeIcon.js +1 -1
  342. package/dist/icons/EyeInvisibleIcon.js +1 -1
  343. package/dist/icons/FilterIcon.js +1 -1
  344. package/dist/icons/FolderFilledIcon.js +1 -1
  345. package/dist/icons/FolderIcon.js +1 -1
  346. package/dist/icons/FolderOpenFilledIcon.js +1 -1
  347. package/dist/icons/FolderOpenIcon.js +1 -1
  348. package/dist/icons/ForwardIcon.js +1 -1
  349. package/dist/icons/GripVerticalIcon.js +1 -1
  350. package/dist/icons/HierarchyIcon.js +1 -1
  351. package/dist/icons/HierarchyOpenIcon.js +1 -1
  352. package/dist/icons/Icon.js +1 -1
  353. package/dist/icons/InfoCircleIcon.js +1 -1
  354. package/dist/icons/InfoIcon.js +1 -1
  355. package/dist/icons/KeyIcon.js +1 -1
  356. package/dist/icons/LeftIcon.js +1 -1
  357. package/dist/icons/LineChartIcon.js +1 -1
  358. package/dist/icons/LoadingIcon.js +1 -1
  359. package/dist/icons/LockFilledIcon.js +1 -1
  360. package/dist/icons/LockIcon.js +1 -1
  361. package/dist/icons/MoreIcon.js +1 -1
  362. package/dist/icons/NotAllowedIcon.js +1 -1
  363. package/dist/icons/Number123Icon.js +1 -1
  364. package/dist/icons/NumberIcon.js +1 -1
  365. package/dist/icons/PauseCircleFilledIcon.js +1 -1
  366. package/dist/icons/PauseCircleIcon.js +1 -1
  367. package/dist/icons/PauseIcon.js +1 -1
  368. package/dist/icons/PercentageIcon.js +1 -1
  369. package/dist/icons/PieChartIcon.js +1 -1
  370. package/dist/icons/PlayCircleIcon.js +1 -1
  371. package/dist/icons/PlayIcon.js +1 -1
  372. package/dist/icons/PlusIcon.js +1 -1
  373. package/dist/icons/ProgressBarIcon.js +1 -1
  374. package/dist/icons/ReloadIcon.js +1 -1
  375. package/dist/icons/ReportIcon.js +1 -1
  376. package/dist/icons/ReturnIcon.js +1 -1
  377. package/dist/icons/RightIcon.js +1 -1
  378. package/dist/icons/RowTotalsIcon.js +1 -1
  379. package/dist/icons/SchemeIcon.js +1 -1
  380. package/dist/icons/SearchIcon.js +1 -1
  381. package/dist/icons/SemanticQueryIcon.js +1 -1
  382. package/dist/icons/SettingsIcon.js +1 -1
  383. package/dist/icons/ShieldFilledIcon.js +1 -1
  384. package/dist/icons/ShieldIcon.js +1 -1
  385. package/dist/icons/SlashIcon.js +1 -1
  386. package/dist/icons/SparklesIcon.js +1 -1
  387. package/dist/icons/SqlIcon.js +1 -1
  388. package/dist/icons/StatsIcon.js +1 -1
  389. package/dist/icons/StopIcon.js +1 -1
  390. package/dist/icons/StringIcon.js +1 -1
  391. package/dist/icons/SubtotalsIcon.js +1 -1
  392. package/dist/icons/SwitchIcon.js +1 -1
  393. package/dist/icons/TableIcon.js +1 -1
  394. package/dist/icons/ThumbsDownIcon.js +1 -1
  395. package/dist/icons/ThumbsUpIcon.js +1 -1
  396. package/dist/icons/ThunderboltCrossedIcon.js +1 -1
  397. package/dist/icons/ThunderboltFilledIcon.js +1 -1
  398. package/dist/icons/ThunderboltIcon.js +1 -1
  399. package/dist/icons/TimeIcon.js +1 -1
  400. package/dist/icons/TrashIcon.js +1 -1
  401. package/dist/icons/UnlockIcon.js +1 -1
  402. package/dist/icons/UpIcon.js +1 -1
  403. package/dist/icons/UserGroupIcon.js +1 -1
  404. package/dist/icons/UserIcon.js +1 -1
  405. package/dist/icons/UserLockIcon.js +1 -1
  406. package/dist/icons/ViewIcon.js +1 -1
  407. package/dist/icons/WarningFilledIcon.js +1 -1
  408. package/dist/icons/WarningIcon.js +1 -1
  409. package/dist/icons/wrap-icon.js +1 -1
  410. package/dist/index.d.ts +1 -1
  411. package/dist/index.js +1 -1
  412. package/dist/provider.js +1 -1
  413. package/dist/providers/TrackingProvider.js +1 -1
  414. package/dist/providers/navigationAdapter.default.js +1 -1
  415. package/dist/tokens/base.js +1 -1
  416. package/dist/tokens/colors.js +1 -1
  417. package/dist/tokens/index.js +1 -1
  418. package/dist/tokens/layout.js +1 -1
  419. package/dist/tokens/palette.js +1 -1
  420. package/dist/tokens/shadows.js +1 -1
  421. package/dist/tokens/sizes.js +1 -1
  422. package/dist/tokens/spacing.js +1 -1
  423. package/dist/tokens/typography.js +1 -1
  424. package/dist/utils/ResizeSensor.js +1 -1
  425. package/dist/utils/is-dev-env.js +1 -1
  426. package/dist/utils/modules.js +1 -1
  427. package/dist/utils/promise.js +1 -1
  428. package/dist/utils/raf.js +1 -1
  429. package/dist/utils/random.js +1 -1
  430. package/dist/utils/range.js +1 -1
  431. package/dist/utils/react/RenderCache.js +1 -1
  432. package/dist/utils/react/Slots.js +1 -1
  433. package/dist/utils/react/chain.js +1 -1
  434. package/dist/utils/react/forwardRefWithGenerics.js +1 -1
  435. package/dist/utils/react/index.js +1 -1
  436. package/dist/utils/react/interactions.js +1 -1
  437. package/dist/utils/react/isTextOnly.js +1 -1
  438. package/dist/utils/react/mapProps.js +1 -1
  439. package/dist/utils/react/mergeProps.js +1 -1
  440. package/dist/utils/react/nullableValue.js +1 -1
  441. package/dist/utils/react/resolveIcon.js +1 -1
  442. package/dist/utils/react/sharedStore.js +1 -1
  443. package/dist/utils/react/useCombinedRefs.js +1 -1
  444. package/dist/utils/react/useControlledFocusVisible.js +1 -1
  445. package/dist/utils/react/useEventBus.js +1 -1
  446. package/dist/utils/react/useId.js +1 -1
  447. package/dist/utils/react/useIsDarwin.js +1 -1
  448. package/dist/utils/react/useKeySymbols.js +1 -1
  449. package/dist/utils/react/useLayoutEffect.js +1 -1
  450. package/dist/utils/react/useLocalStorage.js +1 -1
  451. package/dist/utils/react/useMergeStyles.js +1 -1
  452. package/dist/utils/react/usePopoverSync.js +1 -1
  453. package/dist/utils/react/useQaProps.js +1 -1
  454. package/dist/utils/react/useViewportSize.js +1 -1
  455. package/dist/utils/react/wrapNodeIfPlain.js +1 -1
  456. package/dist/utils/selection.js +1 -1
  457. package/dist/utils/styles.js +1 -1
  458. package/dist/utils/tree.js +1 -1
  459. package/dist/utils/warnings.js +1 -1
  460. package/dist/version.js +2 -2
  461. package/docs/components/layout/Board.md +35 -12
  462. package/package.json +3 -3
  463. package/dist/components/fields/ListBoxPopover/useCompositeFocus.d.ts +0 -2
  464. package/dist/components/portal/PortalProvider.d.ts +0 -2
@@ -1 +1 @@
1
- {"version":3,"file":"Board.js","names":[],"sources":["../../../../src/components/layout/Board/Board.tsx"],"sourcesContent":["import { useResizeObserver } from '@react-aria/utils';\nimport {\n AllBaseProps,\n CONTAINER_STYLES,\n ContainerStyleProps,\n filterBaseProps,\n Styles,\n tasty,\n} from '@tenphi/tasty';\nimport {\n forwardRef,\n ReactNode,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from 'react';\n\nimport { useEvent } from '../../../_internal/hooks';\nimport { useCombinedRefs } from '../../../utils/react';\nimport { extractStyles } from '../../../utils/styles';\n\nimport {\n BoardEntry,\n BoardMetrics,\n BoardMetricsContext,\n useBoardHost,\n useBoardMetrics,\n useBoardRegistry,\n} from './board-context';\nimport { BoardProvider } from './BoardProvider';\nimport {\n applySizeConstraints,\n bottom,\n calcGridColWidth,\n calcGridItemPosition,\n calcWH,\n clamp,\n cloneLayout,\n Compactor,\n CompactType,\n correctBounds,\n defaultConstraints,\n getAllCollisions,\n getCompactor,\n getLayoutItem,\n LayoutConstraint,\n LayoutItem,\n modifyLayout,\n Position,\n PositionParams,\n ResizeHandleAxis,\n} from './grid-core';\nimport { useBoardLayout } from './use-board-layout';\nimport { ResizePhase, WidgetHost } from './WidgetHost';\n\nconst BoardElement = tasty({\n qa: 'Board',\n styles: {\n position: 'relative',\n display: 'block',\n width: '100%',\n flexGrow: 1,\n minHeight: '0',\n fill: '#clear',\n boxSizing: 'border-box',\n },\n});\n\nconst ContentLayer = tasty({\n styles: {\n position: 'absolute',\n inset: 0,\n },\n});\n\nconst PlaceholderElement = tasty({\n qa: 'BoardPlaceholder',\n styles: {\n position: 'absolute',\n top: 0,\n left: 0,\n fill: '#purple.10',\n radius: '1cr',\n border: '#purple.40',\n zIndex: 2,\n pointerEvents: 'none',\n transition: 'transform 80ms linear, width 80ms linear, height 80ms linear',\n boxSizing: 'border-box',\n },\n});\n\n// Grid overlay drawn behind the widgets. Each snap cell is painted as a faint\n// block (column stripes intersected with a row-band alpha mask); the margin gaps\n// between cells stay transparent. The element is positioned as an explicit\n// rectangle inset by the board's resolved padding and sized to the grid content\n// so the padding reads as a symmetric frame on every edge. Its size, position\n// and gradients come from the board's position params via inline `style`. The\n// fill uses the `#border` token (via its CSS var) so it adapts to the scheme.\nconst GridOverlayElement = tasty({\n qa: 'BoardGridOverlay',\n styles: {\n position: 'absolute',\n zIndex: 0,\n pointerEvents: 'none',\n boxSizing: 'border-box',\n opacity: '.5',\n },\n});\n\n/**\n * Lower bound for the reduced row height used by an aligned nested board, so a\n * very short container can never collapse its rows to zero.\n */\nconst MIN_ALIGNED_ROW_HEIGHT = 24;\n\nexport type BoardCompactType = 'vertical' | 'horizontal' | 'free' | null;\n\n/**\n * Payload passed to the drag/resize lifecycle callbacks. `layout` is the board's\n * current layout at the moment the callback fires, `item` is the affected item\n * (falls back to `oldItem` if the item just left this board via a cross-board\n * transfer), `oldItem` is that item as it was when the gesture started, and\n * `placeholder` is the current drop-slot preview (if any).\n */\nexport interface BoardInteractionInfo {\n layout: LayoutItem[];\n item: LayoutItem;\n oldItem: LayoutItem;\n placeholder: LayoutItem | null;\n}\n\n/** Visibility of the internal grid-line overlay. */\nexport type BoardGridLines = boolean | 'drag';\n\nexport interface CubeBoardProps\n extends Omit<\n AllBaseProps,\n 'children' | 'onDragStart' | 'onDrag' | 'onResize'\n >,\n Omit<ContainerStyleProps, 'margin'> {\n /** Stable board id (used for cross-board drag). Auto-generated if omitted. */\n id?: string;\n /** Controlled layout. */\n layout?: LayoutItem[];\n /** Initial layout for uncontrolled usage. */\n defaultLayout?: LayoutItem[];\n onLayoutChange?: (layout: LayoutItem[]) => void;\n /** Called when a drag gesture starts. */\n onDragStart?: (info: BoardInteractionInfo) => void;\n /** Called on every step of a drag gesture. */\n onDrag?: (info: BoardInteractionInfo) => void;\n /** Called when a drag gesture ends (after the layout is committed). */\n onDragStop?: (info: BoardInteractionInfo) => void;\n /** Called when a resize gesture starts. */\n onResizeStart?: (info: BoardInteractionInfo) => void;\n /** Called on every step of a resize gesture. */\n onResize?: (info: BoardInteractionInfo) => void;\n /** Called when a resize gesture ends (after the layout is committed). */\n onResizeStop?: (info: BoardInteractionInfo) => void;\n /** Number of columns. @default 12 */\n cols?: number;\n /** Row height in pixels. @default 100 */\n rowHeight?: number;\n /** [horizontal, vertical] margin between widgets in pixels. @default [8, 8] */\n margin?: [number, number];\n /** [horizontal, vertical] padding inside the board. Defaults to `margin`. */\n containerPadding?: [number, number];\n /** Maximum number of rows. @default Infinity */\n maxRows?: number;\n /**\n * Compaction behavior. `'vertical'` / `'horizontal'` reflow widgets to remove\n * gaps; `'free'` places each widget exactly where dropped and never pushes its\n * neighbours (pair with `allowOverlap` to let widgets stack, otherwise moving\n * onto an occupied cell is blocked); `null` disables compaction but still\n * resolves collisions the legacy react-grid-layout way. @default 'vertical'\n */\n compact?: BoardCompactType;\n /** Allow widgets to overlap. @default false */\n allowOverlap?: boolean;\n /** Block movement into occupied cells instead of pushing. @default false */\n preventCollision?: boolean;\n /** Enable dragging for all widgets. @default true */\n isDraggable?: boolean;\n /** Enable resizing for all widgets. @default true */\n isResizable?: boolean;\n /** Whether this board accepts widgets dropped from other boards. @default true */\n isDroppable?: boolean;\n /** Which resize handles to show. @default ['se'] */\n resizeHandles?: ResizeHandleAxis[];\n /**\n * CSS selector for elements that must not start a pointer drag (e.g. form\n * controls inside a widget: `\"input,textarea,button,a,.no-drag\"`). Keyboard\n * moves are unaffected. Can be overridden per widget on `Board.Widget`.\n */\n dragCancel?: string;\n /**\n * CSS selector for the only elements from which a pointer drag may start.\n * Can be overridden per widget on `Board.Widget`.\n */\n dragHandle?: string;\n /**\n * Show grid lines behind the widgets. `true` always shows them, `'drag'`\n * shows them only while a widget is being dragged or resized, `false` never.\n * @default false\n */\n showGridLines?: BoardGridLines;\n /**\n * Align this board's grid with an ancestor `Board`'s layout. Only takes\n * effect when the board is nested inside another `Board`'s widget. When set,\n * the board inherits the parent's column pitch (deriving its own column count\n * from its measured width so cells stay parent-sized) and inherits the\n * parent's row height as a target, shrinking rows slightly when needed to fit\n * the height the container widget grants it. @default false\n */\n isAligned?: boolean;\n /** Grid/item layout constraints. */\n constraints?: LayoutConstraint[];\n /**\n * Explicit container width in pixels. When provided, disables automatic width\n * measurement (useful for SSR and tests).\n */\n width?: number;\n children?: ReactNode;\n}\n\nfunction compactTypeToCore(compact: BoardCompactType): CompactType {\n if (compact === 'free') return null;\n return compact;\n}\n\nfunction BoardInner(\n props: CubeBoardProps,\n ref: React.ForwardedRef<HTMLDivElement>,\n) {\n const {\n id: providedId,\n layout: controlledLayout,\n defaultLayout,\n onLayoutChange,\n onDragStart,\n onDrag,\n onDragStop,\n onResizeStart,\n onResize: onResizeProp,\n onResizeStop,\n cols = 12,\n rowHeight = 100,\n margin = [8, 8],\n containerPadding,\n maxRows = Infinity,\n compact = 'vertical',\n allowOverlap = false,\n preventCollision = false,\n isDraggable = true,\n isResizable = true,\n isDroppable = true,\n resizeHandles = ['se'],\n dragCancel,\n dragHandle,\n showGridLines = false,\n isAligned = false,\n constraints,\n width: providedWidth,\n children,\n ...otherProps\n } = props;\n\n const registry = useBoardRegistry()!;\n const parentMetrics = useBoardMetrics();\n const host = useBoardHost();\n const aligned = isAligned && !!parentMetrics;\n const generatedId = useId();\n const boardId = providedId ?? generatedId;\n\n const containerRef = useCombinedRefs(ref);\n const contentRef = useRef<HTMLDivElement | null>(null);\n const [measuredWidth, setMeasuredWidth] = useState<number>(0);\n // Rendered height is only needed for aligned nested boards (to fit rows into\n // the space the container grants). It never drives the board's own height, so\n // measuring it cannot create a feedback loop.\n const [measuredHeight, setMeasuredHeight] = useState<number>(0);\n const width = providedWidth ?? measuredWidth;\n\n const onResizeContainer = useEvent(() => {\n const el = containerRef.current;\n if (!el) return;\n // A hidden container (e.g. the board inside an inactive tab after a\n // spring-loaded tab switch) reports 0. Keep the last non-zero measurement so\n // the board stays \"ready\" and keeps its widget hosts mounted while briefly\n // hidden. Otherwise the board would render nothing, unmounting the widget\n // that owns an in-flight drag gesture and stranding the drag (React Aria's\n // `useMove` tears down its listeners on unmount, so the drop never fires).\n const nextWidth = el.offsetWidth;\n const nextHeight = el.offsetHeight;\n if (nextWidth > 0) setMeasuredWidth(nextWidth);\n if (nextHeight > 0) setMeasuredHeight(nextHeight);\n });\n useResizeObserver({ ref: containerRef, onResize: onResizeContainer });\n useEffect(() => {\n if (providedWidth == null) {\n onResizeContainer();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [providedWidth]);\n\n const {\n layout,\n layoutRef,\n placeholder,\n placeholderRef,\n setPlaceholder,\n applyLayout,\n } = useBoardLayout({\n layout: controlledLayout,\n defaultLayout,\n onLayoutChange,\n });\n\n // Re-render when any widget's registered content/config changes.\n useSyncExternalStore(registry.store.subscribe, registry.store.getVersion);\n\n // In aligned mode the board inherits the parent's gap so widget edges line up\n // with the surrounding layout; otherwise it uses its own `margin`.\n const effectiveMargin: readonly [number, number] = aligned\n ? parentMetrics!.margin\n : margin;\n // The board keeps its own padding (it sits inside the container's chrome);\n // when unspecified it defaults to the effective gap.\n const resolvedPadding: readonly [number, number] =\n containerPadding ?? effectiveMargin;\n\n const rows = Math.max(\n bottom(layout),\n placeholder ? placeholder.y + placeholder.h : 0,\n );\n\n // Derive the aligned column count so each column keeps the parent's pixel\n // pitch: as the container widget is resized, columns are added/removed rather\n // than stretched. `containerWidth` is then back-solved so `calcGridColWidth`\n // returns exactly the parent's column width.\n const parentColWidth = aligned ? parentMetrics!.colWidth : 0;\n const alignedCols =\n aligned && width > 0\n ? Math.max(\n 1,\n Math.floor(\n (width - resolvedPadding[0] * 2 + effectiveMargin[0]) /\n (parentColWidth + effectiveMargin[0]),\n ),\n )\n : cols;\n const effectiveCols = aligned ? alignedCols : cols;\n const effectiveContainerWidth = aligned\n ? parentColWidth * effectiveCols +\n effectiveMargin[0] * Math.max(0, effectiveCols - 1) +\n resolvedPadding[0] * 2\n : width;\n\n // Row height inherits the parent's as the target, but shrinks (never grows\n // beyond it) so the board's rows fit the height the container grants. When\n // the height is unbounded/unmeasured, it stays at the parent's row height.\n const parentRowHeight = aligned ? parentMetrics!.rowHeight : rowHeight;\n const effectiveRowHeight =\n aligned && rows > 0 && measuredHeight > 0\n ? clamp(\n (measuredHeight -\n Math.max(0, rows - 1) * effectiveMargin[1] -\n resolvedPadding[1] * 2) /\n rows,\n MIN_ALIGNED_ROW_HEIGHT,\n parentRowHeight,\n )\n : parentRowHeight;\n\n const positionParams = useMemo<PositionParams>(\n () => ({\n margin: effectiveMargin,\n containerPadding: resolvedPadding,\n containerWidth: effectiveContainerWidth,\n cols: effectiveCols,\n rowHeight: effectiveRowHeight,\n maxRows,\n }),\n [\n effectiveMargin[0],\n effectiveMargin[1],\n resolvedPadding[0],\n resolvedPadding[1],\n effectiveContainerWidth,\n effectiveCols,\n effectiveRowHeight,\n maxRows,\n ],\n );\n\n // 'free' means no compaction (nothing is pushed up/left or recompacted) AND a\n // dragged widget never pushes or swaps its neighbours: it is placed exactly\n // where dropped. Without `allowOverlap` a move onto an occupied cell is\n // blocked (the widget stays at its last free spot); with `allowOverlap`\n // widgets may stack. The explicit `preventCollision` prop still applies to the\n // compacting modes (`vertical` / `horizontal`) and to the legacy `null` mode.\n const compactor = useMemo<Compactor>(\n () =>\n getCompactor(\n compactTypeToCore(compact),\n allowOverlap,\n compact === 'free' ? !allowOverlap : preventCollision,\n ),\n [compact, allowOverlap, preventCollision],\n );\n\n const resolvedConstraints = constraints ?? defaultConstraints;\n\n const computedHeight =\n rows > 0\n ? rows * effectiveRowHeight +\n Math.max(0, rows - 1) * effectiveMargin[1] +\n resolvedPadding[1] * 2\n : effectiveRowHeight;\n // An aligned board fills the height the container grants it, so it reports its\n // measured height; otherwise it reports the height its content needs.\n const containerHeight =\n aligned && measuredHeight > 0 ? measuredHeight : computedHeight;\n\n // Live refs so the stable registry entry always reads current values.\n const liveRef = useRef({\n positionParams,\n compactor,\n constraints: resolvedConstraints,\n maxRows,\n containerHeight,\n isDroppable,\n });\n liveRef.current = {\n positionParams,\n compactor,\n constraints: resolvedConstraints,\n maxRows,\n containerHeight,\n isDroppable,\n };\n\n const applyLayoutEvent = useEvent(applyLayout);\n const setPlaceholderEvent = useEvent(setPlaceholder);\n\n const entryRef = useRef<BoardEntry | null>(null);\n if (!entryRef.current) {\n entryRef.current = {\n id: boardId,\n getContentRect: () => contentRef.current?.getBoundingClientRect() ?? null,\n getContentNode: () => contentRef.current,\n getPositionParams: () => liveRef.current.positionParams,\n getConstraints: () => liveRef.current.constraints,\n getCompactor: () => liveRef.current.compactor,\n getMaxRows: () => liveRef.current.maxRows,\n getContainerHeight: () => liveRef.current.containerHeight,\n getLayout: () => layoutRef.current,\n applyLayout: (next, commit) => applyLayoutEvent(next, commit),\n setPlaceholder: (item) => setPlaceholderEvent(item),\n isDroppable: () => liveRef.current.isDroppable,\n };\n }\n\n useEffect(() => {\n const entry = entryRef.current!;\n // Keep the entry's id in sync with the (possibly changed) board id before\n // registering. The previous effect's cleanup has already removed the old id,\n // so registering here keys the entry under the current id.\n entry.id = boardId;\n return registry.registerBoard(entry);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [boardId]);\n\n // When the aligned column count changes (the container was resized), reflow\n // the layout to the new width: clamp items back into bounds and recompact so\n // nothing overflows the narrower/wider grid.\n const recompactForCols = useEvent((nextCols: number) => {\n const corrected = correctBounds(cloneLayout(layoutRef.current), {\n cols: nextCols,\n });\n const compacted = [\n ...liveRef.current.compactor.compact(corrected, nextCols),\n ];\n applyLayoutEvent(compacted, true);\n });\n // `null` until the first *measured* aligned column count is established. This\n // avoids treating the initial zero-width -> measured-width transition as a\n // column-count change: a board that measures its own width (no explicit\n // `width` prop) renders first with `width === 0`, so `effectiveCols` falls\n // back to `cols` and only becomes the derived aligned count once measured.\n // Seeding the baseline on that first measured value (without committing)\n // prevents an unsolicited reflow + `onLayoutChange` before the user interacts.\n const prevAlignedColsRef = useRef<number | null>(null);\n useEffect(() => {\n if (!aligned) {\n // Re-entering aligned mode should re-seed from the next measured value.\n prevAlignedColsRef.current = null;\n return;\n }\n // Wait for a real width measurement; the fallback-`cols` value that stands\n // in before measurement is not a meaningful aligned column count.\n if (width <= 0) return;\n if (prevAlignedColsRef.current === null) {\n prevAlignedColsRef.current = effectiveCols;\n return;\n }\n if (prevAlignedColsRef.current === effectiveCols) return;\n prevAlignedColsRef.current = effectiveCols;\n recompactForCols(effectiveCols);\n }, [aligned, width, effectiveCols, recompactForCols]);\n\n // Natural height this board wants: its rows at the (unshrunk) target row\n // height. When aligned rows are shrunk to fit a short container, this exceeds\n // the measured height by the amount the board was squeezed.\n const naturalHeight =\n rows > 0\n ? rows * parentRowHeight +\n Math.max(0, rows - 1) * effectiveMargin[1] +\n resolvedPadding[1] * 2\n : parentRowHeight;\n\n // Report this aligned board's height deficit to an auto-sizing host so the\n // host can both grow to fit and pin its resize floor. The value is signed:\n // positive when the board is squeezed (needs more height), negative when the\n // container is taller than needed (so the floor can be lowered). The host\n // never shrinks the widget on its own - it only grows and clamps resizing.\n const requestHeightDeficit = host?.requestHeightDeficit;\n useEffect(() => {\n if (!aligned || !host?.isAutoHeight || !requestHeightDeficit) return;\n if (measuredHeight <= 0) return;\n requestHeightDeficit(naturalHeight - measuredHeight);\n }, [\n aligned,\n host?.isAutoHeight,\n requestHeightDeficit,\n naturalHeight,\n measuredHeight,\n ]);\n\n // In-board resize orchestration.\n const resizeStateRef = useRef<{\n id: string;\n axis: ResizeHandleAxis;\n item: LayoutItem;\n origin: Position;\n accX: number;\n accY: number;\n } | null>(null);\n\n // Minimum rows each auto-height widget currently needs to fit its content.\n // Read during resize so a widget can never be dragged shorter than its\n // content, and used to grow the item when the content needs more room.\n const autoHeightMinRowsRef = useRef<Record<string, number>>({});\n\n const handleResize = useEvent(\n (\n id: string,\n axis: ResizeHandleAxis,\n phase: ResizePhase,\n dx: number,\n dy: number,\n ) => {\n const pp = liveRef.current.positionParams;\n\n if (phase === 'start') {\n const rawItem = getLayoutItem(layoutRef.current, id);\n if (!rawItem) return;\n // Layout-item constraints win; otherwise fall back to the ones declared\n // on the owning `Board.Widget` so `applySizeConstraints` picks them up.\n const item: LayoutItem = {\n ...rawItem,\n constraints:\n rawItem.constraints ?? registry.store.get(id)?.constraints,\n };\n resizeStateRef.current = {\n id,\n axis,\n item: { ...item },\n origin: calcGridItemPosition(pp, item.x, item.y, item.w, item.h),\n accX: 0,\n accY: 0,\n };\n setPlaceholder({ ...item });\n onResizeStart?.({\n layout: layoutRef.current,\n item: { ...item },\n oldItem: { ...item },\n placeholder: { ...item },\n });\n return;\n }\n\n const rs = resizeStateRef.current;\n if (!rs) return;\n\n if (phase === 'end') {\n const finalLayout = [...layoutRef.current];\n applyLayout(finalLayout, true);\n setPlaceholder(null);\n onResizeStop?.({\n layout: finalLayout,\n item: getLayoutItem(finalLayout, id) ?? rs.item,\n oldItem: rs.item,\n placeholder: null,\n });\n resizeStateRef.current = null;\n return;\n }\n\n rs.accX += dx;\n rs.accY += dy;\n\n const { origin, item, axis: handle } = rs;\n let newW = origin.width;\n let newH = origin.height;\n if (handle.includes('e')) newW = origin.width + rs.accX;\n if (handle.includes('w')) newW = origin.width - rs.accX;\n if (handle.includes('s')) newH = origin.height + rs.accY;\n if (handle.includes('n')) newH = origin.height - rs.accY;\n newW = Math.max(newW, 8);\n newH = Math.max(newH, 8);\n\n const raw = calcWH(pp, newW, newH, item.x, item.y, handle);\n const constrained = applySizeConstraints(\n liveRef.current.constraints,\n item,\n raw.w,\n raw.h,\n handle,\n {\n cols: pp.cols,\n maxRows: liveRef.current.maxRows,\n containerWidth: pp.containerWidth,\n containerHeight: liveRef.current.containerHeight,\n rowHeight: pp.rowHeight,\n margin: pp.margin,\n layout: layoutRef.current,\n },\n );\n\n // An auto-height widget cannot be resized shorter than the content it\n // hosts (a nested board) currently needs, so pin its height to the floor.\n const floorRows = autoHeightMinRowsRef.current[id] ?? 0;\n const finalW = constrained.w;\n const finalH = Math.max(constrained.h, floorRows);\n\n let x = item.x;\n let y = item.y;\n if (handle.includes('w')) x = item.x + item.w - finalW;\n if (handle.includes('n')) y = item.y + item.h - finalH;\n x = Math.max(0, x);\n y = Math.max(0, y);\n\n let newItem: LayoutItem = {\n ...item,\n x,\n y,\n w: finalW,\n h: finalH,\n };\n\n // Collision-blocking modes (`free` without `allowOverlap`, or an explicit\n // `preventCollision`) run a no-op/gap-filling compactor that never\n // resolves overlaps, so a resize must be blocked here the same way the\n // drag path blocks a move (`moveElement` reverts on collision). Without\n // this, growing or moving an edge via a resize handle could push the box\n // onto an occupied cell. When the new box overlaps a neighbour, revert to\n // the last committed box for this widget so the gesture stalls at the\n // last valid size/position instead of overlapping.\n const compactor = liveRef.current.compactor;\n if (compactor.preventCollision && !compactor.allowOverlap) {\n const collides = getAllCollisions(layoutRef.current, newItem).some(\n (other) => other.i !== id,\n );\n if (collides) {\n const lastValid = getLayoutItem(layoutRef.current, id);\n if (lastValid) newItem = { ...lastValid };\n }\n }\n\n const working = modifyLayout(layoutRef.current, newItem);\n const compacted = [...compactor.compact(working, pp.cols)];\n applyLayout(compacted, false);\n const nextPlaceholder = getLayoutItem(compacted, id) ?? newItem;\n setPlaceholder(nextPlaceholder);\n onResizeProp?.({\n layout: compacted,\n item: getLayoutItem(compacted, id) ?? newItem,\n oldItem: rs.item,\n placeholder: nextPlaceholder,\n });\n },\n );\n\n // Record an auto-height widget's needed rows. Grow the item when its content\n // needs more height (only ever increases); the stored value is also the\n // resize floor enforced in `handleResize`.\n const handleAutoHeight = useEvent((id: string, neededRows: number) => {\n autoHeightMinRowsRef.current[id] = neededRows;\n const current = getLayoutItem(layoutRef.current, id);\n if (!current || neededRows <= current.h) return;\n // While a drag or resize gesture is in flight the layout is transient - the\n // registry (drag) and `handleResize` write uncommitted previews and commit\n // only on drop / release. Growing an auto-height widget here with\n // `commit: true` would fire `onLayoutChange` mid-gesture and persist the\n // in-flight positions of the widget being moved. Skip the grow-commit; the\n // floor ref is already updated above (so `handleResize` still respects it),\n // and the deficit effect re-fires once the gesture settles.\n if (registry.dragState || resizeStateRef.current) return;\n const pp = liveRef.current.positionParams;\n const working = modifyLayout(layoutRef.current, {\n ...current,\n h: neededRows,\n });\n const compacted = [...liveRef.current.compactor.compact(working, pp.cols)];\n applyLayout(compacted, true);\n });\n\n // The dragged item captured at gesture start, so drag callbacks can report the\n // original position throughout (and after a cross-board transfer removes the\n // item from this board's layout).\n const dragOldItemRef = useRef<LayoutItem | null>(null);\n\n const handleDragLifecycle = useEvent((id: string, phase: ResizePhase) => {\n const currentLayout = layoutRef.current;\n const liveItem = getLayoutItem(currentLayout, id);\n\n if (phase === 'start') {\n dragOldItemRef.current = liveItem ? { ...liveItem } : null;\n }\n const oldItem = dragOldItemRef.current ?? liveItem;\n if (!oldItem) return;\n const item = liveItem ?? oldItem;\n\n const info: BoardInteractionInfo = {\n layout: currentLayout,\n item,\n oldItem,\n // Read the live ref, not render-time state: the registry calls\n // `setPlaceholder` synchronously right before this fires, and that only\n // schedules a re-render, so `placeholder` state still holds the previous\n // value (or a stale preview after the drop clears it to `null`).\n placeholder: placeholderRef.current,\n };\n if (phase === 'start') onDragStart?.(info);\n else if (phase === 'move') onDrag?.(info);\n else {\n onDragStop?.(info);\n dragOldItemRef.current = null;\n }\n });\n\n const styles: Styles = extractStyles(otherProps, CONTAINER_STYLES);\n\n const dragState = registry.dragState;\n const ready = width > 0;\n\n const placeholderStyle = placeholder\n ? (() => {\n const pos = calcGridItemPosition(\n positionParams,\n placeholder.x,\n placeholder.y,\n placeholder.w,\n placeholder.h,\n );\n return {\n transform: `translate(${pos.left}px, ${pos.top}px)`,\n width: `${pos.width}px`,\n height: `${pos.height}px`,\n };\n })()\n : null;\n\n const showPlaceholder = placeholder && placeholderStyle;\n\n const gridLinesVisible =\n showGridLines === true ||\n (showGridLines === 'drag' && (!!dragState || !!placeholder));\n const gridOverlayStyle = gridLinesVisible\n ? (() => {\n const colWidth = calcGridColWidth(positionParams);\n const rowHeightPx = positionParams.rowHeight;\n // A grid with margins has real gaps between cells, so any line-based\n // overlay either misses a cell edge (single line at the cell pitch) or\n // shows a double line in every gap (a line at both edges). Instead,\n // paint each snap cell as a faint block sized exactly `colWidth` x\n // `rowHeightPx` with the margin gaps left transparent: the blocks line\n // up 1:1 with the drop-zone placeholder and there are no lines to\n // double. Column stripes form the background; a row-band alpha mask\n // intersects them into cells.\n const pitchX = colWidth + effectiveMargin[0];\n const pitchY = rowHeightPx + effectiveMargin[1];\n // Position the overlay as an explicit rectangle inset by the board's\n // resolved padding and sized to exactly cover the grid content (cols x\n // rows). This makes the padding a symmetric frame on all four edges (the\n // previous `inset: 0` + top-left-anchored repeat left the padding\n // unvisualized on the right/bottom and inside any extra min-height) and\n // lets the cell pattern tile from the overlay's own origin.\n const padX = resolvedPadding[0];\n const padY = resolvedPadding[1];\n const gridWidth = Math.max(0, effectiveContainerWidth - padX * 2);\n const gridHeight =\n rows > 0 ? rows * rowHeightPx + (rows - 1) * effectiveMargin[1] : 0;\n const fill = 'var(--border-color)';\n const columns = `repeating-linear-gradient(to right, ${fill} 0, ${fill} ${colWidth}px, transparent ${colWidth}px, transparent ${pitchX}px)`;\n const rowsGrad = `repeating-linear-gradient(to bottom, #000 0, #000 ${rowHeightPx}px, transparent ${rowHeightPx}px, transparent ${pitchY}px)`;\n return {\n left: `${padX}px`,\n top: `${padY}px`,\n width: `${gridWidth}px`,\n height: `${gridHeight}px`,\n backgroundImage: columns,\n backgroundPosition: '0 0',\n backgroundRepeat: 'repeat',\n maskImage: rowsGrad,\n WebkitMaskImage: rowsGrad,\n maskPosition: '0 0',\n WebkitMaskPosition: '0 0',\n maskRepeat: 'repeat',\n WebkitMaskRepeat: 'repeat',\n };\n })()\n : null;\n\n // Metrics this board exposes to any aligned boards nested inside its widgets.\n const boardMetrics = useMemo<BoardMetrics>(\n () => ({\n colWidth: calcGridColWidth(positionParams),\n rowHeight: positionParams.rowHeight,\n margin: positionParams.margin,\n containerPadding: positionParams.containerPadding,\n }),\n [positionParams],\n );\n\n return (\n <BoardMetricsContext.Provider value={boardMetrics}>\n <BoardElement\n {...filterBaseProps(otherProps, { eventProps: true })}\n ref={containerRef}\n styles={styles}\n // Non-aligned: use min-height (not a fixed height) so the board\n // auto-sizes to its content by default but can still grow to fill a\n // taller parent. Widgets are absolutely positioned, so growing never\n // shifts them, and the content layer (inset: 0) always covers the full\n // board -> the whole board is droppable. Aligned: omit the inline height\n // so the board fills (and is bounded by) the space the container grants,\n // which is what drives the reduced row height.\n style={aligned ? undefined : { minHeight: `${containerHeight}px` }}\n mods={{\n dragging: !!dragState,\n 'drop-target': dragState?.currentBoardId === boardId,\n }}\n >\n <ContentLayer ref={contentRef}>\n {ready && gridOverlayStyle ? (\n <GridOverlayElement aria-hidden=\"true\" style={gridOverlayStyle} />\n ) : null}\n {ready\n ? layout.map((item) => {\n const registration = registry.store.get(item.i);\n const widgetDraggable =\n isDraggable &&\n registration?.isDraggable !== false &&\n item.isDraggable !== false &&\n !item.static;\n const widgetResizable =\n isResizable &&\n registration?.isResizable !== false &&\n item.isResizable !== false &&\n !item.static;\n const handles =\n item.resizeHandles ??\n registration?.resizeHandles ??\n resizeHandles;\n const widgetDragCancel = registration?.dragCancel ?? dragCancel;\n const widgetDragHandle = registration?.dragHandle ?? dragHandle;\n\n return (\n <WidgetHost\n key={item.i}\n boardId={boardId}\n item={item}\n positionParams={positionParams}\n registration={registration}\n isDraggable={widgetDraggable}\n isResizable={widgetResizable}\n resizeHandles={handles}\n dragCancel={widgetDragCancel}\n dragHandle={widgetDragHandle}\n registry={registry}\n dragState={dragState}\n onResize={handleResize}\n onAutoHeight={handleAutoHeight}\n onDragLifecycle={handleDragLifecycle}\n />\n );\n })\n : null}\n {showPlaceholder ? (\n <PlaceholderElement aria-hidden=\"true\" style={placeholderStyle!} />\n ) : null}\n </ContentLayer>\n {children}\n </BoardElement>\n </BoardMetricsContext.Provider>\n );\n}\n\nconst BoardInnerForwarded = forwardRef(BoardInner);\n\n/**\n * A draggable and resizable widget grid. Widgets are declared with\n * `Board.Widget` and positioned via a `layout`. Wrap multiple boards in a\n * `BoardProvider` to enable dragging widgets between them.\n */\nexport const Board = forwardRef(function Board(\n props: CubeBoardProps,\n ref: React.ForwardedRef<HTMLDivElement>,\n) {\n const existingRegistry = useBoardRegistry();\n\n if (existingRegistry) {\n return <BoardInnerForwarded {...props} ref={ref} />;\n }\n\n return (\n <BoardProvider>\n <BoardInnerForwarded {...props} ref={ref} />\n </BoardProvider>\n );\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"Board.js","names":[],"sources":["../../../../src/components/layout/Board/Board.tsx"],"sourcesContent":["import { useResizeObserver } from '@react-aria/utils';\nimport {\n AllBaseProps,\n CONTAINER_STYLES,\n ContainerStyleProps,\n filterBaseProps,\n mergeStyles,\n Styles,\n tasty,\n} from '@tenphi/tasty';\nimport {\n forwardRef,\n ReactNode,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from 'react';\n\nimport { useEvent } from '../../../_internal/hooks';\nimport { useCombinedRefs } from '../../../utils/react';\nimport { extractStyles } from '../../../utils/styles';\n\nimport {\n BoardEntry,\n BoardGridLinesContext,\n BoardMetrics,\n BoardMetricsContext,\n useBoardGridLines,\n useBoardHost,\n useBoardMetrics,\n useBoardRegistry,\n} from './board-context';\nimport { BoardProvider } from './BoardProvider';\nimport {\n applySizeConstraints,\n bottom,\n calcGridColWidth,\n calcGridItemPosition,\n calcWH,\n cloneLayout,\n Compactor,\n CompactType,\n correctBounds,\n defaultConstraints,\n getAllCollisions,\n getCompactor,\n getLayoutItem,\n LayoutConstraint,\n LayoutItem,\n modifyLayout,\n Position,\n PositionParams,\n ResizeHandleAxis,\n} from './grid-core';\nimport { useBoardLayout } from './use-board-layout';\nimport { ResizePhase, WidgetHost } from './WidgetHost';\n\nimport type { CubeBoardWidgetProps } from './Widget';\n\nconst BoardElement = tasty({\n qa: 'Board',\n styles: {\n position: 'relative',\n display: 'block',\n width: '100%',\n flexGrow: 1,\n minHeight: '0',\n fill: '#surface',\n boxSizing: 'border-box',\n },\n});\n\nconst ContentLayer = tasty({\n styles: {\n position: 'absolute',\n inset: 0,\n },\n});\n\nconst PlaceholderElement = tasty({\n qa: 'BoardPlaceholder',\n styles: {\n position: 'absolute',\n top: 0,\n left: 0,\n fill: '#purple.10',\n radius: '1cr',\n border: '#purple.40',\n zIndex: 2,\n pointerEvents: 'none',\n transition: 'inset 80ms linear, width 80ms linear, height 80ms linear',\n boxSizing: 'border-box',\n },\n});\n\n// Grid overlay drawn behind the widgets. Each snap cell is painted as a faint\n// block (column stripes intersected with a row-band alpha mask); the margin gaps\n// between cells stay transparent. The element is positioned as an explicit\n// rectangle inset by the board's resolved padding and sized to the grid content\n// so the padding reads as a symmetric frame on every edge. Its size, position\n// and gradients come from the board's position params via inline `style`. The\n// fill uses the `#border` token (via its CSS var) so it adapts to the scheme.\nconst GridOverlayElement = tasty({\n qa: 'BoardGridOverlay',\n styles: {\n position: 'absolute',\n zIndex: 0,\n pointerEvents: 'none',\n boxSizing: 'border-box',\n opacity: '.5',\n },\n});\n\nexport type BoardCompactType = 'vertical' | 'horizontal' | 'free' | null;\n\n/**\n * Payload passed to the drag/resize lifecycle callbacks. `layout` is the board's\n * current layout at the moment the callback fires, `item` is the affected item\n * (falls back to `oldItem` if the item just left this board via a cross-board\n * transfer), `oldItem` is that item as it was when the gesture started, and\n * `placeholder` is the current drop-slot preview (if any).\n */\nexport interface BoardInteractionInfo {\n layout: LayoutItem[];\n item: LayoutItem;\n oldItem: LayoutItem;\n placeholder: LayoutItem | null;\n}\n\n/** Visibility of the internal grid-line overlay. */\nexport type BoardGridLines = boolean | 'drag';\n\n/**\n * The subset of `Board.Widget` props a `Board` can set as defaults for every\n * widget it hosts (via `widgetProps`). Excludes `id`/`children`, which are\n * per-widget. Per-widget `Board.Widget` props override these.\n */\nexport type CubeBoardWidgetDefaults = Omit<\n CubeBoardWidgetProps,\n 'id' | 'children'\n>;\n\nexport interface CubeBoardProps\n extends Omit<\n AllBaseProps,\n 'children' | 'onDragStart' | 'onDrag' | 'onResize'\n >,\n Omit<ContainerStyleProps, 'margin'> {\n /** Stable board id (used for cross-board drag). Auto-generated if omitted. */\n id?: string;\n /** Controlled layout. */\n layout?: LayoutItem[];\n /** Initial layout for uncontrolled usage. */\n defaultLayout?: LayoutItem[];\n onLayoutChange?: (layout: LayoutItem[]) => void;\n /** Called when a drag gesture starts. */\n onDragStart?: (info: BoardInteractionInfo) => void;\n /** Called on every step of a drag gesture. */\n onDrag?: (info: BoardInteractionInfo) => void;\n /** Called when a drag gesture ends (after the layout is committed). */\n onDragStop?: (info: BoardInteractionInfo) => void;\n /** Called when a resize gesture starts. */\n onResizeStart?: (info: BoardInteractionInfo) => void;\n /** Called on every step of a resize gesture. */\n onResize?: (info: BoardInteractionInfo) => void;\n /** Called when a resize gesture ends (after the layout is committed). */\n onResizeStop?: (info: BoardInteractionInfo) => void;\n /** Number of columns. @default 12 */\n cols?: number;\n /** Row height in pixels. @default 100 */\n rowHeight?: number;\n /** [horizontal, vertical] margin between widgets in pixels. @default [8, 8] */\n margin?: [number, number];\n /**\n * [horizontal, vertical] padding inside the board. Defaults to `margin`, or\n * to `[0, 0]` for an aligned nested board (`isAligned`) so its grid lines up\n * with the ancestor board's.\n */\n containerPadding?: [number, number];\n /** Maximum number of rows. @default Infinity */\n maxRows?: number;\n /**\n * Compaction behavior. `'vertical'` / `'horizontal'` reflow widgets to remove\n * gaps; `'free'` places each widget exactly where dropped and never pushes its\n * neighbours (pair with `allowOverlap` to let widgets stack, otherwise moving\n * onto an occupied cell is blocked); `null` disables compaction but still\n * resolves collisions the legacy react-grid-layout way. @default 'vertical'\n */\n compact?: BoardCompactType;\n /** Allow widgets to overlap. @default false */\n allowOverlap?: boolean;\n /** Block movement into occupied cells instead of pushing. @default false */\n preventCollision?: boolean;\n /** Enable dragging for all widgets. @default true */\n isDraggable?: boolean;\n /** Enable resizing for all widgets. @default true */\n isResizable?: boolean;\n /** Whether this board accepts widgets dropped from other boards. @default true */\n isDroppable?: boolean;\n /** Which resize handles to show. @default ['se'] */\n resizeHandles?: ResizeHandleAxis[];\n /**\n * CSS selector for elements that must not start a pointer drag (e.g. form\n * controls inside a widget: `\"input,textarea,button,a,.no-drag\"`). Keyboard\n * moves are unaffected. Can be overridden per widget on `Board.Widget`.\n */\n dragCancel?: string;\n /**\n * CSS selector for the only elements from which a pointer drag may start.\n * Can be overridden per widget on `Board.Widget`.\n */\n dragHandle?: string;\n /**\n * Show grid lines behind the widgets. `true` always shows them, `'drag'`\n * shows them only while a widget is being dragged or resized, `false` never.\n * @default false\n */\n showGridLines?: BoardGridLines;\n /**\n * Align this board's grid with an ancestor `Board`'s layout. Only takes\n * effect when the board is nested inside another `Board`'s widget. When set,\n * every cell matches the parent's cell size exactly: the board inherits the\n * parent's column pitch (deriving its own column count from its measured\n * width) and uses the parent's row height verbatim. It never shrinks rows to\n * fit; pair it with an `isAutoHeight` container so the widget grows to fit its\n * rows at that height. @default false\n */\n isAligned?: boolean;\n /** Grid/item layout constraints. */\n constraints?: LayoutConstraint[];\n /**\n * Explicit container width in pixels. When provided, disables automatic width\n * measurement (useful for SSR and tests).\n */\n width?: number;\n /**\n * Default props applied to every widget this board hosts. Per-widget\n * `Board.Widget` props override these. Use it to add a card border to every\n * widget (`widgetProps={{ isCard: true }}`) or set shared sizing/`styles`\n * defaults without repeating them on each `Board.Widget`.\n */\n widgetProps?: Partial<CubeBoardWidgetDefaults>;\n children?: ReactNode;\n}\n\nfunction compactTypeToCore(compact: BoardCompactType): CompactType {\n if (compact === 'free') return null;\n return compact;\n}\n\nfunction BoardInner(\n props: CubeBoardProps,\n ref: React.ForwardedRef<HTMLDivElement>,\n) {\n const {\n id: providedId,\n layout: controlledLayout,\n defaultLayout,\n onLayoutChange,\n onDragStart,\n onDrag,\n onDragStop,\n onResizeStart,\n onResize: onResizeProp,\n onResizeStop,\n cols = 12,\n rowHeight = 100,\n margin = [8, 8],\n containerPadding,\n maxRows = Infinity,\n compact = 'vertical',\n allowOverlap = false,\n preventCollision = false,\n isDraggable = true,\n isResizable = true,\n isDroppable = true,\n resizeHandles = ['se'],\n dragCancel,\n dragHandle,\n showGridLines,\n isAligned = false,\n constraints,\n width: providedWidth,\n widgetProps,\n children,\n ...otherProps\n } = props;\n\n const registry = useBoardRegistry()!;\n const parentMetrics = useBoardMetrics();\n const host = useBoardHost();\n const inheritedGridLines = useBoardGridLines();\n const aligned = isAligned && !!parentMetrics;\n // `widgetProps` may carry container style props directly (e.g. `fill`,\n // `padding`, `radius`) alongside an explicit `styles` object, mirroring\n // `Board.Widget`. Extract them into a single style map here so those defaults\n // actually reach every widget - forwarding only `widgetProps.styles` would\n // drop the direct props. A direct prop wins over the same key in `styles`.\n const widgetPropsStyles = useMemo<Styles | undefined>(() => {\n if (!widgetProps) return undefined;\n const extracted = extractStyles(widgetProps, CONTAINER_STYLES);\n return Object.keys(extracted).length > 0 ? extracted : undefined;\n }, [widgetProps]);\n // A nested board with no explicit `showGridLines` inherits the ancestor's:\n // when the ancestor has grid lines enabled, show them here while dragging.\n const effectiveShowGridLines: BoardGridLines =\n showGridLines ?? (inheritedGridLines ? 'drag' : false);\n const generatedId = useId();\n const boardId = providedId ?? generatedId;\n\n const containerRef = useCombinedRefs(ref);\n const contentRef = useRef<HTMLDivElement | null>(null);\n const [measuredWidth, setMeasuredWidth] = useState<number>(0);\n // Rendered height is only needed for aligned nested boards (to fit rows into\n // the space the container grants). It never drives the board's own height, so\n // measuring it cannot create a feedback loop.\n const [measuredHeight, setMeasuredHeight] = useState<number>(0);\n const width = providedWidth ?? measuredWidth;\n\n const onResizeContainer = useEvent(() => {\n const el = containerRef.current;\n if (!el) return;\n // A hidden container (e.g. the board inside an inactive tab after a\n // spring-loaded tab switch) reports 0. Keep the last non-zero measurement so\n // the board stays \"ready\" and keeps its widget hosts mounted while briefly\n // hidden. Otherwise the board would render nothing, unmounting the widget\n // that owns an in-flight drag gesture and stranding the drag (React Aria's\n // `useMove` tears down its listeners on unmount, so the drop never fires).\n const nextWidth = el.offsetWidth;\n const nextHeight = el.offsetHeight;\n if (nextWidth > 0) setMeasuredWidth(nextWidth);\n if (nextHeight > 0) setMeasuredHeight(nextHeight);\n });\n useResizeObserver({ ref: containerRef, onResize: onResizeContainer });\n useEffect(() => {\n if (providedWidth == null) {\n onResizeContainer();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [providedWidth]);\n\n const {\n layout,\n layoutRef,\n placeholder,\n placeholderRef,\n setPlaceholder,\n applyLayout,\n } = useBoardLayout({\n layout: controlledLayout,\n defaultLayout,\n onLayoutChange,\n });\n\n // Re-render when any widget's registered content/config changes.\n useSyncExternalStore(registry.store.subscribe, registry.store.getVersion);\n\n // In aligned mode the board inherits the parent's gap so widget edges line up\n // with the surrounding layout; otherwise it uses its own `margin`.\n const effectiveMargin: readonly [number, number] = aligned\n ? parentMetrics!.margin\n : margin;\n // The board keeps its own padding (it sits inside the container's chrome);\n // when unspecified it defaults to the effective gap. An aligned nested board\n // is the exception: its grid origin must sit flush on the container widget's\n // edge (which already coincides with the parent's column-0 origin) so its\n // columns line up with the ancestor board's. Inheriting the gap there would\n // inset every column by one margin and break the alignment, so it defaults\n // to zero padding instead.\n const resolvedPadding: readonly [number, number] =\n containerPadding ?? (aligned ? [0, 0] : effectiveMargin);\n\n const rows = Math.max(\n bottom(layout),\n placeholder ? placeholder.y + placeholder.h : 0,\n );\n\n // Derive the aligned column count so each column keeps the parent's pixel\n // pitch: as the container widget is resized, columns are added/removed rather\n // than stretched. `containerWidth` is then back-solved so `calcGridColWidth`\n // returns exactly the parent's column width.\n const parentColWidth = aligned ? parentMetrics!.colWidth : 0;\n // `width` is `offsetWidth` (an integer the browser rounds), while\n // `parentColWidth` is fractional. A container sized to exactly N parent\n // columns can therefore measure a fraction of a pixel short, so a bare\n // `Math.floor` would drop the last column and leave its space unused. Add a\n // small pixel tolerance to absorb that rounding; it only rounds up when the\n // width is within ~2px of a full column, so it can't invent a column that\n // genuinely doesn't fit.\n const ALIGN_WIDTH_TOLERANCE = 2;\n const alignedCols =\n aligned && width > 0\n ? Math.max(\n 1,\n Math.floor(\n (width -\n resolvedPadding[0] * 2 +\n effectiveMargin[0] +\n ALIGN_WIDTH_TOLERANCE) /\n (parentColWidth + effectiveMargin[0]),\n ),\n )\n : cols;\n const effectiveCols = aligned ? alignedCols : cols;\n const effectiveContainerWidth = aligned\n ? parentColWidth * effectiveCols +\n effectiveMargin[0] * Math.max(0, effectiveCols - 1) +\n resolvedPadding[0] * 2\n : width;\n\n // An aligned board uses the parent's row height verbatim, so every cell is\n // exactly the parent's cell size (width already matches via the inherited\n // column pitch). It never shrinks rows to fit; pair it with an `isAutoHeight`\n // container so the widget grows to fit the rows at this height instead.\n const effectiveRowHeight = aligned ? parentMetrics!.rowHeight : rowHeight;\n\n const positionParams = useMemo<PositionParams>(\n () => ({\n margin: effectiveMargin,\n containerPadding: resolvedPadding,\n containerWidth: effectiveContainerWidth,\n cols: effectiveCols,\n rowHeight: effectiveRowHeight,\n maxRows,\n }),\n [\n effectiveMargin[0],\n effectiveMargin[1],\n resolvedPadding[0],\n resolvedPadding[1],\n effectiveContainerWidth,\n effectiveCols,\n effectiveRowHeight,\n maxRows,\n ],\n );\n\n // 'free' means no compaction (nothing is pushed up/left or recompacted) AND a\n // dragged widget never pushes or swaps its neighbours: it is placed exactly\n // where dropped. Without `allowOverlap` a move onto an occupied cell is\n // blocked (the widget stays at its last free spot); with `allowOverlap`\n // widgets may stack. The explicit `preventCollision` prop still applies to the\n // compacting modes (`vertical` / `horizontal`) and to the legacy `null` mode.\n const compactor = useMemo<Compactor>(\n () =>\n getCompactor(\n compactTypeToCore(compact),\n allowOverlap,\n compact === 'free' ? !allowOverlap : preventCollision,\n ),\n [compact, allowOverlap, preventCollision],\n );\n\n const resolvedConstraints = constraints ?? defaultConstraints;\n\n const computedHeight =\n rows > 0\n ? rows * effectiveRowHeight +\n Math.max(0, rows - 1) * effectiveMargin[1] +\n resolvedPadding[1] * 2\n : effectiveRowHeight;\n // An aligned board fills the height the container grants it, so it reports its\n // measured height; otherwise it reports the height its content needs.\n const containerHeight =\n aligned && measuredHeight > 0 ? measuredHeight : computedHeight;\n\n // Live refs so the stable registry entry always reads current values.\n const liveRef = useRef({\n positionParams,\n compactor,\n constraints: resolvedConstraints,\n maxRows,\n containerHeight,\n isDroppable,\n });\n liveRef.current = {\n positionParams,\n compactor,\n constraints: resolvedConstraints,\n maxRows,\n containerHeight,\n isDroppable,\n };\n\n const applyLayoutEvent = useEvent(applyLayout);\n const setPlaceholderEvent = useEvent(setPlaceholder);\n\n const entryRef = useRef<BoardEntry | null>(null);\n if (!entryRef.current) {\n entryRef.current = {\n id: boardId,\n getContentRect: () => contentRef.current?.getBoundingClientRect() ?? null,\n getContentNode: () => contentRef.current,\n getPositionParams: () => liveRef.current.positionParams,\n getConstraints: () => liveRef.current.constraints,\n getCompactor: () => liveRef.current.compactor,\n getMaxRows: () => liveRef.current.maxRows,\n getContainerHeight: () => liveRef.current.containerHeight,\n getLayout: () => layoutRef.current,\n applyLayout: (next, commit) => applyLayoutEvent(next, commit),\n setPlaceholder: (item) => setPlaceholderEvent(item),\n isDroppable: () => liveRef.current.isDroppable,\n };\n }\n\n useEffect(() => {\n const entry = entryRef.current!;\n // Keep the entry's id in sync with the (possibly changed) board id before\n // registering. The previous effect's cleanup has already removed the old id,\n // so registering here keys the entry under the current id.\n entry.id = boardId;\n return registry.registerBoard(entry);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [boardId]);\n\n // When the aligned column count changes (the container was resized), reflow\n // the layout to the new width: clamp items back into bounds and recompact so\n // nothing overflows the narrower/wider grid.\n const recompactForCols = useEvent((nextCols: number) => {\n const corrected = correctBounds(cloneLayout(layoutRef.current), {\n cols: nextCols,\n });\n const compacted = [\n ...liveRef.current.compactor.compact(corrected, nextCols),\n ];\n applyLayoutEvent(compacted, true);\n });\n // `null` until the first *measured* aligned column count is established. This\n // avoids treating the initial zero-width -> measured-width transition as a\n // column-count change: a board that measures its own width (no explicit\n // `width` prop) renders first with `width === 0`, so `effectiveCols` falls\n // back to `cols` and only becomes the derived aligned count once measured.\n // Seeding the baseline on that first measured value (without committing)\n // prevents an unsolicited reflow + `onLayoutChange` before the user interacts.\n const prevAlignedColsRef = useRef<number | null>(null);\n useEffect(() => {\n if (!aligned) {\n // Re-entering aligned mode should re-seed from the next measured value.\n prevAlignedColsRef.current = null;\n return;\n }\n // Wait for a real width measurement; the fallback-`cols` value that stands\n // in before measurement is not a meaningful aligned column count.\n if (width <= 0) return;\n if (prevAlignedColsRef.current === null) {\n prevAlignedColsRef.current = effectiveCols;\n return;\n }\n if (prevAlignedColsRef.current === effectiveCols) return;\n prevAlignedColsRef.current = effectiveCols;\n recompactForCols(effectiveCols);\n }, [aligned, width, effectiveCols, recompactForCols]);\n\n // Natural height this board wants: its rows at the (parent) row height. When\n // the container is shorter than this, an `isAutoHeight` host grows to fit it\n // (aligned boards no longer shrink their rows).\n const naturalHeight =\n rows > 0\n ? rows * effectiveRowHeight +\n Math.max(0, rows - 1) * effectiveMargin[1] +\n resolvedPadding[1] * 2\n : effectiveRowHeight;\n\n // Report this aligned board's height deficit to an auto-sizing host so the\n // host can both grow to fit and pin its resize floor. The value is signed:\n // positive when the board is squeezed (needs more height), negative when the\n // container is taller than needed (so the floor can be lowered). The host\n // never shrinks the widget on its own - it only grows and clamps resizing.\n const requestHeightDeficit = host?.requestHeightDeficit;\n useEffect(() => {\n if (!aligned || !host?.isAutoHeight || !requestHeightDeficit) return;\n if (measuredHeight <= 0) return;\n requestHeightDeficit(naturalHeight - measuredHeight);\n }, [\n aligned,\n host?.isAutoHeight,\n requestHeightDeficit,\n naturalHeight,\n measuredHeight,\n ]);\n\n // In-board resize orchestration.\n const resizeStateRef = useRef<{\n id: string;\n axis: ResizeHandleAxis;\n item: LayoutItem;\n origin: Position;\n accX: number;\n accY: number;\n } | null>(null);\n\n // Minimum rows each auto-height widget currently needs to fit its content.\n // Read during resize so a widget can never be dragged shorter than its\n // content, and used to grow the item when the content needs more room.\n const autoHeightMinRowsRef = useRef<Record<string, number>>({});\n\n const handleResize = useEvent(\n (\n id: string,\n axis: ResizeHandleAxis,\n phase: ResizePhase,\n dx: number,\n dy: number,\n ) => {\n const pp = liveRef.current.positionParams;\n\n if (phase === 'start') {\n const rawItem = getLayoutItem(layoutRef.current, id);\n if (!rawItem) return;\n // Layout-item min/max and constraints win; otherwise fall back to the\n // ones declared on the owning `Board.Widget` (and then the board-level\n // `widgetProps` defaults) so `applySizeConstraints` (via `minMaxSize`)\n // picks them up.\n const reg = registry.store.get(id);\n const item: LayoutItem = {\n ...rawItem,\n minW: rawItem.minW ?? reg?.minW ?? widgetProps?.minW,\n maxW: rawItem.maxW ?? reg?.maxW ?? widgetProps?.maxW,\n minH: rawItem.minH ?? reg?.minH ?? widgetProps?.minH,\n maxH: rawItem.maxH ?? reg?.maxH ?? widgetProps?.maxH,\n constraints:\n rawItem.constraints ?? reg?.constraints ?? widgetProps?.constraints,\n };\n resizeStateRef.current = {\n id,\n axis,\n item: { ...item },\n origin: calcGridItemPosition(pp, item.x, item.y, item.w, item.h),\n accX: 0,\n accY: 0,\n };\n setPlaceholder({ ...item });\n onResizeStart?.({\n layout: layoutRef.current,\n item: { ...item },\n oldItem: { ...item },\n placeholder: { ...item },\n });\n return;\n }\n\n const rs = resizeStateRef.current;\n if (!rs) return;\n\n if (phase === 'end') {\n const finalLayout = [...layoutRef.current];\n applyLayout(finalLayout, true);\n setPlaceholder(null);\n onResizeStop?.({\n layout: finalLayout,\n item: getLayoutItem(finalLayout, id) ?? rs.item,\n oldItem: rs.item,\n placeholder: null,\n });\n resizeStateRef.current = null;\n return;\n }\n\n rs.accX += dx;\n rs.accY += dy;\n\n const { origin, item, axis: handle } = rs;\n let newW = origin.width;\n let newH = origin.height;\n if (handle.includes('e')) newW = origin.width + rs.accX;\n if (handle.includes('w')) newW = origin.width - rs.accX;\n if (handle.includes('s')) newH = origin.height + rs.accY;\n if (handle.includes('n')) newH = origin.height - rs.accY;\n newW = Math.max(newW, 8);\n newH = Math.max(newH, 8);\n\n const raw = calcWH(pp, newW, newH, item.x, item.y, handle);\n const constrained = applySizeConstraints(\n liveRef.current.constraints,\n item,\n raw.w,\n raw.h,\n handle,\n {\n cols: pp.cols,\n maxRows: liveRef.current.maxRows,\n containerWidth: pp.containerWidth,\n containerHeight: liveRef.current.containerHeight,\n rowHeight: pp.rowHeight,\n margin: pp.margin,\n layout: layoutRef.current,\n },\n );\n\n // An auto-height widget cannot be resized shorter than the content it\n // hosts (a nested board) currently needs, so pin its height to the floor.\n const floorRows = autoHeightMinRowsRef.current[id] ?? 0;\n const finalW = constrained.w;\n const finalH = Math.max(constrained.h, floorRows);\n\n let x = item.x;\n let y = item.y;\n if (handle.includes('w')) x = item.x + item.w - finalW;\n if (handle.includes('n')) y = item.y + item.h - finalH;\n x = Math.max(0, x);\n y = Math.max(0, y);\n\n let newItem: LayoutItem = {\n ...item,\n x,\n y,\n w: finalW,\n h: finalH,\n };\n\n // Collision-blocking modes (`free` without `allowOverlap`, or an explicit\n // `preventCollision`) run a no-op/gap-filling compactor that never\n // resolves overlaps, so a resize must be blocked here the same way the\n // drag path blocks a move (`moveElement` reverts on collision). Without\n // this, growing or moving an edge via a resize handle could push the box\n // onto an occupied cell. When the new box overlaps a neighbour, revert to\n // the last committed box for this widget so the gesture stalls at the\n // last valid size/position instead of overlapping.\n const compactor = liveRef.current.compactor;\n if (compactor.preventCollision && !compactor.allowOverlap) {\n const collides = getAllCollisions(layoutRef.current, newItem).some(\n (other) => other.i !== id,\n );\n if (collides) {\n const lastValid = getLayoutItem(layoutRef.current, id);\n if (lastValid) newItem = { ...lastValid };\n }\n }\n\n const working = modifyLayout(layoutRef.current, newItem);\n const compacted = [...compactor.compact(working, pp.cols)];\n applyLayout(compacted, false);\n const nextPlaceholder = getLayoutItem(compacted, id) ?? newItem;\n setPlaceholder(nextPlaceholder);\n onResizeProp?.({\n layout: compacted,\n item: getLayoutItem(compacted, id) ?? newItem,\n oldItem: rs.item,\n placeholder: nextPlaceholder,\n });\n },\n );\n\n // Record an auto-height widget's needed rows. Grow the item when its content\n // needs more height (only ever increases); the stored value is also the\n // resize floor enforced in `handleResize`.\n const handleAutoHeight = useEvent((id: string, neededRows: number) => {\n autoHeightMinRowsRef.current[id] = neededRows;\n const current = getLayoutItem(layoutRef.current, id);\n if (!current || neededRows <= current.h) return;\n // While a drag or resize gesture is in flight the layout is transient - the\n // registry (drag) and `handleResize` write uncommitted previews and commit\n // only on drop / release. Growing an auto-height widget here with\n // `commit: true` would fire `onLayoutChange` mid-gesture and persist the\n // in-flight positions of the widget being moved. Skip the grow-commit; the\n // floor ref is already updated above (so `handleResize` still respects it),\n // and the deficit effect re-fires once the gesture settles.\n if (registry.dragState || resizeStateRef.current) return;\n const pp = liveRef.current.positionParams;\n const working = modifyLayout(layoutRef.current, {\n ...current,\n h: neededRows,\n });\n const compacted = [...liveRef.current.compactor.compact(working, pp.cols)];\n applyLayout(compacted, true);\n });\n\n // The dragged item captured at gesture start, so drag callbacks can report the\n // original position throughout (and after a cross-board transfer removes the\n // item from this board's layout).\n const dragOldItemRef = useRef<LayoutItem | null>(null);\n\n const handleDragLifecycle = useEvent((id: string, phase: ResizePhase) => {\n const currentLayout = layoutRef.current;\n const liveItem = getLayoutItem(currentLayout, id);\n\n if (phase === 'start') {\n dragOldItemRef.current = liveItem ? { ...liveItem } : null;\n }\n const oldItem = dragOldItemRef.current ?? liveItem;\n if (!oldItem) return;\n const item = liveItem ?? oldItem;\n\n const info: BoardInteractionInfo = {\n layout: currentLayout,\n item,\n oldItem,\n // Read the live ref, not render-time state: the registry calls\n // `setPlaceholder` synchronously right before this fires, and that only\n // schedules a re-render, so `placeholder` state still holds the previous\n // value (or a stale preview after the drop clears it to `null`).\n placeholder: placeholderRef.current,\n };\n if (phase === 'start') onDragStart?.(info);\n else if (phase === 'move') onDrag?.(info);\n else {\n onDragStop?.(info);\n dragOldItemRef.current = null;\n }\n });\n\n const styles: Styles = extractStyles(otherProps, CONTAINER_STYLES);\n\n const dragState = registry.dragState;\n const ready = width > 0;\n\n // When the widget that hosts this nested board is the one being dragged, its\n // whole content (including this board) floats as a single unit, so its own\n // grid lines add nothing but clutter. Suppress them for that drag.\n const hostWidgetIsDragging =\n !!dragState && dragState.nestedBoardIds.has(boardId);\n\n const placeholderStyle = placeholder\n ? (() => {\n const pos = calcGridItemPosition(\n positionParams,\n placeholder.x,\n placeholder.y,\n placeholder.w,\n placeholder.h,\n );\n return {\n left: `${pos.left}px`,\n top: `${pos.top}px`,\n width: `${pos.width}px`,\n height: `${pos.height}px`,\n };\n })()\n : null;\n\n const showPlaceholder = placeholder && placeholderStyle;\n\n const gridLinesVisible =\n !hostWidgetIsDragging &&\n (effectiveShowGridLines === true ||\n (effectiveShowGridLines === 'drag' && (!!dragState || !!placeholder)));\n const gridOverlayStyle = gridLinesVisible\n ? (() => {\n const colWidth = calcGridColWidth(positionParams);\n const rowHeightPx = positionParams.rowHeight;\n // A grid with margins has real gaps between cells, so any line-based\n // overlay either misses a cell edge (single line at the cell pitch) or\n // shows a double line in every gap (a line at both edges). Instead,\n // paint each snap cell as a faint block sized exactly `colWidth` x\n // `rowHeightPx` with the margin gaps left transparent: the blocks line\n // up 1:1 with the drop-zone placeholder and there are no lines to\n // double. Column stripes form the background; a row-band alpha mask\n // intersects them into cells.\n const pitchX = colWidth + effectiveMargin[0];\n const pitchY = rowHeightPx + effectiveMargin[1];\n // Position the overlay as an explicit rectangle inset by the board's\n // resolved padding and sized to exactly cover the grid content (cols x\n // rows). This makes the padding a symmetric frame on all four edges (the\n // previous `inset: 0` + top-left-anchored repeat left the padding\n // unvisualized on the right/bottom and inside any extra min-height) and\n // lets the cell pattern tile from the overlay's own origin.\n const padX = resolvedPadding[0];\n const padY = resolvedPadding[1];\n const gridWidth = Math.max(0, effectiveContainerWidth - padX * 2);\n const gridHeight =\n rows > 0 ? rows * rowHeightPx + (rows - 1) * effectiveMargin[1] : 0;\n const fill = 'var(--border-color)';\n const columns = `repeating-linear-gradient(to right, ${fill} 0, ${fill} ${colWidth}px, transparent ${colWidth}px, transparent ${pitchX}px)`;\n const rowsGrad = `repeating-linear-gradient(to bottom, #000 0, #000 ${rowHeightPx}px, transparent ${rowHeightPx}px, transparent ${pitchY}px)`;\n return {\n left: `${padX}px`,\n top: `${padY}px`,\n width: `${gridWidth}px`,\n height: `${gridHeight}px`,\n backgroundImage: columns,\n backgroundPosition: '0 0',\n backgroundRepeat: 'repeat',\n maskImage: rowsGrad,\n WebkitMaskImage: rowsGrad,\n maskPosition: '0 0',\n WebkitMaskPosition: '0 0',\n maskRepeat: 'repeat',\n WebkitMaskRepeat: 'repeat',\n };\n })()\n : null;\n\n // Metrics this board exposes to any aligned boards nested inside its widgets.\n const boardMetrics = useMemo<BoardMetrics>(\n () => ({\n colWidth: calcGridColWidth(positionParams),\n rowHeight: positionParams.rowHeight,\n margin: positionParams.margin,\n containerPadding: positionParams.containerPadding,\n }),\n [positionParams],\n );\n\n return (\n <BoardMetricsContext.Provider value={boardMetrics}>\n <BoardGridLinesContext.Provider\n value={\n effectiveShowGridLines === true || effectiveShowGridLines === 'drag'\n }\n >\n <BoardElement\n {...filterBaseProps(otherProps, { eventProps: true })}\n ref={containerRef}\n styles={styles}\n // Non-aligned: use min-height (not a fixed height) so the board\n // auto-sizes to its content by default but can still grow to fill a\n // taller parent. Widgets are absolutely positioned, so growing never\n // shifts them, and the content layer (inset: 0) always covers the full\n // board -> the whole board is droppable. Aligned: omit the inline height\n // so the board fills (and is bounded by) the space the container grants,\n // which is what drives the reduced row height.\n style={aligned ? undefined : { minHeight: `${containerHeight}px` }}\n mods={{\n dragging: !!dragState,\n 'drop-target': dragState?.currentBoardId === boardId,\n }}\n >\n <ContentLayer ref={contentRef}>\n {ready && gridOverlayStyle ? (\n <GridOverlayElement aria-hidden=\"true\" style={gridOverlayStyle} />\n ) : null}\n {ready\n ? layout.map((item) => {\n const registration = registry.store.get(item.i);\n const widgetDraggable =\n isDraggable &&\n (registration?.isDraggable ?? widgetProps?.isDraggable) !==\n false &&\n item.isDraggable !== false &&\n !item.static;\n const widgetResizable =\n isResizable &&\n (registration?.isResizable ?? widgetProps?.isResizable) !==\n false &&\n item.isResizable !== false &&\n !item.static;\n const handles =\n item.resizeHandles ??\n registration?.resizeHandles ??\n widgetProps?.resizeHandles ??\n resizeHandles;\n const widgetDragCancel =\n registration?.dragCancel ??\n widgetProps?.dragCancel ??\n dragCancel;\n const widgetDragHandle =\n registration?.dragHandle ??\n widgetProps?.dragHandle ??\n dragHandle;\n // Per-widget `isCard`/`styles` override the board-level\n // `widgetProps` defaults; `isCard` defaults to `false`\n // (borderless - widgets are always filled and rounded).\n const widgetIsCard =\n registration?.isCard ?? widgetProps?.isCard ?? false;\n // Per-widget `isAutoHeight`/`qa` fall back to the board-level\n // `widgetProps` defaults (mirroring the other widget props).\n const widgetIsAutoHeight =\n registration?.isAutoHeight ??\n widgetProps?.isAutoHeight ??\n false;\n const widgetQa = registration?.qa ?? widgetProps?.qa;\n // Merge board-level `widgetProps` styles (its `styles` object\n // plus direct style props) with the per-widget styles so\n // shared defaults survive when a widget sets even a single\n // style prop; per-widget styles win on conflicts. Only merge\n // when both exist to preserve reference stability (and avoid\n // churn) in the common single-source case.\n const widgetStyles =\n registration?.styles && widgetPropsStyles\n ? mergeStyles(widgetPropsStyles, registration.styles)\n : registration?.styles ?? widgetPropsStyles;\n\n return (\n <WidgetHost\n key={item.i}\n boardId={boardId}\n item={item}\n positionParams={positionParams}\n registration={registration}\n isCard={widgetIsCard}\n styles={widgetStyles as Styles}\n isDraggable={widgetDraggable}\n isResizable={widgetResizable}\n resizeHandles={handles}\n isAutoHeight={widgetIsAutoHeight}\n qa={widgetQa}\n dragCancel={widgetDragCancel}\n dragHandle={widgetDragHandle}\n registry={registry}\n dragState={dragState}\n onResize={handleResize}\n onAutoHeight={handleAutoHeight}\n onDragLifecycle={handleDragLifecycle}\n />\n );\n })\n : null}\n {showPlaceholder ? (\n <PlaceholderElement\n aria-hidden=\"true\"\n style={placeholderStyle!}\n />\n ) : null}\n </ContentLayer>\n {children}\n </BoardElement>\n </BoardGridLinesContext.Provider>\n </BoardMetricsContext.Provider>\n );\n}\n\nconst BoardInnerForwarded = forwardRef(BoardInner);\n\n/**\n * A draggable and resizable widget grid. Widgets are declared with\n * `Board.Widget` and positioned via a `layout`. Wrap multiple boards in a\n * `BoardProvider` to enable dragging widgets between them.\n */\nexport const Board = forwardRef(function Board(\n props: CubeBoardProps,\n ref: React.ForwardedRef<HTMLDivElement>,\n) {\n const existingRegistry = useBoardRegistry();\n\n if (existingRegistry) {\n return <BoardInnerForwarded {...props} ref={ref} />;\n }\n\n return (\n <BoardProvider>\n <BoardInnerForwarded {...props} ref={ref} />\n </BoardProvider>\n );\n});\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.144.0 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.145.1 | Cube Dev Team */
2
2
  import { BoardDragActiveContext, BoardRegistryContext } from "./board-context.js";
3
3
  import { useBoardRegistry } from "./use-board-registry.js";
4
4
  import { tasty } from "@tenphi/tasty";
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.144.0 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.145.1 | Cube Dev Team */
2
2
  import { useCombinedRefs } from "../../../utils/react/useCombinedRefs.js";
3
3
  import { useEvent } from "../../../_internal/hooks/use-event.js";
4
4
  import { getCompactor } from "./grid-core/compactors.js";
@@ -1,10 +1,10 @@
1
1
 
2
2
  import { LayoutConstraint, ResizeHandleAxis } from "./grid-core/types.js";
3
- import { Styles } from "@tenphi/tasty";
3
+ import { ContainerStyleProps, Styles } from "@tenphi/tasty";
4
4
  import { ReactNode } from "react";
5
5
 
6
6
  //#region src/components/layout/Board/Widget.d.ts
7
- interface CubeBoardWidgetProps {
7
+ interface CubeBoardWidgetProps extends ContainerStyleProps {
8
8
  /** Unique id, must match the `i` of a layout item in a `Board`. */
9
9
  id: string;
10
10
  /** Widget content. */
@@ -15,11 +15,31 @@ interface CubeBoardWidgetProps {
15
15
  isResizable?: boolean;
16
16
  /** Which resize handles to show (overrides the board default). */
17
17
  resizeHandles?: ResizeHandleAxis[];
18
+ /**
19
+ * Render this widget as a card by adding a border. Widgets are always filled
20
+ * (`#surface-2`) and rounded; `isCard` adds the border on top. Defaults to
21
+ * `false` (borderless) unless the owning `Board`'s `widgetProps.isCard` opts
22
+ * in. Override per widget to enable or disable.
23
+ */
24
+ isCard?: boolean;
25
+ /** Minimum width in grid columns (used when the layout item omits `minW`). */
26
+ minW?: number;
27
+ /** Maximum width in grid columns (used when the layout item omits `maxW`). */
28
+ maxW?: number;
29
+ /** Minimum height in grid rows (used when the layout item omits `minH`). */
30
+ minH?: number;
31
+ /** Maximum height in grid rows (used when the layout item omits `maxH`). */
32
+ maxH?: number;
18
33
  /** Per-widget layout constraints. */
19
34
  constraints?: LayoutConstraint[];
20
35
  /** Test id applied to the rendered widget element. */
21
36
  qa?: string;
22
- /** Style overrides applied to the rendered widget element. */
37
+ /**
38
+ * Style overrides applied to the rendered widget element. Individual style
39
+ * props (`fill`, `padding`, `radius`, `border`, ...) can also be passed
40
+ * directly on `Board.Widget`, just like on `Board`; they are merged into
41
+ * these styles (a direct prop wins over the same key in the `styles` object).
42
+ */
23
43
  styles?: Styles;
24
44
  /**
25
45
  * Grow this widget's height in its board to fit its content (only ever
@@ -1,17 +1,38 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.144.0 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.145.1 | Cube Dev Team */
2
+ import { extractStyles } from "../../../utils/styles.js";
2
3
  import { useLayoutEffect as useLayoutEffect$1 } from "../../../utils/react/useLayoutEffect.js";
3
4
  import { useBoardRegistry } from "./board-context.js";
5
+ import { CONTAINER_STYLES } from "@tenphi/tasty";
4
6
  import { useEffect, useRef } from "react";
5
7
 
6
8
  //#region src/components/layout/Board/Widget.tsx
7
9
  /**
10
+ * Shallow-compare two style maps by their top-level keys. Direct style props
11
+ * (e.g. `fill`) are primitives, so this reliably detects a real change while
12
+ * ignoring the fresh object identity `extractStyles` produces each render.
13
+ */
14
+ function shallowEqualStyles(a, b) {
15
+ if (a === b) return true;
16
+ if (!a || !b) return false;
17
+ const aKeys = Object.keys(a);
18
+ const bKeys = Object.keys(b);
19
+ if (aKeys.length !== bKeys.length) return false;
20
+ for (const key of aKeys) if (a[key] !== b[key]) return false;
21
+ return true;
22
+ }
23
+ /**
8
24
  * Declares a widget's content and per-widget options. Rendering and positioning
9
25
  * are performed by the owning `Board` (the component itself renders nothing),
10
26
  * which is what allows a widget to be transferred between boards.
11
27
  */
12
28
  function Widget(props) {
13
- const { id, children, isDraggable, isResizable, resizeHandles, constraints, qa, styles, isAutoHeight, dragCancel, dragHandle } = props;
29
+ const { id, children, isDraggable, isResizable, resizeHandles, isCard, minW, maxW, minH, maxH, constraints, qa, isAutoHeight, dragCancel, dragHandle } = props;
14
30
  const registry = useBoardRegistry();
31
+ const extractedStyles = extractStyles(props, CONTAINER_STYLES);
32
+ const nextStyles = Object.keys(extractedStyles).length > 0 ? extractedStyles : void 0;
33
+ const stylesRef = useRef(void 0);
34
+ if (!shallowEqualStyles(stylesRef.current, nextStyles)) stylesRef.current = nextStyles;
35
+ const styles = stylesRef.current;
15
36
  const ownerRef = useRef({});
16
37
  useLayoutEffect$1(() => {
17
38
  registry?.store.register({
@@ -20,6 +41,11 @@ function Widget(props) {
20
41
  isDraggable,
21
42
  isResizable,
22
43
  resizeHandles,
44
+ isCard,
45
+ minW,
46
+ maxW,
47
+ minH,
48
+ maxH,
23
49
  constraints,
24
50
  qa,
25
51
  styles,
@@ -1 +1 @@
1
- {"version":3,"file":"Widget.js","names":[],"sources":["../../../../src/components/layout/Board/Widget.tsx"],"sourcesContent":["import { Styles } from '@tenphi/tasty';\nimport { ReactNode, useEffect, useRef } from 'react';\n\nimport { useLayoutEffect } from '../../../utils/react';\n\nimport { useBoardRegistry } from './board-context';\nimport { LayoutConstraint, ResizeHandleAxis } from './grid-core';\n\nexport interface CubeBoardWidgetProps {\n /** Unique id, must match the `i` of a layout item in a `Board`. */\n id: string;\n /** Widget content. */\n children?: ReactNode;\n /** Disable dragging for this widget. */\n isDraggable?: boolean;\n /** Disable resizing for this widget. */\n isResizable?: boolean;\n /** Which resize handles to show (overrides the board default). */\n resizeHandles?: ResizeHandleAxis[];\n /** Per-widget layout constraints. */\n constraints?: LayoutConstraint[];\n /** Test id applied to the rendered widget element. */\n qa?: string;\n /** Style overrides applied to the rendered widget element. */\n styles?: Styles;\n /**\n * Grow this widget's height in its board to fit its content (only ever\n * increases). Pair with a nested `Board isAligned` to make the container\n * expand until the inner board's rows fit at the parent's row height.\n */\n isAutoHeight?: boolean;\n /**\n * CSS selector for elements that must not start a pointer drag inside this\n * widget (overrides the board's `dragCancel`).\n */\n dragCancel?: string;\n /**\n * CSS selector for the only elements from which a pointer drag may start\n * inside this widget (overrides the board's `dragHandle`).\n */\n dragHandle?: string;\n}\n\n/**\n * Declares a widget's content and per-widget options. Rendering and positioning\n * are performed by the owning `Board` (the component itself renders nothing),\n * which is what allows a widget to be transferred between boards.\n */\nexport function Widget(props: CubeBoardWidgetProps) {\n const {\n id,\n children,\n isDraggable,\n isResizable,\n resizeHandles,\n constraints,\n qa,\n styles,\n isAutoHeight,\n dragCancel,\n dragHandle,\n } = props;\n const registry = useBoardRegistry();\n\n // Stable per-instance token so a stale unregister (from an unmounting copy of\n // this widget) can't wipe out a newer instance's registration.\n const ownerRef = useRef({});\n\n // Register/update content on every render so content stays fresh in the store.\n useLayoutEffect(() => {\n registry?.store.register(\n {\n id,\n content: children,\n isDraggable,\n isResizable,\n resizeHandles,\n constraints,\n qa,\n styles,\n isAutoHeight,\n dragCancel,\n dragHandle,\n },\n ownerRef.current,\n );\n });\n\n // Remove from the store on unmount.\n useEffect(() => {\n const owner = ownerRef.current;\n return () => {\n registry?.store.unregister(id, owner);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [id]);\n\n return null;\n}\n"],"mappings":";;;;;;;;;;;AAgDA,SAAgB,OAAO,OAA6B;CAClD,MAAM,EACJ,IACA,UACA,aACA,aACA,eACA,aACA,IACA,QACA,cACA,YACA,eACE;CACJ,MAAM,WAAW,kBAAkB;CAInC,MAAM,WAAW,OAAO,EAAE,CAAC;AAG3B,yBAAsB;AACpB,YAAU,MAAM,SACd;GACE;GACA,SAAS;GACT;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD,EACD,SAAS,QACV;GACD;AAGF,iBAAgB;EACd,MAAM,QAAQ,SAAS;AACvB,eAAa;AACX,aAAU,MAAM,WAAW,IAAI,MAAM;;IAGtC,CAAC,GAAG,CAAC;AAER,QAAO"}
1
+ {"version":3,"file":"Widget.js","names":[],"sources":["../../../../src/components/layout/Board/Widget.tsx"],"sourcesContent":["import { CONTAINER_STYLES, ContainerStyleProps, Styles } from '@tenphi/tasty';\nimport { ReactNode, useEffect, useRef } from 'react';\n\nimport { useLayoutEffect } from '../../../utils/react';\nimport { extractStyles } from '../../../utils/styles';\n\nimport { useBoardRegistry } from './board-context';\nimport { LayoutConstraint, ResizeHandleAxis } from './grid-core';\n\nexport interface CubeBoardWidgetProps extends ContainerStyleProps {\n /** Unique id, must match the `i` of a layout item in a `Board`. */\n id: string;\n /** Widget content. */\n children?: ReactNode;\n /** Disable dragging for this widget. */\n isDraggable?: boolean;\n /** Disable resizing for this widget. */\n isResizable?: boolean;\n /** Which resize handles to show (overrides the board default). */\n resizeHandles?: ResizeHandleAxis[];\n /**\n * Render this widget as a card by adding a border. Widgets are always filled\n * (`#surface-2`) and rounded; `isCard` adds the border on top. Defaults to\n * `false` (borderless) unless the owning `Board`'s `widgetProps.isCard` opts\n * in. Override per widget to enable or disable.\n */\n isCard?: boolean;\n /** Minimum width in grid columns (used when the layout item omits `minW`). */\n minW?: number;\n /** Maximum width in grid columns (used when the layout item omits `maxW`). */\n maxW?: number;\n /** Minimum height in grid rows (used when the layout item omits `minH`). */\n minH?: number;\n /** Maximum height in grid rows (used when the layout item omits `maxH`). */\n maxH?: number;\n /** Per-widget layout constraints. */\n constraints?: LayoutConstraint[];\n /** Test id applied to the rendered widget element. */\n qa?: string;\n /**\n * Style overrides applied to the rendered widget element. Individual style\n * props (`fill`, `padding`, `radius`, `border`, ...) can also be passed\n * directly on `Board.Widget`, just like on `Board`; they are merged into\n * these styles (a direct prop wins over the same key in the `styles` object).\n */\n styles?: Styles;\n /**\n * Grow this widget's height in its board to fit its content (only ever\n * increases). Pair with a nested `Board isAligned` to make the container\n * expand until the inner board's rows fit at the parent's row height.\n */\n isAutoHeight?: boolean;\n /**\n * CSS selector for elements that must not start a pointer drag inside this\n * widget (overrides the board's `dragCancel`).\n */\n dragCancel?: string;\n /**\n * CSS selector for the only elements from which a pointer drag may start\n * inside this widget (overrides the board's `dragHandle`).\n */\n dragHandle?: string;\n}\n\n/**\n * Shallow-compare two style maps by their top-level keys. Direct style props\n * (e.g. `fill`) are primitives, so this reliably detects a real change while\n * ignoring the fresh object identity `extractStyles` produces each render.\n */\nfunction shallowEqualStyles(a?: Styles, b?: Styles): boolean {\n if (a === b) return true;\n if (!a || !b) return false;\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n if (aKeys.length !== bKeys.length) return false;\n for (const key of aKeys) {\n if (\n (a as Record<string, unknown>)[key] !==\n (b as Record<string, unknown>)[key]\n ) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Declares a widget's content and per-widget options. Rendering and positioning\n * are performed by the owning `Board` (the component itself renders nothing),\n * which is what allows a widget to be transferred between boards.\n */\nexport function Widget(props: CubeBoardWidgetProps) {\n const {\n id,\n children,\n isDraggable,\n isResizable,\n resizeHandles,\n isCard,\n minW,\n maxW,\n minH,\n maxH,\n constraints,\n qa,\n isAutoHeight,\n dragCancel,\n dragHandle,\n } = props;\n const registry = useBoardRegistry();\n\n // Collect direct style props (e.g. `fill`, `padding`, `radius`) and merge them\n // with the explicit `styles` prop, mirroring how `Board` extracts its own\n // styles. Fall back to `undefined` when nothing was provided so widgets with\n // no styling keep a stable registration (avoids needless store churn).\n const extractedStyles = extractStyles(props, CONTAINER_STYLES);\n const nextStyles =\n Object.keys(extractedStyles).length > 0 ? extractedStyles : undefined;\n\n // `extractStyles` returns a fresh object every render, so passing it straight\n // to `register` would make the store treat every render as a style change,\n // bump its version, and re-render the hosting board in a loop. Keep a stable\n // reference across renders and only swap it when the shallow style values\n // actually change (direct props are primitives; a `styles` object is compared\n // per top-level key).\n const stylesRef = useRef<Styles | undefined>(undefined);\n if (!shallowEqualStyles(stylesRef.current, nextStyles)) {\n stylesRef.current = nextStyles;\n }\n const styles = stylesRef.current;\n\n // Stable per-instance token so a stale unregister (from an unmounting copy of\n // this widget) can't wipe out a newer instance's registration.\n const ownerRef = useRef({});\n\n // Register/update content on every render so content stays fresh in the store.\n useLayoutEffect(() => {\n registry?.store.register(\n {\n id,\n content: children,\n isDraggable,\n isResizable,\n resizeHandles,\n isCard,\n minW,\n maxW,\n minH,\n maxH,\n constraints,\n qa,\n styles,\n isAutoHeight,\n dragCancel,\n dragHandle,\n },\n ownerRef.current,\n );\n });\n\n // Remove from the store on unmount.\n useEffect(() => {\n const owner = ownerRef.current;\n return () => {\n registry?.store.unregister(id, owner);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [id]);\n\n return null;\n}\n"],"mappings":";;;;;;;;;;;;;AAqEA,SAAS,mBAAmB,GAAY,GAAqB;AAC3D,KAAI,MAAM,EAAG,QAAO;AACpB,KAAI,CAAC,KAAK,CAAC,EAAG,QAAO;CACrB,MAAM,QAAQ,OAAO,KAAK,EAAE;CAC5B,MAAM,QAAQ,OAAO,KAAK,EAAE;AAC5B,KAAI,MAAM,WAAW,MAAM,OAAQ,QAAO;AAC1C,MAAK,MAAM,OAAO,MAChB,KACG,EAA8B,SAC9B,EAA8B,KAE/B,QAAO;AAGX,QAAO;;;;;;;AAQT,SAAgB,OAAO,OAA6B;CAClD,MAAM,EACJ,IACA,UACA,aACA,aACA,eACA,QACA,MACA,MACA,MACA,MACA,aACA,IACA,cACA,YACA,eACE;CACJ,MAAM,WAAW,kBAAkB;CAMnC,MAAM,kBAAkB,cAAc,OAAO,iBAAiB;CAC9D,MAAM,aACJ,OAAO,KAAK,gBAAgB,CAAC,SAAS,IAAI,kBAAkB;CAQ9D,MAAM,YAAY,OAA2B,OAAU;AACvD,KAAI,CAAC,mBAAmB,UAAU,SAAS,WAAW,CACpD,WAAU,UAAU;CAEtB,MAAM,SAAS,UAAU;CAIzB,MAAM,WAAW,OAAO,EAAE,CAAC;AAG3B,yBAAsB;AACpB,YAAU,MAAM,SACd;GACE;GACA,SAAS;GACT;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD,EACD,SAAS,QACV;GACD;AAGF,iBAAgB;EACd,MAAM,QAAQ,SAAS;AACvB,eAAa;AACX,aAAU,MAAM,WAAW,IAAI,MAAM;;IAGtC,CAAC,GAAG,CAAC;AAER,QAAO"}
@@ -1,4 +1,4 @@
1
- /** @license MIT | @cube-dev/ui-kit v0.144.0 | Cube Dev Team */
1
+ /** @license MIT | @cube-dev/ui-kit v0.145.1 | Cube Dev Team */
2
2
  import { mergeProps as mergeProps$1 } from "../../../utils/react/mergeProps.js";
3
3
  import { useEvent } from "../../../_internal/hooks/use-event.js";
4
4
  import { BoardHostContext } from "./board-context.js";
@@ -21,11 +21,15 @@ const WidgetElement = tasty({
21
21
  position: "absolute",
22
22
  top: 0,
23
23
  left: 0,
24
- fill: "#surface",
24
+ fill: "#surface-2",
25
25
  radius: "1cr",
26
- border: true,
26
+ border: {
27
+ "": false,
28
+ card: true
29
+ },
27
30
  shadow: {
28
31
  "": false,
32
+ "hovered & !card & (draggable | resizing)": "0 0 0 1bw #border",
29
33
  "drag | resizing": "$dialog-shadow"
30
34
  },
31
35
  zIndex: {
@@ -36,7 +40,10 @@ const WidgetElement = tasty({
36
40
  "": 1,
37
41
  floating: .8
38
42
  },
39
- transition: "theme, shadow, opacity",
43
+ transition: {
44
+ "": "theme, shadow, opacity, inset",
45
+ "drag | floating | resizing": "theme, shadow, opacity"
46
+ },
40
47
  boxSizing: "border-box",
41
48
  userSelect: {
42
49
  "": "auto",
@@ -245,10 +252,9 @@ function ResizeHandle({ axis, onResize }) {
245
252
  * renders into the shared overlay portal so it can float outside its board.
246
253
  */
247
254
  function WidgetHost(props) {
248
- const { boardId, item, positionParams, registration, isDraggable, isResizable, resizeHandles, dragCancel, dragHandle, registry, dragState, onResize, onAutoHeight, onDragLifecycle } = props;
255
+ const { boardId, item, positionParams, registration, isCard, styles: widgetStyles, isDraggable, isResizable, resizeHandles, isAutoHeight, qa, dragCancel, dragHandle, registry, dragState, onResize, onAutoHeight, onDragLifecycle } = props;
249
256
  const hostRef = useRef(null);
250
257
  const isActiveDrag = dragState?.itemId === item.i;
251
- const isAutoHeight = registration?.isAutoHeight === true;
252
258
  const requestHeightDeficit = useEvent((deficitPx) => {
253
259
  if (!isAutoHeight || isActiveDrag) return;
254
260
  const step = positionParams.rowHeight + positionParams.margin[1];
@@ -307,7 +313,7 @@ function WidgetHost(props) {
307
313
  const a11yProps = {
308
314
  tabIndex: isDraggable ? 0 : void 0,
309
315
  "aria-roledescription": isDraggable ? "Draggable widget" : void 0,
310
- "aria-label": registration?.qa ?? item.i
316
+ "aria-label": qa ?? item.i
311
317
  };
312
318
  const stopBubbleProps = isDraggable ? {
313
319
  onPointerDown: (e) => e.stopPropagation(),
@@ -319,7 +325,7 @@ function WidgetHost(props) {
319
325
  if (dragHandle && !target.closest(dragHandle)) return true;
320
326
  return !!(dragCancel && target.closest(dragCancel));
321
327
  };
322
- const gatedMoveProps = isDraggable && (dragHandle || dragCancel) ? {
328
+ const gatedMoveProps = !isDraggable ? {} : dragHandle || dragCancel ? {
323
329
  ...moveProps,
324
330
  ...moveProps.onPointerDown && { onPointerDown: (e) => {
325
331
  if (shouldGateDrag(e.target)) return;
@@ -343,7 +349,9 @@ function WidgetHost(props) {
343
349
  drag: isActiveDrag,
344
350
  draggable: isDraggable && !isActiveDrag,
345
351
  static: !!item.static,
346
- resizing: isResizing
352
+ resizing: isResizing,
353
+ card: isCard,
354
+ hovered: isHovered
347
355
  };
348
356
  const content = /* @__PURE__ */ jsxs(BoardHostContext.Provider, {
349
357
  value: hostValue,
@@ -378,7 +386,8 @@ function WidgetHost(props) {
378
386
  const overlayNode = registry.overlayRef.current;
379
387
  const floatInOverlay = useOverlay && !!overlayNode && !!dragState;
380
388
  const hostStyle = {
381
- transform: `translate(${pos.left}px, ${pos.top}px)`,
389
+ left: `${pos.left}px`,
390
+ top: `${pos.top}px`,
382
391
  width: `${pos.width}px`,
383
392
  height: `${pos.height}px`,
384
393
  ...floatInOverlay ? {
@@ -394,9 +403,9 @@ function WidgetHost(props) {
394
403
  ref: hostRef,
395
404
  "data-board-widget-host": "",
396
405
  ...mergeProps$1(gatedMoveProps, stopBubbleProps, hoverProps, focusWithinProps, a11yProps, { style: hostStyle }),
397
- qa: registration?.qa,
406
+ qa,
398
407
  mods: hostMods,
399
- styles: registration?.styles,
408
+ styles: widgetStyles,
400
409
  children: floatInOverlay ? null : content
401
410
  }), floatInOverlay ? createPortal(/* @__PURE__ */ jsx(WidgetElement, {
402
411
  style: {
@@ -412,7 +421,7 @@ function WidgetHost(props) {
412
421
  drag: true,
413
422
  floating: true
414
423
  },
415
- styles: registration?.styles,
424
+ styles: widgetStyles,
416
425
  "aria-hidden": "true",
417
426
  children: content
418
427
  }), overlayNode) : null] });