@elliemae/ds-data-table 3.80.0-next.62 → 3.80.0-next.65

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 (366) hide show
  1. package/dist/cjs/TruncatedTooltipText.js +1 -3
  2. package/dist/cjs/TruncatedTooltipText.js.map +2 -2
  3. package/dist/cjs/addons/Columns/ColumnAction/ColumnAction.js.map +2 -2
  4. package/dist/cjs/addons/Columns/ColumnDragHandle/ColumnDragHandle.js +27 -19
  5. package/dist/cjs/addons/Columns/ColumnDragHandle/ColumnDragHandle.js.map +2 -2
  6. package/dist/cjs/addons/Columns/ColumnExpand/ColumnExpand.js +25 -17
  7. package/dist/cjs/addons/Columns/ColumnExpand/ColumnExpand.js.map +2 -2
  8. package/dist/cjs/addons/Columns/ColumnSelectSingle/ColumnSelectSingle.js +24 -14
  9. package/dist/cjs/addons/Columns/ColumnSelectSingle/ColumnSelectSingle.js.map +2 -2
  10. package/dist/cjs/addons/Filters/Components/CurrencyRangeFilter/CurrencyRangeFilterV2.js.map +2 -2
  11. package/dist/cjs/addons/Filters/Components/CurrencyRangeFilter/index.js.map +2 -2
  12. package/dist/cjs/addons/Filters/Components/DateRangeFilter/DateRangeFilterV2.js.map +2 -2
  13. package/dist/cjs/addons/Filters/Components/DateRangeFilter/index.js.map +2 -2
  14. package/dist/cjs/addons/Filters/Components/DateSwitcherFilter/DateSwitcherFilterV2.js.map +2 -2
  15. package/dist/cjs/addons/Filters/Components/DateSwitcherFilter/index.js.map +2 -2
  16. package/dist/cjs/addons/Filters/Components/NumberRangeFilter/NumberRangeFilterV2.js.map +2 -2
  17. package/dist/cjs/addons/Filters/Components/NumberRangeFilter/index.js.map +2 -2
  18. package/dist/cjs/addons/Filters/Components/SelectFilter/BaseSelectFilter.js.map +2 -2
  19. package/dist/cjs/addons/Filters/Components/SelectFilter/BaseSelectFilterV2.js.map +2 -2
  20. package/dist/cjs/addons/Filters/Components/SelectFilter/MultiCreatableFilter.js.map +2 -2
  21. package/dist/cjs/addons/Filters/Components/SelectFilter/MultiCreatableFilterV2.js.map +2 -2
  22. package/dist/cjs/addons/Filters/Components/SelectFilter/MultiSelectFilter.js.map +2 -2
  23. package/dist/cjs/addons/Filters/Components/SelectFilter/MultiSelectFilterV2.js.map +2 -2
  24. package/dist/cjs/addons/Filters/Components/SelectFilter/SingleCreatableFilter.js.map +2 -2
  25. package/dist/cjs/addons/Filters/Components/SelectFilter/SingleCreatableFilterV2.js.map +2 -2
  26. package/dist/cjs/addons/Filters/Components/SelectFilter/SingleSelectFilter.js.map +2 -2
  27. package/dist/cjs/addons/Filters/Components/SelectFilter/SingleSelectFilterV2.js.map +2 -2
  28. package/dist/cjs/addons/Filters/Components/SingleDateFilter/SingleDateFilterV2.js.map +2 -2
  29. package/dist/cjs/addons/Filters/Components/SingleDateFilter/index.js.map +2 -2
  30. package/dist/cjs/configs/constants.js +1 -3
  31. package/dist/cjs/configs/constants.js.map +2 -2
  32. package/dist/cjs/configs/index.js +0 -1
  33. package/dist/cjs/configs/index.js.map +2 -2
  34. package/dist/cjs/configs/useStore/index.js +1 -7
  35. package/dist/cjs/configs/useStore/index.js.map +2 -2
  36. package/dist/cjs/configs/useTableColsWithAddons.js +2 -2
  37. package/dist/cjs/configs/useTableColsWithAddons.js.map +2 -2
  38. package/dist/cjs/constants/index.js +2 -1
  39. package/dist/cjs/constants/index.js.map +2 -2
  40. package/dist/cjs/exported-related/EditableCell.js +6 -4
  41. package/dist/cjs/exported-related/EditableCell.js.map +2 -2
  42. package/dist/cjs/exported-related/FilterBar/FilterBarDropdownMenu.js +16 -62
  43. package/dist/cjs/exported-related/FilterBar/FilterBarDropdownMenu.js.map +2 -2
  44. package/dist/cjs/exported-related/FilterBar/FilterMenuButton.js +15 -15
  45. package/dist/cjs/exported-related/FilterBar/FilterMenuButton.js.map +2 -2
  46. package/dist/cjs/exported-related/FilterBar/PillsFromDataTableFilters.js.map +2 -2
  47. package/dist/cjs/{parts/RowVariants/types.js → exported-related/FilterBar/dropdownMenuV2Bridge/bridgeTypes.js} +3 -3
  48. package/dist/cjs/exported-related/FilterBar/dropdownMenuV2Bridge/bridgeTypes.js.map +7 -0
  49. package/dist/cjs/exported-related/FilterBar/dropdownMenuV2Bridge/conversionHelpers.js +137 -0
  50. package/dist/cjs/exported-related/FilterBar/dropdownMenuV2Bridge/conversionHelpers.js.map +7 -0
  51. package/dist/cjs/exported-related/FilterBar/dropdownMenuV2Bridge/getHumanReadableWarnings.js +64 -0
  52. package/dist/cjs/exported-related/FilterBar/dropdownMenuV2Bridge/getHumanReadableWarnings.js.map +7 -0
  53. package/dist/cjs/exported-related/FilterBar/dropdownMenuV2Bridge/index.js +113 -0
  54. package/dist/cjs/exported-related/FilterBar/dropdownMenuV2Bridge/index.js.map +7 -0
  55. package/dist/cjs/exported-related/FilterBar/dropdownMenuV2Bridge/types.js.map +7 -0
  56. package/dist/cjs/exported-related/FilterPopover/FilterPopoverV2.js +17 -8
  57. package/dist/cjs/exported-related/FilterPopover/FilterPopoverV2.js.map +2 -2
  58. package/dist/cjs/exported-related/FilterPopover/index.js +11 -2
  59. package/dist/cjs/exported-related/FilterPopover/index.js.map +2 -2
  60. package/dist/cjs/exported-related/FilterPopover/styled.js +11 -0
  61. package/dist/cjs/exported-related/FilterPopover/styled.js.map +2 -2
  62. package/dist/cjs/exported-related/FilterPopover/useGetFilterHandlers.js.map +1 -1
  63. package/dist/cjs/exported-related/FilterTypes.js +10 -0
  64. package/dist/cjs/exported-related/FilterTypes.js.map +2 -2
  65. package/dist/cjs/exported-related/RowRenderer/DefaultRowContentRenderer.js.map +2 -2
  66. package/dist/cjs/exported-related/RowRenderer/index.js +2 -0
  67. package/dist/cjs/exported-related/RowRenderer/index.js.map +2 -2
  68. package/dist/cjs/exported-related/Toolbar/Toolbar.js +36 -22
  69. package/dist/cjs/exported-related/Toolbar/Toolbar.js.map +2 -2
  70. package/dist/cjs/helpers/getIdFromUniqueRowAccessor.js.map +1 -1
  71. package/dist/cjs/helpers/gridLayoutHelpers.js +2 -0
  72. package/dist/cjs/helpers/gridLayoutHelpers.js.map +2 -2
  73. package/dist/cjs/helpers/index.js +1 -0
  74. package/dist/cjs/helpers/index.js.map +2 -2
  75. package/dist/cjs/{parts/internal.js → helpers/smallButtonSize.js} +17 -8
  76. package/dist/cjs/helpers/smallButtonSize.js.map +7 -0
  77. package/dist/cjs/parts/Cells/CellFactory.js.map +2 -2
  78. package/dist/cjs/parts/Cells/index.js +19 -8
  79. package/dist/cjs/parts/Cells/index.js.map +2 -2
  80. package/dist/cjs/parts/DnDHandle.js +4 -2
  81. package/dist/cjs/parts/DnDHandle.js.map +2 -2
  82. package/dist/cjs/parts/DropIndicator.js.map +2 -2
  83. package/dist/cjs/parts/EmptyContent.js +2 -2
  84. package/dist/cjs/parts/EmptyContent.js.map +2 -2
  85. package/dist/cjs/parts/FilterBar/FilterBarMenuButtonAddon.js +88 -0
  86. package/dist/cjs/parts/FilterBar/FilterBarMenuButtonAddon.js.map +7 -0
  87. package/dist/cjs/parts/FilterBar/FiltersBar.js +4 -39
  88. package/dist/cjs/parts/FilterBar/FiltersBar.js.map +2 -2
  89. package/dist/cjs/parts/FilterBar/components/MultiSelectPill.js.map +2 -2
  90. package/dist/cjs/{configs/fixedSizes.js → parts/FilterBar/convertExtraOptions.js} +16 -8
  91. package/dist/cjs/parts/FilterBar/convertExtraOptions.js.map +7 -0
  92. package/dist/cjs/parts/Headers/EmptyChildrenGroup.js +4 -2
  93. package/dist/cjs/parts/Headers/EmptyChildrenGroup.js.map +2 -2
  94. package/dist/cjs/parts/Headers/HeaderCell.js +29 -11
  95. package/dist/cjs/parts/Headers/HeaderCell.js.map +2 -2
  96. package/dist/cjs/parts/Headers/HeaderCellGroup.js +3 -1
  97. package/dist/cjs/parts/Headers/HeaderCellGroup.js.map +2 -2
  98. package/dist/cjs/parts/Headers/HeaderCellTitle.js +5 -1
  99. package/dist/cjs/parts/Headers/HeaderCellTitle.js.map +2 -2
  100. package/dist/cjs/parts/Headers/HeaderResizer.js +3 -1
  101. package/dist/cjs/parts/Headers/HeaderResizer.js.map +2 -2
  102. package/dist/cjs/parts/Headers/useHeaderCellConfig.js.map +2 -2
  103. package/dist/cjs/parts/Headers/useHeaderCellHandlers.js.map +2 -2
  104. package/dist/cjs/parts/Headers/useHeaderResizer.js +2 -2
  105. package/dist/cjs/parts/Headers/useHeaderResizer.js.map +2 -2
  106. package/dist/cjs/parts/HoC/withConditionalDnDSortableContext.js.map +2 -2
  107. package/dist/cjs/parts/RowVariants/RowVariantHeader.js +6 -2
  108. package/dist/cjs/parts/RowVariants/RowVariantHeader.js.map +2 -2
  109. package/dist/cjs/parts/SkeletonTable.js +1 -1
  110. package/dist/cjs/parts/SkeletonTable.js.map +2 -2
  111. package/dist/cjs/parts/SortByCaret.js +0 -1
  112. package/dist/cjs/parts/SortByCaret.js.map +2 -2
  113. package/dist/cjs/react-desc-prop-types.js +75 -21
  114. package/dist/cjs/react-desc-prop-types.js.map +2 -2
  115. package/dist/cjs/styled.js +7 -1
  116. package/dist/cjs/styled.js.map +2 -2
  117. package/dist/cjs/tentative-typescript-testing-for-unsafe-type/README.md +9 -0
  118. package/dist/cjs/tentative-typescript-testing-for-unsafe-type/filter-bar-props.js +71 -0
  119. package/dist/cjs/tentative-typescript-testing-for-unsafe-type/filter-bar-props.js.map +7 -0
  120. package/dist/cjs/tentative-typescript-testing-for-unsafe-type/get-row-variant.js +38 -0
  121. package/dist/cjs/tentative-typescript-testing-for-unsafe-type/get-row-variant.js.map +7 -0
  122. package/dist/cjs/{parts/FilterBar/index.js → tentative-typescript-testing-for-unsafe-type/sizes.js} +10 -12
  123. package/dist/cjs/tentative-typescript-testing-for-unsafe-type/sizes.js.map +7 -0
  124. package/dist/cjs/tentative-typescript-testing-for-unsafe-type/slot-props.js +134 -0
  125. package/dist/cjs/tentative-typescript-testing-for-unsafe-type/slot-props.js.map +7 -0
  126. package/dist/esm/TruncatedTooltipText.js +2 -8
  127. package/dist/esm/TruncatedTooltipText.js.map +2 -2
  128. package/dist/esm/addons/Columns/ColumnAction/ColumnAction.js.map +2 -2
  129. package/dist/esm/addons/Columns/ColumnDragHandle/ColumnDragHandle.js +28 -20
  130. package/dist/esm/addons/Columns/ColumnDragHandle/ColumnDragHandle.js.map +2 -2
  131. package/dist/esm/addons/Columns/ColumnExpand/ColumnExpand.js +25 -17
  132. package/dist/esm/addons/Columns/ColumnExpand/ColumnExpand.js.map +2 -2
  133. package/dist/esm/addons/Columns/ColumnSelectSingle/ColumnSelectSingle.js +24 -14
  134. package/dist/esm/addons/Columns/ColumnSelectSingle/ColumnSelectSingle.js.map +2 -2
  135. package/dist/esm/addons/Filters/Components/CurrencyRangeFilter/CurrencyRangeFilterV2.js.map +2 -2
  136. package/dist/esm/addons/Filters/Components/CurrencyRangeFilter/index.js.map +2 -2
  137. package/dist/esm/addons/Filters/Components/DateRangeFilter/DateRangeFilterV2.js.map +2 -2
  138. package/dist/esm/addons/Filters/Components/DateRangeFilter/index.js.map +2 -2
  139. package/dist/esm/addons/Filters/Components/DateSwitcherFilter/DateSwitcherFilterV2.js.map +2 -2
  140. package/dist/esm/addons/Filters/Components/DateSwitcherFilter/index.js.map +2 -2
  141. package/dist/esm/addons/Filters/Components/NumberRangeFilter/NumberRangeFilterV2.js.map +2 -2
  142. package/dist/esm/addons/Filters/Components/NumberRangeFilter/index.js.map +2 -2
  143. package/dist/esm/addons/Filters/Components/SelectFilter/BaseSelectFilter.js.map +2 -2
  144. package/dist/esm/addons/Filters/Components/SelectFilter/BaseSelectFilterV2.js.map +2 -2
  145. package/dist/esm/addons/Filters/Components/SelectFilter/MultiCreatableFilter.js.map +2 -2
  146. package/dist/esm/addons/Filters/Components/SelectFilter/MultiCreatableFilterV2.js.map +2 -2
  147. package/dist/esm/addons/Filters/Components/SelectFilter/MultiSelectFilter.js.map +2 -2
  148. package/dist/esm/addons/Filters/Components/SelectFilter/MultiSelectFilterV2.js.map +2 -2
  149. package/dist/esm/addons/Filters/Components/SelectFilter/SingleCreatableFilter.js.map +2 -2
  150. package/dist/esm/addons/Filters/Components/SelectFilter/SingleCreatableFilterV2.js.map +2 -2
  151. package/dist/esm/addons/Filters/Components/SelectFilter/SingleSelectFilter.js.map +2 -2
  152. package/dist/esm/addons/Filters/Components/SelectFilter/SingleSelectFilterV2.js.map +2 -2
  153. package/dist/esm/addons/Filters/Components/SingleDateFilter/SingleDateFilterV2.js.map +2 -2
  154. package/dist/esm/addons/Filters/Components/SingleDateFilter/index.js.map +2 -2
  155. package/dist/esm/configs/constants.js +1 -3
  156. package/dist/esm/configs/constants.js.map +2 -2
  157. package/dist/esm/configs/index.js +0 -1
  158. package/dist/esm/configs/index.js.map +2 -2
  159. package/dist/esm/configs/useStore/index.js +2 -8
  160. package/dist/esm/configs/useStore/index.js.map +2 -2
  161. package/dist/esm/configs/useTableColsWithAddons.js +2 -2
  162. package/dist/esm/configs/useTableColsWithAddons.js.map +2 -2
  163. package/dist/esm/constants/index.js +2 -1
  164. package/dist/esm/constants/index.js.map +2 -2
  165. package/dist/esm/exported-related/EditableCell.js +6 -4
  166. package/dist/esm/exported-related/EditableCell.js.map +2 -2
  167. package/dist/esm/exported-related/FilterBar/FilterBarDropdownMenu.js +17 -63
  168. package/dist/esm/exported-related/FilterBar/FilterBarDropdownMenu.js.map +2 -2
  169. package/dist/esm/exported-related/FilterBar/FilterMenuButton.js +16 -16
  170. package/dist/esm/exported-related/FilterBar/FilterMenuButton.js.map +2 -2
  171. package/dist/esm/exported-related/FilterBar/PillsFromDataTableFilters.js.map +2 -2
  172. package/dist/esm/exported-related/FilterBar/dropdownMenuV2Bridge/bridgeTypes.js +2 -0
  173. package/dist/esm/{parts/RowVariants/types.js.map → exported-related/FilterBar/dropdownMenuV2Bridge/bridgeTypes.js.map} +1 -1
  174. package/dist/esm/exported-related/FilterBar/dropdownMenuV2Bridge/conversionHelpers.js +107 -0
  175. package/dist/esm/exported-related/FilterBar/dropdownMenuV2Bridge/conversionHelpers.js.map +7 -0
  176. package/dist/esm/exported-related/FilterBar/dropdownMenuV2Bridge/getHumanReadableWarnings.js +34 -0
  177. package/dist/esm/exported-related/FilterBar/dropdownMenuV2Bridge/getHumanReadableWarnings.js.map +7 -0
  178. package/dist/esm/exported-related/FilterBar/dropdownMenuV2Bridge/index.js +89 -0
  179. package/dist/esm/exported-related/FilterBar/dropdownMenuV2Bridge/index.js.map +7 -0
  180. package/dist/esm/exported-related/{FilterPopover → FilterBar/dropdownMenuV2Bridge}/types.js.map +1 -1
  181. package/dist/esm/exported-related/FilterPopover/FilterPopoverV2.js +17 -8
  182. package/dist/esm/exported-related/FilterPopover/FilterPopoverV2.js.map +2 -2
  183. package/dist/esm/exported-related/FilterPopover/index.js +11 -2
  184. package/dist/esm/exported-related/FilterPopover/index.js.map +2 -2
  185. package/dist/esm/exported-related/FilterPopover/styled.js +11 -0
  186. package/dist/esm/exported-related/FilterPopover/styled.js.map +2 -2
  187. package/dist/esm/exported-related/FilterPopover/useGetFilterHandlers.js.map +1 -1
  188. package/dist/esm/exported-related/FilterTypes.js +10 -0
  189. package/dist/esm/exported-related/FilterTypes.js.map +2 -2
  190. package/dist/esm/exported-related/RowRenderer/DefaultRowContentRenderer.js.map +2 -2
  191. package/dist/esm/exported-related/RowRenderer/index.js +3 -1
  192. package/dist/esm/exported-related/RowRenderer/index.js.map +2 -2
  193. package/dist/esm/exported-related/Toolbar/Toolbar.js +36 -22
  194. package/dist/esm/exported-related/Toolbar/Toolbar.js.map +2 -2
  195. package/dist/esm/helpers/getIdFromUniqueRowAccessor.js.map +1 -1
  196. package/dist/esm/helpers/gridLayoutHelpers.js +2 -0
  197. package/dist/esm/helpers/gridLayoutHelpers.js.map +2 -2
  198. package/dist/esm/helpers/index.js +1 -0
  199. package/dist/esm/helpers/index.js.map +2 -2
  200. package/dist/esm/helpers/smallButtonSize.js +17 -0
  201. package/dist/esm/helpers/smallButtonSize.js.map +7 -0
  202. package/dist/esm/parts/Cells/CellFactory.js.map +2 -2
  203. package/dist/esm/parts/Cells/index.js +19 -8
  204. package/dist/esm/parts/Cells/index.js.map +2 -2
  205. package/dist/esm/parts/DnDHandle.js +5 -3
  206. package/dist/esm/parts/DnDHandle.js.map +2 -2
  207. package/dist/esm/parts/DropIndicator.js.map +2 -2
  208. package/dist/esm/parts/EmptyContent.js +2 -2
  209. package/dist/esm/parts/EmptyContent.js.map +2 -2
  210. package/dist/esm/parts/FilterBar/FilterBarMenuButtonAddon.js +58 -0
  211. package/dist/esm/parts/FilterBar/FilterBarMenuButtonAddon.js.map +7 -0
  212. package/dist/esm/parts/FilterBar/FiltersBar.js +5 -40
  213. package/dist/esm/parts/FilterBar/FiltersBar.js.map +2 -2
  214. package/dist/esm/parts/FilterBar/components/MultiSelectPill.js.map +2 -2
  215. package/dist/esm/parts/FilterBar/convertExtraOptions.js +16 -0
  216. package/dist/esm/parts/FilterBar/convertExtraOptions.js.map +7 -0
  217. package/dist/esm/parts/Headers/EmptyChildrenGroup.js +4 -2
  218. package/dist/esm/parts/Headers/EmptyChildrenGroup.js.map +2 -2
  219. package/dist/esm/parts/Headers/HeaderCell.js +29 -11
  220. package/dist/esm/parts/Headers/HeaderCell.js.map +2 -2
  221. package/dist/esm/parts/Headers/HeaderCellGroup.js +4 -2
  222. package/dist/esm/parts/Headers/HeaderCellGroup.js.map +2 -2
  223. package/dist/esm/parts/Headers/HeaderCellTitle.js +5 -1
  224. package/dist/esm/parts/Headers/HeaderCellTitle.js.map +2 -2
  225. package/dist/esm/parts/Headers/HeaderResizer.js +4 -2
  226. package/dist/esm/parts/Headers/HeaderResizer.js.map +2 -2
  227. package/dist/esm/parts/Headers/useHeaderCellConfig.js.map +2 -2
  228. package/dist/esm/parts/Headers/useHeaderCellHandlers.js.map +2 -2
  229. package/dist/esm/parts/Headers/useHeaderResizer.js +3 -2
  230. package/dist/esm/parts/Headers/useHeaderResizer.js.map +2 -2
  231. package/dist/esm/parts/HoC/withConditionalDnDSortableContext.js.map +2 -2
  232. package/dist/esm/parts/RowVariants/RowVariantHeader.js +7 -3
  233. package/dist/esm/parts/RowVariants/RowVariantHeader.js.map +2 -2
  234. package/dist/esm/parts/SkeletonTable.js +1 -1
  235. package/dist/esm/parts/SkeletonTable.js.map +2 -2
  236. package/dist/esm/parts/SortByCaret.js +0 -1
  237. package/dist/esm/parts/SortByCaret.js.map +2 -2
  238. package/dist/esm/react-desc-prop-types.js +75 -21
  239. package/dist/esm/react-desc-prop-types.js.map +2 -2
  240. package/dist/esm/styled.js +8 -2
  241. package/dist/esm/styled.js.map +2 -2
  242. package/dist/esm/tentative-typescript-testing-for-unsafe-type/README.md +9 -0
  243. package/dist/esm/tentative-typescript-testing-for-unsafe-type/filter-bar-props.js +48 -0
  244. package/dist/esm/tentative-typescript-testing-for-unsafe-type/filter-bar-props.js.map +7 -0
  245. package/dist/esm/tentative-typescript-testing-for-unsafe-type/get-row-variant.js +15 -0
  246. package/dist/esm/tentative-typescript-testing-for-unsafe-type/get-row-variant.js.map +7 -0
  247. package/dist/esm/tentative-typescript-testing-for-unsafe-type/sizes.js +11 -0
  248. package/dist/esm/tentative-typescript-testing-for-unsafe-type/sizes.js.map +7 -0
  249. package/dist/esm/tentative-typescript-testing-for-unsafe-type/slot-props.js +111 -0
  250. package/dist/esm/tentative-typescript-testing-for-unsafe-type/slot-props.js.map +7 -0
  251. package/dist/types/TruncatedTooltipText.d.ts +2 -7
  252. package/dist/types/addons/Columns/ColumnAction/ColumnAction.d.ts +1 -3
  253. package/dist/types/addons/Filters/Components/CurrencyRangeFilter/CurrencyRangeFilterV2.d.ts +1 -6
  254. package/dist/types/addons/Filters/Components/CurrencyRangeFilter/index.d.ts +1 -6
  255. package/dist/types/addons/Filters/Components/DateRangeFilter/DateRangeFilterV2.d.ts +1 -6
  256. package/dist/types/addons/Filters/Components/DateRangeFilter/index.d.ts +1 -6
  257. package/dist/types/addons/Filters/Components/DateSwitcherFilter/DateSwitcherFilterV2.d.ts +1 -7
  258. package/dist/types/addons/Filters/Components/DateSwitcherFilter/index.d.ts +1 -7
  259. package/dist/types/addons/Filters/Components/NumberRangeFilter/NumberRangeFilterV2.d.ts +1 -6
  260. package/dist/types/addons/Filters/Components/NumberRangeFilter/index.d.ts +1 -6
  261. package/dist/types/addons/Filters/Components/SelectFilter/BaseSelectFilter.d.ts +1 -9
  262. package/dist/types/addons/Filters/Components/SelectFilter/BaseSelectFilterV2.d.ts +1 -9
  263. package/dist/types/addons/Filters/Components/SelectFilter/MultiCreatableFilter.d.ts +1 -4
  264. package/dist/types/addons/Filters/Components/SelectFilter/MultiCreatableFilterV2.d.ts +1 -4
  265. package/dist/types/addons/Filters/Components/SelectFilter/MultiSelectFilter.d.ts +1 -4
  266. package/dist/types/addons/Filters/Components/SelectFilter/MultiSelectFilterV2.d.ts +1 -4
  267. package/dist/types/addons/Filters/Components/SelectFilter/SingleCreatableFilter.d.ts +1 -4
  268. package/dist/types/addons/Filters/Components/SelectFilter/SingleCreatableFilterV2.d.ts +1 -4
  269. package/dist/types/addons/Filters/Components/SelectFilter/SingleSelectFilter.d.ts +1 -4
  270. package/dist/types/addons/Filters/Components/SelectFilter/SingleSelectFilterV2.d.ts +1 -4
  271. package/dist/types/addons/Filters/Components/SingleDateFilter/SingleDateFilterV2.d.ts +1 -3
  272. package/dist/types/addons/Filters/Components/SingleDateFilter/index.d.ts +1 -3
  273. package/dist/types/configs/constants.d.ts +0 -1
  274. package/dist/types/configs/index.d.ts +0 -1
  275. package/dist/types/configs/useStore/index.d.ts +1 -2
  276. package/dist/types/constants/index.d.ts +4 -0
  277. package/dist/types/exported-related/FilterBar/FilterBarDropdownMenu.d.ts +8 -7
  278. package/dist/types/exported-related/FilterBar/FilterMenuButton.d.ts +2 -19
  279. package/dist/types/exported-related/FilterBar/PillsFromDataTableFilters.d.ts +1 -10
  280. package/dist/types/exported-related/FilterBar/dropdownMenuV2Bridge/bridgeTypes.d.ts +22 -0
  281. package/dist/types/exported-related/FilterBar/dropdownMenuV2Bridge/conversionHelpers.d.ts +78 -0
  282. package/dist/types/exported-related/FilterBar/dropdownMenuV2Bridge/getHumanReadableWarnings.d.ts +7 -0
  283. package/dist/types/exported-related/FilterBar/dropdownMenuV2Bridge/index.d.ts +14 -0
  284. package/dist/types/exported-related/FilterBar/dropdownMenuV2Bridge/types.d.ts +60 -0
  285. package/dist/types/exported-related/FilterPopover/FilterPopoverV2.d.ts +2 -2
  286. package/dist/types/exported-related/FilterPopover/index.d.ts +2 -2
  287. package/dist/types/exported-related/FilterPopover/styled.d.ts +3 -1
  288. package/dist/types/exported-related/FilterPopover/useGetFilterHandlers.d.ts +2 -2
  289. package/dist/types/exported-related/FilterTypes.d.ts +10 -0
  290. package/dist/types/exported-related/RowRenderer/DefaultRowContentRenderer.d.ts +2 -2
  291. package/dist/types/exported-related/RowRenderer/index.d.ts +1 -16
  292. package/dist/types/exported-related/Toolbar/Toolbar.d.ts +1 -7
  293. package/dist/types/helpers/gridLayoutHelpers.d.ts +1 -0
  294. package/dist/types/helpers/index.d.ts +1 -0
  295. package/dist/types/helpers/smallButtonSize.d.ts +4 -0
  296. package/dist/types/parts/Cells/CellFactory.d.ts +1 -10
  297. package/dist/types/parts/DnDHandle.d.ts +4 -0
  298. package/dist/types/parts/DropIndicator.d.ts +1 -7
  299. package/dist/types/parts/FilterBar/FilterBarMenuButtonAddon.d.ts +14 -0
  300. package/dist/types/parts/FilterBar/components/MultiSelectPill.d.ts +1 -4
  301. package/dist/types/parts/FilterBar/convertExtraOptions.d.ts +8 -0
  302. package/dist/types/parts/Headers/EmptyChildrenGroup.d.ts +3 -1
  303. package/dist/types/parts/Headers/HeaderCell.d.ts +1 -7
  304. package/dist/types/parts/Headers/HeaderCellTitle.d.ts +1 -8
  305. package/dist/types/parts/Headers/useHeaderCellConfig.d.ts +1 -15
  306. package/dist/types/parts/Headers/useHeaderCellHandlers.d.ts +1 -22
  307. package/dist/types/parts/HoC/withConditionalDnDSortableContext.d.ts +1 -6
  308. package/dist/types/parts/SkeletonTable.d.ts +1 -1
  309. package/dist/types/react-desc-prop-types.d.ts +305 -6
  310. package/package.json +29 -31
  311. package/skills/ds-data-table-boundaries/SKILL.md +50 -43
  312. package/skills/ds-data-table-columns/SKILL.md +17 -11
  313. package/skills/ds-data-table-expandable/SKILL.md +21 -13
  314. package/skills/ds-data-table-feedback/SKILL.md +9 -9
  315. package/skills/ds-data-table-filtering/SKILL.md +32 -11
  316. package/skills/ds-data-table-health-check/SKILL.md +7 -7
  317. package/skills/ds-data-table-migration/SKILL.md +8 -7
  318. package/skills/ds-data-table-pagination/SKILL.md +6 -6
  319. package/skills/ds-data-table-row-variants/SKILL.md +34 -22
  320. package/skills/ds-data-table-selection/SKILL.md +23 -25
  321. package/skills/ds-data-table-setup/SKILL.md +31 -13
  322. package/skills/ds-data-table-slots/SKILL.md +55 -25
  323. package/dist/cjs/addons/Editables/DateEditableCell/DateEditableCell.js +0 -63
  324. package/dist/cjs/addons/Editables/DateEditableCell/DateEditableCell.js.map +0 -7
  325. package/dist/cjs/configs/fixedSizes.js.map +0 -7
  326. package/dist/cjs/configs/useInternalStateConfig.js +0 -80
  327. package/dist/cjs/configs/useInternalStateConfig.js.map +0 -7
  328. package/dist/cjs/configs/useValidateProps.js +0 -47
  329. package/dist/cjs/configs/useValidateProps.js.map +0 -7
  330. package/dist/cjs/exported-related/FilterPopover/types.js.map +0 -7
  331. package/dist/cjs/parts/Cells/Cell.js +0 -126
  332. package/dist/cjs/parts/Cells/Cell.js.map +0 -7
  333. package/dist/cjs/parts/FilterBar/DeprecatedDropdown.js +0 -85
  334. package/dist/cjs/parts/FilterBar/DeprecatedDropdown.js.map +0 -7
  335. package/dist/cjs/parts/FilterBar/index.js.map +0 -7
  336. package/dist/cjs/parts/RowVariants/types.js.map +0 -7
  337. package/dist/cjs/parts/internal.js.map +0 -7
  338. package/dist/esm/addons/Editables/DateEditableCell/DateEditableCell.js +0 -33
  339. package/dist/esm/addons/Editables/DateEditableCell/DateEditableCell.js.map +0 -7
  340. package/dist/esm/configs/fixedSizes.js +0 -8
  341. package/dist/esm/configs/fixedSizes.js.map +0 -7
  342. package/dist/esm/configs/useInternalStateConfig.js +0 -50
  343. package/dist/esm/configs/useInternalStateConfig.js.map +0 -7
  344. package/dist/esm/configs/useValidateProps.js +0 -17
  345. package/dist/esm/configs/useValidateProps.js.map +0 -7
  346. package/dist/esm/parts/Cells/Cell.js +0 -96
  347. package/dist/esm/parts/Cells/Cell.js.map +0 -7
  348. package/dist/esm/parts/FilterBar/DeprecatedDropdown.js +0 -55
  349. package/dist/esm/parts/FilterBar/DeprecatedDropdown.js.map +0 -7
  350. package/dist/esm/parts/FilterBar/index.js +0 -6
  351. package/dist/esm/parts/FilterBar/index.js.map +0 -7
  352. package/dist/esm/parts/RowVariants/types.js +0 -2
  353. package/dist/esm/parts/internal.js +0 -8
  354. package/dist/esm/parts/internal.js.map +0 -7
  355. package/dist/types/addons/Editables/DateEditableCell/DateEditableCell.d.ts +0 -7
  356. package/dist/types/configs/fixedSizes.d.ts +0 -3
  357. package/dist/types/configs/useInternalStateConfig.d.ts +0 -12
  358. package/dist/types/configs/useValidateProps.d.ts +0 -2
  359. package/dist/types/exported-related/FilterPopover/types.d.ts +0 -33
  360. package/dist/types/parts/Cells/Cell.d.ts +0 -12
  361. package/dist/types/parts/FilterBar/DeprecatedDropdown.d.ts +0 -13
  362. package/dist/types/parts/FilterBar/index.d.ts +0 -1
  363. package/dist/types/parts/RowVariants/types.d.ts +0 -19
  364. package/dist/types/parts/internal.d.ts +0 -2
  365. /package/dist/cjs/exported-related/{FilterPopover → FilterBar/dropdownMenuV2Bridge}/types.js +0 -0
  366. /package/dist/esm/exported-related/{FilterPopover → FilterBar/dropdownMenuV2Bridge}/types.js +0 -0
@@ -4,11 +4,12 @@ description: >
4
4
  Row styling variants and visual grouping for @elliemae/ds-data-table. getRowVariant callback
5
5
  returning ROW_VARIANTS values (PRIMARY, SECONDARY, HEADER_GROUP, COMPACT_PRIMARY,
6
6
  COMPACT_SECONDARY). disabledRows Record<uid, boolean>. groupBy utility converting flat data into
7
- nested group objects (dimsumHeaderValue + subRows) that DataTable renders as header-group rows.
8
- groupedRowsRenderHeader for group label rendering (JSX.Element function or static string).
7
+ nested group objects (dimsumHeaderValue + subRows) that DataTable renders as header-group rows when
8
+ getRowVariant returns ROW_VARIANTS.HEADER_GROUP for them. groupedRowsRenderHeader callback for group
9
+ label rendering (a string value is not used as the label).
9
10
  type: core
10
11
  library: ds-data-table
11
- library_version: '3.60.0'
12
+ library_version: '3.80.0'
12
13
  requires:
13
14
  - ds-data-table-setup
14
15
  sources:
@@ -57,7 +58,7 @@ ROW_VARIANTS.SKELETON; // 'ds-skeleton-row' — skeleton loading row; acc
57
58
  ### groupBy — visual header-group rows
58
59
 
59
60
  `groupBy(data, fieldName)` converts a flat data array into a nested group structure that DataTable
60
- renders as header-group rows with their data rows below them.
61
+ renders as group rows with their data rows below them (header styling and expansion have the conditions listed below).
61
62
 
62
63
  **What groupBy produces:**
63
64
 
@@ -65,9 +66,9 @@ renders as header-group rows with their data rows below them.
65
66
  import { groupBy } from '@elliemae/ds-data-table';
66
67
 
67
68
  const rows = [
68
- { id: 1, position: 'Developer', name: 'John', uid: 'abc' },
69
- { id: 2, position: 'Developer', name: 'Jane', uid: 'def' },
70
- { id: 3, position: 'Designer', name: 'Sam', uid: 'ghi' },
69
+ { id: '1', position: 'Developer', name: 'John', uid: 'abc' },
70
+ { id: '2', position: 'Developer', name: 'Jane', uid: 'def' },
71
+ { id: '3', position: 'Designer', name: 'Sam', uid: 'ghi' },
71
72
  ];
72
73
 
73
74
  const groupedData = groupBy(rows, 'position');
@@ -76,22 +77,26 @@ const groupedData = groupBy(rows, 'position');
76
77
  // {
77
78
  // dimsumHeaderValue: 'Developer', // group label — used by getRowVariant and groupedRowsRenderHeader
78
79
  // subRows: [ // the data rows belonging to this group
79
- // { id: 1, position: 'Developer', name: 'John', uid: 'abc' },
80
- // { id: 2, position: 'Developer', name: 'Jane', uid: 'def' },
80
+ // { id: '1', position: 'Developer', name: 'John', uid: 'abc' },
81
+ // { id: '2', position: 'Developer', name: 'Jane', uid: 'def' },
81
82
  // ],
82
- // uid: '<auto-generated>', // stable key for DataTable row identity
83
+ // uid: '<auto-generated>', // key for DataTable row identity (random; new on each groupBy call)
83
84
  // },
84
85
  // {
85
86
  // dimsumHeaderValue: 'Designer',
86
- // subRows: [{ id: 3, position: 'Designer', name: 'Sam', uid: 'ghi' }],
87
+ // subRows: [{ id: '3', position: 'Designer', name: 'Sam', uid: 'ghi' }],
87
88
  // uid: '<auto-generated>',
88
89
  // },
89
90
  // ]
90
91
  ```
91
92
 
92
93
  DataTable receives this nested structure and renders it visually as a flat list:
93
- one header-group row per group (styled via `ROW_VARIANTS.HEADER_GROUP`), followed by
94
- its data rows. DataTable handles the flattening internally — do not manually flatten before passing.
94
+ one row per group, followed by its data rows. DataTable handles the flattening internally — do not manually flatten before passing.
95
+
96
+ Two conditions apply:
97
+
98
+ - A group row is styled as a header only when `getRowVariant` returns `ROW_VARIANTS.HEADER_GROUP` for it. The table does not use `dimsumHeaderValue` to choose the header row component.
99
+ - A group's data rows are shown only while the group is expanded, and only when `isExpandable` is set. So the grouped table needs `isExpandable`, a controlled `expandedRows` and `onRowExpand` (see https://dimsum.mortgagetech.ice.com/iframe.html?id=components-datatable-advanced--group-by-column).
95
100
 
96
101
  **Wiring getRowVariant and groupedRowsRenderHeader:**
97
102
 
@@ -102,7 +107,8 @@ const getRowVariant = useCallback((row) => {
102
107
  return ROW_VARIANTS.PRIMARY;
103
108
  }, []);
104
109
 
105
- // groupedRowsRenderHeader: function returning JSX.Element, or a static string.
110
+ // groupedRowsRenderHeader: a callback (value, subRows) returning the group label. A static string
111
+ // value is not used: the header falls back to dimsumHeaderValue.
106
112
  // groupedRowsRenderHeader is a plain function called at render time — not a React component.
107
113
  // Do not call hooks in the callback body (the linter will flag this).
108
114
  // If returning a JSX element containing a component (e.g.
@@ -117,11 +123,17 @@ const groupedRowsRenderHeader = useCallback(
117
123
  [],
118
124
  );
119
125
 
126
+ const { expandedRows } = useSelector(selectTableState);
127
+ const handleRowExpand = useCallback((newExpandedRows) => dispatch(setExpandedRows(newExpandedRows)), [dispatch]);
128
+
120
129
  <DataTable
121
130
  columns={columns}
122
131
  data={groupedData}
123
132
  height={500}
133
+ isExpandable
124
134
  uniqueRowAccessor="uid"
135
+ expandedRows={expandedRows}
136
+ onRowExpand={handleRowExpand}
125
137
  getRowVariant={getRowVariant}
126
138
  groupedRowsRenderHeader={groupedRowsRenderHeader}
127
139
  />;
@@ -177,7 +189,7 @@ const getRowVariant = (row) => {
177
189
  };
178
190
  ```
179
191
 
180
- `ROW_VARIANTS.HIGHLIGHTED` does not exist. The full set of valid values is `PRIMARY`, `SECONDARY`, `HEADER_GROUP`, `COMPACT_PRIMARY`, `COMPACT_SECONDARY`, `SKELETON`. Returning an unrecognised string throws at runtime: `Error: <value> is not an out-of-the-box row variant` — it does not silently fall back.
192
+ `ROW_VARIANTS.HIGHLIGHTED` does not exist, so the expression evaluates to `undefined`, which the table tries to render as a component type and React rejects with an error. The full set of valid values is `PRIMARY`, `SECONDARY`, `HEADER_GROUP`, `COMPACT_PRIMARY`, `COMPACT_SECONDARY`, `SKELETON`. Returning an unrecognised string literal (for example `'ds-highlighted-row'`) throws at runtime: `Error: <value> is not an out-of-the-box row variant` — it does not silently fall back.
181
193
 
182
194
  ---
183
195
 
@@ -218,7 +230,7 @@ const getRowVariant = useCallback((row) => {
218
230
 
219
231
  `getRowVariant` accepts `RowVariant | React.ComponentType<RowVariantProps>` — the component _reference_ (not a JSX element instance). Returning `<CustomHeaderRow row={row} />` creates a new element object on every call and passes the wrong type. Returning `CustomHeaderRow` (a stable module-level reference) is type-correct and does not violate the rule that component props must receive stable module-level references.
220
232
 
221
- However, DataTable renders the component by spreading the full internal `RowVariantProps` onto it — including `focusedRowId`, `drilldownRowId`, `itemIndex`, `draggableProps`, `isDragOverlay`, `minHeight`, `height`, `dropIndicatorPosition`, `isDropValid`, and `CustomRowContentRenderer`. A custom component must handle all of these correctly or risk breaking row focus, drag-and-drop, height virtualization, and drop indicator rendering. This is why the custom component path is strongly discouraged. Use `ROW_VARIANTS` string values for all standard scenarios. If no available variant satisfies the requirement, contact the Dimsum team through your organization's established channel.
233
+ However, DataTable renders the component as `<Component {...props} />` with five props only: `row`, `itemIndex`, `isDragOverlay`, `focusedRowId` and `drilldownRowId` (the `RowVariantProps` type of the `DSDataTableT` namespace). It does not pass `draggableProps`, `minHeight`, `height`, `dropIndicatorPosition`, `isDropValid` or `CustomRowContentRenderer` to the variant. The custom component owns the row's rendering: its cells, focus handling from `focusedRowId`, and any drag-and-drop or drop-indicator behaviour. This is why the custom component path is strongly discouraged. Use `ROW_VARIANTS` string values for all standard scenarios. If no available variant satisfies the requirement, contact the Dimsum team through your organization's established channel.
222
234
 
223
235
  Source: https://dimsum.mortgagetech.ice.com/iframe.html?id=components-datatable-advanced--group-by-column
224
236
 
@@ -239,7 +251,7 @@ Correct:
239
251
  const groupedData = groupBy(rows, 'position');
240
252
  ```
241
253
 
242
- `groupBy` generates a stable `uid` for each group object via a 16-character random ID. Manually constructing these objects risks producing malformed group data (wrong uid, missing subRows shape) that breaks row identity tracking inside DataTable.
254
+ `groupBy` gives each group object a random 16-character `uid` on every call, so the uids change whenever `groupBy` is re-run. Memoize the result, and do not expect `expandedRows` keys for groups to carry over to a re-grouped array. Manually constructing these objects risks producing malformed group data (wrong uid, missing subRows shape) that breaks row identity tracking inside DataTable.
243
255
 
244
256
  ---
245
257
 
@@ -247,11 +259,11 @@ const groupedData = groupBy(rows, 'position');
247
259
 
248
260
  Every non-primitive prop passed to DataTable must be a stable reference. For row variants and grouping, the props that require memoization are:
249
261
 
250
- | Prop | Type | Memoization |
251
- | ------------------------- | ------------------ | ------------------------------------------------- |
252
- | `getRowVariant` | callback | `useCallback` |
253
- | `groupedRowsRenderHeader` | callback or string | `useCallback` if function; stable const if string |
254
- | `disabledRows` | object | `useMemo` if constructed inline |
262
+ | Prop | Type | Memoization |
263
+ | ------------------------- | -------- | ------------------------------- |
264
+ | `getRowVariant` | callback | `useCallback` |
265
+ | `groupedRowsRenderHeader` | callback | `useCallback` |
266
+ | `disabledRows` | object | `useMemo` if constructed inline |
255
267
 
256
268
  Non-stable references cause DataTable to re-render on every parent render cycle regardless of whether row variant state actually changed.
257
269
 
@@ -9,7 +9,7 @@ description: >
9
9
  select and deselect gestures; newSelection covers all in-memory rows.
10
10
  type: core
11
11
  library: ds-data-table
12
- library_version: '3.60.0'
12
+ library_version: '3.80.0'
13
13
  requires:
14
14
  - ds-data-table-setup
15
15
  sources:
@@ -29,8 +29,8 @@ const columns = [
29
29
  ];
30
30
 
31
31
  // selection: Record<string | number, boolean | 'mixed'>
32
- // 'mixed' is the indeterminate checkbox state — set by DataTable when some but not all
33
- // rows on the current page are selected. Consumers read it as "partially selected".
32
+ // Values are true (selected) or false (not selected). The type also allows 'mixed', but DataTable never
33
+ // writes it: the header checkbox's indeterminate state is derived internally from the displayed rows.
34
34
  // Lives in the project state manager, e.g for Redux:
35
35
  const { selection } = useSelector(selectTableState);
36
36
  const dispatch = useDispatch();
@@ -105,8 +105,8 @@ If after that review the product explicitly confirms they want to continue, the
105
105
  // Only after explicit product sign-off and a11y SME review.
106
106
  // noSelectionColumn + selection + onSelectionChange is sufficient.
107
107
  // Row clicks already invoke onSelectionChange internally — onRowClick is NOT required
108
- // and must not be used to duplicate selection logic (it fires before onSelectionChange
109
- // and would be overwritten by the internal handler).
108
+ // and must not be used to duplicate selection logic (it fires before onSelectionChange,
109
+ // and the internal handler calls onSelectionChange for the same click).
110
110
  <DataTable
111
111
  columns={columns}
112
112
  data={rows}
@@ -120,13 +120,13 @@ If after that review the product explicitly confirms they want to continue, the
120
120
 
121
121
  ### Customizing the selection column
122
122
 
123
- When you need to override the selection column's `Header`, `Cell`, or visual styling, spread the exported addon object and replace what you need. This is the only case where the column exports are used directly.
123
+ When you need to override the selection column's `Header`, `Cell`, or visual styling, spread the exported addon object and replace what you need. This is the only case where the column exports are used directly. For multi-select, `Header` is the select-all checkbox: replacing it removes select-all and leaves its semantics to you.
124
124
 
125
125
  **Before customizing, understand what you are taking on.** The out-of-the-box selection column is built and tested as a unit — a11y attributes, keyboard interaction, indeterminate state, disabled row handling, shift-range selection, and screen reader announcements are all wired together internally. Overriding `Header` or `Cell` moves those responsibilities to the consumer. Dimsum no longer owns or guarantees the correctness of what you replace. If you override `Cell`, you own the checkbox implementation, its aria attributes, its disabled state, and its keyboard behavior. If you override `Header`, you own the select-all semantics and its accessible label. Test the customized column against your a11y requirements explicitly — do not assume the parts you did not touch remain correct in combination with the parts you did.
126
126
 
127
127
  #### multi selection
128
128
 
129
- ```jsx
129
+ ```tsx
130
130
  import { DataTable, multiSelectColumn } from '@elliemae/ds-data-table';
131
131
 
132
132
  // Spread multiSelectColumn and override only what differs.
@@ -134,8 +134,7 @@ import { DataTable, multiSelectColumn } from '@elliemae/ds-data-table';
134
134
  // sees it already in the array and skips auto-injection of a second one.
135
135
  const CustomSelectColumn = {
136
136
  ...multiSelectColumn,
137
- Header: () => <ScreenReaderOnly>Select row</ScreenReaderOnly>,
138
- cellStyle: { position: 'sticky', left: 0, background: 'white', zIndex: 2 },
137
+ cellStyle: { position: 'sticky', left: 0, background: 'white', zIndex: 2 } as const,
139
138
  };
140
139
 
141
140
  const columns = [CustomSelectColumn, { Header: 'Name', accessor: 'name' }];
@@ -157,6 +156,7 @@ For single-select customization, you must also set `selectSingle={true}`. Withou
157
156
 
158
157
  ```jsx
159
158
  import { DataTable, singleSelectColumn } from '@elliemae/ds-data-table';
159
+ import { ScreenReaderOnly } from '@elliemae/ds-accessibility';
160
160
 
161
161
  const CustomSingleSelectColumn = {
162
162
  ...singleSelectColumn,
@@ -181,17 +181,17 @@ const columns = [CustomSingleSelectColumn, { Header: 'Name', accessor: 'name' }]
181
181
 
182
182
  When the header checkbox is clicked, `onSelectionChange` is called with:
183
183
 
184
- - `newSelection` — a `Record<uid, boolean>` built from every row in the `data` prop (all rows and sub-rows recursively). DataTable has no knowledge of records outside what was passed to `data` — it only knows about what is currently displayed.
184
+ - `newSelection` — a `Record<uid, boolean>` built from every row in the `data` prop (all rows and sub-rows recursively). It covers the rows passed to `data`, not only the rows currently displayed (see the note below).
185
185
  - `selectedControl === 'All'` — the literal string `'All'`, signaling the header checkbox triggered the change (not a specific row uid). This fires for **both** select-all and deselect-all gestures — the string does not indicate direction.
186
- - Direction is determined by `newSelection`: populated map = selecting all, empty `{}` = deselecting all. There is no `false`-valued map for deselect.
186
+ - An empty `{}` means deselect. A select-all map holds `true` for enabled rows and `false` for disabled rows; if every row is disabled it holds only `false` values, so detect select-all by the map being non-empty, not by a `true` value.
187
187
 
188
- The correct implementation scopes selection to what is currently displayed. DataTable has no knowledge of records beyond what was passed to `data` — and that boundary is intentional.
188
+ DataTable has no knowledge of records beyond what was passed to `data`, and its select-all acts on exactly that set. With client-side pagination (full data in memory) that set spans every page; with AJAX pagination `data` holds only the current page, so the set is the current page.
189
189
 
190
190
  **Cross-page selection requires an external counter.** The DataTable header checkbox computes its checked/mixed/unchecked state from the currently displayed rows only. It cannot communicate "some other page has selections." When users need to accumulate selections across pages, the application must provide a visible counter contiguous to the table — above it, below it, or alongside it — that always reflects the true total. The header checkbox is not that place. The external counter is the authoritative state indicator.
191
191
 
192
- This is the Dimsum recommendation, consistent with established industry practice. Other industry relevant design system like PatternFly documents the same pattern: _"This text always reflects the total number of items selected. If pagination is in use, it will reflect the items selected across all pages."_ — [patternfly.org/patterns/bulk-selection](https://www.patternfly.org/patterns/bulk-selection/)
192
+ This is the Dimsum recommendation, consistent with established industry practice. Other industry relevant design system like PatternFly documents the same pattern: _"Text label that reflects the total number of items selected. If pagination is in use, it will reflect the number of items selected across all pages."_ — [patternfly.org/patterns/bulk-selection](https://www.patternfly.org/patterns/bulk-selection/)
193
193
 
194
- **Critical implementation detail — "select all" does not merge:** when the header checkbox fires, `newSelection` is built from scratch starting at `{}`. It contains only the UIDs of the currently displayed rows. Individual row toggles spread the existing `selection` (the row handler does `{ ...selection, [uid]: newState }`), but the header checkbox does not. Dispatching `newSelection` directly on "select all" will erase previous pages' selections.
194
+ **Critical implementation detail — "select all" does not merge:** when the header checkbox fires, `newSelection` is built from scratch starting at `{}`. It contains the UIDs of every row in `data`, not only the displayed rows; with AJAX pagination `data` is the current page, so only that page's UIDs are included. Individual row toggles spread the existing `selection` (the row handler does `{ ...selection, [uid]: newState }`), but the header checkbox does not. Dispatching `newSelection` directly on "select all" will erase previous pages' selections.
195
195
 
196
196
  ```jsx
197
197
  const handleSelectionChange = useCallback(
@@ -215,16 +215,14 @@ const handleSelectionChange = useCallback(
215
215
  dispatch(setSelection(newSelection));
216
216
  }
217
217
  },
218
- [dispatch, selection, data, uniqueRowAccessor],
218
+ [dispatch, selection, pagedData, uniqueRowAccessor],
219
219
  );
220
220
 
221
221
  // External "Clear selection" — the only affordance for resetting all pages at once
222
222
  const handleClearSelection = useCallback(() => dispatch(setSelection({})), [dispatch]);
223
223
  ```
224
224
 
225
- The deselect-all from the header is scoped to the current page because the header checkbox's affordance is bounded to what the user can see. Clearing the entire selection across all pages belongs to the external "Clear selection" action — not to the header.
226
-
227
- Source: https://dimsum.mortgagetech.ice.com/iframe.html?id=components-datatable-features-row--select-multiple-paginated-cross-page
225
+ The deselect-all from the header is scoped to the current page because the header checkbox's affordance is bounded to what the user can see. DataTable itself reports `{}`, which replaces the whole selection if dispatched as is. Clearing the entire selection across all pages belongs to the external "Clear selection" action — not to the header.
228
226
 
229
227
  ---
230
228
 
@@ -234,15 +232,15 @@ This is an architectural signal that a dataset-level concern has been routed int
234
232
 
235
233
  **Why this is the wrong layer:**
236
234
 
237
- A table header checkbox is visually and conceptually bounded to what the user can see. When a user interacts with it, their mental model is "I am selecting these rows in front of me." Silently expanding that scope to records on other pages — records the user has never seen, never reviewed, and cannot verify — breaks the implicit contract of the affordance without any signal that the scope changed.
235
+ A table header checkbox is visually and conceptually bounded to what the user can see. When a user interacts with it, their mental model is "I am selecting these rows in front of me." Its select-all acts on every row in `data`, which with client-side pagination already includes rows on other pages. Silently expanding that scope to records the user has never seen, never reviewed, and cannot verify breaks the implicit contract of the affordance without any signal that the scope changed.
238
236
 
239
- This is not theoretical. In 2022, HTTPie accidentally triggered a cascade-deletion of 54,000 GitHub stars through a single mis-click, compounded by a confirmation dialog that described the consequence in abstract terms ("potentially destructive action") rather than surfacing the actual magnitude. The dialog looked identical for an empty repository and one with a decade of community history. The lesson from that incident: **when the scope of a destructive operation is invisible to the user at the moment of action, the confirmation step is theater** — the user is on auto-pilot and nothing interrupts it. ([HTTPie: How we lost 54k GitHub stars](https://httpie.io/blog/stardust))
237
+ This is not theoretical. HTTPie made its main repository private by mistake (the author believed he was working on an empty repo), and GitHub permanently deleted its stars and watchers, about 54,000 stargazers and roughly 1,000 watchers, within roughly half an hour. The confirmation dialog for the visibility change warned of a "potentially destructive action" and did not show the magnitude; the author states it looked the same for a repository with no stars and one with a decade of community history. The lesson from that incident: **when the scope of a destructive operation is invisible to the user at the moment of action, the confirmation step is theater** — the user is on auto-pilot and nothing interrupts it. ([HTTPie: How we lost 54k GitHub stars](https://httpie.io/blog/stardust))
240
238
 
241
239
  For operations like mass reassignment, bulk deletion, or full-dataset export, the same invisibility is the same risk. The user thinks they selected the rows on screen. The system applies the action to 14,000 records they never reviewed. There is no safe version of this pattern without explicit, scoped, out-of-table UI.
242
240
 
243
241
  **The argument to bring to the stakeholder:**
244
242
 
245
- > "The table header checkbox is scoped to what is currently displayed. This is not a limitation — it is the correct behavior for a component whose job is to let users work with what they can see and verify. An action that applies to the full dataset regardless of what is displayed is a different category of concern entirely. It belongs outside the table, named explicitly, with a confirmation step that shows the user the actual count of records they are about to affect. If we wire it through the checkbox, we will eventually ship a mass operation that a user triggers without understanding its true scope. By the time that happens, the damage is already done and there may be no way to undo it."
243
+ > "The table header checkbox acts only on the rows the table has been given. This is not a limitation — it is the correct behavior for a component whose job is to let users work with what they can see and verify. An action that applies to the full dataset regardless of what is displayed is a different category of concern entirely. It belongs outside the table, named explicitly, with a confirmation step that shows the user the actual count of records they are about to affect. If we wire it through the checkbox, we will eventually ship a mass operation that a user triggers without understanding its true scope. By the time that happens, the damage is already done and there may be no way to undo it."
246
244
 
247
245
  **The correct pattern — dataset-level actions belong outside the table:**
248
246
 
@@ -271,7 +269,7 @@ const LoanQueuePage = () => {
271
269
  {/* Dataset-level CTA — scoped explicitly, named, lives outside the table */}
272
270
  <Button onClick={handleBulkReassign}>Reassign all {totalRecords.toLocaleString()} loans</Button>
273
271
 
274
- {/* Table selection is scoped to currently displayed rows only */}
272
+ {/* The header checkbox shows the state of the displayed page; select-all acts on every row in `data` */}
275
273
  <DataTable
276
274
  columns={columns}
277
275
  data={pagedData}
@@ -319,7 +317,7 @@ Correct:
319
317
  />
320
318
  ```
321
319
 
322
- Without `uniqueRowAccessor`, the `selection` record cannot be reliably mapped to rows — selections visually appear to work but apply to wrong rows or break on data update.
320
+ Without `uniqueRowAccessor`, each row's uid falls back to its position in `data`, so the `selection` record is keyed by position. No error is thrown. If `data` is reordered, filtered or replaced, the selected keys point at different rows.
323
321
 
324
322
  Source: `@elliemae/ds-data-table:dist/types/react-desc-prop-types.d.ts`
325
323
 
@@ -347,7 +345,7 @@ Correct:
347
345
  />
348
346
  ```
349
347
 
350
- `selection` and `onSelectionChange` must both be provided. Selections appear to work visually but state is not captured or persisted without the handler.
348
+ `selection` and `onSelectionChange` must both be provided. Selection is controlled: without `onSelectionChange` the table cannot update `selection`, so checkboxes and radios do not change when clicked.
351
349
 
352
350
  Source: https://dimsum.mortgagetech.ice.com/iframe.html?id=components-datatable-features-row--select-multiple
353
351
 
@@ -375,7 +373,7 @@ const columns = [
375
373
  ];
376
374
  ```
377
375
 
378
- The auto-injected column always prepends. A manually placed selection column in a trailing position is visually inconsistent and breaks the expected tab order through the row.
376
+ The auto-injected column always prepends. A manually placed selection column stays where you put it (DataTable does not move a column it already finds in `columns`). In a trailing position it is visually inconsistent and breaks the expected tab order through the row.
379
377
 
380
378
  Source: https://dimsum.mortgagetech.ice.com/iframe.html?id=components-datatable-features-row--select-multiple
381
379
 
@@ -1,14 +1,15 @@
1
1
  ---
2
2
  name: ds-data-table-setup
3
3
  description: >
4
- First-time setup of @elliemae/ds-data-table. Required props: columns, data, height (px only —
5
- non-px silently defeats virtualization). uniqueRowAccessor for any stateful row
6
- interaction. dsDataTableTableWrapper aria-label for a11y. domIdAffix when multiple DataTable
4
+ First-time setup of @elliemae/ds-data-table. Required props: columns, data. height defaults to '100%', and
5
+ for large data it must be bounded (a number, a px string, a viewport unit, or a percentage of a parent with a
6
+ definite height), otherwise the table renders nearly every row. uniqueRowAccessor for any stateful row
7
+ interaction. dsDatatableTableWrapper aria-label for a11y. domIdAffix when multiple DataTable
7
8
  instances coexist on a page. State management: identify project's Redux/RTK/Zustand/Jotai
8
9
  system before wiring — never useState for DataTable state.
9
10
  type: core
10
11
  library: ds-data-table
11
- library_version: '3.60.0'
12
+ library_version: '3.80.0'
12
13
  sources:
13
14
  - '@elliemae/ds-data-table:dist/types/react-desc-prop-types.d.ts'
14
15
  ---
@@ -29,7 +30,7 @@ const columns = [
29
30
  data={rows}
30
31
  height={500}
31
32
  uniqueRowAccessor="id"
32
- dsDataTableTableWrapper={{ 'aria-label': 'Employees table' }}
33
+ dsDatatableTableWrapper={{ 'aria-label': 'Employees table' }}
33
34
  />;
34
35
  ```
35
36
 
@@ -94,7 +95,7 @@ Required for selection, drag & drop, and expandable rows.
94
95
 
95
96
  ```jsx
96
97
  // domIdAffix is used to construct stable, predictable DOM IDs for aria relationships:
97
- // aria-controls on the header checkbox, aria-labelledby on editable cells, inputID/id
98
+ // aria-controls on the header checkbox, the id of a hidden editable-cell instruction span, inputID/id
98
99
  // pairs on filter inputs. Without an explicit value, IDs are random per mount —
99
100
  // external aria references will break on remount.
100
101
  <DataTable columns={loanCols} data={loans} height={400} domIdAffix="loans-table" />
@@ -130,12 +131,12 @@ Source: `@elliemae/ds-data-table:dist/types/react-desc-prop-types.d.ts`
130
131
 
131
132
  ---
132
133
 
133
- ### HIGH Using height in % or vh silently defeats virtualization
134
+ ### HIGH Table without a bounded height renders nearly every row
134
135
 
135
- Wrong:
136
+ Wrong (the default `height="100%"` inside a parent with no definite height, or `height="auto"`):
136
137
 
137
138
  ```jsx
138
- <DataTable columns={columns} data={rows} height="100%" />
139
+ <DataTable columns={columns} data={rows} />
139
140
  ```
140
141
 
141
142
  Correct:
@@ -144,8 +145,25 @@ Correct:
144
145
  <DataTable columns={columns} data={rows} height={500} />
145
146
  ```
146
147
 
147
- DataTable uses a virtual scroll container that measures its own rendered height to calculate which rows to render. When `height` is a percentage and the parent has no defined height, that container resolves to 0px. The virtualizer measures 0px, treats the entire dataset as visible, and renders all rows to the DOM simultaneously. The internal scrollbar disappears — the page scroll takes over instead. With large datasets this silently causes serious performance degradation. Always pass a numeric pixel value — it is self-contained and does not depend on parent container layout.
148
+ The table virtualizes (renders only the visible rows) only when its height is bounded: a number, a px string, a viewport unit such as `'60vh'`, or a percentage of a parent that has a definite height. With the default `'100%'` in a parent without a definite height, or with `height="auto"`, the table grows with its content: it has no internal scroll and renders nearly every row. For large data always give the table a bounded height; a number is the simplest.
149
+
150
+ ---
151
+
152
+ ### HIGH isSkeleton with a percentage height renders the wrong number of skeleton rows
153
+
154
+ Wrong:
155
+
156
+ ```jsx
157
+ <DataTable columns={columns} data={[]} height="100%" isSkeleton={isLoading} />
158
+ ```
159
+
160
+ Correct:
161
+
162
+ ```jsx
163
+ <DataTable columns={columns} data={[]} height={500} isSkeleton={isLoading} />
164
+ ```
148
165
 
166
+ `height` defaults to `'100%'`. A percentage resolves against the parent, so it is bounded only when the parent has a definite height (see the bounded-height rule above). The skeleton row count is the exception: it is computed from the leading number of `height` (`floor((parseInt(height) - 25) / 52)`), so `'100%'` is read as 100px and renders a single placeholder row. Pass a pixel number when using `isSkeleton`.
149
167
  ---
150
168
 
151
169
  ### HIGH Managing DataTable state with local useState instead of the project state manager
@@ -185,13 +203,13 @@ Correct:
185
203
  <DataTable columns={borrowerCols} data={borrowers} height={400} domIdAffix="borrowers-table" />
186
204
  ```
187
205
 
188
- `domIdAffix` is used internally to construct DOM IDs for aria relationships — `aria-controls` on the header checkbox (pointing to individual row checkboxes), `aria-labelledby`/`id` pairs on editable cells, and `inputID`/`id` pairs on filter inputs. Without an explicit value the suffix is a random `uid(8)` per mount — IDs are unpredictable and any external aria reference built against them will break when the component remounts.
206
+ `domIdAffix` is used internally to construct DOM IDs for aria relationships — `aria-controls` on the header checkbox (pointing to individual row checkboxes), the `id` of the hidden instruction span in editable cells (`editable-cell-<cellId>-<domIdAffix>`), which names the editable group through `aria-labelledby`, and `inputID`/`id` pairs on filter inputs. Without an explicit value the suffix is a random `uid(8)` per mount — IDs are unpredictable and any external aria reference built against them will break when the component remounts.
189
207
 
190
208
  Source: https://dimsum.mortgagetech.ice.com/iframe.html?id=components-datatable-advanced--prefixed-ids-for-multiple-tables-in-same-pages
191
209
 
192
210
  ---
193
211
 
194
- ### HIGH Missing dsDataTableTableWrapper aria-label
212
+ ### HIGH Missing dsDatatableTableWrapper aria-label
195
213
 
196
214
  Wrong:
197
215
 
@@ -206,7 +224,7 @@ Correct:
206
224
  columns={columns}
207
225
  data={rows}
208
226
  height={500}
209
- dsDataTableTableWrapper={{ 'aria-label': 'Loan applications table' }}
227
+ dsDatatableTableWrapper={{ 'aria-label': 'Loan applications table' }}
210
228
  />
211
229
  ```
212
230
 
@@ -7,7 +7,7 @@ description: >
7
7
  DSDataTableSlots. App side owns long-term maintenance of anything injected via slots.
8
8
  type: core
9
9
  library: ds-data-table
10
- library_version: '3.60.0'
10
+ library_version: '3.80.0'
11
11
  requires:
12
12
  - ds-data-table-setup
13
13
  sources:
@@ -19,7 +19,7 @@ sources:
19
19
 
20
20
  Slots are injection points into specific rendered DOM nodes. The `data-dimsum-slot` attribute value on each node identifies the slot — values use camelCase with the component prefix, e.g. `dsDatatableCellsContainer`. Understanding the hierarchy is required to inject props into the right element — injecting `aria-*` attributes at the wrong level produces silent accessibility failures.
21
21
 
22
- **About this map:** Verified against `@elliemae/ds-data-table@3.60.0` via probe tests. Slot names and positions are governed by the Dimsum breaking change protocol — renames and structural moves are intentional, coordinated, and documented in the official resources; they do not happen silently. The map is likely accurate for nearby versions, but not guaranteed for all time.
22
+ **About this map:** Verified against `@elliemae/ds-data-table@3.80.0` via probe tests. Slot names and positions are governed by the Dimsum breaking change protocol — renames and structural moves are intentional, coordinated, and documented in the official resources; they do not happen silently. The map is likely accurate for nearby versions, but not guaranteed for all time.
23
23
 
24
24
  **If something doesn't match the version you're integrating with:** Find a way to inspect the actual rendered HTML of the component — how you do that depends on your environment and what tools are available to you. If you cannot do it autonomously, ask the human in the loop to render the component with synthetic or placeholder data and share the resulting HTML structure. **Important:** the human must not copy HTML from a production environment or any page containing real user data, real loan information, or any personally identifiable information — the goal is slot position verification, which requires only the DOM structure, not real content. Placeholder text and fake IDs are sufficient and correct for this purpose.
25
25
 
@@ -28,8 +28,12 @@ Each entry below shows: `SLOT_KEY (data-dimsum-slot="value") · tag · notes`.
28
28
  ```
29
29
  ROOT (dsDatatableRoot) · div
30
30
  ├── FILTER_BAR_WRAPPER (dsDatatableFilterBarWrapper) · div ← only when withFilterBar=true
31
- │ └── FILTER_BAR_MENU_BUTTON ← static, no interaction needed
32
- │ wraps DSMenuButton → DOM shows dsButtonRoot (no dsDatatableFilterBarMenuButton attr)
31
+ │ └── (default menu, when no filterBarAddonRenderer) dsMenubuttonRoot · div[data-testid="ds-menubutton-root"]
32
+ │ ├── FILTER_BAR_MENU_BUTTON: the DSMenuButton trigger · button[data-testid="filter-bar-ddmenu-button"]
33
+ │ │ data-dimsum-slot="dsButtonRoot", data-dimsum-parent-slot="dsOpinionatedbuttonRoot", aria-haspopup="menu",
34
+ │ │ aria-expanded. Props injected through the FILTER_BAR_MENU_BUTTON slot prop land on this trigger button (see the note below the nested-slots table).
35
+ │ └── flyout menu, after the trigger is clicked (portal, dsFloatingwrapperContent):
36
+ │ dsFlyoutmenuRoot > dsFlyoutmenuListWrapper[role="menu"] > dsMenuitemMenuItemWrapper[role="menuitem"]
33
37
  └── CONTENT_WRAPPER (dsDatatableContentWrapper) · div
34
38
  ├── TABLE_WRAPPER (dsDatatableTableWrapper) · div[role="table"]
35
39
  │ └── VIRTUAL_LIST_WRAPPER (dsDatatableVirtualListWrapper) · div[role="rowgroup" tabIndex="-1"]
@@ -40,6 +44,8 @@ ROOT (dsDatatableRoot) · div
40
44
  │ │ └── HEAD_TH (dsDatatableHeadTh) · div[role="columnheader"]
41
45
  │ │ ║ prop: dsDatatableHeadTh
42
46
  │ │ ║ callback: ({ columnId, firstFocuseableColumnHeaderId }) => props
47
+ │ │ ├── GLOBAL_CHECKBOX_CONTAINER (dsDatatableGlobalCheckboxContainer) · span
48
+ │ │ │ present in: the multi-select column header cell only (select-all checkbox)
43
49
  │ │ ├── HEAD_RIGHT_ICONS_WRAPPER (dsDatatableHeadRightIconsWrapper) · div
44
50
  │ │ │ present when: canSort=true OR column.filter is set
45
51
  │ │ │ ├── sort button (dsButtonRoot — no DataTable slot attr)
@@ -68,10 +74,10 @@ ROOT (dsDatatableRoot) · div
68
74
  │ ├── CENTER_CONTENT_FLEX_WRAPPER (dsDatatableCenterContentFlexWrapper) · div[role="row"]
69
75
  │ │ present when: data=[] (sibling of HEAD_WRAPPER)
70
76
  │ │ └── EMPTY_STATE_WRAPPER (dsDatatableEmptyStateWrapper) · div[role="cell"]
71
- │ │ ├── warning icon (dsIconRoot — no DataTable slot attr)
77
+ │ │ ├── WARNING_ICON (data-dimsum-slot="dsIconRoot", data-dimsum-parent-slot="dsDatatableWarningIcon") · span
72
78
  │ │ ├── EMPTY_PRIMARY_MESSAGE (dsDatatableEmptyPrimaryMessage) · p
73
79
  │ │ ├── EMPTY_SECONDARY_MESSAGE (dsDatatableEmptySecondaryMessage) · p
74
- │ │ └── CTA button (dsButtonRoot — no DataTable slot attr)
80
+ │ │ └── EMPTY_BUTTON (data-dimsum-slot="dsButtonRoot", data-dimsum-parent-slot="dsDatatableEmptyButton") · button
75
81
  │ │ present when: noResultsButtonLabel + onNoResultsButtonClick provided
76
82
  │ │
77
83
  │ └── ROW (dsDatatableRow) · div[position:absolute] (one per visible row)
@@ -92,7 +98,7 @@ ROOT (dsDatatableRoot) · div
92
98
  │ │ ├── EDITABLE_CONTAINER (dsDatatableEditableContainer) · div[role="group"]
93
99
  │ │ │ present when: column.editable is set
94
100
  │ │ │ ├── CELL_CONTENT (dsDatatableCellContent) · div
95
- │ │ │ ├── pencil icon (dsIconRoot — no DataTable slot attr)
101
+ │ │ │ ├── PENCIL_ICON (data-dimsum-slot="dsIconRoot", data-dimsum-parent-slot="dsDatatablePencilIcon") · span
96
102
  │ │ │ └── TEXT_EDITABLE_CELL_INPUT (dsDatatableTextEditableCellInput) · input
97
103
  │ │ │ present after user clicks to enter edit mode (autoFocus on mount)
98
104
  │ │ └── CELL_CONTENT (dsDatatableCellContent) · div (standard columns)
@@ -109,7 +115,7 @@ ROOT (dsDatatableRoot) · div
109
115
  │ └── TOOLBAR_WRAPPER (dsDatatableToolbarWrapper) · div
110
116
  │ ├── TOOLBAR_BUTTONS_WRAPPER (dsDatatableToolbarButtonsWrapper) · div
111
117
  │ │ present after user opens the toolbar
112
- │ └── trigger button (dsButtonRoot — no DataTable slot attr)
118
+ │ └── TOOLBAR_BUTTON (data-dimsum-slot="dsButtonRoot", data-dimsum-parent-slot="dsDatatableToolbarButton") · button
113
119
  │ data-testid="data-table-toolbar-trigger"
114
120
  │
115
121
  └── PAGINATION_WRAPPER (dsDatatablePaginationWrapper) · div
@@ -118,30 +124,54 @@ ROOT (dsDatatableRoot) · div
118
124
 
119
125
  ── FILTER_POPOVER portal ← rendered at document body level, not inside DataTable DOM
120
126
  present after user clicks a column's FILTER_POPOVER_BUTTON trigger
121
- DOM shows: dsFloatingwrapperRoot[role="dialog"] · (root)
127
+ DOM shows: dsFloatingwrapperRoot[role="dialog"] · (root), data-dimsum-parent-slot="dsDatatableFilterPopover"
122
128
  └── dsFloatingwrapperContent
123
129
  └── FILTER_POPOVER_CONTENT (dsDatatableFilterPopoverContent) · div
124
130
  ├── FREE_TEXT_SEARCH_WRAPPER (dsDatatableFreeTextSearchWrapper) · div
125
131
  │ └── FREE_TEXT_SEARCH_FILTER (dsDatatableFreeTextSearchFilter)
126
- │ prop: dsDatatableFreeTextSearchFilter · wraps DSInputText
127
- │ data-dimsum-slot="dsDatatableFreeTextSearchFilter" and data-testid="data-table-filter-free-text-search"
128
- │ land on the inner input element
129
- └── FILTER_POPOVER_FOOTER — no dsDatatableFilterPopoverFooter attr in DOM
130
- └── submit/reset buttons (dsButtonRoot)
132
+ │ prop: dsDatatableFreeTextSearchFilter · wraps DSInputText; only the inner <input> is visible in the DOM:
133
+ │ data-testid="data-table-filter-free-text-search", data-dimsum-slot="dsInputtextInput" and
134
+ │ data-dimsum-parent-slot="dsDatatableFreeTextSearchFilter" (same for the V1 and V2 filter types)
135
+ └── FILTER_POPOVER_FOOTER (data-dimsum-slot="dsDialogFooter", data-dimsum-parent-slot="dsDatatableFilterPopoverFooter") · div
136
+ └── submit/reset buttons (dsButtonRoot) — V2 filter types only (the V1 popover has no footer)
131
137
  ```
132
138
 
133
- **Slots that are injectable but do not appear as `dsDatatable*` in the DOM:**
139
+ **Slots on wrapped Dimsum components — nested slots:**
134
140
 
135
- These slot props work for injection, but when you inspect the DOM you will not see a `dsDatatableXxx` attribute. The table below shows what you will see instead. This matters if you are debugging injection or writing DOM-based test assertions.
141
+ When the DataTable gives a slot to a Dimsum component (an input, a button, an icon, a dialog footer, a floating wrapper), the element in the DOM carries the wrapped component's own `data-dimsum-slot`, and the DataTable slot name is in `data-dimsum-parent-slot`. This is how nested slots work: you inject through the DataTable slot prop as usual (for example `dsDatatableFilterPopover={{ ... }}`), and when you inspect the DOM or write DOM-based test assertions you look the element up by `data-dimsum-parent-slot`.
136
142
 
137
- | Slot key | What the DOM shows | Where to find it |
138
- | ------------------------ | ---------------------------------------------------- | ------------------------------------------------------------------------------- |
139
- | `PENCIL_ICON` | `dsIconRoot` + `dsIconSvg` | Inside `EDITABLE_CONTAINER`; present in DOM but CSS-hidden until hover/focus |
140
- | `TOOLBAR_BUTTON` | `dsButtonRoot` | Inside `TOOLBAR_BUTTONS_WRAPPER`, visible after toolbar is opened |
141
- | `EMPTY_BUTTON` | `dsButtonRoot` | Inside `EMPTY_STATE_WRAPPER`, the CTA button |
142
- | `FILTER_POPOVER` | `dsFloatingwrapperRoot` + `dsFloatingwrapperContent` | Portal at document body — `role="dialog"`, not inside the DataTable DOM subtree |
143
- | `FILTER_POPOVER_FOOTER` | `dsDialogFooter` | Inside `FILTER_POPOVER_CONTENT` |
144
- | `FILTER_BAR_MENU_BUTTON` | `dsButtonRoot` | Inside `FILTER_BAR_WRAPPER`, always visible when `withFilterBar=true` |
143
+ | Slot key | Element in the DOM (`data-dimsum-slot`) | `data-dimsum-parent-slot` | Where to find it |
144
+ | ------------------------- | --------------------------------------------------------------------- | --------------------------------- | ---------------------------------------------------------------------------------------------------- |
145
+ | `RESIZER` | `dsInputtextInput` | `dsDatatableResizer` | The `<input type="range">` inside the column header (see the tree) |
146
+ | `FREE_TEXT_SEARCH_FILTER` | `dsInputtextInput` | `dsDatatableFreeTextSearchFilter` | The input inside the filter popover (V1 and V2 filter types) |
147
+ | `FILTER_POPOVER` | `dsFloatingwrapperRoot` (its `dsFloatingwrapperContent` is inside it) | `dsDatatableFilterPopover` | Portal at document body — `role="dialog"`, not inside the DataTable DOM subtree |
148
+ | `FILTER_POPOVER_FOOTER` | `dsDialogFooter` | `dsDatatableFilterPopoverFooter` | Inside `FILTER_POPOVER_CONTENT` (V2 filter types only) |
149
+ | `WARNING_ICON` | `dsIconRoot` | `dsDatatableWarningIcon` | The icon of the empty state, inside `EMPTY_STATE_WRAPPER` |
150
+ | `EMPTY_BUTTON` | `dsButtonRoot` | `dsDatatableEmptyButton` | The empty state's call-to-action button (needs `noResultsButtonLabel` and `onNoResultsButtonClick`) |
151
+ | `TOOLBAR_BUTTON` | `dsButtonRoot` | `dsDatatableToolbarButton` | The row-actions trigger button (`data-testid="data-table-toolbar-trigger"`) inside `TOOLBAR_WRAPPER` |
152
+ | `PENCIL_ICON` | `dsIconRoot` | `dsDatatablePencilIcon` | Inside `EDITABLE_CONTAINER`; in the DOM but CSS-hidden until hover/focus |
153
+
154
+ **`FILTER_BAR_MENU_BUTTON`:** props injected through the `dsDatatableFilterBarMenuButton` slot prop land on the trigger button of the default filter bar menu and of the menu rendered by `FilterBarDropdownMenu`. That button's `data-dimsum-parent-slot` is the menu button's own (`dsOpinionatedbuttonRoot`), so the DataTable slot name is not in the DOM for this one; find the trigger with `data-testid="filter-bar-ddmenu-button"`.
155
+
156
+ **`FOCUS_WITHIN`:** a `div` that wraps `EXPAND_CELL_CONTAINER` (header and rows) and `DRAG_AND_DROP_GRIPPER` (header and rows): the element that draws the focus border when something inside it has the focus. In the rows its parent is `CELL_CONTENT`. It is not in the tree above.
157
+
158
+ **`EMPTY_HEADER`:** it is not in the DOM at rest. It renders only inside the drag overlay of a column group header (the thin line under the group title) while that group is being dragged, so props injected through `dsDatatableEmptyHeader` can only be observed during that drag.
159
+
160
+ **Arguments of the function form:** slots that repeat per row, cell or column pass that instance to a function-form slot prop as an object with named keys, for example `dsDatatableFullsizeGrid={({ row }) => ({ ... })}`. The single-instance slots (the root, the wrappers around the table, the loader, the filter bar, the empty state) receive no arguments. The keys are ours; the row and the cell inside them are your data and the table's internals, whose shape the DataTable does not guarantee.
161
+
162
+ | Slot keys | Argument |
163
+ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
164
+ | `FULLSIZE_GRID`, `GROUP_HEADER_CONTAINER`, `GROUP_HEADER_TITLE`, `ACTION_CELL`, `SINGLE_CELL_CONTAINER`, `TOOLBAR_POSITION`, `TOOLBAR_WRAPPER`, `TOOLBAR_BUTTONS_WRAPPER`, `TOOLBAR_BUTTON` | `{ row }` |
165
+ | `PENCIL_ICON` | `{ cell }` |
166
+ | `HEAD_TH`, `HEAD_RIGHT_ICONS_WRAPPER` | `{ columnId, firstFocuseableColumnHeaderId }` |
167
+ | `HEADER_CELL_WRAPPER`, `RESIZER`, `EMPTY_HEADER`, `FILTER_POPOVER`, `FILTER_POPOVER_BUTTON`, `FILTER_POPOVER_CONTENT`, `FILTER_POPOVER_FOOTER`, `FREE_TEXT_SEARCH_FILTER`, `FREE_TEXT_SEARCH_WRAPPER` | `{ columnId }` |
168
+ | `DRAG_AND_DROP_GRIPPER` | one object, `{ row?, columnId? }`: `row` for a row handle, `columnId` for a column header handle, the other key is not there |
169
+ | `EXPAND_CELL_CONTAINER` | `{ isGlobal }` (`true` for the header expand-all control) |
170
+ | `FOCUS_WITHIN` | one object, `{ row?, columnId?, firstFocuseableColumnHeaderId?, isGlobal? }`: `columnId` and `firstFocuseableColumnHeaderId` on a header drag handle, `isGlobal` on the expand carets, `row` on a row drag handle, the other keys are not there |
171
+ | `ROW`, `CELL_CONTAINER` (legacy shape) | the row itself, also on group header rows |
172
+ | `CELL`, `CELL_CONTENT`, `EDITABLE_CONTAINER`, `TEXT_EDITABLE_CELL_INPUT` (legacy shape) | the cell itself (`cell.row.original`, `cell.row.uid`, `cell.column`, `cell.id`) |
173
+
174
+ The legacy-shape slots shipped before the named-key convention, so they still receive the row or the cell directly; they will move to `{ row }` / `{ cell }` only through a deliberate, announced breaking change.
145
175
 
146
176
  **Slots only visible in interactive states (not in static render):**
147
177
 
@@ -235,7 +265,7 @@ const cellProps = useCallback((cell) => {
235
265
 
236
266
  Always wrap callbacks in `useCallback`. Inline callbacks create a new reference on every render, causing all virtualized rows to re-render unnecessarily.
237
267
 
238
- In `dsDatatableCell`, access row data via `cell.row.original` (raw data) or `cell.row.uid` (UID from `uniqueRowAccessor`). Do not use `cell.row.id` — that is react-table's internal positional index and shifts when data is reordered.
268
+ In `dsDatatableCell`, access row data via `cell.row.original` (raw data) or `cell.row.uid` (UID from `uniqueRowAccessor`). Do not use `cell.row.id` — that is the DataTable's internal position-based id and shifts when data is reordered.
239
269
 
240
270
  ## `column.cellStyle` vs `dsDatatableCell`
241
271