@multiplatform.one/table 6.7.0 → 7.0.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
@@ -0,0 +1,264 @@
1
+ import { renderWithProviders } from "@multiplatform.one/test-utils";
2
+ import { fireEvent, waitFor } from "@testing-library/react";
3
+ import { describe, expect, it, vi } from "vitest";
4
+ import { DataTableFacetMenu, type DataTableFacetOption } from "./index";
5
+
6
+ const options: DataTableFacetOption[] = [
7
+ { value: "alice@example.com", label: "Alice", count: 12 },
8
+ { value: "bob@example.com", label: "Bob", count: 4 },
9
+ { value: "carol@example.com", label: "Carol", count: 0 },
10
+ ];
11
+
12
+ async function openMenu(
13
+ utils: ReturnType<typeof renderWithProviders>,
14
+ name = "Assigned To",
15
+ ): Promise<void> {
16
+ fireEvent.click(utils.getByRole("button", { name }));
17
+ await waitFor(
18
+ () => {
19
+ expect(utils.getAllByRole("menuitemcheckbox").length).toBeGreaterThan(0);
20
+ },
21
+ { timeout: 3000 },
22
+ );
23
+ }
24
+
25
+ describe("DataTableFacetMenu", () => {
26
+ describe("trigger", () => {
27
+ it("renders the facet label as the trigger", () => {
28
+ const { getByRole } = renderWithProviders(
29
+ <DataTableFacetMenu label="Assigned To" options={options} />,
30
+ );
31
+ const trigger = getByRole("button", { name: "Assigned To" });
32
+ expect(trigger).toBeDefined();
33
+ expect(trigger.textContent).toContain("Assigned To");
34
+ });
35
+
36
+ it("carries the active count on the trigger", () => {
37
+ const { getByRole } = renderWithProviders(
38
+ <DataTableFacetMenu
39
+ label="Assigned To"
40
+ options={options}
41
+ activeValues={["alice@example.com"]}
42
+ />,
43
+ );
44
+ expect(getByRole("button", { name: "Assigned To" }).textContent).toContain(
45
+ "Assigned To (1)",
46
+ );
47
+ });
48
+
49
+ it("does not render menu rows while closed", () => {
50
+ const { queryAllByRole } = renderWithProviders(
51
+ <DataTableFacetMenu label="Assigned To" options={options} />,
52
+ );
53
+ expect(queryAllByRole("menuitemcheckbox").length).toBe(0);
54
+ });
55
+ });
56
+
57
+ describe("menu content", () => {
58
+ it("renders one checkbox row per option with its count", async () => {
59
+ const utils = renderWithProviders(
60
+ <DataTableFacetMenu label="Assigned To" options={options} />,
61
+ );
62
+ await openMenu(utils);
63
+ const rows = utils.getAllByRole("menuitemcheckbox");
64
+ expect(rows.length).toBe(3);
65
+ expect(rows[0].textContent).toContain("Alice");
66
+ expect(rows[0].textContent).toContain("12");
67
+ expect(rows[1].textContent).toContain("Bob");
68
+ expect(rows[1].textContent).toContain("4");
69
+ });
70
+
71
+ it("falls back to the raw value when an option has no label", async () => {
72
+ const utils = renderWithProviders(
73
+ <DataTableFacetMenu label="Tags" options={[{ value: "urgent", count: 2 }]} />,
74
+ );
75
+ await openMenu(utils, "Tags");
76
+ expect(utils.getAllByRole("menuitemcheckbox")[0].textContent).toContain("urgent");
77
+ });
78
+
79
+ it("marks active options checked", async () => {
80
+ const utils = renderWithProviders(
81
+ <DataTableFacetMenu
82
+ label="Assigned To"
83
+ options={options}
84
+ activeValues={["bob@example.com"]}
85
+ />,
86
+ );
87
+ await openMenu(utils);
88
+ const rows = utils.getAllByRole("menuitemcheckbox");
89
+ expect(rows[0].getAttribute("aria-checked")).toBe("false");
90
+ expect(rows[1].getAttribute("aria-checked")).toBe("true");
91
+ });
92
+
93
+ it("shows an empty state when there are no options and not loading", async () => {
94
+ const utils = renderWithProviders(<DataTableFacetMenu label="Tags" options={[]} />);
95
+ fireEvent.click(utils.getByRole("button", { name: "Tags" }));
96
+ await waitFor(() => {
97
+ expect(utils.getByText("No options")).toBeDefined();
98
+ });
99
+ });
100
+
101
+ it("shows a loading indicator and keeps stale options visible", async () => {
102
+ const utils = renderWithProviders(
103
+ <DataTableFacetMenu label="Assigned To" options={options} loading />,
104
+ );
105
+ await openMenu(utils);
106
+ // Stale-while-visible: prior options stay rendered while revalidating.
107
+ expect(utils.getAllByRole("menuitemcheckbox").length).toBe(3);
108
+ expect(utils.baseElement.querySelector("[data-facet-loading='true']")).toBeTruthy();
109
+ });
110
+
111
+ it("suppresses the empty state while loading with no options", async () => {
112
+ const utils = renderWithProviders(
113
+ <DataTableFacetMenu label="Assigned To" options={[]} loading />,
114
+ );
115
+ fireEvent.click(utils.getByRole("button", { name: "Assigned To" }));
116
+ await waitFor(() => {
117
+ expect(utils.baseElement.querySelector("[data-facet-loading='true']")).toBeTruthy();
118
+ });
119
+ expect(utils.queryByText("No options")).toBeNull();
120
+ });
121
+ });
122
+
123
+ describe("replace selection (desk facet semantics)", () => {
124
+ it("replaces the selection with the pressed option", async () => {
125
+ const onActiveValuesChange = vi.fn();
126
+ const utils = renderWithProviders(
127
+ <DataTableFacetMenu
128
+ label="Assigned To"
129
+ options={options}
130
+ activeValues={["alice@example.com"]}
131
+ onActiveValuesChange={onActiveValuesChange}
132
+ />,
133
+ );
134
+ await openMenu(utils);
135
+ fireEvent.click(utils.getAllByRole("menuitemcheckbox")[1]);
136
+ expect(onActiveValuesChange).toHaveBeenCalledWith(["bob@example.com"], options[1]);
137
+ });
138
+
139
+ it("clears the selection when the active option is pressed", async () => {
140
+ const onActiveValuesChange = vi.fn();
141
+ const utils = renderWithProviders(
142
+ <DataTableFacetMenu
143
+ label="Assigned To"
144
+ options={options}
145
+ activeValues={["alice@example.com"]}
146
+ onActiveValuesChange={onActiveValuesChange}
147
+ />,
148
+ );
149
+ await openMenu(utils);
150
+ fireEvent.click(utils.getAllByRole("menuitemcheckbox")[0]);
151
+ expect(onActiveValuesChange).toHaveBeenCalledWith([], options[0]);
152
+ });
153
+ });
154
+
155
+ describe("toggle selection (multi-select)", () => {
156
+ it("adds the pressed option to the active set", async () => {
157
+ const onActiveValuesChange = vi.fn();
158
+ const utils = renderWithProviders(
159
+ <DataTableFacetMenu
160
+ label="Tags"
161
+ selection="toggle"
162
+ options={options}
163
+ activeValues={["alice@example.com"]}
164
+ onActiveValuesChange={onActiveValuesChange}
165
+ />,
166
+ );
167
+ await openMenu(utils, "Tags");
168
+ fireEvent.click(utils.getAllByRole("menuitemcheckbox")[1]);
169
+ expect(onActiveValuesChange).toHaveBeenCalledWith(
170
+ ["alice@example.com", "bob@example.com"],
171
+ options[1],
172
+ );
173
+ });
174
+
175
+ it("removes only the pressed option when it is active", async () => {
176
+ const onActiveValuesChange = vi.fn();
177
+ const utils = renderWithProviders(
178
+ <DataTableFacetMenu
179
+ label="Tags"
180
+ selection="toggle"
181
+ options={options}
182
+ activeValues={["alice@example.com", "bob@example.com"]}
183
+ onActiveValuesChange={onActiveValuesChange}
184
+ />,
185
+ );
186
+ await openMenu(utils, "Tags");
187
+ fireEvent.click(utils.getAllByRole("menuitemcheckbox")[0]);
188
+ expect(onActiveValuesChange).toHaveBeenCalledWith(["bob@example.com"], options[0]);
189
+ });
190
+ });
191
+
192
+ describe("compose behavior", () => {
193
+ it("keeps the menu open after a selection (counts revalidate in place)", async () => {
194
+ const utils = renderWithProviders(
195
+ <DataTableFacetMenu
196
+ label="Assigned To"
197
+ options={options}
198
+ onActiveValuesChange={() => {}}
199
+ />,
200
+ );
201
+ await openMenu(utils);
202
+ fireEvent.click(utils.getAllByRole("menuitemcheckbox")[0]);
203
+ // CheckboxItem COMPOSE default: the menu must not close on select.
204
+ expect(utils.getAllByRole("menuitemcheckbox").length).toBe(3);
205
+ });
206
+ });
207
+
208
+ describe("compound composition", () => {
209
+ it("renders custom Item children instead of options", async () => {
210
+ const onPress = vi.fn();
211
+ const utils = renderWithProviders(
212
+ <DataTableFacetMenu label="Status">
213
+ <DataTableFacetMenu.Item label="Open" count={7} active onPress={onPress} />
214
+ <DataTableFacetMenu.Item label="Closed" count={1} onPress={() => {}} />
215
+ </DataTableFacetMenu>,
216
+ );
217
+ await openMenu(utils, "Status");
218
+ const rows = utils.getAllByRole("menuitemcheckbox");
219
+ expect(rows.length).toBe(2);
220
+ expect(rows[0].textContent).toContain("Open");
221
+ expect(rows[0].textContent).toContain("7");
222
+ expect(rows[0].getAttribute("aria-checked")).toBe("true");
223
+ fireEvent.click(rows[0]);
224
+ expect(onPress).toHaveBeenCalledTimes(1);
225
+ });
226
+ });
227
+
228
+ describe("disabled state", () => {
229
+ it("renders a disabled trigger with its reason", () => {
230
+ const { getByRole } = renderWithProviders(
231
+ <DataTableFacetMenu
232
+ label="Assigned To"
233
+ options={options}
234
+ disabled
235
+ disabledReason="Assignments are unavailable offline"
236
+ />,
237
+ );
238
+ const trigger = getByRole("button", { name: /Assigned To/ });
239
+ expect(trigger.getAttribute("aria-disabled") ?? trigger.getAttribute("disabled")).not.toBe(
240
+ null,
241
+ );
242
+ });
243
+ });
244
+
245
+ describe("edge cases", () => {
246
+ it("handles option presses without an onActiveValuesChange handler", async () => {
247
+ const utils = renderWithProviders(
248
+ <DataTableFacetMenu label="Assigned To" options={options} />,
249
+ );
250
+ await openMenu(utils);
251
+ expect(() => {
252
+ fireEvent.click(utils.getAllByRole("menuitemcheckbox")[0]);
253
+ }).not.toThrow();
254
+ });
255
+
256
+ it("renders options without counts (no trailing number)", async () => {
257
+ const utils = renderWithProviders(
258
+ <DataTableFacetMenu label="Module" options={[{ value: "Core", label: "Core" }]} />,
259
+ );
260
+ await openMenu(utils, "Module");
261
+ expect(utils.getAllByRole("menuitemcheckbox")[0].textContent).toBe("Core");
262
+ });
263
+ });
264
+ });
@@ -0,0 +1,212 @@
1
+ import { action } from "@multiplatform.one/storybook";
2
+ import type { Meta } from "@storybook/react-native-web-vite";
3
+ import { useMemo, useState } from "react";
4
+ import { XStack, YStack } from "tamagui";
5
+ import type { DataTableColumn } from "../../types";
6
+ import { DataTable } from "../DataTable";
7
+ import { DataTableToolbar } from "../DataTableToolbar";
8
+ import { DataTableFacetMenu, type DataTableFacetOption } from "./index";
9
+
10
+ const meta: Meta<typeof DataTableFacetMenu> = {
11
+ title: "Table/DataTableFacetMenu",
12
+ component: DataTableFacetMenu,
13
+ parameters: {
14
+ status: { type: "stable" },
15
+ },
16
+ };
17
+
18
+ export default meta;
19
+
20
+ interface Ticket {
21
+ id: number;
22
+ title: string;
23
+ assignee: string;
24
+ status: "Open" | "Working" | "Closed";
25
+ tags: string;
26
+ }
27
+
28
+ const tickets: Ticket[] = [
29
+ { id: 1, title: "Fix login redirect", assignee: "Alice", status: "Open", tags: "bug" },
30
+ { id: 2, title: "Dark mode pass", assignee: "Bob", status: "Working", tags: "design" },
31
+ { id: 3, title: "Broken CSV export", assignee: "Alice", status: "Open", tags: "bug,export" },
32
+ { id: 4, title: "Onboarding tour", assignee: "Carol", status: "Closed", tags: "design" },
33
+ { id: 5, title: "Rate limit uploads", assignee: "Alice", status: "Working", tags: "infra" },
34
+ { id: 6, title: "Audit log screen", assignee: "Bob", status: "Open", tags: "infra,bug" },
35
+ ];
36
+
37
+ const ticketColumns: DataTableColumn<Ticket>[] = [
38
+ { accessorKey: "title", header: "Title" },
39
+ { accessorKey: "assignee", header: "Assignee" },
40
+ { accessorKey: "status", header: "Status" },
41
+ { accessorKey: "tags", header: "Tags" },
42
+ ];
43
+
44
+ function countBy(rows: Ticket[], pick: (row: Ticket) => string[]): DataTableFacetOption[] {
45
+ const counts = new Map<string, number>();
46
+ for (const row of rows) {
47
+ for (const value of pick(row)) counts.set(value, (counts.get(value) ?? 0) + 1);
48
+ }
49
+ return [...counts.entries()]
50
+ .map(([value, count]) => ({ value, count }))
51
+ .sort((a, b) => b.count - a.count || a.value.localeCompare(b.value));
52
+ }
53
+
54
+ /**
55
+ * The intended composition: facet menus slot into the DataTableToolbar
56
+ * action cluster (customActions) beside the Filter button, feeding the
57
+ * host's own filter state — here the story filters the rows it hands the
58
+ * table, the same shape a Frappe host gets from useFrappeFacets.
59
+ */
60
+ const InToolbarStory = () => {
61
+ const [assignee, setAssignee] = useState<string[]>([]);
62
+ const [statuses, setStatuses] = useState<string[]>([]);
63
+
64
+ const rows = useMemo(
65
+ () =>
66
+ tickets.filter(
67
+ (ticket) =>
68
+ (assignee.length === 0 || assignee.includes(ticket.assignee)) &&
69
+ (statuses.length === 0 || statuses.includes(ticket.status)),
70
+ ),
71
+ [assignee, statuses],
72
+ );
73
+
74
+ // Desk parity: each facet's counts respect every OTHER facet's selection.
75
+ const assigneeOptions = useMemo(
76
+ () =>
77
+ countBy(
78
+ tickets.filter((row) => statuses.length === 0 || statuses.includes(row.status)),
79
+ (row) => [row.assignee],
80
+ ),
81
+ [statuses],
82
+ );
83
+ const statusOptions = useMemo(
84
+ () =>
85
+ countBy(
86
+ tickets.filter((row) => assignee.length === 0 || assignee.includes(row.assignee)),
87
+ (row) => [row.status],
88
+ ),
89
+ [assignee],
90
+ );
91
+
92
+ return (
93
+ <YStack padding="$4">
94
+ <DataTable
95
+ data={rows}
96
+ columns={ticketColumns}
97
+ enableGlobalSearch
98
+ renderToolbar={(props) => (
99
+ <DataTableToolbar
100
+ {...props}
101
+ customActions={
102
+ <XStack gap="$2" alignItems="center">
103
+ <DataTableFacetMenu
104
+ label="Assignee"
105
+ options={assigneeOptions}
106
+ activeValues={assignee}
107
+ onActiveValuesChange={(next, pressed) => {
108
+ setAssignee(next);
109
+ action("assignee-change")(next, pressed.value);
110
+ }}
111
+ />
112
+ <DataTableFacetMenu
113
+ label="Status"
114
+ selection="toggle"
115
+ options={statusOptions}
116
+ activeValues={statuses}
117
+ onActiveValuesChange={(next, pressed) => {
118
+ setStatuses(next);
119
+ action("status-change")(next, pressed.value);
120
+ }}
121
+ />
122
+ </XStack>
123
+ }
124
+ />
125
+ )}
126
+ aria-label="Tickets with facet menus"
127
+ />
128
+ </YStack>
129
+ );
130
+ };
131
+
132
+ export const Default = {
133
+ name: "Main",
134
+ render: () => <InToolbarStory />,
135
+ };
136
+
137
+ const ReplaceSelectionStory = () => {
138
+ const [active, setActive] = useState<string[]>(["Alice"]);
139
+ return (
140
+ <YStack padding="$4" alignItems="flex-start" gap="$3">
141
+ <DataTableFacetMenu
142
+ label="Created By"
143
+ options={[
144
+ { value: "Alice", label: "Me", count: 3 },
145
+ { value: "Bob", count: 2 },
146
+ { value: "Carol", count: 1 },
147
+ ]}
148
+ activeValues={active}
149
+ onActiveValuesChange={(next, pressed) => {
150
+ setActive(next);
151
+ action("created-by-change")(next, pressed.value);
152
+ }}
153
+ />
154
+ </YStack>
155
+ );
156
+ };
157
+
158
+ export const ReplaceSelection = {
159
+ render: () => <ReplaceSelectionStory />,
160
+ };
161
+
162
+ const ToggleSelectionStory = () => {
163
+ const [active, setActive] = useState<string[]>(["bug"]);
164
+ return (
165
+ <YStack padding="$4" alignItems="flex-start" gap="$3">
166
+ <DataTableFacetMenu
167
+ label="Tags"
168
+ selection="toggle"
169
+ options={[
170
+ { value: "bug", count: 3 },
171
+ { value: "design", count: 2 },
172
+ { value: "infra", count: 2 },
173
+ { value: "export", count: 1 },
174
+ ]}
175
+ activeValues={active}
176
+ onActiveValuesChange={(next, pressed) => {
177
+ setActive(next);
178
+ action("tags-change")(next, pressed.value);
179
+ }}
180
+ />
181
+ </YStack>
182
+ );
183
+ };
184
+
185
+ export const ToggleSelection = {
186
+ render: () => <ToggleSelectionStory />,
187
+ };
188
+
189
+ export const LoadingWithStaleCounts = {
190
+ render: () => (
191
+ <YStack padding="$4" alignItems="flex-start">
192
+ <DataTableFacetMenu
193
+ label="Assigned To"
194
+ loading
195
+ options={[
196
+ { value: "Alice", count: 12 },
197
+ { value: "Bob", count: 4 },
198
+ ]}
199
+ activeValues={["Alice"]}
200
+ onActiveValuesChange={action("change")}
201
+ />
202
+ </YStack>
203
+ ),
204
+ };
205
+
206
+ export const Empty = {
207
+ render: () => (
208
+ <YStack padding="$4" alignItems="flex-start">
209
+ <DataTableFacetMenu label="Tags" options={[]} onActiveValuesChange={action("change")} />
210
+ </YStack>
211
+ ),
212
+ };
@@ -0,0 +1,202 @@
1
+ /**
2
+ * DataTableFacetMenu — presentational facet menu for the toolbar action
3
+ * cluster (sits beside DataTableFilterButton / SavedFilterDropdown, slotted
4
+ * through DataTableToolbar's `customActions`). A label trigger opens a menu
5
+ * of options with trailing counts; active options render checked and the
6
+ * trigger carries the active count (accent — same anatomy as the Filter
7
+ * button's active state).
8
+ *
9
+ * Selection SEMANTICS are prop-owned (`selection`):
10
+ * - "replace" (default — desk list_sidebar_group_by parity): pressing a
11
+ * row replaces the facet's whole selection with that row; pressing the
12
+ * active row clears it (toggle off / replace).
13
+ * - "toggle": rows accumulate (multi-select); pressing an active row
14
+ * removes only that row.
15
+ *
16
+ * Purely presentational: options, counts, and active values arrive via
17
+ * props (feed from `useFrappeFacets` in @multiplatform.one/frappe-ui or any
18
+ * host source) and the component reports the NEXT active set through
19
+ * `onActiveValuesChange` — it holds no selection state of its own. The menu
20
+ * stays open on selection (LC-21 COMPOSE, CheckboxItem class default) so
21
+ * revalidated counts paint in place while the user composes.
22
+ */
23
+
24
+ import { CaretDownIcon } from "@phosphor-icons/react";
25
+ import { DropdownMenu, type DropdownMenuPlacement } from "@multiplatform.one/components";
26
+ import { Button, Spinner } from "@multiplatform.one/forms";
27
+ import type { ReactNode } from "react";
28
+ import { useCallback } from "react";
29
+ import { Text, XStack, withStaticProperties } from "tamagui";
30
+ import { t } from "../../shared/t";
31
+
32
+ export interface DataTableFacetOption {
33
+ /** Raw facet value (user id, tag, status value, …). */
34
+ value: string;
35
+ /** Display label; defaults to `value`. */
36
+ label?: string;
37
+ /** Result count for the option (omit to hide the trailing count). */
38
+ count?: number;
39
+ }
40
+
41
+ /** Selection semantics for option presses (see component doc). */
42
+ export type DataTableFacetSelection = "replace" | "toggle";
43
+
44
+ export interface DataTableFacetMenuProps {
45
+ /** Facet label — the trigger text and the menu's accessible name. */
46
+ label: string;
47
+ /** Options with counts. Ignored when compound children are provided. */
48
+ options?: readonly DataTableFacetOption[];
49
+ /** Values currently applied (highlighted / checked options). */
50
+ activeValues?: readonly string[];
51
+ /** Press semantics (default "replace" — desk facet parity). */
52
+ selection?: DataTableFacetSelection;
53
+ /**
54
+ * Fires with the NEXT active set (per `selection` semantics) and the
55
+ * pressed option. The host owns state — map the set to filters there.
56
+ */
57
+ onActiveValuesChange?: (next: string[], pressed: DataTableFacetOption) => void;
58
+ /** True while counts load — renders a menu spinner when no options yet. */
59
+ loading?: boolean;
60
+ disabled?: boolean;
61
+ /** DG-ST-03 — why the trigger is disabled (renders on the trigger). */
62
+ disabledReason?: string;
63
+ /** Menu placement (default "bottom-start"). */
64
+ placement?: DropdownMenuPlacement;
65
+ /**
66
+ * Compound composition: custom rows (DataTableFacetMenu.Item) replace the
67
+ * `options` list; loading/empty chrome stays prop-driven.
68
+ */
69
+ children?: ReactNode;
70
+ }
71
+
72
+ export interface DataTableFacetMenuItemProps {
73
+ label: string;
74
+ /** Trailing count (omit to hide). */
75
+ count?: number;
76
+ /** Row renders checked / highlighted. */
77
+ active?: boolean;
78
+ onPress: () => void;
79
+ disabled?: boolean;
80
+ /** DG-ST-03 — why the row is disabled; renders inline under the label. */
81
+ disabledReason?: string;
82
+ }
83
+
84
+ /**
85
+ * One facet row — label, optional trailing count, checked when active.
86
+ * Rides DropdownMenu.CheckboxItem so the menu stays open on press (COMPOSE)
87
+ * and the row exposes menuitemcheckbox semantics.
88
+ */
89
+ function DataTableFacetMenuItem({
90
+ label,
91
+ count,
92
+ active = false,
93
+ onPress,
94
+ disabled,
95
+ disabledReason,
96
+ }: DataTableFacetMenuItemProps) {
97
+ return (
98
+ <DropdownMenu.CheckboxItem
99
+ checked={active}
100
+ onCheckedChange={onPress}
101
+ {...(disabled ? { disabled } : {})}
102
+ {...(disabledReason ? { disabledReason } : {})}
103
+ // Trailing muted slot — the count reads as part of the row.
104
+ {...(typeof count === "number" ? { shortcut: String(count) } : {})}
105
+ >
106
+ {label}
107
+ </DropdownMenu.CheckboxItem>
108
+ );
109
+ }
110
+
111
+ function DataTableFacetMenuComponent({
112
+ label,
113
+ options,
114
+ activeValues,
115
+ selection = "replace",
116
+ onActiveValuesChange,
117
+ loading = false,
118
+ disabled,
119
+ disabledReason,
120
+ placement = "bottom-start",
121
+ children,
122
+ }: DataTableFacetMenuProps) {
123
+ const active = activeValues ?? [];
124
+ const activeCount = active.length;
125
+
126
+ const handlePress = useCallback(
127
+ (option: DataTableFacetOption) => {
128
+ if (!onActiveValuesChange) return;
129
+ const isActive = active.includes(option.value);
130
+ let next: string[];
131
+ if (selection === "toggle") {
132
+ next = isActive
133
+ ? active.filter((value) => value !== option.value)
134
+ : [...active, option.value];
135
+ } else {
136
+ // "replace" — desk semantics: one active value per facet; pressing
137
+ // the active row clears the facet.
138
+ next = isActive ? [] : [option.value];
139
+ }
140
+ onActiveValuesChange(next, option);
141
+ },
142
+ [active, onActiveValuesChange, selection],
143
+ );
144
+
145
+ const rows = children ?? (
146
+ <>
147
+ {(options ?? []).map((option) => (
148
+ <DataTableFacetMenuItem
149
+ key={option.value}
150
+ label={option.label ?? option.value}
151
+ count={option.count}
152
+ active={active.includes(option.value)}
153
+ onPress={() => handlePress(option)}
154
+ />
155
+ ))}
156
+ {(options?.length ?? 0) === 0 && !loading && (
157
+ <Text fontSize="$2" color="$color10" paddingHorizontal="$3" paddingVertical="$2">
158
+ {t("No options")}
159
+ </Text>
160
+ )}
161
+ </>
162
+ );
163
+
164
+ return (
165
+ <DropdownMenu placement={placement}>
166
+ <DropdownMenu.Trigger asChild>
167
+ <Button
168
+ size="$3"
169
+ compact
170
+ // Active facet = accent trigger with count — the same active
171
+ // anatomy as DataTableFilterButton ("Filter (n)").
172
+ {...(activeCount > 0 ? { accent: true } : { variant: "outlined" as const })}
173
+ iconAfter={<CaretDownIcon size={14} />}
174
+ aria-haspopup="menu"
175
+ aria-label={label}
176
+ {...(disabled ? { disabled } : {})}
177
+ {...(disabledReason ? { disabledReason } : {})}
178
+ >
179
+ {activeCount > 0 ? `${label} (${activeCount})` : label}
180
+ </Button>
181
+ </DropdownMenu.Trigger>
182
+ <DropdownMenu.Content aria-label={label} minWidth={200}>
183
+ {rows}
184
+ {loading && (
185
+ <XStack
186
+ alignItems="center"
187
+ justifyContent="center"
188
+ paddingVertical="$2"
189
+ aria-live="polite"
190
+ data-facet-loading="true"
191
+ >
192
+ <Spinner size="small" />
193
+ </XStack>
194
+ )}
195
+ </DropdownMenu.Content>
196
+ </DropdownMenu>
197
+ );
198
+ }
199
+
200
+ export const DataTableFacetMenu = withStaticProperties(DataTableFacetMenuComponent, {
201
+ Item: DataTableFacetMenuItem,
202
+ });