@multiplatform.one/table 7.7.6 → 7.8.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 (357) 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/DataTableRoot.cjs +33 -6
  8. package/dist/cjs/components/DataTable/DataTableRoot.native.js +29 -4
  9. package/dist/cjs/components/DataTable/DataTableRoot.native.js.map +1 -1
  10. package/dist/cjs/components/DataTable/DataTableStateContext.native.js.map +1 -1
  11. package/dist/cjs/components/DataTableBulkActions/index.cjs +0 -4
  12. package/dist/cjs/components/DataTableBulkActions/index.native.js +0 -4
  13. package/dist/cjs/components/DataTableBulkActions/index.native.js.map +1 -1
  14. package/dist/cjs/components/DataTableCell/index.cjs +16 -1
  15. package/dist/cjs/components/DataTableCell/index.native.js +16 -1
  16. package/dist/cjs/components/DataTableCell/index.native.js.map +1 -1
  17. package/dist/cjs/components/DataTableDateFilter/index.cjs +0 -7
  18. package/dist/cjs/components/DataTableDateFilter/index.native.js +0 -7
  19. package/dist/cjs/components/DataTableDateFilter/index.native.js.map +1 -1
  20. package/dist/cjs/components/DataTableFilterButton/index.cjs +0 -1
  21. package/dist/cjs/components/DataTableFilterButton/index.native.js +0 -1
  22. package/dist/cjs/components/DataTableFilterChips/FilterChip.cjs +2 -1
  23. package/dist/cjs/components/DataTableFilterChips/FilterChip.native.js +4 -1
  24. package/dist/cjs/components/DataTableFilterChips/FilterChip.native.js.map +1 -1
  25. package/dist/cjs/components/DataTableFilters/index.cjs +0 -1
  26. package/dist/cjs/components/DataTableFilters/index.native.js +0 -1
  27. package/dist/cjs/components/DataTableGrouping/index.cjs +0 -8
  28. package/dist/cjs/components/DataTableGrouping/index.native.js +0 -8
  29. package/dist/cjs/components/DataTableGrouping/index.native.js.map +1 -1
  30. package/dist/cjs/components/DataTablePagination/index.cjs +29 -13
  31. package/dist/cjs/components/DataTablePagination/index.native.js +30 -14
  32. package/dist/cjs/components/DataTablePagination/index.native.js.map +1 -1
  33. package/dist/cjs/components/DataTableSearch/index.cjs +0 -3
  34. package/dist/cjs/components/DataTableSearch/index.native.js +0 -3
  35. package/dist/cjs/components/DataTableSearch/index.native.js.map +1 -1
  36. package/dist/cjs/components/DataTableToolbar/index.cjs +0 -1
  37. package/dist/cjs/components/DataTableToolbar/index.native.js +0 -1
  38. package/dist/cjs/components/DataTableToolbar/index.native.js.map +1 -1
  39. package/dist/cjs/components/DataTableViewOptions/index.cjs +0 -5
  40. package/dist/cjs/components/DataTableViewOptions/index.native.js +0 -5
  41. package/dist/cjs/components/DataTableViewOptions/index.native.js.map +1 -1
  42. package/dist/cjs/components/FilterManager.cjs +0 -1
  43. package/dist/cjs/components/FilterManager.native.js +0 -1
  44. package/dist/cjs/components/FilterManager.native.js.map +1 -1
  45. package/dist/cjs/components/FilterOperatorValueEditor/index.cjs +2 -2
  46. package/dist/cjs/components/FilterOperatorValueEditor/index.native.js +2 -2
  47. package/dist/cjs/components/FilterOperatorValueEditor/index.native.js.map +1 -1
  48. package/dist/cjs/components/TableInput/index.cjs +2 -1
  49. package/dist/cjs/components/TableInput/index.native.js +4 -2
  50. package/dist/cjs/components/TableInput/index.native.js.map +1 -1
  51. package/dist/cjs/hooks/useDataTable.cjs +24 -8
  52. package/dist/cjs/hooks/useDataTable.native.js +28 -8
  53. package/dist/cjs/hooks/useDataTable.native.js.map +1 -1
  54. package/dist/cjs/index.cjs +12 -0
  55. package/dist/cjs/index.native.js +12 -0
  56. package/dist/cjs/index.native.js.map +1 -1
  57. package/dist/cjs/shared/devWarn.cjs +70 -0
  58. package/dist/cjs/shared/devWarn.native.js +84 -0
  59. package/dist/cjs/shared/devWarn.native.js.map +1 -0
  60. package/dist/cjs/utils/columnAlign.cjs +4 -1
  61. package/dist/cjs/utils/columnAlign.native.js +4 -1
  62. package/dist/cjs/utils/columnAlign.native.js.map +1 -1
  63. package/dist/cjs/utils/filterFields.cjs +5 -0
  64. package/dist/cjs/utils/filterFields.native.js +5 -0
  65. package/dist/cjs/utils/filterFields.native.js.map +1 -1
  66. package/dist/cjs/utils/filterUtils.cjs +30 -0
  67. package/dist/cjs/utils/filterUtils.native.js +50 -0
  68. package/dist/cjs/utils/filterUtils.native.js.map +1 -1
  69. package/dist/cjs/utils/money.cjs +137 -0
  70. package/dist/cjs/utils/money.native.js +165 -0
  71. package/dist/cjs/utils/money.native.js.map +1 -0
  72. package/dist/cjs/utils/rowAccumulator.cjs +48 -0
  73. package/dist/cjs/utils/rowAccumulator.native.js +51 -0
  74. package/dist/cjs/utils/rowAccumulator.native.js.map +1 -0
  75. package/dist/esm/components/ColumnHeaderFilter/index.mjs +78 -42
  76. package/dist/esm/components/ColumnHeaderFilter/index.mjs.map +1 -1
  77. package/dist/esm/components/ColumnHeaderFilter/index.native.js +101 -55
  78. package/dist/esm/components/ColumnHeaderFilter/index.native.js.map +1 -1
  79. package/dist/esm/components/DataTable/DataTableCardControls.mjs +0 -1
  80. package/dist/esm/components/DataTable/DataTableCardControls.mjs.map +1 -1
  81. package/dist/esm/components/DataTable/DataTableCardControls.native.js +0 -1
  82. package/dist/esm/components/DataTable/DataTableCardControls.native.js.map +1 -1
  83. package/dist/esm/components/DataTable/DataTableRoot.mjs +33 -6
  84. package/dist/esm/components/DataTable/DataTableRoot.mjs.map +1 -1
  85. package/dist/esm/components/DataTable/DataTableRoot.native.js +29 -4
  86. package/dist/esm/components/DataTable/DataTableRoot.native.js.map +1 -1
  87. package/dist/esm/components/DataTable/DataTableStateContext.mjs.map +1 -1
  88. package/dist/esm/components/DataTable/DataTableStateContext.native.js.map +1 -1
  89. package/dist/esm/components/DataTableBulkActions/index.mjs +0 -4
  90. package/dist/esm/components/DataTableBulkActions/index.mjs.map +1 -1
  91. package/dist/esm/components/DataTableBulkActions/index.native.js +0 -4
  92. package/dist/esm/components/DataTableBulkActions/index.native.js.map +1 -1
  93. package/dist/esm/components/DataTableCell/index.mjs +17 -2
  94. package/dist/esm/components/DataTableCell/index.mjs.map +1 -1
  95. package/dist/esm/components/DataTableCell/index.native.js +17 -2
  96. package/dist/esm/components/DataTableCell/index.native.js.map +1 -1
  97. package/dist/esm/components/DataTableDateFilter/index.mjs +0 -7
  98. package/dist/esm/components/DataTableDateFilter/index.mjs.map +1 -1
  99. package/dist/esm/components/DataTableDateFilter/index.native.js +0 -7
  100. package/dist/esm/components/DataTableDateFilter/index.native.js.map +1 -1
  101. package/dist/esm/components/DataTableFilterButton/index.mjs +0 -1
  102. package/dist/esm/components/DataTableFilterButton/index.mjs.map +1 -1
  103. package/dist/esm/components/DataTableFilterButton/index.native.js +0 -1
  104. package/dist/esm/components/DataTableFilterChips/FilterChip.mjs +3 -2
  105. package/dist/esm/components/DataTableFilterChips/FilterChip.mjs.map +1 -1
  106. package/dist/esm/components/DataTableFilterChips/FilterChip.native.js +5 -2
  107. package/dist/esm/components/DataTableFilterChips/FilterChip.native.js.map +1 -1
  108. package/dist/esm/components/DataTableFilters/index.mjs +0 -1
  109. package/dist/esm/components/DataTableFilters/index.mjs.map +1 -1
  110. package/dist/esm/components/DataTableFilters/index.native.js +0 -1
  111. package/dist/esm/components/DataTableGrouping/index.mjs +0 -8
  112. package/dist/esm/components/DataTableGrouping/index.mjs.map +1 -1
  113. package/dist/esm/components/DataTableGrouping/index.native.js +0 -8
  114. package/dist/esm/components/DataTableGrouping/index.native.js.map +1 -1
  115. package/dist/esm/components/DataTablePagination/index.mjs +30 -14
  116. package/dist/esm/components/DataTablePagination/index.mjs.map +1 -1
  117. package/dist/esm/components/DataTablePagination/index.native.js +31 -15
  118. package/dist/esm/components/DataTablePagination/index.native.js.map +1 -1
  119. package/dist/esm/components/DataTableSearch/index.mjs +0 -3
  120. package/dist/esm/components/DataTableSearch/index.mjs.map +1 -1
  121. package/dist/esm/components/DataTableSearch/index.native.js +0 -3
  122. package/dist/esm/components/DataTableSearch/index.native.js.map +1 -1
  123. package/dist/esm/components/DataTableToolbar/index.mjs +0 -1
  124. package/dist/esm/components/DataTableToolbar/index.mjs.map +1 -1
  125. package/dist/esm/components/DataTableToolbar/index.native.js +0 -1
  126. package/dist/esm/components/DataTableToolbar/index.native.js.map +1 -1
  127. package/dist/esm/components/DataTableViewOptions/index.mjs +0 -5
  128. package/dist/esm/components/DataTableViewOptions/index.mjs.map +1 -1
  129. package/dist/esm/components/DataTableViewOptions/index.native.js +0 -5
  130. package/dist/esm/components/DataTableViewOptions/index.native.js.map +1 -1
  131. package/dist/esm/components/FilterManager.mjs +0 -1
  132. package/dist/esm/components/FilterManager.mjs.map +1 -1
  133. package/dist/esm/components/FilterManager.native.js +0 -1
  134. package/dist/esm/components/FilterManager.native.js.map +1 -1
  135. package/dist/esm/components/FilterOperatorValueEditor/index.mjs +2 -2
  136. package/dist/esm/components/FilterOperatorValueEditor/index.mjs.map +1 -1
  137. package/dist/esm/components/FilterOperatorValueEditor/index.native.js +2 -2
  138. package/dist/esm/components/FilterOperatorValueEditor/index.native.js.map +1 -1
  139. package/dist/esm/components/TableInput/index.mjs +3 -2
  140. package/dist/esm/components/TableInput/index.mjs.map +1 -1
  141. package/dist/esm/components/TableInput/index.native.js +5 -3
  142. package/dist/esm/components/TableInput/index.native.js.map +1 -1
  143. package/dist/esm/hooks/useDataTable.mjs +24 -8
  144. package/dist/esm/hooks/useDataTable.mjs.map +1 -1
  145. package/dist/esm/hooks/useDataTable.native.js +28 -8
  146. package/dist/esm/hooks/useDataTable.native.js.map +1 -1
  147. package/dist/esm/index.mjs +3 -1
  148. package/dist/esm/index.mjs.map +1 -1
  149. package/dist/esm/index.native.js +3 -1
  150. package/dist/esm/index.native.js.map +1 -1
  151. package/dist/esm/shared/devWarn.mjs +43 -0
  152. package/dist/esm/shared/devWarn.mjs.map +1 -0
  153. package/dist/esm/shared/devWarn.native.js +54 -0
  154. package/dist/esm/shared/devWarn.native.js.map +1 -0
  155. package/dist/esm/utils/columnAlign.mjs +4 -1
  156. package/dist/esm/utils/columnAlign.mjs.map +1 -1
  157. package/dist/esm/utils/columnAlign.native.js +4 -1
  158. package/dist/esm/utils/columnAlign.native.js.map +1 -1
  159. package/dist/esm/utils/filterFields.mjs +5 -0
  160. package/dist/esm/utils/filterFields.mjs.map +1 -1
  161. package/dist/esm/utils/filterFields.native.js +5 -0
  162. package/dist/esm/utils/filterFields.native.js.map +1 -1
  163. package/dist/esm/utils/filterUtils.mjs +30 -0
  164. package/dist/esm/utils/filterUtils.mjs.map +1 -1
  165. package/dist/esm/utils/filterUtils.native.js +50 -0
  166. package/dist/esm/utils/filterUtils.native.js.map +1 -1
  167. package/dist/esm/utils/money.mjs +104 -0
  168. package/dist/esm/utils/money.mjs.map +1 -0
  169. package/dist/esm/utils/money.native.js +129 -0
  170. package/dist/esm/utils/money.native.js.map +1 -0
  171. package/dist/esm/utils/rowAccumulator.mjs +23 -0
  172. package/dist/esm/utils/rowAccumulator.mjs.map +1 -0
  173. package/dist/esm/utils/rowAccumulator.native.js +23 -0
  174. package/dist/esm/utils/rowAccumulator.native.js.map +1 -0
  175. package/dist/jsx/components/ColumnHeaderFilter/index.mjs +78 -42
  176. package/dist/jsx/components/ColumnHeaderFilter/index.mjs.map +1 -1
  177. package/dist/jsx/components/ColumnHeaderFilter/index.native.js +97 -51
  178. package/dist/jsx/components/ColumnHeaderFilter/index.native.js.map +1 -1
  179. package/dist/jsx/components/DataTable/DataTableCardControls.mjs +0 -1
  180. package/dist/jsx/components/DataTable/DataTableCardControls.mjs.map +1 -1
  181. package/dist/jsx/components/DataTable/DataTableCardControls.native.js +0 -1
  182. package/dist/jsx/components/DataTable/DataTableCardControls.native.js.map +1 -1
  183. package/dist/jsx/components/DataTable/DataTableRoot.mjs +33 -6
  184. package/dist/jsx/components/DataTable/DataTableRoot.mjs.map +1 -1
  185. package/dist/jsx/components/DataTable/DataTableRoot.native.js +29 -4
  186. package/dist/jsx/components/DataTable/DataTableRoot.native.js.map +1 -1
  187. package/dist/jsx/components/DataTable/DataTableStateContext.mjs.map +1 -1
  188. package/dist/jsx/components/DataTable/DataTableStateContext.native.js.map +1 -1
  189. package/dist/jsx/components/DataTableBulkActions/index.mjs +0 -4
  190. package/dist/jsx/components/DataTableBulkActions/index.mjs.map +1 -1
  191. package/dist/jsx/components/DataTableBulkActions/index.native.js +0 -4
  192. package/dist/jsx/components/DataTableBulkActions/index.native.js.map +1 -1
  193. package/dist/jsx/components/DataTableCell/index.mjs +17 -2
  194. package/dist/jsx/components/DataTableCell/index.mjs.map +1 -1
  195. package/dist/jsx/components/DataTableCell/index.native.js +16 -1
  196. package/dist/jsx/components/DataTableCell/index.native.js.map +1 -1
  197. package/dist/jsx/components/DataTableDateFilter/index.mjs +0 -7
  198. package/dist/jsx/components/DataTableDateFilter/index.mjs.map +1 -1
  199. package/dist/jsx/components/DataTableDateFilter/index.native.js +0 -7
  200. package/dist/jsx/components/DataTableDateFilter/index.native.js.map +1 -1
  201. package/dist/jsx/components/DataTableFilterButton/index.mjs +0 -1
  202. package/dist/jsx/components/DataTableFilterButton/index.mjs.map +1 -1
  203. package/dist/jsx/components/DataTableFilterButton/index.native.js +0 -1
  204. package/dist/jsx/components/DataTableFilterChips/FilterChip.mjs +3 -2
  205. package/dist/jsx/components/DataTableFilterChips/FilterChip.mjs.map +1 -1
  206. package/dist/jsx/components/DataTableFilterChips/FilterChip.native.js +4 -1
  207. package/dist/jsx/components/DataTableFilterChips/FilterChip.native.js.map +1 -1
  208. package/dist/jsx/components/DataTableFilters/index.mjs +0 -1
  209. package/dist/jsx/components/DataTableFilters/index.mjs.map +1 -1
  210. package/dist/jsx/components/DataTableFilters/index.native.js +0 -1
  211. package/dist/jsx/components/DataTableGrouping/index.mjs +0 -8
  212. package/dist/jsx/components/DataTableGrouping/index.mjs.map +1 -1
  213. package/dist/jsx/components/DataTableGrouping/index.native.js +0 -8
  214. package/dist/jsx/components/DataTableGrouping/index.native.js.map +1 -1
  215. package/dist/jsx/components/DataTablePagination/index.mjs +30 -14
  216. package/dist/jsx/components/DataTablePagination/index.mjs.map +1 -1
  217. package/dist/jsx/components/DataTablePagination/index.native.js +30 -14
  218. package/dist/jsx/components/DataTablePagination/index.native.js.map +1 -1
  219. package/dist/jsx/components/DataTableSearch/index.mjs +0 -3
  220. package/dist/jsx/components/DataTableSearch/index.mjs.map +1 -1
  221. package/dist/jsx/components/DataTableSearch/index.native.js +0 -3
  222. package/dist/jsx/components/DataTableSearch/index.native.js.map +1 -1
  223. package/dist/jsx/components/DataTableToolbar/index.mjs +0 -1
  224. package/dist/jsx/components/DataTableToolbar/index.mjs.map +1 -1
  225. package/dist/jsx/components/DataTableToolbar/index.native.js +0 -1
  226. package/dist/jsx/components/DataTableToolbar/index.native.js.map +1 -1
  227. package/dist/jsx/components/DataTableViewOptions/index.mjs +0 -5
  228. package/dist/jsx/components/DataTableViewOptions/index.mjs.map +1 -1
  229. package/dist/jsx/components/DataTableViewOptions/index.native.js +0 -5
  230. package/dist/jsx/components/DataTableViewOptions/index.native.js.map +1 -1
  231. package/dist/jsx/components/FilterManager.mjs +0 -1
  232. package/dist/jsx/components/FilterManager.mjs.map +1 -1
  233. package/dist/jsx/components/FilterManager.native.js +0 -1
  234. package/dist/jsx/components/FilterManager.native.js.map +1 -1
  235. package/dist/jsx/components/FilterOperatorValueEditor/index.mjs +2 -2
  236. package/dist/jsx/components/FilterOperatorValueEditor/index.mjs.map +1 -1
  237. package/dist/jsx/components/FilterOperatorValueEditor/index.native.js +2 -2
  238. package/dist/jsx/components/FilterOperatorValueEditor/index.native.js.map +1 -1
  239. package/dist/jsx/components/TableInput/index.mjs +3 -2
  240. package/dist/jsx/components/TableInput/index.mjs.map +1 -1
  241. package/dist/jsx/components/TableInput/index.native.js +4 -2
  242. package/dist/jsx/components/TableInput/index.native.js.map +1 -1
  243. package/dist/jsx/hooks/useDataTable.mjs +24 -8
  244. package/dist/jsx/hooks/useDataTable.mjs.map +1 -1
  245. package/dist/jsx/hooks/useDataTable.native.js +28 -8
  246. package/dist/jsx/hooks/useDataTable.native.js.map +1 -1
  247. package/dist/jsx/index.js +3 -1
  248. package/dist/jsx/index.js.map +1 -1
  249. package/dist/jsx/index.mjs +3 -1
  250. package/dist/jsx/index.mjs.map +1 -1
  251. package/dist/jsx/index.native.js +12 -0
  252. package/dist/jsx/index.native.js.map +1 -1
  253. package/dist/jsx/shared/devWarn.mjs +43 -0
  254. package/dist/jsx/shared/devWarn.mjs.map +1 -0
  255. package/dist/jsx/shared/devWarn.native.js +84 -0
  256. package/dist/jsx/shared/devWarn.native.js.map +1 -0
  257. package/dist/jsx/utils/columnAlign.mjs +4 -1
  258. package/dist/jsx/utils/columnAlign.mjs.map +1 -1
  259. package/dist/jsx/utils/columnAlign.native.js +4 -1
  260. package/dist/jsx/utils/columnAlign.native.js.map +1 -1
  261. package/dist/jsx/utils/filterFields.mjs +5 -0
  262. package/dist/jsx/utils/filterFields.mjs.map +1 -1
  263. package/dist/jsx/utils/filterFields.native.js +5 -0
  264. package/dist/jsx/utils/filterFields.native.js.map +1 -1
  265. package/dist/jsx/utils/filterUtils.mjs +30 -0
  266. package/dist/jsx/utils/filterUtils.mjs.map +1 -1
  267. package/dist/jsx/utils/filterUtils.native.js +50 -0
  268. package/dist/jsx/utils/filterUtils.native.js.map +1 -1
  269. package/dist/jsx/utils/money.mjs +104 -0
  270. package/dist/jsx/utils/money.mjs.map +1 -0
  271. package/dist/jsx/utils/money.native.js +165 -0
  272. package/dist/jsx/utils/money.native.js.map +1 -0
  273. package/dist/jsx/utils/rowAccumulator.mjs +23 -0
  274. package/dist/jsx/utils/rowAccumulator.mjs.map +1 -0
  275. package/dist/jsx/utils/rowAccumulator.native.js +51 -0
  276. package/dist/jsx/utils/rowAccumulator.native.js.map +1 -0
  277. package/package.json +12 -12
  278. package/src/components/ColumnHeaderFilter/ColumnHeaderFilter.spec.tsx +142 -7
  279. package/src/components/ColumnHeaderFilter/ColumnHeaderFilter.stories.tsx +46 -9
  280. package/src/components/ColumnHeaderFilter/index.tsx +104 -47
  281. package/src/components/DataTable/DataTable.stories.tsx +186 -14
  282. package/src/components/DataTable/DataTableCardControls.tsx +11 -13
  283. package/src/components/DataTable/DataTableRoot.tsx +40 -14
  284. package/src/components/DataTable/DataTableStateContext.ts +7 -0
  285. package/src/components/DataTable/columnWidthLayout.spec.tsx +195 -0
  286. package/src/components/DataTable/headerSorting.spec.tsx +25 -0
  287. package/src/components/DataTable/moneyColumn.spec.tsx +151 -0
  288. package/src/components/DataTable/rowAccumulator.spec.tsx +171 -0
  289. package/src/components/DataTableBulkActions/index.tsx +0 -4
  290. package/src/components/DataTableCell/index.tsx +28 -2
  291. package/src/components/DataTableColumnPinning/DataTableColumnPinning.stories.tsx +0 -4
  292. package/src/components/DataTableDateFilter/index.tsx +0 -7
  293. package/src/components/DataTableFilterButton/index.tsx +1 -1
  294. package/src/components/DataTableFilterChips/FilterChip.spec.tsx +6 -0
  295. package/src/components/DataTableFilterChips/FilterChip.tsx +3 -2
  296. package/src/components/DataTableFilters/index.tsx +1 -1
  297. package/src/components/DataTableGrouping/DataTableGrouping.stories.tsx +0 -4
  298. package/src/components/DataTableGrouping/index.tsx +1 -13
  299. package/src/components/DataTablePagination/DataTablePagination.stories.tsx +14 -1
  300. package/src/components/DataTablePagination/DataTablePagination.width.spec.tsx +51 -0
  301. package/src/components/DataTablePagination/index.tsx +60 -16
  302. package/src/components/DataTableSearch/index.tsx +2 -3
  303. package/src/components/DataTableToolbar/DataTableToolbar.stories.tsx +2 -4
  304. package/src/components/DataTableToolbar/index.tsx +1 -5
  305. package/src/components/DataTableViewOptions/index.tsx +2 -13
  306. package/src/components/FilterManager.tsx +1 -3
  307. package/src/components/FilterOperatorValueEditor/FilterOperatorValueEditor.spec.tsx +1 -1
  308. package/src/components/FilterOperatorValueEditor/FilterOperatorValueEditor.stories.tsx +1 -0
  309. package/src/components/FilterOperatorValueEditor/index.tsx +10 -2
  310. package/src/components/TableInput/index.native.tsx +3 -2
  311. package/src/components/TableInput/index.tsx +3 -2
  312. package/src/hooks/useDataTable.ts +43 -7
  313. package/src/index.ts +13 -0
  314. package/src/shared/devWarn.ts +97 -0
  315. package/src/types.ts +71 -2
  316. package/src/utils/columnAlign.ts +9 -1
  317. package/src/utils/filterFields.ts +23 -1
  318. package/src/utils/filterUtils.ts +50 -1
  319. package/src/utils/money.spec.ts +156 -0
  320. package/src/utils/money.ts +202 -0
  321. package/src/utils/rowAccumulator.ts +136 -0
  322. package/types/components/ColumnHeaderFilter/index.d.ts +9 -2
  323. package/types/components/ColumnHeaderFilter/index.d.ts.map +1 -1
  324. package/types/components/DataTable/DataTableCardControls.d.ts.map +1 -1
  325. package/types/components/DataTable/DataTableRoot.d.ts +1 -1
  326. package/types/components/DataTable/DataTableRoot.d.ts.map +1 -1
  327. package/types/components/DataTable/DataTableStateContext.d.ts +7 -0
  328. package/types/components/DataTable/DataTableStateContext.d.ts.map +1 -1
  329. package/types/components/DataTableBulkActions/index.d.ts.map +1 -1
  330. package/types/components/DataTableCell/index.d.ts.map +1 -1
  331. package/types/components/DataTableDateFilter/index.d.ts.map +1 -1
  332. package/types/components/DataTableFilterChips/FilterChip.d.ts.map +1 -1
  333. package/types/components/DataTableGrouping/index.d.ts.map +1 -1
  334. package/types/components/DataTablePagination/index.d.ts.map +1 -1
  335. package/types/components/DataTableSearch/index.d.ts.map +1 -1
  336. package/types/components/DataTableToolbar/index.d.ts.map +1 -1
  337. package/types/components/DataTableViewOptions/index.d.ts.map +1 -1
  338. package/types/components/FilterManager.d.ts.map +1 -1
  339. package/types/components/FilterOperatorValueEditor/index.d.ts.map +1 -1
  340. package/types/components/TableInput/index.d.ts.map +1 -1
  341. package/types/components/TableInput/index.native.d.ts.map +1 -1
  342. package/types/hooks/useDataTable.d.ts +1 -1
  343. package/types/hooks/useDataTable.d.ts.map +1 -1
  344. package/types/index.d.ts +3 -0
  345. package/types/index.d.ts.map +1 -1
  346. package/types/shared/devWarn.d.ts +50 -0
  347. package/types/shared/devWarn.d.ts.map +1 -0
  348. package/types/types.d.ts +71 -3
  349. package/types/types.d.ts.map +1 -1
  350. package/types/utils/columnAlign.d.ts.map +1 -1
  351. package/types/utils/filterFields.d.ts.map +1 -1
  352. package/types/utils/filterUtils.d.ts +1 -1
  353. package/types/utils/filterUtils.d.ts.map +1 -1
  354. package/types/utils/money.d.ts +94 -0
  355. package/types/utils/money.d.ts.map +1 -0
  356. package/types/utils/rowAccumulator.d.ts +107 -0
  357. package/types/utils/rowAccumulator.d.ts.map +1 -0
@@ -6,21 +6,30 @@
6
6
  import { FunnelIcon } from "@phosphor-icons/react";
7
7
  import { Button } from "@multiplatform.one/forms";
8
8
  import {
9
+ ensureCompositeFocusRing,
9
10
  MIN_PRESS_TARGET,
10
11
  pressTargetHitSlop,
11
12
  pressTargetStyle,
13
+ useAccentOnSurface,
12
14
  useResolvedKnobs,
15
+ useGlyphColor,
13
16
  } from "@multiplatform.one/theme";
14
- import { useState } from "react";
17
+ import { useId, useRef, useState } from "react";
15
18
  import { Tooltip } from "@multiplatform.one/components";
16
- import { Popover, Text, View, XStack, YStack } from "tamagui";
19
+ import { Popover, Text, View, XStack, YStack, isWeb, type TamaguiElement } from "tamagui";
17
20
  import { t } from "../../shared/t";
18
- import type { FilterOperator } from "../../types";
21
+ import type { DataTableColumnType, FilterOperator } from "../../types";
19
22
  import { iconSizeForToken } from "../../utils/chromeIcons";
20
- import { operatorNeedsNoValue } from "../../utils/filterFields";
23
+ import { defaultOperatorForFilterType, operatorNeedsNoValue } from "../../utils/filterFields";
21
24
  import { FilterOperatorValueEditor } from "../FilterOperatorValueEditor";
22
25
 
23
- export type ColumnFilterType = "text" | "number" | "date" | "boolean" | "select";
26
+ /**
27
+ * The funnel's column type IS the table's column type — one vocabulary, not a
28
+ * second copy (LC-16). Kept as a named alias because consumers import it.
29
+ * Adding `"money"` to DataTableColumnType therefore reaches the funnel too
30
+ * (MPO-252).
31
+ */
32
+ export type ColumnFilterType = DataTableColumnType;
24
33
 
25
34
  export interface ColumnHeaderFilterProps {
26
35
  columnId: string;
@@ -49,17 +58,38 @@ export function ColumnHeaderFilter({
49
58
  columnId: _columnId,
50
59
  columnLabel,
51
60
  columnType,
52
- filterValue: _filterValue,
61
+ filterValue,
53
62
  onFilterChange,
54
63
  options,
55
64
  isFiltered,
56
65
  }: ColumnHeaderFilterProps) {
57
66
  const { knobProps } = useResolvedKnobs();
67
+ const idleColor = useGlyphColor("$color11");
68
+ const activeColor = useAccentOnSurface();
69
+ const glyphColor = isFiltered ? activeColor : idleColor;
70
+ // The nested Tooltip has its own Popper context. Keep this trigger and
71
+ // editor anchored to the same instance rather than its nearest overlay.
72
+ const popoverScope = useId();
73
+ const triggerRef = useRef<TamaguiElement | null>(null);
74
+ const returnFocusRef = useRef(true);
75
+ ensureCompositeFocusRing();
58
76
  const iconPx = iconSizeForToken(String(knobProps.sizeToken));
59
77
  const [open, setOpen] = useState(false);
60
- const [operator, setOperator] = useState<FilterOperator>("contains");
78
+ const [operator, setOperator] = useState<FilterOperator>(() =>
79
+ defaultOperatorForFilterType(columnType),
80
+ );
61
81
  const [value, setValue] = useState<string>("");
62
82
 
83
+ const handleOpenChange = (next: boolean) => {
84
+ // Reopening reads the applied filter. External updates while editing
85
+ // leave the current draft alone, including the stay-open Clear flow.
86
+ if (next && !open) {
87
+ setOperator(filterValue?.operator ?? defaultOperatorForFilterType(columnType));
88
+ setValue(filterValue?.value == null ? "" : String(filterValue.value));
89
+ }
90
+ setOpen(next);
91
+ };
92
+
63
93
  // Apply is the explicit done affordance of this draft editor — commit-and-
64
94
  // close is its stated intent (LC-21 allows an explicit done/close control).
65
95
  const handleApply = () => {
@@ -76,58 +106,85 @@ export function ColumnHeaderFilter({
76
106
  // filter; outside click / Escape / Apply close.
77
107
  const handleClear = () => {
78
108
  setValue("");
79
- setOperator("contains");
109
+ setOperator(defaultOperatorForFilterType(columnType));
80
110
  onFilterChange(undefined);
81
111
  };
82
112
 
83
113
  return (
84
- <Popover open={open} onOpenChange={setOpen}>
85
- <Tooltip content={isFiltered ? t("Edit filter") : t("Filter this column")}>
86
- <Popover.Trigger asChild>
87
- {/* LC-54 amendment (2026-08-13): the grown press target NEVER
114
+ <Popover scope={popoverScope} open={open} onOpenChange={handleOpenChange} disableFocus>
115
+ {/* Inherit the nearest Popover before entering Tooltip. An explicit
116
+ scope makes Tamagui register web anchors only on mouse hover,
117
+ leaving keyboard opens without a reference. */}
118
+ <Popover.Anchor>
119
+ <Tooltip content={isFiltered ? t("Edit filter") : t("Filter this column")}>
120
+ <Popover.Trigger scope={popoverScope} asChild>
121
+ {/* LC-54 amendment (2026-08-13): the grown press target NEVER
88
122
  paints — hover/press fills on this box spread across the full
89
123
  44px floor and bled into the neighboring header rows via the
90
- negative outsets. Floor-wide feedback is subtree opacity; the
91
- painted hover chrome rides the glyph-scale ring inside
124
+ negative outsets. Painted hover and keyboard focus feedback
125
+ ride the glyph-scale ring inside
92
126
  (Chip dismiss anatomy). */}
93
- <View
94
- cursor="pointer"
95
- {...pressTargetStyle()}
96
- alignItems="center"
97
- justifyContent="center"
98
- marginVertical={-FILTER_TRIGGER_OUTSET}
99
- marginHorizontal={-FILTER_TRIGGER_OUTSET}
100
- hitSlop={pressTargetHitSlop(FILTER_TRIGGER_VISUAL)}
101
- // Axiom 6 HONEST STATE: an applied filter is an active signal —
102
- // it keeps full strength; only the idle affordance rests dimmed.
103
- opacity={isFiltered ? 1 : 0.7}
104
- hoverStyle={{ opacity: 1 }}
105
- pressStyle={{ opacity: 0.9 }}
106
- onPress={(e) => {
107
- e.stopPropagation();
108
- setOpen(true);
109
- }}
110
- role="button"
111
- aria-label={`Filter column ${columnLabel}`}
112
- >
113
127
  <View
114
- padding="$1"
115
- borderRadius="$2"
128
+ ref={triggerRef}
129
+ cursor="pointer"
130
+ {...pressTargetStyle()}
116
131
  alignItems="center"
117
132
  justifyContent="center"
118
- hoverStyle={{ backgroundColor: "$color4" }}
133
+ marginVertical={-FILTER_TRIGGER_OUTSET}
134
+ marginHorizontal={-FILTER_TRIGGER_OUTSET}
135
+ hitSlop={pressTargetHitSlop(FILTER_TRIGGER_VISUAL)}
136
+ // Enabled glyphs keep readable ink; hue and weight distinguish
137
+ // an applied filter from the secondary-color idle affordance.
138
+ // Shared unpainted press-floor / painted glyph-ring anatomy.
139
+ className="mp-chip-dismiss"
140
+ tabIndex={0}
141
+ onKeyDown={
142
+ ((event: { key?: string; preventDefault(): void; stopPropagation(): void }) => {
143
+ if (event.key !== "Enter" && event.key !== " ") return;
144
+ event.preventDefault();
145
+ event.stopPropagation();
146
+ handleOpenChange(true);
147
+ }) as unknown as () => void
148
+ }
149
+ onPress={(e) => {
150
+ e.stopPropagation();
151
+ handleOpenChange(true);
152
+ }}
153
+ role="button"
154
+ aria-label={`Filter column ${columnLabel}`}
119
155
  >
120
- <FunnelIcon
121
- size={iconPx}
122
- color={isFiltered ? "var(--accentColor)" : "var(--color10)"}
123
- weight={isFiltered ? "fill" : "regular"}
124
- />
156
+ <View
157
+ className="mp-chip-dismiss-ring"
158
+ padding="$1"
159
+ borderRadius="$2"
160
+ alignItems="center"
161
+ justifyContent="center"
162
+ hoverStyle={{ backgroundColor: "$color4" }}
163
+ pressStyle={{ backgroundColor: "$color5" }}
164
+ >
165
+ <FunnelIcon
166
+ size={iconPx}
167
+ color={glyphColor}
168
+ weight={isFiltered ? "fill" : "regular"}
169
+ />
170
+ </View>
125
171
  </View>
126
- </View>
127
- </Popover.Trigger>
128
- </Tooltip>
172
+ </Popover.Trigger>
173
+ </Tooltip>
174
+ </Popover.Anchor>
129
175
 
130
176
  <Popover.Content
177
+ scope={popoverScope}
178
+ onPointerDownOutside={() => {
179
+ returnFocusRef.current = false;
180
+ }}
181
+ onCloseAutoFocus={(event) => {
182
+ event.preventDefault();
183
+ if (isWeb && returnFocusRef.current) {
184
+ (triggerRef.current as HTMLElement | null)?.focus();
185
+ }
186
+ returnFocusRef.current = true;
187
+ }}
131
188
  {...knobProps.elevatedSurface}
132
189
  {...knobProps.panelPadding}
133
190
  minWidth={240}
@@ -135,7 +192,7 @@ export function ColumnHeaderFilter({
135
192
  enterStyle={{ y: -5, opacity: 0 }}
136
193
  exitStyle={{ y: -5, opacity: 0 }}
137
194
  >
138
- <Popover.Arrow borderColor="$borderColor" backgroundColor="$color1" />
195
+ <Popover.Arrow scope={popoverScope} borderColor="$borderColor" backgroundColor="$color1" />
139
196
 
140
197
  <YStack {...knobProps.gap}>
141
198
  <Text {...knobProps.label} fontWeight="400" color="$color11">
@@ -155,7 +212,7 @@ export function ColumnHeaderFilter({
155
212
  {/* Actions */}
156
213
  <XStack {...knobProps.gap} justifyContent="flex-end">
157
214
  {isFiltered && (
158
- <Button size={knobProps.sizeToken} variant="outlined" onPress={handleClear}>
215
+ <Button size={knobProps.sizeToken} onPress={handleClear}>
159
216
  {t("Clear")}
160
217
  </Button>
161
218
  )}
@@ -16,8 +16,11 @@ import {
16
16
  DataTableFilters,
17
17
  DataTablePagination,
18
18
  DataTableToolbar,
19
+ formatMoney,
20
+ type RowAccumulator,
21
+ sumMoneyByCurrency,
19
22
  } from "../../index";
20
- import { DataTable } from "./index";
23
+ import { DataTable, useDataTableState } from "./index";
21
24
 
22
25
  const meta: Meta<typeof DataTable> = {
23
26
  title: "Table/DataTable",
@@ -204,11 +207,7 @@ const columns: DataTableColumn<User>[] = [
204
207
  columnHelper.display({
205
208
  id: "actions",
206
209
  header: "Actions",
207
- cell: (_info) => (
208
- <Button size="$2" variant="outlined">
209
- Edit
210
- </Button>
211
- ),
210
+ cell: (_info) => <Button size="$2">Edit</Button>,
212
211
  enableSorting: false,
213
212
  enableColumnFilter: false,
214
213
  }) as DataTableColumn<User>,
@@ -321,14 +320,7 @@ const AdvancedTableStory = () => {
321
320
  enableGlobalSearch={true}
322
321
  enableViews={true}
323
322
  renderToolbar={(props) => (
324
- <DataTableToolbar
325
- {...props}
326
- customActions={
327
- <Button size="$3" variant="outlined">
328
- Export CSV
329
- </Button>
330
- }
331
- />
323
+ <DataTableToolbar {...props} customActions={<Button size="$3">Export CSV</Button>} />
332
324
  )}
333
325
  renderFilters={(props) => (
334
326
  <DataTableFilters {...props} availableColumns={columnsWithCounts} maxFilters={5} />
@@ -3090,3 +3082,183 @@ export const CustomCellAlignment: Story = {
3090
3082
  },
3091
3083
  },
3092
3084
  };
3085
+
3086
+ // ---------------------------------------------------------------------------
3087
+ // Running balance (MPO-250) — a column that is a function of every row before
3088
+ // it. The fold runs BEFORE pagination, so page two continues instead of
3089
+ // restarting at zero, and its final value paints a footer total.
3090
+ // ---------------------------------------------------------------------------
3091
+
3092
+ interface Posting extends DataTableData {
3093
+ id: string;
3094
+ date: string;
3095
+ payee: string;
3096
+ /** Cents. Integers here; a real ledger uses the "money" column type. */
3097
+ amount: number;
3098
+ /** Derived by the accumulator — declared so a column can name it. */
3099
+ running?: number;
3100
+ }
3101
+
3102
+ const registerPostings: Posting[] = [
3103
+ { id: "P-01", date: "2026-01-02", payee: "Opening deposit", amount: 250_000 },
3104
+ { id: "P-02", date: "2026-01-04", payee: "Rent", amount: -180_000 },
3105
+ { id: "P-03", date: "2026-01-05", payee: "Grocers", amount: -8_450 },
3106
+ { id: "P-04", date: "2026-01-07", payee: "Payroll", amount: 412_300 },
3107
+ { id: "P-05", date: "2026-01-09", payee: "Utilities", amount: -14_600 },
3108
+ { id: "P-06", date: "2026-01-11", payee: "Coffee roaster", amount: -1_875 },
3109
+ { id: "P-07", date: "2026-01-14", payee: "Refund", amount: 3_200 },
3110
+ { id: "P-08", date: "2026-01-16", payee: "Insurance", amount: -62_000 },
3111
+ { id: "P-09", date: "2026-01-19", payee: "Consulting", amount: 150_000 },
3112
+ { id: "P-10", date: "2026-01-21", payee: "Hardware", amount: -47_990 },
3113
+ { id: "P-11", date: "2026-01-24", payee: "Payroll", amount: 412_300 },
3114
+ { id: "P-12", date: "2026-01-27", payee: "Taxes", amount: -305_000 },
3115
+ ];
3116
+
3117
+ const cents = (value: number | undefined) =>
3118
+ value == null ? "" : formatCurrency(value / 100, { symbol: "$", fractionDigits: "auto" });
3119
+
3120
+ /**
3121
+ * The fold. A module constant, not an inline literal — the table refolds
3122
+ * whenever this identity changes.
3123
+ */
3124
+ const registerBalance: RowAccumulator<Posting, number> = {
3125
+ initial: 0,
3126
+ reduce: (carried, row) => carried + row.amount,
3127
+ derive: (carried) => ({ running: carried }),
3128
+ order: (a, b) => (a.date < b.date ? -1 : a.date > b.date ? 1 : 0),
3129
+ total: (carried) => carried,
3130
+ };
3131
+
3132
+ /** Reads the fold's end value off the table state — the total row. */
3133
+ const RegisterTotal = () => {
3134
+ const context = useDataTableState();
3135
+ return <Text fontWeight="700">{cents(context?.computed.foldTotal as number | undefined)}</Text>;
3136
+ };
3137
+
3138
+ const registerColumns: DataTableColumn<Posting>[] = [
3139
+ { id: "date", accessorKey: "date", header: "Date", width: 120 },
3140
+ { id: "payee", accessorKey: "payee", header: "Payee", sortable: true },
3141
+ {
3142
+ id: "amount",
3143
+ accessorKey: "amount",
3144
+ header: "Amount",
3145
+ align: "right",
3146
+ cell: (info) => <Text>{cents(info.getValue() as number)}</Text>,
3147
+ footer: () => <Text fontWeight="700">Total</Text>,
3148
+ },
3149
+ {
3150
+ id: "running",
3151
+ accessorKey: "running",
3152
+ header: "Balance",
3153
+ align: "right",
3154
+ // Not sortable on purpose: sorting a fold column reorders it WITHOUT
3155
+ // refolding, so the figures stop reading down the column as a
3156
+ // progression. The contract is on RowAccumulator.
3157
+ sortable: false,
3158
+ cell: (info) => <Text fontWeight="600">{cents(info.getValue() as number)}</Text>,
3159
+ footer: () => <RegisterTotal />,
3160
+ },
3161
+ ];
3162
+
3163
+ export const RunningBalance: Story = {
3164
+ render: () => (
3165
+ <DataTable
3166
+ data={registerPostings}
3167
+ columns={registerColumns as DataTableColumn<Record<string, any>>[]}
3168
+ rowAccumulator={registerBalance as RowAccumulator<Record<string, any>>}
3169
+ layout="table"
3170
+ columnLayout="auto"
3171
+ enableFiltering={false}
3172
+ enableGlobalSearch={false}
3173
+ initialState={{ pagination: { pageIndex: 0, pageSize: 5 } }}
3174
+ aria-label="Account register with a running balance"
3175
+ />
3176
+ ),
3177
+ parameters: {
3178
+ docs: {
3179
+ description: {
3180
+ story:
3181
+ "A running balance is a FOLD over the rows in a total order, so it has to be computed before the table paginates. Page through this table: the Balance column continues onto page two rather than restarting, because `rowAccumulator` runs once over the whole row set before the row model. Its `total` is read once at the end and painted in the footer through `useDataTableState().computed.foldTotal`. Sorting on Payee reorders rows for display and does NOT refold — the balance stays attached to its own row.",
3182
+ },
3183
+ },
3184
+ },
3185
+ };
3186
+
3187
+ // ---------------------------------------------------------------------------
3188
+ // Money column (MPO-252) — a Currency field is a decimal STRING. It sorts
3189
+ // numerically, filters with the numeric operators, formats from the ROW's own
3190
+ // currency, and totals per currency because two currencies never convert.
3191
+ // ---------------------------------------------------------------------------
3192
+
3193
+ interface Charge extends DataTableData {
3194
+ id: string;
3195
+ vendor: string;
3196
+ amount: string;
3197
+ currency: string;
3198
+ }
3199
+
3200
+ const charges: Charge[] = [
3201
+ { id: "C-1", vendor: "Coffee roaster", amount: "9.00", currency: "USD" },
3202
+ { id: "C-2", vendor: "Bookshop", amount: "10.00", currency: "USD" },
3203
+ { id: "C-3", vendor: "Chai stall", amount: "250.75", currency: "INR" },
3204
+ { id: "C-4", vendor: "Refund", amount: "-455.87", currency: "USD" },
3205
+ { id: "C-5", vendor: "Hosting", amount: "1200.00", currency: "INR" },
3206
+ { id: "C-6", vendor: "Domain", amount: "9.99", currency: "USD" },
3207
+ ];
3208
+
3209
+ /** One figure per currency — the mixed-currency rule, rendered. */
3210
+ const ChargeTotals = () => {
3211
+ const totals = sumMoneyByCurrency(
3212
+ charges,
3213
+ (row) => row.amount,
3214
+ (row) => row.currency,
3215
+ );
3216
+ return (
3217
+ <YStack>
3218
+ {Object.entries(totals).map(([code, total]) => (
3219
+ <Text key={code} fontWeight="700">
3220
+ {formatMoney(total, code)}
3221
+ </Text>
3222
+ ))}
3223
+ </YStack>
3224
+ );
3225
+ };
3226
+
3227
+ const chargeColumns: DataTableColumn<Charge>[] = [
3228
+ { id: "vendor", accessorKey: "vendor", header: "Vendor" },
3229
+ { id: "currency", accessorKey: "currency", header: "Currency" },
3230
+ {
3231
+ id: "amount",
3232
+ accessorKey: "amount",
3233
+ header: "Amount",
3234
+ field: "money",
3235
+ // Safe now: the money type carries an exact decimal comparator, so
3236
+ // "9.00" sorts BELOW "10.00". As a "text" column this was silently wrong.
3237
+ sortable: true,
3238
+ filterable: true,
3239
+ fieldProps: { currencyField: "currency" },
3240
+ footer: () => <ChargeTotals />,
3241
+ },
3242
+ ];
3243
+
3244
+ export const MoneyColumn: Story = {
3245
+ render: () => (
3246
+ <DataTable
3247
+ data={charges}
3248
+ columns={chargeColumns as DataTableColumn<Record<string, any>>[]}
3249
+ layout="table"
3250
+ columnLayout="auto"
3251
+ enablePagination={false}
3252
+ readOnly
3253
+ aria-label="Charges with a money column"
3254
+ />
3255
+ ),
3256
+ parameters: {
3257
+ docs: {
3258
+ description: {
3259
+ story:
3260
+ '`field: "money"` types a column as a decimal STRING rather than as text. Sort on Amount: `9.00` orders below `10.00`, which the text fallback got backwards in silence. The column filter offers `is less than` / `is greater than` / `between` instead of `contains`. Each row formats in its OWN currency (`fieldProps.currencyField`), and the footer totals PER currency — two currencies are two figures and neither converts, because there is no rate in the table.',
3261
+ },
3262
+ },
3263
+ },
3264
+ };
@@ -89,7 +89,6 @@ export function DataTableCardControls({
89
89
  <DropdownMenu.Trigger asChild>
90
90
  <Button
91
91
  size={knobProps.sizeToken}
92
- variant="outlined"
93
92
  icon={<CaretUpDownIcon size={chrome.iconPx} />}
94
93
  aria-label={t("Sort rows")}
95
94
  disabled={disabled}
@@ -134,18 +133,17 @@ export function DataTableCardControls({
134
133
  </DropdownMenu.Content>
135
134
  </DropdownMenu>
136
135
  )}
137
- {enableFiltering &&
138
- availableColumns.length > 0 && (
139
- // DataTableFilters (chrome) has no disabled API — the wrapper is the
140
- // LC-40 carrier and interaction gate for the disabled table.
141
- <View
142
- {...(disabled
143
- ? { ...disabledState.chromeKnobProps, pointerEvents: "none" as const }
144
- : {})}
145
- >
146
- <DataTableFilters compact availableColumns={availableColumns} />
147
- </View>
148
- )}
136
+ {enableFiltering && availableColumns.length > 0 && (
137
+ // DataTableFilters (chrome) has no disabled API — the wrapper is the
138
+ // LC-40 carrier and interaction gate for the disabled table.
139
+ <View
140
+ {...(disabled
141
+ ? { ...disabledState.chromeKnobProps, pointerEvents: "none" as const }
142
+ : {})}
143
+ >
144
+ <DataTableFilters compact availableColumns={availableColumns} />
145
+ </View>
146
+ )}
149
147
  </XStack>
150
148
  );
151
149
  }
@@ -62,6 +62,7 @@ import { DataTableDocumentList } from "./DataTableDocumentList";
62
62
  import { DataTableVirtualized } from "./DataTableVirtualized";
63
63
  import { dataTableChrome, resolveDataTableIntent, rowIntentProps } from "./dataTableChrome";
64
64
  import { tableCellKeyboardProps, tableRowStateProps } from "./rowStateChrome";
65
+ import { warnColumnWidthIgnored } from "../../shared/devWarn";
65
66
  import { alignToFlex, getDefaultColumnAlign } from "../../utils/columnAlign";
66
67
  import { mapFieldToFilterType } from "../../utils/filterFields";
67
68
  import { INFINITE_TRIGGER_ROWS } from "../../utils/paginationDefaults";
@@ -125,6 +126,7 @@ export function DataTableRoot<TData extends Record<string, any> = Record<string,
125
126
  pageSizeOptions,
126
127
  paginationMode = "pages",
127
128
  loadPage,
129
+ rowAccumulator,
128
130
  enableColumnVisibility = true,
129
131
  enableColumnOrdering = false,
130
132
  enableColumnResizing = false,
@@ -176,6 +178,7 @@ export function DataTableRoot<TData extends Record<string, any> = Record<string,
176
178
  "aria-describedby": ariaDescribedBy,
177
179
  ...props
178
180
  }: DataTableRootProps<TData>) {
181
+ warnColumnWidthIgnored({ columnLayout, enableColumnResizing, columns });
179
182
  const { t } = useTranslation();
180
183
  const { sm } = useMedia();
181
184
  // Resolved responsive layout: cards below `$sm` (W11 compact class) unless
@@ -224,6 +227,7 @@ export function DataTableRoot<TData extends Record<string, any> = Record<string,
224
227
  enablePagination,
225
228
  paginationMode,
226
229
  loadPage,
230
+ rowAccumulator,
227
231
  enableColumnVisibility,
228
232
  enableColumnOrdering,
229
233
  enableColumnResizing,
@@ -1670,22 +1674,21 @@ export function DataTableRoot<TData extends Record<string, any> = Record<string,
1670
1674
  {sortDirection === "asc" && (
1671
1675
  <CaretDownIcon
1672
1676
  size={chrome.iconPx}
1673
- color={
1674
- sortDirection ? "var(--color10)" : "var(--color8)"
1675
- }
1677
+ color="var(--color11)"
1676
1678
  />
1677
1679
  )}
1678
1680
  {sortDirection === "desc" && (
1679
1681
  <CaretDownIcon
1680
1682
  size={chrome.iconPx}
1681
- color={
1682
- sortDirection ? "var(--color10)" : "var(--color8)"
1683
- }
1683
+ color="var(--color11)"
1684
1684
  style={{ transform: "rotate(180deg)" }}
1685
1685
  />
1686
1686
  )}
1687
1687
  {sortDirection === false && (
1688
- <CaretUpDownIcon size={chrome.iconPx} color="$color8" />
1688
+ <CaretUpDownIcon
1689
+ size={chrome.iconPx}
1690
+ color="var(--color11)"
1691
+ />
1689
1692
  )}
1690
1693
  </View>
1691
1694
  </Tooltip>
@@ -2082,13 +2085,36 @@ export function DataTableRoot<TData extends Record<string, any> = Record<string,
2082
2085
  <Table.Foot>
2083
2086
  {footerGroups.map((footerGroup: any) => (
2084
2087
  <Table.Row key={footerGroup.id}>
2085
- {footerGroup.headers.map((header: any) => (
2086
- <Table.Cell key={header.id}>
2087
- {header.isPlaceholder
2088
- ? null
2089
- : flexRender(header.column.columnDef.footer, header.getContext())}
2090
- </Table.Cell>
2091
- ))}
2088
+ {footerGroup.headers.map((header: any) => {
2089
+ const columnAlign = resolveColumnAlign({
2090
+ ...(header.column.columnDef as DataTableColumn),
2091
+ id: header.column.id,
2092
+ });
2093
+ return (
2094
+ <Table.Cell
2095
+ key={header.id}
2096
+ justifyContent={alignToFlex(columnAlign)}
2097
+ data-align={columnAlign}
2098
+ >
2099
+ {header.isPlaceholder ? null : (
2100
+ <View
2101
+ width="100%"
2102
+ minWidth={0}
2103
+ flexDirection="row"
2104
+ alignItems="center"
2105
+ justifyContent={alignToFlex(columnAlign)}
2106
+ data-cell-align={columnAlign}
2107
+ style={isWeb ? { textAlign: columnAlign } : undefined}
2108
+ >
2109
+ {flexRender(
2110
+ header.column.columnDef.footer,
2111
+ header.getContext(),
2112
+ )}
2113
+ </View>
2114
+ )}
2115
+ </Table.Cell>
2116
+ );
2117
+ })}
2092
2118
  </Table.Row>
2093
2119
  ))}
2094
2120
  </Table.Foot>
@@ -62,6 +62,13 @@ export interface DataTableStateContextValue<TData = any> {
62
62
  totalRows: number;
63
63
  hasActiveFilters: boolean;
64
64
  activeFilterCount: number;
65
+ /**
66
+ * The row accumulator's `total(finalAccumulator, rowCount)` — the fold
67
+ * read once at the end (MPO-250). A column's TanStack `footer` renderer
68
+ * reads it from here to paint a total row; the table already renders a
69
+ * footer whenever any column defines one.
70
+ */
71
+ foldTotal?: unknown;
65
72
  [key: string]: any;
66
73
  };
67
74
  }