@cube-dev/ui-kit 0.155.0 → 0.157.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (652) hide show
  1. package/dist/CHANGELOG.md +284 -0
  2. package/dist/_internal/hooks/use-chained-callback.js +1 -1
  3. package/dist/_internal/hooks/use-debounced-value.js +1 -1
  4. package/dist/_internal/hooks/use-deprecation-warning.js +1 -1
  5. package/dist/_internal/hooks/use-event.js +1 -1
  6. package/dist/_internal/hooks/use-is-first-render.js +1 -1
  7. package/dist/_internal/hooks/use-sync-ref.js +1 -1
  8. package/dist/_internal/hooks/use-timer/timer.js +1 -1
  9. package/dist/_internal/hooks/use-timer/use-timer.js +1 -1
  10. package/dist/_internal/hooks/use-warn.js +1 -1
  11. package/dist/components/Block.js +1 -1
  12. package/dist/components/CollectionItem.js +1 -1
  13. package/dist/components/GlobalStyles.js +1 -1
  14. package/dist/components/GridProvider.js +1 -1
  15. package/dist/components/HiddenInput.js +1 -1
  16. package/dist/components/Root.js +1 -1
  17. package/dist/components/actions/Action/Action.js +1 -1
  18. package/dist/components/actions/Banner/Banner.js +1 -1
  19. package/dist/components/actions/Button/Button.js +1 -1
  20. package/dist/components/actions/ButtonGroup/ButtonGroup.js +1 -1
  21. package/dist/components/actions/ButtonSplit/ButtonSplit.js +1 -1
  22. package/dist/components/actions/ButtonSplit/context.js +1 -1
  23. package/dist/components/actions/CommandMenu/CommandMenu.d.ts +10 -1
  24. package/dist/components/actions/CommandMenu/CommandMenu.js +4 -3
  25. package/dist/components/actions/CommandMenu/CommandMenu.js.map +1 -1
  26. package/dist/components/actions/CommandMenu/styled.js +1 -1
  27. package/dist/components/actions/ItemAction/ItemAction.js +1 -1
  28. package/dist/components/actions/ItemActionContext.js +1 -1
  29. package/dist/components/actions/ItemButton/ItemButton.js +1 -1
  30. package/dist/components/actions/Link/Link.js +1 -1
  31. package/dist/components/actions/Menu/Menu.js +1 -1
  32. package/dist/components/actions/Menu/MenuItem.js +1 -1
  33. package/dist/components/actions/Menu/MenuSection.js +1 -1
  34. package/dist/components/actions/Menu/MenuTrigger.js +1 -1
  35. package/dist/components/actions/Menu/SubMenuTrigger.js +1 -1
  36. package/dist/components/actions/Menu/SubmenuTriggerContext.js +1 -1
  37. package/dist/components/actions/Menu/context.js +1 -1
  38. package/dist/components/actions/Menu/styled.js +1 -1
  39. package/dist/components/actions/index.js +1 -1
  40. package/dist/components/actions/use-action.js +1 -1
  41. package/dist/components/actions/use-anchored-menu.js +1 -1
  42. package/dist/components/actions/use-context-menu.js +42 -44
  43. package/dist/components/actions/use-context-menu.js.map +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/InfoBadge/InfoBadge.js +1 -1
  59. package/dist/components/content/InlineInput/InlineInput.js +1 -1
  60. package/dist/components/content/Item/Item.js +1 -1
  61. package/dist/components/content/ItemBadge/ItemBadge.js +1 -1
  62. package/dist/components/content/ItemCard/ItemCard.js +1 -1
  63. package/dist/components/content/Layout/GridLayout.js +1 -1
  64. package/dist/components/content/Layout/Layout.js +1 -1
  65. package/dist/components/content/Layout/LayoutBlock.js +1 -1
  66. package/dist/components/content/Layout/LayoutCenter.js +1 -1
  67. package/dist/components/content/Layout/LayoutContainer.js +1 -1
  68. package/dist/components/content/Layout/LayoutContent.js +1 -1
  69. package/dist/components/content/Layout/LayoutContext.js +1 -1
  70. package/dist/components/content/Layout/LayoutFlex.js +1 -1
  71. package/dist/components/content/Layout/LayoutFooter.js +1 -1
  72. package/dist/components/content/Layout/LayoutGrid.js +1 -1
  73. package/dist/components/content/Layout/LayoutHeader.js +1 -1
  74. package/dist/components/content/Layout/LayoutPane.js +1 -1
  75. package/dist/components/content/Layout/LayoutPanel.js +1 -1
  76. package/dist/components/content/Layout/LayoutPanelHeader.js +1 -1
  77. package/dist/components/content/Layout/LayoutToolbar.js +1 -1
  78. package/dist/components/content/Layout/hooks/useTinyScrollbar.js +1 -1
  79. package/dist/components/content/Layout/index.js +1 -1
  80. package/dist/components/content/Layout/utils.js +1 -1
  81. package/dist/components/content/Paragraph.js +1 -1
  82. package/dist/components/content/Placeholder/Placeholder.js +1 -1
  83. package/dist/components/content/PrismCode/PrismCode.js +1 -1
  84. package/dist/components/content/PrismCode/prismSetup.js +1 -1
  85. package/dist/components/content/PrismDiffCode/PrismDiffCode.js +1 -1
  86. package/dist/components/content/Result/Result.js +1 -1
  87. package/dist/components/content/Skeleton/Skeleton.js +1 -1
  88. package/dist/components/content/Tag/Tag.js +2 -2
  89. package/dist/components/content/Tag/Tag.js.map +1 -1
  90. package/dist/components/content/Text.d.ts +14 -14
  91. package/dist/components/content/Text.js +1 -1
  92. package/dist/components/content/TextItem/TextItem.js +1 -1
  93. package/dist/components/content/Title.js +1 -1
  94. package/dist/components/content/Tree/Tree.js +1 -1
  95. package/dist/components/content/Tree/TreeNode.js +1 -1
  96. package/dist/components/content/Tree/styled.js +1 -1
  97. package/dist/components/content/Tree/tree-index.js +1 -1
  98. package/dist/components/content/Tree/use-checkbox-tree.js +1 -1
  99. package/dist/components/content/Tree/use-load-data.js +1 -1
  100. package/dist/components/content/highlightText.js +1 -1
  101. package/dist/components/content/use-auto-tooltip.js +1 -1
  102. package/dist/components/data/DataTable/DataTable.d.ts +13 -0
  103. package/dist/components/data/DataTable/DataTable.js +246 -0
  104. package/dist/components/data/DataTable/DataTable.js.map +1 -0
  105. package/dist/components/data/DataTable/index.d.ts +3 -0
  106. package/dist/components/data/DataTable/types.d.ts +145 -0
  107. package/dist/components/data/ItemTable/ItemTable.d.ts +19 -0
  108. package/dist/components/data/ItemTable/ItemTable.js +350 -0
  109. package/dist/components/data/ItemTable/ItemTable.js.map +1 -0
  110. package/dist/components/data/ItemTable/ItemTableBulkBar.d.ts +23 -0
  111. package/dist/components/data/ItemTable/ItemTableBulkBar.js +131 -0
  112. package/dist/components/data/ItemTable/ItemTableBulkBar.js.map +1 -0
  113. package/dist/components/data/ItemTable/ItemTableDragPreview.js +46 -0
  114. package/dist/components/data/ItemTable/ItemTableDragPreview.js.map +1 -0
  115. package/dist/components/data/ItemTable/ItemTableFooter.js +79 -0
  116. package/dist/components/data/ItemTable/ItemTableFooter.js.map +1 -0
  117. package/dist/components/data/ItemTable/ItemTableToolbar.d.ts +34 -0
  118. package/dist/components/data/ItemTable/ItemTableToolbar.js +91 -0
  119. package/dist/components/data/ItemTable/ItemTableToolbar.js.map +1 -0
  120. package/dist/components/data/ItemTable/index.d.ts +4 -0
  121. package/dist/components/data/ItemTable/types.d.ts +327 -0
  122. package/dist/components/data/TableBase/ColumnResizer.js +70 -0
  123. package/dist/components/data/TableBase/ColumnResizer.js.map +1 -0
  124. package/dist/components/data/TableBase/RowCollection.js +99 -0
  125. package/dist/components/data/TableBase/RowCollection.js.map +1 -0
  126. package/dist/components/data/TableBase/TableRow.js +89 -0
  127. package/dist/components/data/TableBase/TableRow.js.map +1 -0
  128. package/dist/components/data/TableBase/TableView.d.ts +22 -0
  129. package/dist/components/data/TableBase/TableView.js +921 -0
  130. package/dist/components/data/TableBase/TableView.js.map +1 -0
  131. package/dist/components/data/TableBase/index.d.ts +5 -0
  132. package/dist/components/data/TableBase/row-menu.js +40 -0
  133. package/dist/components/data/TableBase/row-menu.js.map +1 -0
  134. package/dist/components/data/TableBase/styled.d.ts +5 -0
  135. package/dist/components/data/TableBase/styled.js +532 -0
  136. package/dist/components/data/TableBase/styled.js.map +1 -0
  137. package/dist/components/data/TableBase/types.d.ts +160 -0
  138. package/dist/components/data/TableBase/types.js +31 -0
  139. package/dist/components/data/TableBase/types.js.map +1 -0
  140. package/dist/components/data/TableBase/use-cell-selection.d.ts +3 -0
  141. package/dist/components/data/TableBase/use-cell-selection.js +0 -0
  142. package/dist/components/data/TableBase/use-cell-selection.js.map +1 -0
  143. package/dist/components/data/TableBase/use-container-width.js +35 -0
  144. package/dist/components/data/TableBase/use-container-width.js.map +1 -0
  145. package/dist/components/data/TableBase/use-row-move-animation.js +90 -0
  146. package/dist/components/data/TableBase/use-row-move-animation.js.map +1 -0
  147. package/dist/components/data/TableBase/use-scrollability.js +49 -0
  148. package/dist/components/data/TableBase/use-scrollability.js.map +1 -0
  149. package/dist/components/data/TableBase/use-table-columns.d.ts +2 -0
  150. package/dist/components/data/TableBase/use-table-columns.js +166 -0
  151. package/dist/components/data/TableBase/use-table-columns.js.map +1 -0
  152. package/dist/components/data/TableBase/use-table-search.js +64 -0
  153. package/dist/components/data/TableBase/use-table-search.js.map +1 -0
  154. package/dist/components/data/TableBase/use-table-selection.d.ts +4 -0
  155. package/dist/components/data/TableBase/use-table-selection.js +233 -0
  156. package/dist/components/data/TableBase/use-table-selection.js.map +1 -0
  157. package/dist/components/data/TableBase/use-table-sort.js +91 -0
  158. package/dist/components/data/TableBase/use-table-sort.js.map +1 -0
  159. package/dist/components/data/TableBase/use-table-sorts.js +97 -0
  160. package/dist/components/data/TableBase/use-table-sorts.js.map +1 -0
  161. package/dist/components/data/TableBase/use-table-storage.d.ts +8 -0
  162. package/dist/components/data/TableBase/use-table-storage.js +58 -0
  163. package/dist/components/data/TableBase/use-table-storage.js.map +1 -0
  164. package/dist/components/data/index.d.ts +10 -0
  165. package/dist/components/fields/Checkbox/Checkbox.js +1 -1
  166. package/dist/components/fields/Checkbox/CheckboxGroup.js +1 -1
  167. package/dist/components/fields/Checkbox/context.js +1 -1
  168. package/dist/components/fields/ColorInput/ColorInput.d.ts +67 -0
  169. package/dist/components/fields/ColorInput/ColorInput.js +230 -0
  170. package/dist/components/fields/ColorInput/ColorInput.js.map +1 -0
  171. package/dist/components/fields/ColorInput/index.d.ts +2 -0
  172. package/dist/components/fields/ColorPicker/ColorPicker.d.ts +64 -0
  173. package/dist/components/fields/ColorPicker/ColorPicker.js +189 -0
  174. package/dist/components/fields/ColorPicker/ColorPicker.js.map +1 -0
  175. package/dist/components/fields/ColorPicker/index.d.ts +2 -0
  176. package/dist/components/fields/ColorSwatchGroup/ColorSwatchGroup.d.ts +50 -0
  177. package/dist/components/fields/ColorSwatchGroup/ColorSwatchGroup.js +269 -0
  178. package/dist/components/fields/ColorSwatchGroup/ColorSwatchGroup.js.map +1 -0
  179. package/dist/components/fields/ColorSwatchGroup/index.d.ts +2 -0
  180. package/dist/components/fields/ComboBox/ComboBox.js +1 -1
  181. package/dist/components/fields/CommandTextArea/CommandTextArea.js +1 -1
  182. package/dist/components/fields/CommandTextArea/caretPosition.js +1 -1
  183. package/dist/components/fields/CommandTextArea/useCaretAnchor.js +1 -1
  184. package/dist/components/fields/DatePicker/DateInput.js +1 -1
  185. package/dist/components/fields/DatePicker/DateInputBase.js +1 -1
  186. package/dist/components/fields/DatePicker/DatePicker.js +1 -1
  187. package/dist/components/fields/DatePicker/DatePickerButton.js +1 -1
  188. package/dist/components/fields/DatePicker/DatePickerElement.js +1 -1
  189. package/dist/components/fields/DatePicker/DatePickerInput.js +1 -1
  190. package/dist/components/fields/DatePicker/DatePickerSegment.js +1 -1
  191. package/dist/components/fields/DatePicker/DateRangePicker.js +1 -1
  192. package/dist/components/fields/DatePicker/DateRangeSeparatedPicker.js +1 -1
  193. package/dist/components/fields/DatePicker/MonthPicker.js +1 -1
  194. package/dist/components/fields/DatePicker/PeriodPicker.js +1 -1
  195. package/dist/components/fields/DatePicker/QuarterPicker.js +1 -1
  196. package/dist/components/fields/DatePicker/TimeInput.js +1 -1
  197. package/dist/components/fields/DatePicker/WeekPicker.js +1 -1
  198. package/dist/components/fields/DatePicker/YearPicker.js +1 -1
  199. package/dist/components/fields/DatePicker/parseDate.js +1 -1
  200. package/dist/components/fields/DatePicker/period.js +1 -1
  201. package/dist/components/fields/DatePicker/props.js +1 -1
  202. package/dist/components/fields/DatePicker/utils.js +1 -1
  203. package/dist/components/fields/FileInput/FileInput.js +1 -1
  204. package/dist/components/fields/FilterListBox/FilterListBox.d.ts +3 -3
  205. package/dist/components/fields/FilterListBox/FilterListBox.js +8 -6
  206. package/dist/components/fields/FilterListBox/FilterListBox.js.map +1 -1
  207. package/dist/components/fields/FilterPicker/FilterPicker.js +6 -1
  208. package/dist/components/fields/FilterPicker/FilterPicker.js.map +1 -1
  209. package/dist/components/fields/Input/Input.js +2 -2
  210. package/dist/components/fields/ListBox/DraggableListBox.js +1 -1
  211. package/dist/components/fields/ListBox/ListBox.d.ts +7 -0
  212. package/dist/components/fields/ListBox/ListBox.js +4 -3
  213. package/dist/components/fields/ListBox/ListBox.js.map +1 -1
  214. package/dist/components/fields/ListBoxPopover/ListBoxPopover.js +1 -1
  215. package/dist/components/fields/ListBoxPopover/listNavigation.js +1 -1
  216. package/dist/components/fields/ListBoxPopover/useCompositeFocus.js +1 -1
  217. package/dist/components/fields/NumberInput/NumberInput.js +1 -1
  218. package/dist/components/fields/NumberInput/StepButton.js +1 -1
  219. package/dist/components/fields/PasswordInput/PasswordInput.d.ts +2 -2
  220. package/dist/components/fields/PasswordInput/PasswordInput.js +12 -2
  221. package/dist/components/fields/PasswordInput/PasswordInput.js.map +1 -1
  222. package/dist/components/fields/Picker/Picker.js +6 -1
  223. package/dist/components/fields/Picker/Picker.js.map +1 -1
  224. package/dist/components/fields/RadioGroup/Radio.d.ts +2 -2
  225. package/dist/components/fields/RadioGroup/Radio.js +4 -4
  226. package/dist/components/fields/RadioGroup/Radio.js.map +1 -1
  227. package/dist/components/fields/RadioGroup/RadioGroup.js +1 -1
  228. package/dist/components/fields/RadioGroup/context.js +1 -1
  229. package/dist/components/fields/SearchComboBox/SearchComboBox.js +1 -1
  230. package/dist/components/fields/SearchInput/SearchInput.d.ts +2 -2
  231. package/dist/components/fields/SearchInput/SearchInput.js +17 -4
  232. package/dist/components/fields/SearchInput/SearchInput.js.map +1 -1
  233. package/dist/components/fields/Select/Select.js +1 -1
  234. package/dist/components/fields/Slider/Gradation.js +1 -1
  235. package/dist/components/fields/Slider/HueSlider.js +1 -1
  236. package/dist/components/fields/Slider/RangeSlider.js +1 -1
  237. package/dist/components/fields/Slider/Slider.js +1 -1
  238. package/dist/components/fields/Slider/SliderBase.js +1 -1
  239. package/dist/components/fields/Slider/SliderThumb.js +1 -1
  240. package/dist/components/fields/Slider/SliderTrack.js +1 -1
  241. package/dist/components/fields/Slider/elements.js +1 -1
  242. package/dist/components/fields/Slider/index.js +1 -1
  243. package/dist/components/fields/Switch/Switch.js +1 -1
  244. package/dist/components/fields/TextArea/TextArea.d.ts +2 -2
  245. package/dist/components/fields/TextArea/TextArea.js +12 -5
  246. package/dist/components/fields/TextArea/TextArea.js.map +1 -1
  247. package/dist/components/fields/TextInput/TextInput.d.ts +2 -2
  248. package/dist/components/fields/TextInput/TextInput.js +15 -3
  249. package/dist/components/fields/TextInput/TextInput.js.map +1 -1
  250. package/dist/components/fields/TextInput/TextInputBase.d.ts +17 -1
  251. package/dist/components/fields/TextInput/TextInputBase.js +1 -1
  252. package/dist/components/fields/TextInput/TextInputBase.js.map +1 -1
  253. package/dist/components/fields/TextInput/index.d.ts +1 -1
  254. package/dist/components/fields/TextInputMapper/TextInputMapper.js +1 -1
  255. package/dist/components/fields/color/ColorPanel.js +152 -0
  256. package/dist/components/fields/color/ColorPanel.js.map +1 -0
  257. package/dist/components/fields/color/ColorSwatch.d.ts +22 -0
  258. package/dist/components/fields/color/ColorSwatch.js +58 -0
  259. package/dist/components/fields/color/ColorSwatch.js.map +1 -0
  260. package/dist/components/fields/color/channels.d.ts +13 -0
  261. package/dist/components/fields/color/channels.js +194 -0
  262. package/dist/components/fields/color/channels.js.map +1 -0
  263. package/dist/components/fields/color/color.d.ts +21 -0
  264. package/dist/components/fields/color/color.js +282 -0
  265. package/dist/components/fields/color/color.js.map +1 -0
  266. package/dist/components/fields/color/context.js +20 -0
  267. package/dist/components/fields/color/context.js.map +1 -0
  268. package/dist/components/fields/color/index.d.ts +4 -0
  269. package/dist/components/fields/index.d.ts +11 -1
  270. package/dist/components/form/FieldWrapper/FieldWrapper.js +1 -1
  271. package/dist/components/form/Form/Field.js +1 -1
  272. package/dist/components/form/Form/Form.js +1 -1
  273. package/dist/components/form/Form/ResetButton/ResetButton.js +1 -1
  274. package/dist/components/form/Form/SubmitButton/SubmitButton.js +1 -1
  275. package/dist/components/form/Form/SubmitError.js +1 -1
  276. package/dist/components/form/Form/index.js +1 -1
  277. package/dist/components/form/Form/use-field/use-field-props.js +1 -1
  278. package/dist/components/form/Form/use-field/use-field.js +1 -1
  279. package/dist/components/form/Form/use-form.js +1 -1
  280. package/dist/components/form/Form/validation.js +1 -1
  281. package/dist/components/form/Label.js +1 -1
  282. package/dist/components/form/validation/ValidationIndicator.js +1 -1
  283. package/dist/components/form/validation/resolve-validation-props.js +1 -1
  284. package/dist/components/form/validation/use-validation-props.js +1 -1
  285. package/dist/components/form/wrapper.js +1 -1
  286. package/dist/components/helpers/DisplayTransition/DisplayTransition.js +1 -1
  287. package/dist/components/helpers/IconSwitch/IconSwitch.d.ts +26 -0
  288. package/dist/components/helpers/IconSwitch/IconSwitch.js +1 -1
  289. package/dist/components/layout/Board/Board.d.ts +55 -1
  290. package/dist/components/layout/Board/Board.js +278 -75
  291. package/dist/components/layout/Board/Board.js.map +1 -1
  292. package/dist/components/layout/Board/BoardProvider.js +1 -1
  293. package/dist/components/layout/Board/BoardResponsive.js +1 -1
  294. package/dist/components/layout/Board/Widget.d.ts +16 -0
  295. package/dist/components/layout/Board/Widget.js +6 -3
  296. package/dist/components/layout/Board/Widget.js.map +1 -1
  297. package/dist/components/layout/Board/WidgetHost.js +81 -14
  298. package/dist/components/layout/Board/WidgetHost.js.map +1 -1
  299. package/dist/components/layout/Board/board-context.js +1 -1
  300. package/dist/components/layout/Board/board-context.js.map +1 -1
  301. package/dist/components/layout/Board/board-store.js +2 -2
  302. package/dist/components/layout/Board/board-store.js.map +1 -1
  303. package/dist/components/layout/Board/grid-core/calculate.js +1 -1
  304. package/dist/components/layout/Board/grid-core/collision.js +1 -1
  305. package/dist/components/layout/Board/grid-core/compactors.js +1 -1
  306. package/dist/components/layout/Board/grid-core/constraints.js +1 -1
  307. package/dist/components/layout/Board/grid-core/group-move.js +132 -0
  308. package/dist/components/layout/Board/grid-core/group-move.js.map +1 -0
  309. package/dist/components/layout/Board/grid-core/layout.js +1 -1
  310. package/dist/components/layout/Board/grid-core/sort.js +1 -1
  311. package/dist/components/layout/Board/index.d.ts +2 -1
  312. package/dist/components/layout/Board/index.js +2 -2
  313. package/dist/components/layout/Board/index.js.map +1 -1
  314. package/dist/components/layout/Board/responsive-utils.js +1 -1
  315. package/dist/components/layout/Board/use-board-layout.js +17 -12
  316. package/dist/components/layout/Board/use-board-layout.js.map +1 -1
  317. package/dist/components/layout/Board/use-board-registry.js +139 -20
  318. package/dist/components/layout/Board/use-board-registry.js.map +1 -1
  319. package/dist/components/layout/Board/use-board-select-modifier-key.js +24 -0
  320. package/dist/components/layout/Board/use-board-select-modifier-key.js.map +1 -0
  321. package/dist/components/layout/Board/use-board-selection.d.ts +8 -0
  322. package/dist/components/layout/Board/use-board-selection.js +113 -0
  323. package/dist/components/layout/Board/use-board-selection.js.map +1 -0
  324. package/dist/components/layout/Flex.js +1 -1
  325. package/dist/components/layout/Flow.js +1 -1
  326. package/dist/components/layout/Grid.js +1 -1
  327. package/dist/components/layout/Panel.js +1 -1
  328. package/dist/components/layout/Prefix.js +1 -1
  329. package/dist/components/layout/ResizablePanel.js +1 -1
  330. package/dist/components/layout/Space.js +1 -1
  331. package/dist/components/layout/Suffix.js +1 -1
  332. package/dist/components/navigation/Pagination/Pagination.d.ts +9 -0
  333. package/dist/components/navigation/Pagination/Pagination.js +258 -0
  334. package/dist/components/navigation/Pagination/Pagination.js.map +1 -0
  335. package/dist/components/navigation/Pagination/index.d.ts +4 -0
  336. package/dist/components/navigation/Pagination/types.d.ts +81 -0
  337. package/dist/components/navigation/Pagination/use-pagination.d.ts +52 -0
  338. package/dist/components/navigation/Pagination/use-pagination.js +83 -0
  339. package/dist/components/navigation/Pagination/use-pagination.js.map +1 -0
  340. package/dist/components/navigation/Tabs/DraggableTabList.js +1 -1
  341. package/dist/components/navigation/Tabs/TabButton.js +1 -1
  342. package/dist/components/navigation/Tabs/TabDropIndicator.js +1 -1
  343. package/dist/components/navigation/Tabs/TabPanel.js +1 -1
  344. package/dist/components/navigation/Tabs/TabPicker.js +1 -1
  345. package/dist/components/navigation/Tabs/Tabs.js +1 -1
  346. package/dist/components/navigation/Tabs/TabsAction.js +1 -1
  347. package/dist/components/navigation/Tabs/TabsContext.js +1 -1
  348. package/dist/components/navigation/Tabs/popover-placement.js +1 -1
  349. package/dist/components/navigation/Tabs/styled.js +1 -1
  350. package/dist/components/navigation/Tabs/types.js +1 -1
  351. package/dist/components/navigation/Tabs/use-tab-editing.js +1 -1
  352. package/dist/components/navigation/Tabs/use-tab-indicator.js +1 -1
  353. package/dist/components/navigation/index.d.ts +5 -1
  354. package/dist/components/organisms/StatsCard/StatsCard.js +1 -1
  355. package/dist/components/other/Calendar/Calendar.js +1 -1
  356. package/dist/components/other/Calendar/CalendarCell.js +1 -1
  357. package/dist/components/other/Calendar/CalendarGrid.js +1 -1
  358. package/dist/components/other/Calendar/PeriodCalendar.js +1 -1
  359. package/dist/components/other/Calendar/RangeCalendar.js +1 -1
  360. package/dist/components/other/CubeLogo/CubeLogo.js +1 -1
  361. package/dist/components/overlays/AlertDialog/AlertDialog.js +1 -1
  362. package/dist/components/overlays/AlertDialog/AlertDialogApiProvider.js +1 -1
  363. package/dist/components/overlays/AlertDialog/AlertDialogZone.js +1 -1
  364. package/dist/components/overlays/Dialog/Dialog.js +1 -1
  365. package/dist/components/overlays/Dialog/DialogContainer.js +1 -1
  366. package/dist/components/overlays/Dialog/DialogForm.js +1 -1
  367. package/dist/components/overlays/Dialog/DialogTrigger.js +1 -1
  368. package/dist/components/overlays/Dialog/context.js +1 -1
  369. package/dist/components/overlays/Dialog/use-dialog-container.js +1 -1
  370. package/dist/components/overlays/Modal/Modal.js +1 -1
  371. package/dist/components/overlays/Modal/OpenTransitionContext.js +1 -1
  372. package/dist/components/overlays/Modal/Overlay.js +1 -1
  373. package/dist/components/overlays/Modal/Popover.js +1 -1
  374. package/dist/components/overlays/Modal/Tray.js +1 -1
  375. package/dist/components/overlays/Modal/Underlay.js +1 -1
  376. package/dist/components/overlays/Notifications/Notification.js +1 -1
  377. package/dist/components/overlays/Notifications/NotificationAction.js +1 -1
  378. package/dist/components/overlays/Notifications/NotificationCard.js +1 -1
  379. package/dist/components/overlays/Notifications/NotificationContext.js +1 -1
  380. package/dist/components/overlays/Notifications/NotificationItem.js +1 -1
  381. package/dist/components/overlays/Notifications/OverlayContainer.js +1 -1
  382. package/dist/components/overlays/Notifications/OverlayProvider.js +1 -1
  383. package/dist/components/overlays/Notifications/PersistentNotificationsList.js +1 -1
  384. package/dist/components/overlays/Notifications/dismissed-storage.js +1 -1
  385. package/dist/components/overlays/Notifications/format-relative-time.js +1 -1
  386. package/dist/components/overlays/Notifications/index.js +1 -1
  387. package/dist/components/overlays/Notifications/use-notification-state.js +1 -1
  388. package/dist/components/overlays/Notifications/use-notifications.js +1 -1
  389. package/dist/components/overlays/Notifications/use-overlay-timers.js +1 -1
  390. package/dist/components/overlays/Notifications/use-persistent-notifications.js +1 -1
  391. package/dist/components/overlays/Notifications/use-persistent-state.js +1 -1
  392. package/dist/components/overlays/Notifications/use-toast-state.js +1 -1
  393. package/dist/components/overlays/Toast/ToastItem.js +1 -1
  394. package/dist/components/overlays/Toast/index.js +1 -1
  395. package/dist/components/overlays/Toast/useProgressToast.js +1 -1
  396. package/dist/components/overlays/Toast/useToast.js +1 -1
  397. package/dist/components/overlays/Tooltip/Tooltip.js +1 -1
  398. package/dist/components/overlays/Tooltip/TooltipProvider.js +1 -1
  399. package/dist/components/overlays/Tooltip/TooltipTrigger.js +1 -1
  400. package/dist/components/overlays/Tooltip/context.js +1 -1
  401. package/dist/components/portal/Portal.js +1 -1
  402. package/dist/components/portal/PortalProvider.js +1 -1
  403. package/dist/components/portal/usePortal.js +1 -1
  404. package/dist/components/shared/DraggableCollection.js +24 -8
  405. package/dist/components/shared/DraggableCollection.js.map +1 -1
  406. package/dist/components/shared/InvalidIcon.js +1 -1
  407. package/dist/components/shared/ValidIcon.js +1 -1
  408. package/dist/components/status/LoadingAnimation/LoadingAnimation.js +1 -1
  409. package/dist/components/status/Spin/Cube.js +1 -1
  410. package/dist/components/status/Spin/InternalSpinner.js +1 -1
  411. package/dist/components/status/Spin/Spin.js +1 -1
  412. package/dist/components/status/Spin/SpinsContainer.js +1 -1
  413. package/dist/data/item-themes.js +1 -1
  414. package/dist/data/themes.js +1 -1
  415. package/dist/eslint-plugin/defaults.generated.js +227 -5
  416. package/dist/eslint-plugin/defaults.generated.js.map +1 -1
  417. package/dist/eslint-plugin/index.js +1 -1
  418. package/dist/eslint-plugin/rules/no-redundant-default-prop.js +1 -1
  419. package/dist/i18n/I18nProvider.js +1 -1
  420. package/dist/i18n/createFormatter.js +1 -1
  421. package/dist/i18n/index.js +1 -1
  422. package/dist/i18n/instance.js +1 -1
  423. package/dist/i18n/locales/de-DE/uikit.js +44 -1
  424. package/dist/i18n/locales/en-US/uikit.js +44 -1
  425. package/dist/i18n/locales/en-US/uikit.json.d.ts +49 -1
  426. package/dist/i18n/locales/es-ES/uikit.js +44 -1
  427. package/dist/i18n/locales/es-MX/uikit.js +44 -1
  428. package/dist/i18n/locales/fr-FR/uikit.js +44 -1
  429. package/dist/i18n/locales/it-IT/uikit.js +44 -1
  430. package/dist/i18n/locales/ja-JP/uikit.js +44 -1
  431. package/dist/i18n/locales/nb-NO/uikit.js +44 -1
  432. package/dist/i18n/locales/pt-BR/uikit.js +44 -1
  433. package/dist/i18n/locales/pt-PT/uikit.js +44 -1
  434. package/dist/i18n/locales/sv-SE/uikit.js +44 -1
  435. package/dist/i18n/locales/vi-VN/uikit.js +44 -1
  436. package/dist/i18n/locales.js +1 -1
  437. package/dist/i18n/useFormatter.js +1 -1
  438. package/dist/i18n/useI18n.js +1 -1
  439. package/dist/icons/AdjustmentsHorizontalIcon.js +1 -1
  440. package/dist/icons/AdjustmentsIcon.js +1 -1
  441. package/dist/icons/AiIcon.js +1 -1
  442. package/dist/icons/AreaChartIcon.js +1 -1
  443. package/dist/icons/BackwardIcon.js +1 -1
  444. package/dist/icons/BarChartIcon.js +1 -1
  445. package/dist/icons/BellFilledIcon.js +1 -1
  446. package/dist/icons/BellIcon.js +1 -1
  447. package/dist/icons/BooleanIcon.js +1 -1
  448. package/dist/icons/CalendarEditIcon.js +1 -1
  449. package/dist/icons/CalendarIcon.js +1 -1
  450. package/dist/icons/CaretDownIcon.js +1 -1
  451. package/dist/icons/CaretUpIcon.js +1 -1
  452. package/dist/icons/ChartAreaStackedIcon.js +1 -1
  453. package/dist/icons/ChartAreaStackedPercentageIcon.js +1 -1
  454. package/dist/icons/ChartBarGroupedHorizontalIcon.js +1 -1
  455. package/dist/icons/ChartBarGroupedIcon.js +1 -1
  456. package/dist/icons/ChartBarHorizontalIcon.js +1 -1
  457. package/dist/icons/ChartBarLineIcon.js +1 -1
  458. package/dist/icons/ChartBarStackedHorizontalIcon.js +1 -1
  459. package/dist/icons/ChartBarStackedIcon.js +1 -1
  460. package/dist/icons/ChartBarStackedPercentageHorizontalIcon.js +1 -1
  461. package/dist/icons/ChartBarStackedPercentageIcon.js +1 -1
  462. package/dist/icons/ChartBoxPlot2Icon.js +1 -1
  463. package/dist/icons/ChartBoxPlotIcon.js +1 -1
  464. package/dist/icons/ChartBubbleIcon.js +1 -1
  465. package/dist/icons/ChartDonut2Icon.js +1 -1
  466. package/dist/icons/ChartFunnelIcon.js +1 -1
  467. package/dist/icons/ChartHeatmapIcon.js +1 -1
  468. package/dist/icons/ChartKPIIcon.js +1 -1
  469. package/dist/icons/ChartPie2Icon.js +1 -1
  470. package/dist/icons/ChartScatterIcon.js +1 -1
  471. package/dist/icons/CheckCircleFilledIcon.js +1 -1
  472. package/dist/icons/CheckCircleIcon.js +1 -1
  473. package/dist/icons/CheckIcon.js +1 -1
  474. package/dist/icons/CircleFilledIcon.js +1 -1
  475. package/dist/icons/ClearIcon.js +1 -1
  476. package/dist/icons/CloseCircleFilledIcon.js +1 -1
  477. package/dist/icons/CloseCircleIcon.js +1 -1
  478. package/dist/icons/CloseIcon.js +1 -1
  479. package/dist/icons/CodeIcon.js +1 -1
  480. package/dist/icons/ColumnTotalIcon.js +1 -1
  481. package/dist/icons/CopyIcon.js +1 -1
  482. package/dist/icons/CountIcon.js +1 -1
  483. package/dist/icons/CubeIcon.js +1 -1
  484. package/dist/icons/CubePauseIcon.js +1 -1
  485. package/dist/icons/CubePlayIcon.js +1 -1
  486. package/dist/icons/CurrencyDollarIcon.js +1 -1
  487. package/dist/icons/DangerIcon.js +1 -1
  488. package/dist/icons/DashboardIcon.js +1 -1
  489. package/dist/icons/DatabaseIcon.js +1 -1
  490. package/dist/icons/DecimalDecreaseIcon.js +1 -1
  491. package/dist/icons/DecimalIncreaseIcon.js +1 -1
  492. package/dist/icons/DirectionIcon.js +1 -1
  493. package/dist/icons/DonutIcon.js +1 -1
  494. package/dist/icons/DownIcon.js +1 -1
  495. package/dist/icons/EditIcon.js +1 -1
  496. package/dist/icons/ExclamationCircleFilledIcon.js +1 -1
  497. package/dist/icons/ExclamationCircleIcon.js +1 -1
  498. package/dist/icons/ExclamationIcon.js +1 -1
  499. package/dist/icons/EyeIcon.js +1 -1
  500. package/dist/icons/EyeInvisibleIcon.js +1 -1
  501. package/dist/icons/FilterIcon.js +1 -1
  502. package/dist/icons/FolderFilledIcon.js +1 -1
  503. package/dist/icons/FolderIcon.js +1 -1
  504. package/dist/icons/FolderOpenFilledIcon.js +1 -1
  505. package/dist/icons/FolderOpenIcon.js +1 -1
  506. package/dist/icons/ForwardIcon.js +1 -1
  507. package/dist/icons/GripVerticalIcon.js +1 -1
  508. package/dist/icons/HierarchyIcon.js +1 -1
  509. package/dist/icons/HierarchyOpenIcon.js +1 -1
  510. package/dist/icons/Icon.js +1 -1
  511. package/dist/icons/InfoCircleIcon.js +1 -1
  512. package/dist/icons/InfoIcon.js +1 -1
  513. package/dist/icons/KeyIcon.js +1 -1
  514. package/dist/icons/LeftIcon.js +1 -1
  515. package/dist/icons/LineChartIcon.js +1 -1
  516. package/dist/icons/LoadingIcon.js +1 -1
  517. package/dist/icons/LockFilledIcon.js +1 -1
  518. package/dist/icons/LockIcon.js +1 -1
  519. package/dist/icons/MoreIcon.js +1 -1
  520. package/dist/icons/NotAllowedIcon.js +1 -1
  521. package/dist/icons/Number123Icon.js +1 -1
  522. package/dist/icons/NumberIcon.js +1 -1
  523. package/dist/icons/PauseCircleFilledIcon.js +1 -1
  524. package/dist/icons/PauseCircleIcon.js +1 -1
  525. package/dist/icons/PauseIcon.js +1 -1
  526. package/dist/icons/PercentageIcon.js +1 -1
  527. package/dist/icons/PieChartIcon.js +1 -1
  528. package/dist/icons/PipetteIcon.d.ts +12 -0
  529. package/dist/icons/PipetteIcon.js +11 -0
  530. package/dist/icons/PipetteIcon.js.map +1 -0
  531. package/dist/icons/PlayCircleIcon.js +1 -1
  532. package/dist/icons/PlayIcon.js +1 -1
  533. package/dist/icons/PlusIcon.js +1 -1
  534. package/dist/icons/ProgressBarIcon.js +1 -1
  535. package/dist/icons/ReloadIcon.js +1 -1
  536. package/dist/icons/ReportIcon.js +1 -1
  537. package/dist/icons/ReturnIcon.js +1 -1
  538. package/dist/icons/RightIcon.js +1 -1
  539. package/dist/icons/RowTotalsIcon.js +1 -1
  540. package/dist/icons/SchemeIcon.js +1 -1
  541. package/dist/icons/SearchIcon.js +1 -1
  542. package/dist/icons/SemanticQueryIcon.js +1 -1
  543. package/dist/icons/SettingsIcon.js +1 -1
  544. package/dist/icons/ShieldFilledIcon.js +1 -1
  545. package/dist/icons/ShieldIcon.js +1 -1
  546. package/dist/icons/SlashIcon.js +1 -1
  547. package/dist/icons/SparklesIcon.js +1 -1
  548. package/dist/icons/SqlIcon.js +1 -1
  549. package/dist/icons/StatsIcon.js +1 -1
  550. package/dist/icons/StopIcon.js +1 -1
  551. package/dist/icons/StringIcon.js +1 -1
  552. package/dist/icons/SubtotalsIcon.js +1 -1
  553. package/dist/icons/SwitchIcon.js +1 -1
  554. package/dist/icons/TableIcon.js +1 -1
  555. package/dist/icons/ThumbsDownIcon.js +1 -1
  556. package/dist/icons/ThumbsUpIcon.js +1 -1
  557. package/dist/icons/ThunderboltCrossedIcon.js +1 -1
  558. package/dist/icons/ThunderboltFilledIcon.js +1 -1
  559. package/dist/icons/ThunderboltIcon.js +1 -1
  560. package/dist/icons/TimeIcon.js +1 -1
  561. package/dist/icons/TrashIcon.js +1 -1
  562. package/dist/icons/UnlockIcon.js +1 -1
  563. package/dist/icons/UpIcon.js +1 -1
  564. package/dist/icons/UserGroupIcon.js +1 -1
  565. package/dist/icons/UserIcon.js +1 -1
  566. package/dist/icons/UserLockIcon.js +1 -1
  567. package/dist/icons/ViewIcon.js +1 -1
  568. package/dist/icons/WarningFilledIcon.js +1 -1
  569. package/dist/icons/WarningIcon.js +1 -1
  570. package/dist/icons/index.d.ts +1 -0
  571. package/dist/icons/wrap-icon.js +1 -1
  572. package/dist/index.d.ts +31 -12
  573. package/dist/index.js +24 -11
  574. package/dist/index.js.map +1 -1
  575. package/dist/provider.js +1 -1
  576. package/dist/providers/TrackingProvider.js +1 -1
  577. package/dist/providers/navigationAdapter.default.js +1 -1
  578. package/dist/tokens/base.js +1 -1
  579. package/dist/tokens/colors.js +1 -1
  580. package/dist/tokens/index.js +1 -1
  581. package/dist/tokens/layout.js +1 -1
  582. package/dist/tokens/lazy-styles.js +1 -1
  583. package/dist/tokens/palette-config.js +1 -1
  584. package/dist/tokens/palette.js +1 -1
  585. package/dist/tokens/shadows.js +1 -1
  586. package/dist/tokens/sizes.js +1 -1
  587. package/dist/tokens/spacing.js +1 -1
  588. package/dist/tokens/typography.d.ts +1 -1
  589. package/dist/tokens/typography.js +11 -2
  590. package/dist/tokens/typography.js.map +1 -1
  591. package/dist/utils/ResizeSensor.js +1 -1
  592. package/dist/utils/index.d.ts +1 -0
  593. package/dist/utils/is-dev-env.js +1 -1
  594. package/dist/utils/modules.js +1 -1
  595. package/dist/utils/promise.js +1 -1
  596. package/dist/utils/raf.js +1 -1
  597. package/dist/utils/random.js +1 -1
  598. package/dist/utils/range.js +1 -1
  599. package/dist/utils/react/RenderCache.js +1 -1
  600. package/dist/utils/react/Slots.js +1 -1
  601. package/dist/utils/react/chain.js +1 -1
  602. package/dist/utils/react/forwardRefWithGenerics.js +1 -1
  603. package/dist/utils/react/index.d.ts +1 -0
  604. package/dist/utils/react/index.js +2 -1
  605. package/dist/utils/react/interactions.js +1 -1
  606. package/dist/utils/react/isTextOnly.js +1 -1
  607. package/dist/utils/react/mapProps.js +1 -1
  608. package/dist/utils/react/mergeProps.js +1 -1
  609. package/dist/utils/react/nullableValue.js +1 -1
  610. package/dist/utils/react/resolveIcon.js +1 -1
  611. package/dist/utils/react/sharedStore.js +1 -1
  612. package/dist/utils/react/useBufferedValue.d.ts +56 -0
  613. package/dist/utils/react/useBufferedValue.js +86 -0
  614. package/dist/utils/react/useBufferedValue.js.map +1 -0
  615. package/dist/utils/react/useCombinedRefs.js +1 -1
  616. package/dist/utils/react/useControlledFocusVisible.js +1 -1
  617. package/dist/utils/react/useEventBus.js +1 -1
  618. package/dist/utils/react/useId.js +1 -1
  619. package/dist/utils/react/useIsDarwin.js +1 -1
  620. package/dist/utils/react/useKeySymbols.js +1 -1
  621. package/dist/utils/react/useLayoutEffect.js +1 -1
  622. package/dist/utils/react/useLocalStorage.js +1 -1
  623. package/dist/utils/react/useMergeStyles.js +1 -1
  624. package/dist/utils/react/usePopoverSync.js +1 -1
  625. package/dist/utils/react/useQaProps.js +1 -1
  626. package/dist/utils/react/useViewportSize.js +1 -1
  627. package/dist/utils/react/wrapNodeIfPlain.js +1 -1
  628. package/dist/utils/selection.js +1 -1
  629. package/dist/utils/styles.js +1 -1
  630. package/dist/utils/tree.js +1 -1
  631. package/dist/utils/warnings.js +1 -1
  632. package/dist/version.js +2 -2
  633. package/docs/components/actions/ButtonGroup.md +1 -1
  634. package/docs/components/data/DataTable.md +298 -0
  635. package/docs/components/data/ItemTable.md +984 -0
  636. package/docs/components/fields/ColorInput.md +284 -0
  637. package/docs/components/fields/ColorPicker.md +212 -0
  638. package/docs/components/fields/ColorSwatchGroup.md +206 -0
  639. package/docs/components/fields/FilterPicker.md +1 -1
  640. package/docs/components/fields/ListBox.md +4 -0
  641. package/docs/components/fields/PasswordInput.md +1 -0
  642. package/docs/components/fields/Picker.md +1 -1
  643. package/docs/components/fields/SearchInput.md +1 -0
  644. package/docs/components/fields/TextArea.md +1 -0
  645. package/docs/components/fields/TextInput.md +1 -0
  646. package/docs/components/layout/Board.md +154 -6
  647. package/docs/components/navigation/Pagination.md +245 -0
  648. package/package.json +8 -3
  649. package/dist/components/organisms/FileTabs/FileTabs.d.ts +0 -54
  650. package/dist/components/organisms/FileTabs/FileTabs.js +0 -282
  651. package/dist/components/organisms/FileTabs/FileTabs.js.map +0 -1
  652. package/docs/components/organisms/FileTabs.md +0 -51
@@ -0,0 +1,984 @@
1
+ # ItemTable
2
+
3
+ ItemTable renders a list of records as a table: one row per entity, columns
4
+ declared as data rather than JSX. It is the general-purpose table for list and
5
+ admin pages.
6
+
7
+ It renders a real `<table>` with `role="grid"`, and is styled entirely through
8
+ tasty sub-elements — `Row`, `Cell`, `HeaderCell` and friends are reachable from
9
+ the single `styles` prop.
10
+
11
+ > `ItemTable` and `DataTable` are siblings over one internal engine. `ItemTable`
12
+ > is for records; `DataTable` is for analytics results (pivoted columns, pinned
13
+ > totals, cell-range selection).
14
+
15
+ ## When to Use
16
+
17
+ - Listing entities the user acts on: deployments, users, API keys, roles.
18
+ - Any table where a row is a *thing* — it can be opened, selected, or given a
19
+ menu.
20
+ - Tables that need a column header richer than a label: icon, description,
21
+ tooltip, actions.
22
+
23
+ Use `DataTable` instead when a *cell* is the unit of interest — query results,
24
+ pivots, totals. Use `ListBox` when there is only one column.
25
+
26
+ ## Component
27
+
28
+ ### Properties
29
+
30
+ - **`data`** `readonly T[]` — The rows to render.
31
+ - **`columns`** `CubeItemTableColumn<T>[]` — Column definitions. See below.
32
+ - **`rowKey`** `string` (default: `'id'`) — Property used as the row key.
33
+ - **`getRowKey`** `(row: T, index: number) => Key` — Wins over `rowKey`.
34
+ - **`isLoading`** `boolean` (default: `false`) — Marks a fetch in flight. What
35
+ the user sees depends on `loadingIndicator`.
36
+ - **`loadingIndicator`** `'overlay' | 'skeleton' | 'none'` (default: `'overlay'`)
37
+ — What to show while `isLoading` is true over rows the table already has.
38
+ `overlay` keeps them, faded under a sweeping band; `skeleton` replaces them with
39
+ placeholders; `none` paints nothing beyond `aria-busy`. With no rows yet,
40
+ `overlay` and `skeleton` both fall back to skeleton rows.
41
+ - **`skeletonRowCount`** `number` (default: `6`) — Skeleton rows to show while
42
+ loading.
43
+ - **`emptyLabel`** `ReactNode` — Shown when there is nothing at all. Defaults to
44
+ a localized "No items".
45
+ - **`noResultsLabel`** `ReactNode` — Shown instead of `emptyLabel` when
46
+ `isFiltered` is set. Defaults to a localized "No results found".
47
+ - **`isFiltered`** `boolean` — Marks the emptiness as the result of a filter, so
48
+ `noResultsLabel` is shown instead of `emptyLabel`. The built-in search sets it
49
+ on its own; pass it explicitly when you filter `data` yourself.
50
+ - **`error`** `ReactNode` — Takes precedence over both labels.
51
+ - **`shape`** `'plain' | 'card'` (default: `'plain'`) — `card` adds a border and
52
+ a card radius.
53
+ - **`size`** `'xsmall' | 'small' | 'medium' | 'large' | 'xlarge'` (default:
54
+ `'medium'`) — Drives both heights. At `medium` a row is 40px and the header
55
+ 32px, each plus its 1px separator.
56
+ - **`rowHeight`** `number` — Row height in px, overriding the one `size`
57
+ implies. Excludes the 1px separator.
58
+ - **`headerHeight`** `number` — Header height in px, excluding its 1px border.
59
+ - **`headerPreset`** `string` (default: `'c3'`) — Typography preset for the
60
+ column header. `c3` is the small uppercase caption the Cloud list tables use;
61
+ pass `'t3m'` for body-sized headers.
62
+ - **`isRowMoveAnimated`** `boolean` (default: `true`) — Slide rows to their new positions when the order changes, instead of teleporting them. Respects `prefers-reduced-motion`.
63
+ - **`isStriped`** `boolean` (default: `false`) — Alternating row background.
64
+ - **`isHeaderHidden`** `boolean` (default: `false`) — Hides the column header
65
+ row and drops it from `aria-rowcount`.
66
+ - **`isHeaderSticky`** `boolean` (default: `true`) — Pins the column header
67
+ while the body scrolls.
68
+ - **`sortMode`** `'client' | 'server' | 'off'` (default: `'client'` when any
69
+ column is sortable, else `'off'`) — `client` reorders `data` itself; `server`
70
+ only reflects `sort` and fires `onSortChange`; `off` removes the affordance.
71
+ - **`sort`** `CubeTableSort | null` — Controlled sort, `{ columnKey, direction }`
72
+ with `direction` being `'asc' | 'desc'`.
73
+ - **`defaultSort`** `CubeTableSort | null` — Initial sort for uncontrolled usage.
74
+ - **`onSortChange`** `(sort: CubeTableSort | null) => void` — Fires on every step
75
+ of the cycle, including the return to unsorted.
76
+ - **`toolbar`** `ReactNode` — Replaces the entire toolbar row. Compose it from
77
+ `ItemTable.Search` / `ItemTable.Toolbar`, which read the table's state from
78
+ context.
79
+ - **`isSearchable`** `boolean` (default: `false`) — Render the built-in search
80
+ input in the toolbar.
81
+ - **`searchMode`** `'client' | 'server'` (default: `'client'`) — `client`
82
+ filters `data` with the built-in matcher; `server` only reports the term.
83
+ - **`searchPlaceholder`** `string` — Placeholder for the search input.
84
+ - **`searchValue`** `string` — Controlled term. Works with
85
+ `isSearchable={false}` too, so a page can render its own input anywhere and
86
+ still drive the table's matcher.
87
+ - **`defaultSearchValue`** `string` — Initial term for uncontrolled usage.
88
+ - **`onSearchChange`** `(value: string) => void` — Debounced.
89
+ - **`searchDelay`** `number` (default: `500`) — Debounces the filter **and** the
90
+ callback, in both modes. The input itself stays immediate.
91
+ - **`searchFilter`** `(row: T, query: string) => boolean` — Replaces the default
92
+ client matcher.
93
+ - **`filters`** `ReactNode` — Left group, after the search input.
94
+ - **`actions`** `ReactNode` — Right group. Arbitrary JSX.
95
+ - **`onRefresh`** `() => void` — Renders a refresh button at the end of the
96
+ toolbar.
97
+ - **`isVirtualized`** `boolean | 'auto'` (default: `'auto'`) — `'auto'` turns
98
+ virtualization on once the row count passes `virtualizeThreshold`. It needs a
99
+ bounded height to have a viewport to work against.
100
+ - **`virtualizeThreshold`** `number` (default: `50`) — Row count above which
101
+ `'auto'` virtualizes.
102
+ - **`overscan`** `number` (default: `12`) — Rows mounted beyond each viewport
103
+ edge while virtualized. Higher than a list's, because a fast flick outruns
104
+ React's re-render and the gap shows as blank rows.
105
+ - **`selectionMode`** `'none' | 'single' | 'multiple'` (default: `'none'`) —
106
+ `multiple` adds the checkbox column and a select-all header checkbox;
107
+ `single` adds the column without the header checkbox.
108
+ - **`selectedKeys`** `Key[] | 'all'` — Controlled selection. `'all'` is a
109
+ sentinel meaning "everything, including rows the client has not loaded".
110
+ - **`defaultSelectedKeys`** `Key[] | 'all'` — Initial selection.
111
+ - **`onSelectionChange`** `(keys: Key[] | 'all', rows: T[]) => void` — `rows`
112
+ holds only the rows the client has loaded.
113
+ - **`selectAllMode`** `'page' | 'filtered' | 'all'` (default: `'page'`) — What
114
+ the header checkbox acts on.
115
+ - **`isRowSelectable`** `(row: T) => boolean` — The row stays focusable and
116
+ clickable; only its checkbox goes inert.
117
+ - **`selectionTooltip`** `string | ((row: T) => string | undefined)` — Explains
118
+ an inert checkbox.
119
+ - **`disabledKeys`** `Key[]` — Rows that cannot be interacted with at all.
120
+ - **`rowLink`** `(row: T, index: number) => NavigateArg | undefined` — Turns the
121
+ row-header cell into a stretched link covering the whole row. Return
122
+ `undefined` for a row that should not navigate.
123
+ - **`onRowAction`** `(row: T, key: Key) => void` — Non-navigational activation:
124
+ Enter, or a click that did not land on a control inside a cell.
125
+ - **`rowMenu`** `ReactNode | ((row, ctx) => ReactNode | null)` — `Menu.Item`
126
+ children. Inert until `rowContextMenu` exposes it.
127
+ - **`rowContextMenu`** `boolean | 'context-only'` (default: `false`) — `true`
128
+ gives a `⋮` trigger column **and** right-click / Shift+F10;
129
+ `'context-only'` gives the keyboard and pointer paths without the column.
130
+ - **`onRowMenuAction`** `(action: string, row: T, key: Key) => void` — The
131
+ action key as written on `Menu.Item`.
132
+ - **`rowMenuTriggerProps`** `Partial<CubeItemActionProps>` — Forwarded to every
133
+ `⋮` trigger.
134
+ - **`bulkActions`** `CubeTableBulkAction<T>[]` — Actions offered while rows are
135
+ selected. Supplying any implies `selectionMode="multiple"`.
136
+ - **`bulkBarPlacement`** `'floating' | 'toolbar'` (default: `'floating'`) —
137
+ `floating` centres the bar over the body without changing the table's height;
138
+ `toolbar` replaces the `actions` group while a selection exists.
139
+ - **`bulkBarStyles`** `Styles` — Styles for the bar.
140
+ - **`paginationMode`** `'client' | 'server' | 'off'` (default: `'client'`) —
141
+ `client` slices the searched and sorted rows; `server` never slices and only
142
+ reflects `page` / `total`; `off` removes the control.
143
+ - **`pageSize`** `number` — Controlled page size.
144
+ - **`defaultPageSize`** `number` (default: `50`) — Initial page size.
145
+ - **`onPageSizeChange`** `(pageSize: number) => void` — Fires with the new size.
146
+ Changing the size returns to page 1.
147
+ - **`pageSizeOptions`** `number[]` (default: `[10, 20, 50, 100, 500]`) — Choices
148
+ in the page-size selector.
149
+ - **`page`** `number` — Controlled 1-based page.
150
+ - **`defaultPage`** `number` (default: `1`) — Initial page.
151
+ - **`onPageChange`** `(page: number) => void` — Fires with the clamped page.
152
+ - **`onLoadMore`** `() => void` — `paginationMode="infinite"` only. Fires once
153
+ the end of the list comes into view.
154
+ - **`hasMore`** `boolean` — Whether there is anything left to fetch.
155
+ - **`isLoadingMore`** `boolean` — Suppresses further calls while a batch is in
156
+ flight and shows a loading row.
157
+ - **`loadMoreMargin`** `number` (default: one viewport height) — How far before
158
+ the end to start fetching, in px.
159
+ - **`autoHidePagination`** `boolean` (default: `true`) — Hides the pagination
160
+ control when it cannot do anything: a single page whose total even the
161
+ smallest `pageSizeOptions` entry would not split. The footer still renders if
162
+ any slot has content.
163
+ - **`total`** `number` — Server mode: total row count behind the query.
164
+ - **`totalPages`** `number` — Server mode alternative to `total` when the count
165
+ is unknown.
166
+ - **`hasNextPage`** `boolean` — Server mode: keeps "next" enabled when neither
167
+ `total` nor `totalPages` is known.
168
+ - **`summary`** `boolean | ((info: CubeTablePageInfo) => ReactNode)` (default:
169
+ `true`) — The localized item range in the footer, e.g. "1–50 of 1,204".
170
+ - **`footer`** `ReactNode` — Replaces the entire footer row.
171
+ - **`footerStart`** `ReactNode` — Start footer slot. Renders even with
172
+ `paginationMode="off"` — this is where a "Load all results" button belongs.
173
+ - **`footerCenter`** `ReactNode` — Center footer slot.
174
+ - **`footerEnd`** `ReactNode` — End footer slot, before the pagination control.
175
+ - **`footerStyles`** `Styles` — Styles for the footer row.
176
+ - **`isReorderable`** `boolean` (default: `false`) — Lets rows be dragged into a
177
+ new order.
178
+ - **`onReorder`** `(keys: Key[], rows: T[]) => void` — The **whole** new order,
179
+ not just the moved row, so it can be persisted directly.
180
+ - **`dropOnRow`** `{ isTarget, isAllowed?, onDrop }` — Dropping rows *onto* a
181
+ row, e.g. a workbook into a folder. Enables dragging on its own, and composes
182
+ with `isReorderable`.
183
+ - **`getItemDragInfo`** `(row: T) => { label, icon? }` — What the cursor drags.
184
+ One row shows its icon and label; several show a count. Without it the browser
185
+ drags a screenshot of the row.
186
+ - **`isResizable`** `boolean` (default: `false`) — Adds a resize handle to every
187
+ column; a column overrides with its own `isResizable`.
188
+ - **`columnWidths`** `Record<string, number>` — Controlled widths by column key.
189
+ - **`defaultColumnWidths`** `Record<string, number>` — Initial widths.
190
+ - **`onColumnResize`** `(columnKey, width, all) => void` — Fires once the
191
+ gesture ends, not on every pixel.
192
+ - **`storageKey`** `string` — Persists the table's own state under
193
+ `cube-ui-kit:table:${storageKey}`. Controlled state is never stored — a
194
+ controlled `pageSize` or `sort` belongs to the page, and restoring it would
195
+ give the table a second, competing source of truth.
196
+ - **`persist`** `('pageSize' | 'columnWidths' | 'sort')[]` (default:
197
+ `['pageSize', 'columnWidths']`) — What `storageKey` covers. Sort is opt-in,
198
+ because a stored sort silently changes what the first screen of a table means.
199
+ - **`getRowProps`** `(ctx) => { isDimmed?, mods?, styles?, height?, qa?, tooltip? }`
200
+ — Per-row visuals.
201
+ - **`ariaLabel`** `string` — Labels the grid.
202
+
203
+ #### `CubeItemTableColumn<T>`
204
+
205
+ ```ts
206
+ interface CubeItemTableColumn<T> {
207
+ key: string; // column id; also the data path — dots walk objects
208
+ title?: ReactNode; // header label
209
+ header?: CubeTableColumnHeader;
210
+ isRowHeader?: boolean; // renders <th scope="row"> and names the row
211
+
212
+ width?: number; // fixed px; mutually exclusive with `flex`
213
+ flex?: number; // weight for the leftover space (default 1)
214
+ minWidth?: number; // default 150
215
+ maxWidth?: number;
216
+ pin?: 'start' | 'end'; // sticky to an edge during horizontal scroll
217
+ isHidden?: boolean;
218
+
219
+ getValue?: (row, i) => unknown; // when `key` is not the data path
220
+ format?: (value, row, i) => string; // raw value → display text
221
+ compare?: (a, b, rowA, rowB) => number; // client-side comparator
222
+
223
+ render?: (value, row, i, ctx) => ReactNode;
224
+ cellStyles?: Styles | ((ctx) => Styles | undefined);
225
+ cellProps?: (ctx) => Record<string, any> | undefined;
226
+
227
+ align?: 'start' | 'center' | 'end';
228
+ isSortable?: boolean;
229
+ isSearchable?: boolean; // include in the built-in search (default true)
230
+ isCopyable?: boolean; // include in TSV copy (default true)
231
+ autoHeight?: boolean; // wrap text and let the row grow
232
+ meta?: Record<string, unknown>;
233
+ }
234
+ ```
235
+
236
+ **The value pipeline is the escape hatch.** `getValue`, `format` and `compare`
237
+ exist so a column whose displayed text differs from its raw value stays
238
+ sortable, searchable and copyable. `render` is for appearance only — sorting and
239
+ searching never see its output, which is why an object-valued column with no
240
+ `format` renders empty rather than `"[object Object]"`.
241
+
242
+ #### `CubeTableColumnHeader`
243
+
244
+ Every slot maps 1:1 onto the `Item` rendered inside the header cell, so a header
245
+ gets an icon, a description, a tooltip and actions for free:
246
+
247
+ ```jsx
248
+ {
249
+ key: 'owner',
250
+ title: 'Owner',
251
+ header: {
252
+ icon: <UserIcon />,
253
+ description: 'Who created it',
254
+ descriptionPlacement: 'block',
255
+ tooltip: true, // auto tooltip when the label truncates
256
+ actions: <ItemAction icon={<MoreIcon />} />,
257
+ },
258
+ }
259
+ ```
260
+
261
+ `header.render(ctx)` takes over the cell's content entirely.
262
+
263
+ On a sortable column the sort arrow occupies the `rightIcon` slot — it is an
264
+ icon, and that slot is sized and aligned for one. The slot stays reserved while
265
+ unsorted, so toggling a sort never shifts the label. If you set
266
+ `header.rightIcon` yourself it keeps the slot and the arrow falls back to
267
+ `suffix`.
268
+
269
+ ### Base Properties
270
+
271
+ Supports Base Properties.
272
+
273
+ ### Styling Properties
274
+
275
+ #### styles
276
+
277
+ Customizes the root frame. Every internal part of the table is a **sub-element**
278
+ reachable from this one prop — that is the whole styling contract.
279
+
280
+ **Sub-elements:**
281
+
282
+ - `Scroller` — the single scroll container (both axes)
283
+ - `Table` — the `<table>`
284
+ - `Head`, `HeadRow`, `HeaderCell` — the column header
285
+ - `Body`, `Row`, `Cell` — the data rows
286
+ - `SortIndicator` — the sort arrow, inside the header `Item`'s suffix
287
+ - `Foot`, `FootRow`, `FootCell` — pinned totals
288
+ - `StateContent` — the empty / no-results / error content
289
+
290
+ ```jsx
291
+ const Compact = tasty(ItemTable, {
292
+ styles: {
293
+ Cell: { padding: '1x' },
294
+ Row: { height: 'min 6x' },
295
+ },
296
+ });
297
+ ```
298
+
299
+ Rows publish their paint as inherited custom properties — `#row-base`,
300
+ `#row-overlay`, `#row-text` and `$dim` — which cells consume. That is what lets
301
+ a pinned (and therefore opaque) cell match its row's state without duplicating
302
+ the state matrix.
303
+
304
+ Geometry runs through tokens too: `$row-height`, `$header-height`,
305
+ `$cell-padding-x` (16px) and `$cell-padding-y`. Height lives on the **cells**,
306
+ not the `<tr>` — table layout ignores `min-height` on a row and sizes it from
307
+ its cells instead.
308
+
309
+ #### toolbarStyles
310
+
311
+ The toolbar row. Sub-elements: `Start` (search + filters) and `End` (actions +
312
+ refresh).
313
+
314
+ #### searchStyles
315
+
316
+ The built-in search input.
317
+
318
+ #### headerStyles
319
+
320
+ The **column header row**. (The top chrome, when it arrives, is `toolbarStyles`
321
+ — a table has two things called "header" and this one is the columns.)
322
+
323
+ #### headerCellStyles
324
+
325
+ Every column header cell. Wins over `headerPreset`, so this is where you go for
326
+ anything the preset does not cover.
327
+
328
+ #### bodyStyles
329
+
330
+ The `<tbody>`.
331
+
332
+ #### rowStyles
333
+
334
+ Every body row.
335
+
336
+ #### cellStyles
337
+
338
+ Every body cell.
339
+
340
+ ### Style Properties
341
+
342
+ These properties allow direct style application without using the `styles` prop:
343
+
344
+ - **Base:** `display`, `font`, `preset`, `hide`, `opacity`, `whiteSpace`, `transition`
345
+ - **Position:** `gridArea`, `order`, `gridColumn`, `gridRow`, `place`, `placeSelf`, `alignSelf`, `justifySelf`, `zIndex`, `margin`, `inset`, `position`, `scrollMargin`
346
+ - **Dimension:** `width`, `height`, `flexBasis`, `flexGrow`, `flexShrink`, `flex`
347
+ - **Block:** `padding`, `paddingInline`, `paddingBlock`, `border`, `radius`, `shadow`, `overflow`, `outline`, `scrollbar`, `textAlign`
348
+ - **Color:** `color`, `fill`, `fade`, `image`
349
+ - **Flow:** `flow`, `gap`, `columnGap`, `rowGap`, `placeItems`, `placeContent`, `alignItems`, `alignContent`, `justifyItems`, `justifyContent`, `align`, `justify`, `gridColumns`, `gridRows`, `gridTemplate`, `gridAreas`
350
+
351
+ `height` is the important one: there is no page-scroll mode, so
352
+ bounding the table is what turns the body into a scroller and pins the header.
353
+ An unbounded table simply sizes to its content.
354
+
355
+ ### Modifiers
356
+
357
+ | Modifier | Type | Description |
358
+ | -------- | ---- | ----------- |
359
+ | `size` | `SizeName` | Row height scale |
360
+ | `shape` | `'plain' \| 'card'` | Frame treatment |
361
+ | `sticky-header` | `boolean` | Header is pinned |
362
+
363
+ Row-level modifiers, set on each `<tr>`: `odd`, `selected`, `focused`, `dimmed`,
364
+ `disabled`, `drop-target`, `placeholder`. Cell-level: `pin`, `pin-edge`,
365
+ `align`, `wrap`, `state`.
366
+
367
+ ## Examples
368
+
369
+ ### Basic Usage
370
+
371
+ ```jsx
372
+ <ItemTable
373
+ data={deployments}
374
+ columns={[
375
+ { key: 'name', title: 'Name', isRowHeader: true, flex: 2 },
376
+ { key: 'status', title: 'Status', width: 140 },
377
+ { key: 'owner.name', title: 'Owner' },
378
+ { key: 'queries', title: 'Queries', width: 140, align: 'end',
379
+ format: (v) => v.toLocaleString() },
380
+ ]}
381
+ ariaLabel="Deployments"
382
+ />
383
+ ```
384
+
385
+ ### Custom Cells
386
+
387
+ ```jsx
388
+ {
389
+ key: 'status',
390
+ title: 'Status',
391
+ width: 140,
392
+ render: (value) => <Tag theme={STATUS_THEME[value]}>{value}</Tag>,
393
+ }
394
+ ```
395
+
396
+ ### Appearance
397
+
398
+ `shape="card"` frames the table, `isStriped` bands the rows, `size` drives both
399
+ row and header height, and `isHeaderHidden` drops the header row.
400
+
401
+ ### Empty, No-results and Error States
402
+
403
+ `isFiltered` is what separates "no matches" from "nothing exists"; the built-in
404
+ search sets it for you.
405
+
406
+ ### Sorting
407
+
408
+ Mark columns `isSortable` and clicking a header cycles
409
+ `ascending → descending → unsorted`. The third state matters whenever the source
410
+ order is meaningful, which is why it is the default cycle; set
411
+ `disallowSortRemoval` on a column to reduce it to `asc ↔ desc`.
412
+
413
+ ```jsx
414
+ <ItemTable
415
+ data={rows}
416
+ columns={[
417
+ { key: 'name', title: 'Name', isSortable: true },
418
+ { key: 'queries', title: 'Queries', isSortable: true,
419
+ format: (v) => v.toLocaleString() },
420
+ ]}
421
+ defaultSort={{ columnKey: 'queries', direction: 'desc' }}
422
+ />
423
+ ```
424
+
425
+ Client-side sorting compares raw `getValue` results — numerically for numbers,
426
+ chronologically for dates — and falls back to a locale-aware collator over the
427
+ column's display text, so a formatted column sorts the way it reads. `compare`
428
+ overrides all of it. Nullish values sort first, then flip with the direction.
429
+
430
+ `sortMode="server"` reflects the state and reports changes without ever
431
+ reordering the rows. The second table below is server-sorted over a simulated
432
+ round trip:
433
+
434
+ ```jsx
435
+ <ItemTable
436
+ sortMode="server"
437
+ sort={sort}
438
+ onSortChange={setSort}
439
+ isLoading={isFetching}
440
+ data={rowsFromQuery}
441
+ columns={columns}
442
+ />
443
+ ```
444
+
445
+ ### Search
446
+
447
+ `isSearchable` puts the input in the toolbar and the table filters itself:
448
+
449
+ ```jsx
450
+ <ItemTable
451
+ data={deployments}
452
+ columns={columns}
453
+ isSearchable
454
+ searchPlaceholder="Search deployments..."
455
+ noResultsLabel="No deployments match that search"
456
+ />
457
+ ```
458
+
459
+ The default matcher tests each column's **display text** — `format?.(value) ??
460
+ String(getValue(row))` — not the raw value. So a formatted column matches what
461
+ the user can actually see, a dotted `key` like `owner.name` is searchable, and a
462
+ column holding an object with no `format` is skipped rather than stringified
463
+ into `"[object Object]"` (which would make the query "object" match every row).
464
+ Opt a column out with `isSearchable: false`, or replace the matcher entirely
465
+ with `searchFilter`.
466
+
467
+ Searching also selects `noResultsLabel` over `emptyLabel` on its own, and resets
468
+ to page 1, so a client-search table distinguishes "no matches" from "nothing
469
+ exists" without the page owning the term.
470
+
471
+ ### Server-side Search
472
+
473
+ `searchMode="server"` never filters — it reports the debounced term and the
474
+ query does the work.
475
+
476
+ ### An External Search Box, and a Custom Toolbar
477
+
478
+ The input does not have to live in the table. `isSearchable={false}` hides the
479
+ built-in one while a controlled `searchValue` still drives the table's matcher —
480
+ a first-class path, not a workaround. The second table rebuilds the toolbar
481
+ entirely; `ItemTable.Search` reads the table's state from context, so the term
482
+ still has one owner.
483
+
484
+ ```jsx
485
+ const [term, setTerm] = useState('');
486
+
487
+ <SearchInput value={term} onChange={setTerm} />
488
+ <ItemTable data={rows} columns={columns} isSearchable={false} searchValue={term} />
489
+ ```
490
+
491
+ ### Pagination
492
+
493
+ Pagination lives in the footer and is on by default (`paginationMode="client"`,
494
+ 50 rows a page). The page-size selector appears whenever `pageSizeOptions` is
495
+ set, and `summary` prints the localized item range.
496
+
497
+ ```jsx
498
+ <ItemTable data={rows} columns={columns} defaultPageSize={20} pageSizeOptions={[20, 50, 100]} />
499
+ ```
500
+
501
+ Client pagination slices the **searched and sorted** rows, so a page always
502
+ reflects what the user is looking at, and the summary counts filtered rows
503
+ rather than the raw array. Changing the page size returns to page 1, because the
504
+ old page index points at different rows under a new size.
505
+
506
+ Pagination that cannot do anything hides itself. One page of five rows would
507
+ otherwise render "1–5 of 5", a page-size selector whose every option shows the
508
+ same five rows, and a solitary "1" button. The test is both conditions together
509
+ — a single page **and** a total the smallest page size would not split — so a
510
+ 15-row single page keeps its control, because "10 / page" would genuinely
511
+ paginate it. Set `autoHidePagination={false}` to always show it.
512
+
513
+ Note that pagination and virtualization are alternatives: a 50-row page is well
514
+ under `virtualizeThreshold`, so a paginated table normally renders every row.
515
+ Set `paginationMode="off"` for the long-scroll case.
516
+
517
+ ### Infinite Scroll
518
+
519
+ `paginationMode="infinite"` replaces the page control with load-on-scroll. The
520
+ table never slices in this mode — `data` is the list accumulated so far:
521
+
522
+ ```jsx
523
+ <ItemTable
524
+ height="420px"
525
+ data={loaded}
526
+ columns={columns}
527
+ paginationMode="infinite"
528
+ hasMore={hasMore}
529
+ isLoadingMore={isFetching}
530
+ onLoadMore={fetchNextPage}
531
+ />
532
+ ```
533
+
534
+ It is driven by an `IntersectionObserver` on a sentinel at the end of the body
535
+ rather than a scroll handler: `loadMoreMargin` then expresses "prefetch this far
536
+ before the end" directly, and it costs nothing per scroll tick. The observer
537
+ re-arms only once `isLoadingMore` clears, so a request in flight is never fired
538
+ twice by a sentinel still sitting in view.
539
+
540
+ The fetch starts **a full screen before the end** — `loadMoreMargin` defaults to
541
+ the scroller's own height — so the request goes out while there is still a
542
+ viewport of rows left to read, and the batch has usually arrived by the time the
543
+ user gets there. A fixed 200px, about five rows, meant a fast scroll reached the
544
+ bottom before the response did, which is exactly the stall infinite scroll is
545
+ supposed to avoid.
546
+
547
+ While a batch is in flight the table appends **skeleton rows**, not a spinner.
548
+ They keep the row grid, read as "more rows of this shape are coming", and grow
549
+ the scroll height smoothly instead of a block that appears and vanishes — and it
550
+ matches what the first load already shows.
551
+
552
+ The burst is sized to **the batch that is coming**, measured from the last one
553
+ that arrived, so the list keeps its length through the load: the user can carry
554
+ on scrolling into it, and nothing lurches when the rows land. Measured rather
555
+ than read from `pageSize`, which infinite-scroll consumers often do not set —
556
+ and the first batch is the best predictor of the second. Capped at 50 rows,
557
+ which is taller than any viewport, because these particular rows are not
558
+ virtualized.
559
+
560
+ Under virtualization the trailing spacer holds the remaining height, so the
561
+ sentinel still marks the true end of the list rather than the end of the
562
+ rendered window.
563
+
564
+ ### Footer Slots
565
+
566
+ The footer has three named slots, and they render whether or not pagination is
567
+ on. `footerStart` is where Cloud's "Load all results" button belongs — the thing
568
+ that today needs a `MutationObserver` to inject into ag-grid's paging panel,
569
+ because Community has no status bar.
570
+
571
+ ```jsx
572
+ <ItemTable
573
+ data={rows}
574
+ columns={columns}
575
+ footerStart={<Button type="outline" size="small">Load all results</Button>}
576
+ footerCenter={<Text color="#dark-03">Partial result set</Text>}
577
+ />
578
+ ```
579
+
580
+ ### Server-side Pagination
581
+
582
+ `paginationMode="server"` never slices — it reflects `page` and reports changes,
583
+ and `total` comes from the query. `data` is the current page.
584
+
585
+ ```jsx
586
+ <ItemTable
587
+ data={pageFromQuery}
588
+ columns={columns}
589
+ paginationMode="server"
590
+ page={page}
591
+ pageSize={pageSize}
592
+ total={totalFromQuery}
593
+ isLoading={isFetching}
594
+ onPageChange={setPage}
595
+ onPageSizeChange={setPageSize}
596
+ />
597
+ ```
598
+
599
+ ### Loading Behaviour
600
+
601
+ `loadingIndicator` chooses what happens while `isLoading` is true over rows the
602
+ table already has — the window that only exists once a query is involved:
603
+
604
+ | Value | Behaviour |
605
+ | --- | --- |
606
+ | `overlay` (default) | The previous rows stay readable and uncovered. The table fades — header included — and a band of lower opacity sweeps left to right across it, the way ag-grid marks a reloading grid. Nothing moves and nothing is drawn on top, so the eye keeps its place and the table does not change height. |
607
+ | `skeleton` | The previous rows are discarded for placeholders. Honest that the data is gone, but it flashes on every page and a short page makes the table jump. |
608
+ | `none` | No visuals beyond `aria-busy`. For pages that already show a top-level progress bar and do not want a second indicator. |
609
+
610
+ With no rows yet, `overlay` and `skeleton` both render skeleton rows — there is
611
+ nothing to keep — and `none` renders an empty body rather than flashing the
612
+ `emptyLabel` before the first response arrives.
613
+
614
+ ### Bounded Height, Sticky Header and Pinned Columns
615
+
616
+ A bounded height turns the body into a scroller and pins the header. Pinned
617
+ columns are sticky `<th>`/`<td>` — one scroller, no lanes, no scroll sync. They
618
+ are moved to the edges in DOM order too, so `aria-colindex` stays truthful.
619
+
620
+ ```jsx
621
+ <ItemTable
622
+ height="400px"
623
+ columns={[
624
+ { key: 'name', title: 'Name', pin: 'start', width: 220 },
625
+ /* … */
626
+ { key: 'status', title: 'Status', pin: 'end', width: 140 },
627
+ ]}
628
+ data={rows}
629
+ />
630
+ ```
631
+
632
+ ### Virtualization
633
+
634
+ Above `virtualizeThreshold` rows a bounded table virtualizes automatically. The
635
+ DOM and the styles are identical either way — only the number of mounted rows
636
+ changes, so sorting, search, pinned columns and the sticky header all behave the
637
+ same.
638
+
639
+ ```jsx
640
+ <ItemTable height="420px" paginationMode="off" data={tenThousandRows} columns={columns} />
641
+ ```
642
+
643
+ Overscroll is locked per axis, and only where the table can actually scroll, so
644
+ a table whose content fits never traps the wheel — the page behind it scrolls as
645
+ usual. On an axis that does scroll, a swipe at the edge neither chains to the
646
+ page (which is what would trigger browser back-navigation) nor rubber-bands,
647
+ since bouncing drags the rows off the sticky header and shows blank surface
648
+ behind them.
649
+
650
+ A native table cannot absolutely position a `<tr>` without breaking the table
651
+ box, so the offset comes from leading and trailing spacer rows. Those are
652
+ `aria-hidden`, and `aria-rowcount` / `aria-rowindex` continue to describe the
653
+ whole dataset rather than the mounted window.
654
+
655
+ Virtualization is skipped for the empty, error and loading states, and turns off
656
+ entirely with `isVirtualized={false}`.
657
+
658
+ ### Wrapping Cells
659
+
660
+ Rows are **measured, not assumed**, so a column with `autoHeight` can wrap to a
661
+ different number of lines per row and the virtualized window still tracks
662
+ correctly.
663
+
664
+ ### Selection
665
+
666
+ `selectionMode="multiple"` adds the checkbox column:
667
+
668
+ ```jsx
669
+ const [keys, setKeys] = useState([]);
670
+
671
+ <ItemTable
672
+ data={deployments}
673
+ columns={columns}
674
+ selectionMode="multiple"
675
+ selectedKeys={keys}
676
+ onSelectionChange={(next) => setKeys(next)}
677
+ />
678
+ ```
679
+
680
+ Selection is **keyed, not indexed**, so it survives sorting, searching and
681
+ paging — the same row stays selected wherever it lands, and a row filtered out
682
+ by a search keeps its key rather than being silently deselected.
683
+
684
+ Shift-click a checkbox to extend the range from the last one you clicked
685
+ plainly. Shift-clicking back toward the anchor shrinks the range rather than
686
+ leaving the overshoot selected.
687
+
688
+ #### Three ways a row can be special
689
+
690
+ Deliberately distinct, and not interchangeable:
691
+
692
+ | Prop | Focusable | Interactive | Selectable |
693
+ | --- | --- | --- | --- |
694
+ | `disabledKeys` | no | no | no |
695
+ | `isRowSelectable` | yes | yes | no |
696
+ | `getRowProps().isDimmed` | yes | yes | **yes** — it is purely visual |
697
+
698
+ `selectionTooltip` explains an inert checkbox, which is the difference between
699
+ "this is broken" and "this row is still deploying".
700
+
701
+ #### What select-all reaches
702
+
703
+ `selectAllMode` decides the scope of the header checkbox:
704
+
705
+ - **`'page'`** (default) — the rows on the current page.
706
+ - **`'filtered'`** — every row passing the current search or filter, across
707
+ pages.
708
+ - **`'all'`** — emits the `'all'` sentinel instead of a key list. This is the
709
+ only mode that can mean rows the client has never loaded, so the consumer
710
+ decides what it means for its query — usually a `DELETE … WHERE <filter>`
711
+ rather than `WHERE id IN (…)`.
712
+
713
+ Unselectable rows are excluded from every scope. Pressing the header checkbox
714
+ while everything in scope is selected clears the **whole** selection, not just
715
+ the scope — leaving keys selected on other pages behind an unchecked-looking box
716
+ is how people delete things they did not mean to.
717
+
718
+ ### Row Links and Row Actions
719
+
720
+ `rowLink` turns the row-header cell into a stretched anchor covering the whole
721
+ row:
722
+
723
+ ```jsx
724
+ <ItemTable
725
+ data={deployments}
726
+ columns={columns}
727
+ rowLink={(row) => `/deployments/${row.id}`}
728
+ />
729
+ ```
730
+
731
+ Because it is a real `<a href>`, ⌘-click, middle-click and "Open in new tab"
732
+ all work natively — none of which an `onClick` handler can give you. The anchor
733
+ sits below the cells' own content in the stacking order, so a button or `⋮`
734
+ trigger inside a cell still takes its own clicks, and its accessible name comes
735
+ from the row-header cell rather than being announced as "link".
736
+
737
+ The row-header cell is styled as a link — `#purple-text` at weight 600, matching
738
+ the kit's `Link`, with an underline while the row is hovered. The anchor itself
739
+ is invisible, so without that the row would give no sign that it navigates.
740
+
741
+ `onRowAction` is the non-navigational alternative — Enter, or a click that did
742
+ not land on a control inside a cell. Use one or the other, not both.
743
+
744
+ ### Row Menu
745
+
746
+ `rowMenu` supplies `Menu.Item` children, and `rowContextMenu` decides where they
747
+ are exposed. The split is deliberate: `rowMenu` alone renders nothing, so a row
748
+ never grows a `⋮` nobody asked for.
749
+
750
+ ```jsx
751
+ <ItemTable
752
+ data={deployments}
753
+ columns={columns}
754
+ rowContextMenu
755
+ rowMenu={(row) => (
756
+ <>
757
+ <Menu.Item key="open">Open {row.name}</Menu.Item>
758
+ <Menu.Item key="delete">Delete</Menu.Item>
759
+ </>
760
+ )}
761
+ onRowMenuAction={(action, row) => run(action, row)}
762
+ />
763
+ ```
764
+
765
+ | `rowContextMenu` | `⋮` column | Right-click / Shift+F10 |
766
+ | --- | --- | --- |
767
+ | `false` (default) | no | no |
768
+ | `true` | yes | yes |
769
+ | `'context-only'` | no | yes |
770
+
771
+ A row whose resolver returns `null` gets no trigger, and right-clicking it falls
772
+ through to the browser's own context menu — more useful than an empty popover.
773
+
774
+ ### Bulk Actions
775
+
776
+ `bulkActions` implies `selectionMode="multiple"` — a bulk action with no way to
777
+ select rows is a contradiction, not a configuration.
778
+
779
+ ```jsx
780
+ <ItemTable
781
+ data={deployments}
782
+ columns={columns}
783
+ bulkActions={[
784
+ {
785
+ key: 'restart',
786
+ label: 'Restart',
787
+ onAction: async (rows, { setLoading }) => {
788
+ setLoading(true);
789
+ await restart(rows.map((row) => row.id));
790
+ },
791
+ },
792
+ {
793
+ key: 'delete',
794
+ label: 'Delete',
795
+ theme: 'danger',
796
+ isDisabled: (rows) => rows.some((row) => row.status === 'running'),
797
+ disabledTooltip: 'A running deployment cannot be deleted',
798
+ onAction: (rows) => remove(rows),
799
+ },
800
+ ]}
801
+ />
802
+ ```
803
+
804
+ Each action drives its own spinner through `setLoading`, so one slow request
805
+ does not freeze the others, and the selection clears when the action resolves.
806
+ Opt out with `deselectAfter: false` for an action that only reads — the default
807
+ exists because the rows an action just deleted or moved are usually gone.
808
+
809
+ `bulkBarPlacement="floating"` (the default) centres the bar over the body
810
+ without changing the table's height, so the rows never shift under the cursor.
811
+ `"toolbar"` takes over the `actions` group instead, for a page whose toolbar is
812
+ already crowded — the two compete for the same space, and while rows are
813
+ selected the bulk actions are what the user is reaching for.
814
+
815
+ **Escape** clears the selection from anywhere inside the table.
816
+
817
+ `ItemTable.BulkBar` is available as a compound member for placing the bar
818
+ outside the default chrome; it reads the selection from context, so there is
819
+ still exactly one owner.
820
+
821
+ ### Reordering Rows
822
+
823
+ `isReorderable` lets rows be dragged into a new order:
824
+
825
+ ```jsx
826
+ <ItemTable
827
+ isReorderable
828
+ data={rows}
829
+ columns={columns}
830
+ onReorder={(keys, nextRows) => setRows(nextRows)}
831
+ />
832
+ ```
833
+
834
+ It is built on React Aria's collection drag-and-drop, through the same
835
+ `DraggableCollection` wrapper `Tabs` and `ListBox` use — `RowCollection` and the
836
+ table's own `SelectionManager` satisfy its contract unchanged.
837
+
838
+ That buys the keyboard path as well as the pointer one: the grid takes a single
839
+ tab stop, arrows move between rows, Enter picks a row up and drops it, Escape
840
+ cancels. The drop line is drawn **on** the row rather than between rows, because
841
+ a native table has nowhere to put an element between two `<tr>`s.
842
+
843
+ `onReorder` reports the whole key order rather than just the moved row, so the
844
+ result can be persisted without reconstructing it.
845
+
846
+ ### Dropping Rows onto a Row
847
+
848
+ Some tables move rows *into* other rows rather than around them — a workbook
849
+ into a folder. `dropOnRow` covers that, and enables dragging on its own:
850
+
851
+ ```jsx
852
+ <ItemTable
853
+ data={items}
854
+ columns={columns}
855
+ dropOnRow={{
856
+ isTarget: (row) => row.type === 'folder',
857
+ isAllowed: (dragged, target) => dragged.every((row) => row.id !== target.id),
858
+ onDrop: (dragged, target) => move(dragged, target),
859
+ }}
860
+ />
861
+ ```
862
+
863
+ This is a **different case from reordering**, and usually the only one a given
864
+ table wants: Cloud's Workbooks page drags items into folders and never reorders
865
+ them. The story below is that shape.
866
+
867
+ They do compose if you need it — set `isReorderable` as well and a row that
868
+ refuses a drop falls back to reordering — but that combination is rare. Cloud
869
+ has to treat them as mutually exclusive because ag-grid cannot express both at
870
+ once; that restriction does not carry over.
871
+
872
+ `dropOnRow` replaces Cloud's `isDropOnRowEnabled`, `isDropTarget`,
873
+ `isDropOnRowAllowed` and `onDropOnRow` with one object, and drops the two
874
+ ag-grid workarounds beside them (`dropTargetRowKeyRef`,
875
+ `dropTargetRefreshColumnKey`) that existed only because ag-grid cannot re-render
876
+ a single cell from React state. Here the hovered row is just
877
+ `ctx.isDropTarget`.
878
+
879
+ ### Column Resize
880
+
881
+ `isResizable` puts a grab handle on each column's trailing edge:
882
+
883
+ ```jsx
884
+ <ItemTable isResizable storageKey="deployments" data={rows} columns={columns} />
885
+ ```
886
+
887
+ It is built on React Aria's `useMove` — the same hook behind `Board`'s widgets —
888
+ so the handle takes **keyboard** input for free: focus it and use the arrow
889
+ keys, or Home/End to jump to the column's minimum and maximum. Widths clamp to
890
+ each column's `minWidth` / `maxWidth`, and a column opts out with
891
+ `isResizable: false`.
892
+
893
+ `onColumnResize` fires once the gesture ends rather than on every pixel, and
894
+ `columnWidths` is in the default `persist` list, so pairing `isResizable` with
895
+ `storageKey` makes a resized table come back the way the user left it.
896
+
897
+ ### Persisting State
898
+
899
+ `storageKey` remembers the parts of the table's state a user expects to survive
900
+ a reload:
901
+
902
+ ```jsx
903
+ <ItemTable data={rows} columns={columns} storageKey="deployments" />
904
+ ```
905
+
906
+ Only state the **table** owns is stored, so a controlled `pageSize` or `sort`
907
+ stays entirely the page's business. Sort is opt-in via `persist` — a stored sort
908
+ silently changes what the first screen of a table means, which is rarely what
909
+ you want by default:
910
+
911
+ ```jsx
912
+ <ItemTable storageKey="deployments" persist={['pageSize', 'sort']} data={rows} columns={columns} />
913
+ ```
914
+
915
+ Reads and writes are best-effort: private mode, a disabled store, a quota error
916
+ or a hand-edited value all degrade to "no persistence" rather than failing.
917
+
918
+ ### Per-row Visuals
919
+
920
+ ```jsx
921
+ <ItemTable
922
+ getRowProps={({ row }) => ({ isDimmed: row.status === 'stopped' })}
923
+ data={rows}
924
+ columns={columns}
925
+ />
926
+ ```
927
+
928
+ ## Accessibility
929
+
930
+ ### Screen Reader Support
931
+
932
+ - The `<table>` carries `role="grid"` with `aria-rowcount` and `aria-colcount`.
933
+ - Row and column indices are **1-based and document-absolute** — header rows are
934
+ counted, and the indices stay truthful when rows are virtualized or columns
935
+ are pinned.
936
+ - A column marked `isRowHeader` renders `<th scope="row">`, so a screen reader
937
+ announces the row by name when moving between cells.
938
+ - `aria-sort` is set on the sorted header only, never `"none"` on the rest.
939
+ - `aria-busy` is set while loading; skeleton rows keep the full cell structure so
940
+ nothing shifts when the data lands.
941
+
942
+ ### ARIA Properties
943
+
944
+ | Property | Applied to |
945
+ | -------- | ---------- |
946
+ | `role="grid"` | the `<table>` |
947
+ | `aria-rowcount` / `aria-colcount` | the `<table>` |
948
+ | `aria-rowindex` | every `<tr>` |
949
+ | `aria-colindex` | every cell and column header |
950
+ | `aria-sort` | the sorted column header |
951
+ | `aria-busy` | the grid and its skeleton rows |
952
+
953
+ ## Best Practices
954
+
955
+ - Do: mark one column `isRowHeader`. It names the row for assistive tech and is
956
+ where a row link will anchor.
957
+ - Do: give a column `format` when its display text differs from its raw value —
958
+ that is what keeps it sortable, searchable and copyable.
959
+ - Do: bound the table's height. Without a bound it grows to fit, the header
960
+ cannot stick, and virtualization has no viewport to work against.
961
+ - Do: leave the header preset alone unless you have a reason. `c3` is what the
962
+ Cloud list tables use, and the header `Item` inherits the cell's typography so
963
+ overriding `headerPreset` restyles the whole header consistently.
964
+ - Do: pass `isFiltered` when you filter `data` yourself, so the empty state says
965
+ "no matches".
966
+ - Don't: reach for `render` to reformat text. `format` does it in a way the rest
967
+ of the table understands — including sorting and search.
968
+ - Don't: filter `data` yourself *and* leave `isFiltered` unset, or an empty
969
+ result will read as "nothing exists".
970
+ - Don't: put an `Item` in every cell. `Item` runs a hotkey subscription per
971
+ instance; use `TextItem` (which the table does automatically for plain text)
972
+ and reserve `Item` for the row-header cell.
973
+
974
+ ## Suggested Improvements
975
+
976
+ - Selection, pagination, row menus and drag & drop are arriving in follow-ups.
977
+ - Multi-column sorting (the sibling `DataTable` will take `sorts: []`).
978
+
979
+ ## Related Components
980
+
981
+ - [Pagination](../navigation/Pagination.md) — pairs with the table footer
982
+ - [Item](../content/Item.md) — the header cell's content
983
+ - [TextItem](../content/TextItem.md) — truncating body text
984
+ - [ListBox](../fields/ListBox.md) — when there is only one column