@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.
- package/README.md +4 -3
- package/dist/cjs/components/ChildTable/index.cjs +2 -1
- package/dist/cjs/components/ChildTable/index.native.js +2 -1
- package/dist/cjs/components/ChildTable/index.native.js.map +1 -1
- package/dist/cjs/components/ColumnHeaderFilter/index.cjs +17 -9
- package/dist/cjs/components/ColumnHeaderFilter/index.native.js +32 -11
- package/dist/cjs/components/ColumnHeaderFilter/index.native.js.map +1 -1
- package/dist/cjs/components/DataTable/DataTableDocumentList.cjs +222 -0
- package/dist/cjs/components/DataTable/DataTableDocumentList.native.js +237 -0
- package/dist/cjs/components/DataTable/DataTableDocumentList.native.js.map +1 -0
- package/dist/cjs/components/DataTable/DataTableMobileCards.cjs +5 -2
- package/dist/cjs/components/DataTable/DataTableMobileCards.native.js +6 -2
- package/dist/cjs/components/DataTable/DataTableMobileCards.native.js.map +1 -1
- package/dist/cjs/components/DataTable/DataTableRoot.cjs +92 -41
- package/dist/cjs/components/DataTable/DataTableRoot.native.js +97 -43
- package/dist/cjs/components/DataTable/DataTableRoot.native.js.map +1 -1
- package/dist/cjs/components/DataTable/DataTableVirtualized.cjs +8 -2
- package/dist/cjs/components/DataTable/DataTableVirtualized.native.js +9 -3
- package/dist/cjs/components/DataTable/DataTableVirtualized.native.js.map +1 -1
- package/dist/cjs/components/DataTable/documentListSlots.cjs +59 -0
- package/dist/cjs/components/DataTable/documentListSlots.native.js +85 -0
- package/dist/cjs/components/DataTable/documentListSlots.native.js.map +1 -0
- package/dist/cjs/components/DataTable/index.native.js +74 -59
- package/dist/cjs/components/DataTable/index.native.js.map +1 -1
- package/dist/cjs/components/DataTable/rowStateChrome.cjs +55 -0
- package/dist/cjs/components/DataTable/rowStateChrome.native.js +59 -0
- package/dist/cjs/components/DataTable/rowStateChrome.native.js.map +1 -0
- package/dist/cjs/components/DataTableCell/CellModalEditor.cjs +24 -3
- package/dist/cjs/components/DataTableCell/CellModalEditor.native.js +6 -1
- package/dist/cjs/components/DataTableCell/CellModalEditor.native.js.map +1 -1
- package/dist/cjs/components/DataTableCell/CellOptionsEditor.cjs +9 -2
- package/dist/cjs/components/DataTableCell/CellOptionsEditor.native.js +11 -2
- package/dist/cjs/components/DataTableCell/CellOptionsEditor.native.js.map +1 -1
- package/dist/cjs/components/DataTableCell/index.cjs +74 -63
- package/dist/cjs/components/DataTableCell/index.native.js +94 -82
- package/dist/cjs/components/DataTableCell/index.native.js.map +1 -1
- package/dist/cjs/components/DataTableColumnPinning/index.cjs +54 -37
- package/dist/cjs/components/DataTableColumnPinning/index.native.js +59 -38
- package/dist/cjs/components/DataTableColumnPinning/index.native.js.map +1 -1
- package/dist/cjs/components/DataTableDateFilter/index.cjs +33 -14
- package/dist/cjs/components/DataTableDateFilter/index.native.js +33 -12
- package/dist/cjs/components/DataTableDateFilter/index.native.js.map +1 -1
- package/dist/cjs/components/DataTableExport/index.cjs +35 -7
- package/dist/cjs/components/DataTableExport/index.native.js +42 -7
- package/dist/cjs/components/DataTableExport/index.native.js.map +1 -1
- package/dist/cjs/components/DataTableFacetMenu/index.cjs +140 -0
- package/dist/cjs/components/DataTableFacetMenu/index.native.js +156 -0
- package/dist/cjs/components/DataTableFacetMenu/index.native.js.map +1 -0
- package/dist/cjs/components/DataTableFilterButton/index.cjs +51 -32
- package/dist/cjs/components/DataTableFilterButton/index.native.js +63 -40
- package/dist/cjs/components/DataTableFilterButton/index.native.js.map +1 -1
- package/dist/cjs/components/DataTableFilterChips/FilterChip.cjs +143 -0
- package/dist/cjs/components/DataTableFilterChips/FilterChip.native.js +148 -0
- package/dist/cjs/components/DataTableFilterChips/FilterChip.native.js.map +1 -0
- package/dist/cjs/components/DataTableFilterChips/index.cjs +9 -31
- package/dist/cjs/components/DataTableFilterChips/index.native.js +9 -32
- package/dist/cjs/components/DataTableFilterChips/index.native.js.map +1 -1
- package/dist/cjs/components/DataTableFilters/index.cjs +145 -502
- package/dist/cjs/components/DataTableFilters/index.native.js +171 -544
- package/dist/cjs/components/DataTableFilters/index.native.js.map +1 -1
- package/dist/cjs/components/DataTableGrouping/index.cjs +273 -108
- package/dist/cjs/components/DataTableGrouping/index.native.js +310 -157
- package/dist/cjs/components/DataTableGrouping/index.native.js.map +1 -1
- package/dist/cjs/components/DataTablePagination/index.cjs +147 -95
- package/dist/cjs/components/DataTablePagination/index.native.js +159 -106
- package/dist/cjs/components/DataTablePagination/index.native.js.map +1 -1
- package/dist/cjs/components/DataTableSearch/index.cjs +251 -210
- package/dist/cjs/components/DataTableSearch/index.native.js +292 -243
- package/dist/cjs/components/DataTableSearch/index.native.js.map +1 -1
- package/dist/cjs/components/DataTableToolbar/index.cjs +141 -115
- package/dist/cjs/components/DataTableToolbar/index.native.js +163 -148
- package/dist/cjs/components/DataTableToolbar/index.native.js.map +1 -1
- package/dist/cjs/components/DataTableViewOptions/index.cjs +25 -21
- package/dist/cjs/components/DataTableViewOptions/index.native.js +6 -4
- package/dist/cjs/components/DataTableViewOptions/index.native.js.map +1 -1
- package/dist/cjs/components/SimpleTable/index.cjs +336 -46
- package/dist/cjs/components/SimpleTable/index.native.js +356 -48
- package/dist/cjs/components/SimpleTable/index.native.js.map +1 -1
- package/dist/cjs/components/TableInput/index.cjs +147 -38
- package/dist/cjs/components/TableInput/index.native.js +54 -38
- package/dist/cjs/components/TableInput/index.native.js.map +1 -1
- package/dist/cjs/components/TableInput/shared.cjs +36 -1
- package/dist/cjs/components/TableInput/shared.native.js +35 -0
- package/dist/cjs/components/TableInput/shared.native.js.map +1 -1
- package/dist/cjs/hooks/useDataTable.cjs +33 -2
- package/dist/cjs/hooks/useDataTable.native.js +41 -2
- package/dist/cjs/hooks/useDataTable.native.js.map +1 -1
- package/dist/cjs/hooks/useInfiniteRows.cjs +20 -3
- package/dist/cjs/hooks/useInfiniteRows.native.js +20 -3
- package/dist/cjs/hooks/useInfiniteRows.native.js.map +1 -1
- package/dist/cjs/index.cjs +2 -0
- package/dist/cjs/index.native.js +2 -0
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/utils/filterUtils.cjs +12 -5
- package/dist/cjs/utils/filterUtils.native.js +20 -5
- package/dist/cjs/utils/filterUtils.native.js.map +1 -1
- package/dist/esm/components/ChildTable/index.mjs +2 -1
- package/dist/esm/components/ChildTable/index.mjs.map +1 -1
- package/dist/esm/components/ChildTable/index.native.js +2 -1
- package/dist/esm/components/ChildTable/index.native.js.map +1 -1
- package/dist/esm/components/ColumnHeaderFilter/index.mjs +17 -9
- package/dist/esm/components/ColumnHeaderFilter/index.mjs.map +1 -1
- package/dist/esm/components/ColumnHeaderFilter/index.native.js +32 -11
- package/dist/esm/components/ColumnHeaderFilter/index.native.js.map +1 -1
- package/dist/esm/components/DataTable/DataTableDocumentList.mjs +196 -0
- package/dist/esm/components/DataTable/DataTableDocumentList.mjs.map +1 -0
- package/dist/esm/components/DataTable/DataTableDocumentList.native.js +208 -0
- package/dist/esm/components/DataTable/DataTableDocumentList.native.js.map +1 -0
- package/dist/esm/components/DataTable/DataTableMobileCards.mjs +5 -2
- package/dist/esm/components/DataTable/DataTableMobileCards.mjs.map +1 -1
- package/dist/esm/components/DataTable/DataTableMobileCards.native.js +6 -2
- package/dist/esm/components/DataTable/DataTableMobileCards.native.js.map +1 -1
- package/dist/esm/components/DataTable/DataTableRoot.mjs +93 -42
- package/dist/esm/components/DataTable/DataTableRoot.mjs.map +1 -1
- package/dist/esm/components/DataTable/DataTableRoot.native.js +98 -44
- package/dist/esm/components/DataTable/DataTableRoot.native.js.map +1 -1
- package/dist/esm/components/DataTable/DataTableVirtualized.mjs +8 -2
- package/dist/esm/components/DataTable/DataTableVirtualized.mjs.map +1 -1
- package/dist/esm/components/DataTable/DataTableVirtualized.native.js +9 -3
- package/dist/esm/components/DataTable/DataTableVirtualized.native.js.map +1 -1
- package/dist/esm/components/DataTable/documentListSlots.mjs +33 -0
- package/dist/esm/components/DataTable/documentListSlots.mjs.map +1 -0
- package/dist/esm/components/DataTable/documentListSlots.native.js +56 -0
- package/dist/esm/components/DataTable/documentListSlots.native.js.map +1 -0
- package/dist/esm/components/DataTable/index.native.js +52 -37
- package/dist/esm/components/DataTable/index.native.js.map +1 -1
- package/dist/esm/components/DataTable/rowStateChrome.mjs +28 -0
- package/dist/esm/components/DataTable/rowStateChrome.mjs.map +1 -0
- package/dist/esm/components/DataTable/rowStateChrome.native.js +29 -0
- package/dist/esm/components/DataTable/rowStateChrome.native.js.map +1 -0
- package/dist/esm/components/DataTableCell/CellModalEditor.mjs +25 -4
- package/dist/esm/components/DataTableCell/CellModalEditor.mjs.map +1 -1
- package/dist/esm/components/DataTableCell/CellModalEditor.native.js +6 -1
- package/dist/esm/components/DataTableCell/CellModalEditor.native.js.map +1 -1
- package/dist/esm/components/DataTableCell/CellOptionsEditor.mjs +9 -2
- package/dist/esm/components/DataTableCell/CellOptionsEditor.mjs.map +1 -1
- package/dist/esm/components/DataTableCell/CellOptionsEditor.native.js +11 -2
- package/dist/esm/components/DataTableCell/CellOptionsEditor.native.js.map +1 -1
- package/dist/esm/components/DataTableCell/index.mjs +75 -64
- package/dist/esm/components/DataTableCell/index.mjs.map +1 -1
- package/dist/esm/components/DataTableCell/index.native.js +95 -83
- package/dist/esm/components/DataTableCell/index.native.js.map +1 -1
- package/dist/esm/components/DataTableColumnPinning/index.mjs +54 -37
- package/dist/esm/components/DataTableColumnPinning/index.mjs.map +1 -1
- package/dist/esm/components/DataTableColumnPinning/index.native.js +59 -38
- package/dist/esm/components/DataTableColumnPinning/index.native.js.map +1 -1
- package/dist/esm/components/DataTableDateFilter/index.mjs +34 -15
- package/dist/esm/components/DataTableDateFilter/index.mjs.map +1 -1
- package/dist/esm/components/DataTableDateFilter/index.native.js +34 -13
- package/dist/esm/components/DataTableDateFilter/index.native.js.map +1 -1
- package/dist/esm/components/DataTableExport/index.mjs +36 -8
- package/dist/esm/components/DataTableExport/index.mjs.map +1 -1
- package/dist/esm/components/DataTableExport/index.native.js +43 -8
- package/dist/esm/components/DataTableExport/index.native.js.map +1 -1
- package/dist/esm/components/DataTableFacetMenu/index.mjs +115 -0
- package/dist/esm/components/DataTableFacetMenu/index.mjs.map +1 -0
- package/dist/esm/components/DataTableFacetMenu/index.native.js +128 -0
- package/dist/esm/components/DataTableFacetMenu/index.native.js.map +1 -0
- package/dist/esm/components/DataTableFilterButton/index.mjs +54 -35
- package/dist/esm/components/DataTableFilterButton/index.mjs.map +1 -1
- package/dist/esm/components/DataTableFilterButton/index.native.js +66 -43
- package/dist/esm/components/DataTableFilterButton/index.native.js.map +1 -1
- package/dist/esm/components/DataTableFilterChips/FilterChip.mjs +118 -0
- package/dist/esm/components/DataTableFilterChips/FilterChip.mjs.map +1 -0
- package/dist/esm/components/DataTableFilterChips/FilterChip.native.js +120 -0
- package/dist/esm/components/DataTableFilterChips/FilterChip.native.js.map +1 -0
- package/dist/esm/components/DataTableFilterChips/index.mjs +9 -32
- package/dist/esm/components/DataTableFilterChips/index.mjs.map +1 -1
- package/dist/esm/components/DataTableFilterChips/index.native.js +9 -33
- package/dist/esm/components/DataTableFilterChips/index.native.js.map +1 -1
- package/dist/esm/components/DataTableFilters/index.mjs +149 -506
- package/dist/esm/components/DataTableFilters/index.mjs.map +1 -1
- package/dist/esm/components/DataTableFilters/index.native.js +175 -548
- package/dist/esm/components/DataTableFilters/index.native.js.map +1 -1
- package/dist/esm/components/DataTableGrouping/index.mjs +275 -110
- package/dist/esm/components/DataTableGrouping/index.mjs.map +1 -1
- package/dist/esm/components/DataTableGrouping/index.native.js +287 -134
- package/dist/esm/components/DataTableGrouping/index.native.js.map +1 -1
- package/dist/esm/components/DataTablePagination/index.mjs +148 -96
- package/dist/esm/components/DataTablePagination/index.mjs.map +1 -1
- package/dist/esm/components/DataTablePagination/index.native.js +160 -107
- package/dist/esm/components/DataTablePagination/index.native.js.map +1 -1
- package/dist/esm/components/DataTableSearch/index.mjs +256 -215
- package/dist/esm/components/DataTableSearch/index.mjs.map +1 -1
- package/dist/esm/components/DataTableSearch/index.native.js +297 -248
- package/dist/esm/components/DataTableSearch/index.native.js.map +1 -1
- package/dist/esm/components/DataTableToolbar/index.mjs +145 -119
- package/dist/esm/components/DataTableToolbar/index.mjs.map +1 -1
- package/dist/esm/components/DataTableToolbar/index.native.js +167 -152
- package/dist/esm/components/DataTableToolbar/index.native.js.map +1 -1
- package/dist/esm/components/DataTableViewOptions/index.mjs +26 -22
- package/dist/esm/components/DataTableViewOptions/index.mjs.map +1 -1
- package/dist/esm/components/DataTableViewOptions/index.native.js +7 -5
- package/dist/esm/components/DataTableViewOptions/index.native.js.map +1 -1
- package/dist/esm/components/SimpleTable/index.mjs +338 -48
- package/dist/esm/components/SimpleTable/index.mjs.map +1 -1
- package/dist/esm/components/SimpleTable/index.native.js +358 -50
- package/dist/esm/components/SimpleTable/index.native.js.map +1 -1
- package/dist/esm/components/TableInput/index.mjs +150 -41
- package/dist/esm/components/TableInput/index.mjs.map +1 -1
- package/dist/esm/components/TableInput/index.native.js +55 -39
- package/dist/esm/components/TableInput/index.native.js.map +1 -1
- package/dist/esm/components/TableInput/shared.mjs +34 -1
- package/dist/esm/components/TableInput/shared.mjs.map +1 -1
- package/dist/esm/components/TableInput/shared.native.js +34 -1
- package/dist/esm/components/TableInput/shared.native.js.map +1 -1
- package/dist/esm/hooks/useDataTable.mjs +33 -2
- package/dist/esm/hooks/useDataTable.mjs.map +1 -1
- package/dist/esm/hooks/useDataTable.native.js +41 -2
- package/dist/esm/hooks/useDataTable.native.js.map +1 -1
- package/dist/esm/hooks/useInfiniteRows.mjs +20 -3
- package/dist/esm/hooks/useInfiniteRows.mjs.map +1 -1
- package/dist/esm/hooks/useInfiniteRows.native.js +20 -3
- package/dist/esm/hooks/useInfiniteRows.native.js.map +1 -1
- package/dist/esm/index.mjs +2 -1
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +2 -1
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/utils/filterUtils.mjs +12 -5
- package/dist/esm/utils/filterUtils.mjs.map +1 -1
- package/dist/esm/utils/filterUtils.native.js +20 -5
- package/dist/esm/utils/filterUtils.native.js.map +1 -1
- package/dist/jsx/components/ChildTable/index.mjs +2 -1
- package/dist/jsx/components/ChildTable/index.mjs.map +1 -1
- package/dist/jsx/components/ChildTable/index.native.js +2 -1
- package/dist/jsx/components/ChildTable/index.native.js.map +1 -1
- package/dist/jsx/components/ColumnHeaderFilter/index.mjs +17 -9
- package/dist/jsx/components/ColumnHeaderFilter/index.mjs.map +1 -1
- package/dist/jsx/components/ColumnHeaderFilter/index.native.js +32 -11
- package/dist/jsx/components/ColumnHeaderFilter/index.native.js.map +1 -1
- package/dist/jsx/components/DataTable/DataTableDocumentList.mjs +196 -0
- package/dist/jsx/components/DataTable/DataTableDocumentList.mjs.map +1 -0
- package/dist/jsx/components/DataTable/DataTableDocumentList.native.js +237 -0
- package/dist/jsx/components/DataTable/DataTableDocumentList.native.js.map +1 -0
- package/dist/jsx/components/DataTable/DataTableMobileCards.mjs +5 -2
- package/dist/jsx/components/DataTable/DataTableMobileCards.mjs.map +1 -1
- package/dist/jsx/components/DataTable/DataTableMobileCards.native.js +6 -2
- package/dist/jsx/components/DataTable/DataTableMobileCards.native.js.map +1 -1
- package/dist/jsx/components/DataTable/DataTableRoot.mjs +93 -42
- package/dist/jsx/components/DataTable/DataTableRoot.mjs.map +1 -1
- package/dist/jsx/components/DataTable/DataTableRoot.native.js +97 -43
- package/dist/jsx/components/DataTable/DataTableRoot.native.js.map +1 -1
- package/dist/jsx/components/DataTable/DataTableVirtualized.mjs +8 -2
- package/dist/jsx/components/DataTable/DataTableVirtualized.mjs.map +1 -1
- package/dist/jsx/components/DataTable/DataTableVirtualized.native.js +9 -3
- package/dist/jsx/components/DataTable/DataTableVirtualized.native.js.map +1 -1
- package/dist/jsx/components/DataTable/documentListSlots.mjs +33 -0
- package/dist/jsx/components/DataTable/documentListSlots.mjs.map +1 -0
- package/dist/jsx/components/DataTable/documentListSlots.native.js +85 -0
- package/dist/jsx/components/DataTable/documentListSlots.native.js.map +1 -0
- package/dist/jsx/components/DataTable/index.native.js +74 -59
- package/dist/jsx/components/DataTable/index.native.js.map +1 -1
- package/dist/jsx/components/DataTable/rowStateChrome.mjs +28 -0
- package/dist/jsx/components/DataTable/rowStateChrome.mjs.map +1 -0
- package/dist/jsx/components/DataTable/rowStateChrome.native.js +59 -0
- package/dist/jsx/components/DataTable/rowStateChrome.native.js.map +1 -0
- package/dist/jsx/components/DataTableCell/CellModalEditor.mjs +25 -4
- package/dist/jsx/components/DataTableCell/CellModalEditor.mjs.map +1 -1
- package/dist/jsx/components/DataTableCell/CellModalEditor.native.js +6 -1
- package/dist/jsx/components/DataTableCell/CellModalEditor.native.js.map +1 -1
- package/dist/jsx/components/DataTableCell/CellOptionsEditor.mjs +9 -2
- package/dist/jsx/components/DataTableCell/CellOptionsEditor.mjs.map +1 -1
- package/dist/jsx/components/DataTableCell/CellOptionsEditor.native.js +11 -2
- package/dist/jsx/components/DataTableCell/CellOptionsEditor.native.js.map +1 -1
- package/dist/jsx/components/DataTableCell/index.mjs +75 -64
- package/dist/jsx/components/DataTableCell/index.mjs.map +1 -1
- package/dist/jsx/components/DataTableCell/index.native.js +94 -82
- package/dist/jsx/components/DataTableCell/index.native.js.map +1 -1
- package/dist/jsx/components/DataTableColumnPinning/index.mjs +54 -37
- package/dist/jsx/components/DataTableColumnPinning/index.mjs.map +1 -1
- package/dist/jsx/components/DataTableColumnPinning/index.native.js +59 -38
- package/dist/jsx/components/DataTableColumnPinning/index.native.js.map +1 -1
- package/dist/jsx/components/DataTableDateFilter/index.mjs +34 -15
- package/dist/jsx/components/DataTableDateFilter/index.mjs.map +1 -1
- package/dist/jsx/components/DataTableDateFilter/index.native.js +33 -12
- package/dist/jsx/components/DataTableDateFilter/index.native.js.map +1 -1
- package/dist/jsx/components/DataTableExport/index.mjs +36 -8
- package/dist/jsx/components/DataTableExport/index.mjs.map +1 -1
- package/dist/jsx/components/DataTableExport/index.native.js +42 -7
- package/dist/jsx/components/DataTableExport/index.native.js.map +1 -1
- package/dist/jsx/components/DataTableFacetMenu/index.mjs +115 -0
- package/dist/jsx/components/DataTableFacetMenu/index.mjs.map +1 -0
- package/dist/jsx/components/DataTableFacetMenu/index.native.js +156 -0
- package/dist/jsx/components/DataTableFacetMenu/index.native.js.map +1 -0
- package/dist/jsx/components/DataTableFilterButton/index.mjs +54 -35
- package/dist/jsx/components/DataTableFilterButton/index.mjs.map +1 -1
- package/dist/jsx/components/DataTableFilterButton/index.native.js +63 -40
- package/dist/jsx/components/DataTableFilterButton/index.native.js.map +1 -1
- package/dist/jsx/components/DataTableFilterChips/FilterChip.mjs +118 -0
- package/dist/jsx/components/DataTableFilterChips/FilterChip.mjs.map +1 -0
- package/dist/jsx/components/DataTableFilterChips/FilterChip.native.js +148 -0
- package/dist/jsx/components/DataTableFilterChips/FilterChip.native.js.map +1 -0
- package/dist/jsx/components/DataTableFilterChips/index.mjs +9 -32
- package/dist/jsx/components/DataTableFilterChips/index.mjs.map +1 -1
- package/dist/jsx/components/DataTableFilterChips/index.native.js +9 -32
- package/dist/jsx/components/DataTableFilterChips/index.native.js.map +1 -1
- package/dist/jsx/components/DataTableFilters/index.mjs +149 -506
- package/dist/jsx/components/DataTableFilters/index.mjs.map +1 -1
- package/dist/jsx/components/DataTableFilters/index.native.js +171 -544
- package/dist/jsx/components/DataTableFilters/index.native.js.map +1 -1
- package/dist/jsx/components/DataTableGrouping/index.mjs +275 -110
- package/dist/jsx/components/DataTableGrouping/index.mjs.map +1 -1
- package/dist/jsx/components/DataTableGrouping/index.native.js +310 -157
- package/dist/jsx/components/DataTableGrouping/index.native.js.map +1 -1
- package/dist/jsx/components/DataTablePagination/index.mjs +148 -96
- package/dist/jsx/components/DataTablePagination/index.mjs.map +1 -1
- package/dist/jsx/components/DataTablePagination/index.native.js +159 -106
- package/dist/jsx/components/DataTablePagination/index.native.js.map +1 -1
- package/dist/jsx/components/DataTableSearch/index.mjs +256 -215
- package/dist/jsx/components/DataTableSearch/index.mjs.map +1 -1
- package/dist/jsx/components/DataTableSearch/index.native.js +292 -243
- package/dist/jsx/components/DataTableSearch/index.native.js.map +1 -1
- package/dist/jsx/components/DataTableToolbar/index.mjs +145 -119
- package/dist/jsx/components/DataTableToolbar/index.mjs.map +1 -1
- package/dist/jsx/components/DataTableToolbar/index.native.js +163 -148
- package/dist/jsx/components/DataTableToolbar/index.native.js.map +1 -1
- package/dist/jsx/components/DataTableViewOptions/index.mjs +26 -22
- package/dist/jsx/components/DataTableViewOptions/index.mjs.map +1 -1
- package/dist/jsx/components/DataTableViewOptions/index.native.js +6 -4
- package/dist/jsx/components/DataTableViewOptions/index.native.js.map +1 -1
- package/dist/jsx/components/SimpleTable/index.mjs +338 -48
- package/dist/jsx/components/SimpleTable/index.mjs.map +1 -1
- package/dist/jsx/components/SimpleTable/index.native.js +356 -48
- package/dist/jsx/components/SimpleTable/index.native.js.map +1 -1
- package/dist/jsx/components/TableInput/index.mjs +150 -41
- package/dist/jsx/components/TableInput/index.mjs.map +1 -1
- package/dist/jsx/components/TableInput/index.native.js +54 -38
- package/dist/jsx/components/TableInput/index.native.js.map +1 -1
- package/dist/jsx/components/TableInput/shared.mjs +34 -1
- package/dist/jsx/components/TableInput/shared.mjs.map +1 -1
- package/dist/jsx/components/TableInput/shared.native.js +35 -0
- package/dist/jsx/components/TableInput/shared.native.js.map +1 -1
- package/dist/jsx/hooks/useDataTable.mjs +33 -2
- package/dist/jsx/hooks/useDataTable.mjs.map +1 -1
- package/dist/jsx/hooks/useDataTable.native.js +41 -2
- package/dist/jsx/hooks/useDataTable.native.js.map +1 -1
- package/dist/jsx/hooks/useInfiniteRows.mjs +20 -3
- package/dist/jsx/hooks/useInfiniteRows.mjs.map +1 -1
- package/dist/jsx/hooks/useInfiniteRows.native.js +20 -3
- package/dist/jsx/hooks/useInfiniteRows.native.js.map +1 -1
- package/dist/jsx/index.js +2 -1
- package/dist/jsx/index.js.map +1 -1
- package/dist/jsx/index.mjs +2 -1
- package/dist/jsx/index.mjs.map +1 -1
- package/dist/jsx/index.native.js +2 -0
- package/dist/jsx/index.native.js.map +1 -1
- package/dist/jsx/utils/filterUtils.mjs +12 -5
- package/dist/jsx/utils/filterUtils.mjs.map +1 -1
- package/dist/jsx/utils/filterUtils.native.js +20 -5
- package/dist/jsx/utils/filterUtils.native.js.map +1 -1
- package/package.json +15 -15
- package/src/components/ChildTable/index.tsx +1 -0
- package/src/components/ColumnHeaderFilter/ColumnHeaderFilter.spec.tsx +85 -0
- package/src/components/ColumnHeaderFilter/index.tsx +28 -10
- package/src/components/DataTable/DataTable.stories.tsx +30 -0
- package/src/components/DataTable/DataTableDocumentList.tsx +224 -0
- package/src/components/DataTable/DataTableMobileCards.tsx +20 -8
- package/src/components/DataTable/DataTableRoot.tsx +135 -58
- package/src/components/DataTable/DataTableVirtualized.tsx +8 -11
- package/src/components/DataTable/cardLayout.spec.tsx +89 -0
- package/src/components/DataTable/documentListSlots.ts +57 -0
- package/src/components/DataTable/index.native.tsx +76 -50
- package/src/components/DataTable/keepPreviousData.spec.tsx +137 -0
- package/src/components/DataTable/rowRing.spec.tsx +118 -0
- package/src/components/DataTable/rowStateChrome.ts +38 -0
- package/src/components/DataTableCell/CellModalEditor.native.tsx +4 -0
- package/src/components/DataTableCell/CellModalEditor.tsx +31 -3
- package/src/components/DataTableCell/CellOptionsEditor.tsx +29 -12
- package/src/components/DataTableCell/DataTableCell.stories.tsx +3 -3
- package/src/components/DataTableCell/cellDraftPolicy.spec.tsx +131 -4
- package/src/components/DataTableCell/dataTableCell.spec.tsx +36 -1
- package/src/components/DataTableCell/index.tsx +121 -86
- package/src/components/DataTableColumnPinning/DataTableColumnPinning.spec.tsx +66 -0
- package/src/components/DataTableColumnPinning/index.tsx +32 -17
- package/src/components/DataTableDateFilter/DataTableDateFilter.spec.tsx +9 -1
- package/src/components/DataTableDateFilter/dateFilterZones.spec.ts +316 -0
- package/src/components/DataTableDateFilter/index.tsx +42 -22
- package/src/components/DataTableExport/exportDateZones.spec.tsx +348 -0
- package/src/components/DataTableExport/index.tsx +107 -63
- package/src/components/DataTableFacetMenu/DataTableFacetMenu.spec.tsx +264 -0
- package/src/components/DataTableFacetMenu/DataTableFacetMenu.stories.tsx +212 -0
- package/src/components/DataTableFacetMenu/index.tsx +202 -0
- package/src/components/DataTableFilterButton/index.tsx +66 -49
- package/src/components/DataTableFilterChips/DataTableFilterChips.spec.tsx +22 -0
- package/src/components/DataTableFilterChips/FilterChip.tsx +122 -0
- package/src/components/DataTableFilterChips/index.tsx +13 -29
- package/src/components/DataTableFilters/DataTableFilters.spec.tsx +56 -0
- package/src/components/DataTableFilters/index.tsx +169 -584
- package/src/components/DataTableGrouping/DataTableGrouping.spec.tsx +85 -0
- package/src/components/DataTableGrouping/index.tsx +270 -130
- package/src/components/DataTablePagination/DataTablePagination.spec.tsx +79 -4
- package/src/components/DataTablePagination/index.tsx +168 -112
- package/src/components/DataTableSearch/DataTableSearch.spec.tsx +40 -0
- package/src/components/DataTableSearch/DataTableSearch.stories.tsx +1 -1
- package/src/components/DataTableSearch/index.tsx +192 -163
- package/src/components/DataTableToolbar/DataTableToolbar.spec.tsx +48 -18
- package/src/components/DataTableToolbar/DataTableToolbar.stories.tsx +5 -45
- package/src/components/DataTableToolbar/index.tsx +128 -99
- package/src/components/DataTableViewOptions/index.tsx +29 -22
- package/src/components/SimpleTable/SimpleTable.stories.tsx +29 -5
- package/src/components/SimpleTable/index.tsx +442 -61
- package/src/components/SimpleTable/simpleTable.spec.tsx +140 -12
- package/src/components/TableInput/index.native.tsx +91 -81
- package/src/components/TableInput/index.tsx +191 -50
- package/src/components/TableInput/shared.ts +57 -0
- package/src/components/TableInput/tableInput.spec.tsx +104 -0
- package/src/hooks/useDataTable.spec.ts +100 -3
- package/src/hooks/useDataTable.ts +44 -1
- package/src/hooks/useInfiniteRows.spec.tsx +37 -0
- package/src/hooks/useInfiniteRows.ts +34 -4
- package/src/index.ts +7 -0
- package/src/types.ts +54 -3
- package/src/utils/filterUtils.ts +27 -5
- package/types/components/ChildTable/index.d.ts.map +1 -1
- package/types/components/ColumnHeaderFilter/index.d.ts.map +1 -1
- package/types/components/DataTable/DataTableDocumentList.d.ts +32 -0
- package/types/components/DataTable/DataTableDocumentList.d.ts.map +1 -0
- package/types/components/DataTable/DataTableMobileCards.d.ts +3 -1
- package/types/components/DataTable/DataTableMobileCards.d.ts.map +1 -1
- package/types/components/DataTable/DataTableRoot.d.ts +1 -1
- package/types/components/DataTable/DataTableRoot.d.ts.map +1 -1
- package/types/components/DataTable/DataTableVirtualized.d.ts +1 -2
- package/types/components/DataTable/DataTableVirtualized.d.ts.map +1 -1
- package/types/components/DataTable/documentListSlots.d.ts +26 -0
- package/types/components/DataTable/documentListSlots.d.ts.map +1 -0
- package/types/components/DataTable/index.native.d.ts +1 -1
- package/types/components/DataTable/index.native.d.ts.map +1 -1
- package/types/components/DataTable/rowStateChrome.d.ts +18 -0
- package/types/components/DataTable/rowStateChrome.d.ts.map +1 -0
- package/types/components/DataTableCell/CellModalEditor.d.ts +6 -1
- package/types/components/DataTableCell/CellModalEditor.d.ts.map +1 -1
- package/types/components/DataTableCell/CellModalEditor.native.d.ts +1 -1
- package/types/components/DataTableCell/CellModalEditor.native.d.ts.map +1 -1
- package/types/components/DataTableCell/CellOptionsEditor.d.ts +11 -3
- package/types/components/DataTableCell/CellOptionsEditor.d.ts.map +1 -1
- package/types/components/DataTableCell/index.d.ts +1 -1
- package/types/components/DataTableCell/index.d.ts.map +1 -1
- package/types/components/DataTableColumnPinning/index.d.ts.map +1 -1
- package/types/components/DataTableDateFilter/index.d.ts.map +1 -1
- package/types/components/DataTableExport/index.d.ts +17 -6
- package/types/components/DataTableExport/index.d.ts.map +1 -1
- package/types/components/DataTableFacetMenu/index.d.ts +84 -0
- package/types/components/DataTableFacetMenu/index.d.ts.map +1 -0
- package/types/components/DataTableFilterButton/index.d.ts.map +1 -1
- package/types/components/DataTableFilterChips/FilterChip.d.ts +15 -0
- package/types/components/DataTableFilterChips/FilterChip.d.ts.map +1 -0
- package/types/components/DataTableFilterChips/index.d.ts +5 -0
- package/types/components/DataTableFilterChips/index.d.ts.map +1 -1
- package/types/components/DataTableFilters/index.d.ts +11 -0
- package/types/components/DataTableFilters/index.d.ts.map +1 -1
- package/types/components/DataTableGrouping/index.d.ts.map +1 -1
- package/types/components/DataTablePagination/index.d.ts +5 -0
- package/types/components/DataTablePagination/index.d.ts.map +1 -1
- package/types/components/DataTableSearch/index.d.ts.map +1 -1
- package/types/components/DataTableToolbar/index.d.ts +2 -0
- package/types/components/DataTableToolbar/index.d.ts.map +1 -1
- package/types/components/SimpleTable/index.d.ts +27 -5
- package/types/components/SimpleTable/index.d.ts.map +1 -1
- package/types/components/TableInput/index.d.ts +6 -1
- package/types/components/TableInput/index.d.ts.map +1 -1
- package/types/components/TableInput/index.native.d.ts +6 -1
- package/types/components/TableInput/index.native.d.ts.map +1 -1
- package/types/components/TableInput/shared.d.ts +38 -0
- package/types/components/TableInput/shared.d.ts.map +1 -1
- package/types/hooks/useDataTable.d.ts +1 -1
- package/types/hooks/useDataTable.d.ts.map +1 -1
- package/types/hooks/useInfiniteRows.d.ts +8 -1
- package/types/hooks/useInfiniteRows.d.ts.map +1 -1
- package/types/index.d.ts +1 -0
- package/types/index.d.ts.map +1 -1
- package/types/types.d.ts +54 -3
- package/types/types.d.ts.map +1 -1
- 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
|
+
});
|