From 8aca325d999e509d4358db7dcaa4cd7a6088f3f4 Mon Sep 17 00:00:00 2001 From: dyecma <38642322+sawadyecma@users.noreply.github.com> Date: Mon, 22 May 2023 13:03:57 +0900 Subject: [PATCH] feat: implement sortIcon on Table (#42498) * implement sortIcon on Table * drop React.ReactNode from sortIcon * add sortIcon test * fix sortIcon arg type * add sortIcon to docs --------- Co-authored-by: afc163 --- .../table/__tests__/Table.sorter.test.tsx | 33 +++++++++++ .../__snapshots__/Table.sorter.test.tsx.snap | 24 ++++++++ components/table/hooks/useSorter.tsx | 58 +++++++++++-------- components/table/index.en-US.md | 1 + components/table/index.zh-CN.md | 1 + components/table/interface.ts | 9 +-- 6 files changed, 98 insertions(+), 28 deletions(-) diff --git a/components/table/__tests__/Table.sorter.test.tsx b/components/table/__tests__/Table.sorter.test.tsx index e500b76e93..7ade9a64c8 100644 --- a/components/table/__tests__/Table.sorter.test.tsx +++ b/components/table/__tests__/Table.sorter.test.tsx @@ -355,6 +355,39 @@ describe('Table.sorter', () => { expect(container.querySelector('.ant-tooltip-open')).toBeFalsy(); }); + it('renders custome sort icon correctly', () => { + const sortIcon = ({ sorterOrder }: { sorterOrder?: SortOrder }): React.ReactNode => { + let text: string; + if (sorterOrder === undefined) { + text = 'unsorted'; + } else if (sorterOrder === 'descend') { + text = 'sortDescend'; + } else { + text = 'sortAscend'; + } + + return {text}; + }; + + const { container } = render( + createTable({ + columns: [ + { + ...column, + sortIcon, + }, + ], + }), + ); + + fireEvent.click(container.querySelector('.customize-icon')!); + expect(container.querySelector('.customize-icon')).toMatchSnapshot(); + fireEvent.click(container.querySelector('.customize-icon')!); + expect(container.querySelector('.customize-icon')).toMatchSnapshot(); + fireEvent.click(container.querySelector('.customize-icon')!); + expect(container.querySelector('.customize-icon')).toMatchSnapshot(); + }); + it('works with grouping columns in controlled mode', () => { const columns = [ { diff --git a/components/table/__tests__/__snapshots__/Table.sorter.test.tsx.snap b/components/table/__tests__/__snapshots__/Table.sorter.test.tsx.snap index b283bcd7d7..0a520e33a2 100644 --- a/components/table/__tests__/__snapshots__/Table.sorter.test.tsx.snap +++ b/components/table/__tests__/__snapshots__/Table.sorter.test.tsx.snap @@ -1,5 +1,29 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Table.sorter renders custome sort icon correctly 1`] = ` + + sortAscend + +`; + +exports[`Table.sorter renders custome sort icon correctly 2`] = ` + + sortDescend + +`; + +exports[`Table.sorter renders custome sort icon correctly 3`] = ` + + unsorted + +`; + exports[`Table.sorter renders sorter icon correctly 1`] = ` ( const sorterState = sorterStates.find(({ key }) => key === columnKey); const sorterOrder = sorterState ? sorterState.sortOrder : null; const nextSortOrder = nextSortDirection(sortDirections, sorterOrder); - const upNode: React.ReactNode = sortDirections.includes(ASCEND) && ( - - ); - const downNode: React.ReactNode = sortDirections.includes(DESCEND) && ( - - ); + + let sorter: React.ReactNode; + if (column.sortIcon) { + sorter = column.sortIcon({ sorterOrder }); + } else { + const upNode: React.ReactNode = sortDirections.includes(ASCEND) && ( + + ); + const downNode: React.ReactNode = sortDirections.includes(DESCEND) && ( + + ); + sorter = ( + + + + ); + } + const { cancelSort, triggerAsc, triggerDesc } = tableLocale || {}; let sortTip: string | undefined = cancelSort; if (nextSortOrder === DESCEND) { @@ -159,16 +178,7 @@ function injectSorter( {renderColumnTitle(column.title, renderProps)} - - - + {sorter} ); return showSorterTooltip ? ( diff --git a/components/table/index.en-US.md b/components/table/index.en-US.md index 2d1d9526c0..8e5cb90ad8 100644 --- a/components/table/index.en-US.md +++ b/components/table/index.en-US.md @@ -194,6 +194,7 @@ One of the Table `columns` prop for describing the table's columns, Column has t | sortDirections | Supported sort way, override `sortDirections` in `Table`, could be `ascend`, `descend` | Array | \[`ascend`, `descend`] | | | sorter | Sort function for local sort, see [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)'s compareFunction. If you need sort buttons only, set to `true` | function \| boolean | - | | | sortOrder | Order of sorted values: `ascend` `descend` `null` | `ascend` \| `descend` \| null | - | | +| sortIcon | Customized sort icon | (props: { sorterOrder }) => ReactNode | - | | | title | Title of this column | ReactNode \| ({ sortOrder, sortColumn, filters }) => ReactNode | - | | | width | Width of this column ([width not working?](https://github.com/ant-design/ant-design/issues/13825#issuecomment-449889241)) | string \| number | - | | | onCell | Set props on per cell | function(record, rowIndex) | - | | diff --git a/components/table/index.zh-CN.md b/components/table/index.zh-CN.md index 5aeead393c..45258977d4 100644 --- a/components/table/index.zh-CN.md +++ b/components/table/index.zh-CN.md @@ -196,6 +196,7 @@ const columns = [ | sortDirections | 支持的排序方式,覆盖 `Table` 中 `sortDirections`, 取值为 `ascend` `descend` | Array | \[`ascend`, `descend`] | | | sorter | 排序函数,本地排序使用一个函数(参考 [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) 的 compareFunction),需要服务端排序可设为 true | function \| boolean | - | | | sortOrder | 排序的受控属性,外界可用此控制列的排序,可设置为 `ascend` `descend` `null` | `ascend` \| `descend` \| null | - | | +| sortIcon | 自定义 sort 图标。 | (props: { sorterOrder }) => ReactNode | - | | | title | 列头显示文字(函数用法 `3.10.0` 后支持) | ReactNode \| ({ sortOrder, sortColumn, filters }) => ReactNode | - | | | width | 列宽度([指定了也不生效?](https://github.com/ant-design/ant-design/issues/13825#issuecomment-449889241)) | string \| number | - | | | onCell | 设置单元格属性 | function(record, rowIndex) | - | | diff --git a/components/table/interface.ts b/components/table/interface.ts index 1d73a8f384..f09125f702 100644 --- a/components/table/interface.ts +++ b/components/table/interface.ts @@ -1,17 +1,17 @@ import type { - ColumnType as RcColumnType, FixedType, GetComponentProps, + ColumnType as RcColumnType, RenderedCell as RcRenderedCell, } from 'rc-table/lib/interface'; import { ExpandableConfig, GetRowKey } from 'rc-table/lib/interface'; import type * as React from 'react'; +import type { Breakpoint } from '../_util/responsiveObserver'; import type { CheckboxProps } from '../checkbox'; import type { PaginationProps } from '../pagination'; import type { TooltipProps } from '../tooltip'; -import type { Breakpoint } from '../_util/responsiveObserver'; -import type { INTERNAL_SELECTION_ITEM } from './hooks/useSelection'; import type { InternalTableProps, TableProps } from './InternalTable'; +import type { INTERNAL_SELECTION_ITEM } from './hooks/useSelection'; export type RefTable = ( props: React.PropsWithChildren> & { ref?: React.Ref }, @@ -56,7 +56,7 @@ export interface TableLocale { export type SortOrder = 'descend' | 'ascend' | null; const TableActions = ['paginate', 'sort', 'filter'] as const; -export type TableAction = typeof TableActions[number]; +export type TableAction = (typeof TableActions)[number]; export type CompareFn = (a: T, b: T, sortOrder?: SortOrder) => number; @@ -119,6 +119,7 @@ export interface ColumnType extends Omit, ' sortOrder?: SortOrder; defaultSortOrder?: SortOrder; sortDirections?: SortOrder[]; + sortIcon?: (props: { sorterOrder: SortOrder }) => React.ReactNode; showSorterTooltip?: boolean | TooltipProps; // Filter