@multiplatform.one/table 7.7.6 → 7.10.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 (384) hide show
  1. package/dist/cjs/components/ColumnHeaderFilter/index.cjs +74 -38
  2. package/dist/cjs/components/ColumnHeaderFilter/index.native.js +97 -51
  3. package/dist/cjs/components/ColumnHeaderFilter/index.native.js.map +1 -1
  4. package/dist/cjs/components/DataTable/DataTableCardControls.cjs +0 -1
  5. package/dist/cjs/components/DataTable/DataTableCardControls.native.js +0 -1
  6. package/dist/cjs/components/DataTable/DataTableCardControls.native.js.map +1 -1
  7. package/dist/cjs/components/DataTable/DataTableMobileCards.cjs +100 -33
  8. package/dist/cjs/components/DataTable/DataTableMobileCards.native.js +139 -38
  9. package/dist/cjs/components/DataTable/DataTableMobileCards.native.js.map +1 -1
  10. package/dist/cjs/components/DataTable/DataTableRoot.cjs +33 -6
  11. package/dist/cjs/components/DataTable/DataTableRoot.native.js +29 -4
  12. package/dist/cjs/components/DataTable/DataTableRoot.native.js.map +1 -1
  13. package/dist/cjs/components/DataTable/DataTableStateContext.native.js.map +1 -1
  14. package/dist/cjs/components/DataTable/index.native.js +59 -93
  15. package/dist/cjs/components/DataTable/index.native.js.map +1 -1
  16. package/dist/cjs/components/DataTableBulkActions/index.cjs +0 -4
  17. package/dist/cjs/components/DataTableBulkActions/index.native.js +0 -4
  18. package/dist/cjs/components/DataTableBulkActions/index.native.js.map +1 -1
  19. package/dist/cjs/components/DataTableCell/index.cjs +16 -1
  20. package/dist/cjs/components/DataTableCell/index.native.js +16 -1
  21. package/dist/cjs/components/DataTableCell/index.native.js.map +1 -1
  22. package/dist/cjs/components/DataTableDateFilter/index.cjs +0 -7
  23. package/dist/cjs/components/DataTableDateFilter/index.native.js +0 -7
  24. package/dist/cjs/components/DataTableDateFilter/index.native.js.map +1 -1
  25. package/dist/cjs/components/DataTableFilterButton/index.cjs +0 -1
  26. package/dist/cjs/components/DataTableFilterButton/index.native.js +0 -1
  27. package/dist/cjs/components/DataTableFilterChips/FilterChip.cjs +2 -1
  28. package/dist/cjs/components/DataTableFilterChips/FilterChip.native.js +4 -1
  29. package/dist/cjs/components/DataTableFilterChips/FilterChip.native.js.map +1 -1
  30. package/dist/cjs/components/DataTableFilters/index.cjs +0 -1
  31. package/dist/cjs/components/DataTableFilters/index.native.js +0 -1
  32. package/dist/cjs/components/DataTableGrouping/index.cjs +0 -8
  33. package/dist/cjs/components/DataTableGrouping/index.native.js +0 -8
  34. package/dist/cjs/components/DataTableGrouping/index.native.js.map +1 -1
  35. package/dist/cjs/components/DataTablePagination/index.cjs +29 -13
  36. package/dist/cjs/components/DataTablePagination/index.native.js +30 -14
  37. package/dist/cjs/components/DataTablePagination/index.native.js.map +1 -1
  38. package/dist/cjs/components/DataTableSearch/index.cjs +0 -3
  39. package/dist/cjs/components/DataTableSearch/index.native.js +0 -3
  40. package/dist/cjs/components/DataTableSearch/index.native.js.map +1 -1
  41. package/dist/cjs/components/DataTableToolbar/index.cjs +0 -1
  42. package/dist/cjs/components/DataTableToolbar/index.native.js +0 -1
  43. package/dist/cjs/components/DataTableToolbar/index.native.js.map +1 -1
  44. package/dist/cjs/components/DataTableViewOptions/index.cjs +0 -5
  45. package/dist/cjs/components/DataTableViewOptions/index.native.js +0 -5
  46. package/dist/cjs/components/DataTableViewOptions/index.native.js.map +1 -1
  47. package/dist/cjs/components/FilterManager.cjs +0 -1
  48. package/dist/cjs/components/FilterManager.native.js +0 -1
  49. package/dist/cjs/components/FilterManager.native.js.map +1 -1
  50. package/dist/cjs/components/FilterOperatorValueEditor/index.cjs +2 -2
  51. package/dist/cjs/components/FilterOperatorValueEditor/index.native.js +2 -2
  52. package/dist/cjs/components/FilterOperatorValueEditor/index.native.js.map +1 -1
  53. package/dist/cjs/components/TableInput/index.cjs +2 -1
  54. package/dist/cjs/components/TableInput/index.native.js +4 -2
  55. package/dist/cjs/components/TableInput/index.native.js.map +1 -1
  56. package/dist/cjs/hooks/useDataTable.cjs +24 -8
  57. package/dist/cjs/hooks/useDataTable.native.js +28 -8
  58. package/dist/cjs/hooks/useDataTable.native.js.map +1 -1
  59. package/dist/cjs/index.cjs +12 -0
  60. package/dist/cjs/index.native.js +12 -0
  61. package/dist/cjs/index.native.js.map +1 -1
  62. package/dist/cjs/shared/devWarn.cjs +70 -0
  63. package/dist/cjs/shared/devWarn.native.js +84 -0
  64. package/dist/cjs/shared/devWarn.native.js.map +1 -0
  65. package/dist/cjs/utils/columnAlign.cjs +4 -1
  66. package/dist/cjs/utils/columnAlign.native.js +4 -1
  67. package/dist/cjs/utils/columnAlign.native.js.map +1 -1
  68. package/dist/cjs/utils/filterFields.cjs +5 -0
  69. package/dist/cjs/utils/filterFields.native.js +5 -0
  70. package/dist/cjs/utils/filterFields.native.js.map +1 -1
  71. package/dist/cjs/utils/filterUtils.cjs +30 -0
  72. package/dist/cjs/utils/filterUtils.native.js +50 -0
  73. package/dist/cjs/utils/filterUtils.native.js.map +1 -1
  74. package/dist/cjs/utils/money.cjs +137 -0
  75. package/dist/cjs/utils/money.native.js +165 -0
  76. package/dist/cjs/utils/money.native.js.map +1 -0
  77. package/dist/cjs/utils/rowAccumulator.cjs +48 -0
  78. package/dist/cjs/utils/rowAccumulator.native.js +51 -0
  79. package/dist/cjs/utils/rowAccumulator.native.js.map +1 -0
  80. package/dist/esm/components/ColumnHeaderFilter/index.mjs +78 -42
  81. package/dist/esm/components/ColumnHeaderFilter/index.mjs.map +1 -1
  82. package/dist/esm/components/ColumnHeaderFilter/index.native.js +101 -55
  83. package/dist/esm/components/ColumnHeaderFilter/index.native.js.map +1 -1
  84. package/dist/esm/components/DataTable/DataTableCardControls.mjs +0 -1
  85. package/dist/esm/components/DataTable/DataTableCardControls.mjs.map +1 -1
  86. package/dist/esm/components/DataTable/DataTableCardControls.native.js +0 -1
  87. package/dist/esm/components/DataTable/DataTableCardControls.native.js.map +1 -1
  88. package/dist/esm/components/DataTable/DataTableMobileCards.mjs +99 -34
  89. package/dist/esm/components/DataTable/DataTableMobileCards.mjs.map +1 -1
  90. package/dist/esm/components/DataTable/DataTableMobileCards.native.js +138 -39
  91. package/dist/esm/components/DataTable/DataTableMobileCards.native.js.map +1 -1
  92. package/dist/esm/components/DataTable/DataTableRoot.mjs +33 -6
  93. package/dist/esm/components/DataTable/DataTableRoot.mjs.map +1 -1
  94. package/dist/esm/components/DataTable/DataTableRoot.native.js +29 -4
  95. package/dist/esm/components/DataTable/DataTableRoot.native.js.map +1 -1
  96. package/dist/esm/components/DataTable/DataTableStateContext.mjs.map +1 -1
  97. package/dist/esm/components/DataTable/DataTableStateContext.native.js.map +1 -1
  98. package/dist/esm/components/DataTable/index.native.js +60 -94
  99. package/dist/esm/components/DataTable/index.native.js.map +1 -1
  100. package/dist/esm/components/DataTableBulkActions/index.mjs +0 -4
  101. package/dist/esm/components/DataTableBulkActions/index.mjs.map +1 -1
  102. package/dist/esm/components/DataTableBulkActions/index.native.js +0 -4
  103. package/dist/esm/components/DataTableBulkActions/index.native.js.map +1 -1
  104. package/dist/esm/components/DataTableCell/index.mjs +17 -2
  105. package/dist/esm/components/DataTableCell/index.mjs.map +1 -1
  106. package/dist/esm/components/DataTableCell/index.native.js +17 -2
  107. package/dist/esm/components/DataTableCell/index.native.js.map +1 -1
  108. package/dist/esm/components/DataTableDateFilter/index.mjs +0 -7
  109. package/dist/esm/components/DataTableDateFilter/index.mjs.map +1 -1
  110. package/dist/esm/components/DataTableDateFilter/index.native.js +0 -7
  111. package/dist/esm/components/DataTableDateFilter/index.native.js.map +1 -1
  112. package/dist/esm/components/DataTableFilterButton/index.mjs +0 -1
  113. package/dist/esm/components/DataTableFilterButton/index.mjs.map +1 -1
  114. package/dist/esm/components/DataTableFilterButton/index.native.js +0 -1
  115. package/dist/esm/components/DataTableFilterChips/FilterChip.mjs +3 -2
  116. package/dist/esm/components/DataTableFilterChips/FilterChip.mjs.map +1 -1
  117. package/dist/esm/components/DataTableFilterChips/FilterChip.native.js +5 -2
  118. package/dist/esm/components/DataTableFilterChips/FilterChip.native.js.map +1 -1
  119. package/dist/esm/components/DataTableFilters/index.mjs +0 -1
  120. package/dist/esm/components/DataTableFilters/index.mjs.map +1 -1
  121. package/dist/esm/components/DataTableFilters/index.native.js +0 -1
  122. package/dist/esm/components/DataTableGrouping/index.mjs +0 -8
  123. package/dist/esm/components/DataTableGrouping/index.mjs.map +1 -1
  124. package/dist/esm/components/DataTableGrouping/index.native.js +0 -8
  125. package/dist/esm/components/DataTableGrouping/index.native.js.map +1 -1
  126. package/dist/esm/components/DataTablePagination/index.mjs +30 -14
  127. package/dist/esm/components/DataTablePagination/index.mjs.map +1 -1
  128. package/dist/esm/components/DataTablePagination/index.native.js +31 -15
  129. package/dist/esm/components/DataTablePagination/index.native.js.map +1 -1
  130. package/dist/esm/components/DataTableSearch/index.mjs +0 -3
  131. package/dist/esm/components/DataTableSearch/index.mjs.map +1 -1
  132. package/dist/esm/components/DataTableSearch/index.native.js +0 -3
  133. package/dist/esm/components/DataTableSearch/index.native.js.map +1 -1
  134. package/dist/esm/components/DataTableToolbar/index.mjs +0 -1
  135. package/dist/esm/components/DataTableToolbar/index.mjs.map +1 -1
  136. package/dist/esm/components/DataTableToolbar/index.native.js +0 -1
  137. package/dist/esm/components/DataTableToolbar/index.native.js.map +1 -1
  138. package/dist/esm/components/DataTableViewOptions/index.mjs +0 -5
  139. package/dist/esm/components/DataTableViewOptions/index.mjs.map +1 -1
  140. package/dist/esm/components/DataTableViewOptions/index.native.js +0 -5
  141. package/dist/esm/components/DataTableViewOptions/index.native.js.map +1 -1
  142. package/dist/esm/components/FilterManager.mjs +0 -1
  143. package/dist/esm/components/FilterManager.mjs.map +1 -1
  144. package/dist/esm/components/FilterManager.native.js +0 -1
  145. package/dist/esm/components/FilterManager.native.js.map +1 -1
  146. package/dist/esm/components/FilterOperatorValueEditor/index.mjs +2 -2
  147. package/dist/esm/components/FilterOperatorValueEditor/index.mjs.map +1 -1
  148. package/dist/esm/components/FilterOperatorValueEditor/index.native.js +2 -2
  149. package/dist/esm/components/FilterOperatorValueEditor/index.native.js.map +1 -1
  150. package/dist/esm/components/TableInput/index.mjs +3 -2
  151. package/dist/esm/components/TableInput/index.mjs.map +1 -1
  152. package/dist/esm/components/TableInput/index.native.js +5 -3
  153. package/dist/esm/components/TableInput/index.native.js.map +1 -1
  154. package/dist/esm/hooks/useDataTable.mjs +24 -8
  155. package/dist/esm/hooks/useDataTable.mjs.map +1 -1
  156. package/dist/esm/hooks/useDataTable.native.js +28 -8
  157. package/dist/esm/hooks/useDataTable.native.js.map +1 -1
  158. package/dist/esm/index.mjs +3 -1
  159. package/dist/esm/index.mjs.map +1 -1
  160. package/dist/esm/index.native.js +3 -1
  161. package/dist/esm/index.native.js.map +1 -1
  162. package/dist/esm/shared/devWarn.mjs +43 -0
  163. package/dist/esm/shared/devWarn.mjs.map +1 -0
  164. package/dist/esm/shared/devWarn.native.js +54 -0
  165. package/dist/esm/shared/devWarn.native.js.map +1 -0
  166. package/dist/esm/utils/columnAlign.mjs +4 -1
  167. package/dist/esm/utils/columnAlign.mjs.map +1 -1
  168. package/dist/esm/utils/columnAlign.native.js +4 -1
  169. package/dist/esm/utils/columnAlign.native.js.map +1 -1
  170. package/dist/esm/utils/filterFields.mjs +5 -0
  171. package/dist/esm/utils/filterFields.mjs.map +1 -1
  172. package/dist/esm/utils/filterFields.native.js +5 -0
  173. package/dist/esm/utils/filterFields.native.js.map +1 -1
  174. package/dist/esm/utils/filterUtils.mjs +30 -0
  175. package/dist/esm/utils/filterUtils.mjs.map +1 -1
  176. package/dist/esm/utils/filterUtils.native.js +50 -0
  177. package/dist/esm/utils/filterUtils.native.js.map +1 -1
  178. package/dist/esm/utils/money.mjs +104 -0
  179. package/dist/esm/utils/money.mjs.map +1 -0
  180. package/dist/esm/utils/money.native.js +129 -0
  181. package/dist/esm/utils/money.native.js.map +1 -0
  182. package/dist/esm/utils/rowAccumulator.mjs +23 -0
  183. package/dist/esm/utils/rowAccumulator.mjs.map +1 -0
  184. package/dist/esm/utils/rowAccumulator.native.js +23 -0
  185. package/dist/esm/utils/rowAccumulator.native.js.map +1 -0
  186. package/dist/jsx/components/ColumnHeaderFilter/index.mjs +78 -42
  187. package/dist/jsx/components/ColumnHeaderFilter/index.mjs.map +1 -1
  188. package/dist/jsx/components/ColumnHeaderFilter/index.native.js +97 -51
  189. package/dist/jsx/components/ColumnHeaderFilter/index.native.js.map +1 -1
  190. package/dist/jsx/components/DataTable/DataTableCardControls.mjs +0 -1
  191. package/dist/jsx/components/DataTable/DataTableCardControls.mjs.map +1 -1
  192. package/dist/jsx/components/DataTable/DataTableCardControls.native.js +0 -1
  193. package/dist/jsx/components/DataTable/DataTableCardControls.native.js.map +1 -1
  194. package/dist/jsx/components/DataTable/DataTableMobileCards.mjs +99 -34
  195. package/dist/jsx/components/DataTable/DataTableMobileCards.mjs.map +1 -1
  196. package/dist/jsx/components/DataTable/DataTableMobileCards.native.js +139 -38
  197. package/dist/jsx/components/DataTable/DataTableMobileCards.native.js.map +1 -1
  198. package/dist/jsx/components/DataTable/DataTableRoot.mjs +33 -6
  199. package/dist/jsx/components/DataTable/DataTableRoot.mjs.map +1 -1
  200. package/dist/jsx/components/DataTable/DataTableRoot.native.js +29 -4
  201. package/dist/jsx/components/DataTable/DataTableRoot.native.js.map +1 -1
  202. package/dist/jsx/components/DataTable/DataTableStateContext.mjs.map +1 -1
  203. package/dist/jsx/components/DataTable/DataTableStateContext.native.js.map +1 -1
  204. package/dist/jsx/components/DataTable/index.native.js +59 -93
  205. package/dist/jsx/components/DataTable/index.native.js.map +1 -1
  206. package/dist/jsx/components/DataTableBulkActions/index.mjs +0 -4
  207. package/dist/jsx/components/DataTableBulkActions/index.mjs.map +1 -1
  208. package/dist/jsx/components/DataTableBulkActions/index.native.js +0 -4
  209. package/dist/jsx/components/DataTableBulkActions/index.native.js.map +1 -1
  210. package/dist/jsx/components/DataTableCell/index.mjs +17 -2
  211. package/dist/jsx/components/DataTableCell/index.mjs.map +1 -1
  212. package/dist/jsx/components/DataTableCell/index.native.js +16 -1
  213. package/dist/jsx/components/DataTableCell/index.native.js.map +1 -1
  214. package/dist/jsx/components/DataTableDateFilter/index.mjs +0 -7
  215. package/dist/jsx/components/DataTableDateFilter/index.mjs.map +1 -1
  216. package/dist/jsx/components/DataTableDateFilter/index.native.js +0 -7
  217. package/dist/jsx/components/DataTableDateFilter/index.native.js.map +1 -1
  218. package/dist/jsx/components/DataTableFilterButton/index.mjs +0 -1
  219. package/dist/jsx/components/DataTableFilterButton/index.mjs.map +1 -1
  220. package/dist/jsx/components/DataTableFilterButton/index.native.js +0 -1
  221. package/dist/jsx/components/DataTableFilterChips/FilterChip.mjs +3 -2
  222. package/dist/jsx/components/DataTableFilterChips/FilterChip.mjs.map +1 -1
  223. package/dist/jsx/components/DataTableFilterChips/FilterChip.native.js +4 -1
  224. package/dist/jsx/components/DataTableFilterChips/FilterChip.native.js.map +1 -1
  225. package/dist/jsx/components/DataTableFilters/index.mjs +0 -1
  226. package/dist/jsx/components/DataTableFilters/index.mjs.map +1 -1
  227. package/dist/jsx/components/DataTableFilters/index.native.js +0 -1
  228. package/dist/jsx/components/DataTableGrouping/index.mjs +0 -8
  229. package/dist/jsx/components/DataTableGrouping/index.mjs.map +1 -1
  230. package/dist/jsx/components/DataTableGrouping/index.native.js +0 -8
  231. package/dist/jsx/components/DataTableGrouping/index.native.js.map +1 -1
  232. package/dist/jsx/components/DataTablePagination/index.mjs +30 -14
  233. package/dist/jsx/components/DataTablePagination/index.mjs.map +1 -1
  234. package/dist/jsx/components/DataTablePagination/index.native.js +30 -14
  235. package/dist/jsx/components/DataTablePagination/index.native.js.map +1 -1
  236. package/dist/jsx/components/DataTableSearch/index.mjs +0 -3
  237. package/dist/jsx/components/DataTableSearch/index.mjs.map +1 -1
  238. package/dist/jsx/components/DataTableSearch/index.native.js +0 -3
  239. package/dist/jsx/components/DataTableSearch/index.native.js.map +1 -1
  240. package/dist/jsx/components/DataTableToolbar/index.mjs +0 -1
  241. package/dist/jsx/components/DataTableToolbar/index.mjs.map +1 -1
  242. package/dist/jsx/components/DataTableToolbar/index.native.js +0 -1
  243. package/dist/jsx/components/DataTableToolbar/index.native.js.map +1 -1
  244. package/dist/jsx/components/DataTableViewOptions/index.mjs +0 -5
  245. package/dist/jsx/components/DataTableViewOptions/index.mjs.map +1 -1
  246. package/dist/jsx/components/DataTableViewOptions/index.native.js +0 -5
  247. package/dist/jsx/components/DataTableViewOptions/index.native.js.map +1 -1
  248. package/dist/jsx/components/FilterManager.mjs +0 -1
  249. package/dist/jsx/components/FilterManager.mjs.map +1 -1
  250. package/dist/jsx/components/FilterManager.native.js +0 -1
  251. package/dist/jsx/components/FilterManager.native.js.map +1 -1
  252. package/dist/jsx/components/FilterOperatorValueEditor/index.mjs +2 -2
  253. package/dist/jsx/components/FilterOperatorValueEditor/index.mjs.map +1 -1
  254. package/dist/jsx/components/FilterOperatorValueEditor/index.native.js +2 -2
  255. package/dist/jsx/components/FilterOperatorValueEditor/index.native.js.map +1 -1
  256. package/dist/jsx/components/TableInput/index.mjs +3 -2
  257. package/dist/jsx/components/TableInput/index.mjs.map +1 -1
  258. package/dist/jsx/components/TableInput/index.native.js +4 -2
  259. package/dist/jsx/components/TableInput/index.native.js.map +1 -1
  260. package/dist/jsx/hooks/useDataTable.mjs +24 -8
  261. package/dist/jsx/hooks/useDataTable.mjs.map +1 -1
  262. package/dist/jsx/hooks/useDataTable.native.js +28 -8
  263. package/dist/jsx/hooks/useDataTable.native.js.map +1 -1
  264. package/dist/jsx/index.js +3 -1
  265. package/dist/jsx/index.js.map +1 -1
  266. package/dist/jsx/index.mjs +3 -1
  267. package/dist/jsx/index.mjs.map +1 -1
  268. package/dist/jsx/index.native.js +12 -0
  269. package/dist/jsx/index.native.js.map +1 -1
  270. package/dist/jsx/shared/devWarn.mjs +43 -0
  271. package/dist/jsx/shared/devWarn.mjs.map +1 -0
  272. package/dist/jsx/shared/devWarn.native.js +84 -0
  273. package/dist/jsx/shared/devWarn.native.js.map +1 -0
  274. package/dist/jsx/utils/columnAlign.mjs +4 -1
  275. package/dist/jsx/utils/columnAlign.mjs.map +1 -1
  276. package/dist/jsx/utils/columnAlign.native.js +4 -1
  277. package/dist/jsx/utils/columnAlign.native.js.map +1 -1
  278. package/dist/jsx/utils/filterFields.mjs +5 -0
  279. package/dist/jsx/utils/filterFields.mjs.map +1 -1
  280. package/dist/jsx/utils/filterFields.native.js +5 -0
  281. package/dist/jsx/utils/filterFields.native.js.map +1 -1
  282. package/dist/jsx/utils/filterUtils.mjs +30 -0
  283. package/dist/jsx/utils/filterUtils.mjs.map +1 -1
  284. package/dist/jsx/utils/filterUtils.native.js +50 -0
  285. package/dist/jsx/utils/filterUtils.native.js.map +1 -1
  286. package/dist/jsx/utils/money.mjs +104 -0
  287. package/dist/jsx/utils/money.mjs.map +1 -0
  288. package/dist/jsx/utils/money.native.js +165 -0
  289. package/dist/jsx/utils/money.native.js.map +1 -0
  290. package/dist/jsx/utils/rowAccumulator.mjs +23 -0
  291. package/dist/jsx/utils/rowAccumulator.mjs.map +1 -0
  292. package/dist/jsx/utils/rowAccumulator.native.js +51 -0
  293. package/dist/jsx/utils/rowAccumulator.native.js.map +1 -0
  294. package/package.json +12 -12
  295. package/src/components/ColumnHeaderFilter/ColumnHeaderFilter.spec.tsx +142 -7
  296. package/src/components/ColumnHeaderFilter/ColumnHeaderFilter.stories.tsx +46 -9
  297. package/src/components/ColumnHeaderFilter/index.tsx +104 -47
  298. package/src/components/DataTable/DataTable.spec.tsx +5 -3
  299. package/src/components/DataTable/DataTable.stories.tsx +186 -14
  300. package/src/components/DataTable/DataTableCardControls.tsx +11 -13
  301. package/src/components/DataTable/DataTableMobileCards.tsx +162 -39
  302. package/src/components/DataTable/DataTableRoot.tsx +40 -14
  303. package/src/components/DataTable/DataTableStateContext.ts +7 -0
  304. package/src/components/DataTable/cardLayout.spec.tsx +19 -8
  305. package/src/components/DataTable/columnWidthLayout.spec.tsx +195 -0
  306. package/src/components/DataTable/dataTableMobileCards.spec.tsx +50 -2
  307. package/src/components/DataTable/headerSorting.spec.tsx +25 -0
  308. package/src/components/DataTable/index.native.tsx +80 -124
  309. package/src/components/DataTable/moneyColumn.spec.tsx +151 -0
  310. package/src/components/DataTable/nativeCardParity.spec.tsx +95 -0
  311. package/src/components/DataTable/rowAccumulator.spec.tsx +171 -0
  312. package/src/components/DataTableBulkActions/index.tsx +0 -4
  313. package/src/components/DataTableCell/index.tsx +28 -2
  314. package/src/components/DataTableColumnPinning/DataTableColumnPinning.stories.tsx +0 -4
  315. package/src/components/DataTableDateFilter/index.tsx +0 -7
  316. package/src/components/DataTableFilterButton/index.tsx +1 -1
  317. package/src/components/DataTableFilterChips/FilterChip.spec.tsx +6 -0
  318. package/src/components/DataTableFilterChips/FilterChip.tsx +3 -2
  319. package/src/components/DataTableFilters/index.tsx +1 -1
  320. package/src/components/DataTableGrouping/DataTableGrouping.stories.tsx +0 -4
  321. package/src/components/DataTableGrouping/index.tsx +1 -13
  322. package/src/components/DataTablePagination/DataTablePagination.stories.tsx +14 -1
  323. package/src/components/DataTablePagination/DataTablePagination.width.spec.tsx +51 -0
  324. package/src/components/DataTablePagination/index.tsx +60 -16
  325. package/src/components/DataTableSearch/index.tsx +2 -3
  326. package/src/components/DataTableToolbar/DataTableToolbar.stories.tsx +2 -4
  327. package/src/components/DataTableToolbar/index.tsx +1 -5
  328. package/src/components/DataTableViewOptions/index.tsx +2 -13
  329. package/src/components/FilterManager.tsx +1 -3
  330. package/src/components/FilterOperatorValueEditor/FilterOperatorValueEditor.spec.tsx +1 -1
  331. package/src/components/FilterOperatorValueEditor/FilterOperatorValueEditor.stories.tsx +1 -0
  332. package/src/components/FilterOperatorValueEditor/index.tsx +10 -2
  333. package/src/components/TableInput/index.native.tsx +3 -2
  334. package/src/components/TableInput/index.tsx +3 -2
  335. package/src/hooks/useDataTable.ts +43 -7
  336. package/src/index.ts +13 -0
  337. package/src/shared/devWarn.ts +97 -0
  338. package/src/types.ts +71 -2
  339. package/src/utils/columnAlign.ts +9 -1
  340. package/src/utils/filterFields.ts +23 -1
  341. package/src/utils/filterUtils.ts +50 -1
  342. package/src/utils/money.spec.ts +156 -0
  343. package/src/utils/money.ts +202 -0
  344. package/src/utils/rowAccumulator.ts +136 -0
  345. package/types/components/ColumnHeaderFilter/index.d.ts +9 -2
  346. package/types/components/ColumnHeaderFilter/index.d.ts.map +1 -1
  347. package/types/components/DataTable/DataTableCardControls.d.ts.map +1 -1
  348. package/types/components/DataTable/DataTableMobileCards.d.ts +42 -8
  349. package/types/components/DataTable/DataTableMobileCards.d.ts.map +1 -1
  350. package/types/components/DataTable/DataTableRoot.d.ts +1 -1
  351. package/types/components/DataTable/DataTableRoot.d.ts.map +1 -1
  352. package/types/components/DataTable/DataTableStateContext.d.ts +7 -0
  353. package/types/components/DataTable/DataTableStateContext.d.ts.map +1 -1
  354. package/types/components/DataTable/index.native.d.ts +1 -1
  355. package/types/components/DataTable/index.native.d.ts.map +1 -1
  356. package/types/components/DataTableBulkActions/index.d.ts.map +1 -1
  357. package/types/components/DataTableCell/index.d.ts.map +1 -1
  358. package/types/components/DataTableDateFilter/index.d.ts.map +1 -1
  359. package/types/components/DataTableFilterChips/FilterChip.d.ts.map +1 -1
  360. package/types/components/DataTableGrouping/index.d.ts.map +1 -1
  361. package/types/components/DataTablePagination/index.d.ts.map +1 -1
  362. package/types/components/DataTableSearch/index.d.ts.map +1 -1
  363. package/types/components/DataTableToolbar/index.d.ts.map +1 -1
  364. package/types/components/DataTableViewOptions/index.d.ts.map +1 -1
  365. package/types/components/FilterManager.d.ts.map +1 -1
  366. package/types/components/FilterOperatorValueEditor/index.d.ts.map +1 -1
  367. package/types/components/TableInput/index.d.ts.map +1 -1
  368. package/types/components/TableInput/index.native.d.ts.map +1 -1
  369. package/types/hooks/useDataTable.d.ts +1 -1
  370. package/types/hooks/useDataTable.d.ts.map +1 -1
  371. package/types/index.d.ts +3 -0
  372. package/types/index.d.ts.map +1 -1
  373. package/types/shared/devWarn.d.ts +50 -0
  374. package/types/shared/devWarn.d.ts.map +1 -0
  375. package/types/types.d.ts +71 -3
  376. package/types/types.d.ts.map +1 -1
  377. package/types/utils/columnAlign.d.ts.map +1 -1
  378. package/types/utils/filterFields.d.ts.map +1 -1
  379. package/types/utils/filterUtils.d.ts +1 -1
  380. package/types/utils/filterUtils.d.ts.map +1 -1
  381. package/types/utils/money.d.ts +94 -0
  382. package/types/utils/money.d.ts.map +1 -0
  383. package/types/utils/rowAccumulator.d.ts +107 -0
  384. package/types/utils/rowAccumulator.d.ts.map +1 -0
@@ -7,7 +7,7 @@
7
7
  * breakpoint switch are exercised without resizing a window.
8
8
  *
9
9
  * Covers: breakpoint/override switching, card anatomy (title slot +
10
- * label/value rows), column visibility, sorting order, global search,
10
+ * classified fields), column visibility, sorting order, global search,
11
11
  * column filters, the card sort/filter controls, the SimpleTable layout
12
12
  * override, and the Table primitives card layout.
13
13
  */
@@ -127,7 +127,7 @@ describe("DataTable card layout", () => {
127
127
  });
128
128
 
129
129
  describe("card anatomy", () => {
130
- it("renders the first visible column as the card title and the rest as label/value rows", () => {
130
+ it("renders the first visible column as the card title and classifies the rest", () => {
131
131
  const { container } = renderWithProviders(
132
132
  <DataTable data={sampleData} columns={columns} onStateChange={vi.fn()} />,
133
133
  );
@@ -140,15 +140,21 @@ describe("DataTable card layout", () => {
140
140
  expect(title!.textContent).toContain("John");
141
141
  expect(within(firstCard).queryByText("First Name")).toBeNull();
142
142
 
143
- // Remaining visible columns render as label/value rows.
144
- expect(within(firstCard).getByText("Last Name")).toBeDefined();
143
+ // A self-naming string goes bare. Its column name still reaches
144
+ // assistive tech, through a hidden node that costs no layout.
145
+ expect(within(firstCard).queryByText("Last Name")).toBeNull();
146
+ expect(within(firstCard).queryByText("Email")).toBeNull();
147
+ expect(firstCard.textContent).toContain("Last Name:");
148
+ expect(firstCard.textContent).toContain("Email:");
149
+
150
+ // A figure cannot be read without its name, so that one prints.
145
151
  expect(within(firstCard).getByText("Age")).toBeDefined();
146
- expect(within(firstCard).getByText("Email")).toBeDefined();
152
+
147
153
  expect(firstCard.textContent).toContain("Doe");
148
154
  expect(firstCard.textContent).toContain("28");
149
155
  });
150
156
 
151
- it("labels field rows from meta.label when the header is a render function", () => {
157
+ it("names a control from meta.label when the header is a render function", () => {
152
158
  const glyphColumns: DataTableColumn<Person>[] = [
153
159
  { id: "firstName", accessorKey: "firstName", header: "First Name" },
154
160
  {
@@ -162,7 +168,9 @@ describe("DataTable card layout", () => {
162
168
  <DataTable data={sampleData} columns={glyphColumns} onStateChange={vi.fn()} />,
163
169
  );
164
170
  const [firstCard] = getCards(container);
165
- expect(within(firstCard).getByText("Liked")).toBeDefined();
171
+ // A leading underscore marks a control: its own row, no printed label.
172
+ expect(within(firstCard).queryByText("Liked")).toBeNull();
173
+ expect(firstCard.textContent).toContain("Liked:");
166
174
  expect(firstCard.textContent).not.toContain("_liked_by");
167
175
  });
168
176
 
@@ -180,9 +188,11 @@ describe("DataTable card layout", () => {
180
188
  <DataTable data={sampleData} columns={mixedColumns} onStateChange={vi.fn()} />,
181
189
  );
182
190
  const [firstCard] = getCards(container);
191
+ // A figure prints its name, a bare string hides it. meta.label wins
192
+ // either way, and the id fallback stays honest.
183
193
  expect(within(firstCard).getByText("Age (years)")).toBeDefined();
184
194
  expect(within(firstCard).queryByText("♥")).toBeNull();
185
- expect(within(firstCard).getByText("email_addr")).toBeDefined();
195
+ expect(firstCard.textContent).toContain("email_addr:");
186
196
  });
187
197
 
188
198
  it("respects column visibility (hidden columns stay hidden in cards)", () => {
@@ -196,6 +206,7 @@ describe("DataTable card layout", () => {
196
206
  );
197
207
  const [firstCard] = getCards(container);
198
208
  expect(within(firstCard).queryByText("Email")).toBeNull();
209
+ expect(firstCard.textContent).not.toContain("Email:");
199
210
  expect(firstCard.textContent).not.toContain("john@example.com");
200
211
  });
201
212
  });
@@ -0,0 +1,195 @@
1
+ /**
2
+ * MPO-236 — per-column width under `columnLayout: "equal"`.
3
+ *
4
+ * `equal` is the default, and it flexes every cell to `flexGrow: 1,
5
+ * flexBasis: 0`. A column's `width` / `size` therefore never reaches the cell
6
+ * box: the render comes out identical to one that declared no widths at all,
7
+ * which reads as "the widths ARE applied and are not enough" and sends the
8
+ * reader looking in the wrong place.
9
+ *
10
+ * The default is not changed here — that would move every existing table's
11
+ * render. The combination warns instead, naming `columnLayout` as the reason.
12
+ */
13
+
14
+ import { renderWithProviders } from "@multiplatform.one/test-utils";
15
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
16
+ import type { DataTableColumn } from "../../types";
17
+ import { __resetTableDevWarnSeen, warnColumnWidthIgnored } from "../../shared/devWarn";
18
+ import { DataTable } from "./index";
19
+
20
+ type Pokemon = { id: number; name: string; xp: number };
21
+
22
+ const sampleData: Pokemon[] = [
23
+ { id: 1, name: "Bulbasaur", xp: 64 },
24
+ { id: 2, name: "Charmander", xp: 62 },
25
+ ];
26
+
27
+ const plainColumns: DataTableColumn<Pokemon>[] = [
28
+ { id: "name", accessorKey: "name", header: "Name" },
29
+ { id: "xp", accessorKey: "xp", header: "XP" },
30
+ ];
31
+
32
+ const widthColumns: DataTableColumn<Pokemon>[] = [
33
+ { id: "name", accessorKey: "name", header: "Name", width: 320 },
34
+ { id: "xp", accessorKey: "xp", header: "XP", width: 80 },
35
+ ];
36
+
37
+ let warnings: string[] = [];
38
+ let warnSpy: ReturnType<typeof vi.spyOn>;
39
+
40
+ function startCapture() {
41
+ warnings = [];
42
+ __resetTableDevWarnSeen();
43
+ warnSpy = vi.spyOn(console, "warn").mockImplementation((...args) => {
44
+ warnings.push(args.map((arg) => String(arg)).join(" "));
45
+ });
46
+ }
47
+
48
+ function stopCapture() {
49
+ warnSpy.mockRestore();
50
+ __resetTableDevWarnSeen();
51
+ }
52
+
53
+ /** Only this rule's warnings — other table chrome may warn for its own reasons. */
54
+ function widthWarnings(): string[] {
55
+ return warnings.filter((line) => line.includes("column-width-ignored"));
56
+ }
57
+
58
+ /**
59
+ * React 19's client `useId` counter is module-global (`_r_<base32>_`), so two
60
+ * renders in one process never share generated ids. Normalize them out before
61
+ * comparing markup.
62
+ */
63
+ function stripGeneratedIds(html: string): string {
64
+ return html.replace(/_r_[0-9a-z]+_/g, "_r_id_");
65
+ }
66
+
67
+ /** `columnLayout` omitted on purpose in most calls: "equal" is the default. */
68
+ function renderTable(
69
+ columns: DataTableColumn<Pokemon>[],
70
+ columnLayout?: "equal" | "auto" | "scroll",
71
+ ) {
72
+ return renderWithProviders(
73
+ <DataTable
74
+ data={sampleData}
75
+ columns={columns as DataTableColumn<Record<string, any>>[]}
76
+ layout="table"
77
+ columnLayout={columnLayout}
78
+ enablePagination={false}
79
+ readOnly
80
+ />,
81
+ );
82
+ }
83
+
84
+ describe("warnColumnWidthIgnored", () => {
85
+ let prevEnv: string | undefined;
86
+
87
+ beforeEach(() => {
88
+ prevEnv = process.env.NODE_ENV;
89
+ process.env.NODE_ENV = "development";
90
+ startCapture();
91
+ });
92
+
93
+ afterEach(() => {
94
+ stopCapture();
95
+ process.env.NODE_ENV = prevEnv;
96
+ });
97
+
98
+ it("names columnLayout and the offending columns", () => {
99
+ warnColumnWidthIgnored({ columnLayout: "equal", columns: widthColumns });
100
+ expect(widthWarnings()).toHaveLength(1);
101
+ expect(widthWarnings()[0]).toContain("[table] column-width-ignored");
102
+ expect(widthWarnings()[0]).toContain("columnLayout=equal");
103
+ expect(widthWarnings()[0]).toContain("columns=name,xp");
104
+ });
105
+
106
+ it("catches the TanStack `size` spelling too", () => {
107
+ warnColumnWidthIgnored({ columnLayout: "equal", columns: [{ id: "avatar", size: 60 }] });
108
+ expect(widthWarnings()).toHaveLength(1);
109
+ expect(widthWarnings()[0]).toContain("columns=avatar");
110
+ });
111
+
112
+ it("falls back to accessorKey, then position, for the column name", () => {
113
+ warnColumnWidthIgnored({
114
+ columnLayout: "equal",
115
+ columns: [{ accessorKey: "xp", width: 80 }, { size: 60 }],
116
+ });
117
+ expect(widthWarnings()[0]).toContain("columns=xp,#1");
118
+ });
119
+
120
+ it("stays quiet when no column declares a width", () => {
121
+ warnColumnWidthIgnored({ columnLayout: "equal", columns: plainColumns });
122
+ expect(widthWarnings()).toHaveLength(0);
123
+ });
124
+
125
+ it.each(["auto", "scroll"] as const)("stays quiet under columnLayout=%s", (columnLayout) => {
126
+ warnColumnWidthIgnored({ columnLayout, columns: widthColumns });
127
+ expect(widthWarnings()).toHaveLength(0);
128
+ });
129
+
130
+ it("stays quiet with enableColumnResizing, where the width does survive", () => {
131
+ warnColumnWidthIgnored({
132
+ columnLayout: "equal",
133
+ enableColumnResizing: true,
134
+ columns: widthColumns,
135
+ });
136
+ expect(widthWarnings()).toHaveLength(0);
137
+ });
138
+
139
+ it("no-ops in production", () => {
140
+ process.env.NODE_ENV = "production";
141
+ warnColumnWidthIgnored({ columnLayout: "equal", columns: widthColumns });
142
+ expect(widthWarnings()).toHaveLength(0);
143
+ });
144
+
145
+ it("warns once per offending column set, not once per call", () => {
146
+ warnColumnWidthIgnored({ columnLayout: "equal", columns: widthColumns });
147
+ warnColumnWidthIgnored({ columnLayout: "equal", columns: widthColumns });
148
+ warnColumnWidthIgnored({ columnLayout: "equal", columns: widthColumns });
149
+ expect(widthWarnings()).toHaveLength(1);
150
+ });
151
+ });
152
+
153
+ describe("DataTable columnLayout=equal with per-column widths", () => {
154
+ beforeEach(startCapture);
155
+ afterEach(stopCapture);
156
+
157
+ it("discards the widths: the markup matches a table that declared none", () => {
158
+ const withWidths = renderTable(widthColumns);
159
+ const widthMarkup = stripGeneratedIds(withWidths.container.innerHTML);
160
+ withWidths.unmount();
161
+
162
+ const withoutWidths = renderTable(plainColumns);
163
+ expect(stripGeneratedIds(withoutWidths.container.innerHTML)).toBe(widthMarkup);
164
+ });
165
+
166
+ it("warns, so the discard is not silent", () => {
167
+ renderTable(widthColumns);
168
+ expect(widthWarnings()).toHaveLength(1);
169
+ expect(widthWarnings()[0]).toContain("component=DataTable");
170
+ });
171
+
172
+ it("warns once per table, not once per render", () => {
173
+ const { rerender } = renderTable(widthColumns);
174
+ rerender(
175
+ <DataTable
176
+ data={[...sampleData, { id: 3, name: "Squirtle", xp: 63 }]}
177
+ columns={widthColumns as DataTableColumn<Record<string, any>>[]}
178
+ layout="table"
179
+ enablePagination={false}
180
+ readOnly
181
+ />,
182
+ );
183
+ expect(widthWarnings()).toHaveLength(1);
184
+ });
185
+
186
+ it("does not warn under columnLayout=auto", () => {
187
+ renderTable(widthColumns, "auto");
188
+ expect(widthWarnings()).toHaveLength(0);
189
+ });
190
+
191
+ it("does not warn for a table with no per-column widths", () => {
192
+ renderTable(plainColumns);
193
+ expect(widthWarnings()).toHaveLength(0);
194
+ });
195
+ });
@@ -8,10 +8,14 @@
8
8
  * delete cluster beside the title, the delete floor at `minRows`, and the two
9
9
  * distinct empty-state copies (no data vs no results) — plus the rule that an
10
10
  * in-flight refetch paints NO empty state over a momentarily blank body.
11
+ *
12
+ * It also pins `classifyCardField`, which decides whether a field prints its
13
+ * column name at all. In the grid a header is written once for a whole
14
+ * column; on a card it would be written once per value.
11
15
  */
12
16
 
13
17
  import { renderWithProviders } from "@multiplatform.one/test-utils";
14
- import { fireEvent, screen, waitFor } from "@testing-library/react";
18
+ import { fireEvent, screen, waitFor, within } from "@testing-library/react";
15
19
  import { describe, expect, it, vi } from "vitest";
16
20
  import type { DataTableColumn, TableFilter } from "../../types";
17
21
  import { DataTable } from "./index";
@@ -52,7 +56,7 @@ describe("DataTableMobileCards", () => {
52
56
  expect(cards(container).length).toBe(people.length);
53
57
  });
54
58
 
55
- it("the first visible column is the card title, the rest are label/value rows", () => {
59
+ it("the first visible column is the card title, the rest are classified fields", () => {
56
60
  const { container } = renderCards();
57
61
  const first = cards(container)[0];
58
62
  expect(first.querySelector('[data-card-slot="title"]')?.textContent).toBe("John");
@@ -69,6 +73,50 @@ describe("DataTableMobileCards", () => {
69
73
  expect(first.textContent).not.toContain("Last Name");
70
74
  });
71
75
 
76
+ it("a self-naming string goes bare, into one wrapped flow with its name hidden", () => {
77
+ const { container } = renderCards();
78
+ const first = cards(container)[0];
79
+ const meta = first.querySelector('[data-card-slot="meta"]');
80
+ expect(meta).not.toBeNull();
81
+ expect(meta!.textContent).toContain("Doe");
82
+ expect(within(first).queryByText("Last Name")).toBeNull();
83
+ expect(first.textContent).toContain("Last Name:");
84
+ });
85
+
86
+ it("a figure keeps its column name, inline beside the value", () => {
87
+ const { container } = renderCards();
88
+ const first = cards(container)[0];
89
+ const figure = first.querySelector('[data-card-slot="figure"]');
90
+ expect(figure).not.toBeNull();
91
+ expect(figure!.textContent).toContain("28");
92
+ expect(within(first).getByText("Age")).toBeDefined();
93
+ });
94
+
95
+ it("a field with no value spends no row at all", () => {
96
+ const { container } = renderCards({
97
+ data: [{ id: 1, firstName: "John", lastName: "", age: 28 }],
98
+ });
99
+ const first = cards(container)[0];
100
+ expect(first.querySelector('[data-card-slot="meta"]')).toBeNull();
101
+ expect(first.textContent).not.toContain("Last Name");
102
+ });
103
+
104
+ it("a control keeps a row of its own and prints no label", () => {
105
+ // Explicit id on BOTH columns: DataTable seeds columnOrder from
106
+ // `col.id || ""`, so an id-less accessor column beside an id'd one would
107
+ // put `_actions` first and make the control the card title instead.
108
+ const { container } = renderCards({
109
+ columns: [
110
+ { id: "firstName", accessorKey: "firstName", header: "First Name" },
111
+ { id: "_actions", accessorKey: "lastName", header: "Actions", meta: { role: "actions" } },
112
+ ],
113
+ });
114
+ const first = cards(container)[0];
115
+ expect(first.querySelector('[data-card-slot="control"]')).not.toBeNull();
116
+ expect(within(first).queryByText("Actions")).toBeNull();
117
+ expect(first.textContent).toContain("Actions:");
118
+ });
119
+
72
120
  it("selection adds a select-all bar above the stack and a checkbox per card", () => {
73
121
  const { container } = renderCards({ enableRowSelection: true });
74
122
  expect(screen.getByLabelText("Select all rows")).toBeTruthy();
@@ -130,6 +130,31 @@ describe("DataTable header sorting (web grid)", () => {
130
130
  await waitFor(() => expect(header().getAttribute("aria-sort")).toBe("none"));
131
131
  });
132
132
 
133
+ it("gives Phosphor resolved CSS colors in every sort state", async () => {
134
+ const { header } = renderTable();
135
+ for (const direction of ["none", "ascending", "descending"]) {
136
+ await waitFor(() => expect(header().getAttribute("aria-sort")).toBe(direction));
137
+ const icon = header().querySelector("svg");
138
+ expect(icon).not.toBeNull();
139
+ const ink = icon?.getAttribute("fill") || icon?.getAttribute("color") || icon?.style.color;
140
+ expect(ink).toBeTruthy();
141
+ expect(ink).not.toMatch(/\$/);
142
+ fireEvent.click(header());
143
+ }
144
+ });
145
+
146
+ it("plain click replaces another column sort and Shift+click adds to it", async () => {
147
+ const { header, container, states } = renderTable();
148
+ const ageHeader = container.querySelector("#age-header") as HTMLElement;
149
+ fireEvent.click(header());
150
+ fireEvent.click(ageHeader);
151
+ await waitFor(() => expect(states.at(-1)?.sorting.map((sort) => sort.id)).toEqual(["age"]));
152
+ fireEvent.click(header(), { shiftKey: true });
153
+ await waitFor(() =>
154
+ expect(states.at(-1)?.sorting.map((sort) => sort.id)).toEqual(["age", "firstName"]),
155
+ );
156
+ });
157
+
133
158
  it("non-sortable headers get no press affordance, no tab stop, and no aria-sort", () => {
134
159
  const { container } = renderWithProviders(
135
160
  <DataTable
@@ -17,12 +17,12 @@ import { FlashList, type FlashListRef } from "@shopify/flash-list";
17
17
  import { AsyncBoundary, EmptyState, useDirection } from "@multiplatform.one/components";
18
18
  import { Button, Field, useFormField } from "@multiplatform.one/forms";
19
19
  import { flexRender } from "@tanstack/react-table";
20
- import { hairline, useResolvedKnobs } from "@multiplatform.one/theme";
20
+ import { useResolvedKnobs } from "@multiplatform.one/theme";
21
21
  import React, { useRef, useMemo, useCallback } from "react";
22
22
  import { ScrollView, Text, View, useMedia, withStaticProperties } from "tamagui";
23
23
  import { useTranslation } from "react-i18next";
24
24
  import { useDataTable } from "../../hooks/useDataTable";
25
- import type { DataTableColumn, DataTableField } from "../../types";
25
+ import type { DataTableColumn, DataTableField, SelectAllScope } from "../../types";
26
26
  import { DEFAULT_PAGE_SIZE_OPTIONS } from "../../utils/paginationDefaults";
27
27
  import { withInterp } from "../../utils/withInterp";
28
28
  import { DataTableColumnPinning } from "../DataTableColumnPinning";
@@ -38,6 +38,7 @@ import { DataTableCell } from "../DataTableCell";
38
38
  import { Table } from "@multiplatform.one/table-primitives";
39
39
  import { DataTableContext } from "./DataTableContext";
40
40
  import { DataTableDocumentList } from "./DataTableDocumentList";
41
+ import { DataTableMobileCards } from "./DataTableMobileCards";
41
42
  import { dataTableChrome, resolveDataTableIntent, rowIntentProps } from "./dataTableChrome";
42
43
  import { tableRowStateProps } from "./rowStateChrome";
43
44
  import { DataTableStateContext } from "./DataTableStateContext";
@@ -134,6 +135,8 @@ function DataTableRoot<TData extends Record<string, any> = Record<string, any>>(
134
135
  virtualizationOverscan = 5,
135
136
  enableRowExpansion = false,
136
137
  renderSubComponent,
138
+ enableRowSelection = false,
139
+ selectAllScope: selectAllScopeProp,
137
140
  enableColumnPinning = false,
138
141
  maxPinnedColumns = 3,
139
142
  enableKeyboardNavigation: _enableKeyboardNavigation = false,
@@ -181,6 +184,9 @@ function DataTableRoot<TData extends Record<string, any> = Record<string, any>>(
181
184
  compact,
182
185
  });
183
186
  const chrome = dataTableChrome(String(knobProps.sizeToken));
187
+ // House selectAllScope knob (DG-TBL-03): prop overrides knob; default page.
188
+ const selectAllScope: SelectAllScope =
189
+ selectAllScopeProp ?? (knobProps.selectAllScope === "filtered" ? "filtered" : "page");
184
190
  const rowHeightPx = chrome.rowPx;
185
191
  // Collapsed expand-caret points toward inline-end, so it mirrors in RTL via
186
192
  // glyph swap (useDirection, Axiom 15); rotation sign flips so expanded
@@ -216,6 +222,7 @@ function DataTableRoot<TData extends Record<string, any> = Record<string, any>>(
216
222
  virtualizationOverscan,
217
223
  enableRowExpansion,
218
224
  renderSubComponent,
225
+ enableRowSelection,
219
226
  enableColumnPinning,
220
227
  maxPinnedColumns,
221
228
  enableKeyboardNavigation: false,
@@ -225,6 +232,25 @@ function DataTableRoot<TData extends Record<string, any> = Record<string, any>>(
225
232
  isFetching: isFetchingProp,
226
233
  });
227
234
 
235
+ const selectAllChecked =
236
+ enableRowSelection &&
237
+ (selectAllScope === "filtered"
238
+ ? table.getIsAllRowsSelected()
239
+ : table.getIsAllPageRowsSelected());
240
+ const selectAllIndeterminate =
241
+ enableRowSelection &&
242
+ (selectAllScope === "filtered"
243
+ ? table.getIsSomeRowsSelected() && !table.getIsAllRowsSelected()
244
+ : table.getIsSomePageRowsSelected() && !table.getIsAllPageRowsSelected());
245
+
246
+ const toggleSelectAll = useCallback(() => {
247
+ if (selectAllScope === "filtered") {
248
+ table.toggleAllRowsSelected();
249
+ } else {
250
+ table.toggleAllPageRowsSelected();
251
+ }
252
+ }, [selectAllScope, table]);
253
+
228
254
  const resolvedSize: "sm" | "md" | "lg" =
229
255
  size ?? (knobProps.sizeToken === "$3" ? "sm" : knobProps.sizeToken === "$5" ? "lg" : "md");
230
256
 
@@ -493,8 +519,8 @@ function DataTableRoot<TData extends Record<string, any> = Record<string, any>>(
493
519
  // (see utils/rowPress.ts). Roving tabindex is a web-only concern.
494
520
  const rowPressActive = Boolean(onRowPress) && !disabled;
495
521
 
496
- const deriveRowLabel = useCallback(
497
- (row: (typeof tableRows)[0], index: number): string => {
522
+ const deriveRowIdentity = useCallback(
523
+ (row: (typeof tableRows)[0]): string | undefined => {
498
524
  const fromAccessor = rowLabel?.(row.original as TData);
499
525
  if (fromAccessor) return fromAccessor;
500
526
  let firstCellValue: unknown;
@@ -509,13 +535,33 @@ function DataTableRoot<TData extends Record<string, any> = Record<string, any>>(
509
535
  ) {
510
536
  return String(firstCellValue);
511
537
  }
512
- return withInterp(t("Row {{row}}", { row: index + 1 }), { row: index + 1 });
538
+ return undefined;
513
539
  },
514
- [rowLabel, t],
540
+ [rowLabel],
541
+ );
542
+
543
+ const deriveRowLabel = useCallback(
544
+ (row: (typeof tableRows)[0], index: number): string =>
545
+ deriveRowIdentity(row) ??
546
+ withInterp(t("Row {{row}}", { row: index + 1 }), { row: index + 1 }),
547
+ [deriveRowIdentity, t],
548
+ );
549
+
550
+ // Selection-toggle name: row identity beats a bare index ("Select row
551
+ // Bulbasaur", falling back to "Select row 3"), the same source the grid
552
+ // and the card list both read.
553
+ const deriveSelectRowLabel = useCallback(
554
+ (row: (typeof tableRows)[0], index: number): string => {
555
+ const identity = deriveRowIdentity(row) ?? String(index + 1);
556
+ return withInterp(t("Select row {{row}}", { row: identity }), { row: identity });
557
+ },
558
+ [deriveRowIdentity, t],
515
559
  );
516
560
 
517
561
  const getRowPressProps = useCallback(
518
- (row: (typeof tableRows)[0], index: number) => {
562
+ // The card list asks for the "card" variant. Native carries no DOM row
563
+ // role for it to override, so both variants land on role="button".
564
+ (row: (typeof tableRows)[0], index: number, _variant: "row" | "card" = "row") => {
519
565
  if (!rowPressActive) return {};
520
566
  return {
521
567
  onPress: () => onRowPress?.(row.original as TData, index),
@@ -551,101 +597,6 @@ function DataTableRoot<TData extends Record<string, any> = Record<string, any>>(
551
597
  [renderRowContent, tableZebraOn, t, getRowPressProps],
552
598
  );
553
599
 
554
- const renderMobileCard = useCallback(
555
- (row: (typeof tableRows)[0], index: number, onDelete?: (idx: number) => void) => {
556
- const rowData = row.original as TData;
557
- const visibleCells = row.getVisibleCells();
558
- return (
559
- <View
560
- key={`${row.id}-${index}`}
561
- backgroundColor="$color1"
562
- borderRadius="$4"
563
- borderWidth={1}
564
- borderColor="$borderColor"
565
- padding="$3"
566
- marginBottom="$2"
567
- {...(getRowPressProps(row, index) as any)}
568
- {...(rowIntentProps(rowData) as any)}
569
- >
570
- {showRowNumbers && (
571
- <View
572
- flexDirection="row"
573
- justifyContent="space-between"
574
- paddingBottom="$2"
575
- {...hairline.bottom}
576
- borderBottomColor="$borderColor"
577
- marginBottom="$2"
578
- >
579
- <Text fontSize="$3" color="$color10" fontWeight="600">
580
- #{index + 1}
581
- </Text>
582
- {showDeleteRow && !readOnly && (
583
- <Button
584
- chromeless
585
- circular
586
- size="$2"
587
- icon={TrashIcon}
588
- disabled={disabled || tableRows.length <= minRows}
589
- onPress={() => onDelete?.(index)}
590
- aria-label={withInterp(t("Delete row {{row}}", { row: index + 1 }), {
591
- row: index + 1,
592
- })}
593
- />
594
- )}
595
- </View>
596
- )}
597
- {visibleCells.map((cell: any) => {
598
- const columnDef = cell.column.columnDef as DataTableColumn;
599
- const headerLabel =
600
- typeof columnDef.header === "string"
601
- ? columnDef.header
602
- : columnDef.id || cell.column.id;
603
- return (
604
- <View
605
- key={cell.id}
606
- flexDirection="row"
607
- alignItems="center"
608
- paddingVertical="$1.5"
609
- gap="$2"
610
- >
611
- <Text fontSize="$3" color="$color10" fontWeight="500" width="40%" flexShrink={0}>
612
- {headerLabel}
613
- </Text>
614
- <View flex={1}>{renderCellContent(cell, index, rowData)}</View>
615
- </View>
616
- );
617
- })}
618
- {!showRowNumbers && showDeleteRow && !readOnly && (
619
- <View paddingTop="$2" alignItems="flex-end">
620
- <Button
621
- chromeless
622
- circular
623
- size="$2"
624
- icon={TrashIcon}
625
- disabled={disabled || tableRows.length <= minRows}
626
- onPress={() => onDelete?.(index)}
627
- aria-label={withInterp(t("Delete row {{row}}", { row: index + 1 }), {
628
- row: index + 1,
629
- })}
630
- />
631
- </View>
632
- )}
633
- </View>
634
- );
635
- },
636
- [
637
- showRowNumbers,
638
- showDeleteRow,
639
- readOnly,
640
- disabled,
641
- tableRows.length,
642
- minRows,
643
- renderCellContent,
644
- t,
645
- getRowPressProps,
646
- ],
647
- );
648
-
649
600
  const renderToolbarComponent = () => {
650
601
  if (renderToolbar) {
651
602
  return renderToolbar({
@@ -777,36 +728,37 @@ function DataTableRoot<TData extends Record<string, any> = Record<string, any>>(
777
728
  {showList ? (
778
729
  <DataTableDocumentList
779
730
  tableRows={displayRows}
731
+ enableRowSelection={enableRowSelection}
780
732
  disabled={disabled}
781
733
  hasActiveFilters={computed.hasActiveFilters}
782
734
  renderCellContent={renderCellContent}
783
735
  compact={isCompact}
736
+ selectRowLabel={deriveSelectRowLabel}
784
737
  queryInFlight={queryInFlight}
785
738
  {...(rowPressActive ? { getRowPressProps } : {})}
786
739
  />
787
740
  ) : showCards ? (
788
741
  <View flexDirection="column" gap="$2">
789
- {displayRows.length === 0 ? (
790
- queryInFlight ? null : (
791
- <EmptyState
792
- compact
793
- backgroundColor="$color1"
794
- borderRadius="$4"
795
- aria-live="polite"
796
- title={
797
- computed.hasActiveFilters ? t("No results found") : t("No data available")
798
- }
799
- />
800
- )
801
- ) : (
802
- displayRows.map((row, index) =>
803
- renderMobileCard(
804
- row,
805
- index,
806
- isFormMode ? effectiveHandleDeleteRow : handleDeleteRow,
807
- ),
808
- )
809
- )}
742
+ <DataTableMobileCards
743
+ tableRows={displayRows}
744
+ enableRowSelection={enableRowSelection}
745
+ showRowNumbers={showRowNumbers}
746
+ showDeleteRow={showDeleteRow}
747
+ readOnly={readOnly}
748
+ disabled={disabled}
749
+ dataLength={tableData.length}
750
+ minRows={minRows}
751
+ hasActiveFilters={computed.hasActiveFilters}
752
+ renderCellContent={renderCellContent}
753
+ onDeleteRow={isFormMode ? effectiveHandleDeleteRow : handleDeleteRow}
754
+ selectAllChecked={selectAllChecked}
755
+ selectAllIndeterminate={selectAllIndeterminate}
756
+ onToggleSelectAll={toggleSelectAll}
757
+ compact={isCompact}
758
+ selectRowLabel={deriveSelectRowLabel}
759
+ queryInFlight={queryInFlight}
760
+ {...(rowPressActive ? { getRowPressProps } : {})}
761
+ />
810
762
  {enablePagination && (
811
763
  <View width="100%" {...(disabled ? disabledState.chromeKnobProps : {})}>
812
764
  {renderPaginationComponent()}
@@ -1099,7 +1051,6 @@ function DataTableRoot<TData extends Record<string, any> = Record<string, any>>(
1099
1051
  virtualizationHeight,
1100
1052
  virtualizationOverscan,
1101
1053
  renderRow,
1102
- renderMobileCard,
1103
1054
  renderSubComponent,
1104
1055
  footerGroups,
1105
1056
  sm,
@@ -1118,6 +1069,11 @@ function DataTableRoot<TData extends Record<string, any> = Record<string, any>>(
1118
1069
  renderCellContent,
1119
1070
  rowPressActive,
1120
1071
  getRowPressProps,
1072
+ enableRowSelection,
1073
+ selectAllChecked,
1074
+ selectAllIndeterminate,
1075
+ toggleSelectAll,
1076
+ deriveSelectRowLabel,
1121
1077
  displayRows,
1122
1078
  queryInFlight,
1123
1079
  t,