diff --git a/src/components/BaseHeaderCell/BaseHeaderCell.tsx b/src/components/BaseHeaderCell/BaseHeaderCell.tsx index 14c3259..21d7f60 100644 --- a/src/components/BaseHeaderCell/BaseHeaderCell.tsx +++ b/src/components/BaseHeaderCell/BaseHeaderCell.tsx @@ -8,6 +8,7 @@ import { getCellStyles, getHeaderCellAriaColIndex, getHeaderCellClassModes, + getKeyDownToggleSortingHandler, } from '../../utils'; import type {BaseResizeHandleProps} from '../BaseResizeHandle'; import {BaseResizeHandle} from '../BaseResizeHandle'; @@ -24,6 +25,7 @@ export interface BaseHeaderCellProps { renderResizeHandle?: (props: BaseResizeHandleProps) => React.ReactNode; renderSortIndicator?: (props: BaseSortIndicatorProps) => React.ReactNode; resizeHandleClassName?: string; + sortClassName?: string; sortIndicatorClassName?: string; attributes?: | React.ThHTMLAttributes @@ -40,6 +42,7 @@ export const BaseHeaderCell = ({ renderResizeHandle, renderSortIndicator, resizeHandleClassName, + sortClassName, sortIndicatorClassName, attributes: attributesProp, }: BaseHeaderCellProps) => { @@ -58,25 +61,35 @@ export const BaseHeaderCell = ({ className={b('header-cell', getHeaderCellClassModes(header), className)} colSpan={header.colSpan > 1 ? header.colSpan : undefined} rowSpan={rowSpan > 1 ? rowSpan : undefined} - onClick={header.column.getToggleSortingHandler()} aria-sort={getAriaSort(header.column.getIsSorted())} aria-colindex={getHeaderCellAriaColIndex(header)} {...attributes} style={getCellStyles(header, attributes?.style)} > - {flexRender(header.column.columnDef.header, header.getContext())}{' '} - {header.column.getCanSort() && - (renderSortIndicator ? ( - renderSortIndicator({ - className: b('sort-indicator', sortIndicatorClassName), - header, - }) - ) : ( - - ))} + {header.column.getCanSort() ? ( + + {flexRender(header.column.columnDef.header, header.getContext())}{' '} + {renderSortIndicator ? ( + renderSortIndicator({ + className: b('sort-indicator', sortIndicatorClassName), + header, + }) + ) : ( + + )} + + ) : ( + flexRender(header.column.columnDef.header, header.getContext()) + )} {header.column.getCanResize() && (renderResizeHandle ? ( renderResizeHandle({ diff --git a/src/components/BaseHeaderRow/BaseHeaderRow.tsx b/src/components/BaseHeaderRow/BaseHeaderRow.tsx index 7cb5c7b..8ac8395 100644 --- a/src/components/BaseHeaderRow/BaseHeaderRow.tsx +++ b/src/components/BaseHeaderRow/BaseHeaderRow.tsx @@ -19,6 +19,7 @@ export interface BaseHeaderRowProps renderResizeHandle?: (props: BaseResizeHandleProps) => React.ReactNode; renderSortIndicator: BaseHeaderCellProps['renderSortIndicator']; resizeHandleClassName?: BaseHeaderCellProps['resizeHandleClassName']; + sortClassName: BaseHeaderCellProps['sortClassName']; sortIndicatorClassName: BaseHeaderCellProps['sortIndicatorClassName']; attributes?: | React.HTMLAttributes @@ -37,6 +38,7 @@ export const BaseHeaderRow = ({ renderResizeHandle, renderSortIndicator, resizeHandleClassName, + sortClassName, sortIndicatorClassName, attributes: attributesProp, cellAttributes, @@ -68,6 +70,7 @@ export const BaseHeaderRow = ({ renderResizeHandle={renderResizeHandle} renderSortIndicator={renderSortIndicator} resizeHandleClassName={resizeHandleClassName} + sortClassName={sortClassName} sortIndicatorClassName={sortIndicatorClassName} attributes={cellAttributes} /> diff --git a/src/components/BaseSortIndicator/BaseSortIndicator.scss b/src/components/BaseSortIndicator/BaseSortIndicator.scss index 4630bd8..178854f 100644 --- a/src/components/BaseSortIndicator/BaseSortIndicator.scss +++ b/src/components/BaseSortIndicator/BaseSortIndicator.scss @@ -6,7 +6,6 @@ $blockTable: '.#{variables.$ns}table'; #{$block} { display: inline-flex; margin-inline-start: 4px; - vertical-align: middle; transform: rotate(0); color: var(--g-color-text-hint); diff --git a/src/components/BaseTable/BaseTable.scss b/src/components/BaseTable/BaseTable.scss index 17ed209..76b9f6d 100644 --- a/src/components/BaseTable/BaseTable.scss +++ b/src/components/BaseTable/BaseTable.scss @@ -41,11 +41,11 @@ $block: '.#{variables.$ns}table'; font-weight: 500; } - &__header-cell { - &_sortable { - cursor: pointer; - user-select: none; - } + &__sort { + display: inline-flex; + align-items: center; + cursor: pointer; + user-select: none; } &__cell, diff --git a/src/components/BaseTable/BaseTable.tsx b/src/components/BaseTable/BaseTable.tsx index 48b7966..df1a6dd 100644 --- a/src/components/BaseTable/BaseTable.tsx +++ b/src/components/BaseTable/BaseTable.tsx @@ -91,6 +91,8 @@ export interface BaseTableProps['className']; /** The row virtualizer instance returned from `useRowVirtualizer` or `useWindowRowVirtualizer` hooks */ rowVirtualizer?: Virtualizer; + /** CSS classes for the sort content wrapper inside `` elements */ + sortClassName?: BaseHeaderRowProps['sortClassName']; /** CSS classes for the sort indicator inside `` elements */ sortIndicatorClassName?: BaseHeaderRowProps['sortIndicatorClassName']; /** Makes the `` element sticky */ @@ -137,6 +139,7 @@ export const BaseTable = React.forwardRef( rowAttributes, rowClassName, rowVirtualizer, + sortClassName, sortIndicatorClassName, stickyFooter = false, stickyHeader = false, @@ -243,6 +246,7 @@ export const BaseTable = React.forwardRef( renderResizeHandle={renderResizeHandle} renderSortIndicator={renderSortIndicator} resizeHandleClassName={resizeHandleClassName} + sortClassName={sortClassName} sortIndicatorClassName={sortIndicatorClassName} attributes={headerRowAttributes} cellAttributes={headerCellAttributes} 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..8ea2da9 --- /dev/null +++ b/src/components/SortIndicator/SortIndicator.tsx @@ -0,0 +1,41 @@ +import React from 'react'; + +import { + ArrowDown as ArrowDownIcon, + ArrowUpArrowDown as ArrowUpArrowDownIcon, + ArrowUp as ArrowUpIcon, +} from '@gravity-ui/icons'; +import {Icon} from '@gravity-ui/uikit'; + +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(); + + let icon; + switch (order) { + case 'asc': + icon = ArrowUpIcon; + break; + case 'desc': + icon = ArrowDownIcon; + break; + default: + icon = ArrowUpArrowDownIcon; + } + + 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/Table.scss b/src/components/Table/Table.scss index 27de484..1e7b4a1 100644 --- a/src/components/Table/Table.scss +++ b/src/components/Table/Table.scss @@ -16,6 +16,15 @@ $block: '.#{variables.$ns}styled-table'; @include mixins.text-subheader-1(); } + &__sort { + gap: var(--g-spacing-1); + border-radius: var(--g-border-radius-xs); + + &:focus-visible { + outline: 2px solid var(--g-color-line-focus); + } + } + &__cell, &__header-cell, &__footer-cell { diff --git a/src/components/Table/Table.tsx b/src/components/Table/Table.tsx index f16092d..fa7086a 100644 --- a/src/components/Table/Table.tsx +++ b/src/components/Table/Table.tsx @@ -2,6 +2,7 @@ import React from 'react'; import {BaseTable} from '../BaseTable'; import type {BaseTableProps} from '../BaseTable'; +import {SortIndicator} from '../SortIndicator'; import {b} from './Table.classname'; @@ -18,6 +19,8 @@ export const Table = React.forwardRef( footerCellClassName: footerCellClassNameProp, headerCellClassName: headerCellClassNameProp, headerClassName, + renderSortIndicator: renderSortIndicatorProp, + sortClassName, ...props }: TableProps, ref: React.Ref, @@ -46,6 +49,18 @@ export const Table = React.forwardRef( return b('footer-cell', footerCellClassNameProp); }, [footerCellClassNameProp]); + const renderSortIndicator = React.useCallback< + NonNullable['renderSortIndicator']> + >( + (sortIndicatorProps) => { + if (renderSortIndicatorProp) { + return renderSortIndicatorProp(sortIndicatorProps); + } + return ; + }, + [renderSortIndicatorProp], + ); + return ( ); diff --git a/src/components/Table/__stories__/Table.stories.tsx b/src/components/Table/__stories__/Table.stories.tsx index 173c78f..69058cd 100644 --- a/src/components/Table/__stories__/Table.stories.tsx +++ b/src/components/Table/__stories__/Table.stories.tsx @@ -5,6 +5,7 @@ import {Table} from '../index'; import {DefaultStory} from './stories/DefaultStory'; import {ReorderingStory} from './stories/ReorderingStory'; import {ReorderingWithVirtualizationStory} from './stories/ReorderingWithVirtualizationStory'; +import {SortingStory} from './stories/SortingStory'; import {StickyHeaderStory} from './stories/StickyHeaderStory'; import {VirtualizationStory} from './stories/VirtualizationStory'; import {WindowVirtualizationStory} from './stories/WindowVirtualizationStory'; @@ -25,6 +26,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.tsx b/src/components/Table/__stories__/stories/SortingStory.tsx new file mode 100644 index 0000000..16f12f2 --- /dev/null +++ b/src/components/Table/__stories__/stories/SortingStory.tsx @@ -0,0 +1,25 @@ +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 {Table} from '../../Table'; + +export const SortingStory = () => { + const [sorting, setSorting] = React.useState([]); + + const table = useTable({ + columns, + data, + enableSorting: true, + getRowId: (item) => item.id, + onSortingChange: setSorting, + state: { + sorting, + }, + }); + + return ; +}; diff --git a/src/constants/index.ts b/src/constants/index.ts index ccfbf49..ad8d557 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -1,2 +1,3 @@ export * from './dragHandleColumn'; +export * from './keyCode'; export * from './selectionColumn'; diff --git a/src/constants/keyCode.ts b/src/constants/keyCode.ts new file mode 100644 index 0000000..64edc70 --- /dev/null +++ b/src/constants/keyCode.ts @@ -0,0 +1,6 @@ +export const keyCode = { + ENTER: 'Enter', + // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values#whitespace_keys + SPACEBAR: ' ', + SPACEBAR_OLD: 'Spacebar', +}; diff --git a/src/utils/getKeyDownToggleSortingHandler.ts b/src/utils/getKeyDownToggleSortingHandler.ts new file mode 100644 index 0000000..a5d3b2a --- /dev/null +++ b/src/utils/getKeyDownToggleSortingHandler.ts @@ -0,0 +1,15 @@ +import type React from 'react'; + +import type {Header} from '@tanstack/react-table'; + +import {keyCode} from '../constants'; + +export const getKeyDownToggleSortingHandler = (header: Header) => { + return (event: React.KeyboardEvent) => { + if ([keyCode.ENTER, keyCode.SPACEBAR, keyCode.SPACEBAR_OLD].includes(event.key)) { + event.preventDefault(); + + header.column.toggleSorting(); + } + }; +}; diff --git a/src/utils/index.ts b/src/utils/index.ts index aa3d3f6..c9feefa 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 './getKeyDownToggleSortingHandler'; export * from './getVirtualRowRangeExtractor'; export * from './shouldRenderFooterCell'; export * from './shouldRenderFooterRow';