From 7b222981f2bae0617fcaf7ab0a9d4d945fea12f9 Mon Sep 17 00:00:00 2001 From: kuechlin Date: Thu, 25 May 2023 15:18:54 +0200 Subject: [PATCH 1/6] fix: mantine as peer dependency #169 --- package.json | 8 ++++++-- pnpm-lock.yaml | 39 +++++++++++++++++++++++++++--------- src/ColumnFilter.tsx | 8 ++++---- src/ColumnSorter.tsx | 4 ++-- src/DataGrid.tsx | 22 ++++++++++---------- src/GlobalFilter.tsx | 4 ++-- src/filters/dateFilter.tsx | 6 +++--- src/filters/numberFilter.tsx | 6 +++--- src/filters/stringFilter.tsx | 4 ++-- vite.config.ts | 16 +++++++++++---- 10 files changed, 74 insertions(+), 43 deletions(-) diff --git a/package.json b/package.json index a31e308..eede352 100644 --- a/package.json +++ b/package.json @@ -35,12 +35,12 @@ "@mantine/core": "^6.0.6", "@mantine/dates": "^6.0.6", "@mantine/hooks": "^6.0.6", + "@tabler/icons-react": "^2.20.0", "@tanstack/react-table": "8.8.5", "@tanstack/react-virtual": "3.0.0-beta.26", "dayjs": "^1.11.7", "react": "^18.0.0", - "react-dom": "^18.0.0", - "tabler-icons-react": "^1.56.0" + "react-dom": "^18.0.0" }, "devDependencies": { "@commitlint/cli": "17.5.1", @@ -73,6 +73,10 @@ "vite": "4.2.1" }, "peerDependencies": { + "@emotion/react": "^11.10.6", + "@mantine/core": "^6.0.6", + "@mantine/dates": "^6.0.6", + "@mantine/hooks": "^6.0.6", "dayjs": "^1.11.7", "react": "^18.0.0", "react-dom": "^18.0.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 374fe33..19faf5b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,6 +13,7 @@ specifiers: '@mantine/dates': ^6.0.6 '@mantine/hooks': ^6.0.6 '@mantine/prism': 6.0.6 + '@tabler/icons-react': ^2.20.0 '@tanstack/react-table': 8.8.5 '@tanstack/react-virtual': 3.0.0-beta.26 '@types/node': 18.15.11 @@ -36,7 +37,6 @@ specifiers: react-router-dom: 6.10.0 rollup: 3.20.2 rollup-plugin-visualizer: 5.9.0 - tabler-icons-react: ^1.56.0 typescript: 4.9.5 vite: 4.2.1 @@ -45,12 +45,12 @@ dependencies: '@mantine/core': 6.0.11_efsdpiyvsd2ra7l4auvahzybmy '@mantine/dates': 6.0.11_vdmfa7bh7vsvlxpy4ncjhijilu '@mantine/hooks': 6.0.11_react@18.2.0 + '@tabler/icons-react': 2.20.0_react@18.2.0 '@tanstack/react-table': 8.8.5_biqbaboplfbrettd7655fr4n2y '@tanstack/react-virtual': 3.0.0-beta.26_react@18.2.0 dayjs: 1.11.7 react: 18.2.0 react-dom: 18.2.0_react@18.2.0 - tabler-icons-react: 1.56.0_react@18.2.0 devDependencies: '@commitlint/cli': 17.5.1 @@ -1181,6 +1181,20 @@ packages: engines: {node: '>=14'} dev: true + /@tabler/icons-react/2.20.0_react@18.2.0: + resolution: {integrity: sha512-r2uC0Mi3ozHD2G+IYi0A0Iy2203dbQo5EAFxn055MyIhH7U2VNsvyopTqOj+AVedy7cqR86T9zhryRUGC78WZA==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 + dependencies: + '@tabler/icons': 2.20.0 + prop-types: 15.8.1 + react: 18.2.0 + dev: false + + /@tabler/icons/2.20.0: + resolution: {integrity: sha512-BsUEJoqREs8bqcrf5HfJBq6/rDvsRI3h+T+0X1o7i8LBHonsH0iAngcyL0I82YKoSy9NiVDvM3LV63zDP0nPYQ==} + dev: false + /@tanstack/react-table/8.8.5_biqbaboplfbrettd7655fr4n2y: resolution: {integrity: sha512-g/t21E/ICHvaCOJOhsDNr5QaB/6aDQEHFbx/YliwwU/CJThMqG+dS28vnToIBV/5MBgpeXoGRi2waDJVJlZrtg==} engines: {node: '>=12'} @@ -3276,6 +3290,11 @@ packages: path-key: 4.0.0 dev: true + /object-assign/4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + dev: false + /object-inspect/1.12.2: resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==} dev: true @@ -3481,6 +3500,14 @@ packages: react: 18.2.0 dev: true + /prop-types/15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + dev: false + /punycode/2.1.1: resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==} engines: {node: '>=6'} @@ -4008,14 +4035,6 @@ packages: /tabbable/6.1.1: resolution: {integrity: sha512-4kl5w+nCB44EVRdO0g/UGoOp3vlwgycUVtkk/7DPyeLZUCuNFFKCFG6/t/DgHLrUPHjrZg6s5tNm+56Q2B0xyg==} - /tabler-icons-react/1.56.0_react@18.2.0: - resolution: {integrity: sha512-FOme3w6PJIWDpeXqQ4xjArQqdxzrr9xNy7PSSgWpRzOUQ71RyZ7jt6WThsfyLBz5os78TPJRA8f/0NLjnKcx9A==} - peerDependencies: - react: '>= 16.8.0' - dependencies: - react: 18.2.0 - dev: false - /tapable/2.2.1: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} diff --git a/src/ColumnFilter.tsx b/src/ColumnFilter.tsx index 89db019..d9d8e0e 100644 --- a/src/ColumnFilter.tsx +++ b/src/ColumnFilter.tsx @@ -1,8 +1,8 @@ import { ActionIcon, Button, Group, Menu, Stack } from '@mantine/core'; import { useSetState } from '@mantine/hooks'; +import { IconCheck, IconFilter, IconX } from '@tabler/icons-react'; import { Column } from '@tanstack/react-table'; import { createElement, useState } from 'react'; -import { Check, Filter, X } from 'tabler-icons-react'; import { DataGridFilterFn, isDataGridFilter } from './filters/types'; export interface ColumnFilterProps { @@ -55,7 +55,7 @@ export const ColumnFilter = function ColumnFilter({ column, className, color, fi } + children={} onClick={handleOpen} className={className} variant={column.getIsFiltered() ? 'light' : 'transparent'} @@ -69,7 +69,7 @@ export const ColumnFilter = function ColumnFilter({ column, className, color, fi + cell.getValue()?.toLocaleDateString(), + filterFn: dateFilterFn, + }, + { + accessorKey: 'bool', + filterFn: booleanFilterFn, + }, + ]} + /> + + ); +} diff --git a/docs/pages/examples/index.ts b/docs/pages/examples/index.ts index cc02eaf..4d10d15 100644 --- a/docs/pages/examples/index.ts +++ b/docs/pages/examples/index.ts @@ -75,6 +75,10 @@ import NestedExample from './NestedExample'; // @ts-ignore import NestedExampleCode from './NestedExample.tsx?raw'; +import ResetFilterExample from './ResetFilterExample'; +// @ts-ignore +import ResetFilterExampleCode from './ResetFilterExample.tsx?raw'; + export type Example = { label: string; path: string; @@ -192,4 +196,10 @@ export const examples = { element: NestedExample, code: NestedExampleCode, }), + reset: ex({ + label: 'Reset Filter', + path: '/example/reset', + element: ResetFilterExample, + code: ResetFilterExampleCode, + }), }; diff --git a/src/DataGrid.tsx b/src/DataGrid.tsx index f3cf3bd..86989cf 100644 --- a/src/DataGrid.tsx +++ b/src/DataGrid.tsx @@ -10,6 +10,7 @@ import { RowSelectionState, SortingState, Table, + TableState, flexRender, functionalUpdate, getCoreRowModel, @@ -170,88 +171,59 @@ export function DataGrid({ } }, [table, width, noFlexLayout, tableSize]); - const handleGlobalFilterChange: OnChangeFn = useCallback( - (arg0) => - table.setState((state) => { - const next = functionalUpdate(arg0, state.globalFilter || ''); - onSearch && onSearch(next); - return { - ...state, - globalFilter: next, - }; - }), - [table, onSearch] + const handleChange = useCallback( + function change( + key: T, + handler?: (value: TableState[T]) => void + ): OnChangeFn { + return (arg0) => { + if (state && state[key]) { + const next = functionalUpdate(arg0, state[key]); + handler && handler(next); + } else { + table.setState((state) => { + const next = functionalUpdate(arg0, state[key]); + handler && handler(next); + return { + ...state, + [key]: next, + }; + }); + } + }; + }, + [state, table] ); - const handleSortingChange: OnChangeFn = useCallback( - (arg0) => - table.setState((state) => { - const next = functionalUpdate(arg0, state.sorting); - onSort && onSort(next); - return { - ...state, - sorting: next, - }; - }), - [table, onSort] - ); + const handleGlobalFilterChange: OnChangeFn = useCallback(handleChange('globalFilter', onSearch), [ + handleChange, + onSearch, + ]); + + const handleSortingChange: OnChangeFn = useCallback(handleChange('sorting', onSort), [ + handleChange, + onSort, + ]); const handleColumnFiltersChange: OnChangeFn = useCallback( - (arg0) => - table.setState((state) => { - const next = functionalUpdate(arg0, state.columnFilters); - onFilter && onFilter(next); - return { - ...state, - columnFilters: next, - }; - }), - [table, onFilter] + handleChange('columnFilters', onFilter), + [handleChange, onFilter] ); - const handlePaginationChange: OnChangeFn = useCallback( - (arg0) => { - const pagination = table.getState().pagination; - const next = functionalUpdate(arg0, pagination); - if (next.pageIndex !== pagination.pageIndex || next.pageSize !== pagination.pageSize) { - onPageChange && onPageChange(next); - table.setState((state) => ({ - ...state, - pagination: next, - })); - } - }, - [table, onPageChange] - ); + const handlePaginationChange: OnChangeFn = useCallback(handleChange('pagination', onPageChange), [ + handleChange, + onPageChange, + ]); const handleRowSelectionChange: OnChangeFn = useCallback( - (arg0) => { - table.setState(() => { - const state = table.getState(); - const next = functionalUpdate(arg0, state.rowSelection); - onRowSelectionChange && onRowSelectionChange(next); - return { - ...state, - rowSelection: next, - }; - }); - }, - [table, onRowSelectionChange] + handleChange('rowSelection', onRowSelectionChange), + [handleChange, onRowSelectionChange] ); - const handleExpandedChange: OnChangeFn = useCallback( - (arg0) => { - table.setState((state) => { - const next = functionalUpdate(arg0, state.expanded); - onExpandedChange && onExpandedChange(next); - return { - ...state, - expanded: next, - }; - }); - }, - [table, onExpandedChange] - ); + const handleExpandedChange: OnChangeFn = useCallback(handleChange('expanded', onExpandedChange), [ + handleChange, + onExpandedChange, + ]); const pageCount = withPagination && total ? Math.ceil(total / table.getState().pagination.pageSize) : undefined; From 1222fa4dc46a38822202e7065256094b5f229a49 Mon Sep 17 00:00:00 2001 From: kuechlin Date: Thu, 25 May 2023 16:32:25 +0200 Subject: [PATCH 5/6] feat: add overrides for filter and sorter #154 --- src/ColumnFilter.tsx | 2 +- src/ColumnSorter.tsx | 2 +- src/DataGrid.tsx | 18 +++++++++++++++--- src/types.ts | 4 ++++ 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/ColumnFilter.tsx b/src/ColumnFilter.tsx index d9d8e0e..1a0b9f2 100644 --- a/src/ColumnFilter.tsx +++ b/src/ColumnFilter.tsx @@ -12,7 +12,7 @@ export interface ColumnFilterProps { color: string; } -export const ColumnFilter = function ColumnFilter({ column, className, color, filterFn }: ColumnFilterProps) { +export const DefaultColumnFilter = function ColumnFilter({ column, className, color, filterFn }: ColumnFilterProps) { const [state, setState] = useSetState({ open: false, value: null as unknown }); const handleOpen = () => diff --git a/src/ColumnSorter.tsx b/src/ColumnSorter.tsx index b7443d8..cddd5c6 100644 --- a/src/ColumnSorter.tsx +++ b/src/ColumnSorter.tsx @@ -8,7 +8,7 @@ export interface ColumnSorterProps { color: string; } -export const ColumnSorter = ({ column, className, color }: ColumnSorterProps) => { +export const DefaultColumnSorter = ({ column, className, color }: ColumnSorterProps) => { const sorted = column.getIsSorted(); return ( ({ empty, locale, // component overrides - components: { headerWrapper, headerRow, headerCell, bodyWrapper, bodyRow, bodyCell, pagination } = {}, + components: { + headerWrapper, + headerRow, + headerCell, + bodyWrapper, + bodyRow, + bodyCell, + pagination, + columnFilter, + columnSorter, + } = {}, // table option ovverides options, // rest @@ -109,6 +119,8 @@ export function DataGrid({ const BodyRow = bodyRow ?? DefaultBodyRow; const BodyCell = bodyCell ?? DefaultBodyCell; const Pagination = pagination ?? DefaultPagination; + const ColumnFilter = columnFilter ?? DefaultColumnFilter; + const ColumnSorter = columnSorter ?? DefaultColumnSorter; const { classes, theme, cx } = useStyles( { height, diff --git a/src/types.ts b/src/types.ts index c7e8d22..df331f5 100644 --- a/src/types.ts +++ b/src/types.ts @@ -16,6 +16,8 @@ import { TableState, } from '@tanstack/react-table'; import { ComponentPropsWithoutRef, ComponentType, HTMLAttributes, ReactElement, ReactNode, Ref } from 'react'; +import { ColumnFilterProps } from './ColumnFilter'; +import { ColumnSorterProps } from './ColumnSorter'; import useStyles from './DataGrid.styles'; import { PaginationProps } from './Pagination'; import { @@ -229,4 +231,6 @@ export type DataGridComponents = { bodyRow: ComponentType>; bodyCell: ComponentType>; pagination: ComponentType>; + columnFilter: ComponentType; + columnSorter: ComponentType; }; From c6563c0e2348960b572ca05bb5bbae344025731b Mon Sep 17 00:00:00 2001 From: kuechlin Date: Thu, 25 May 2023 16:45:34 +0200 Subject: [PATCH 6/6] v0.2.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 546a61b..7e0f818 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mantine-data-grid", - "version": "0.2.1", + "version": "0.2.2", "homepage": "https://kuechlin.github.io/mantine-data-grid/", "repository": { "type": "git",