@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
|
@@ -16,8 +16,11 @@ import {
|
|
|
16
16
|
DataTableFilters,
|
|
17
17
|
DataTablePagination,
|
|
18
18
|
DataTableToolbar,
|
|
19
|
+
formatMoney,
|
|
20
|
+
type RowAccumulator,
|
|
21
|
+
sumMoneyByCurrency,
|
|
19
22
|
} from "../../index";
|
|
20
|
-
import { DataTable } from "./index";
|
|
23
|
+
import { DataTable, useDataTableState } from "./index";
|
|
21
24
|
|
|
22
25
|
const meta: Meta<typeof DataTable> = {
|
|
23
26
|
title: "Table/DataTable",
|
|
@@ -204,11 +207,7 @@ const columns: DataTableColumn<User>[] = [
|
|
|
204
207
|
columnHelper.display({
|
|
205
208
|
id: "actions",
|
|
206
209
|
header: "Actions",
|
|
207
|
-
cell: (_info) =>
|
|
208
|
-
<Button size="$2" variant="outlined">
|
|
209
|
-
Edit
|
|
210
|
-
</Button>
|
|
211
|
-
),
|
|
210
|
+
cell: (_info) => <Button size="$2">Edit</Button>,
|
|
212
211
|
enableSorting: false,
|
|
213
212
|
enableColumnFilter: false,
|
|
214
213
|
}) as DataTableColumn<User>,
|
|
@@ -321,14 +320,7 @@ const AdvancedTableStory = () => {
|
|
|
321
320
|
enableGlobalSearch={true}
|
|
322
321
|
enableViews={true}
|
|
323
322
|
renderToolbar={(props) => (
|
|
324
|
-
<DataTableToolbar
|
|
325
|
-
{...props}
|
|
326
|
-
customActions={
|
|
327
|
-
<Button size="$3" variant="outlined">
|
|
328
|
-
Export CSV
|
|
329
|
-
</Button>
|
|
330
|
-
}
|
|
331
|
-
/>
|
|
323
|
+
<DataTableToolbar {...props} customActions={<Button size="$3">Export CSV</Button>} />
|
|
332
324
|
)}
|
|
333
325
|
renderFilters={(props) => (
|
|
334
326
|
<DataTableFilters {...props} availableColumns={columnsWithCounts} maxFilters={5} />
|
|
@@ -3090,3 +3082,183 @@ export const CustomCellAlignment: Story = {
|
|
|
3090
3082
|
},
|
|
3091
3083
|
},
|
|
3092
3084
|
};
|
|
3085
|
+
|
|
3086
|
+
// ---------------------------------------------------------------------------
|
|
3087
|
+
// Running balance (MPO-250) — a column that is a function of every row before
|
|
3088
|
+
// it. The fold runs BEFORE pagination, so page two continues instead of
|
|
3089
|
+
// restarting at zero, and its final value paints a footer total.
|
|
3090
|
+
// ---------------------------------------------------------------------------
|
|
3091
|
+
|
|
3092
|
+
interface Posting extends DataTableData {
|
|
3093
|
+
id: string;
|
|
3094
|
+
date: string;
|
|
3095
|
+
payee: string;
|
|
3096
|
+
/** Cents. Integers here; a real ledger uses the "money" column type. */
|
|
3097
|
+
amount: number;
|
|
3098
|
+
/** Derived by the accumulator — declared so a column can name it. */
|
|
3099
|
+
running?: number;
|
|
3100
|
+
}
|
|
3101
|
+
|
|
3102
|
+
const registerPostings: Posting[] = [
|
|
3103
|
+
{ id: "P-01", date: "2026-01-02", payee: "Opening deposit", amount: 250_000 },
|
|
3104
|
+
{ id: "P-02", date: "2026-01-04", payee: "Rent", amount: -180_000 },
|
|
3105
|
+
{ id: "P-03", date: "2026-01-05", payee: "Grocers", amount: -8_450 },
|
|
3106
|
+
{ id: "P-04", date: "2026-01-07", payee: "Payroll", amount: 412_300 },
|
|
3107
|
+
{ id: "P-05", date: "2026-01-09", payee: "Utilities", amount: -14_600 },
|
|
3108
|
+
{ id: "P-06", date: "2026-01-11", payee: "Coffee roaster", amount: -1_875 },
|
|
3109
|
+
{ id: "P-07", date: "2026-01-14", payee: "Refund", amount: 3_200 },
|
|
3110
|
+
{ id: "P-08", date: "2026-01-16", payee: "Insurance", amount: -62_000 },
|
|
3111
|
+
{ id: "P-09", date: "2026-01-19", payee: "Consulting", amount: 150_000 },
|
|
3112
|
+
{ id: "P-10", date: "2026-01-21", payee: "Hardware", amount: -47_990 },
|
|
3113
|
+
{ id: "P-11", date: "2026-01-24", payee: "Payroll", amount: 412_300 },
|
|
3114
|
+
{ id: "P-12", date: "2026-01-27", payee: "Taxes", amount: -305_000 },
|
|
3115
|
+
];
|
|
3116
|
+
|
|
3117
|
+
const cents = (value: number | undefined) =>
|
|
3118
|
+
value == null ? "" : formatCurrency(value / 100, { symbol: "$", fractionDigits: "auto" });
|
|
3119
|
+
|
|
3120
|
+
/**
|
|
3121
|
+
* The fold. A module constant, not an inline literal — the table refolds
|
|
3122
|
+
* whenever this identity changes.
|
|
3123
|
+
*/
|
|
3124
|
+
const registerBalance: RowAccumulator<Posting, number> = {
|
|
3125
|
+
initial: 0,
|
|
3126
|
+
reduce: (carried, row) => carried + row.amount,
|
|
3127
|
+
derive: (carried) => ({ running: carried }),
|
|
3128
|
+
order: (a, b) => (a.date < b.date ? -1 : a.date > b.date ? 1 : 0),
|
|
3129
|
+
total: (carried) => carried,
|
|
3130
|
+
};
|
|
3131
|
+
|
|
3132
|
+
/** Reads the fold's end value off the table state — the total row. */
|
|
3133
|
+
const RegisterTotal = () => {
|
|
3134
|
+
const context = useDataTableState();
|
|
3135
|
+
return <Text fontWeight="700">{cents(context?.computed.foldTotal as number | undefined)}</Text>;
|
|
3136
|
+
};
|
|
3137
|
+
|
|
3138
|
+
const registerColumns: DataTableColumn<Posting>[] = [
|
|
3139
|
+
{ id: "date", accessorKey: "date", header: "Date", width: 120 },
|
|
3140
|
+
{ id: "payee", accessorKey: "payee", header: "Payee", sortable: true },
|
|
3141
|
+
{
|
|
3142
|
+
id: "amount",
|
|
3143
|
+
accessorKey: "amount",
|
|
3144
|
+
header: "Amount",
|
|
3145
|
+
align: "right",
|
|
3146
|
+
cell: (info) => <Text>{cents(info.getValue() as number)}</Text>,
|
|
3147
|
+
footer: () => <Text fontWeight="700">Total</Text>,
|
|
3148
|
+
},
|
|
3149
|
+
{
|
|
3150
|
+
id: "running",
|
|
3151
|
+
accessorKey: "running",
|
|
3152
|
+
header: "Balance",
|
|
3153
|
+
align: "right",
|
|
3154
|
+
// Not sortable on purpose: sorting a fold column reorders it WITHOUT
|
|
3155
|
+
// refolding, so the figures stop reading down the column as a
|
|
3156
|
+
// progression. The contract is on RowAccumulator.
|
|
3157
|
+
sortable: false,
|
|
3158
|
+
cell: (info) => <Text fontWeight="600">{cents(info.getValue() as number)}</Text>,
|
|
3159
|
+
footer: () => <RegisterTotal />,
|
|
3160
|
+
},
|
|
3161
|
+
];
|
|
3162
|
+
|
|
3163
|
+
export const RunningBalance: Story = {
|
|
3164
|
+
render: () => (
|
|
3165
|
+
<DataTable
|
|
3166
|
+
data={registerPostings}
|
|
3167
|
+
columns={registerColumns as DataTableColumn<Record<string, any>>[]}
|
|
3168
|
+
rowAccumulator={registerBalance as RowAccumulator<Record<string, any>>}
|
|
3169
|
+
layout="table"
|
|
3170
|
+
columnLayout="auto"
|
|
3171
|
+
enableFiltering={false}
|
|
3172
|
+
enableGlobalSearch={false}
|
|
3173
|
+
initialState={{ pagination: { pageIndex: 0, pageSize: 5 } }}
|
|
3174
|
+
aria-label="Account register with a running balance"
|
|
3175
|
+
/>
|
|
3176
|
+
),
|
|
3177
|
+
parameters: {
|
|
3178
|
+
docs: {
|
|
3179
|
+
description: {
|
|
3180
|
+
story:
|
|
3181
|
+
"A running balance is a FOLD over the rows in a total order, so it has to be computed before the table paginates. Page through this table: the Balance column continues onto page two rather than restarting, because `rowAccumulator` runs once over the whole row set before the row model. Its `total` is read once at the end and painted in the footer through `useDataTableState().computed.foldTotal`. Sorting on Payee reorders rows for display and does NOT refold — the balance stays attached to its own row.",
|
|
3182
|
+
},
|
|
3183
|
+
},
|
|
3184
|
+
},
|
|
3185
|
+
};
|
|
3186
|
+
|
|
3187
|
+
// ---------------------------------------------------------------------------
|
|
3188
|
+
// Money column (MPO-252) — a Currency field is a decimal STRING. It sorts
|
|
3189
|
+
// numerically, filters with the numeric operators, formats from the ROW's own
|
|
3190
|
+
// currency, and totals per currency because two currencies never convert.
|
|
3191
|
+
// ---------------------------------------------------------------------------
|
|
3192
|
+
|
|
3193
|
+
interface Charge extends DataTableData {
|
|
3194
|
+
id: string;
|
|
3195
|
+
vendor: string;
|
|
3196
|
+
amount: string;
|
|
3197
|
+
currency: string;
|
|
3198
|
+
}
|
|
3199
|
+
|
|
3200
|
+
const charges: Charge[] = [
|
|
3201
|
+
{ id: "C-1", vendor: "Coffee roaster", amount: "9.00", currency: "USD" },
|
|
3202
|
+
{ id: "C-2", vendor: "Bookshop", amount: "10.00", currency: "USD" },
|
|
3203
|
+
{ id: "C-3", vendor: "Chai stall", amount: "250.75", currency: "INR" },
|
|
3204
|
+
{ id: "C-4", vendor: "Refund", amount: "-455.87", currency: "USD" },
|
|
3205
|
+
{ id: "C-5", vendor: "Hosting", amount: "1200.00", currency: "INR" },
|
|
3206
|
+
{ id: "C-6", vendor: "Domain", amount: "9.99", currency: "USD" },
|
|
3207
|
+
];
|
|
3208
|
+
|
|
3209
|
+
/** One figure per currency — the mixed-currency rule, rendered. */
|
|
3210
|
+
const ChargeTotals = () => {
|
|
3211
|
+
const totals = sumMoneyByCurrency(
|
|
3212
|
+
charges,
|
|
3213
|
+
(row) => row.amount,
|
|
3214
|
+
(row) => row.currency,
|
|
3215
|
+
);
|
|
3216
|
+
return (
|
|
3217
|
+
<YStack>
|
|
3218
|
+
{Object.entries(totals).map(([code, total]) => (
|
|
3219
|
+
<Text key={code} fontWeight="700">
|
|
3220
|
+
{formatMoney(total, code)}
|
|
3221
|
+
</Text>
|
|
3222
|
+
))}
|
|
3223
|
+
</YStack>
|
|
3224
|
+
);
|
|
3225
|
+
};
|
|
3226
|
+
|
|
3227
|
+
const chargeColumns: DataTableColumn<Charge>[] = [
|
|
3228
|
+
{ id: "vendor", accessorKey: "vendor", header: "Vendor" },
|
|
3229
|
+
{ id: "currency", accessorKey: "currency", header: "Currency" },
|
|
3230
|
+
{
|
|
3231
|
+
id: "amount",
|
|
3232
|
+
accessorKey: "amount",
|
|
3233
|
+
header: "Amount",
|
|
3234
|
+
field: "money",
|
|
3235
|
+
// Safe now: the money type carries an exact decimal comparator, so
|
|
3236
|
+
// "9.00" sorts BELOW "10.00". As a "text" column this was silently wrong.
|
|
3237
|
+
sortable: true,
|
|
3238
|
+
filterable: true,
|
|
3239
|
+
fieldProps: { currencyField: "currency" },
|
|
3240
|
+
footer: () => <ChargeTotals />,
|
|
3241
|
+
},
|
|
3242
|
+
];
|
|
3243
|
+
|
|
3244
|
+
export const MoneyColumn: Story = {
|
|
3245
|
+
render: () => (
|
|
3246
|
+
<DataTable
|
|
3247
|
+
data={charges}
|
|
3248
|
+
columns={chargeColumns as DataTableColumn<Record<string, any>>[]}
|
|
3249
|
+
layout="table"
|
|
3250
|
+
columnLayout="auto"
|
|
3251
|
+
enablePagination={false}
|
|
3252
|
+
readOnly
|
|
3253
|
+
aria-label="Charges with a money column"
|
|
3254
|
+
/>
|
|
3255
|
+
),
|
|
3256
|
+
parameters: {
|
|
3257
|
+
docs: {
|
|
3258
|
+
description: {
|
|
3259
|
+
story:
|
|
3260
|
+
'`field: "money"` types a column as a decimal STRING rather than as text. Sort on Amount: `9.00` orders below `10.00`, which the text fallback got backwards in silence. The column filter offers `is less than` / `is greater than` / `between` instead of `contains`. Each row formats in its OWN currency (`fieldProps.currencyField`), and the footer totals PER currency — two currencies are two figures and neither converts, because there is no rate in the table.',
|
|
3261
|
+
},
|
|
3262
|
+
},
|
|
3263
|
+
},
|
|
3264
|
+
};
|
|
@@ -89,7 +89,6 @@ export function DataTableCardControls({
|
|
|
89
89
|
<DropdownMenu.Trigger asChild>
|
|
90
90
|
<Button
|
|
91
91
|
size={knobProps.sizeToken}
|
|
92
|
-
variant="outlined"
|
|
93
92
|
icon={<CaretUpDownIcon size={chrome.iconPx} />}
|
|
94
93
|
aria-label={t("Sort rows")}
|
|
95
94
|
disabled={disabled}
|
|
@@ -134,18 +133,17 @@ export function DataTableCardControls({
|
|
|
134
133
|
</DropdownMenu.Content>
|
|
135
134
|
</DropdownMenu>
|
|
136
135
|
)}
|
|
137
|
-
{enableFiltering &&
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
{...
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
)}
|
|
136
|
+
{enableFiltering && availableColumns.length > 0 && (
|
|
137
|
+
// DataTableFilters (chrome) has no disabled API — the wrapper is the
|
|
138
|
+
// LC-40 carrier and interaction gate for the disabled table.
|
|
139
|
+
<View
|
|
140
|
+
{...(disabled
|
|
141
|
+
? { ...disabledState.chromeKnobProps, pointerEvents: "none" as const }
|
|
142
|
+
: {})}
|
|
143
|
+
>
|
|
144
|
+
<DataTableFilters compact availableColumns={availableColumns} />
|
|
145
|
+
</View>
|
|
146
|
+
)}
|
|
149
147
|
</XStack>
|
|
150
148
|
);
|
|
151
149
|
}
|
|
@@ -5,14 +5,18 @@
|
|
|
5
5
|
* resolved layout is "cards" (below the `$sm` breakpoint with
|
|
6
6
|
* layout="auto", or forced via layout="cards").
|
|
7
7
|
*
|
|
8
|
-
* Card anatomy
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
8
|
+
* Card anatomy: the first visible column is the card title in the header
|
|
9
|
+
* row (with selection checkbox / row number / delete). The remaining
|
|
10
|
+
* visible columns are NOT a stack of label/value rows any more — see
|
|
11
|
+
* `classifyCardField`. Column visibility and order from table state apply
|
|
12
|
+
* unchanged — cells come from `row.getVisibleCells()`. Values render
|
|
13
|
+
* through the same cell renderers as the grid, inside `TableCellContext`
|
|
14
|
+
* so fields stay chromeless (useIsInTableCell).
|
|
15
|
+
*
|
|
16
|
+
* The card is FLAT: no border, no elevation. A card list is drawn inside
|
|
17
|
+
* a panel that already has its own frame, and an outlined, shadowed card
|
|
18
|
+
* inside it reads as a box inside a box. The `cardSurface` fill and the
|
|
19
|
+
* gap between cards are what separate one row from the next.
|
|
16
20
|
*/
|
|
17
21
|
|
|
18
22
|
import { TrashIcon } from "@phosphor-icons/react";
|
|
@@ -21,10 +25,10 @@ import { Button, Checkbox } from "@multiplatform.one/forms";
|
|
|
21
25
|
import { hairline, useResolvedKnobs } from "@multiplatform.one/theme";
|
|
22
26
|
import type React from "react";
|
|
23
27
|
import { useCallback } from "react";
|
|
24
|
-
import { Text, View, XStack } from "tamagui";
|
|
28
|
+
import { Text, View, VisuallyHidden, XStack } from "tamagui";
|
|
25
29
|
import { useTranslation } from "react-i18next";
|
|
26
30
|
import { TableCellContext } from "@multiplatform.one/table-primitives";
|
|
27
|
-
import type { DataTableColumn } from "../../types";
|
|
31
|
+
import type { DataTableColumn, DataTableField } from "../../types";
|
|
28
32
|
import { withInterp } from "../../utils/withInterp";
|
|
29
33
|
import { rowIntentProps } from "./dataTableChrome";
|
|
30
34
|
|
|
@@ -34,13 +38,74 @@ import { rowIntentProps } from "./dataTableChrome";
|
|
|
34
38
|
* header is a render function or a bare glyph (the liked heart) — without
|
|
35
39
|
* it a card field row would print the raw column id (`_liked_by`).
|
|
36
40
|
*/
|
|
37
|
-
function getColumnLabel(cell: any): string {
|
|
41
|
+
export function getColumnLabel(cell: any): string {
|
|
38
42
|
const columnDef = cell.column.columnDef as DataTableColumn;
|
|
39
43
|
const metaLabel = columnDef.meta?.label;
|
|
40
44
|
if (typeof metaLabel === "string" && metaLabel) return metaLabel;
|
|
41
45
|
return typeof columnDef.header === "string" ? columnDef.header : columnDef.id || cell.column.id;
|
|
42
46
|
}
|
|
43
47
|
|
|
48
|
+
/** Fields that draw their own control, which names itself and needs a target. */
|
|
49
|
+
const selfNamingFields = new Set<DataTableField>([
|
|
50
|
+
"checkbox",
|
|
51
|
+
"switch",
|
|
52
|
+
"rating",
|
|
53
|
+
"progress",
|
|
54
|
+
"image",
|
|
55
|
+
"signature",
|
|
56
|
+
"fileupload",
|
|
57
|
+
"colorpicker",
|
|
58
|
+
"barcode",
|
|
59
|
+
"geolocation",
|
|
60
|
+
]);
|
|
61
|
+
|
|
62
|
+
/** Column ids whose value is a state badge. A badge names itself. */
|
|
63
|
+
const indicatorIds = new Set(["status", "priority", "workflow_state", "state"]);
|
|
64
|
+
|
|
65
|
+
const dateLike = /^\d{4}-\d{2}-\d{2}([T ]|$)|^\d{1,2}\/\d{1,2}\/\d{2,4}$/;
|
|
66
|
+
const numberLike = /^[+\-−]?[\d,\s]*\d(\.\d+)?%?$/;
|
|
67
|
+
|
|
68
|
+
export type CardFieldKind = "skip" | "control" | "bare" | "figure";
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Whether a card field prints the column's name, and where it goes.
|
|
72
|
+
*
|
|
73
|
+
* A card is not the grid with its header repeated down the page. In the
|
|
74
|
+
* grid the header is written ONCE for a whole column of values; on a card
|
|
75
|
+
* it is written once per value, so a 12-column table prints 12 labels per
|
|
76
|
+
* record. That is what a label costs here, and most labels do not earn it.
|
|
77
|
+
*
|
|
78
|
+
* skip the raw value is absent. A field with nothing in it is not a
|
|
79
|
+
* fact — "Rejected —" spends a row saying nothing.
|
|
80
|
+
* control a button, a switch, a rating. The control names itself and
|
|
81
|
+
* needs its own tap target, so it keeps a row and takes no label.
|
|
82
|
+
* bare a string that is neither a number nor a date. "DIVIDEND
|
|
83
|
+
* CREDIT" and "Income:Dividends" say what they are; "Payee" and
|
|
84
|
+
* "Account" in front of them are the header printed twice. The
|
|
85
|
+
* name is kept for assistive tech via VisuallyHidden, which
|
|
86
|
+
* costs no layout.
|
|
87
|
+
* figure a number, a date, a boolean. "1,204" alone cannot be read, so
|
|
88
|
+
* these DO keep their label — inline beside the figure, not in a
|
|
89
|
+
* 40%-wide column of its own.
|
|
90
|
+
*/
|
|
91
|
+
export function classifyCardField(cell: any): CardFieldKind {
|
|
92
|
+
const def = cell.column.columnDef as DataTableColumn;
|
|
93
|
+
const id = String(cell.column.id ?? "");
|
|
94
|
+
const role = def.meta?.role;
|
|
95
|
+
if (role === "hidden" || role === "skip") return "skip";
|
|
96
|
+
if (role === "actions" || id.startsWith("_") || (def.field && selfNamingFields.has(def.field))) {
|
|
97
|
+
return "control";
|
|
98
|
+
}
|
|
99
|
+
const raw = typeof cell.getValue === "function" ? cell.getValue() : undefined;
|
|
100
|
+
if (raw == null || (typeof raw === "string" && raw.trim() === "")) return "skip";
|
|
101
|
+
if (role === "indicator" || indicatorIds.has(id)) return "bare";
|
|
102
|
+
if (typeof raw === "string") {
|
|
103
|
+
const value = raw.trim();
|
|
104
|
+
return numberLike.test(value) || dateLike.test(value) ? "figure" : "bare";
|
|
105
|
+
}
|
|
106
|
+
return "figure";
|
|
107
|
+
}
|
|
108
|
+
|
|
44
109
|
export interface DataTableMobileCardsProps<TData> {
|
|
45
110
|
tableRows: any[];
|
|
46
111
|
enableRowSelection?: boolean;
|
|
@@ -98,6 +163,15 @@ export function DataTableMobileCards<TData extends Record<string, any>>({
|
|
|
98
163
|
const { knobProps } = useResolvedKnobs({ component: "DataTable", compact });
|
|
99
164
|
const tableZebraOn = knobProps.tableZebra === "on";
|
|
100
165
|
|
|
166
|
+
const renderCell = useCallback(
|
|
167
|
+
(cell: any, index: number, rowData: TData) => (
|
|
168
|
+
<TableCellContext.Provider value={{ inTableCell: true, isHeader: false }}>
|
|
169
|
+
{renderCellContent(cell, index, rowData)}
|
|
170
|
+
</TableCellContext.Provider>
|
|
171
|
+
),
|
|
172
|
+
[renderCellContent],
|
|
173
|
+
);
|
|
174
|
+
|
|
101
175
|
const renderMobileCard = useCallback(
|
|
102
176
|
(row: any, index: number) => {
|
|
103
177
|
const rowData = row.original as TData;
|
|
@@ -105,14 +179,22 @@ export function DataTableMobileCards<TData extends Record<string, any>>({
|
|
|
105
179
|
const [titleCell, ...detailCells] = visibleCells;
|
|
106
180
|
const showDelete = showDeleteRow && !readOnly;
|
|
107
181
|
|
|
182
|
+
const bare: any[] = [];
|
|
183
|
+
const figures: any[] = [];
|
|
184
|
+
const controls: any[] = [];
|
|
185
|
+
for (const cell of detailCells) {
|
|
186
|
+
const kind = classifyCardField(cell);
|
|
187
|
+
if (kind === "bare") bare.push(cell);
|
|
188
|
+
else if (kind === "figure") figures.push(cell);
|
|
189
|
+
else if (kind === "control") controls.push(cell);
|
|
190
|
+
}
|
|
191
|
+
const hasBody = bare.length > 0 || figures.length > 0 || controls.length > 0;
|
|
192
|
+
|
|
108
193
|
return (
|
|
109
194
|
<View
|
|
110
195
|
key={`${row.id}-${index}`}
|
|
111
196
|
testID="data-table-card"
|
|
112
|
-
{...knobProps.surface}
|
|
113
197
|
{...knobProps.cardSurface}
|
|
114
|
-
elevation={knobProps.elevation}
|
|
115
|
-
borderColor="$color6"
|
|
116
198
|
{...(tableZebraOn && index % 2 === 1 ? { backgroundColor: "$color2" } : {})}
|
|
117
199
|
{...({
|
|
118
200
|
"data-table-zebra": tableZebraOn ? (index % 2 === 0 ? "even" : "odd") : "off",
|
|
@@ -124,7 +206,7 @@ export function DataTableMobileCards<TData extends Record<string, any>>({
|
|
|
124
206
|
<XStack
|
|
125
207
|
alignItems="center"
|
|
126
208
|
gap="$2"
|
|
127
|
-
{...(
|
|
209
|
+
{...(hasBody
|
|
128
210
|
? {
|
|
129
211
|
paddingBottom: "$2",
|
|
130
212
|
marginBottom: "$2",
|
|
@@ -156,11 +238,10 @@ export function DataTableMobileCards<TData extends Record<string, any>>({
|
|
|
156
238
|
flex={1}
|
|
157
239
|
minWidth={0}
|
|
158
240
|
aria-label={getColumnLabel(titleCell)}
|
|
241
|
+
accessibilityLabel={getColumnLabel(titleCell)}
|
|
159
242
|
{...({ "data-card-slot": "title" } as any)}
|
|
160
243
|
>
|
|
161
|
-
|
|
162
|
-
{renderCellContent(titleCell, index, rowData)}
|
|
163
|
-
</TableCellContext.Provider>
|
|
244
|
+
{renderCell(titleCell, index, rowData)}
|
|
164
245
|
</View>
|
|
165
246
|
) : (
|
|
166
247
|
<View flex={1} />
|
|
@@ -185,29 +266,71 @@ export function DataTableMobileCards<TData extends Record<string, any>>({
|
|
|
185
266
|
)}
|
|
186
267
|
</XStack>
|
|
187
268
|
|
|
188
|
-
{/*
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
269
|
+
{/* Self-naming values, wrapped into one flow. No printed labels:
|
|
270
|
+
the name goes to assistive tech only, at no layout cost. */}
|
|
271
|
+
{bare.length > 0 ? (
|
|
272
|
+
<XStack
|
|
273
|
+
flexWrap="wrap"
|
|
193
274
|
alignItems="center"
|
|
194
|
-
paddingVertical="$1.5"
|
|
195
275
|
gap="$2"
|
|
276
|
+
{...({ "data-card-slot": "meta" } as any)}
|
|
196
277
|
>
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
278
|
+
{bare.map((cell: any, i: number) => (
|
|
279
|
+
<XStack key={cell.id} alignItems="center" gap="$2" flexShrink={1} minWidth={0}>
|
|
280
|
+
<VisuallyHidden>{`${getColumnLabel(cell)}: `}</VisuallyHidden>
|
|
281
|
+
<View flexShrink={1} minWidth={0}>
|
|
282
|
+
{renderCell(cell, index, rowData)}
|
|
283
|
+
</View>
|
|
284
|
+
{/* The separator TRAILS its value, so a line that wraps
|
|
285
|
+
starts with content instead of a stray dot. */}
|
|
286
|
+
{i < bare.length - 1 ? (
|
|
287
|
+
<Text
|
|
288
|
+
fontSize={knobProps.sizeToken}
|
|
289
|
+
color="$color8"
|
|
290
|
+
aria-hidden
|
|
291
|
+
accessibilityElementsHidden
|
|
292
|
+
importantForAccessibility="no-hide-descendants"
|
|
293
|
+
>
|
|
294
|
+
·
|
|
295
|
+
</Text>
|
|
296
|
+
) : null}
|
|
297
|
+
</XStack>
|
|
298
|
+
))}
|
|
299
|
+
</XStack>
|
|
300
|
+
) : null}
|
|
301
|
+
|
|
302
|
+
{/* Figures keep their name, inline beside the value. */}
|
|
303
|
+
{figures.length > 0 ? (
|
|
304
|
+
<XStack
|
|
305
|
+
flexWrap="wrap"
|
|
306
|
+
alignItems="center"
|
|
307
|
+
gap="$3"
|
|
308
|
+
paddingTop={bare.length > 0 ? "$1.5" : 0}
|
|
309
|
+
{...({ "data-card-slot": "figure" } as any)}
|
|
310
|
+
>
|
|
311
|
+
{figures.map((cell: any) => (
|
|
312
|
+
<XStack key={cell.id} alignItems="center" gap="$1.5" flexShrink={1} minWidth={0}>
|
|
313
|
+
<Text fontSize={knobProps.sizeToken} color="$color10" fontWeight="500">
|
|
314
|
+
{getColumnLabel(cell)}
|
|
315
|
+
</Text>
|
|
316
|
+
<View flexShrink={1} minWidth={0}>
|
|
317
|
+
{renderCell(cell, index, rowData)}
|
|
318
|
+
</View>
|
|
319
|
+
</XStack>
|
|
320
|
+
))}
|
|
321
|
+
</XStack>
|
|
322
|
+
) : null}
|
|
323
|
+
|
|
324
|
+
{/* Controls keep a row of their own — they are tap targets. */}
|
|
325
|
+
{controls.map((cell: any) => (
|
|
326
|
+
<View
|
|
327
|
+
key={cell.id}
|
|
328
|
+
paddingTop="$2"
|
|
329
|
+
minWidth={0}
|
|
330
|
+
{...({ "data-card-slot": "control" } as any)}
|
|
331
|
+
>
|
|
332
|
+
<VisuallyHidden>{`${getColumnLabel(cell)}: `}</VisuallyHidden>
|
|
333
|
+
{renderCell(cell, index, rowData)}
|
|
211
334
|
</View>
|
|
212
335
|
))}
|
|
213
336
|
</View>
|
|
@@ -221,7 +344,7 @@ export function DataTableMobileCards<TData extends Record<string, any>>({
|
|
|
221
344
|
disabled,
|
|
222
345
|
dataLength,
|
|
223
346
|
minRows,
|
|
224
|
-
|
|
347
|
+
renderCell,
|
|
225
348
|
onDeleteRow,
|
|
226
349
|
compact,
|
|
227
350
|
knobProps,
|
|
@@ -62,6 +62,7 @@ import { DataTableDocumentList } from "./DataTableDocumentList";
|
|
|
62
62
|
import { DataTableVirtualized } from "./DataTableVirtualized";
|
|
63
63
|
import { dataTableChrome, resolveDataTableIntent, rowIntentProps } from "./dataTableChrome";
|
|
64
64
|
import { tableCellKeyboardProps, tableRowStateProps } from "./rowStateChrome";
|
|
65
|
+
import { warnColumnWidthIgnored } from "../../shared/devWarn";
|
|
65
66
|
import { alignToFlex, getDefaultColumnAlign } from "../../utils/columnAlign";
|
|
66
67
|
import { mapFieldToFilterType } from "../../utils/filterFields";
|
|
67
68
|
import { INFINITE_TRIGGER_ROWS } from "../../utils/paginationDefaults";
|
|
@@ -125,6 +126,7 @@ export function DataTableRoot<TData extends Record<string, any> = Record<string,
|
|
|
125
126
|
pageSizeOptions,
|
|
126
127
|
paginationMode = "pages",
|
|
127
128
|
loadPage,
|
|
129
|
+
rowAccumulator,
|
|
128
130
|
enableColumnVisibility = true,
|
|
129
131
|
enableColumnOrdering = false,
|
|
130
132
|
enableColumnResizing = false,
|
|
@@ -176,6 +178,7 @@ export function DataTableRoot<TData extends Record<string, any> = Record<string,
|
|
|
176
178
|
"aria-describedby": ariaDescribedBy,
|
|
177
179
|
...props
|
|
178
180
|
}: DataTableRootProps<TData>) {
|
|
181
|
+
warnColumnWidthIgnored({ columnLayout, enableColumnResizing, columns });
|
|
179
182
|
const { t } = useTranslation();
|
|
180
183
|
const { sm } = useMedia();
|
|
181
184
|
// Resolved responsive layout: cards below `$sm` (W11 compact class) unless
|
|
@@ -224,6 +227,7 @@ export function DataTableRoot<TData extends Record<string, any> = Record<string,
|
|
|
224
227
|
enablePagination,
|
|
225
228
|
paginationMode,
|
|
226
229
|
loadPage,
|
|
230
|
+
rowAccumulator,
|
|
227
231
|
enableColumnVisibility,
|
|
228
232
|
enableColumnOrdering,
|
|
229
233
|
enableColumnResizing,
|
|
@@ -1670,22 +1674,21 @@ export function DataTableRoot<TData extends Record<string, any> = Record<string,
|
|
|
1670
1674
|
{sortDirection === "asc" && (
|
|
1671
1675
|
<CaretDownIcon
|
|
1672
1676
|
size={chrome.iconPx}
|
|
1673
|
-
color=
|
|
1674
|
-
sortDirection ? "var(--color10)" : "var(--color8)"
|
|
1675
|
-
}
|
|
1677
|
+
color="var(--color11)"
|
|
1676
1678
|
/>
|
|
1677
1679
|
)}
|
|
1678
1680
|
{sortDirection === "desc" && (
|
|
1679
1681
|
<CaretDownIcon
|
|
1680
1682
|
size={chrome.iconPx}
|
|
1681
|
-
color=
|
|
1682
|
-
sortDirection ? "var(--color10)" : "var(--color8)"
|
|
1683
|
-
}
|
|
1683
|
+
color="var(--color11)"
|
|
1684
1684
|
style={{ transform: "rotate(180deg)" }}
|
|
1685
1685
|
/>
|
|
1686
1686
|
)}
|
|
1687
1687
|
{sortDirection === false && (
|
|
1688
|
-
<CaretUpDownIcon
|
|
1688
|
+
<CaretUpDownIcon
|
|
1689
|
+
size={chrome.iconPx}
|
|
1690
|
+
color="var(--color11)"
|
|
1691
|
+
/>
|
|
1689
1692
|
)}
|
|
1690
1693
|
</View>
|
|
1691
1694
|
</Tooltip>
|
|
@@ -2082,13 +2085,36 @@ export function DataTableRoot<TData extends Record<string, any> = Record<string,
|
|
|
2082
2085
|
<Table.Foot>
|
|
2083
2086
|
{footerGroups.map((footerGroup: any) => (
|
|
2084
2087
|
<Table.Row key={footerGroup.id}>
|
|
2085
|
-
{footerGroup.headers.map((header: any) =>
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2088
|
+
{footerGroup.headers.map((header: any) => {
|
|
2089
|
+
const columnAlign = resolveColumnAlign({
|
|
2090
|
+
...(header.column.columnDef as DataTableColumn),
|
|
2091
|
+
id: header.column.id,
|
|
2092
|
+
});
|
|
2093
|
+
return (
|
|
2094
|
+
<Table.Cell
|
|
2095
|
+
key={header.id}
|
|
2096
|
+
justifyContent={alignToFlex(columnAlign)}
|
|
2097
|
+
data-align={columnAlign}
|
|
2098
|
+
>
|
|
2099
|
+
{header.isPlaceholder ? null : (
|
|
2100
|
+
<View
|
|
2101
|
+
width="100%"
|
|
2102
|
+
minWidth={0}
|
|
2103
|
+
flexDirection="row"
|
|
2104
|
+
alignItems="center"
|
|
2105
|
+
justifyContent={alignToFlex(columnAlign)}
|
|
2106
|
+
data-cell-align={columnAlign}
|
|
2107
|
+
style={isWeb ? { textAlign: columnAlign } : undefined}
|
|
2108
|
+
>
|
|
2109
|
+
{flexRender(
|
|
2110
|
+
header.column.columnDef.footer,
|
|
2111
|
+
header.getContext(),
|
|
2112
|
+
)}
|
|
2113
|
+
</View>
|
|
2114
|
+
)}
|
|
2115
|
+
</Table.Cell>
|
|
2116
|
+
);
|
|
2117
|
+
})}
|
|
2092
2118
|
</Table.Row>
|
|
2093
2119
|
))}
|
|
2094
2120
|
</Table.Foot>
|
|
@@ -62,6 +62,13 @@ export interface DataTableStateContextValue<TData = any> {
|
|
|
62
62
|
totalRows: number;
|
|
63
63
|
hasActiveFilters: boolean;
|
|
64
64
|
activeFilterCount: number;
|
|
65
|
+
/**
|
|
66
|
+
* The row accumulator's `total(finalAccumulator, rowCount)` — the fold
|
|
67
|
+
* read once at the end (MPO-250). A column's TanStack `footer` renderer
|
|
68
|
+
* reads it from here to paint a total row; the table already renders a
|
|
69
|
+
* footer whenever any column defines one.
|
|
70
|
+
*/
|
|
71
|
+
foldTotal?: unknown;
|
|
65
72
|
[key: string]: any;
|
|
66
73
|
};
|
|
67
74
|
}
|