diff --git a/src/components/__stories__/ColumnPinningDemo.scss b/src/components/__stories__/ColumnPinningDemo.scss index 9f11e40..b542f76 100644 --- a/src/components/__stories__/ColumnPinningDemo.scss +++ b/src/components/__stories__/ColumnPinningDemo.scss @@ -34,21 +34,21 @@ $block: '.#{variables.$ns}column-pinning-demo'; } .gt-table__header-row { - .gt-table__header-cell:first-of-type { + .gt-table__header-cell:first-child { border-inline-start: 0; } - .gt-table__header-cell:last-of-type { + .gt-table__header-cell:last-child { border-inline-end: 0; } } .gt-table__row { - .gt-table__cell:first-of-type { + .gt-table__cell:first-child { border-inline-start: 0; } - .gt-table__cell:last-of-type { + .gt-table__cell:last-child { border-inline-end: 0; } } diff --git a/src/components/__stories__/ColumnPinningDemo.tsx b/src/components/__stories__/ColumnPinningDemo.tsx index 27bf220..d4c449b 100644 --- a/src/components/__stories__/ColumnPinningDemo.tsx +++ b/src/components/__stories__/ColumnPinningDemo.tsx @@ -1,87 +1,16 @@ import React from 'react'; -import type {ColumnDef, ColumnPinningState, ExpandedState} from '@tanstack/react-table'; +import type {ColumnPinningState} from '@tanstack/react-table'; -import {defaultDragHandleColumn} from '../../constants'; -import {withTableReorder} from '../../hocs'; import {useTable} from '../../hooks'; -import type {SortableListDragResult} from '../SortableList'; import {Table} from '../Table'; import {cnColumnPinningDemo} from './ColumnPinningDemo.classname'; -import {ColumnPinningHeaderCell} from './cells/ColumnPinningHeaderCell'; -import {TreeNameCell} from './cells/TreeNameCell'; -import {data as originalData} from './constants/data'; -import {data as treeData} from './constants/tree'; -import type {TreeItem} from './constants/tree'; -import type {Item} from './types'; +import {columns} from './constants/columnPinning'; +import {data} from './constants/data'; import './ColumnPinningDemo.scss'; -const columns: ColumnDef[] = [ - { - accessorKey: 'name', - header: (info) => ( - - ), - minSize: 200, - }, - { - accessorKey: 'age', - header: (info) => ( - - ), - minSize: 200, - }, - { - accessorKey: 'status', - header: (info) => ( - - ), - minSize: 300, - }, -]; - -const treeColumns: ColumnDef[] = [ - { - accessorKey: 'name', - header: (info) => ( - - ), - cell: (info) => ( - ()} /> - ), - minSize: 320, - }, - { - accessorKey: 'age', - header: (info) => ( - - ), - minSize: 320, - }, -]; - export const ColumnPinningDemo = () => { const [columnPinning, setColumnPinning] = React.useState({ left: [], @@ -90,104 +19,11 @@ export const ColumnPinningDemo = () => { const table = useTable({ columns, - data: originalData, - enableColumnPinning: true, - onColumnPinningChange: setColumnPinning, - state: { - columnPinning, - }, - }); - - return ( -
- - - ); -}; - -const TableWithReordering = withTableReorder(Table); - -const columnsWithReordering: ColumnDef[] = [ - { - ...(defaultDragHandleColumn as ColumnDef), - minSize: 16, - }, - ...columns, -]; - -export const ColumnPinningWithReorderingDemo = () => { - const [data, setData] = React.useState(originalData); - - const [columnPinning, setColumnPinning] = React.useState({ - left: [defaultDragHandleColumn.id ?? ''], - right: [], - }); - - const table = useTable({ data, - columns: columnsWithReordering, - getRowId: (item) => item.id, - enableColumnPinning: true, - onColumnPinningChange: setColumnPinning, - state: { - columnPinning, - }, - }); - - const handleReorder = React.useCallback( - ({draggedItemKey, baseItemKey}: SortableListDragResult) => { - setData((prevData) => { - const dataClone = prevData.slice(); - - const index = dataClone.findIndex((item) => item.id === draggedItemKey); - - if (index >= 0) { - const dragged = dataClone.splice(index, 1)[0] as Item; - const insertIndex = dataClone.findIndex((item) => item.id === baseItemKey); - - if (insertIndex >= 0) { - dataClone.splice(insertIndex + 1, 0, dragged); - } else { - dataClone.unshift(dragged); - } - } - - return dataClone; - }); - }, - [], - ); - - return ( -
- -
- ); -}; - -export const ColumnPinningWithTreeDemo = () => { - const [expanded, setExpanded] = React.useState({}); - - const [columnPinning, setColumnPinning] = React.useState({ - left: [defaultDragHandleColumn.id ?? ''], - right: [], - }); - - const table = useTable({ - columns: treeColumns, - data: treeData, - getSubRows: (item) => item.children, - enableExpanding: true, - onExpandedChange: setExpanded, enableColumnPinning: true, onColumnPinningChange: setColumnPinning, state: { columnPinning, - expanded, }, }); diff --git a/src/components/__stories__/ColumnPinningWithReorderingDemo.tsx b/src/components/__stories__/ColumnPinningWithReorderingDemo.tsx new file mode 100644 index 0000000..157f84e --- /dev/null +++ b/src/components/__stories__/ColumnPinningWithReorderingDemo.tsx @@ -0,0 +1,78 @@ +import React from 'react'; + +import type {ColumnDef, ColumnPinningState} from '@tanstack/react-table'; + +import {defaultDragHandleColumn} from '../../constants'; +import {withTableReorder} from '../../hocs'; +import {useTable} from '../../hooks'; +import type {SortableListDragResult} from '../SortableList'; +import {Table} from '../Table'; + +import {cnColumnPinningDemo} from './ColumnPinningDemo.classname'; +import {columns} from './constants/columnPinning'; +import {data as originalData} from './constants/data'; +import type {Item} from './types'; + +const TableWithReordering = withTableReorder(Table); + +const columnsWithReordering: ColumnDef[] = [ + { + ...(defaultDragHandleColumn as ColumnDef), + minSize: 16, + }, + ...columns, +]; + +export const ColumnPinningWithReorderingDemo = () => { + const [data, setData] = React.useState(originalData); + + const [columnPinning, setColumnPinning] = React.useState({ + left: [defaultDragHandleColumn.id ?? ''], + right: [], + }); + + const table = useTable({ + data, + columns: columnsWithReordering, + getRowId: (item) => item.id, + enableColumnPinning: true, + onColumnPinningChange: setColumnPinning, + state: { + columnPinning, + }, + }); + + const handleReorder = React.useCallback( + ({draggedItemKey, baseItemKey}: SortableListDragResult) => { + setData((prevData) => { + const dataClone = prevData.slice(); + + const index = dataClone.findIndex((item) => item.id === draggedItemKey); + + if (index >= 0) { + const dragged = dataClone.splice(index, 1)[0] as Item; + const insertIndex = dataClone.findIndex((item) => item.id === baseItemKey); + + if (insertIndex >= 0) { + dataClone.splice(insertIndex + 1, 0, dragged); + } else { + dataClone.unshift(dragged); + } + } + + return dataClone; + }); + }, + [], + ); + + return ( +
+ +
+ ); +}; diff --git a/src/components/__stories__/ColumnPinningWithSelectionDemo.tsx b/src/components/__stories__/ColumnPinningWithSelectionDemo.tsx new file mode 100644 index 0000000..df0728e --- /dev/null +++ b/src/components/__stories__/ColumnPinningWithSelectionDemo.tsx @@ -0,0 +1,49 @@ +import React from 'react'; + +import type {ColumnDef, ColumnPinningState, RowSelectionState} from '@tanstack/react-table'; + +import {defaultSelectionColumn} from '../../constants'; +import {useTable} from '../../hooks'; +import {Table} from '../Table'; + +import {cnColumnPinningDemo} from './ColumnPinningDemo.classname'; +import {columns} from './constants/columnPinning'; +import {data} from './constants/data'; +import type {Item} from './types'; + +const columnsWithSelection: ColumnDef[] = [ + { + ...(defaultSelectionColumn as ColumnDef), + }, + ...columns, +]; + +export const ColumnPinningWithSelectionDemo = () => { + const [columnPinning, setColumnPinning] = React.useState({ + left: [defaultSelectionColumn.id ?? ''], + right: [], + }); + + const [rowSelection, setRowSelection] = React.useState({}); + + const table = useTable({ + data, + columns: columnsWithSelection, + getRowId: (item) => item.id, + enableColumnPinning: true, + enableRowSelection: true, + enableMultiRowSelection: true, + onColumnPinningChange: setColumnPinning, + onRowSelectionChange: setRowSelection, + state: { + columnPinning, + rowSelection, + }, + }); + + return ( +
+
+ + ); +}; diff --git a/src/components/__stories__/Table.stories.tsx b/src/components/__stories__/Table.stories.tsx index dc18047..e26cd20 100644 --- a/src/components/__stories__/Table.stories.tsx +++ b/src/components/__stories__/Table.stories.tsx @@ -4,11 +4,9 @@ import type {Meta, StoryFn} from '@storybook/react'; import {Table} from '../Table'; -import { - ColumnPinningDemo, - ColumnPinningWithReorderingDemo, - ColumnPinningWithTreeDemo, -} from './ColumnPinningDemo'; +import {ColumnPinningDemo} from './ColumnPinningDemo'; +import {ColumnPinningWithReorderingDemo} from './ColumnPinningWithReorderingDemo'; +import {ColumnPinningWithSelectionDemo} from './ColumnPinningWithSelectionDemo'; import {DefaultDemo} from './DefaultDemo'; import {GroupingDemo} from './GroupingDemo'; import {GroupingDemo2} from './GroupingDemo2'; @@ -85,5 +83,5 @@ export const ColumnPinning: StoryFn = ColumnPinningTemplate.bind({}); const ColumnPinningWithReorderingTemplate: StoryFn = () => ; export const ColumnPinningWithReordering: StoryFn = ColumnPinningWithReorderingTemplate.bind({}); -const ColumnPinningWithTreeTemplate: StoryFn = () => ; -export const ColumnPinningWithTree: StoryFn = ColumnPinningWithTreeTemplate.bind({}); +const ColumnPinningWithSelectionTemplate: StoryFn = () => ; +export const ColumnPinningWithSelection: StoryFn = ColumnPinningWithSelectionTemplate.bind({}); diff --git a/src/components/__stories__/cells/ColumnPinningHeaderCell.tsx b/src/components/__stories__/cells/ColumnPinningHeaderCell.tsx index d49c005..feb3d58 100644 --- a/src/components/__stories__/cells/ColumnPinningHeaderCell.tsx +++ b/src/components/__stories__/cells/ColumnPinningHeaderCell.tsx @@ -17,6 +17,10 @@ export const ColumnPinningHeaderCell = ({ }: ColumnPinningHeaderCellProps) => { const canPin = info.column.getCanPin(); + const canPinLeft = canPin && info.column.getIsPinned() !== 'left'; + const canPinRight = canPin && info.column.getIsPinned() !== 'right'; + const canUnpin = canPin && info.column.getIsPinned(); + const handlePinLeft = () => { info.column.pin('left'); }; @@ -34,9 +38,9 @@ export const ColumnPinningHeaderCell = ({
{value}
{canPin && (
- - - + {canPinLeft && } + {canUnpin && } + {canPinRight && }
)} diff --git a/src/components/__stories__/constants/columnPinning.tsx b/src/components/__stories__/constants/columnPinning.tsx new file mode 100644 index 0000000..c90e0fd --- /dev/null +++ b/src/components/__stories__/constants/columnPinning.tsx @@ -0,0 +1,43 @@ +import React from 'react'; + +import type {ColumnDef} from '@tanstack/react-table'; + +import {cnColumnPinningDemo} from '../ColumnPinningDemo.classname'; +import {ColumnPinningHeaderCell} from '../cells/ColumnPinningHeaderCell'; +import type {Item} from '../types'; + +export const columns: ColumnDef[] = [ + { + accessorKey: 'name', + header: (info) => ( + + ), + minSize: 200, + }, + { + accessorKey: 'age', + header: (info) => ( + + ), + minSize: 200, + }, + { + accessorKey: 'status', + header: (info) => ( + + ), + minSize: 300, + }, +];