@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
|
@@ -171,6 +171,7 @@ export const createUrlStrategy = {
|
|
|
171
171
|
import React, { useMemo, useState, useCallback, useEffect, useRef } from "react";
|
|
172
172
|
import type {
|
|
173
173
|
DataTableData,
|
|
174
|
+
DataTableField,
|
|
174
175
|
DataTableInfiniteState,
|
|
175
176
|
DataTableState,
|
|
176
177
|
UseDataTableOptions,
|
|
@@ -183,6 +184,8 @@ import {
|
|
|
183
184
|
resolveFilterFields,
|
|
184
185
|
} from "../utils/filterFields";
|
|
185
186
|
import { applyFilterToValue } from "../utils/filterUtils";
|
|
187
|
+
import { accumulateRows } from "../utils/rowAccumulator";
|
|
188
|
+
import { moneyComparator } from "../utils/money";
|
|
186
189
|
import { DEFAULT_PAGE_SIZE } from "../utils/paginationDefaults";
|
|
187
190
|
import { deserializeTableState, serializeTableState } from "../utils/urlStateUtils";
|
|
188
191
|
import { useInfiniteRows } from "./useInfiniteRows";
|
|
@@ -190,6 +193,13 @@ import { useTableFiltering } from "./useTableFiltering";
|
|
|
190
193
|
import { useTableSorting } from "./useTableSorting";
|
|
191
194
|
import { useTableViews } from "./useTableViews";
|
|
192
195
|
|
|
196
|
+
/**
|
|
197
|
+
* TanStack sort for a `money` column: exact decimal-string ordering, so
|
|
198
|
+
* "9.00" sorts below "10.00" (MPO-252).
|
|
199
|
+
*/
|
|
200
|
+
const moneySortingFn = (rowA: any, rowB: any, columnId: string): number =>
|
|
201
|
+
moneyComparator(rowA.getValue(columnId), rowB.getValue(columnId));
|
|
202
|
+
|
|
193
203
|
export function useDataTable<TData extends DataTableData = DataTableData>({
|
|
194
204
|
data = [],
|
|
195
205
|
columns = [],
|
|
@@ -208,6 +218,7 @@ export function useDataTable<TData extends DataTableData = DataTableData>({
|
|
|
208
218
|
enablePagination: _enablePagination = true,
|
|
209
219
|
paginationMode = "pages",
|
|
210
220
|
loadPage,
|
|
221
|
+
rowAccumulator,
|
|
211
222
|
enableColumnVisibility = true,
|
|
212
223
|
enableColumnOrdering: _enableColumnOrdering = false,
|
|
213
224
|
enableColumnResizing = false,
|
|
@@ -360,6 +371,21 @@ export function useDataTable<TData extends DataTableData = DataTableData>({
|
|
|
360
371
|
// pre-filtered/sorted, so manual modes are forced on. In infinite mode the
|
|
361
372
|
// pagination row model is never applied (rows accumulate instead of slice).
|
|
362
373
|
const effectiveData = isLoaderMode ? infiniteRows.rows : data;
|
|
374
|
+
|
|
375
|
+
// ---- Row accumulator (MPO-250) ----
|
|
376
|
+
//
|
|
377
|
+
// The fold runs HERE — over the whole row set, before the advanced filters
|
|
378
|
+
// below and before TanStack's filter/sort/paginate models — because a
|
|
379
|
+
// derived column like a running balance depends on every row before it and
|
|
380
|
+
// would restart on page two otherwise. `order` (when given) is also the
|
|
381
|
+
// order the rows reach the table in: a fold order is the order its column
|
|
382
|
+
// reads down. Sorting on another column reorders for display and does NOT
|
|
383
|
+
// refold; see the contract on RowAccumulator.
|
|
384
|
+
const { rows: accumulatedData, total: foldTotal } = useMemo(
|
|
385
|
+
() => accumulateRows(effectiveData, rowAccumulator),
|
|
386
|
+
[effectiveData, rowAccumulator],
|
|
387
|
+
);
|
|
388
|
+
|
|
363
389
|
const effectiveManualFiltering = manualFiltering || isLoaderMode;
|
|
364
390
|
const effectiveManualSorting = manualSorting || isLoaderMode;
|
|
365
391
|
const effectiveManualPagination = manualPagination || infiniteEnabled;
|
|
@@ -375,9 +401,9 @@ export function useDataTable<TData extends DataTableData = DataTableData>({
|
|
|
375
401
|
// including hidden / non-column fields. Server-side tables (manualFiltering)
|
|
376
402
|
// map the same filters to query params instead.
|
|
377
403
|
const preFilteredData = useMemo(() => {
|
|
378
|
-
if (effectiveManualFiltering) return
|
|
379
|
-
return applyFiltersToData(
|
|
380
|
-
}, [
|
|
404
|
+
if (effectiveManualFiltering) return accumulatedData;
|
|
405
|
+
return applyFiltersToData(accumulatedData, filtering.advancedFilters, filterFields);
|
|
406
|
+
}, [accumulatedData, effectiveManualFiltering, filtering.advancedFilters, filterFields]);
|
|
381
407
|
|
|
382
408
|
// Column-funnel filters store FilterValue objects ({operator, value}) —
|
|
383
409
|
// interpret them with the shared operator semantics instead of TanStack's
|
|
@@ -455,13 +481,20 @@ export function useDataTable<TData extends DataTableData = DataTableData>({
|
|
|
455
481
|
const normalizedColumns = useMemo(
|
|
456
482
|
() =>
|
|
457
483
|
columns.map((column) => {
|
|
458
|
-
const { sortable, filterable } = column as {
|
|
484
|
+
const { sortable, filterable, field } = column as {
|
|
459
485
|
sortable?: boolean;
|
|
460
486
|
filterable?: boolean;
|
|
487
|
+
field?: DataTableField;
|
|
461
488
|
};
|
|
462
|
-
|
|
489
|
+
// A money column holds a decimal STRING, and TanStack's auto sort
|
|
490
|
+
// would compare it as text — "9.00" above "10.00", silently wrong on
|
|
491
|
+
// every amount column (MPO-252). Give it the exact comparator so
|
|
492
|
+
// `sortable: true` is safe to turn on. An explicit sortingFn wins.
|
|
493
|
+
const needsMoneySort = field === "money" && column.sortingFn === undefined;
|
|
494
|
+
if (sortable === undefined && filterable === undefined && !needsMoneySort) return column;
|
|
463
495
|
return {
|
|
464
496
|
...column,
|
|
497
|
+
...(needsMoneySort ? { sortingFn: moneySortingFn } : {}),
|
|
465
498
|
...(sortable !== undefined && column.enableSorting === undefined
|
|
466
499
|
? { enableSorting: sortable }
|
|
467
500
|
: {}),
|
|
@@ -596,9 +629,9 @@ export function useDataTable<TData extends DataTableData = DataTableData>({
|
|
|
596
629
|
// ---- Computed Values ----
|
|
597
630
|
|
|
598
631
|
const filteredData = useMemo(() => {
|
|
599
|
-
if (effectiveManualFiltering) return
|
|
632
|
+
if (effectiveManualFiltering) return accumulatedData;
|
|
600
633
|
return table.getFilteredRowModel().rows.map((row) => row.original);
|
|
601
|
-
}, [
|
|
634
|
+
}, [accumulatedData, table, effectiveManualFiltering]);
|
|
602
635
|
|
|
603
636
|
const paginatedData = useMemo(() => {
|
|
604
637
|
if (effectiveManualPagination) return filteredData;
|
|
@@ -708,6 +741,9 @@ export function useDataTable<TData extends DataTableData = DataTableData>({
|
|
|
708
741
|
activeFilterCount: filtering.activeFilterCount,
|
|
709
742
|
filterFields,
|
|
710
743
|
infinite,
|
|
744
|
+
// The fold read once at the end — a footer cell renders it through
|
|
745
|
+
// useDataTableState() (MPO-250).
|
|
746
|
+
foldTotal,
|
|
711
747
|
};
|
|
712
748
|
|
|
713
749
|
// ---- State Change Callback ----
|
package/src/index.ts
CHANGED
|
@@ -157,6 +157,19 @@ export {
|
|
|
157
157
|
resolveFilterFields,
|
|
158
158
|
} from "./utils/filterFields";
|
|
159
159
|
export * from "./utils/urlStateUtils";
|
|
160
|
+
export {
|
|
161
|
+
addMoney,
|
|
162
|
+
compareMoney,
|
|
163
|
+
formatMoney,
|
|
164
|
+
isMoneyString,
|
|
165
|
+
isNegativeMoney,
|
|
166
|
+
moneyComparator,
|
|
167
|
+
subtractMoney,
|
|
168
|
+
sumMoney,
|
|
169
|
+
sumMoneyByCurrency,
|
|
170
|
+
} from "./utils/money";
|
|
171
|
+
export { accumulateRows } from "./utils/rowAccumulator";
|
|
172
|
+
export type { RowAccumulator, RowAccumulatorResult } from "./utils/rowAccumulator";
|
|
160
173
|
export {
|
|
161
174
|
getDefaultColumnAlign,
|
|
162
175
|
alignToFlex,
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Table DEV guardrails — same shape as the `@multiplatform.one/theme` §5
|
|
3
|
+
* catalog (`devWarn` / `warnBareDisabled` / `warnSizeRecipeEscape`): a
|
|
4
|
+
* module-level seen set, a `NODE_ENV === "production"` no-op, and helpers
|
|
5
|
+
* called inline during render.
|
|
6
|
+
*
|
|
7
|
+
* The prefix is `[table]`, not `[theme]`: the codes here are table-local and
|
|
8
|
+
* the story-hygiene harvester (`p-results/story-hygiene/verify.mjs`) collects
|
|
9
|
+
* on the `[theme]` prefix.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { DataTableProps } from "../types";
|
|
13
|
+
|
|
14
|
+
export type TableDevWarnCode =
|
|
15
|
+
/**
|
|
16
|
+
* A column declares a width (`width` or TanStack `size`) that the resolved
|
|
17
|
+
* `columnLayout` discards before it reaches the cell box.
|
|
18
|
+
*/
|
|
19
|
+
"column-width-ignored";
|
|
20
|
+
|
|
21
|
+
export type TableDevWarnDetail = {
|
|
22
|
+
component?: string;
|
|
23
|
+
id?: string;
|
|
24
|
+
columns?: string;
|
|
25
|
+
columnLayout?: string;
|
|
26
|
+
suggest?: string;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const seen = new Set<string>();
|
|
30
|
+
|
|
31
|
+
function isDev(): boolean {
|
|
32
|
+
return process.env.NODE_ENV !== "production";
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Emit a once-per-key console warning in non-production builds. */
|
|
36
|
+
export function tableDevWarn(code: TableDevWarnCode, detail: TableDevWarnDetail = {}): void {
|
|
37
|
+
if (!isDev()) return;
|
|
38
|
+
const key = [code, detail.component ?? "", detail.id ?? "", detail.columns ?? ""].join(":");
|
|
39
|
+
if (seen.has(key)) return;
|
|
40
|
+
seen.add(key);
|
|
41
|
+
const bits = [
|
|
42
|
+
detail.component ? `component=${detail.component}` : undefined,
|
|
43
|
+
detail.id ? `id=${detail.id}` : undefined,
|
|
44
|
+
detail.columns ? `columns=${detail.columns}` : undefined,
|
|
45
|
+
detail.columnLayout ? `columnLayout=${detail.columnLayout}` : undefined,
|
|
46
|
+
detail.suggest ? `suggest=${detail.suggest}` : undefined,
|
|
47
|
+
].filter(Boolean);
|
|
48
|
+
const suffix = bits.length ? ` (${bits.join(", ")})` : "";
|
|
49
|
+
console.warn(`[table] ${code}${suffix}`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** @internal test helper */
|
|
53
|
+
export function __resetTableDevWarnSeen(): void {
|
|
54
|
+
seen.clear();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
type WidthBearingColumn = {
|
|
58
|
+
id?: unknown;
|
|
59
|
+
accessorKey?: unknown;
|
|
60
|
+
width?: unknown;
|
|
61
|
+
size?: unknown;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
function columnKey(column: WidthBearingColumn, index: number): string {
|
|
65
|
+
if (typeof column.id === "string" && column.id) return column.id;
|
|
66
|
+
if (typeof column.accessorKey === "string" && column.accessorKey) return column.accessorKey;
|
|
67
|
+
return `#${index}`;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* MPO-236 — `columnLayout: "equal"` (the default) flexes every column to the
|
|
72
|
+
* same width, so a per-column `width` / `size` never reaches the cell box and
|
|
73
|
+
* the render is byte-identical to one with no widths at all.
|
|
74
|
+
*
|
|
75
|
+
* `enableColumnResizing` is the exemption: it swaps the cell flex to
|
|
76
|
+
* `flexBasis: "auto"`, under which a declared width does survive.
|
|
77
|
+
*/
|
|
78
|
+
export function warnColumnWidthIgnored(args: {
|
|
79
|
+
columnLayout?: DataTableProps["columnLayout"];
|
|
80
|
+
enableColumnResizing?: boolean;
|
|
81
|
+
columns: readonly WidthBearingColumn[];
|
|
82
|
+
component?: string;
|
|
83
|
+
}): void {
|
|
84
|
+
if (!isDev()) return;
|
|
85
|
+
if (args.columnLayout !== "equal" || args.enableColumnResizing) return;
|
|
86
|
+
const offenders = args.columns
|
|
87
|
+
.map((column, index) => ({ column, index }))
|
|
88
|
+
.filter(({ column }) => typeof column.width === "number" || typeof column.size === "number")
|
|
89
|
+
.map(({ column, index }) => columnKey(column, index));
|
|
90
|
+
if (!offenders.length) return;
|
|
91
|
+
tableDevWarn("column-width-ignored", {
|
|
92
|
+
component: args.component ?? "DataTable",
|
|
93
|
+
columns: offenders.join(","),
|
|
94
|
+
columnLayout: "equal",
|
|
95
|
+
suggest: 'columnLayout="auto" or "scroll", or enableColumnResizing',
|
|
96
|
+
});
|
|
97
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ColumnDef, ColumnFiltersState, Row } from "@tanstack/react-table";
|
|
2
|
+
import type { RowAccumulator } from "./utils/rowAccumulator";
|
|
2
3
|
import type { UrlStateStrategy } from "./hooks/useDataTable";
|
|
3
4
|
import type { AnyFormApi } from "@multiplatform.one/forms";
|
|
4
5
|
import type React from "react";
|
|
@@ -50,6 +51,12 @@ export type DataTableField =
|
|
|
50
51
|
// Numeric inputs
|
|
51
52
|
| "stepper"
|
|
52
53
|
| "slider"
|
|
54
|
+
/**
|
|
55
|
+
* A Currency field: a decimal STRING, formatted for display and ordered
|
|
56
|
+
* numerically. Read-only presentation — money is edited through the form
|
|
57
|
+
* surfaces, not typed into a grid cell (MPO-252).
|
|
58
|
+
*/
|
|
59
|
+
| "money"
|
|
53
60
|
// Selection inputs
|
|
54
61
|
| "select"
|
|
55
62
|
| "combobox"
|
|
@@ -113,8 +120,17 @@ export interface DataTableFieldProps {
|
|
|
113
120
|
step?: number;
|
|
114
121
|
/** Precision for numeric fields */
|
|
115
122
|
precision?: number;
|
|
116
|
-
/** Currency code for currency fields */
|
|
123
|
+
/** Currency code for currency fields. A column-level constant. */
|
|
117
124
|
currency?: string;
|
|
125
|
+
/**
|
|
126
|
+
* Row-data key holding this row's currency code, for a `money` column
|
|
127
|
+
* (MPO-252). A ledger genuinely mixes currencies row by row, so the row's
|
|
128
|
+
* own code WINS over the column-level `currency` constant; `currency` is
|
|
129
|
+
* the fallback for the rows that carry none.
|
|
130
|
+
*/
|
|
131
|
+
currencyField?: string;
|
|
132
|
+
/** BCP-47 locale for money formatting. Defaults to the runtime's. */
|
|
133
|
+
locale?: string;
|
|
118
134
|
/** Doctype for link fields (Frappe) */
|
|
119
135
|
doctype?: string;
|
|
120
136
|
/** Default country for phone input (ISO 3166-1 alpha-2) */
|
|
@@ -164,6 +180,12 @@ export type DataTableColumn<TData extends DataTableData = DataTableData> = Colum
|
|
|
164
180
|
sortable?: boolean;
|
|
165
181
|
searchable?: boolean;
|
|
166
182
|
hidden?: boolean;
|
|
183
|
+
/**
|
|
184
|
+
* Column width intent, in px. Read by the view-options width slider and by
|
|
185
|
+
* saved views; the RENDERED cell box comes from TanStack `size`. Under the
|
|
186
|
+
* default `columnLayout: "equal"` neither one survives, and declaring
|
|
187
|
+
* either warns (see `columnLayout`).
|
|
188
|
+
*/
|
|
167
189
|
width?: number;
|
|
168
190
|
minWidth?: number;
|
|
169
191
|
maxWidth?: number;
|
|
@@ -423,9 +445,27 @@ export interface DataTableState {
|
|
|
423
445
|
|
|
424
446
|
// Component Props Types
|
|
425
447
|
|
|
448
|
+
export type { RowAccumulator, RowAccumulatorResult } from "./utils/rowAccumulator";
|
|
449
|
+
|
|
426
450
|
export interface DataTableProps<TData extends DataTableData = DataTableData> {
|
|
427
451
|
data: TData[];
|
|
428
452
|
columns: DataTableColumn<TData>[];
|
|
453
|
+
/**
|
|
454
|
+
* A fold over the ordered row set, run ONCE before filtering, sorting and
|
|
455
|
+
* pagination — the seam a running balance needs, because the value on row N
|
|
456
|
+
* depends on rows 1..N-1 and a column `cell` renderer only ever sees one
|
|
457
|
+
* row (MPO-250).
|
|
458
|
+
*
|
|
459
|
+
* The derived fields are merged onto each row, so a column names one in
|
|
460
|
+
* `accessorKey` like any other. Declare them on the row type. `total` is
|
|
461
|
+
* published as `computed.foldTotal` for a footer cell.
|
|
462
|
+
*
|
|
463
|
+
* Must be a STABLE reference (module constant or `useMemo`) — the fold
|
|
464
|
+
* re-runs when its identity changes. The full ordering contract, including
|
|
465
|
+
* what happens when the user sorts on another column, is documented on
|
|
466
|
+
* `RowAccumulator` in utils/rowAccumulator.ts.
|
|
467
|
+
*/
|
|
468
|
+
rowAccumulator?: RowAccumulator<TData>;
|
|
429
469
|
|
|
430
470
|
// State Management
|
|
431
471
|
initialState?: Partial<DataTableState>;
|
|
@@ -528,6 +568,14 @@ export interface DataTableProps<TData extends DataTableData = DataTableData> {
|
|
|
528
568
|
* - 'equal': All columns equal width, no horizontal scroll (default)
|
|
529
569
|
* - 'auto': Content-based width, last column fills remainder, squishes if needed
|
|
530
570
|
* - 'scroll': Content-based width, horizontal scroll when content exceeds container
|
|
571
|
+
*
|
|
572
|
+
* Under 'equal' a PER-COLUMN WIDTH IS IGNORED. Every cell gets
|
|
573
|
+
* `flexGrow: 1, flexBasis: 0`, so a column's `width` / `size` never reaches
|
|
574
|
+
* the cell box and the render is identical to one that declared no widths.
|
|
575
|
+
* Use 'auto' or 'scroll' when the widths must hold, or turn on
|
|
576
|
+
* `enableColumnResizing`, which switches the cells to `flexBasis: "auto"`.
|
|
577
|
+
* Declaring a width under 'equal' emits the `[table] column-width-ignored`
|
|
578
|
+
* dev warning rather than failing silently (MPO-236).
|
|
531
579
|
*/
|
|
532
580
|
columnLayout?: "equal" | "auto" | "scroll";
|
|
533
581
|
|
|
@@ -762,12 +810,33 @@ export interface UseDataTableReturn<TData extends DataTableData = DataTableData>
|
|
|
762
810
|
filterFields: ResolvedFilterField[];
|
|
763
811
|
/** Present when paginationMode="infinite" */
|
|
764
812
|
infinite?: DataTableInfiniteState;
|
|
813
|
+
/**
|
|
814
|
+
* `rowAccumulator.total(finalAccumulator, rowCount)` — the fold read once
|
|
815
|
+
* at the end, for a footer/total row. Undefined when the table has no
|
|
816
|
+
* accumulator or the accumulator declares no `total` (MPO-250).
|
|
817
|
+
*/
|
|
818
|
+
foldTotal?: unknown;
|
|
765
819
|
};
|
|
766
820
|
}
|
|
767
821
|
|
|
768
822
|
// Utility Types
|
|
769
823
|
|
|
770
|
-
|
|
824
|
+
/**
|
|
825
|
+
* Filter-editor / comparison type for a column.
|
|
826
|
+
*
|
|
827
|
+
* `"money"` (MPO-252) is a decimal STRING, not a number: a Frappe Currency
|
|
828
|
+
* field arrives as "-455.87" because a float would round it. It sorts and
|
|
829
|
+
* filters through the exact BigInt helpers in utils/money.ts, so `"9.00"`
|
|
830
|
+
* orders BELOW `"10.00"` — which the `"text"` fallback got backwards, in
|
|
831
|
+
* silence, on every amount column in the kit.
|
|
832
|
+
*
|
|
833
|
+
* The mixed-currency rule rides this type: TWO CURRENCIES ARE TWO FIGURES AND
|
|
834
|
+
* NEITHER CONVERTS. A money column formats from the row's own currency
|
|
835
|
+
* (`fieldProps.currencyField`), comparison is by magnitude only, and a total
|
|
836
|
+
* over mixed rows is `sumMoneyByCurrency` — one figure per code, never one
|
|
837
|
+
* number. There is no rate in the table and the kit will not invent one.
|
|
838
|
+
*/
|
|
839
|
+
export type DataTableColumnType = "text" | "number" | "money" | "date" | "boolean" | "select";
|
|
771
840
|
|
|
772
841
|
export interface DataTableColumnConfig {
|
|
773
842
|
type: DataTableColumnType;
|
package/src/utils/columnAlign.ts
CHANGED
|
@@ -17,7 +17,15 @@ export type ColumnAlignInput = {
|
|
|
17
17
|
meta?: { align?: ColumnAlign; role?: string };
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
-
const NUMERIC_FIELDS = new Set<DataTableField>([
|
|
20
|
+
const NUMERIC_FIELDS = new Set<DataTableField>([
|
|
21
|
+
"stepper",
|
|
22
|
+
"slider",
|
|
23
|
+
"progress",
|
|
24
|
+
"duration",
|
|
25
|
+
// A money column right-aligns on its own, without needing a column-level
|
|
26
|
+
// `currency` constant — a ledger reads its code off each row (MPO-252).
|
|
27
|
+
"money",
|
|
28
|
+
]);
|
|
21
29
|
|
|
22
30
|
/** Booleans + icon-like metrics (EUI: center symbols). */
|
|
23
31
|
const CENTER_FIELDS = new Set<DataTableField>(["checkbox", "switch", "rating"]);
|
|
@@ -41,6 +41,8 @@ export function mapFieldToFilterType(field?: DataTableField): DataTableColumnTyp
|
|
|
41
41
|
case "rating":
|
|
42
42
|
case "duration":
|
|
43
43
|
return "number";
|
|
44
|
+
case "money":
|
|
45
|
+
return "money";
|
|
44
46
|
case "datepicker":
|
|
45
47
|
case "datetimepicker":
|
|
46
48
|
case "timepicker":
|
|
@@ -117,7 +119,9 @@ export function getFilterFieldType(
|
|
|
117
119
|
// ── Client-side application ───────────────────────────────────
|
|
118
120
|
|
|
119
121
|
/** "select" fields compare as text; the others map 1:1. */
|
|
120
|
-
function comparisonType(
|
|
122
|
+
function comparisonType(
|
|
123
|
+
type: DataTableColumnType,
|
|
124
|
+
): "text" | "number" | "money" | "date" | "boolean" {
|
|
121
125
|
return type === "select" ? "text" : type;
|
|
122
126
|
}
|
|
123
127
|
|
|
@@ -167,6 +171,22 @@ const NUMBER_OPERATORS: FilterOperator[] = [
|
|
|
167
171
|
"isGreaterThanOrEqual",
|
|
168
172
|
];
|
|
169
173
|
|
|
174
|
+
/**
|
|
175
|
+
* Money takes the numeric operators PLUS the range pair — "every posting over
|
|
176
|
+
* 500" and "between 100 and 500" are the two questions asked of an amount
|
|
177
|
+
* column, and typing it "text" offered `contains` instead (MPO-252).
|
|
178
|
+
*/
|
|
179
|
+
const MONEY_OPERATORS: FilterOperator[] = [
|
|
180
|
+
"is",
|
|
181
|
+
"isNot",
|
|
182
|
+
"isLessThan",
|
|
183
|
+
"isGreaterThan",
|
|
184
|
+
"isLessThanOrEqual",
|
|
185
|
+
"isGreaterThanOrEqual",
|
|
186
|
+
"isBetween",
|
|
187
|
+
"isNotBetween",
|
|
188
|
+
];
|
|
189
|
+
|
|
170
190
|
const DATE_OPERATORS: FilterOperator[] = [
|
|
171
191
|
"is",
|
|
172
192
|
"isNot",
|
|
@@ -185,6 +205,8 @@ export function operatorsForFilterType(type: DataTableColumnType): FilterOperato
|
|
|
185
205
|
switch (type) {
|
|
186
206
|
case "number":
|
|
187
207
|
return NUMBER_OPERATORS;
|
|
208
|
+
case "money":
|
|
209
|
+
return MONEY_OPERATORS;
|
|
188
210
|
case "date":
|
|
189
211
|
return DATE_OPERATORS;
|
|
190
212
|
case "boolean":
|
package/src/utils/filterUtils.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { parseCalendarDate, type DateInput } from "@multiplatform.one/theme";
|
|
2
|
+
import { isMoneyString, moneyComparator } from "./money";
|
|
2
3
|
import { t } from "../shared/t";
|
|
3
4
|
import type { FilterValue, TableFilter } from "../types";
|
|
4
5
|
|
|
@@ -51,10 +52,28 @@ export function deserializeFilters(filterString: string): TableFilter[] {
|
|
|
51
52
|
|
|
52
53
|
// Filter Application Logic
|
|
53
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Order a money cell against a money comparand (MPO-252).
|
|
57
|
+
*
|
|
58
|
+
* Money is a decimal STRING, so `Number()` would round it and `<` would
|
|
59
|
+
* compare it lexically — "9.00" above "10.00". Both sides go through the
|
|
60
|
+
* exact BigInt comparator. A comparand that is not a decimal string matches
|
|
61
|
+
* nothing, the way a NaN numeric comparison already did.
|
|
62
|
+
*/
|
|
63
|
+
function compareMoneyValues(
|
|
64
|
+
value: unknown,
|
|
65
|
+
filterValue: unknown,
|
|
66
|
+
ordered: (delta: number) => boolean,
|
|
67
|
+
): boolean {
|
|
68
|
+
const right = typeof filterValue === "number" ? String(filterValue) : filterValue;
|
|
69
|
+
if (!isMoneyString(value) || !isMoneyString(right)) return false;
|
|
70
|
+
return ordered(moneyComparator(value, right));
|
|
71
|
+
}
|
|
72
|
+
|
|
54
73
|
export function applyFilterToValue(
|
|
55
74
|
value: any,
|
|
56
75
|
filterValue: FilterValue,
|
|
57
|
-
columnType: "text" | "number" | "date" | "boolean" = "text",
|
|
76
|
+
columnType: "text" | "number" | "money" | "date" | "boolean" = "text",
|
|
58
77
|
): boolean {
|
|
59
78
|
const { operator, value: filterVal, values } = filterValue;
|
|
60
79
|
|
|
@@ -83,6 +102,9 @@ export function applyFilterToValue(
|
|
|
83
102
|
|
|
84
103
|
// Equality operators - handle different types
|
|
85
104
|
case "is":
|
|
105
|
+
if (columnType === "money") {
|
|
106
|
+
return compareMoneyValues(value, filterVal, (delta) => delta === 0);
|
|
107
|
+
}
|
|
86
108
|
if (columnType === "number") {
|
|
87
109
|
return Number(value) === Number(filterVal);
|
|
88
110
|
}
|
|
@@ -91,6 +113,9 @@ export function applyFilterToValue(
|
|
|
91
113
|
}
|
|
92
114
|
return stringValue === filterStringValue;
|
|
93
115
|
case "isNot":
|
|
116
|
+
if (columnType === "money") {
|
|
117
|
+
return !compareMoneyValues(value, filterVal, (delta) => delta === 0);
|
|
118
|
+
}
|
|
94
119
|
if (columnType === "number") {
|
|
95
120
|
return Number(value) !== Number(filterVal);
|
|
96
121
|
}
|
|
@@ -98,23 +123,41 @@ export function applyFilterToValue(
|
|
|
98
123
|
|
|
99
124
|
// Number/Date Filters
|
|
100
125
|
case "isLessThan":
|
|
126
|
+
if (columnType === "money") {
|
|
127
|
+
return compareMoneyValues(value, filterVal, (delta) => delta < 0);
|
|
128
|
+
}
|
|
101
129
|
return columnType === "number"
|
|
102
130
|
? Number(value) < Number(filterVal)
|
|
103
131
|
: stringValue < filterStringValue;
|
|
104
132
|
case "isGreaterThan":
|
|
133
|
+
if (columnType === "money") {
|
|
134
|
+
return compareMoneyValues(value, filterVal, (delta) => delta > 0);
|
|
135
|
+
}
|
|
105
136
|
return columnType === "number"
|
|
106
137
|
? Number(value) > Number(filterVal)
|
|
107
138
|
: stringValue > filterStringValue;
|
|
108
139
|
case "isLessThanOrEqual":
|
|
140
|
+
if (columnType === "money") {
|
|
141
|
+
return compareMoneyValues(value, filterVal, (delta) => delta <= 0);
|
|
142
|
+
}
|
|
109
143
|
return columnType === "number"
|
|
110
144
|
? Number(value) <= Number(filterVal)
|
|
111
145
|
: stringValue <= filterStringValue;
|
|
112
146
|
case "isGreaterThanOrEqual":
|
|
147
|
+
if (columnType === "money") {
|
|
148
|
+
return compareMoneyValues(value, filterVal, (delta) => delta >= 0);
|
|
149
|
+
}
|
|
113
150
|
return columnType === "number"
|
|
114
151
|
? Number(value) >= Number(filterVal)
|
|
115
152
|
: stringValue >= filterStringValue;
|
|
116
153
|
case "isBetween":
|
|
117
154
|
if (values && values.length >= 2) {
|
|
155
|
+
if (columnType === "money") {
|
|
156
|
+
return (
|
|
157
|
+
compareMoneyValues(value, values[0], (delta) => delta >= 0) &&
|
|
158
|
+
compareMoneyValues(value, values[1], (delta) => delta <= 0)
|
|
159
|
+
);
|
|
160
|
+
}
|
|
118
161
|
const numValue = Number(value);
|
|
119
162
|
const min = Number(values[0]);
|
|
120
163
|
const max = Number(values[1]);
|
|
@@ -123,6 +166,12 @@ export function applyFilterToValue(
|
|
|
123
166
|
return false;
|
|
124
167
|
case "isNotBetween":
|
|
125
168
|
if (values && values.length >= 2) {
|
|
169
|
+
if (columnType === "money") {
|
|
170
|
+
return (
|
|
171
|
+
compareMoneyValues(value, values[0], (delta) => delta < 0) ||
|
|
172
|
+
compareMoneyValues(value, values[1], (delta) => delta > 0)
|
|
173
|
+
);
|
|
174
|
+
}
|
|
126
175
|
const numValue = Number(value);
|
|
127
176
|
const min = Number(values[0]);
|
|
128
177
|
const max = Number(values[1]);
|