@multiplatform.one/table 7.7.4 → 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 (359) 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 +51 -15
  31. package/dist/cjs/components/DataTablePagination/index.native.js +54 -16
  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 +54 -18
  116. package/dist/esm/components/DataTablePagination/index.mjs.map +1 -1
  117. package/dist/esm/components/DataTablePagination/index.native.js +57 -19
  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 +54 -18
  216. package/dist/jsx/components/DataTablePagination/index.mjs.map +1 -1
  217. package/dist/jsx/components/DataTablePagination/index.native.js +54 -16
  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.spec.tsx +9 -2
  300. package/src/components/DataTablePagination/DataTablePagination.stories.tsx +32 -0
  301. package/src/components/DataTablePagination/DataTablePagination.width.spec.tsx +109 -0
  302. package/src/components/DataTablePagination/index.tsx +100 -20
  303. package/src/components/DataTableSearch/index.tsx +2 -3
  304. package/src/components/DataTableToolbar/DataTableToolbar.stories.tsx +2 -4
  305. package/src/components/DataTableToolbar/index.tsx +1 -5
  306. package/src/components/DataTableViewOptions/index.tsx +2 -13
  307. package/src/components/FilterManager.tsx +1 -3
  308. package/src/components/FilterOperatorValueEditor/FilterOperatorValueEditor.spec.tsx +1 -1
  309. package/src/components/FilterOperatorValueEditor/FilterOperatorValueEditor.stories.tsx +1 -0
  310. package/src/components/FilterOperatorValueEditor/index.tsx +10 -2
  311. package/src/components/TableInput/index.native.tsx +3 -2
  312. package/src/components/TableInput/index.tsx +3 -2
  313. package/src/hooks/useDataTable.ts +43 -7
  314. package/src/index.ts +13 -0
  315. package/src/shared/devWarn.ts +97 -0
  316. package/src/types.ts +71 -2
  317. package/src/utils/columnAlign.ts +9 -1
  318. package/src/utils/filterFields.ts +23 -1
  319. package/src/utils/filterUtils.ts +50 -1
  320. package/src/utils/money.spec.ts +156 -0
  321. package/src/utils/money.ts +202 -0
  322. package/src/utils/rowAccumulator.ts +136 -0
  323. package/types/components/ColumnHeaderFilter/index.d.ts +9 -2
  324. package/types/components/ColumnHeaderFilter/index.d.ts.map +1 -1
  325. package/types/components/DataTable/DataTableCardControls.d.ts.map +1 -1
  326. package/types/components/DataTable/DataTableRoot.d.ts +1 -1
  327. package/types/components/DataTable/DataTableRoot.d.ts.map +1 -1
  328. package/types/components/DataTable/DataTableStateContext.d.ts +7 -0
  329. package/types/components/DataTable/DataTableStateContext.d.ts.map +1 -1
  330. package/types/components/DataTableBulkActions/index.d.ts.map +1 -1
  331. package/types/components/DataTableCell/index.d.ts.map +1 -1
  332. package/types/components/DataTableDateFilter/index.d.ts.map +1 -1
  333. package/types/components/DataTableFilterChips/FilterChip.d.ts.map +1 -1
  334. package/types/components/DataTableGrouping/index.d.ts.map +1 -1
  335. package/types/components/DataTablePagination/index.d.ts +1 -1
  336. package/types/components/DataTablePagination/index.d.ts.map +1 -1
  337. package/types/components/DataTableSearch/index.d.ts.map +1 -1
  338. package/types/components/DataTableToolbar/index.d.ts.map +1 -1
  339. package/types/components/DataTableViewOptions/index.d.ts.map +1 -1
  340. package/types/components/FilterManager.d.ts.map +1 -1
  341. package/types/components/FilterOperatorValueEditor/index.d.ts.map +1 -1
  342. package/types/components/TableInput/index.d.ts.map +1 -1
  343. package/types/components/TableInput/index.native.d.ts.map +1 -1
  344. package/types/hooks/useDataTable.d.ts +1 -1
  345. package/types/hooks/useDataTable.d.ts.map +1 -1
  346. package/types/index.d.ts +3 -0
  347. package/types/index.d.ts.map +1 -1
  348. package/types/shared/devWarn.d.ts +50 -0
  349. package/types/shared/devWarn.d.ts.map +1 -0
  350. package/types/types.d.ts +71 -3
  351. package/types/types.d.ts.map +1 -1
  352. package/types/utils/columnAlign.d.ts.map +1 -1
  353. package/types/utils/filterFields.d.ts.map +1 -1
  354. package/types/utils/filterUtils.d.ts +1 -1
  355. package/types/utils/filterUtils.d.ts.map +1 -1
  356. package/types/utils/money.d.ts +94 -0
  357. package/types/utils/money.d.ts.map +1 -0
  358. package/types/utils/rowAccumulator.d.ts +107 -0
  359. package/types/utils/rowAccumulator.d.ts.map +1 -0
@@ -326,7 +326,6 @@ export function DataTableDateFilter({
326
326
  <Popover.Trigger asChild>
327
327
  <Button
328
328
  size={knobProps.sizeToken}
329
- variant="outlined"
330
329
  disabled={disabled}
331
330
  icon={<CalendarIcon size={iconPx} />}
332
331
  justifyContent="flex-start"
@@ -370,7 +369,6 @@ export function DataTableDateFilter({
370
369
  {value && (
371
370
  <Button
372
371
  size={knobProps.sizeToken}
373
- variant="outlined"
374
372
  onPress={handleClear}
375
373
  icon={<XIcon size={iconPx} />}
376
374
  >
@@ -391,7 +389,6 @@ export function DataTableDateFilter({
391
389
  <Button
392
390
  key={preset.id}
393
391
  size={knobProps.sizeToken}
394
- variant="outlined"
395
392
  justifyContent="flex-start"
396
393
  onPress={() => handlePresetSelect(preset)}
397
394
  {...(activePresetId === preset.id
@@ -418,7 +415,6 @@ export function DataTableDateFilter({
418
415
  <Button
419
416
  flex={1}
420
417
  size={knobProps.sizeToken}
421
- variant="outlined"
422
418
  onPress={() => handleCustomDateSelect(new Date().toISOString(), "is")}
423
419
  >
424
420
  {t("Today")}
@@ -426,7 +422,6 @@ export function DataTableDateFilter({
426
422
  <Button
427
423
  flex={1}
428
424
  size={knobProps.sizeToken}
429
- variant="outlined"
430
425
  onPress={() =>
431
426
  handleCustomDateSelect(
432
427
  new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString(),
@@ -447,7 +442,6 @@ export function DataTableDateFilter({
447
442
  <Button
448
443
  flex={1}
449
444
  size={knobProps.sizeToken}
450
- variant="outlined"
451
445
  onPress={() =>
452
446
  handleDateRangeSelect(
453
447
  new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString(),
@@ -460,7 +454,6 @@ export function DataTableDateFilter({
460
454
  <Button
461
455
  flex={1}
462
456
  size={knobProps.sizeToken}
463
- variant="outlined"
464
457
  onPress={() =>
465
458
  handleDateRangeSelect(
466
459
  new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString(),
@@ -348,7 +348,7 @@ export function DataTableFilterButton() {
348
348
 
349
349
  {editingExisting && (
350
350
  <XStack justifyContent="flex-end">
351
- <Button size="$2" variant="outlined" onPress={handleRemoveCurrent}>
351
+ <Button size="$2" onPress={handleRemoveCurrent}>
352
352
  {t("Remove filter")}
353
353
  </Button>
354
354
  </XStack>
@@ -18,6 +18,12 @@ describe("FilterChip", () => {
18
18
  renderWithProviders(<FilterChip label="Email: contains corp" onRemove={vi.fn()} />);
19
19
  expect(screen.getByText("Email: contains corp")).toBeTruthy();
20
20
  expect(screen.getByRole("button", { name: "Remove" })).toBeTruthy();
21
+ const fill = screen
22
+ .getByRole("button", { name: "Remove" })
23
+ .querySelector("svg")
24
+ ?.getAttribute("fill");
25
+ expect(fill).toBeTruthy();
26
+ expect(fill?.startsWith("$")).toBe(false);
21
27
  });
22
28
 
23
29
  it("with onPress the pill is an edit button; both focusables are tab stops (LC-71)", () => {
@@ -16,7 +16,7 @@ import {
16
16
  pressTargetStyle,
17
17
  useResolvedKnobs,
18
18
  } from "@multiplatform.one/theme";
19
- import { View, styled } from "tamagui";
19
+ import { View, styled, useTheme } from "tamagui";
20
20
  import { t } from "../../shared/t";
21
21
 
22
22
  export interface FilterChipProps {
@@ -49,6 +49,7 @@ const DismissRing = styled(View, {
49
49
 
50
50
  export function FilterChip({ label, onRemove, onPress }: FilterChipProps) {
51
51
  const { knobProps } = useResolvedKnobs();
52
+ const theme = useTheme();
52
53
  if (typeof document !== "undefined") ensureCompositeFocusRing();
53
54
 
54
55
  const resolvedSize = (knobProps.sizeToken as ChipSize) || "$3";
@@ -114,7 +115,7 @@ export function FilterChip({ label, onRemove, onPress }: FilterChipProps) {
114
115
  }
115
116
  >
116
117
  <DismissRing className="mp-chip-dismiss-ring" borderRadius={knobProps.pointy ? 0 : 1000}>
117
- <XIcon size={iconSize} color="$color12" />
118
+ <XIcon size={iconSize} color={theme.color12?.val ?? "currentColor"} />
118
119
  </DismissRing>
119
120
  </DismissButton>
120
121
  </ChipFrame>
@@ -255,7 +255,7 @@ function FilterBuilder({
255
255
  ) : null}
256
256
 
257
257
  <XStack gap="$2" justifyContent="flex-end">
258
- <Button size="$3" compact variant="outlined" onPress={onCancel}>
258
+ <Button size="$3" compact onPress={onCancel}>
259
259
  {t("Cancel")}
260
260
  </Button>
261
261
  <Button
@@ -366,7 +366,6 @@ export const WithGroupingControls = () => {
366
366
  <XStack gap="$3" flexWrap="wrap">
367
367
  <Button
368
368
  size="$3"
369
- variant="outlined"
370
369
  onPress={() =>
371
370
  setGroupingConfig({
372
371
  columns: ["region"],
@@ -378,7 +377,6 @@ export const WithGroupingControls = () => {
378
377
  </Button>
379
378
  <Button
380
379
  size="$3"
381
- variant="outlined"
382
380
  onPress={() =>
383
381
  setGroupingConfig({
384
382
  columns: ["category"],
@@ -390,7 +388,6 @@ export const WithGroupingControls = () => {
390
388
  </Button>
391
389
  <Button
392
390
  size="$3"
393
- variant="outlined"
394
391
  onPress={() =>
395
392
  setGroupingConfig({
396
393
  columns: ["region", "category"],
@@ -405,7 +402,6 @@ export const WithGroupingControls = () => {
405
402
  </Button>
406
403
  <Button
407
404
  size="$3"
408
- variant="outlined"
409
405
  onPress={() =>
410
406
  setGroupingConfig({
411
407
  columns: [],
@@ -637,7 +637,6 @@ export function DataTableGroupingConfig<T = any>(props: DataTableGroupingConfigP
637
637
  <Popover.Trigger asChild>
638
638
  <Button
639
639
  size={knobProps.sizeToken}
640
- variant="outlined"
641
640
  icon={<GearIcon size={iconSize} />}
642
641
  disabled={disabled}
643
642
  aria-label="Grouping configuration"
@@ -716,7 +715,6 @@ export function DataTableGroupingConfig<T = any>(props: DataTableGroupingConfigP
716
715
  </Text>
717
716
  <Button
718
717
  size={knobProps.sizeToken}
719
- variant="outlined"
720
718
  icon={<ArrowUpIcon size={iconSize} />}
721
719
  disabled={disabled || index === 0}
722
720
  onPress={() => handleMoveGroupBy(index, -1)}
@@ -724,7 +722,6 @@ export function DataTableGroupingConfig<T = any>(props: DataTableGroupingConfigP
724
722
  />
725
723
  <Button
726
724
  size={knobProps.sizeToken}
727
- variant="outlined"
728
725
  icon={<ArrowDownIcon size={iconSize} />}
729
726
  disabled={disabled || index === currentConfig.columns.length - 1}
730
727
  onPress={() => handleMoveGroupBy(index, 1)}
@@ -732,7 +729,6 @@ export function DataTableGroupingConfig<T = any>(props: DataTableGroupingConfigP
732
729
  />
733
730
  <Button
734
731
  size={knobProps.sizeToken}
735
- variant="outlined"
736
732
  icon={<MinusIcon size={iconSize} />}
737
733
  disabled={disabled}
738
734
  onPress={() => handleRemoveGroupBy(columnKey)}
@@ -756,7 +752,6 @@ export function DataTableGroupingConfig<T = any>(props: DataTableGroupingConfigP
756
752
  <Button
757
753
  key={key}
758
754
  size={knobProps.sizeToken}
759
- variant="outlined"
760
755
  onPress={() => handleAddGroupBy(key)}
761
756
  >
762
757
  {column.header || key}
@@ -803,7 +798,6 @@ export function DataTableGroupingConfig<T = any>(props: DataTableGroupingConfigP
803
798
  </Text>
804
799
  <Button
805
800
  size={knobProps.sizeToken}
806
- variant="outlined"
807
801
  icon={<MinusIcon size={iconSize} />}
808
802
  disabled={disabled}
809
803
  onPress={() => handleRemoveAggregation(index)}
@@ -828,7 +822,6 @@ export function DataTableGroupingConfig<T = any>(props: DataTableGroupingConfigP
828
822
  <Separator />
829
823
  <Button
830
824
  size={knobProps.sizeToken}
831
- variant="outlined"
832
825
  error
833
826
  onPress={() => onConfigChange({ columns: [], aggregations: [] })}
834
827
  aria-label="Clear all grouping and aggregation"
@@ -946,12 +939,7 @@ function AggregationSelector<T = any>({ columns, onAddAggregation }: Aggregation
946
939
  />
947
940
  </View>
948
941
 
949
- <Button
950
- size={knobProps.sizeToken}
951
- variant="outlined"
952
- disabled={!selectedColumn}
953
- onPress={handleAdd}
954
- >
942
+ <Button size={knobProps.sizeToken} disabled={!selectedColumn} onPress={handleAdd}>
955
943
  Add
956
944
  </Button>
957
945
  </XStack>
@@ -1,16 +1,23 @@
1
- import { useState } from "react";
1
+ import { createElement, forwardRef, useEffect, useState } from "react";
2
2
  import { renderWithProviders } from "@multiplatform.one/test-utils";
3
3
  import { fireEvent, screen } from "@testing-library/react";
4
4
  import { describe, expect, it, vi } from "vitest";
5
5
 
6
6
  // The happy-dom env resolves useMedia to { sm: false } (mobile), which hides
7
- // the desktop-only meta clusters (rows-per-page, jump, range info). Pin sm on
7
+ // the desktop-only meta clusters. Model a measured wide container and pin sm on
8
8
  // so the range-label contract below is testable (same pattern as
9
9
  // components/Debug and markdown/mdx specs).
10
10
  vi.mock("tamagui", async (importOriginal) => {
11
11
  const actual = await importOriginal<typeof import("tamagui")>();
12
12
  return {
13
13
  ...actual,
14
+ XStack: forwardRef((props: any, ref) => {
15
+ const onLayout = props["aria-label"] === "Table pagination" ? props.onLayout : undefined;
16
+ useEffect(() => {
17
+ onLayout?.({ nativeEvent: { layout: { width: 1200, height: 44, x: 0, y: 0 } } });
18
+ }, [onLayout]);
19
+ return createElement(actual.XStack, { ...props, ref });
20
+ }),
14
21
  useMedia: (...args: any[]) => ({ ...(actual.useMedia as any)(...args), sm: true }),
15
22
  };
16
23
  });
@@ -1,5 +1,6 @@
1
1
  import { action } from "@multiplatform.one/storybook";
2
2
  import type { GuardrailSpecimenParameter } from "@multiplatform.one/theme";
3
+ import { Preset } from "@multiplatform.one/theme";
3
4
  import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
4
5
  import React from "react";
5
6
  // Catalog Button + Input (LC-56 STORY-HONESTY — no raw interactive primitives).
@@ -780,3 +781,34 @@ export const InfiniteVirtualized: Story = {
780
781
  />
781
782
  ),
782
783
  };
784
+
785
+ export const NarrowPanel: Story = {
786
+ render: (args) => {
787
+ const [pagination, setPagination] = React.useState({ pageIndex: 0, pageSize: 25 });
788
+ return (
789
+ <YStack width={249}>
790
+ <DataTablePagination
791
+ compact
792
+ pagination={{
793
+ ...pagination,
794
+ totalCount: 1000,
795
+ totalPages: Math.ceil(1000 / pagination.pageSize),
796
+ }}
797
+ onPaginationChange={setPagination}
798
+ {...args}
799
+ />
800
+ </YStack>
801
+ );
802
+ },
803
+ };
804
+
805
+ export const LargeSpaceNarrow: Story = {
806
+ ...NarrowPanel,
807
+ decorators: [
808
+ (Story) => (
809
+ <Preset overrides={{ space: "large" }}>
810
+ <Story />
811
+ </Preset>
812
+ ),
813
+ ],
814
+ };
@@ -0,0 +1,109 @@
1
+ import { createElement, forwardRef } from "react";
2
+ import { renderWithProviders } from "@multiplatform.one/test-utils";
3
+ import { act, fireEvent, screen, within } from "@testing-library/react";
4
+ import { beforeEach, describe, expect, it, vi } from "vitest";
5
+ import type { LayoutChangeEvent } from "react-native";
6
+ import { Preset } from "@multiplatform.one/theme";
7
+
8
+ const observed = vi.hoisted(() => ({
9
+ onLayout: undefined as undefined | ((event: LayoutChangeEvent) => void),
10
+ change: vi.fn(),
11
+ sizeWidth: 0,
12
+ }));
13
+ vi.mock("tamagui", async (importOriginal) => {
14
+ const actual = await importOriginal<typeof import("tamagui")>();
15
+ return {
16
+ ...actual,
17
+ useMedia: () => ({ sm: true }),
18
+ View: forwardRef((props: any, ref) => {
19
+ if (props["data-pagination-control"] === "size") observed.sizeWidth = props.width;
20
+ return createElement(actual.View, { ...props, ref });
21
+ }),
22
+ XStack: forwardRef((props: any, ref) => {
23
+ if (props["aria-label"] === "Table pagination") observed.onLayout = props.onLayout;
24
+ return createElement(actual.XStack, { ...props, ref });
25
+ }),
26
+ };
27
+ });
28
+ vi.mock("../DataTable/DataTableStateContext", () => ({
29
+ useDataTableState: () => ({
30
+ state: { pagination: { pageIndex: 0, pageSize: 25 } },
31
+ computed: { totalPages: 40, totalRows: 1000 },
32
+ actions: { setPagination: observed.change },
33
+ }),
34
+ }));
35
+ import { DataTablePagination } from "./index";
36
+
37
+ function measure(width: number) {
38
+ expect(observed.onLayout).toBeTypeOf("function");
39
+ act(() =>
40
+ observed.onLayout?.({
41
+ nativeEvent: { layout: { width, height: 44, x: 0, y: 0 } },
42
+ } as LayoutChangeEvent),
43
+ );
44
+ }
45
+ beforeEach(() => {
46
+ observed.change.mockReset();
47
+ observed.onLayout = undefined;
48
+ });
49
+
50
+ describe("bounded compact table pagination", () => {
51
+ it("preserves the default footprint and grows for wide numeric options", () => {
52
+ const { rerender } = renderWithProviders(<DataTablePagination compact />);
53
+ expect(observed.sizeWidth).toBe(80);
54
+ rerender(<DataTablePagination compact pageSizeOptions={[10, 25, 1000000]} />);
55
+ expect(observed.sizeWidth).toBeGreaterThan(80);
56
+ });
57
+
58
+ it("budgets the always-compact Select independently from footer spacing", () => {
59
+ const renderPager = (compact: boolean) => (
60
+ <Preset overrides={{ space: "large" }}>
61
+ <DataTablePagination compact={compact} />
62
+ </Preset>
63
+ );
64
+ const { rerender } = renderWithProviders(renderPager(false));
65
+ const width = observed.sizeWidth;
66
+ expect(width).toBeGreaterThan(80);
67
+ rerender(renderPager(true));
68
+ expect(observed.sizeWidth).toBe(width);
69
+ });
70
+
71
+ it("starts safely and responds to container width even on a desktop viewport", () => {
72
+ renderWithProviders(<DataTablePagination compact />);
73
+ const pager = () => within(screen.getByRole("navigation", { name: "Page" }));
74
+ expect(pager().getAllByRole("button")).toHaveLength(2);
75
+ measure(1000);
76
+ expect(pager().getAllByRole("button").length).toBeGreaterThan(2);
77
+ measure(249);
78
+ expect(pager().getAllByRole("button")).toHaveLength(2);
79
+ expect(pager().getByText(/1.*40/)).toBeInTheDocument();
80
+ expect(screen.getByLabelText("Select rows per page")).toBeInTheDocument();
81
+ fireEvent.click(pager().getByLabelText("Go to next page"));
82
+ expect(observed.change).toHaveBeenCalledExactlyOnceWith({ pageIndex: 1, pageSize: 25 });
83
+ });
84
+
85
+ it("preserves the presentation when a container reports its width again", () => {
86
+ renderWithProviders(<DataTablePagination compact />);
87
+ measure(249);
88
+ const pager = screen.getByRole("navigation", { name: "Page" });
89
+ const buttons = within(pager).getAllByRole("button");
90
+ measure(249);
91
+ expect(within(pager).getAllByRole("button")).toEqual(buttons);
92
+ expect(observed.change).not.toHaveBeenCalled();
93
+ });
94
+
95
+ it("resets to the first page when rows per page changes in a narrow table", async () => {
96
+ renderWithProviders(
97
+ <DataTablePagination
98
+ compact
99
+ pagination={{ pageIndex: 5, pageSize: 25, totalPages: 40, totalCount: 1000 }}
100
+ />,
101
+ );
102
+ measure(249);
103
+ fireEvent.click(screen.getByLabelText("Select rows per page"));
104
+ fireEvent.keyDown(await screen.findByRole("option", { name: "50" }), {
105
+ key: "Enter",
106
+ });
107
+ expect(observed.change).toHaveBeenCalledExactlyOnceWith({ pageIndex: 0, pageSize: 50 });
108
+ });
109
+ });
@@ -1,9 +1,16 @@
1
- import { ensureCompositeFocusRing, useResolvedKnobs } from "@multiplatform.one/theme";
2
- import { Pagination } from "@multiplatform.one/components";
1
+ import {
2
+ ensureCompositeFocusRing,
3
+ isTouchSurface,
4
+ MIN_PRESS_TARGET,
5
+ sizeRecipeForToken,
6
+ textFieldInset,
7
+ useResolvedKnobs,
8
+ } from "@multiplatform.one/theme";
9
+ import { Pagination, getPaginationItems } from "@multiplatform.one/components";
3
10
  import { useMemo, useState } from "react";
4
11
  import type React from "react";
5
12
  import { Input, Select } from "@multiplatform.one/forms";
6
- import { Text, View, XStack, useMedia } from "tamagui";
13
+ import { Text, View, XStack, getTokenValue, useMedia } from "tamagui";
7
14
  import type { TablePagination, TablePaginationState } from "../../types";
8
15
  import { DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZE_OPTIONS } from "../../utils/paginationDefaults";
9
16
  import { bidiIsolate } from "../../utils/withInterp";
@@ -24,8 +31,10 @@ export interface DataTablePaginationProps {
24
31
  compact?: boolean;
25
32
  }
26
33
 
27
- function controlWidth(chars: number, chrome: number) {
28
- return Math.max(48, chars * 12 + chrome);
34
+ function controlWidth(chars: number, fontSize: number, inset: number, trailingChrome = 0) {
35
+ // Conservative $body digit width, checked against rendered ink in Storybook.
36
+ // Include the Box's two hairline borders after its single horizontal inset.
37
+ return Math.ceil(chars * fontSize * 0.65) + inset * 2 + trailingChrome + 2;
29
38
  }
30
39
 
31
40
  function formatRange(start: number, end: number, total: number) {
@@ -35,7 +44,7 @@ function formatRange(start: number, end: number, total: number) {
35
44
 
36
45
  /**
37
46
  * DataTable footer pager. Page navigation is the catalog
38
- * `Pagination` component (`variant="numbered"`) — one pagination idiom
47
+ * `Pagination` component (`variant={simplePager ? "simple" : "numbered"}`) — one pagination idiom
39
48
  * across the system. This wrapper adds the table-specific chrome:
40
49
  * rows-per-page selector, go-to-page jump, and the item-range summary.
41
50
  *
@@ -83,7 +92,19 @@ export function DataTablePagination(props: DataTablePaginationProps) {
83
92
 
84
93
  const { sm } = useMedia();
85
94
  const { knobProps } = useResolvedKnobs(compact === undefined ? undefined : { compact });
95
+ // The fields are always compact, independently of the footer's layout.
96
+ const { knobProps: fieldKnobs } = useResolvedKnobs({ compact: true });
97
+ const fieldRecipe = sizeRecipeForToken(knobProps.sizeToken, { touch: isTouchSurface() });
98
+ const selectInset = Number(
99
+ getTokenValue(fieldKnobs.panelPadding.padding as Parameters<typeof getTokenValue>[0], "space"),
100
+ );
86
101
  const isMobile = !sm;
102
+ const packed = compact && insideTable;
103
+ const [availableWidth, setAvailableWidth] = useState<number | undefined>();
104
+ const measureWidth = (event: import("react-native").LayoutChangeEvent) => {
105
+ const width = event.nativeEvent.layout.width;
106
+ if (width > 0) setAvailableWidth((previous) => (previous === width ? previous : width));
107
+ };
87
108
  // LC-71: mount the composite-boundary ring sheet before Select/Input paint.
88
109
  ensureCompositeFocusRing();
89
110
 
@@ -112,6 +133,30 @@ export function DataTablePagination(props: DataTablePaginationProps) {
112
133
  const startItem = totalCount === 0 ? 0 : pagination.pageIndex * pagination.pageSize + 1;
113
134
  const endItem = Math.min((pagination.pageIndex + 1) * pagination.pageSize, totalCount);
114
135
 
136
+ // Budget the numbered window from the active theme's control geometry.
137
+ // An unmeasured host uses the safe simple presentation, including SSR.
138
+ const pageControls =
139
+ getPaginationItems(totalPages, currentPage).length + 2 + (!compact && !isMobile ? 2 : 0);
140
+ const controlBudget = Math.max(
141
+ MIN_PRESS_TARGET,
142
+ knobProps.control.height + knobProps.control.paddingHorizontal * 2,
143
+ );
144
+ const gapPixels = Number(
145
+ getTokenValue(knobProps.gap.gap as Parameters<typeof getTokenValue>[0], "space"),
146
+ );
147
+ const paddingPixels = packed
148
+ ? 0
149
+ : Number(
150
+ getTokenValue(
151
+ knobProps.panelPadding.padding as Parameters<typeof getTokenValue>[0],
152
+ "space",
153
+ ),
154
+ );
155
+ const measuredBudget =
156
+ pageControls * controlBudget + Math.max(0, pageControls - 1) * gapPixels + paddingPixels * 2;
157
+ const numberedBudget = Number.isFinite(measuredBudget) ? measuredBudget : Infinity;
158
+ const simplePager = availableWidth === undefined || availableWidth < numberedBudget;
159
+
115
160
  const sizeOptions = useMemo(() => {
116
161
  const sizes = new Set(pageSizeOptions.filter((n) => Number.isFinite(n) && n > 0));
117
162
  if (pagination.pageSize > 0) sizes.add(pagination.pageSize);
@@ -121,7 +166,7 @@ export function DataTablePagination(props: DataTablePaginationProps) {
121
166
  const showSize = showPageSizeSelector;
122
167
  // Compact-inside-DataTable: the table footer already paints the range.
123
168
  const showRange = showInfo && !(compact && insideTable);
124
- const showJump = showPageJump && showPager && !compact && !isMobile;
169
+ const showJump = showPageJump && showPager && !compact && !isMobile && !simplePager;
125
170
 
126
171
  const [jumpNonce, setJumpNonce] = useState(0);
127
172
 
@@ -138,15 +183,30 @@ export function DataTablePagination(props: DataTablePaginationProps) {
138
183
 
139
184
  const helperText = {
140
185
  ...knobProps.label,
141
- color: "$color10" as const,
186
+ color: knobProps.textAccentColor,
142
187
  userSelect: "none" as const,
143
188
  };
144
189
 
145
190
  const sizeControl = showSize ? (
146
- <XStack alignItems="center" gap="$2" flexShrink={0}>
191
+ <XStack
192
+ alignItems="center"
193
+ gap="$2"
194
+ flexShrink={0}
195
+ flexWrap="wrap"
196
+ minWidth={0}
197
+ maxWidth="100%"
198
+ >
147
199
  <Text {...helperText}>Rows per page:</Text>
148
200
  <View
149
- width={controlWidth(Math.max(2, ...sizeOptions.map((n) => String(n).length)), 44)}
201
+ width={Math.max(
202
+ 80,
203
+ controlWidth(
204
+ Math.max(2, ...sizeOptions.map((n) => String(n).length)),
205
+ fieldKnobs.controlType.fontSize,
206
+ selectInset,
207
+ fieldRecipe.gap + 16, // Select's fixed 16px caret.
208
+ ),
209
+ )}
150
210
  overflow="visible"
151
211
  flexShrink={0}
152
212
  {...({ "data-pagination-control": "size" } as object)}
@@ -172,12 +232,13 @@ export function DataTablePagination(props: DataTablePaginationProps) {
172
232
 
173
233
  const pager = showPager ? (
174
234
  <Pagination
175
- variant="numbered"
235
+ variant={simplePager ? "simple" : "numbered"}
176
236
  total={totalPages}
177
237
  page={currentPage}
178
238
  onPageChange={(page) => handlePageChange(page - 1)}
179
- showFirstLast={!compact && !isMobile}
239
+ showFirstLast={!simplePager && !compact && !isMobile}
180
240
  aria-label="Page"
241
+ padding={0}
181
242
  />
182
243
  ) : null;
183
244
 
@@ -185,7 +246,14 @@ export function DataTablePagination(props: DataTablePaginationProps) {
185
246
  <XStack alignItems="center" gap="$2" flexShrink={0} aria-label="Jump to page">
186
247
  <Text {...helperText}>Go to page:</Text>
187
248
  <View
188
- width={controlWidth(String(totalPages).length, 28)}
249
+ width={Math.max(
250
+ 48,
251
+ controlWidth(
252
+ String(totalPages).length,
253
+ fieldRecipe.fontSize,
254
+ textFieldInset(fieldRecipe),
255
+ ),
256
+ )}
189
257
  overflow="visible"
190
258
  flexShrink={0}
191
259
  {...({ "data-pagination-control": "jump" } as object)}
@@ -221,13 +289,17 @@ export function DataTablePagination(props: DataTablePaginationProps) {
221
289
  </Text>
222
290
  ) : null;
223
291
 
224
- const packed = compact && insideTable;
225
-
226
292
  if (packed) {
227
293
  return (
228
294
  <XStack
229
295
  role="group"
230
296
  aria-label="Table pagination"
297
+ onLayout={measureWidth}
298
+ minWidth={0}
299
+ maxWidth="100%"
300
+ flexGrow={1}
301
+ flexShrink={1}
302
+ flexWrap="wrap"
231
303
  alignItems="center"
232
304
  overflow="visible"
233
305
  {...knobProps.gap}
@@ -239,12 +311,14 @@ export function DataTablePagination(props: DataTablePaginationProps) {
239
311
  }
240
312
 
241
313
  return (
242
- // UX-P08 / LC-10 + Axiom 15 (G-03): side clusters grow equally so the
243
- // pager stays on the true centerline; when the row wraps each cluster
244
- // keeps its own alignment line. rowGap stays on the within-group rhythm.
314
+ // LC-10: intrinsic cluster widths participate in wrapping. Zero flex
315
+ // bases let the controls overlap while the footer itself still fits.
316
+ // A constrained size cluster can also wrap its label above the field.
245
317
  <XStack
246
318
  role="group"
247
319
  aria-label="Table pagination"
320
+ onLayout={measureWidth}
321
+ minWidth={0}
248
322
  alignItems="center"
249
323
  overflow="visible"
250
324
  {...knobProps.gapLg}
@@ -254,7 +328,14 @@ export function DataTablePagination(props: DataTablePaginationProps) {
254
328
  paddingHorizontal={knobProps.panelPadding.padding}
255
329
  paddingVertical="$2"
256
330
  >
257
- <XStack alignItems="center" flexGrow={1} flexBasis={0} justifyContent="flex-start">
331
+ <XStack
332
+ alignItems="center"
333
+ flexGrow={1}
334
+ flexShrink={1}
335
+ minWidth={0}
336
+ maxWidth="100%"
337
+ justifyContent="flex-start"
338
+ >
258
339
  {sizeControl}
259
340
  </XStack>
260
341
 
@@ -269,7 +350,6 @@ export function DataTablePagination(props: DataTablePaginationProps) {
269
350
  alignItems="center"
270
351
  {...knobProps.gap}
271
352
  flexGrow={1}
272
- flexBasis={0}
273
353
  flexShrink={0}
274
354
  justifyContent="flex-end"
275
355
  >
@@ -253,7 +253,6 @@ function SearchOptionsPopover({
253
253
  <Popover.Trigger asChild>
254
254
  <Button
255
255
  size={knobProps.sizeToken}
256
- variant="outlined"
257
256
  accent={optionsActive}
258
257
  icon={<SlidersHorizontalIcon size={iconPx} weight={optionsActive ? "fill" : "regular"} />}
259
258
  disabled={disabled}
@@ -326,10 +325,10 @@ function SearchOptionsPopover({
326
325
  </XStack>
327
326
 
328
327
  <XStack {...knobProps.gap}>
329
- <Button size="$2" compact variant="outlined" onPress={handleSelectAllColumns}>
328
+ <Button size="$2" compact onPress={handleSelectAllColumns}>
330
329
  {t("All")}
331
330
  </Button>
332
- <Button size="$2" compact variant="outlined" onPress={handleSelectNoColumns}>
331
+ <Button size="$2" compact onPress={handleSelectNoColumns}>
333
332
  {t("None")}
334
333
  </Button>
335
334
  </XStack>
@@ -71,9 +71,7 @@ const MainStory = () => {
71
71
  enableGlobalSearch
72
72
  enableViews
73
73
  initialState={{ pagination: { pageIndex: 1, pageSize: 3 } }}
74
- renderToolbar={(props) => (
75
- <DataTableToolbar {...props} enableViews enableExport />
76
- )}
74
+ renderToolbar={(props) => <DataTableToolbar {...props} enableViews enableExport />}
77
75
  aria-label="Employee table with toolbar"
78
76
  />
79
77
  </YStack>
@@ -154,7 +152,7 @@ const WithCustomActionsStory = () => {
154
152
  onClearFilters={() => setSearch("")}
155
153
  customActions={
156
154
  <XStack gap="$2">
157
- <Button size="$2" variant="outlined" onPress={() => action("refresh")()}>
155
+ <Button size="$2" onPress={() => action("refresh")()}>
158
156
  Refresh
159
157
  </Button>
160
158
  <Button size="$2" onPress={() => action("export")()}>