@multiplatform.one/table 6.7.0 → 7.1.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 (473) hide show
  1. package/README.md +4 -3
  2. package/dist/cjs/components/ChildTable/index.cjs +2 -1
  3. package/dist/cjs/components/ChildTable/index.native.js +2 -1
  4. package/dist/cjs/components/ChildTable/index.native.js.map +1 -1
  5. package/dist/cjs/components/ColumnHeaderFilter/index.cjs +17 -9
  6. package/dist/cjs/components/ColumnHeaderFilter/index.native.js +32 -11
  7. package/dist/cjs/components/ColumnHeaderFilter/index.native.js.map +1 -1
  8. package/dist/cjs/components/DataTable/DataTableDocumentList.cjs +222 -0
  9. package/dist/cjs/components/DataTable/DataTableDocumentList.native.js +237 -0
  10. package/dist/cjs/components/DataTable/DataTableDocumentList.native.js.map +1 -0
  11. package/dist/cjs/components/DataTable/DataTableMobileCards.cjs +5 -2
  12. package/dist/cjs/components/DataTable/DataTableMobileCards.native.js +6 -2
  13. package/dist/cjs/components/DataTable/DataTableMobileCards.native.js.map +1 -1
  14. package/dist/cjs/components/DataTable/DataTableRoot.cjs +92 -41
  15. package/dist/cjs/components/DataTable/DataTableRoot.native.js +97 -43
  16. package/dist/cjs/components/DataTable/DataTableRoot.native.js.map +1 -1
  17. package/dist/cjs/components/DataTable/DataTableVirtualized.cjs +8 -2
  18. package/dist/cjs/components/DataTable/DataTableVirtualized.native.js +9 -3
  19. package/dist/cjs/components/DataTable/DataTableVirtualized.native.js.map +1 -1
  20. package/dist/cjs/components/DataTable/documentListSlots.cjs +59 -0
  21. package/dist/cjs/components/DataTable/documentListSlots.native.js +85 -0
  22. package/dist/cjs/components/DataTable/documentListSlots.native.js.map +1 -0
  23. package/dist/cjs/components/DataTable/index.native.js +74 -59
  24. package/dist/cjs/components/DataTable/index.native.js.map +1 -1
  25. package/dist/cjs/components/DataTable/rowStateChrome.cjs +55 -0
  26. package/dist/cjs/components/DataTable/rowStateChrome.native.js +59 -0
  27. package/dist/cjs/components/DataTable/rowStateChrome.native.js.map +1 -0
  28. package/dist/cjs/components/DataTableCell/CellModalEditor.cjs +24 -3
  29. package/dist/cjs/components/DataTableCell/CellModalEditor.native.js +6 -1
  30. package/dist/cjs/components/DataTableCell/CellModalEditor.native.js.map +1 -1
  31. package/dist/cjs/components/DataTableCell/CellOptionsEditor.cjs +9 -2
  32. package/dist/cjs/components/DataTableCell/CellOptionsEditor.native.js +11 -2
  33. package/dist/cjs/components/DataTableCell/CellOptionsEditor.native.js.map +1 -1
  34. package/dist/cjs/components/DataTableCell/index.cjs +74 -63
  35. package/dist/cjs/components/DataTableCell/index.native.js +94 -82
  36. package/dist/cjs/components/DataTableCell/index.native.js.map +1 -1
  37. package/dist/cjs/components/DataTableColumnPinning/index.cjs +54 -37
  38. package/dist/cjs/components/DataTableColumnPinning/index.native.js +59 -38
  39. package/dist/cjs/components/DataTableColumnPinning/index.native.js.map +1 -1
  40. package/dist/cjs/components/DataTableDateFilter/index.cjs +33 -14
  41. package/dist/cjs/components/DataTableDateFilter/index.native.js +33 -12
  42. package/dist/cjs/components/DataTableDateFilter/index.native.js.map +1 -1
  43. package/dist/cjs/components/DataTableExport/index.cjs +35 -7
  44. package/dist/cjs/components/DataTableExport/index.native.js +42 -7
  45. package/dist/cjs/components/DataTableExport/index.native.js.map +1 -1
  46. package/dist/cjs/components/DataTableFacetMenu/index.cjs +140 -0
  47. package/dist/cjs/components/DataTableFacetMenu/index.native.js +156 -0
  48. package/dist/cjs/components/DataTableFacetMenu/index.native.js.map +1 -0
  49. package/dist/cjs/components/DataTableFilterButton/index.cjs +51 -32
  50. package/dist/cjs/components/DataTableFilterButton/index.native.js +63 -40
  51. package/dist/cjs/components/DataTableFilterButton/index.native.js.map +1 -1
  52. package/dist/cjs/components/DataTableFilterChips/FilterChip.cjs +143 -0
  53. package/dist/cjs/components/DataTableFilterChips/FilterChip.native.js +148 -0
  54. package/dist/cjs/components/DataTableFilterChips/FilterChip.native.js.map +1 -0
  55. package/dist/cjs/components/DataTableFilterChips/index.cjs +9 -31
  56. package/dist/cjs/components/DataTableFilterChips/index.native.js +9 -32
  57. package/dist/cjs/components/DataTableFilterChips/index.native.js.map +1 -1
  58. package/dist/cjs/components/DataTableFilters/index.cjs +145 -502
  59. package/dist/cjs/components/DataTableFilters/index.native.js +171 -544
  60. package/dist/cjs/components/DataTableFilters/index.native.js.map +1 -1
  61. package/dist/cjs/components/DataTableGrouping/index.cjs +273 -108
  62. package/dist/cjs/components/DataTableGrouping/index.native.js +310 -157
  63. package/dist/cjs/components/DataTableGrouping/index.native.js.map +1 -1
  64. package/dist/cjs/components/DataTablePagination/index.cjs +147 -95
  65. package/dist/cjs/components/DataTablePagination/index.native.js +159 -106
  66. package/dist/cjs/components/DataTablePagination/index.native.js.map +1 -1
  67. package/dist/cjs/components/DataTableSearch/index.cjs +251 -210
  68. package/dist/cjs/components/DataTableSearch/index.native.js +292 -243
  69. package/dist/cjs/components/DataTableSearch/index.native.js.map +1 -1
  70. package/dist/cjs/components/DataTableToolbar/index.cjs +141 -115
  71. package/dist/cjs/components/DataTableToolbar/index.native.js +163 -148
  72. package/dist/cjs/components/DataTableToolbar/index.native.js.map +1 -1
  73. package/dist/cjs/components/DataTableViewOptions/index.cjs +25 -21
  74. package/dist/cjs/components/DataTableViewOptions/index.native.js +6 -4
  75. package/dist/cjs/components/DataTableViewOptions/index.native.js.map +1 -1
  76. package/dist/cjs/components/SimpleTable/index.cjs +336 -46
  77. package/dist/cjs/components/SimpleTable/index.native.js +356 -48
  78. package/dist/cjs/components/SimpleTable/index.native.js.map +1 -1
  79. package/dist/cjs/components/TableInput/index.cjs +147 -38
  80. package/dist/cjs/components/TableInput/index.native.js +54 -38
  81. package/dist/cjs/components/TableInput/index.native.js.map +1 -1
  82. package/dist/cjs/components/TableInput/shared.cjs +36 -1
  83. package/dist/cjs/components/TableInput/shared.native.js +35 -0
  84. package/dist/cjs/components/TableInput/shared.native.js.map +1 -1
  85. package/dist/cjs/hooks/useDataTable.cjs +33 -2
  86. package/dist/cjs/hooks/useDataTable.native.js +41 -2
  87. package/dist/cjs/hooks/useDataTable.native.js.map +1 -1
  88. package/dist/cjs/hooks/useInfiniteRows.cjs +20 -3
  89. package/dist/cjs/hooks/useInfiniteRows.native.js +20 -3
  90. package/dist/cjs/hooks/useInfiniteRows.native.js.map +1 -1
  91. package/dist/cjs/index.cjs +2 -0
  92. package/dist/cjs/index.native.js +2 -0
  93. package/dist/cjs/index.native.js.map +1 -1
  94. package/dist/cjs/utils/filterUtils.cjs +12 -5
  95. package/dist/cjs/utils/filterUtils.native.js +20 -5
  96. package/dist/cjs/utils/filterUtils.native.js.map +1 -1
  97. package/dist/esm/components/ChildTable/index.mjs +2 -1
  98. package/dist/esm/components/ChildTable/index.mjs.map +1 -1
  99. package/dist/esm/components/ChildTable/index.native.js +2 -1
  100. package/dist/esm/components/ChildTable/index.native.js.map +1 -1
  101. package/dist/esm/components/ColumnHeaderFilter/index.mjs +17 -9
  102. package/dist/esm/components/ColumnHeaderFilter/index.mjs.map +1 -1
  103. package/dist/esm/components/ColumnHeaderFilter/index.native.js +32 -11
  104. package/dist/esm/components/ColumnHeaderFilter/index.native.js.map +1 -1
  105. package/dist/esm/components/DataTable/DataTableDocumentList.mjs +196 -0
  106. package/dist/esm/components/DataTable/DataTableDocumentList.mjs.map +1 -0
  107. package/dist/esm/components/DataTable/DataTableDocumentList.native.js +208 -0
  108. package/dist/esm/components/DataTable/DataTableDocumentList.native.js.map +1 -0
  109. package/dist/esm/components/DataTable/DataTableMobileCards.mjs +5 -2
  110. package/dist/esm/components/DataTable/DataTableMobileCards.mjs.map +1 -1
  111. package/dist/esm/components/DataTable/DataTableMobileCards.native.js +6 -2
  112. package/dist/esm/components/DataTable/DataTableMobileCards.native.js.map +1 -1
  113. package/dist/esm/components/DataTable/DataTableRoot.mjs +93 -42
  114. package/dist/esm/components/DataTable/DataTableRoot.mjs.map +1 -1
  115. package/dist/esm/components/DataTable/DataTableRoot.native.js +98 -44
  116. package/dist/esm/components/DataTable/DataTableRoot.native.js.map +1 -1
  117. package/dist/esm/components/DataTable/DataTableVirtualized.mjs +8 -2
  118. package/dist/esm/components/DataTable/DataTableVirtualized.mjs.map +1 -1
  119. package/dist/esm/components/DataTable/DataTableVirtualized.native.js +9 -3
  120. package/dist/esm/components/DataTable/DataTableVirtualized.native.js.map +1 -1
  121. package/dist/esm/components/DataTable/documentListSlots.mjs +33 -0
  122. package/dist/esm/components/DataTable/documentListSlots.mjs.map +1 -0
  123. package/dist/esm/components/DataTable/documentListSlots.native.js +56 -0
  124. package/dist/esm/components/DataTable/documentListSlots.native.js.map +1 -0
  125. package/dist/esm/components/DataTable/index.native.js +52 -37
  126. package/dist/esm/components/DataTable/index.native.js.map +1 -1
  127. package/dist/esm/components/DataTable/rowStateChrome.mjs +28 -0
  128. package/dist/esm/components/DataTable/rowStateChrome.mjs.map +1 -0
  129. package/dist/esm/components/DataTable/rowStateChrome.native.js +29 -0
  130. package/dist/esm/components/DataTable/rowStateChrome.native.js.map +1 -0
  131. package/dist/esm/components/DataTableCell/CellModalEditor.mjs +25 -4
  132. package/dist/esm/components/DataTableCell/CellModalEditor.mjs.map +1 -1
  133. package/dist/esm/components/DataTableCell/CellModalEditor.native.js +6 -1
  134. package/dist/esm/components/DataTableCell/CellModalEditor.native.js.map +1 -1
  135. package/dist/esm/components/DataTableCell/CellOptionsEditor.mjs +9 -2
  136. package/dist/esm/components/DataTableCell/CellOptionsEditor.mjs.map +1 -1
  137. package/dist/esm/components/DataTableCell/CellOptionsEditor.native.js +11 -2
  138. package/dist/esm/components/DataTableCell/CellOptionsEditor.native.js.map +1 -1
  139. package/dist/esm/components/DataTableCell/index.mjs +75 -64
  140. package/dist/esm/components/DataTableCell/index.mjs.map +1 -1
  141. package/dist/esm/components/DataTableCell/index.native.js +95 -83
  142. package/dist/esm/components/DataTableCell/index.native.js.map +1 -1
  143. package/dist/esm/components/DataTableColumnPinning/index.mjs +54 -37
  144. package/dist/esm/components/DataTableColumnPinning/index.mjs.map +1 -1
  145. package/dist/esm/components/DataTableColumnPinning/index.native.js +59 -38
  146. package/dist/esm/components/DataTableColumnPinning/index.native.js.map +1 -1
  147. package/dist/esm/components/DataTableDateFilter/index.mjs +34 -15
  148. package/dist/esm/components/DataTableDateFilter/index.mjs.map +1 -1
  149. package/dist/esm/components/DataTableDateFilter/index.native.js +34 -13
  150. package/dist/esm/components/DataTableDateFilter/index.native.js.map +1 -1
  151. package/dist/esm/components/DataTableExport/index.mjs +36 -8
  152. package/dist/esm/components/DataTableExport/index.mjs.map +1 -1
  153. package/dist/esm/components/DataTableExport/index.native.js +43 -8
  154. package/dist/esm/components/DataTableExport/index.native.js.map +1 -1
  155. package/dist/esm/components/DataTableFacetMenu/index.mjs +115 -0
  156. package/dist/esm/components/DataTableFacetMenu/index.mjs.map +1 -0
  157. package/dist/esm/components/DataTableFacetMenu/index.native.js +128 -0
  158. package/dist/esm/components/DataTableFacetMenu/index.native.js.map +1 -0
  159. package/dist/esm/components/DataTableFilterButton/index.mjs +54 -35
  160. package/dist/esm/components/DataTableFilterButton/index.mjs.map +1 -1
  161. package/dist/esm/components/DataTableFilterButton/index.native.js +66 -43
  162. package/dist/esm/components/DataTableFilterButton/index.native.js.map +1 -1
  163. package/dist/esm/components/DataTableFilterChips/FilterChip.mjs +118 -0
  164. package/dist/esm/components/DataTableFilterChips/FilterChip.mjs.map +1 -0
  165. package/dist/esm/components/DataTableFilterChips/FilterChip.native.js +120 -0
  166. package/dist/esm/components/DataTableFilterChips/FilterChip.native.js.map +1 -0
  167. package/dist/esm/components/DataTableFilterChips/index.mjs +9 -32
  168. package/dist/esm/components/DataTableFilterChips/index.mjs.map +1 -1
  169. package/dist/esm/components/DataTableFilterChips/index.native.js +9 -33
  170. package/dist/esm/components/DataTableFilterChips/index.native.js.map +1 -1
  171. package/dist/esm/components/DataTableFilters/index.mjs +149 -506
  172. package/dist/esm/components/DataTableFilters/index.mjs.map +1 -1
  173. package/dist/esm/components/DataTableFilters/index.native.js +175 -548
  174. package/dist/esm/components/DataTableFilters/index.native.js.map +1 -1
  175. package/dist/esm/components/DataTableGrouping/index.mjs +275 -110
  176. package/dist/esm/components/DataTableGrouping/index.mjs.map +1 -1
  177. package/dist/esm/components/DataTableGrouping/index.native.js +287 -134
  178. package/dist/esm/components/DataTableGrouping/index.native.js.map +1 -1
  179. package/dist/esm/components/DataTablePagination/index.mjs +148 -96
  180. package/dist/esm/components/DataTablePagination/index.mjs.map +1 -1
  181. package/dist/esm/components/DataTablePagination/index.native.js +160 -107
  182. package/dist/esm/components/DataTablePagination/index.native.js.map +1 -1
  183. package/dist/esm/components/DataTableSearch/index.mjs +256 -215
  184. package/dist/esm/components/DataTableSearch/index.mjs.map +1 -1
  185. package/dist/esm/components/DataTableSearch/index.native.js +297 -248
  186. package/dist/esm/components/DataTableSearch/index.native.js.map +1 -1
  187. package/dist/esm/components/DataTableToolbar/index.mjs +145 -119
  188. package/dist/esm/components/DataTableToolbar/index.mjs.map +1 -1
  189. package/dist/esm/components/DataTableToolbar/index.native.js +167 -152
  190. package/dist/esm/components/DataTableToolbar/index.native.js.map +1 -1
  191. package/dist/esm/components/DataTableViewOptions/index.mjs +26 -22
  192. package/dist/esm/components/DataTableViewOptions/index.mjs.map +1 -1
  193. package/dist/esm/components/DataTableViewOptions/index.native.js +7 -5
  194. package/dist/esm/components/DataTableViewOptions/index.native.js.map +1 -1
  195. package/dist/esm/components/SimpleTable/index.mjs +338 -48
  196. package/dist/esm/components/SimpleTable/index.mjs.map +1 -1
  197. package/dist/esm/components/SimpleTable/index.native.js +358 -50
  198. package/dist/esm/components/SimpleTable/index.native.js.map +1 -1
  199. package/dist/esm/components/TableInput/index.mjs +150 -41
  200. package/dist/esm/components/TableInput/index.mjs.map +1 -1
  201. package/dist/esm/components/TableInput/index.native.js +55 -39
  202. package/dist/esm/components/TableInput/index.native.js.map +1 -1
  203. package/dist/esm/components/TableInput/shared.mjs +34 -1
  204. package/dist/esm/components/TableInput/shared.mjs.map +1 -1
  205. package/dist/esm/components/TableInput/shared.native.js +34 -1
  206. package/dist/esm/components/TableInput/shared.native.js.map +1 -1
  207. package/dist/esm/hooks/useDataTable.mjs +33 -2
  208. package/dist/esm/hooks/useDataTable.mjs.map +1 -1
  209. package/dist/esm/hooks/useDataTable.native.js +41 -2
  210. package/dist/esm/hooks/useDataTable.native.js.map +1 -1
  211. package/dist/esm/hooks/useInfiniteRows.mjs +20 -3
  212. package/dist/esm/hooks/useInfiniteRows.mjs.map +1 -1
  213. package/dist/esm/hooks/useInfiniteRows.native.js +20 -3
  214. package/dist/esm/hooks/useInfiniteRows.native.js.map +1 -1
  215. package/dist/esm/index.mjs +2 -1
  216. package/dist/esm/index.mjs.map +1 -1
  217. package/dist/esm/index.native.js +2 -1
  218. package/dist/esm/index.native.js.map +1 -1
  219. package/dist/esm/utils/filterUtils.mjs +12 -5
  220. package/dist/esm/utils/filterUtils.mjs.map +1 -1
  221. package/dist/esm/utils/filterUtils.native.js +20 -5
  222. package/dist/esm/utils/filterUtils.native.js.map +1 -1
  223. package/dist/jsx/components/ChildTable/index.mjs +2 -1
  224. package/dist/jsx/components/ChildTable/index.mjs.map +1 -1
  225. package/dist/jsx/components/ChildTable/index.native.js +2 -1
  226. package/dist/jsx/components/ChildTable/index.native.js.map +1 -1
  227. package/dist/jsx/components/ColumnHeaderFilter/index.mjs +17 -9
  228. package/dist/jsx/components/ColumnHeaderFilter/index.mjs.map +1 -1
  229. package/dist/jsx/components/ColumnHeaderFilter/index.native.js +32 -11
  230. package/dist/jsx/components/ColumnHeaderFilter/index.native.js.map +1 -1
  231. package/dist/jsx/components/DataTable/DataTableDocumentList.mjs +196 -0
  232. package/dist/jsx/components/DataTable/DataTableDocumentList.mjs.map +1 -0
  233. package/dist/jsx/components/DataTable/DataTableDocumentList.native.js +237 -0
  234. package/dist/jsx/components/DataTable/DataTableDocumentList.native.js.map +1 -0
  235. package/dist/jsx/components/DataTable/DataTableMobileCards.mjs +5 -2
  236. package/dist/jsx/components/DataTable/DataTableMobileCards.mjs.map +1 -1
  237. package/dist/jsx/components/DataTable/DataTableMobileCards.native.js +6 -2
  238. package/dist/jsx/components/DataTable/DataTableMobileCards.native.js.map +1 -1
  239. package/dist/jsx/components/DataTable/DataTableRoot.mjs +93 -42
  240. package/dist/jsx/components/DataTable/DataTableRoot.mjs.map +1 -1
  241. package/dist/jsx/components/DataTable/DataTableRoot.native.js +97 -43
  242. package/dist/jsx/components/DataTable/DataTableRoot.native.js.map +1 -1
  243. package/dist/jsx/components/DataTable/DataTableVirtualized.mjs +8 -2
  244. package/dist/jsx/components/DataTable/DataTableVirtualized.mjs.map +1 -1
  245. package/dist/jsx/components/DataTable/DataTableVirtualized.native.js +9 -3
  246. package/dist/jsx/components/DataTable/DataTableVirtualized.native.js.map +1 -1
  247. package/dist/jsx/components/DataTable/documentListSlots.mjs +33 -0
  248. package/dist/jsx/components/DataTable/documentListSlots.mjs.map +1 -0
  249. package/dist/jsx/components/DataTable/documentListSlots.native.js +85 -0
  250. package/dist/jsx/components/DataTable/documentListSlots.native.js.map +1 -0
  251. package/dist/jsx/components/DataTable/index.native.js +74 -59
  252. package/dist/jsx/components/DataTable/index.native.js.map +1 -1
  253. package/dist/jsx/components/DataTable/rowStateChrome.mjs +28 -0
  254. package/dist/jsx/components/DataTable/rowStateChrome.mjs.map +1 -0
  255. package/dist/jsx/components/DataTable/rowStateChrome.native.js +59 -0
  256. package/dist/jsx/components/DataTable/rowStateChrome.native.js.map +1 -0
  257. package/dist/jsx/components/DataTableCell/CellModalEditor.mjs +25 -4
  258. package/dist/jsx/components/DataTableCell/CellModalEditor.mjs.map +1 -1
  259. package/dist/jsx/components/DataTableCell/CellModalEditor.native.js +6 -1
  260. package/dist/jsx/components/DataTableCell/CellModalEditor.native.js.map +1 -1
  261. package/dist/jsx/components/DataTableCell/CellOptionsEditor.mjs +9 -2
  262. package/dist/jsx/components/DataTableCell/CellOptionsEditor.mjs.map +1 -1
  263. package/dist/jsx/components/DataTableCell/CellOptionsEditor.native.js +11 -2
  264. package/dist/jsx/components/DataTableCell/CellOptionsEditor.native.js.map +1 -1
  265. package/dist/jsx/components/DataTableCell/index.mjs +75 -64
  266. package/dist/jsx/components/DataTableCell/index.mjs.map +1 -1
  267. package/dist/jsx/components/DataTableCell/index.native.js +94 -82
  268. package/dist/jsx/components/DataTableCell/index.native.js.map +1 -1
  269. package/dist/jsx/components/DataTableColumnPinning/index.mjs +54 -37
  270. package/dist/jsx/components/DataTableColumnPinning/index.mjs.map +1 -1
  271. package/dist/jsx/components/DataTableColumnPinning/index.native.js +59 -38
  272. package/dist/jsx/components/DataTableColumnPinning/index.native.js.map +1 -1
  273. package/dist/jsx/components/DataTableDateFilter/index.mjs +34 -15
  274. package/dist/jsx/components/DataTableDateFilter/index.mjs.map +1 -1
  275. package/dist/jsx/components/DataTableDateFilter/index.native.js +33 -12
  276. package/dist/jsx/components/DataTableDateFilter/index.native.js.map +1 -1
  277. package/dist/jsx/components/DataTableExport/index.mjs +36 -8
  278. package/dist/jsx/components/DataTableExport/index.mjs.map +1 -1
  279. package/dist/jsx/components/DataTableExport/index.native.js +42 -7
  280. package/dist/jsx/components/DataTableExport/index.native.js.map +1 -1
  281. package/dist/jsx/components/DataTableFacetMenu/index.mjs +115 -0
  282. package/dist/jsx/components/DataTableFacetMenu/index.mjs.map +1 -0
  283. package/dist/jsx/components/DataTableFacetMenu/index.native.js +156 -0
  284. package/dist/jsx/components/DataTableFacetMenu/index.native.js.map +1 -0
  285. package/dist/jsx/components/DataTableFilterButton/index.mjs +54 -35
  286. package/dist/jsx/components/DataTableFilterButton/index.mjs.map +1 -1
  287. package/dist/jsx/components/DataTableFilterButton/index.native.js +63 -40
  288. package/dist/jsx/components/DataTableFilterButton/index.native.js.map +1 -1
  289. package/dist/jsx/components/DataTableFilterChips/FilterChip.mjs +118 -0
  290. package/dist/jsx/components/DataTableFilterChips/FilterChip.mjs.map +1 -0
  291. package/dist/jsx/components/DataTableFilterChips/FilterChip.native.js +148 -0
  292. package/dist/jsx/components/DataTableFilterChips/FilterChip.native.js.map +1 -0
  293. package/dist/jsx/components/DataTableFilterChips/index.mjs +9 -32
  294. package/dist/jsx/components/DataTableFilterChips/index.mjs.map +1 -1
  295. package/dist/jsx/components/DataTableFilterChips/index.native.js +9 -32
  296. package/dist/jsx/components/DataTableFilterChips/index.native.js.map +1 -1
  297. package/dist/jsx/components/DataTableFilters/index.mjs +149 -506
  298. package/dist/jsx/components/DataTableFilters/index.mjs.map +1 -1
  299. package/dist/jsx/components/DataTableFilters/index.native.js +171 -544
  300. package/dist/jsx/components/DataTableFilters/index.native.js.map +1 -1
  301. package/dist/jsx/components/DataTableGrouping/index.mjs +275 -110
  302. package/dist/jsx/components/DataTableGrouping/index.mjs.map +1 -1
  303. package/dist/jsx/components/DataTableGrouping/index.native.js +310 -157
  304. package/dist/jsx/components/DataTableGrouping/index.native.js.map +1 -1
  305. package/dist/jsx/components/DataTablePagination/index.mjs +148 -96
  306. package/dist/jsx/components/DataTablePagination/index.mjs.map +1 -1
  307. package/dist/jsx/components/DataTablePagination/index.native.js +159 -106
  308. package/dist/jsx/components/DataTablePagination/index.native.js.map +1 -1
  309. package/dist/jsx/components/DataTableSearch/index.mjs +256 -215
  310. package/dist/jsx/components/DataTableSearch/index.mjs.map +1 -1
  311. package/dist/jsx/components/DataTableSearch/index.native.js +292 -243
  312. package/dist/jsx/components/DataTableSearch/index.native.js.map +1 -1
  313. package/dist/jsx/components/DataTableToolbar/index.mjs +145 -119
  314. package/dist/jsx/components/DataTableToolbar/index.mjs.map +1 -1
  315. package/dist/jsx/components/DataTableToolbar/index.native.js +163 -148
  316. package/dist/jsx/components/DataTableToolbar/index.native.js.map +1 -1
  317. package/dist/jsx/components/DataTableViewOptions/index.mjs +26 -22
  318. package/dist/jsx/components/DataTableViewOptions/index.mjs.map +1 -1
  319. package/dist/jsx/components/DataTableViewOptions/index.native.js +6 -4
  320. package/dist/jsx/components/DataTableViewOptions/index.native.js.map +1 -1
  321. package/dist/jsx/components/SimpleTable/index.mjs +338 -48
  322. package/dist/jsx/components/SimpleTable/index.mjs.map +1 -1
  323. package/dist/jsx/components/SimpleTable/index.native.js +356 -48
  324. package/dist/jsx/components/SimpleTable/index.native.js.map +1 -1
  325. package/dist/jsx/components/TableInput/index.mjs +150 -41
  326. package/dist/jsx/components/TableInput/index.mjs.map +1 -1
  327. package/dist/jsx/components/TableInput/index.native.js +54 -38
  328. package/dist/jsx/components/TableInput/index.native.js.map +1 -1
  329. package/dist/jsx/components/TableInput/shared.mjs +34 -1
  330. package/dist/jsx/components/TableInput/shared.mjs.map +1 -1
  331. package/dist/jsx/components/TableInput/shared.native.js +35 -0
  332. package/dist/jsx/components/TableInput/shared.native.js.map +1 -1
  333. package/dist/jsx/hooks/useDataTable.mjs +33 -2
  334. package/dist/jsx/hooks/useDataTable.mjs.map +1 -1
  335. package/dist/jsx/hooks/useDataTable.native.js +41 -2
  336. package/dist/jsx/hooks/useDataTable.native.js.map +1 -1
  337. package/dist/jsx/hooks/useInfiniteRows.mjs +20 -3
  338. package/dist/jsx/hooks/useInfiniteRows.mjs.map +1 -1
  339. package/dist/jsx/hooks/useInfiniteRows.native.js +20 -3
  340. package/dist/jsx/hooks/useInfiniteRows.native.js.map +1 -1
  341. package/dist/jsx/index.js +2 -1
  342. package/dist/jsx/index.js.map +1 -1
  343. package/dist/jsx/index.mjs +2 -1
  344. package/dist/jsx/index.mjs.map +1 -1
  345. package/dist/jsx/index.native.js +2 -0
  346. package/dist/jsx/index.native.js.map +1 -1
  347. package/dist/jsx/utils/filterUtils.mjs +12 -5
  348. package/dist/jsx/utils/filterUtils.mjs.map +1 -1
  349. package/dist/jsx/utils/filterUtils.native.js +20 -5
  350. package/dist/jsx/utils/filterUtils.native.js.map +1 -1
  351. package/package.json +15 -15
  352. package/src/components/ChildTable/index.tsx +1 -0
  353. package/src/components/ColumnHeaderFilter/ColumnHeaderFilter.spec.tsx +85 -0
  354. package/src/components/ColumnHeaderFilter/index.tsx +28 -10
  355. package/src/components/DataTable/DataTable.stories.tsx +30 -0
  356. package/src/components/DataTable/DataTableDocumentList.tsx +224 -0
  357. package/src/components/DataTable/DataTableMobileCards.tsx +20 -8
  358. package/src/components/DataTable/DataTableRoot.tsx +135 -58
  359. package/src/components/DataTable/DataTableVirtualized.tsx +8 -11
  360. package/src/components/DataTable/cardLayout.spec.tsx +89 -0
  361. package/src/components/DataTable/documentListSlots.ts +57 -0
  362. package/src/components/DataTable/index.native.tsx +76 -50
  363. package/src/components/DataTable/keepPreviousData.spec.tsx +137 -0
  364. package/src/components/DataTable/rowRing.spec.tsx +118 -0
  365. package/src/components/DataTable/rowStateChrome.ts +38 -0
  366. package/src/components/DataTableCell/CellModalEditor.native.tsx +4 -0
  367. package/src/components/DataTableCell/CellModalEditor.tsx +31 -3
  368. package/src/components/DataTableCell/CellOptionsEditor.tsx +29 -12
  369. package/src/components/DataTableCell/DataTableCell.stories.tsx +3 -3
  370. package/src/components/DataTableCell/cellDraftPolicy.spec.tsx +131 -4
  371. package/src/components/DataTableCell/dataTableCell.spec.tsx +36 -1
  372. package/src/components/DataTableCell/index.tsx +121 -86
  373. package/src/components/DataTableColumnPinning/DataTableColumnPinning.spec.tsx +66 -0
  374. package/src/components/DataTableColumnPinning/index.tsx +32 -17
  375. package/src/components/DataTableDateFilter/DataTableDateFilter.spec.tsx +9 -1
  376. package/src/components/DataTableDateFilter/dateFilterZones.spec.ts +316 -0
  377. package/src/components/DataTableDateFilter/index.tsx +42 -22
  378. package/src/components/DataTableExport/exportDateZones.spec.tsx +348 -0
  379. package/src/components/DataTableExport/index.tsx +107 -63
  380. package/src/components/DataTableFacetMenu/DataTableFacetMenu.spec.tsx +264 -0
  381. package/src/components/DataTableFacetMenu/DataTableFacetMenu.stories.tsx +212 -0
  382. package/src/components/DataTableFacetMenu/index.tsx +202 -0
  383. package/src/components/DataTableFilterButton/index.tsx +66 -49
  384. package/src/components/DataTableFilterChips/DataTableFilterChips.spec.tsx +22 -0
  385. package/src/components/DataTableFilterChips/FilterChip.tsx +122 -0
  386. package/src/components/DataTableFilterChips/index.tsx +13 -29
  387. package/src/components/DataTableFilters/DataTableFilters.spec.tsx +56 -0
  388. package/src/components/DataTableFilters/index.tsx +169 -584
  389. package/src/components/DataTableGrouping/DataTableGrouping.spec.tsx +85 -0
  390. package/src/components/DataTableGrouping/index.tsx +270 -130
  391. package/src/components/DataTablePagination/DataTablePagination.spec.tsx +79 -4
  392. package/src/components/DataTablePagination/index.tsx +168 -112
  393. package/src/components/DataTableSearch/DataTableSearch.spec.tsx +40 -0
  394. package/src/components/DataTableSearch/DataTableSearch.stories.tsx +1 -1
  395. package/src/components/DataTableSearch/index.tsx +192 -163
  396. package/src/components/DataTableToolbar/DataTableToolbar.spec.tsx +48 -18
  397. package/src/components/DataTableToolbar/DataTableToolbar.stories.tsx +5 -45
  398. package/src/components/DataTableToolbar/index.tsx +128 -99
  399. package/src/components/DataTableViewOptions/index.tsx +29 -22
  400. package/src/components/SimpleTable/SimpleTable.stories.tsx +29 -5
  401. package/src/components/SimpleTable/index.tsx +442 -61
  402. package/src/components/SimpleTable/simpleTable.spec.tsx +140 -12
  403. package/src/components/TableInput/index.native.tsx +91 -81
  404. package/src/components/TableInput/index.tsx +191 -50
  405. package/src/components/TableInput/shared.ts +57 -0
  406. package/src/components/TableInput/tableInput.spec.tsx +104 -0
  407. package/src/hooks/useDataTable.spec.ts +100 -3
  408. package/src/hooks/useDataTable.ts +44 -1
  409. package/src/hooks/useInfiniteRows.spec.tsx +37 -0
  410. package/src/hooks/useInfiniteRows.ts +34 -4
  411. package/src/index.ts +7 -0
  412. package/src/types.ts +54 -3
  413. package/src/utils/filterUtils.ts +27 -5
  414. package/types/components/ChildTable/index.d.ts.map +1 -1
  415. package/types/components/ColumnHeaderFilter/index.d.ts.map +1 -1
  416. package/types/components/DataTable/DataTableDocumentList.d.ts +32 -0
  417. package/types/components/DataTable/DataTableDocumentList.d.ts.map +1 -0
  418. package/types/components/DataTable/DataTableMobileCards.d.ts +3 -1
  419. package/types/components/DataTable/DataTableMobileCards.d.ts.map +1 -1
  420. package/types/components/DataTable/DataTableRoot.d.ts +1 -1
  421. package/types/components/DataTable/DataTableRoot.d.ts.map +1 -1
  422. package/types/components/DataTable/DataTableVirtualized.d.ts +1 -2
  423. package/types/components/DataTable/DataTableVirtualized.d.ts.map +1 -1
  424. package/types/components/DataTable/documentListSlots.d.ts +26 -0
  425. package/types/components/DataTable/documentListSlots.d.ts.map +1 -0
  426. package/types/components/DataTable/index.native.d.ts +1 -1
  427. package/types/components/DataTable/index.native.d.ts.map +1 -1
  428. package/types/components/DataTable/rowStateChrome.d.ts +18 -0
  429. package/types/components/DataTable/rowStateChrome.d.ts.map +1 -0
  430. package/types/components/DataTableCell/CellModalEditor.d.ts +6 -1
  431. package/types/components/DataTableCell/CellModalEditor.d.ts.map +1 -1
  432. package/types/components/DataTableCell/CellModalEditor.native.d.ts +1 -1
  433. package/types/components/DataTableCell/CellModalEditor.native.d.ts.map +1 -1
  434. package/types/components/DataTableCell/CellOptionsEditor.d.ts +11 -3
  435. package/types/components/DataTableCell/CellOptionsEditor.d.ts.map +1 -1
  436. package/types/components/DataTableCell/index.d.ts +1 -1
  437. package/types/components/DataTableCell/index.d.ts.map +1 -1
  438. package/types/components/DataTableColumnPinning/index.d.ts.map +1 -1
  439. package/types/components/DataTableDateFilter/index.d.ts.map +1 -1
  440. package/types/components/DataTableExport/index.d.ts +17 -6
  441. package/types/components/DataTableExport/index.d.ts.map +1 -1
  442. package/types/components/DataTableFacetMenu/index.d.ts +84 -0
  443. package/types/components/DataTableFacetMenu/index.d.ts.map +1 -0
  444. package/types/components/DataTableFilterButton/index.d.ts.map +1 -1
  445. package/types/components/DataTableFilterChips/FilterChip.d.ts +15 -0
  446. package/types/components/DataTableFilterChips/FilterChip.d.ts.map +1 -0
  447. package/types/components/DataTableFilterChips/index.d.ts +5 -0
  448. package/types/components/DataTableFilterChips/index.d.ts.map +1 -1
  449. package/types/components/DataTableFilters/index.d.ts +11 -0
  450. package/types/components/DataTableFilters/index.d.ts.map +1 -1
  451. package/types/components/DataTableGrouping/index.d.ts.map +1 -1
  452. package/types/components/DataTablePagination/index.d.ts +5 -0
  453. package/types/components/DataTablePagination/index.d.ts.map +1 -1
  454. package/types/components/DataTableSearch/index.d.ts.map +1 -1
  455. package/types/components/DataTableToolbar/index.d.ts +2 -0
  456. package/types/components/DataTableToolbar/index.d.ts.map +1 -1
  457. package/types/components/SimpleTable/index.d.ts +27 -5
  458. package/types/components/SimpleTable/index.d.ts.map +1 -1
  459. package/types/components/TableInput/index.d.ts +6 -1
  460. package/types/components/TableInput/index.d.ts.map +1 -1
  461. package/types/components/TableInput/index.native.d.ts +6 -1
  462. package/types/components/TableInput/index.native.d.ts.map +1 -1
  463. package/types/components/TableInput/shared.d.ts +38 -0
  464. package/types/components/TableInput/shared.d.ts.map +1 -1
  465. package/types/hooks/useDataTable.d.ts +1 -1
  466. package/types/hooks/useDataTable.d.ts.map +1 -1
  467. package/types/hooks/useInfiniteRows.d.ts +8 -1
  468. package/types/hooks/useInfiniteRows.d.ts.map +1 -1
  469. package/types/index.d.ts +1 -0
  470. package/types/index.d.ts.map +1 -1
  471. package/types/types.d.ts +54 -3
  472. package/types/types.d.ts.map +1 -1
  473. package/types/utils/filterUtils.d.ts.map +1 -1
@@ -20,7 +20,7 @@
20
20
  * their own layer (frappe-ui).
21
21
  */
22
22
 
23
- import { useCallback, useMemo } from "react";
23
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
24
24
  import {
25
25
  Button,
26
26
  Field,
@@ -32,17 +32,24 @@ import {
32
32
  import { flexRender, getCoreRowModel, useReactTable, type ColumnDef } from "@tanstack/react-table";
33
33
  import { TrashIcon, PlusIcon } from "@phosphor-icons/react";
34
34
  import { useTranslation } from "react-i18next";
35
- import { Text, XStack, YStack } from "tamagui";
35
+ import { Table, getTableCellPadding } from "@multiplatform.one/table-primitives";
36
+ import { hairline, useResolvedKnobs } from "@multiplatform.one/theme";
37
+ import { Text, XStack, YStack, isWeb } from "tamagui";
36
38
  import type {
37
39
  DataTableColumn,
38
40
  DataTableData,
39
41
  DataTableFieldProps,
40
42
  DataTableField,
41
43
  } from "../../types";
42
- import { Table } from "@multiplatform.one/table-primitives";
43
44
  import { DataTableCell } from "../DataTableCell";
44
45
  import { withInterp } from "../../utils/withInterp";
45
- import { generateRowId, isEmptyRows, SKELETON_ROW_COUNT } from "./shared";
46
+ import {
47
+ childRowAttrs,
48
+ childTableKeyAction,
49
+ generateRowId,
50
+ isEmptyRows,
51
+ SKELETON_ROW_COUNT,
52
+ } from "./shared";
46
53
 
47
54
  export interface TableInputProps<TData extends DataTableData = DataTableData> {
48
55
  /** Data array for the table (ignored in favor of form state in the form branch) */
@@ -83,6 +90,11 @@ export interface TableInputProps<TData extends DataTableData = DataTableData> {
83
90
  emptyMessage?: string;
84
91
  /** Accessible label */
85
92
  "aria-label"?: string;
93
+ /**
94
+ * Nested density (LC-73). Child tables sit on a form surface, so compact
95
+ * is the default — Frappe's grid is a dense in-list editor, not a page table.
96
+ */
97
+ compact?: boolean;
86
98
  }
87
99
 
88
100
  export function TableInput<TData extends DataTableData = DataTableData>({
@@ -105,6 +117,7 @@ export function TableInput<TData extends DataTableData = DataTableData>({
105
117
  defaultRow,
106
118
  emptyMessage,
107
119
  "aria-label": ariaLabel,
120
+ compact = true,
108
121
  }: TableInputProps<TData>) {
109
122
  const { t } = useTranslation();
110
123
  const { resolvedForm } = useFormField({ form: formProp });
@@ -139,6 +152,7 @@ export function TableInput<TData extends DataTableData = DataTableData>({
139
152
  defaultRow,
140
153
  emptyMessage: emptyMessage ?? t("No rows"),
141
154
  ariaLabel: resolvedAriaLabel,
155
+ compact,
142
156
  t,
143
157
  };
144
158
 
@@ -191,6 +205,7 @@ interface TableInputInnerProps<TData extends DataTableData> {
191
205
  defaultRow?: Partial<TData>;
192
206
  emptyMessage: string;
193
207
  ariaLabel: string;
208
+ compact: boolean;
194
209
  t: (key: string, options?: Record<string, unknown>) => string;
195
210
  }
196
211
 
@@ -209,8 +224,24 @@ function TableInputInner<TData extends DataTableData>({
209
224
  defaultRow,
210
225
  emptyMessage,
211
226
  ariaLabel,
227
+ compact,
212
228
  t,
213
229
  }: TableInputInnerProps<TData>) {
230
+ const { knobProps } = useResolvedKnobs({ compact });
231
+ const cellPad = getTableCellPadding(knobProps.space);
232
+ const chromePx = knobProps.nestedControl.px;
233
+ const [activeRowId, setActiveRowId] = useState<string | null>(null);
234
+ const pendingFocusRef = useRef<string | null>(null);
235
+ const gridRef = useRef<HTMLElement | null>(null);
236
+
237
+ const lastDataColumnId = useMemo(() => {
238
+ const last = columns[columns.length - 1];
239
+ if (!last) return null;
240
+ return typeof last.accessorKey === "string"
241
+ ? last.accessorKey
242
+ : last.id || String(last.accessorKey);
243
+ }, [columns]);
244
+
214
245
  const handleCellChange = useCallback(
215
246
  (rowIndex: number, columnId: string, value: unknown) => {
216
247
  onCellChange?.(rowIndex, columnId, value);
@@ -226,8 +257,10 @@ function TableInputInner<TData extends DataTableData>({
226
257
 
227
258
  const handleAddRow = useCallback(() => {
228
259
  if (maxRows && rows.length >= maxRows) return;
260
+ const id = generateRowId();
261
+ pendingFocusRef.current = id;
229
262
  const newRow = {
230
- id: generateRowId(),
263
+ id,
231
264
  ...defaultRow,
232
265
  } as unknown as TData;
233
266
  commit([...rows, newRow]);
@@ -241,24 +274,84 @@ function TableInputInner<TData extends DataTableData>({
241
274
  [rows, commit, minRows],
242
275
  );
243
276
 
277
+ useEffect(() => {
278
+ const id = pendingFocusRef.current;
279
+ if (!id || typeof document === "undefined") return;
280
+ pendingFocusRef.current = null;
281
+ const focus = () => {
282
+ const row = gridRef.current?.querySelector(`[${childRowAttrs.rowId}="${id}"]`);
283
+ const el = row?.querySelector<HTMLElement>(
284
+ `[${childRowAttrs.columnId}] input:not([type="hidden"]):not([type="checkbox"]):not([disabled]), [${childRowAttrs.columnId}] textarea, [${childRowAttrs.columnId}] button, [${childRowAttrs.columnId}] [tabindex]:not([tabindex="-1"])`,
285
+ );
286
+ el?.focus();
287
+ };
288
+ requestAnimationFrame(focus);
289
+ }, [rows]);
290
+
291
+ const focusCell = useCallback((rowIndex: number, columnId: string) => {
292
+ const el = gridRef.current?.querySelector<HTMLElement>(
293
+ `[${childRowAttrs.rowIndex}="${rowIndex}"] [${childRowAttrs.columnId}="${columnId}"] input:not([type="hidden"]):not([disabled]), [${childRowAttrs.rowIndex}="${rowIndex}"] [${childRowAttrs.columnId}="${columnId}"] textarea, [${childRowAttrs.rowIndex}="${rowIndex}"] [${childRowAttrs.columnId}="${columnId}"] button, [${childRowAttrs.rowIndex}="${rowIndex}"] [${childRowAttrs.columnId}="${columnId}"] [tabindex]:not([tabindex="-1"])`,
294
+ );
295
+ el?.focus();
296
+ }, []);
297
+
298
+ const canAddRow = !maxRows || rows.length < maxRows;
299
+
300
+ const handleGridKeyDown = useCallback(
301
+ (e: {
302
+ key: string;
303
+ shiftKey: boolean;
304
+ altKey: boolean;
305
+ metaKey: boolean;
306
+ ctrlKey: boolean;
307
+ target: EventTarget | null;
308
+ preventDefault: () => void;
309
+ }) => {
310
+ if (readOnly || skeleton) return;
311
+ const target = e.target as HTMLElement | null;
312
+ if (!target) return;
313
+ const row = target.closest(`[${childRowAttrs.row}]`) as HTMLElement | null;
314
+ if (!row) return;
315
+ const rowIndex = Number(row.getAttribute(childRowAttrs.rowIndex));
316
+ if (Number.isNaN(rowIndex)) return;
317
+ const action = childTableKeyAction(e, {
318
+ rowIndex,
319
+ rowCount: rows.length,
320
+ columnId:
321
+ target.closest(`[${childRowAttrs.columnId}]`)?.getAttribute(childRowAttrs.columnId) ??
322
+ null,
323
+ inLastDataCell: !!target.closest(`[${childRowAttrs.lastInput}="true"]`),
324
+ field:
325
+ target.closest(`[${childRowAttrs.field}]`)?.getAttribute(childRowAttrs.field) ?? null,
326
+ tagName: target.tagName,
327
+ listboxOpen:
328
+ typeof document !== "undefined" && !!document.querySelector('[role="listbox"]'),
329
+ canAddRow: Boolean(showAddRow && canAddRow),
330
+ });
331
+ if (!action) return;
332
+ e.preventDefault();
333
+ if (action.type === "addRow") handleAddRow();
334
+ else focusCell(action.rowIndex, action.columnId);
335
+ },
336
+ [readOnly, skeleton, rows.length, showAddRow, canAddRow, handleAddRow, focusCell],
337
+ );
338
+
244
339
  const tableColumns = useMemo(() => {
245
340
  const cols: ColumnDef<TData, unknown>[] = [];
246
341
 
247
- // Row number column
248
342
  if (showRowNumbers) {
249
343
  cols.push({
250
344
  id: "_rowNumber",
251
345
  header: "#",
252
- size: 50,
346
+ size: Math.max(36, chromePx),
253
347
  cell: ({ row }) => (
254
- <Text color="$gray11" fontSize="$2">
348
+ <Text color="$color10" fontSize={knobProps.label.fontSize}>
255
349
  {row.index + 1}
256
350
  </Text>
257
351
  ),
258
352
  });
259
353
  }
260
354
 
261
- // Data columns
262
355
  columns.forEach((col) => {
263
356
  const columnId =
264
357
  typeof col.accessorKey === "string" ? col.accessorKey : col.id || String(col.accessorKey);
@@ -278,6 +371,7 @@ function TableInputInner<TData extends DataTableData>({
278
371
  field={field}
279
372
  fieldProps={fieldProps}
280
373
  readOnly={readOnly}
374
+ compact={compact}
281
375
  columnId={columnId}
282
376
  columnLabel={typeof col.header === "string" ? col.header : undefined}
283
377
  rowIndex={row.index}
@@ -288,20 +382,20 @@ function TableInputInner<TData extends DataTableData>({
288
382
  } as ColumnDef<TData, unknown>);
289
383
  });
290
384
 
291
- // Delete column
292
385
  if (showDeleteRow && !readOnly) {
293
386
  cols.push({
294
387
  id: "_actions",
295
388
  header: "",
296
- size: 50,
389
+ size: chromePx + 16,
297
390
  cell: ({ row }) => {
298
391
  const canDelete = !minRows || rows.length > minRows;
299
392
  return (
300
393
  <Button
301
- size="$2"
302
- outlined
394
+ chromeless
395
+ compact={compact}
303
396
  onPress={() => handleDeleteRow(row.index)}
304
397
  disabled={!canDelete}
398
+ hitSlop={knobProps.nestedControl.hitSlop}
305
399
  aria-label={withInterp(t("Delete row {{row}}", { row: row.index + 1 }), {
306
400
  row: row.index + 1,
307
401
  })}
@@ -324,6 +418,10 @@ function TableInputInner<TData extends DataTableData>({
324
418
  rows.length,
325
419
  minRows,
326
420
  t,
421
+ compact,
422
+ chromePx,
423
+ knobProps.label.fontSize,
424
+ knobProps.nestedControl.hitSlop,
327
425
  ]);
328
426
 
329
427
  const table = useReactTable({
@@ -335,18 +433,45 @@ function TableInputInner<TData extends DataTableData>({
335
433
  getRowId: (row, index) => String((row as DataTableData).id ?? index),
336
434
  });
337
435
 
338
- const canAddRow = !maxRows || rows.length < maxRows;
339
- // The primitives table renders CSS-table boxes (divs), so colSpan cannot
340
- // span the empty-state message across columns. With no body rows to align,
341
- // the empty (and skeleton-free) state flips the table to flex layout where
342
- // a single auto-width cell genuinely fills the row.
436
+ // Empty state flips to flex so a single auto-width cell fills the row
437
+ // (colSpan is unreliable when displayMode is overridden).
343
438
  const isEmpty = !skeleton && rows.length === 0;
439
+ const showAdd = showAddRow && !readOnly;
440
+
441
+ const addRowControl =
442
+ skeleton && showAdd ? (
443
+ <XStack {...hairline.top} {...cellPad}>
444
+ <Skeleton variant="rounded" width={100} height={chromePx} />
445
+ </XStack>
446
+ ) : showAdd && !skeleton ? (
447
+ <XStack {...hairline.top} {...cellPad}>
448
+ <Button
449
+ chromeless
450
+ compact={compact}
451
+ onPress={handleAddRow}
452
+ disabled={!canAddRow}
453
+ icon={<PlusIcon size={16} />}
454
+ >
455
+ {t("Add Row")}
456
+ </Button>
457
+ </XStack>
458
+ ) : null;
344
459
 
345
460
  return (
346
- <YStack gap="$2">
461
+ <YStack
462
+ ref={gridRef as never}
463
+ {...knobProps.surface}
464
+ {...knobProps.borderRadiusOuter}
465
+ elevation={knobProps.elevation}
466
+ overflow="hidden"
467
+ {...(isWeb ? { onKeyDown: handleGridKeyDown as never } : null)}
468
+ >
347
469
  <Table
348
470
  aria-label={ariaLabel}
349
471
  aria-busy={skeleton || undefined}
472
+ borderWidth={0}
473
+ borderRadius={0}
474
+ elevation={undefined}
350
475
  {...(isEmpty ? { displayMode: "flex" as const } : null)}
351
476
  >
352
477
  <Table.Head>
@@ -357,8 +482,6 @@ function TableInputInner<TData extends DataTableData>({
357
482
  key={header.id}
358
483
  style={{
359
484
  width: header.getSize(),
360
- // Flex-mode headers don't get fixed-layout stretch; let
361
- // data columns grow so the header strip fills the row.
362
485
  ...(isEmpty &&
363
486
  header.column.id !== "_rowNumber" &&
364
487
  header.column.id !== "_actions"
@@ -394,41 +517,59 @@ function TableInputInner<TData extends DataTableData>({
394
517
  ) : isEmpty ? (
395
518
  <Table.Row>
396
519
  <Table.Cell cellWidth="auto" justifyContent="center">
397
- <Text color="$gray11">{emptyMessage}</Text>
520
+ <Text color="$color10">{emptyMessage}</Text>
398
521
  </Table.Cell>
399
522
  </Table.Row>
400
523
  ) : (
401
- table.getRowModel().rows.map((row) => (
402
- <Table.Row key={row.id}>
403
- {row.getVisibleCells().map((cell) => (
404
- <Table.Cell key={cell.id}>
405
- {flexRender(cell.column.columnDef.cell, cell.getContext())}
406
- </Table.Cell>
407
- ))}
408
- </Table.Row>
409
- ))
524
+ table.getRowModel().rows.map((row) => {
525
+ const isActive = activeRowId === row.id;
526
+ return (
527
+ <Table.Row
528
+ key={row.id}
529
+ {...{ [childRowAttrs.row]: "true" }}
530
+ {...{ [childRowAttrs.rowId]: row.id }}
531
+ {...{ [childRowAttrs.rowIndex]: String(row.index) }}
532
+ {...{ [childRowAttrs.active]: isActive ? "true" : undefined }}
533
+ backgroundColor={isActive ? "$color3" : undefined}
534
+ hoverStyle={{ backgroundColor: "$backgroundHover" }}
535
+ transition={knobProps.transition}
536
+ // onFocusCapture is a web-only capture-phase handler outside
537
+ // ThemedRowProps; the bag forwards it to the DOM <tr> (house
538
+ // Record cast). Tracks the active row as focus enters it.
539
+ {...({ onFocusCapture: () => setActiveRowId(row.id) } as Record<string, unknown>)}
540
+ >
541
+ {row.getVisibleCells().map((cell) => {
542
+ const isData = cell.column.id !== "_rowNumber" && cell.column.id !== "_actions";
543
+ const field = columns.find((col) => {
544
+ const id =
545
+ typeof col.accessorKey === "string"
546
+ ? col.accessorKey
547
+ : col.id || String(col.accessorKey);
548
+ return id === cell.column.id;
549
+ })?.field;
550
+ return (
551
+ <Table.Cell
552
+ key={cell.id}
553
+ {...(isData
554
+ ? {
555
+ [childRowAttrs.columnId]: cell.column.id,
556
+ [childRowAttrs.field]: (field as string) || "input",
557
+ [childRowAttrs.lastInput]:
558
+ cell.column.id === lastDataColumnId ? "true" : undefined,
559
+ }
560
+ : null)}
561
+ >
562
+ {flexRender(cell.column.columnDef.cell, cell.getContext())}
563
+ </Table.Cell>
564
+ );
565
+ })}
566
+ </Table.Row>
567
+ );
568
+ })
410
569
  )}
411
570
  </Table.Body>
412
571
  </Table>
413
-
414
- {showAddRow && !readOnly && !skeleton && (
415
- <XStack>
416
- <Button
417
- size="$2"
418
- outlined
419
- onPress={handleAddRow}
420
- disabled={!canAddRow}
421
- icon={<PlusIcon size={16} />}
422
- >
423
- {t("Add Row")}
424
- </Button>
425
- </XStack>
426
- )}
427
- {skeleton && showAddRow && !readOnly && (
428
- <XStack>
429
- <Skeleton variant="rounded" width={100} height={28} />
430
- </XStack>
431
- )}
572
+ {addRowControl}
432
573
  </YStack>
433
574
  );
434
575
  }
@@ -18,3 +18,60 @@ export const SKELETON_ROW_COUNT = 3;
18
18
  /** Required-validator emptiness for row arrays (default only catches null/""). */
19
19
  export const isEmptyRows = (value: unknown): boolean =>
20
20
  value === null || value === undefined || (Array.isArray(value) && value.length === 0);
21
+
22
+ /** DOM hooks for Frappe-grid keyboard (Tab-on-last-adds-row, arrow between rows). */
23
+ export const childRowAttrs = {
24
+ row: "data-child-row",
25
+ rowId: "data-child-row-id",
26
+ rowIndex: "data-child-row-index",
27
+ columnId: "data-column-id",
28
+ lastInput: "data-last-input",
29
+ field: "data-field",
30
+ active: "data-active",
31
+ } as const;
32
+
33
+ const STEPPER_FIELD = "stepper";
34
+
35
+ /**
36
+ * Frappe grid_row.set_arrow_keys: Tab on the last data cell of the last row
37
+ * inserts a row; Up/Down move to the same column in the adjacent row.
38
+ * Returns the action the grid should take, or null when the event is not ours
39
+ * (textarea, stepper, open listbox, etc.).
40
+ */
41
+ export function childTableKeyAction(
42
+ e: {
43
+ key: string;
44
+ shiftKey: boolean;
45
+ altKey: boolean;
46
+ metaKey: boolean;
47
+ ctrlKey: boolean;
48
+ },
49
+ ctx: {
50
+ rowIndex: number;
51
+ rowCount: number;
52
+ columnId: string | null;
53
+ inLastDataCell: boolean;
54
+ field: string | null;
55
+ tagName: string;
56
+ listboxOpen: boolean;
57
+ canAddRow: boolean;
58
+ },
59
+ ): { type: "addRow" } | { type: "move"; rowIndex: number; columnId: string } | null {
60
+ if (e.altKey || e.metaKey || e.ctrlKey) return null;
61
+ if (ctx.tagName === "TEXTAREA") return null;
62
+ if (ctx.field === STEPPER_FIELD) return null;
63
+ if (ctx.listboxOpen) return null;
64
+
65
+ if (e.key === "Tab" && !e.shiftKey) {
66
+ if (ctx.inLastDataCell && ctx.rowIndex === ctx.rowCount - 1 && ctx.canAddRow) {
67
+ return { type: "addRow" };
68
+ }
69
+ return null;
70
+ }
71
+
72
+ if (e.key !== "ArrowUp" && e.key !== "ArrowDown") return null;
73
+ if (!ctx.columnId) return null;
74
+ const next = e.key === "ArrowDown" ? ctx.rowIndex + 1 : ctx.rowIndex - 1;
75
+ if (next < 0 || next >= ctx.rowCount) return null;
76
+ return { type: "move", rowIndex: next, columnId: ctx.columnId };
77
+ }
@@ -37,6 +37,7 @@ import { describe, expect, it, vi } from "vitest";
37
37
  import type { DataTableColumn, DataTableData } from "../../types";
38
38
  import { TableInput } from "./index";
39
39
  import { ChildTable } from "../ChildTable";
40
+ import { childTableKeyAction } from "./shared";
40
41
 
41
42
  interface Row extends DataTableData {
42
43
  id: string;
@@ -456,3 +457,106 @@ describe("ChildTable — field wrapper integration", () => {
456
457
  expect(screen.getByRole("group", { name: /Line items/ })).toBeTruthy();
457
458
  });
458
459
  });
460
+
461
+ describe("TableInput — Frappe grid + LC-71", () => {
462
+ const keys = {
463
+ key: "",
464
+ shiftKey: false,
465
+ altKey: false,
466
+ metaKey: false,
467
+ ctrlKey: false,
468
+ };
469
+
470
+ it("Tab on the last data cell of the last row adds a row", () => {
471
+ expect(
472
+ childTableKeyAction(
473
+ { ...keys, key: "Tab" },
474
+ {
475
+ rowIndex: 2,
476
+ rowCount: 3,
477
+ columnId: "urgent",
478
+ inLastDataCell: true,
479
+ field: "checkbox",
480
+ tagName: "INPUT",
481
+ listboxOpen: false,
482
+ canAddRow: true,
483
+ },
484
+ ),
485
+ ).toEqual({ type: "addRow" });
486
+ });
487
+
488
+ it("Tab on a middle cell does not add a row", () => {
489
+ expect(
490
+ childTableKeyAction(
491
+ { ...keys, key: "Tab" },
492
+ {
493
+ rowIndex: 2,
494
+ rowCount: 3,
495
+ columnId: "item",
496
+ inLastDataCell: false,
497
+ field: "input",
498
+ tagName: "INPUT",
499
+ listboxOpen: false,
500
+ canAddRow: true,
501
+ },
502
+ ),
503
+ ).toBeNull();
504
+ });
505
+
506
+ it("ArrowDown/Up move to the same column; stepper and textarea are ignored", () => {
507
+ expect(
508
+ childTableKeyAction(
509
+ { ...keys, key: "ArrowDown" },
510
+ {
511
+ rowIndex: 0,
512
+ rowCount: 3,
513
+ columnId: "item",
514
+ inLastDataCell: false,
515
+ field: "input",
516
+ tagName: "INPUT",
517
+ listboxOpen: false,
518
+ canAddRow: true,
519
+ },
520
+ ),
521
+ ).toEqual({ type: "move", rowIndex: 1, columnId: "item" });
522
+ expect(
523
+ childTableKeyAction(
524
+ { ...keys, key: "ArrowDown" },
525
+ {
526
+ rowIndex: 0,
527
+ rowCount: 3,
528
+ columnId: "qty",
529
+ inLastDataCell: false,
530
+ field: "stepper",
531
+ tagName: "INPUT",
532
+ listboxOpen: false,
533
+ canAddRow: true,
534
+ },
535
+ ),
536
+ ).toBeNull();
537
+ });
538
+
539
+ it("Add Row lives inside the grid frame (Frappe grid-footer)", () => {
540
+ const { container } = renderStandalone();
541
+ const add = screen.getByRole("button", { name: "Add Row" });
542
+ const frame = container.querySelector('[aria-label="Table input"]')?.parentElement;
543
+ expect(frame?.contains(add)).toBe(true);
544
+ });
545
+
546
+ it("focusing a cell marks that row active (LC-71 selected = fill)", async () => {
547
+ renderStandalone();
548
+ const input = screen.getByDisplayValue("Bracket");
549
+ expect(input.closest("[data-active='true']")).toBeNull();
550
+ await userEvent.click(input);
551
+ expect(input.closest("[data-active='true']")).toBeTruthy();
552
+ });
553
+
554
+ it("Tab on the last cell of the last row commits a new row through onChange", async () => {
555
+ const onChange = vi.fn();
556
+ renderWithProviders(<Controlled onChange={onChange} />);
557
+ const checkboxes = screen.getAllByRole("checkbox");
558
+ fireEvent.keyDown(checkboxes[checkboxes.length - 1], { key: "Tab" });
559
+ expect(onChange).toHaveBeenCalledTimes(1);
560
+ expect(onChange.mock.calls[0][0]).toHaveLength(4);
561
+ });
562
+ });
@@ -1,4 +1,6 @@
1
+ import { act, renderHook } from "@testing-library/react";
1
2
  import { beforeEach, describe, expect, it, vi } from "vitest";
3
+ import type { DataTableColumn, DataTableState, TableFilter } from "../types";
2
4
  import { useDataTable } from "./useDataTable";
3
5
 
4
6
  describe("useDataTable", () => {
@@ -9,8 +11,103 @@ describe("useDataTable", () => {
9
11
  it("should be defined", () => {
10
12
  expect(useDataTable).toBeDefined();
11
13
  });
14
+ });
15
+
16
+ // ---------------------------------------------------------------------------
17
+ // controlledState adoption — the keep-rows-and-reconcile channel
18
+ // (filter/sort changes from an OUTER surface adopt in place, no remount)
19
+ // ---------------------------------------------------------------------------
20
+
21
+ const data = [
22
+ { id: 1, name: "Alice", status: "Active" },
23
+ { id: 2, name: "Bob", status: "Lead" },
24
+ { id: 3, name: "Charlie", status: "Active" },
25
+ ];
26
+
27
+ const columns: DataTableColumn<(typeof data)[number]>[] = [
28
+ { id: "name", accessorKey: "name", header: "Name" },
29
+ { id: "status", accessorKey: "status", header: "Status" },
30
+ ];
31
+
32
+ const statusFilter = (value: string): TableFilter => ({
33
+ id: `status-${value}`,
34
+ columnId: "status",
35
+ value: { operator: "is", value },
36
+ });
37
+
38
+ function renderControlled(initialControlled: Partial<Pick<DataTableState, "filters" | "sorting">>) {
39
+ return renderHook(
40
+ ({ controlled }: { controlled: Partial<Pick<DataTableState, "filters" | "sorting">> }) =>
41
+ useDataTable({
42
+ data,
43
+ columns,
44
+ controlledState: controlled,
45
+ initialState: {
46
+ filters: initialControlled.filters ?? [],
47
+ sorting: initialControlled.sorting ?? [],
48
+ pagination: { pageIndex: 2, pageSize: 1 },
49
+ },
50
+ }),
51
+ { initialProps: { controlled: initialControlled } },
52
+ );
53
+ }
54
+
55
+ describe("useDataTable controlledState adoption", () => {
56
+ it("adopts an inbound filter CONTENT change in place and resets to page 0", () => {
57
+ const { result, rerender } = renderControlled({ filters: [] });
58
+ expect(result.current.state.filters).toEqual([]);
59
+ expect(result.current.state.pagination.pageIndex).toBe(2);
60
+
61
+ act(() => {
62
+ rerender({ controlled: { filters: [statusFilter("Active")] } });
63
+ });
64
+
65
+ expect(result.current.state.filters).toHaveLength(1);
66
+ expect(result.current.state.filters[0].columnId).toBe("status");
67
+ expect(result.current.state.pagination.pageIndex).toBe(0);
68
+ });
69
+
70
+ it("a same-content echo (new array identity) is a no-op — internal state is never fought", () => {
71
+ const initial = { filters: [statusFilter("Active")] };
72
+ const { result, rerender } = renderControlled(initial);
12
73
 
13
- // Note: More comprehensive tests would require React Testing Library
14
- // and rendering the hook in a test component. This is a placeholder
15
- // for when the hook implementation is available.
74
+ // User pages forward through the table's own chrome.
75
+ act(() => {
76
+ result.current.actions.setPagination({ pageIndex: 1, pageSize: 1 });
77
+ });
78
+ expect(result.current.state.pagination.pageIndex).toBe(1);
79
+
80
+ // Outer surface re-renders with the SAME tuples in a fresh array.
81
+ act(() => {
82
+ rerender({ controlled: { filters: [statusFilter("Active")] } });
83
+ });
84
+
85
+ // No adoption: page position (user work) survives.
86
+ expect(result.current.state.pagination.pageIndex).toBe(1);
87
+ expect(result.current.state.filters).toHaveLength(1);
88
+ });
89
+
90
+ it("adopts an inbound sorting change in place and resets to page 0", () => {
91
+ const { result, rerender } = renderControlled({ sorting: [{ id: "name", desc: false }] });
92
+ expect(result.current.state.sorting).toEqual([{ id: "name", desc: false }]);
93
+ expect(result.current.state.pagination.pageIndex).toBe(2);
94
+
95
+ act(() => {
96
+ rerender({ controlled: { sorting: [{ id: "status", desc: true }] } });
97
+ });
98
+
99
+ expect(result.current.state.sorting).toEqual([{ id: "status", desc: true }]);
100
+ expect(result.current.state.pagination.pageIndex).toBe(0);
101
+ });
102
+
103
+ it("clearing filters through the channel adopts the empty set", () => {
104
+ const { result, rerender } = renderControlled({ filters: [statusFilter("Active")] });
105
+ expect(result.current.state.filters).toHaveLength(1);
106
+
107
+ act(() => {
108
+ rerender({ controlled: { filters: [] } });
109
+ });
110
+
111
+ expect(result.current.state.filters).toEqual([]);
112
+ });
16
113
  });