@multiplatform.one/table 7.7.6 → 7.8.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/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/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/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/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/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/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.stories.tsx +186 -14
- package/src/components/DataTable/DataTableCardControls.tsx +11 -13
- package/src/components/DataTable/DataTableRoot.tsx +40 -14
- package/src/components/DataTable/DataTableStateContext.ts +7 -0
- package/src/components/DataTable/columnWidthLayout.spec.tsx +195 -0
- package/src/components/DataTable/headerSorting.spec.tsx +25 -0
- package/src/components/DataTable/moneyColumn.spec.tsx +151 -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/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/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
|
@@ -6,21 +6,30 @@
|
|
|
6
6
|
import { FunnelIcon } from "@phosphor-icons/react";
|
|
7
7
|
import { Button } from "@multiplatform.one/forms";
|
|
8
8
|
import {
|
|
9
|
+
ensureCompositeFocusRing,
|
|
9
10
|
MIN_PRESS_TARGET,
|
|
10
11
|
pressTargetHitSlop,
|
|
11
12
|
pressTargetStyle,
|
|
13
|
+
useAccentOnSurface,
|
|
12
14
|
useResolvedKnobs,
|
|
15
|
+
useGlyphColor,
|
|
13
16
|
} from "@multiplatform.one/theme";
|
|
14
|
-
import { useState } from "react";
|
|
17
|
+
import { useId, useRef, useState } from "react";
|
|
15
18
|
import { Tooltip } from "@multiplatform.one/components";
|
|
16
|
-
import { Popover, Text, View, XStack, YStack } from "tamagui";
|
|
19
|
+
import { Popover, Text, View, XStack, YStack, isWeb, type TamaguiElement } from "tamagui";
|
|
17
20
|
import { t } from "../../shared/t";
|
|
18
|
-
import type { FilterOperator } from "../../types";
|
|
21
|
+
import type { DataTableColumnType, FilterOperator } from "../../types";
|
|
19
22
|
import { iconSizeForToken } from "../../utils/chromeIcons";
|
|
20
|
-
import { operatorNeedsNoValue } from "../../utils/filterFields";
|
|
23
|
+
import { defaultOperatorForFilterType, operatorNeedsNoValue } from "../../utils/filterFields";
|
|
21
24
|
import { FilterOperatorValueEditor } from "../FilterOperatorValueEditor";
|
|
22
25
|
|
|
23
|
-
|
|
26
|
+
/**
|
|
27
|
+
* The funnel's column type IS the table's column type — one vocabulary, not a
|
|
28
|
+
* second copy (LC-16). Kept as a named alias because consumers import it.
|
|
29
|
+
* Adding `"money"` to DataTableColumnType therefore reaches the funnel too
|
|
30
|
+
* (MPO-252).
|
|
31
|
+
*/
|
|
32
|
+
export type ColumnFilterType = DataTableColumnType;
|
|
24
33
|
|
|
25
34
|
export interface ColumnHeaderFilterProps {
|
|
26
35
|
columnId: string;
|
|
@@ -49,17 +58,38 @@ export function ColumnHeaderFilter({
|
|
|
49
58
|
columnId: _columnId,
|
|
50
59
|
columnLabel,
|
|
51
60
|
columnType,
|
|
52
|
-
filterValue
|
|
61
|
+
filterValue,
|
|
53
62
|
onFilterChange,
|
|
54
63
|
options,
|
|
55
64
|
isFiltered,
|
|
56
65
|
}: ColumnHeaderFilterProps) {
|
|
57
66
|
const { knobProps } = useResolvedKnobs();
|
|
67
|
+
const idleColor = useGlyphColor("$color11");
|
|
68
|
+
const activeColor = useAccentOnSurface();
|
|
69
|
+
const glyphColor = isFiltered ? activeColor : idleColor;
|
|
70
|
+
// The nested Tooltip has its own Popper context. Keep this trigger and
|
|
71
|
+
// editor anchored to the same instance rather than its nearest overlay.
|
|
72
|
+
const popoverScope = useId();
|
|
73
|
+
const triggerRef = useRef<TamaguiElement | null>(null);
|
|
74
|
+
const returnFocusRef = useRef(true);
|
|
75
|
+
ensureCompositeFocusRing();
|
|
58
76
|
const iconPx = iconSizeForToken(String(knobProps.sizeToken));
|
|
59
77
|
const [open, setOpen] = useState(false);
|
|
60
|
-
const [operator, setOperator] = useState<FilterOperator>(
|
|
78
|
+
const [operator, setOperator] = useState<FilterOperator>(() =>
|
|
79
|
+
defaultOperatorForFilterType(columnType),
|
|
80
|
+
);
|
|
61
81
|
const [value, setValue] = useState<string>("");
|
|
62
82
|
|
|
83
|
+
const handleOpenChange = (next: boolean) => {
|
|
84
|
+
// Reopening reads the applied filter. External updates while editing
|
|
85
|
+
// leave the current draft alone, including the stay-open Clear flow.
|
|
86
|
+
if (next && !open) {
|
|
87
|
+
setOperator(filterValue?.operator ?? defaultOperatorForFilterType(columnType));
|
|
88
|
+
setValue(filterValue?.value == null ? "" : String(filterValue.value));
|
|
89
|
+
}
|
|
90
|
+
setOpen(next);
|
|
91
|
+
};
|
|
92
|
+
|
|
63
93
|
// Apply is the explicit done affordance of this draft editor — commit-and-
|
|
64
94
|
// close is its stated intent (LC-21 allows an explicit done/close control).
|
|
65
95
|
const handleApply = () => {
|
|
@@ -76,58 +106,85 @@ export function ColumnHeaderFilter({
|
|
|
76
106
|
// filter; outside click / Escape / Apply close.
|
|
77
107
|
const handleClear = () => {
|
|
78
108
|
setValue("");
|
|
79
|
-
setOperator(
|
|
109
|
+
setOperator(defaultOperatorForFilterType(columnType));
|
|
80
110
|
onFilterChange(undefined);
|
|
81
111
|
};
|
|
82
112
|
|
|
83
113
|
return (
|
|
84
|
-
<Popover open={open} onOpenChange={
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
114
|
+
<Popover scope={popoverScope} open={open} onOpenChange={handleOpenChange} disableFocus>
|
|
115
|
+
{/* Inherit the nearest Popover before entering Tooltip. An explicit
|
|
116
|
+
scope makes Tamagui register web anchors only on mouse hover,
|
|
117
|
+
leaving keyboard opens without a reference. */}
|
|
118
|
+
<Popover.Anchor>
|
|
119
|
+
<Tooltip content={isFiltered ? t("Edit filter") : t("Filter this column")}>
|
|
120
|
+
<Popover.Trigger scope={popoverScope} asChild>
|
|
121
|
+
{/* LC-54 amendment (2026-08-13): the grown press target NEVER
|
|
88
122
|
paints — hover/press fills on this box spread across the full
|
|
89
123
|
44px floor and bled into the neighboring header rows via the
|
|
90
|
-
negative outsets.
|
|
91
|
-
|
|
124
|
+
negative outsets. Painted hover and keyboard focus feedback
|
|
125
|
+
ride the glyph-scale ring inside
|
|
92
126
|
(Chip dismiss anatomy). */}
|
|
93
|
-
<View
|
|
94
|
-
cursor="pointer"
|
|
95
|
-
{...pressTargetStyle()}
|
|
96
|
-
alignItems="center"
|
|
97
|
-
justifyContent="center"
|
|
98
|
-
marginVertical={-FILTER_TRIGGER_OUTSET}
|
|
99
|
-
marginHorizontal={-FILTER_TRIGGER_OUTSET}
|
|
100
|
-
hitSlop={pressTargetHitSlop(FILTER_TRIGGER_VISUAL)}
|
|
101
|
-
// Axiom 6 HONEST STATE: an applied filter is an active signal —
|
|
102
|
-
// it keeps full strength; only the idle affordance rests dimmed.
|
|
103
|
-
opacity={isFiltered ? 1 : 0.7}
|
|
104
|
-
hoverStyle={{ opacity: 1 }}
|
|
105
|
-
pressStyle={{ opacity: 0.9 }}
|
|
106
|
-
onPress={(e) => {
|
|
107
|
-
e.stopPropagation();
|
|
108
|
-
setOpen(true);
|
|
109
|
-
}}
|
|
110
|
-
role="button"
|
|
111
|
-
aria-label={`Filter column ${columnLabel}`}
|
|
112
|
-
>
|
|
113
127
|
<View
|
|
114
|
-
|
|
115
|
-
|
|
128
|
+
ref={triggerRef}
|
|
129
|
+
cursor="pointer"
|
|
130
|
+
{...pressTargetStyle()}
|
|
116
131
|
alignItems="center"
|
|
117
132
|
justifyContent="center"
|
|
118
|
-
|
|
133
|
+
marginVertical={-FILTER_TRIGGER_OUTSET}
|
|
134
|
+
marginHorizontal={-FILTER_TRIGGER_OUTSET}
|
|
135
|
+
hitSlop={pressTargetHitSlop(FILTER_TRIGGER_VISUAL)}
|
|
136
|
+
// Enabled glyphs keep readable ink; hue and weight distinguish
|
|
137
|
+
// an applied filter from the secondary-color idle affordance.
|
|
138
|
+
// Shared unpainted press-floor / painted glyph-ring anatomy.
|
|
139
|
+
className="mp-chip-dismiss"
|
|
140
|
+
tabIndex={0}
|
|
141
|
+
onKeyDown={
|
|
142
|
+
((event: { key?: string; preventDefault(): void; stopPropagation(): void }) => {
|
|
143
|
+
if (event.key !== "Enter" && event.key !== " ") return;
|
|
144
|
+
event.preventDefault();
|
|
145
|
+
event.stopPropagation();
|
|
146
|
+
handleOpenChange(true);
|
|
147
|
+
}) as unknown as () => void
|
|
148
|
+
}
|
|
149
|
+
onPress={(e) => {
|
|
150
|
+
e.stopPropagation();
|
|
151
|
+
handleOpenChange(true);
|
|
152
|
+
}}
|
|
153
|
+
role="button"
|
|
154
|
+
aria-label={`Filter column ${columnLabel}`}
|
|
119
155
|
>
|
|
120
|
-
<
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
156
|
+
<View
|
|
157
|
+
className="mp-chip-dismiss-ring"
|
|
158
|
+
padding="$1"
|
|
159
|
+
borderRadius="$2"
|
|
160
|
+
alignItems="center"
|
|
161
|
+
justifyContent="center"
|
|
162
|
+
hoverStyle={{ backgroundColor: "$color4" }}
|
|
163
|
+
pressStyle={{ backgroundColor: "$color5" }}
|
|
164
|
+
>
|
|
165
|
+
<FunnelIcon
|
|
166
|
+
size={iconPx}
|
|
167
|
+
color={glyphColor}
|
|
168
|
+
weight={isFiltered ? "fill" : "regular"}
|
|
169
|
+
/>
|
|
170
|
+
</View>
|
|
125
171
|
</View>
|
|
126
|
-
</
|
|
127
|
-
</
|
|
128
|
-
</
|
|
172
|
+
</Popover.Trigger>
|
|
173
|
+
</Tooltip>
|
|
174
|
+
</Popover.Anchor>
|
|
129
175
|
|
|
130
176
|
<Popover.Content
|
|
177
|
+
scope={popoverScope}
|
|
178
|
+
onPointerDownOutside={() => {
|
|
179
|
+
returnFocusRef.current = false;
|
|
180
|
+
}}
|
|
181
|
+
onCloseAutoFocus={(event) => {
|
|
182
|
+
event.preventDefault();
|
|
183
|
+
if (isWeb && returnFocusRef.current) {
|
|
184
|
+
(triggerRef.current as HTMLElement | null)?.focus();
|
|
185
|
+
}
|
|
186
|
+
returnFocusRef.current = true;
|
|
187
|
+
}}
|
|
131
188
|
{...knobProps.elevatedSurface}
|
|
132
189
|
{...knobProps.panelPadding}
|
|
133
190
|
minWidth={240}
|
|
@@ -135,7 +192,7 @@ export function ColumnHeaderFilter({
|
|
|
135
192
|
enterStyle={{ y: -5, opacity: 0 }}
|
|
136
193
|
exitStyle={{ y: -5, opacity: 0 }}
|
|
137
194
|
>
|
|
138
|
-
<Popover.Arrow borderColor="$borderColor" backgroundColor="$color1" />
|
|
195
|
+
<Popover.Arrow scope={popoverScope} borderColor="$borderColor" backgroundColor="$color1" />
|
|
139
196
|
|
|
140
197
|
<YStack {...knobProps.gap}>
|
|
141
198
|
<Text {...knobProps.label} fontWeight="400" color="$color11">
|
|
@@ -155,7 +212,7 @@ export function ColumnHeaderFilter({
|
|
|
155
212
|
{/* Actions */}
|
|
156
213
|
<XStack {...knobProps.gap} justifyContent="flex-end">
|
|
157
214
|
{isFiltered && (
|
|
158
|
-
<Button size={knobProps.sizeToken}
|
|
215
|
+
<Button size={knobProps.sizeToken} onPress={handleClear}>
|
|
159
216
|
{t("Clear")}
|
|
160
217
|
</Button>
|
|
161
218
|
)}
|
|
@@ -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
|
}
|
|
@@ -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
|
}
|