From d4e7d823f102c9e77e8520b502495a80a1db37c0 Mon Sep 17 00:00:00 2001 From: DanisAvko <48149690+DanisAvko@users.noreply.github.com> Date: Tue, 24 Sep 2024 11:47:32 +0300 Subject: [PATCH] feat(Table): styled SortIndicator added (#49) --- .../__stories__/stories/DefaultStory.tsx | 2 +- .../__stories__/stories/EmptyContentStory.tsx | 2 +- .../__stories__/stories/GroupingStory.tsx | 2 +- .../__stories__/stories/GroupingStory2.tsx | 2 +- .../stories/GroupingWithSelectionStory.tsx | 2 +- .../__stories__/stories/HeaderGroupsStory.tsx | 2 +- .../__stories__/stories/ReorderingStory.tsx | 2 +- .../ReorderingWithVirtualizationStory.tsx | 2 +- .../__stories__/stories/ResizingStory.tsx | 2 +- .../__stories__/stories/SortingStory.tsx | 2 +- .../__stories__/stories/StickyHeaderStory.tsx | 2 +- .../__stories__/stories/TreeStory.tsx | 2 +- .../stories/TreeWithGroupsStory.tsx | 2 +- .../stories/VirtualizationStory.tsx | 2 +- .../stories/WindowVirtualizationStory.tsx | 2 +- .../stories/WithSelectionStory.tsx | 2 +- .../stories/WithoutHeaderStory.tsx | 2 +- .../SortIndicator/SortIndicator.classname.ts | 3 ++ .../SortIndicator/SortIndicator.scss | 15 ++++++++ .../SortIndicator/SortIndicator.tsx | 25 +++++++++++++ src/components/SortIndicator/index.ts | 1 + .../Table/__stories__/Table.stories.tsx | 5 +++ .../stories/SortingStory.classname.ts | 3 ++ .../__stories__/stories/SortingStory.scss | 6 +++ .../__stories__/stories/SortingStory.tsx | 37 +++++++++++++++++++ src/utils/getSortIndicatorIcon.ts | 18 +++++++++ src/utils/index.ts | 1 + 27 files changed, 131 insertions(+), 17 deletions(-) create mode 100644 src/components/SortIndicator/SortIndicator.classname.ts create mode 100644 src/components/SortIndicator/SortIndicator.scss create mode 100644 src/components/SortIndicator/SortIndicator.tsx create mode 100644 src/components/SortIndicator/index.ts create mode 100644 src/components/Table/__stories__/stories/SortingStory.classname.ts create mode 100644 src/components/Table/__stories__/stories/SortingStory.scss create mode 100644 src/components/Table/__stories__/stories/SortingStory.tsx create mode 100644 src/utils/getSortIndicatorIcon.ts diff --git a/src/components/BaseTable/__stories__/stories/DefaultStory.tsx b/src/components/BaseTable/__stories__/stories/DefaultStory.tsx index 3e28ea3..a9fa37c 100644 --- a/src/components/BaseTable/__stories__/stories/DefaultStory.tsx +++ b/src/components/BaseTable/__stories__/stories/DefaultStory.tsx @@ -1,7 +1,7 @@ import React from 'react'; import {useTable} from '../../../../hooks'; -import {BaseTable} from '../../../BaseTable'; +import {BaseTable} from '../../BaseTable'; import {columns} from '../constants/columns'; import {data} from '../constants/data'; diff --git a/src/components/BaseTable/__stories__/stories/EmptyContentStory.tsx b/src/components/BaseTable/__stories__/stories/EmptyContentStory.tsx index 82c4041..45f5e8b 100644 --- a/src/components/BaseTable/__stories__/stories/EmptyContentStory.tsx +++ b/src/components/BaseTable/__stories__/stories/EmptyContentStory.tsx @@ -1,7 +1,7 @@ import React from 'react'; import {useTable} from '../../../../hooks'; -import {BaseTable} from '../../../BaseTable'; +import {BaseTable} from '../../BaseTable'; import {columns} from '../constants/columns'; import {cnEmptyContentStory} from './EmptyContentStory.classname'; diff --git a/src/components/BaseTable/__stories__/stories/GroupingStory.tsx b/src/components/BaseTable/__stories__/stories/GroupingStory.tsx index 38f16ab..0a48d06 100644 --- a/src/components/BaseTable/__stories__/stories/GroupingStory.tsx +++ b/src/components/BaseTable/__stories__/stories/GroupingStory.tsx @@ -3,7 +3,7 @@ import React from 'react'; import type {ExpandedState, Row} from '@tanstack/react-table'; import {useTable} from '../../../../hooks'; -import {BaseTable} from '../../../BaseTable'; +import {BaseTable} from '../../BaseTable'; import type {GroupOrItem} from '../constants/grouping'; import {columns, data} from '../constants/grouping'; diff --git a/src/components/BaseTable/__stories__/stories/GroupingStory2.tsx b/src/components/BaseTable/__stories__/stories/GroupingStory2.tsx index 844c44b..918821c 100644 --- a/src/components/BaseTable/__stories__/stories/GroupingStory2.tsx +++ b/src/components/BaseTable/__stories__/stories/GroupingStory2.tsx @@ -3,7 +3,7 @@ import React from 'react'; import type {ExpandedState, Row} from '@tanstack/react-table'; import {useTable} from '../../../../hooks'; -import {BaseTable} from '../../../BaseTable'; +import {BaseTable} from '../../BaseTable'; import {columns} from '../constants/columns'; import type {Item} from '../types'; import {generateData} from '../utils'; diff --git a/src/components/BaseTable/__stories__/stories/GroupingWithSelectionStory.tsx b/src/components/BaseTable/__stories__/stories/GroupingWithSelectionStory.tsx index af6e072..c55c744 100644 --- a/src/components/BaseTable/__stories__/stories/GroupingWithSelectionStory.tsx +++ b/src/components/BaseTable/__stories__/stories/GroupingWithSelectionStory.tsx @@ -4,7 +4,7 @@ import type {ColumnDef, ExpandedState, Row, RowSelectionState} from '@tanstack/r import {selectionColumn} from '../../../../constants'; import {useTable} from '../../../../hooks'; -import {BaseTable} from '../../../BaseTable'; +import {BaseTable} from '../../BaseTable'; import type {GroupOrItem} from '../constants/grouping'; import {data, columns as originalColumns} from '../constants/grouping'; diff --git a/src/components/BaseTable/__stories__/stories/HeaderGroupsStory.tsx b/src/components/BaseTable/__stories__/stories/HeaderGroupsStory.tsx index 38e816f..3df13c1 100644 --- a/src/components/BaseTable/__stories__/stories/HeaderGroupsStory.tsx +++ b/src/components/BaseTable/__stories__/stories/HeaderGroupsStory.tsx @@ -3,7 +3,7 @@ import React from 'react'; import type {ColumnDef} from '@tanstack/react-table'; import {useTable} from '../../../../hooks'; -import {BaseTable} from '../../../BaseTable'; +import {BaseTable} from '../../BaseTable'; import {columns as nestedColumns} from '../constants/columns'; import {data} from '../constants/data'; import type {Item} from '../types'; diff --git a/src/components/BaseTable/__stories__/stories/ReorderingStory.tsx b/src/components/BaseTable/__stories__/stories/ReorderingStory.tsx index 212f88e..2e162b9 100644 --- a/src/components/BaseTable/__stories__/stories/ReorderingStory.tsx +++ b/src/components/BaseTable/__stories__/stories/ReorderingStory.tsx @@ -4,9 +4,9 @@ import type {ColumnDef} from '@tanstack/react-table'; import {dragHandleColumn} from '../../../../constants'; import {useTable} from '../../../../hooks'; -import {BaseTable} from '../../../BaseTable'; import {ReorderingProvider} from '../../../ReorderingProvider'; import type {ReorderingProviderProps} from '../../../ReorderingProvider'; +import {BaseTable} from '../../BaseTable'; import {columns as originalColumns} from '../constants/columns'; import {data as originalData} from '../constants/data'; import type {Item} from '../types'; diff --git a/src/components/BaseTable/__stories__/stories/ReorderingWithVirtualizationStory.tsx b/src/components/BaseTable/__stories__/stories/ReorderingWithVirtualizationStory.tsx index a2d1506..49205e9 100644 --- a/src/components/BaseTable/__stories__/stories/ReorderingWithVirtualizationStory.tsx +++ b/src/components/BaseTable/__stories__/stories/ReorderingWithVirtualizationStory.tsx @@ -5,9 +5,9 @@ import type {ColumnDef} from '@tanstack/react-table'; import {dragHandleColumn} from '../../../../constants'; import {useTable, useWindowRowVirtualizer} from '../../../../hooks'; import {getVirtualRowRangeExtractor} from '../../../../utils'; -import {BaseTable} from '../../../BaseTable'; import {ReorderingProvider} from '../../../ReorderingProvider'; import type {ReorderingProviderProps} from '../../../ReorderingProvider'; +import {BaseTable} from '../../BaseTable'; import {columns as originalColumns} from '../constants/columns'; import type {Item} from '../types'; import {generateData} from '../utils'; diff --git a/src/components/BaseTable/__stories__/stories/ResizingStory.tsx b/src/components/BaseTable/__stories__/stories/ResizingStory.tsx index 5c733dc..8202ec3 100644 --- a/src/components/BaseTable/__stories__/stories/ResizingStory.tsx +++ b/src/components/BaseTable/__stories__/stories/ResizingStory.tsx @@ -1,7 +1,7 @@ import React from 'react'; import {useTable} from '../../../../hooks'; -import {BaseTable} from '../../../BaseTable'; +import {BaseTable} from '../../BaseTable'; import {columns} from '../constants/columns'; import {data} from '../constants/data'; diff --git a/src/components/BaseTable/__stories__/stories/SortingStory.tsx b/src/components/BaseTable/__stories__/stories/SortingStory.tsx index 16dbd3f..2bdc91d 100644 --- a/src/components/BaseTable/__stories__/stories/SortingStory.tsx +++ b/src/components/BaseTable/__stories__/stories/SortingStory.tsx @@ -3,7 +3,7 @@ import React from 'react'; import type {SortingState} from '@tanstack/react-table'; import {useTable} from '../../../../hooks'; -import {BaseTable} from '../../../BaseTable'; +import {BaseTable} from '../../BaseTable'; import {columns} from '../constants/columns'; import {data} from '../constants/data'; diff --git a/src/components/BaseTable/__stories__/stories/StickyHeaderStory.tsx b/src/components/BaseTable/__stories__/stories/StickyHeaderStory.tsx index f23cf43..87c806e 100644 --- a/src/components/BaseTable/__stories__/stories/StickyHeaderStory.tsx +++ b/src/components/BaseTable/__stories__/stories/StickyHeaderStory.tsx @@ -1,7 +1,7 @@ import React from 'react'; import {useTable} from '../../../../hooks'; -import {BaseTable} from '../../../BaseTable'; +import {BaseTable} from '../../BaseTable'; import {columns} from '../constants/columns'; import {generateData} from '../utils'; diff --git a/src/components/BaseTable/__stories__/stories/TreeStory.tsx b/src/components/BaseTable/__stories__/stories/TreeStory.tsx index 50c6e50..aca9f67 100644 --- a/src/components/BaseTable/__stories__/stories/TreeStory.tsx +++ b/src/components/BaseTable/__stories__/stories/TreeStory.tsx @@ -3,7 +3,7 @@ import React from 'react'; import type {ExpandedState} from '@tanstack/react-table'; import {useTable} from '../../../../hooks'; -import {BaseTable} from '../../../BaseTable'; +import {BaseTable} from '../../BaseTable'; import {columns, data} from '../constants/tree'; export const TreeStory = () => { diff --git a/src/components/BaseTable/__stories__/stories/TreeWithGroupsStory.tsx b/src/components/BaseTable/__stories__/stories/TreeWithGroupsStory.tsx index 14a591d..412d49d 100644 --- a/src/components/BaseTable/__stories__/stories/TreeWithGroupsStory.tsx +++ b/src/components/BaseTable/__stories__/stories/TreeWithGroupsStory.tsx @@ -3,7 +3,7 @@ import React from 'react'; import type {ExpandedState, Row} from '@tanstack/react-table'; import {useTable} from '../../../../hooks'; -import {BaseTable} from '../../../BaseTable'; +import {BaseTable} from '../../BaseTable'; import type {TreeGroupItem} from '../constants/tree'; import {groupsColumns, groupsData} from '../constants/tree'; diff --git a/src/components/BaseTable/__stories__/stories/VirtualizationStory.tsx b/src/components/BaseTable/__stories__/stories/VirtualizationStory.tsx index 4d10f8a..a8a80a0 100644 --- a/src/components/BaseTable/__stories__/stories/VirtualizationStory.tsx +++ b/src/components/BaseTable/__stories__/stories/VirtualizationStory.tsx @@ -1,7 +1,7 @@ import React from 'react'; import {useRowVirtualizer, useTable} from '../../../../hooks'; -import {BaseTable} from '../../../BaseTable'; +import {BaseTable} from '../../BaseTable'; import {columns} from '../constants/columns'; import {generateData} from '../utils'; diff --git a/src/components/BaseTable/__stories__/stories/WindowVirtualizationStory.tsx b/src/components/BaseTable/__stories__/stories/WindowVirtualizationStory.tsx index 0df6a56..72b789f 100644 --- a/src/components/BaseTable/__stories__/stories/WindowVirtualizationStory.tsx +++ b/src/components/BaseTable/__stories__/stories/WindowVirtualizationStory.tsx @@ -1,7 +1,7 @@ import React from 'react'; import {useTable, useWindowRowVirtualizer} from '../../../../hooks'; -import {BaseTable} from '../../../BaseTable'; +import {BaseTable} from '../../BaseTable'; import {columns} from '../constants/columns'; import {generateData} from '../utils'; diff --git a/src/components/BaseTable/__stories__/stories/WithSelectionStory.tsx b/src/components/BaseTable/__stories__/stories/WithSelectionStory.tsx index 074ce07..249ba43 100644 --- a/src/components/BaseTable/__stories__/stories/WithSelectionStory.tsx +++ b/src/components/BaseTable/__stories__/stories/WithSelectionStory.tsx @@ -4,7 +4,7 @@ import type {ColumnDef, RowSelectionState} from '@tanstack/react-table'; import {selectionColumn} from '../../../../constants'; import {useTable} from '../../../../hooks'; -import {BaseTable} from '../../../BaseTable'; +import {BaseTable} from '../../BaseTable'; import {columns as originalColumns} from '../constants/columns'; import {data} from '../constants/data'; import type {Item} from '../types'; diff --git a/src/components/BaseTable/__stories__/stories/WithoutHeaderStory.tsx b/src/components/BaseTable/__stories__/stories/WithoutHeaderStory.tsx index a9de4e9..e6b60a3 100644 --- a/src/components/BaseTable/__stories__/stories/WithoutHeaderStory.tsx +++ b/src/components/BaseTable/__stories__/stories/WithoutHeaderStory.tsx @@ -1,7 +1,7 @@ import React from 'react'; import {useTable} from '../../../../hooks'; -import {BaseTable} from '../../../BaseTable'; +import {BaseTable} from '../../BaseTable'; import {columns} from '../constants/columns'; import {data} from '../constants/data'; diff --git a/src/components/SortIndicator/SortIndicator.classname.ts b/src/components/SortIndicator/SortIndicator.classname.ts new file mode 100644 index 0000000..e1a294e --- /dev/null +++ b/src/components/SortIndicator/SortIndicator.classname.ts @@ -0,0 +1,3 @@ +import {block} from '../../utils'; + +export const b = block('styled-sort-indicator'); diff --git a/src/components/SortIndicator/SortIndicator.scss b/src/components/SortIndicator/SortIndicator.scss new file mode 100644 index 0000000..1158e93 --- /dev/null +++ b/src/components/SortIndicator/SortIndicator.scss @@ -0,0 +1,15 @@ +@use '../variables'; + +$block: '.#{variables.$ns}styled-sort-indicator'; + +#{$block} { + display: inline-flex; + padding-block: 1px; + + color: var(--g-color-text-hint); + + &_order_asc, + &_order_desc { + color: var(--g-color-text-primary); + } +} diff --git a/src/components/SortIndicator/SortIndicator.tsx b/src/components/SortIndicator/SortIndicator.tsx new file mode 100644 index 0000000..96f4374 --- /dev/null +++ b/src/components/SortIndicator/SortIndicator.tsx @@ -0,0 +1,25 @@ +import React from 'react'; + +import {Icon} from '@gravity-ui/uikit'; + +import {getSortIndicatorIcon} from '../../utils'; +import type {BaseSortIndicatorProps} from '../BaseSortIndicator'; + +import {b} from './SortIndicator.classname'; + +import './SortIndicator.scss'; + +export interface SortIndicatorProps extends BaseSortIndicatorProps {} + +export const SortIndicator = ({ + className, + header, +}: SortIndicatorProps) => { + const order = header.column.getIsSorted(); + + return ( + + + + ); +}; diff --git a/src/components/SortIndicator/index.ts b/src/components/SortIndicator/index.ts new file mode 100644 index 0000000..eb9ac95 --- /dev/null +++ b/src/components/SortIndicator/index.ts @@ -0,0 +1 @@ +export * from './SortIndicator'; diff --git a/src/components/Table/__stories__/Table.stories.tsx b/src/components/Table/__stories__/Table.stories.tsx index 3df50cd..34db219 100644 --- a/src/components/Table/__stories__/Table.stories.tsx +++ b/src/components/Table/__stories__/Table.stories.tsx @@ -6,6 +6,7 @@ import {DefaultStory} from './stories/DefaultStory'; import {ReorderingStory} from './stories/ReorderingStory'; import {ReorderingWithVirtualizationStory} from './stories/ReorderingWithVirtualizationStory'; import {SizeSStory} from './stories/SizeSStory'; +import {SortingStory} from './stories/SortingStory'; import {StickyHeaderStory} from './stories/StickyHeaderStory'; import {VirtualizationStory} from './stories/VirtualizationStory'; import {WindowVirtualizationStory} from './stories/WindowVirtualizationStory'; @@ -30,6 +31,10 @@ export const WithSelection: StoryObj = { render: WithSelectionStory, }; +export const Sorting: StoryObj = { + render: SortingStory, +}; + export const Reordering: StoryObj = { render: ReorderingStory, }; diff --git a/src/components/Table/__stories__/stories/SortingStory.classname.ts b/src/components/Table/__stories__/stories/SortingStory.classname.ts new file mode 100644 index 0000000..911eac8 --- /dev/null +++ b/src/components/Table/__stories__/stories/SortingStory.classname.ts @@ -0,0 +1,3 @@ +import {cn} from '../../../../utils'; + +export const cnSortingStory = cn('sorting-story'); diff --git a/src/components/Table/__stories__/stories/SortingStory.scss b/src/components/Table/__stories__/stories/SortingStory.scss new file mode 100644 index 0000000..be7a16d --- /dev/null +++ b/src/components/Table/__stories__/stories/SortingStory.scss @@ -0,0 +1,6 @@ +.sorting-story { + &__sort-indicator { + margin-inline-start: var(--g-spacing-1); + vertical-align: top; + } +} diff --git a/src/components/Table/__stories__/stories/SortingStory.tsx b/src/components/Table/__stories__/stories/SortingStory.tsx new file mode 100644 index 0000000..195b15d --- /dev/null +++ b/src/components/Table/__stories__/stories/SortingStory.tsx @@ -0,0 +1,37 @@ +import React from 'react'; + +import type {SortingState} from '@tanstack/react-table'; + +import {useTable} from '../../../../hooks'; +import {columns} from '../../../BaseTable/__stories__/constants/columns'; +import {data} from '../../../BaseTable/__stories__/constants/data'; +import {SortIndicator} from '../../../SortIndicator'; +import {Table} from '../../Table'; + +import {cnSortingStory} from './SortingStory.classname'; + +import './SortingStory.scss'; + +export const SortingStory = () => { + const [sorting, setSorting] = React.useState([]); + + const table = useTable({ + columns, + data, + enableSorting: true, + getRowId: (item) => item.id, + onSortingChange: setSorting, + state: { + sorting, + }, + }); + + return ( + } + sortIndicatorClassName={cnSortingStory('sort-indicator')} + /> + ); +}; diff --git a/src/utils/getSortIndicatorIcon.ts b/src/utils/getSortIndicatorIcon.ts new file mode 100644 index 0000000..ed27d95 --- /dev/null +++ b/src/utils/getSortIndicatorIcon.ts @@ -0,0 +1,18 @@ +import { + ArrowDown as ArrowDownIcon, + ArrowUpArrowDown as ArrowUpArrowDownIcon, + ArrowUp as ArrowUpIcon, +} from '@gravity-ui/icons'; +import type {SortDirection} from '@tanstack/react-table'; + +export const getSortIndicatorIcon = (sortDirection: SortDirection | false) => { + if (sortDirection === 'asc') { + return ArrowUpIcon; + } + + if (sortDirection === 'desc') { + return ArrowDownIcon; + } + + return ArrowUpArrowDownIcon; +}; diff --git a/src/utils/index.ts b/src/utils/index.ts index aa3d3f6..bfd3e34 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -7,6 +7,7 @@ export * from './getCellStyles'; export * from './getColumnPinningClassModes'; export * from './getHeaderCellAriaColIndex'; export * from './getHeaderCellClassModes'; +export * from './getSortIndicatorIcon'; export * from './getVirtualRowRangeExtractor'; export * from './shouldRenderFooterCell'; export * from './shouldRenderFooterRow';