@multiplatform.one/table 7.7.6 → 7.10.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/dist/cjs/components/ColumnHeaderFilter/index.cjs +74 -38
- package/dist/cjs/components/ColumnHeaderFilter/index.native.js +97 -51
- package/dist/cjs/components/ColumnHeaderFilter/index.native.js.map +1 -1
- package/dist/cjs/components/DataTable/DataTableCardControls.cjs +0 -1
- package/dist/cjs/components/DataTable/DataTableCardControls.native.js +0 -1
- package/dist/cjs/components/DataTable/DataTableCardControls.native.js.map +1 -1
- package/dist/cjs/components/DataTable/DataTableMobileCards.cjs +100 -33
- package/dist/cjs/components/DataTable/DataTableMobileCards.native.js +139 -38
- package/dist/cjs/components/DataTable/DataTableMobileCards.native.js.map +1 -1
- package/dist/cjs/components/DataTable/DataTableRoot.cjs +33 -6
- package/dist/cjs/components/DataTable/DataTableRoot.native.js +29 -4
- package/dist/cjs/components/DataTable/DataTableRoot.native.js.map +1 -1
- package/dist/cjs/components/DataTable/DataTableStateContext.native.js.map +1 -1
- package/dist/cjs/components/DataTable/index.native.js +59 -93
- package/dist/cjs/components/DataTable/index.native.js.map +1 -1
- package/dist/cjs/components/DataTableBulkActions/index.cjs +0 -4
- package/dist/cjs/components/DataTableBulkActions/index.native.js +0 -4
- package/dist/cjs/components/DataTableBulkActions/index.native.js.map +1 -1
- package/dist/cjs/components/DataTableCell/index.cjs +16 -1
- package/dist/cjs/components/DataTableCell/index.native.js +16 -1
- package/dist/cjs/components/DataTableCell/index.native.js.map +1 -1
- package/dist/cjs/components/DataTableDateFilter/index.cjs +0 -7
- package/dist/cjs/components/DataTableDateFilter/index.native.js +0 -7
- package/dist/cjs/components/DataTableDateFilter/index.native.js.map +1 -1
- package/dist/cjs/components/DataTableFilterButton/index.cjs +0 -1
- package/dist/cjs/components/DataTableFilterButton/index.native.js +0 -1
- package/dist/cjs/components/DataTableFilterChips/FilterChip.cjs +2 -1
- package/dist/cjs/components/DataTableFilterChips/FilterChip.native.js +4 -1
- package/dist/cjs/components/DataTableFilterChips/FilterChip.native.js.map +1 -1
- package/dist/cjs/components/DataTableFilters/index.cjs +0 -1
- package/dist/cjs/components/DataTableFilters/index.native.js +0 -1
- package/dist/cjs/components/DataTableGrouping/index.cjs +0 -8
- package/dist/cjs/components/DataTableGrouping/index.native.js +0 -8
- package/dist/cjs/components/DataTableGrouping/index.native.js.map +1 -1
- package/dist/cjs/components/DataTablePagination/index.cjs +29 -13
- package/dist/cjs/components/DataTablePagination/index.native.js +30 -14
- package/dist/cjs/components/DataTablePagination/index.native.js.map +1 -1
- package/dist/cjs/components/DataTableSearch/index.cjs +0 -3
- package/dist/cjs/components/DataTableSearch/index.native.js +0 -3
- package/dist/cjs/components/DataTableSearch/index.native.js.map +1 -1
- package/dist/cjs/components/DataTableToolbar/index.cjs +0 -1
- package/dist/cjs/components/DataTableToolbar/index.native.js +0 -1
- package/dist/cjs/components/DataTableToolbar/index.native.js.map +1 -1
- package/dist/cjs/components/DataTableViewOptions/index.cjs +0 -5
- package/dist/cjs/components/DataTableViewOptions/index.native.js +0 -5
- package/dist/cjs/components/DataTableViewOptions/index.native.js.map +1 -1
- package/dist/cjs/components/FilterManager.cjs +0 -1
- package/dist/cjs/components/FilterManager.native.js +0 -1
- package/dist/cjs/components/FilterManager.native.js.map +1 -1
- package/dist/cjs/components/FilterOperatorValueEditor/index.cjs +2 -2
- package/dist/cjs/components/FilterOperatorValueEditor/index.native.js +2 -2
- package/dist/cjs/components/FilterOperatorValueEditor/index.native.js.map +1 -1
- package/dist/cjs/components/TableInput/index.cjs +2 -1
- package/dist/cjs/components/TableInput/index.native.js +4 -2
- package/dist/cjs/components/TableInput/index.native.js.map +1 -1
- package/dist/cjs/hooks/useDataTable.cjs +24 -8
- package/dist/cjs/hooks/useDataTable.native.js +28 -8
- package/dist/cjs/hooks/useDataTable.native.js.map +1 -1
- package/dist/cjs/index.cjs +12 -0
- package/dist/cjs/index.native.js +12 -0
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/shared/devWarn.cjs +70 -0
- package/dist/cjs/shared/devWarn.native.js +84 -0
- package/dist/cjs/shared/devWarn.native.js.map +1 -0
- package/dist/cjs/utils/columnAlign.cjs +4 -1
- package/dist/cjs/utils/columnAlign.native.js +4 -1
- package/dist/cjs/utils/columnAlign.native.js.map +1 -1
- package/dist/cjs/utils/filterFields.cjs +5 -0
- package/dist/cjs/utils/filterFields.native.js +5 -0
- package/dist/cjs/utils/filterFields.native.js.map +1 -1
- package/dist/cjs/utils/filterUtils.cjs +30 -0
- package/dist/cjs/utils/filterUtils.native.js +50 -0
- package/dist/cjs/utils/filterUtils.native.js.map +1 -1
- package/dist/cjs/utils/money.cjs +137 -0
- package/dist/cjs/utils/money.native.js +165 -0
- package/dist/cjs/utils/money.native.js.map +1 -0
- package/dist/cjs/utils/rowAccumulator.cjs +48 -0
- package/dist/cjs/utils/rowAccumulator.native.js +51 -0
- package/dist/cjs/utils/rowAccumulator.native.js.map +1 -0
- package/dist/esm/components/ColumnHeaderFilter/index.mjs +78 -42
- package/dist/esm/components/ColumnHeaderFilter/index.mjs.map +1 -1
- package/dist/esm/components/ColumnHeaderFilter/index.native.js +101 -55
- package/dist/esm/components/ColumnHeaderFilter/index.native.js.map +1 -1
- package/dist/esm/components/DataTable/DataTableCardControls.mjs +0 -1
- package/dist/esm/components/DataTable/DataTableCardControls.mjs.map +1 -1
- package/dist/esm/components/DataTable/DataTableCardControls.native.js +0 -1
- package/dist/esm/components/DataTable/DataTableCardControls.native.js.map +1 -1
- package/dist/esm/components/DataTable/DataTableMobileCards.mjs +99 -34
- package/dist/esm/components/DataTable/DataTableMobileCards.mjs.map +1 -1
- package/dist/esm/components/DataTable/DataTableMobileCards.native.js +138 -39
- package/dist/esm/components/DataTable/DataTableMobileCards.native.js.map +1 -1
- package/dist/esm/components/DataTable/DataTableRoot.mjs +33 -6
- package/dist/esm/components/DataTable/DataTableRoot.mjs.map +1 -1
- package/dist/esm/components/DataTable/DataTableRoot.native.js +29 -4
- package/dist/esm/components/DataTable/DataTableRoot.native.js.map +1 -1
- package/dist/esm/components/DataTable/DataTableStateContext.mjs.map +1 -1
- package/dist/esm/components/DataTable/DataTableStateContext.native.js.map +1 -1
- package/dist/esm/components/DataTable/index.native.js +60 -94
- package/dist/esm/components/DataTable/index.native.js.map +1 -1
- package/dist/esm/components/DataTableBulkActions/index.mjs +0 -4
- package/dist/esm/components/DataTableBulkActions/index.mjs.map +1 -1
- package/dist/esm/components/DataTableBulkActions/index.native.js +0 -4
- package/dist/esm/components/DataTableBulkActions/index.native.js.map +1 -1
- package/dist/esm/components/DataTableCell/index.mjs +17 -2
- package/dist/esm/components/DataTableCell/index.mjs.map +1 -1
- package/dist/esm/components/DataTableCell/index.native.js +17 -2
- package/dist/esm/components/DataTableCell/index.native.js.map +1 -1
- package/dist/esm/components/DataTableDateFilter/index.mjs +0 -7
- package/dist/esm/components/DataTableDateFilter/index.mjs.map +1 -1
- package/dist/esm/components/DataTableDateFilter/index.native.js +0 -7
- package/dist/esm/components/DataTableDateFilter/index.native.js.map +1 -1
- package/dist/esm/components/DataTableFilterButton/index.mjs +0 -1
- package/dist/esm/components/DataTableFilterButton/index.mjs.map +1 -1
- package/dist/esm/components/DataTableFilterButton/index.native.js +0 -1
- package/dist/esm/components/DataTableFilterChips/FilterChip.mjs +3 -2
- package/dist/esm/components/DataTableFilterChips/FilterChip.mjs.map +1 -1
- package/dist/esm/components/DataTableFilterChips/FilterChip.native.js +5 -2
- package/dist/esm/components/DataTableFilterChips/FilterChip.native.js.map +1 -1
- package/dist/esm/components/DataTableFilters/index.mjs +0 -1
- package/dist/esm/components/DataTableFilters/index.mjs.map +1 -1
- package/dist/esm/components/DataTableFilters/index.native.js +0 -1
- package/dist/esm/components/DataTableGrouping/index.mjs +0 -8
- package/dist/esm/components/DataTableGrouping/index.mjs.map +1 -1
- package/dist/esm/components/DataTableGrouping/index.native.js +0 -8
- package/dist/esm/components/DataTableGrouping/index.native.js.map +1 -1
- package/dist/esm/components/DataTablePagination/index.mjs +30 -14
- package/dist/esm/components/DataTablePagination/index.mjs.map +1 -1
- package/dist/esm/components/DataTablePagination/index.native.js +31 -15
- package/dist/esm/components/DataTablePagination/index.native.js.map +1 -1
- package/dist/esm/components/DataTableSearch/index.mjs +0 -3
- package/dist/esm/components/DataTableSearch/index.mjs.map +1 -1
- package/dist/esm/components/DataTableSearch/index.native.js +0 -3
- package/dist/esm/components/DataTableSearch/index.native.js.map +1 -1
- package/dist/esm/components/DataTableToolbar/index.mjs +0 -1
- package/dist/esm/components/DataTableToolbar/index.mjs.map +1 -1
- package/dist/esm/components/DataTableToolbar/index.native.js +0 -1
- package/dist/esm/components/DataTableToolbar/index.native.js.map +1 -1
- package/dist/esm/components/DataTableViewOptions/index.mjs +0 -5
- package/dist/esm/components/DataTableViewOptions/index.mjs.map +1 -1
- package/dist/esm/components/DataTableViewOptions/index.native.js +0 -5
- package/dist/esm/components/DataTableViewOptions/index.native.js.map +1 -1
- package/dist/esm/components/FilterManager.mjs +0 -1
- package/dist/esm/components/FilterManager.mjs.map +1 -1
- package/dist/esm/components/FilterManager.native.js +0 -1
- package/dist/esm/components/FilterManager.native.js.map +1 -1
- package/dist/esm/components/FilterOperatorValueEditor/index.mjs +2 -2
- package/dist/esm/components/FilterOperatorValueEditor/index.mjs.map +1 -1
- package/dist/esm/components/FilterOperatorValueEditor/index.native.js +2 -2
- package/dist/esm/components/FilterOperatorValueEditor/index.native.js.map +1 -1
- package/dist/esm/components/TableInput/index.mjs +3 -2
- package/dist/esm/components/TableInput/index.mjs.map +1 -1
- package/dist/esm/components/TableInput/index.native.js +5 -3
- package/dist/esm/components/TableInput/index.native.js.map +1 -1
- package/dist/esm/hooks/useDataTable.mjs +24 -8
- package/dist/esm/hooks/useDataTable.mjs.map +1 -1
- package/dist/esm/hooks/useDataTable.native.js +28 -8
- package/dist/esm/hooks/useDataTable.native.js.map +1 -1
- package/dist/esm/index.mjs +3 -1
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +3 -1
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/shared/devWarn.mjs +43 -0
- package/dist/esm/shared/devWarn.mjs.map +1 -0
- package/dist/esm/shared/devWarn.native.js +54 -0
- package/dist/esm/shared/devWarn.native.js.map +1 -0
- package/dist/esm/utils/columnAlign.mjs +4 -1
- package/dist/esm/utils/columnAlign.mjs.map +1 -1
- package/dist/esm/utils/columnAlign.native.js +4 -1
- package/dist/esm/utils/columnAlign.native.js.map +1 -1
- package/dist/esm/utils/filterFields.mjs +5 -0
- package/dist/esm/utils/filterFields.mjs.map +1 -1
- package/dist/esm/utils/filterFields.native.js +5 -0
- package/dist/esm/utils/filterFields.native.js.map +1 -1
- package/dist/esm/utils/filterUtils.mjs +30 -0
- package/dist/esm/utils/filterUtils.mjs.map +1 -1
- package/dist/esm/utils/filterUtils.native.js +50 -0
- package/dist/esm/utils/filterUtils.native.js.map +1 -1
- package/dist/esm/utils/money.mjs +104 -0
- package/dist/esm/utils/money.mjs.map +1 -0
- package/dist/esm/utils/money.native.js +129 -0
- package/dist/esm/utils/money.native.js.map +1 -0
- package/dist/esm/utils/rowAccumulator.mjs +23 -0
- package/dist/esm/utils/rowAccumulator.mjs.map +1 -0
- package/dist/esm/utils/rowAccumulator.native.js +23 -0
- package/dist/esm/utils/rowAccumulator.native.js.map +1 -0
- package/dist/jsx/components/ColumnHeaderFilter/index.mjs +78 -42
- package/dist/jsx/components/ColumnHeaderFilter/index.mjs.map +1 -1
- package/dist/jsx/components/ColumnHeaderFilter/index.native.js +97 -51
- package/dist/jsx/components/ColumnHeaderFilter/index.native.js.map +1 -1
- package/dist/jsx/components/DataTable/DataTableCardControls.mjs +0 -1
- package/dist/jsx/components/DataTable/DataTableCardControls.mjs.map +1 -1
- package/dist/jsx/components/DataTable/DataTableCardControls.native.js +0 -1
- package/dist/jsx/components/DataTable/DataTableCardControls.native.js.map +1 -1
- package/dist/jsx/components/DataTable/DataTableMobileCards.mjs +99 -34
- package/dist/jsx/components/DataTable/DataTableMobileCards.mjs.map +1 -1
- package/dist/jsx/components/DataTable/DataTableMobileCards.native.js +139 -38
- package/dist/jsx/components/DataTable/DataTableMobileCards.native.js.map +1 -1
- package/dist/jsx/components/DataTable/DataTableRoot.mjs +33 -6
- package/dist/jsx/components/DataTable/DataTableRoot.mjs.map +1 -1
- package/dist/jsx/components/DataTable/DataTableRoot.native.js +29 -4
- package/dist/jsx/components/DataTable/DataTableRoot.native.js.map +1 -1
- package/dist/jsx/components/DataTable/DataTableStateContext.mjs.map +1 -1
- package/dist/jsx/components/DataTable/DataTableStateContext.native.js.map +1 -1
- package/dist/jsx/components/DataTable/index.native.js +59 -93
- package/dist/jsx/components/DataTable/index.native.js.map +1 -1
- package/dist/jsx/components/DataTableBulkActions/index.mjs +0 -4
- package/dist/jsx/components/DataTableBulkActions/index.mjs.map +1 -1
- package/dist/jsx/components/DataTableBulkActions/index.native.js +0 -4
- package/dist/jsx/components/DataTableBulkActions/index.native.js.map +1 -1
- package/dist/jsx/components/DataTableCell/index.mjs +17 -2
- package/dist/jsx/components/DataTableCell/index.mjs.map +1 -1
- package/dist/jsx/components/DataTableCell/index.native.js +16 -1
- package/dist/jsx/components/DataTableCell/index.native.js.map +1 -1
- package/dist/jsx/components/DataTableDateFilter/index.mjs +0 -7
- package/dist/jsx/components/DataTableDateFilter/index.mjs.map +1 -1
- package/dist/jsx/components/DataTableDateFilter/index.native.js +0 -7
- package/dist/jsx/components/DataTableDateFilter/index.native.js.map +1 -1
- package/dist/jsx/components/DataTableFilterButton/index.mjs +0 -1
- package/dist/jsx/components/DataTableFilterButton/index.mjs.map +1 -1
- package/dist/jsx/components/DataTableFilterButton/index.native.js +0 -1
- package/dist/jsx/components/DataTableFilterChips/FilterChip.mjs +3 -2
- package/dist/jsx/components/DataTableFilterChips/FilterChip.mjs.map +1 -1
- package/dist/jsx/components/DataTableFilterChips/FilterChip.native.js +4 -1
- package/dist/jsx/components/DataTableFilterChips/FilterChip.native.js.map +1 -1
- package/dist/jsx/components/DataTableFilters/index.mjs +0 -1
- package/dist/jsx/components/DataTableFilters/index.mjs.map +1 -1
- package/dist/jsx/components/DataTableFilters/index.native.js +0 -1
- package/dist/jsx/components/DataTableGrouping/index.mjs +0 -8
- package/dist/jsx/components/DataTableGrouping/index.mjs.map +1 -1
- package/dist/jsx/components/DataTableGrouping/index.native.js +0 -8
- package/dist/jsx/components/DataTableGrouping/index.native.js.map +1 -1
- package/dist/jsx/components/DataTablePagination/index.mjs +30 -14
- package/dist/jsx/components/DataTablePagination/index.mjs.map +1 -1
- package/dist/jsx/components/DataTablePagination/index.native.js +30 -14
- package/dist/jsx/components/DataTablePagination/index.native.js.map +1 -1
- package/dist/jsx/components/DataTableSearch/index.mjs +0 -3
- package/dist/jsx/components/DataTableSearch/index.mjs.map +1 -1
- package/dist/jsx/components/DataTableSearch/index.native.js +0 -3
- package/dist/jsx/components/DataTableSearch/index.native.js.map +1 -1
- package/dist/jsx/components/DataTableToolbar/index.mjs +0 -1
- package/dist/jsx/components/DataTableToolbar/index.mjs.map +1 -1
- package/dist/jsx/components/DataTableToolbar/index.native.js +0 -1
- package/dist/jsx/components/DataTableToolbar/index.native.js.map +1 -1
- package/dist/jsx/components/DataTableViewOptions/index.mjs +0 -5
- package/dist/jsx/components/DataTableViewOptions/index.mjs.map +1 -1
- package/dist/jsx/components/DataTableViewOptions/index.native.js +0 -5
- package/dist/jsx/components/DataTableViewOptions/index.native.js.map +1 -1
- package/dist/jsx/components/FilterManager.mjs +0 -1
- package/dist/jsx/components/FilterManager.mjs.map +1 -1
- package/dist/jsx/components/FilterManager.native.js +0 -1
- package/dist/jsx/components/FilterManager.native.js.map +1 -1
- package/dist/jsx/components/FilterOperatorValueEditor/index.mjs +2 -2
- package/dist/jsx/components/FilterOperatorValueEditor/index.mjs.map +1 -1
- package/dist/jsx/components/FilterOperatorValueEditor/index.native.js +2 -2
- package/dist/jsx/components/FilterOperatorValueEditor/index.native.js.map +1 -1
- package/dist/jsx/components/TableInput/index.mjs +3 -2
- package/dist/jsx/components/TableInput/index.mjs.map +1 -1
- package/dist/jsx/components/TableInput/index.native.js +4 -2
- package/dist/jsx/components/TableInput/index.native.js.map +1 -1
- package/dist/jsx/hooks/useDataTable.mjs +24 -8
- package/dist/jsx/hooks/useDataTable.mjs.map +1 -1
- package/dist/jsx/hooks/useDataTable.native.js +28 -8
- package/dist/jsx/hooks/useDataTable.native.js.map +1 -1
- package/dist/jsx/index.js +3 -1
- package/dist/jsx/index.js.map +1 -1
- package/dist/jsx/index.mjs +3 -1
- package/dist/jsx/index.mjs.map +1 -1
- package/dist/jsx/index.native.js +12 -0
- package/dist/jsx/index.native.js.map +1 -1
- package/dist/jsx/shared/devWarn.mjs +43 -0
- package/dist/jsx/shared/devWarn.mjs.map +1 -0
- package/dist/jsx/shared/devWarn.native.js +84 -0
- package/dist/jsx/shared/devWarn.native.js.map +1 -0
- package/dist/jsx/utils/columnAlign.mjs +4 -1
- package/dist/jsx/utils/columnAlign.mjs.map +1 -1
- package/dist/jsx/utils/columnAlign.native.js +4 -1
- package/dist/jsx/utils/columnAlign.native.js.map +1 -1
- package/dist/jsx/utils/filterFields.mjs +5 -0
- package/dist/jsx/utils/filterFields.mjs.map +1 -1
- package/dist/jsx/utils/filterFields.native.js +5 -0
- package/dist/jsx/utils/filterFields.native.js.map +1 -1
- package/dist/jsx/utils/filterUtils.mjs +30 -0
- package/dist/jsx/utils/filterUtils.mjs.map +1 -1
- package/dist/jsx/utils/filterUtils.native.js +50 -0
- package/dist/jsx/utils/filterUtils.native.js.map +1 -1
- package/dist/jsx/utils/money.mjs +104 -0
- package/dist/jsx/utils/money.mjs.map +1 -0
- package/dist/jsx/utils/money.native.js +165 -0
- package/dist/jsx/utils/money.native.js.map +1 -0
- package/dist/jsx/utils/rowAccumulator.mjs +23 -0
- package/dist/jsx/utils/rowAccumulator.mjs.map +1 -0
- package/dist/jsx/utils/rowAccumulator.native.js +51 -0
- package/dist/jsx/utils/rowAccumulator.native.js.map +1 -0
- package/package.json +12 -12
- package/src/components/ColumnHeaderFilter/ColumnHeaderFilter.spec.tsx +142 -7
- package/src/components/ColumnHeaderFilter/ColumnHeaderFilter.stories.tsx +46 -9
- package/src/components/ColumnHeaderFilter/index.tsx +104 -47
- package/src/components/DataTable/DataTable.spec.tsx +5 -3
- package/src/components/DataTable/DataTable.stories.tsx +186 -14
- package/src/components/DataTable/DataTableCardControls.tsx +11 -13
- package/src/components/DataTable/DataTableMobileCards.tsx +162 -39
- package/src/components/DataTable/DataTableRoot.tsx +40 -14
- package/src/components/DataTable/DataTableStateContext.ts +7 -0
- package/src/components/DataTable/cardLayout.spec.tsx +19 -8
- package/src/components/DataTable/columnWidthLayout.spec.tsx +195 -0
- package/src/components/DataTable/dataTableMobileCards.spec.tsx +50 -2
- package/src/components/DataTable/headerSorting.spec.tsx +25 -0
- package/src/components/DataTable/index.native.tsx +80 -124
- package/src/components/DataTable/moneyColumn.spec.tsx +151 -0
- package/src/components/DataTable/nativeCardParity.spec.tsx +95 -0
- package/src/components/DataTable/rowAccumulator.spec.tsx +171 -0
- package/src/components/DataTableBulkActions/index.tsx +0 -4
- package/src/components/DataTableCell/index.tsx +28 -2
- package/src/components/DataTableColumnPinning/DataTableColumnPinning.stories.tsx +0 -4
- package/src/components/DataTableDateFilter/index.tsx +0 -7
- package/src/components/DataTableFilterButton/index.tsx +1 -1
- package/src/components/DataTableFilterChips/FilterChip.spec.tsx +6 -0
- package/src/components/DataTableFilterChips/FilterChip.tsx +3 -2
- package/src/components/DataTableFilters/index.tsx +1 -1
- package/src/components/DataTableGrouping/DataTableGrouping.stories.tsx +0 -4
- package/src/components/DataTableGrouping/index.tsx +1 -13
- package/src/components/DataTablePagination/DataTablePagination.stories.tsx +14 -1
- package/src/components/DataTablePagination/DataTablePagination.width.spec.tsx +51 -0
- package/src/components/DataTablePagination/index.tsx +60 -16
- package/src/components/DataTableSearch/index.tsx +2 -3
- package/src/components/DataTableToolbar/DataTableToolbar.stories.tsx +2 -4
- package/src/components/DataTableToolbar/index.tsx +1 -5
- package/src/components/DataTableViewOptions/index.tsx +2 -13
- package/src/components/FilterManager.tsx +1 -3
- package/src/components/FilterOperatorValueEditor/FilterOperatorValueEditor.spec.tsx +1 -1
- package/src/components/FilterOperatorValueEditor/FilterOperatorValueEditor.stories.tsx +1 -0
- package/src/components/FilterOperatorValueEditor/index.tsx +10 -2
- package/src/components/TableInput/index.native.tsx +3 -2
- package/src/components/TableInput/index.tsx +3 -2
- package/src/hooks/useDataTable.ts +43 -7
- package/src/index.ts +13 -0
- package/src/shared/devWarn.ts +97 -0
- package/src/types.ts +71 -2
- package/src/utils/columnAlign.ts +9 -1
- package/src/utils/filterFields.ts +23 -1
- package/src/utils/filterUtils.ts +50 -1
- package/src/utils/money.spec.ts +156 -0
- package/src/utils/money.ts +202 -0
- package/src/utils/rowAccumulator.ts +136 -0
- package/types/components/ColumnHeaderFilter/index.d.ts +9 -2
- package/types/components/ColumnHeaderFilter/index.d.ts.map +1 -1
- package/types/components/DataTable/DataTableCardControls.d.ts.map +1 -1
- package/types/components/DataTable/DataTableMobileCards.d.ts +42 -8
- 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/DataTableStateContext.d.ts +7 -0
- package/types/components/DataTable/DataTableStateContext.d.ts.map +1 -1
- package/types/components/DataTable/index.native.d.ts +1 -1
- package/types/components/DataTable/index.native.d.ts.map +1 -1
- package/types/components/DataTableBulkActions/index.d.ts.map +1 -1
- package/types/components/DataTableCell/index.d.ts.map +1 -1
- package/types/components/DataTableDateFilter/index.d.ts.map +1 -1
- package/types/components/DataTableFilterChips/FilterChip.d.ts.map +1 -1
- package/types/components/DataTableGrouping/index.d.ts.map +1 -1
- 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.map +1 -1
- package/types/components/DataTableViewOptions/index.d.ts.map +1 -1
- package/types/components/FilterManager.d.ts.map +1 -1
- package/types/components/FilterOperatorValueEditor/index.d.ts.map +1 -1
- package/types/components/TableInput/index.d.ts.map +1 -1
- package/types/components/TableInput/index.native.d.ts.map +1 -1
- package/types/hooks/useDataTable.d.ts +1 -1
- package/types/hooks/useDataTable.d.ts.map +1 -1
- package/types/index.d.ts +3 -0
- package/types/index.d.ts.map +1 -1
- package/types/shared/devWarn.d.ts +50 -0
- package/types/shared/devWarn.d.ts.map +1 -0
- package/types/types.d.ts +71 -3
- package/types/types.d.ts.map +1 -1
- package/types/utils/columnAlign.d.ts.map +1 -1
- package/types/utils/filterFields.d.ts.map +1 -1
- package/types/utils/filterUtils.d.ts +1 -1
- package/types/utils/filterUtils.d.ts.map +1 -1
- package/types/utils/money.d.ts +94 -0
- package/types/utils/money.d.ts.map +1 -0
- package/types/utils/rowAccumulator.d.ts +107 -0
- package/types/utils/rowAccumulator.d.ts.map +1 -0
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* breakpoint switch are exercised without resizing a window.
|
|
8
8
|
*
|
|
9
9
|
* Covers: breakpoint/override switching, card anatomy (title slot +
|
|
10
|
-
*
|
|
10
|
+
* classified fields), column visibility, sorting order, global search,
|
|
11
11
|
* column filters, the card sort/filter controls, the SimpleTable layout
|
|
12
12
|
* override, and the Table primitives card layout.
|
|
13
13
|
*/
|
|
@@ -127,7 +127,7 @@ describe("DataTable card layout", () => {
|
|
|
127
127
|
});
|
|
128
128
|
|
|
129
129
|
describe("card anatomy", () => {
|
|
130
|
-
it("renders the first visible column as the card title and the rest
|
|
130
|
+
it("renders the first visible column as the card title and classifies the rest", () => {
|
|
131
131
|
const { container } = renderWithProviders(
|
|
132
132
|
<DataTable data={sampleData} columns={columns} onStateChange={vi.fn()} />,
|
|
133
133
|
);
|
|
@@ -140,15 +140,21 @@ describe("DataTable card layout", () => {
|
|
|
140
140
|
expect(title!.textContent).toContain("John");
|
|
141
141
|
expect(within(firstCard).queryByText("First Name")).toBeNull();
|
|
142
142
|
|
|
143
|
-
//
|
|
144
|
-
|
|
143
|
+
// A self-naming string goes bare. Its column name still reaches
|
|
144
|
+
// assistive tech, through a hidden node that costs no layout.
|
|
145
|
+
expect(within(firstCard).queryByText("Last Name")).toBeNull();
|
|
146
|
+
expect(within(firstCard).queryByText("Email")).toBeNull();
|
|
147
|
+
expect(firstCard.textContent).toContain("Last Name:");
|
|
148
|
+
expect(firstCard.textContent).toContain("Email:");
|
|
149
|
+
|
|
150
|
+
// A figure cannot be read without its name, so that one prints.
|
|
145
151
|
expect(within(firstCard).getByText("Age")).toBeDefined();
|
|
146
|
-
|
|
152
|
+
|
|
147
153
|
expect(firstCard.textContent).toContain("Doe");
|
|
148
154
|
expect(firstCard.textContent).toContain("28");
|
|
149
155
|
});
|
|
150
156
|
|
|
151
|
-
it("
|
|
157
|
+
it("names a control from meta.label when the header is a render function", () => {
|
|
152
158
|
const glyphColumns: DataTableColumn<Person>[] = [
|
|
153
159
|
{ id: "firstName", accessorKey: "firstName", header: "First Name" },
|
|
154
160
|
{
|
|
@@ -162,7 +168,9 @@ describe("DataTable card layout", () => {
|
|
|
162
168
|
<DataTable data={sampleData} columns={glyphColumns} onStateChange={vi.fn()} />,
|
|
163
169
|
);
|
|
164
170
|
const [firstCard] = getCards(container);
|
|
165
|
-
|
|
171
|
+
// A leading underscore marks a control: its own row, no printed label.
|
|
172
|
+
expect(within(firstCard).queryByText("Liked")).toBeNull();
|
|
173
|
+
expect(firstCard.textContent).toContain("Liked:");
|
|
166
174
|
expect(firstCard.textContent).not.toContain("_liked_by");
|
|
167
175
|
});
|
|
168
176
|
|
|
@@ -180,9 +188,11 @@ describe("DataTable card layout", () => {
|
|
|
180
188
|
<DataTable data={sampleData} columns={mixedColumns} onStateChange={vi.fn()} />,
|
|
181
189
|
);
|
|
182
190
|
const [firstCard] = getCards(container);
|
|
191
|
+
// A figure prints its name, a bare string hides it. meta.label wins
|
|
192
|
+
// either way, and the id fallback stays honest.
|
|
183
193
|
expect(within(firstCard).getByText("Age (years)")).toBeDefined();
|
|
184
194
|
expect(within(firstCard).queryByText("♥")).toBeNull();
|
|
185
|
-
expect(
|
|
195
|
+
expect(firstCard.textContent).toContain("email_addr:");
|
|
186
196
|
});
|
|
187
197
|
|
|
188
198
|
it("respects column visibility (hidden columns stay hidden in cards)", () => {
|
|
@@ -196,6 +206,7 @@ describe("DataTable card layout", () => {
|
|
|
196
206
|
);
|
|
197
207
|
const [firstCard] = getCards(container);
|
|
198
208
|
expect(within(firstCard).queryByText("Email")).toBeNull();
|
|
209
|
+
expect(firstCard.textContent).not.toContain("Email:");
|
|
199
210
|
expect(firstCard.textContent).not.toContain("john@example.com");
|
|
200
211
|
});
|
|
201
212
|
});
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MPO-236 — per-column width under `columnLayout: "equal"`.
|
|
3
|
+
*
|
|
4
|
+
* `equal` is the default, and it flexes every cell to `flexGrow: 1,
|
|
5
|
+
* flexBasis: 0`. A column's `width` / `size` therefore never reaches the cell
|
|
6
|
+
* box: the render comes out identical to one that declared no widths at all,
|
|
7
|
+
* which reads as "the widths ARE applied and are not enough" and sends the
|
|
8
|
+
* reader looking in the wrong place.
|
|
9
|
+
*
|
|
10
|
+
* The default is not changed here — that would move every existing table's
|
|
11
|
+
* render. The combination warns instead, naming `columnLayout` as the reason.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
15
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
16
|
+
import type { DataTableColumn } from "../../types";
|
|
17
|
+
import { __resetTableDevWarnSeen, warnColumnWidthIgnored } from "../../shared/devWarn";
|
|
18
|
+
import { DataTable } from "./index";
|
|
19
|
+
|
|
20
|
+
type Pokemon = { id: number; name: string; xp: number };
|
|
21
|
+
|
|
22
|
+
const sampleData: Pokemon[] = [
|
|
23
|
+
{ id: 1, name: "Bulbasaur", xp: 64 },
|
|
24
|
+
{ id: 2, name: "Charmander", xp: 62 },
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
const plainColumns: DataTableColumn<Pokemon>[] = [
|
|
28
|
+
{ id: "name", accessorKey: "name", header: "Name" },
|
|
29
|
+
{ id: "xp", accessorKey: "xp", header: "XP" },
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
const widthColumns: DataTableColumn<Pokemon>[] = [
|
|
33
|
+
{ id: "name", accessorKey: "name", header: "Name", width: 320 },
|
|
34
|
+
{ id: "xp", accessorKey: "xp", header: "XP", width: 80 },
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
let warnings: string[] = [];
|
|
38
|
+
let warnSpy: ReturnType<typeof vi.spyOn>;
|
|
39
|
+
|
|
40
|
+
function startCapture() {
|
|
41
|
+
warnings = [];
|
|
42
|
+
__resetTableDevWarnSeen();
|
|
43
|
+
warnSpy = vi.spyOn(console, "warn").mockImplementation((...args) => {
|
|
44
|
+
warnings.push(args.map((arg) => String(arg)).join(" "));
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function stopCapture() {
|
|
49
|
+
warnSpy.mockRestore();
|
|
50
|
+
__resetTableDevWarnSeen();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Only this rule's warnings — other table chrome may warn for its own reasons. */
|
|
54
|
+
function widthWarnings(): string[] {
|
|
55
|
+
return warnings.filter((line) => line.includes("column-width-ignored"));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* React 19's client `useId` counter is module-global (`_r_<base32>_`), so two
|
|
60
|
+
* renders in one process never share generated ids. Normalize them out before
|
|
61
|
+
* comparing markup.
|
|
62
|
+
*/
|
|
63
|
+
function stripGeneratedIds(html: string): string {
|
|
64
|
+
return html.replace(/_r_[0-9a-z]+_/g, "_r_id_");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** `columnLayout` omitted on purpose in most calls: "equal" is the default. */
|
|
68
|
+
function renderTable(
|
|
69
|
+
columns: DataTableColumn<Pokemon>[],
|
|
70
|
+
columnLayout?: "equal" | "auto" | "scroll",
|
|
71
|
+
) {
|
|
72
|
+
return renderWithProviders(
|
|
73
|
+
<DataTable
|
|
74
|
+
data={sampleData}
|
|
75
|
+
columns={columns as DataTableColumn<Record<string, any>>[]}
|
|
76
|
+
layout="table"
|
|
77
|
+
columnLayout={columnLayout}
|
|
78
|
+
enablePagination={false}
|
|
79
|
+
readOnly
|
|
80
|
+
/>,
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
describe("warnColumnWidthIgnored", () => {
|
|
85
|
+
let prevEnv: string | undefined;
|
|
86
|
+
|
|
87
|
+
beforeEach(() => {
|
|
88
|
+
prevEnv = process.env.NODE_ENV;
|
|
89
|
+
process.env.NODE_ENV = "development";
|
|
90
|
+
startCapture();
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
afterEach(() => {
|
|
94
|
+
stopCapture();
|
|
95
|
+
process.env.NODE_ENV = prevEnv;
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it("names columnLayout and the offending columns", () => {
|
|
99
|
+
warnColumnWidthIgnored({ columnLayout: "equal", columns: widthColumns });
|
|
100
|
+
expect(widthWarnings()).toHaveLength(1);
|
|
101
|
+
expect(widthWarnings()[0]).toContain("[table] column-width-ignored");
|
|
102
|
+
expect(widthWarnings()[0]).toContain("columnLayout=equal");
|
|
103
|
+
expect(widthWarnings()[0]).toContain("columns=name,xp");
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it("catches the TanStack `size` spelling too", () => {
|
|
107
|
+
warnColumnWidthIgnored({ columnLayout: "equal", columns: [{ id: "avatar", size: 60 }] });
|
|
108
|
+
expect(widthWarnings()).toHaveLength(1);
|
|
109
|
+
expect(widthWarnings()[0]).toContain("columns=avatar");
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it("falls back to accessorKey, then position, for the column name", () => {
|
|
113
|
+
warnColumnWidthIgnored({
|
|
114
|
+
columnLayout: "equal",
|
|
115
|
+
columns: [{ accessorKey: "xp", width: 80 }, { size: 60 }],
|
|
116
|
+
});
|
|
117
|
+
expect(widthWarnings()[0]).toContain("columns=xp,#1");
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it("stays quiet when no column declares a width", () => {
|
|
121
|
+
warnColumnWidthIgnored({ columnLayout: "equal", columns: plainColumns });
|
|
122
|
+
expect(widthWarnings()).toHaveLength(0);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it.each(["auto", "scroll"] as const)("stays quiet under columnLayout=%s", (columnLayout) => {
|
|
126
|
+
warnColumnWidthIgnored({ columnLayout, columns: widthColumns });
|
|
127
|
+
expect(widthWarnings()).toHaveLength(0);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it("stays quiet with enableColumnResizing, where the width does survive", () => {
|
|
131
|
+
warnColumnWidthIgnored({
|
|
132
|
+
columnLayout: "equal",
|
|
133
|
+
enableColumnResizing: true,
|
|
134
|
+
columns: widthColumns,
|
|
135
|
+
});
|
|
136
|
+
expect(widthWarnings()).toHaveLength(0);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it("no-ops in production", () => {
|
|
140
|
+
process.env.NODE_ENV = "production";
|
|
141
|
+
warnColumnWidthIgnored({ columnLayout: "equal", columns: widthColumns });
|
|
142
|
+
expect(widthWarnings()).toHaveLength(0);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it("warns once per offending column set, not once per call", () => {
|
|
146
|
+
warnColumnWidthIgnored({ columnLayout: "equal", columns: widthColumns });
|
|
147
|
+
warnColumnWidthIgnored({ columnLayout: "equal", columns: widthColumns });
|
|
148
|
+
warnColumnWidthIgnored({ columnLayout: "equal", columns: widthColumns });
|
|
149
|
+
expect(widthWarnings()).toHaveLength(1);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
describe("DataTable columnLayout=equal with per-column widths", () => {
|
|
154
|
+
beforeEach(startCapture);
|
|
155
|
+
afterEach(stopCapture);
|
|
156
|
+
|
|
157
|
+
it("discards the widths: the markup matches a table that declared none", () => {
|
|
158
|
+
const withWidths = renderTable(widthColumns);
|
|
159
|
+
const widthMarkup = stripGeneratedIds(withWidths.container.innerHTML);
|
|
160
|
+
withWidths.unmount();
|
|
161
|
+
|
|
162
|
+
const withoutWidths = renderTable(plainColumns);
|
|
163
|
+
expect(stripGeneratedIds(withoutWidths.container.innerHTML)).toBe(widthMarkup);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it("warns, so the discard is not silent", () => {
|
|
167
|
+
renderTable(widthColumns);
|
|
168
|
+
expect(widthWarnings()).toHaveLength(1);
|
|
169
|
+
expect(widthWarnings()[0]).toContain("component=DataTable");
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it("warns once per table, not once per render", () => {
|
|
173
|
+
const { rerender } = renderTable(widthColumns);
|
|
174
|
+
rerender(
|
|
175
|
+
<DataTable
|
|
176
|
+
data={[...sampleData, { id: 3, name: "Squirtle", xp: 63 }]}
|
|
177
|
+
columns={widthColumns as DataTableColumn<Record<string, any>>[]}
|
|
178
|
+
layout="table"
|
|
179
|
+
enablePagination={false}
|
|
180
|
+
readOnly
|
|
181
|
+
/>,
|
|
182
|
+
);
|
|
183
|
+
expect(widthWarnings()).toHaveLength(1);
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
it("does not warn under columnLayout=auto", () => {
|
|
187
|
+
renderTable(widthColumns, "auto");
|
|
188
|
+
expect(widthWarnings()).toHaveLength(0);
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
it("does not warn for a table with no per-column widths", () => {
|
|
192
|
+
renderTable(plainColumns);
|
|
193
|
+
expect(widthWarnings()).toHaveLength(0);
|
|
194
|
+
});
|
|
195
|
+
});
|
|
@@ -8,10 +8,14 @@
|
|
|
8
8
|
* delete cluster beside the title, the delete floor at `minRows`, and the two
|
|
9
9
|
* distinct empty-state copies (no data vs no results) — plus the rule that an
|
|
10
10
|
* in-flight refetch paints NO empty state over a momentarily blank body.
|
|
11
|
+
*
|
|
12
|
+
* It also pins `classifyCardField`, which decides whether a field prints its
|
|
13
|
+
* column name at all. In the grid a header is written once for a whole
|
|
14
|
+
* column; on a card it would be written once per value.
|
|
11
15
|
*/
|
|
12
16
|
|
|
13
17
|
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
14
|
-
import { fireEvent, screen, waitFor } from "@testing-library/react";
|
|
18
|
+
import { fireEvent, screen, waitFor, within } from "@testing-library/react";
|
|
15
19
|
import { describe, expect, it, vi } from "vitest";
|
|
16
20
|
import type { DataTableColumn, TableFilter } from "../../types";
|
|
17
21
|
import { DataTable } from "./index";
|
|
@@ -52,7 +56,7 @@ describe("DataTableMobileCards", () => {
|
|
|
52
56
|
expect(cards(container).length).toBe(people.length);
|
|
53
57
|
});
|
|
54
58
|
|
|
55
|
-
it("the first visible column is the card title, the rest are
|
|
59
|
+
it("the first visible column is the card title, the rest are classified fields", () => {
|
|
56
60
|
const { container } = renderCards();
|
|
57
61
|
const first = cards(container)[0];
|
|
58
62
|
expect(first.querySelector('[data-card-slot="title"]')?.textContent).toBe("John");
|
|
@@ -69,6 +73,50 @@ describe("DataTableMobileCards", () => {
|
|
|
69
73
|
expect(first.textContent).not.toContain("Last Name");
|
|
70
74
|
});
|
|
71
75
|
|
|
76
|
+
it("a self-naming string goes bare, into one wrapped flow with its name hidden", () => {
|
|
77
|
+
const { container } = renderCards();
|
|
78
|
+
const first = cards(container)[0];
|
|
79
|
+
const meta = first.querySelector('[data-card-slot="meta"]');
|
|
80
|
+
expect(meta).not.toBeNull();
|
|
81
|
+
expect(meta!.textContent).toContain("Doe");
|
|
82
|
+
expect(within(first).queryByText("Last Name")).toBeNull();
|
|
83
|
+
expect(first.textContent).toContain("Last Name:");
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("a figure keeps its column name, inline beside the value", () => {
|
|
87
|
+
const { container } = renderCards();
|
|
88
|
+
const first = cards(container)[0];
|
|
89
|
+
const figure = first.querySelector('[data-card-slot="figure"]');
|
|
90
|
+
expect(figure).not.toBeNull();
|
|
91
|
+
expect(figure!.textContent).toContain("28");
|
|
92
|
+
expect(within(first).getByText("Age")).toBeDefined();
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it("a field with no value spends no row at all", () => {
|
|
96
|
+
const { container } = renderCards({
|
|
97
|
+
data: [{ id: 1, firstName: "John", lastName: "", age: 28 }],
|
|
98
|
+
});
|
|
99
|
+
const first = cards(container)[0];
|
|
100
|
+
expect(first.querySelector('[data-card-slot="meta"]')).toBeNull();
|
|
101
|
+
expect(first.textContent).not.toContain("Last Name");
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it("a control keeps a row of its own and prints no label", () => {
|
|
105
|
+
// Explicit id on BOTH columns: DataTable seeds columnOrder from
|
|
106
|
+
// `col.id || ""`, so an id-less accessor column beside an id'd one would
|
|
107
|
+
// put `_actions` first and make the control the card title instead.
|
|
108
|
+
const { container } = renderCards({
|
|
109
|
+
columns: [
|
|
110
|
+
{ id: "firstName", accessorKey: "firstName", header: "First Name" },
|
|
111
|
+
{ id: "_actions", accessorKey: "lastName", header: "Actions", meta: { role: "actions" } },
|
|
112
|
+
],
|
|
113
|
+
});
|
|
114
|
+
const first = cards(container)[0];
|
|
115
|
+
expect(first.querySelector('[data-card-slot="control"]')).not.toBeNull();
|
|
116
|
+
expect(within(first).queryByText("Actions")).toBeNull();
|
|
117
|
+
expect(first.textContent).toContain("Actions:");
|
|
118
|
+
});
|
|
119
|
+
|
|
72
120
|
it("selection adds a select-all bar above the stack and a checkbox per card", () => {
|
|
73
121
|
const { container } = renderCards({ enableRowSelection: true });
|
|
74
122
|
expect(screen.getByLabelText("Select all rows")).toBeTruthy();
|
|
@@ -130,6 +130,31 @@ describe("DataTable header sorting (web grid)", () => {
|
|
|
130
130
|
await waitFor(() => expect(header().getAttribute("aria-sort")).toBe("none"));
|
|
131
131
|
});
|
|
132
132
|
|
|
133
|
+
it("gives Phosphor resolved CSS colors in every sort state", async () => {
|
|
134
|
+
const { header } = renderTable();
|
|
135
|
+
for (const direction of ["none", "ascending", "descending"]) {
|
|
136
|
+
await waitFor(() => expect(header().getAttribute("aria-sort")).toBe(direction));
|
|
137
|
+
const icon = header().querySelector("svg");
|
|
138
|
+
expect(icon).not.toBeNull();
|
|
139
|
+
const ink = icon?.getAttribute("fill") || icon?.getAttribute("color") || icon?.style.color;
|
|
140
|
+
expect(ink).toBeTruthy();
|
|
141
|
+
expect(ink).not.toMatch(/\$/);
|
|
142
|
+
fireEvent.click(header());
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it("plain click replaces another column sort and Shift+click adds to it", async () => {
|
|
147
|
+
const { header, container, states } = renderTable();
|
|
148
|
+
const ageHeader = container.querySelector("#age-header") as HTMLElement;
|
|
149
|
+
fireEvent.click(header());
|
|
150
|
+
fireEvent.click(ageHeader);
|
|
151
|
+
await waitFor(() => expect(states.at(-1)?.sorting.map((sort) => sort.id)).toEqual(["age"]));
|
|
152
|
+
fireEvent.click(header(), { shiftKey: true });
|
|
153
|
+
await waitFor(() =>
|
|
154
|
+
expect(states.at(-1)?.sorting.map((sort) => sort.id)).toEqual(["age", "firstName"]),
|
|
155
|
+
);
|
|
156
|
+
});
|
|
157
|
+
|
|
133
158
|
it("non-sortable headers get no press affordance, no tab stop, and no aria-sort", () => {
|
|
134
159
|
const { container } = renderWithProviders(
|
|
135
160
|
<DataTable
|
|
@@ -17,12 +17,12 @@ import { FlashList, type FlashListRef } from "@shopify/flash-list";
|
|
|
17
17
|
import { AsyncBoundary, EmptyState, useDirection } from "@multiplatform.one/components";
|
|
18
18
|
import { Button, Field, useFormField } from "@multiplatform.one/forms";
|
|
19
19
|
import { flexRender } from "@tanstack/react-table";
|
|
20
|
-
import {
|
|
20
|
+
import { useResolvedKnobs } from "@multiplatform.one/theme";
|
|
21
21
|
import React, { useRef, useMemo, useCallback } from "react";
|
|
22
22
|
import { ScrollView, Text, View, useMedia, withStaticProperties } from "tamagui";
|
|
23
23
|
import { useTranslation } from "react-i18next";
|
|
24
24
|
import { useDataTable } from "../../hooks/useDataTable";
|
|
25
|
-
import type { DataTableColumn, DataTableField } from "../../types";
|
|
25
|
+
import type { DataTableColumn, DataTableField, SelectAllScope } from "../../types";
|
|
26
26
|
import { DEFAULT_PAGE_SIZE_OPTIONS } from "../../utils/paginationDefaults";
|
|
27
27
|
import { withInterp } from "../../utils/withInterp";
|
|
28
28
|
import { DataTableColumnPinning } from "../DataTableColumnPinning";
|
|
@@ -38,6 +38,7 @@ import { DataTableCell } from "../DataTableCell";
|
|
|
38
38
|
import { Table } from "@multiplatform.one/table-primitives";
|
|
39
39
|
import { DataTableContext } from "./DataTableContext";
|
|
40
40
|
import { DataTableDocumentList } from "./DataTableDocumentList";
|
|
41
|
+
import { DataTableMobileCards } from "./DataTableMobileCards";
|
|
41
42
|
import { dataTableChrome, resolveDataTableIntent, rowIntentProps } from "./dataTableChrome";
|
|
42
43
|
import { tableRowStateProps } from "./rowStateChrome";
|
|
43
44
|
import { DataTableStateContext } from "./DataTableStateContext";
|
|
@@ -134,6 +135,8 @@ function DataTableRoot<TData extends Record<string, any> = Record<string, any>>(
|
|
|
134
135
|
virtualizationOverscan = 5,
|
|
135
136
|
enableRowExpansion = false,
|
|
136
137
|
renderSubComponent,
|
|
138
|
+
enableRowSelection = false,
|
|
139
|
+
selectAllScope: selectAllScopeProp,
|
|
137
140
|
enableColumnPinning = false,
|
|
138
141
|
maxPinnedColumns = 3,
|
|
139
142
|
enableKeyboardNavigation: _enableKeyboardNavigation = false,
|
|
@@ -181,6 +184,9 @@ function DataTableRoot<TData extends Record<string, any> = Record<string, any>>(
|
|
|
181
184
|
compact,
|
|
182
185
|
});
|
|
183
186
|
const chrome = dataTableChrome(String(knobProps.sizeToken));
|
|
187
|
+
// House selectAllScope knob (DG-TBL-03): prop overrides knob; default page.
|
|
188
|
+
const selectAllScope: SelectAllScope =
|
|
189
|
+
selectAllScopeProp ?? (knobProps.selectAllScope === "filtered" ? "filtered" : "page");
|
|
184
190
|
const rowHeightPx = chrome.rowPx;
|
|
185
191
|
// Collapsed expand-caret points toward inline-end, so it mirrors in RTL via
|
|
186
192
|
// glyph swap (useDirection, Axiom 15); rotation sign flips so expanded
|
|
@@ -216,6 +222,7 @@ function DataTableRoot<TData extends Record<string, any> = Record<string, any>>(
|
|
|
216
222
|
virtualizationOverscan,
|
|
217
223
|
enableRowExpansion,
|
|
218
224
|
renderSubComponent,
|
|
225
|
+
enableRowSelection,
|
|
219
226
|
enableColumnPinning,
|
|
220
227
|
maxPinnedColumns,
|
|
221
228
|
enableKeyboardNavigation: false,
|
|
@@ -225,6 +232,25 @@ function DataTableRoot<TData extends Record<string, any> = Record<string, any>>(
|
|
|
225
232
|
isFetching: isFetchingProp,
|
|
226
233
|
});
|
|
227
234
|
|
|
235
|
+
const selectAllChecked =
|
|
236
|
+
enableRowSelection &&
|
|
237
|
+
(selectAllScope === "filtered"
|
|
238
|
+
? table.getIsAllRowsSelected()
|
|
239
|
+
: table.getIsAllPageRowsSelected());
|
|
240
|
+
const selectAllIndeterminate =
|
|
241
|
+
enableRowSelection &&
|
|
242
|
+
(selectAllScope === "filtered"
|
|
243
|
+
? table.getIsSomeRowsSelected() && !table.getIsAllRowsSelected()
|
|
244
|
+
: table.getIsSomePageRowsSelected() && !table.getIsAllPageRowsSelected());
|
|
245
|
+
|
|
246
|
+
const toggleSelectAll = useCallback(() => {
|
|
247
|
+
if (selectAllScope === "filtered") {
|
|
248
|
+
table.toggleAllRowsSelected();
|
|
249
|
+
} else {
|
|
250
|
+
table.toggleAllPageRowsSelected();
|
|
251
|
+
}
|
|
252
|
+
}, [selectAllScope, table]);
|
|
253
|
+
|
|
228
254
|
const resolvedSize: "sm" | "md" | "lg" =
|
|
229
255
|
size ?? (knobProps.sizeToken === "$3" ? "sm" : knobProps.sizeToken === "$5" ? "lg" : "md");
|
|
230
256
|
|
|
@@ -493,8 +519,8 @@ function DataTableRoot<TData extends Record<string, any> = Record<string, any>>(
|
|
|
493
519
|
// (see utils/rowPress.ts). Roving tabindex is a web-only concern.
|
|
494
520
|
const rowPressActive = Boolean(onRowPress) && !disabled;
|
|
495
521
|
|
|
496
|
-
const
|
|
497
|
-
(row: (typeof tableRows)[0]
|
|
522
|
+
const deriveRowIdentity = useCallback(
|
|
523
|
+
(row: (typeof tableRows)[0]): string | undefined => {
|
|
498
524
|
const fromAccessor = rowLabel?.(row.original as TData);
|
|
499
525
|
if (fromAccessor) return fromAccessor;
|
|
500
526
|
let firstCellValue: unknown;
|
|
@@ -509,13 +535,33 @@ function DataTableRoot<TData extends Record<string, any> = Record<string, any>>(
|
|
|
509
535
|
) {
|
|
510
536
|
return String(firstCellValue);
|
|
511
537
|
}
|
|
512
|
-
return
|
|
538
|
+
return undefined;
|
|
513
539
|
},
|
|
514
|
-
[rowLabel
|
|
540
|
+
[rowLabel],
|
|
541
|
+
);
|
|
542
|
+
|
|
543
|
+
const deriveRowLabel = useCallback(
|
|
544
|
+
(row: (typeof tableRows)[0], index: number): string =>
|
|
545
|
+
deriveRowIdentity(row) ??
|
|
546
|
+
withInterp(t("Row {{row}}", { row: index + 1 }), { row: index + 1 }),
|
|
547
|
+
[deriveRowIdentity, t],
|
|
548
|
+
);
|
|
549
|
+
|
|
550
|
+
// Selection-toggle name: row identity beats a bare index ("Select row
|
|
551
|
+
// Bulbasaur", falling back to "Select row 3"), the same source the grid
|
|
552
|
+
// and the card list both read.
|
|
553
|
+
const deriveSelectRowLabel = useCallback(
|
|
554
|
+
(row: (typeof tableRows)[0], index: number): string => {
|
|
555
|
+
const identity = deriveRowIdentity(row) ?? String(index + 1);
|
|
556
|
+
return withInterp(t("Select row {{row}}", { row: identity }), { row: identity });
|
|
557
|
+
},
|
|
558
|
+
[deriveRowIdentity, t],
|
|
515
559
|
);
|
|
516
560
|
|
|
517
561
|
const getRowPressProps = useCallback(
|
|
518
|
-
|
|
562
|
+
// The card list asks for the "card" variant. Native carries no DOM row
|
|
563
|
+
// role for it to override, so both variants land on role="button".
|
|
564
|
+
(row: (typeof tableRows)[0], index: number, _variant: "row" | "card" = "row") => {
|
|
519
565
|
if (!rowPressActive) return {};
|
|
520
566
|
return {
|
|
521
567
|
onPress: () => onRowPress?.(row.original as TData, index),
|
|
@@ -551,101 +597,6 @@ function DataTableRoot<TData extends Record<string, any> = Record<string, any>>(
|
|
|
551
597
|
[renderRowContent, tableZebraOn, t, getRowPressProps],
|
|
552
598
|
);
|
|
553
599
|
|
|
554
|
-
const renderMobileCard = useCallback(
|
|
555
|
-
(row: (typeof tableRows)[0], index: number, onDelete?: (idx: number) => void) => {
|
|
556
|
-
const rowData = row.original as TData;
|
|
557
|
-
const visibleCells = row.getVisibleCells();
|
|
558
|
-
return (
|
|
559
|
-
<View
|
|
560
|
-
key={`${row.id}-${index}`}
|
|
561
|
-
backgroundColor="$color1"
|
|
562
|
-
borderRadius="$4"
|
|
563
|
-
borderWidth={1}
|
|
564
|
-
borderColor="$borderColor"
|
|
565
|
-
padding="$3"
|
|
566
|
-
marginBottom="$2"
|
|
567
|
-
{...(getRowPressProps(row, index) as any)}
|
|
568
|
-
{...(rowIntentProps(rowData) as any)}
|
|
569
|
-
>
|
|
570
|
-
{showRowNumbers && (
|
|
571
|
-
<View
|
|
572
|
-
flexDirection="row"
|
|
573
|
-
justifyContent="space-between"
|
|
574
|
-
paddingBottom="$2"
|
|
575
|
-
{...hairline.bottom}
|
|
576
|
-
borderBottomColor="$borderColor"
|
|
577
|
-
marginBottom="$2"
|
|
578
|
-
>
|
|
579
|
-
<Text fontSize="$3" color="$color10" fontWeight="600">
|
|
580
|
-
#{index + 1}
|
|
581
|
-
</Text>
|
|
582
|
-
{showDeleteRow && !readOnly && (
|
|
583
|
-
<Button
|
|
584
|
-
chromeless
|
|
585
|
-
circular
|
|
586
|
-
size="$2"
|
|
587
|
-
icon={TrashIcon}
|
|
588
|
-
disabled={disabled || tableRows.length <= minRows}
|
|
589
|
-
onPress={() => onDelete?.(index)}
|
|
590
|
-
aria-label={withInterp(t("Delete row {{row}}", { row: index + 1 }), {
|
|
591
|
-
row: index + 1,
|
|
592
|
-
})}
|
|
593
|
-
/>
|
|
594
|
-
)}
|
|
595
|
-
</View>
|
|
596
|
-
)}
|
|
597
|
-
{visibleCells.map((cell: any) => {
|
|
598
|
-
const columnDef = cell.column.columnDef as DataTableColumn;
|
|
599
|
-
const headerLabel =
|
|
600
|
-
typeof columnDef.header === "string"
|
|
601
|
-
? columnDef.header
|
|
602
|
-
: columnDef.id || cell.column.id;
|
|
603
|
-
return (
|
|
604
|
-
<View
|
|
605
|
-
key={cell.id}
|
|
606
|
-
flexDirection="row"
|
|
607
|
-
alignItems="center"
|
|
608
|
-
paddingVertical="$1.5"
|
|
609
|
-
gap="$2"
|
|
610
|
-
>
|
|
611
|
-
<Text fontSize="$3" color="$color10" fontWeight="500" width="40%" flexShrink={0}>
|
|
612
|
-
{headerLabel}
|
|
613
|
-
</Text>
|
|
614
|
-
<View flex={1}>{renderCellContent(cell, index, rowData)}</View>
|
|
615
|
-
</View>
|
|
616
|
-
);
|
|
617
|
-
})}
|
|
618
|
-
{!showRowNumbers && showDeleteRow && !readOnly && (
|
|
619
|
-
<View paddingTop="$2" alignItems="flex-end">
|
|
620
|
-
<Button
|
|
621
|
-
chromeless
|
|
622
|
-
circular
|
|
623
|
-
size="$2"
|
|
624
|
-
icon={TrashIcon}
|
|
625
|
-
disabled={disabled || tableRows.length <= minRows}
|
|
626
|
-
onPress={() => onDelete?.(index)}
|
|
627
|
-
aria-label={withInterp(t("Delete row {{row}}", { row: index + 1 }), {
|
|
628
|
-
row: index + 1,
|
|
629
|
-
})}
|
|
630
|
-
/>
|
|
631
|
-
</View>
|
|
632
|
-
)}
|
|
633
|
-
</View>
|
|
634
|
-
);
|
|
635
|
-
},
|
|
636
|
-
[
|
|
637
|
-
showRowNumbers,
|
|
638
|
-
showDeleteRow,
|
|
639
|
-
readOnly,
|
|
640
|
-
disabled,
|
|
641
|
-
tableRows.length,
|
|
642
|
-
minRows,
|
|
643
|
-
renderCellContent,
|
|
644
|
-
t,
|
|
645
|
-
getRowPressProps,
|
|
646
|
-
],
|
|
647
|
-
);
|
|
648
|
-
|
|
649
600
|
const renderToolbarComponent = () => {
|
|
650
601
|
if (renderToolbar) {
|
|
651
602
|
return renderToolbar({
|
|
@@ -777,36 +728,37 @@ function DataTableRoot<TData extends Record<string, any> = Record<string, any>>(
|
|
|
777
728
|
{showList ? (
|
|
778
729
|
<DataTableDocumentList
|
|
779
730
|
tableRows={displayRows}
|
|
731
|
+
enableRowSelection={enableRowSelection}
|
|
780
732
|
disabled={disabled}
|
|
781
733
|
hasActiveFilters={computed.hasActiveFilters}
|
|
782
734
|
renderCellContent={renderCellContent}
|
|
783
735
|
compact={isCompact}
|
|
736
|
+
selectRowLabel={deriveSelectRowLabel}
|
|
784
737
|
queryInFlight={queryInFlight}
|
|
785
738
|
{...(rowPressActive ? { getRowPressProps } : {})}
|
|
786
739
|
/>
|
|
787
740
|
) : showCards ? (
|
|
788
741
|
<View flexDirection="column" gap="$2">
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
)}
|
|
742
|
+
<DataTableMobileCards
|
|
743
|
+
tableRows={displayRows}
|
|
744
|
+
enableRowSelection={enableRowSelection}
|
|
745
|
+
showRowNumbers={showRowNumbers}
|
|
746
|
+
showDeleteRow={showDeleteRow}
|
|
747
|
+
readOnly={readOnly}
|
|
748
|
+
disabled={disabled}
|
|
749
|
+
dataLength={tableData.length}
|
|
750
|
+
minRows={minRows}
|
|
751
|
+
hasActiveFilters={computed.hasActiveFilters}
|
|
752
|
+
renderCellContent={renderCellContent}
|
|
753
|
+
onDeleteRow={isFormMode ? effectiveHandleDeleteRow : handleDeleteRow}
|
|
754
|
+
selectAllChecked={selectAllChecked}
|
|
755
|
+
selectAllIndeterminate={selectAllIndeterminate}
|
|
756
|
+
onToggleSelectAll={toggleSelectAll}
|
|
757
|
+
compact={isCompact}
|
|
758
|
+
selectRowLabel={deriveSelectRowLabel}
|
|
759
|
+
queryInFlight={queryInFlight}
|
|
760
|
+
{...(rowPressActive ? { getRowPressProps } : {})}
|
|
761
|
+
/>
|
|
810
762
|
{enablePagination && (
|
|
811
763
|
<View width="100%" {...(disabled ? disabledState.chromeKnobProps : {})}>
|
|
812
764
|
{renderPaginationComponent()}
|
|
@@ -1099,7 +1051,6 @@ function DataTableRoot<TData extends Record<string, any> = Record<string, any>>(
|
|
|
1099
1051
|
virtualizationHeight,
|
|
1100
1052
|
virtualizationOverscan,
|
|
1101
1053
|
renderRow,
|
|
1102
|
-
renderMobileCard,
|
|
1103
1054
|
renderSubComponent,
|
|
1104
1055
|
footerGroups,
|
|
1105
1056
|
sm,
|
|
@@ -1118,6 +1069,11 @@ function DataTableRoot<TData extends Record<string, any> = Record<string, any>>(
|
|
|
1118
1069
|
renderCellContent,
|
|
1119
1070
|
rowPressActive,
|
|
1120
1071
|
getRowPressProps,
|
|
1072
|
+
enableRowSelection,
|
|
1073
|
+
selectAllChecked,
|
|
1074
|
+
selectAllIndeterminate,
|
|
1075
|
+
toggleSelectAll,
|
|
1076
|
+
deriveSelectRowLabel,
|
|
1121
1077
|
displayRows,
|
|
1122
1078
|
queryInFlight,
|
|
1123
1079
|
t,
|