feat(table): Add defaultFilteredValues to table columns (#20088)

This commit is contained in:
Olivier Louvignes 2019-12-11 08:15:23 +01:00 committed by 二货机器人
parent 05c2f92b69
commit 3ef0a402b5
5 changed files with 81 additions and 31 deletions

View File

@ -20,10 +20,7 @@ describe('Table.filter', () => {
{
text: 'Title',
value: 'title',
children: [
{ text: 'Designer', value: 'designer' },
{ text: 'Coder', value: 'coder' },
],
children: [{ text: 'Designer', value: 'designer' }, { text: 'Coder', value: 'coder' }],
},
],
onFilter: filterFn,
@ -310,6 +307,58 @@ describe('Table.filter', () => {
expect(wrapper.find('tbody tr').length).toBe(4);
});
it('can read defaults from defaultFilteredValue', () => {
const wrapper = mount(
createTable({
columns: [
{
...column,
defaultFilteredValue: ['Lucy'],
},
],
}),
);
expect(wrapper.find('tbody tr').length).toBe(1);
expect(wrapper.find('tbody tr').text()).toBe('Lucy');
// Should properly ignore further defaultFilteredValue changes
wrapper.setProps({
columns: [
{
...column,
defaultFilteredValue: [],
},
],
});
expect(wrapper.find('tbody tr').length).toBe(1);
expect(wrapper.find('tbody tr').text()).toBe('Lucy');
// Should properly be overidden by non-null filteredValue
wrapper.setProps({
columns: [
{
...column,
defaultFilteredValue: ['Lucy'],
filteredValue: ['Tom'],
},
],
});
expect(wrapper.find('tbody tr').length).toBe(1);
expect(wrapper.find('tbody tr').text()).toBe('Tom');
// Should properly be overidden by a null filteredValue
wrapper.setProps({
columns: [
{
...column,
defaultFilteredValue: ['Lucy'],
filteredValue: null,
},
],
});
expect(wrapper.find('tbody tr').length).toBe(4);
});
it('fires change event', () => {
const handleChange = jest.fn();
const wrapper = mount(createTable({ onChange: handleChange }));
@ -418,10 +467,7 @@ describe('Table.filter', () => {
// });
describe('should support value types', () => {
[
['Light', 93],
['Bamboo', false],
].forEach(([text, value]) => {
[['Light', 93], ['Bamboo', false]].forEach(([text, value]) => {
it(`${typeof value} type`, () => {
const onFilter = jest.fn();
const filters = [{ text, value }];
@ -505,10 +551,7 @@ describe('Table.filter', () => {
title="name"
dataIndex="name"
key="name"
filters={[
{ text: 'Jack', value: 'Jack' },
{ text: 'Lucy', value: 'Lucy' },
]}
filters={[{ text: 'Jack', value: 'Jack' }, { text: 'Lucy', value: 'Lucy' }]}
filteredValue={filters.name}
onFilter={filterFn}
/>
@ -547,10 +590,7 @@ describe('Table.filter', () => {
title: 'Name',
dataIndex: 'name',
key: 'name',
filters: [
{ text: 'Jack', value: 'Jack' },
{ text: 'Lucy', value: 'Lucy' },
],
filters: [{ text: 'Jack', value: 'Jack' }, { text: 'Lucy', value: 'Lucy' }],
onFilter: filterFn,
filteredValue: ['Jack'],
},
@ -580,10 +620,7 @@ describe('Table.filter', () => {
columns: [
{
...column,
filters: [
{ text: 'Jack', value: 'Jack' },
{ text: 'Lucy', value: 'Lucy' },
],
filters: [{ text: 'Jack', value: 'Jack' }, { text: 'Lucy', value: 'Lucy' }],
},
],
onChange: handleChange,

View File

@ -22,6 +22,7 @@ export interface FilterState<RecordType> {
function collectFilterStates<RecordType>(
columns: ColumnsType<RecordType>,
init: boolean,
pos?: string,
): FilterState<RecordType>[] {
let filterStates: FilterState<RecordType>[] = [];
@ -30,14 +31,24 @@ function collectFilterStates<RecordType>(
const columnPos = getColumnPos(index, pos);
if ('children' in column) {
filterStates = [...filterStates, ...collectFilterStates(column.children, columnPos)];
filterStates = [...filterStates, ...collectFilterStates(column.children, init, columnPos)];
} else if ('filters' in column || 'filterDropdown' in column) {
// Controlled
filterStates.push({
column,
key: getColumnKey(column, columnPos),
filteredKeys: column.filteredValue,
});
if ('filteredValue' in column) {
// Controlled
filterStates.push({
column,
key: getColumnKey(column, columnPos),
filteredKeys: column.filteredValue,
});
} else {
// Uncontrolled
filterStates.push({
column,
key: getColumnKey(column, columnPos),
filteredKeys:
init && column.defaultFilteredValue ? column.defaultFilteredValue! : undefined,
});
}
}
});
@ -172,11 +183,11 @@ function useFilter<RecordType>({
const tableLocale = (locale.Table || {}) as TableLocale;
const [filterStates, setFilterStates] = React.useState<FilterState<RecordType>[]>(
collectFilterStates(columns),
collectFilterStates(columns, true),
);
const mergedFilterStates = React.useMemo(() => {
const collectedStates = collectFilterStates(columns);
const collectedStates = collectFilterStates(columns, false);
// Return if not controlled
if (collectedStates.every(({ filteredKeys }) => filteredKeys === undefined)) {

View File

@ -116,6 +116,7 @@ One of the Table `columns` prop for describing the table's columns, Column has t
| className | className of this column | string | - |
| colSpan | Span of this column's title | number | - |
| dataIndex | Display field of the data record, support nest path by string array | string \| string\[] | - |
| defaultFilteredValue | Default filtered values | string\[] | - | |
| defaultSortOrder | Default order of sorted values | 'ascend' \| 'descend' | - |
| filterDropdown | Customized filter overlay | React.ReactNode \| (props: [FilterDropdownProps](https://git.io/fjP5h)) => React.ReactNode | - |
| filterDropdownVisible | Whether `filterDropdown` is visible | boolean | - |

View File

@ -121,6 +121,7 @@ const columns = [
| className | 列样式类名 | string | - |
| colSpan | 表头列合并,设置为 0 时,不渲染 | number | - |
| dataIndex | 列数据在数据项中对应的路径,支持通过数组查询嵌套路径 | string \| string\[] | - |
| defaultFilteredValue | 默认筛选值 | string\[] | - | |
| defaultSortOrder | 默认排序顺序 | 'ascend' \| 'descend' | - |
| filterDropdown | 可以自定义筛选菜单,此函数只负责渲染图层,需要自行编写各种交互 | React.ReactNode \| (props: [FilterDropdownProps](https://git.io/fjP5h)) => React.ReactNode | - |
| filterDropdownVisible | 用于控制自定义筛选菜单是否可见 | boolean | - |

View File

@ -83,6 +83,7 @@ export interface ColumnType<RecordType> extends RcColumnType<RecordType> {
filterDropdown?: React.ReactNode | ((props: FilterDropdownProps) => React.ReactNode);
filterMultiple?: boolean;
filteredValue?: Key[] | null;
defaultFilteredValue?: Key[] | null;
filterIcon?: React.ReactNode | ((filtered: boolean) => React.ReactNode);
onFilter?: (value: any, record: RecordType) => boolean;
filterDropdownVisible?: boolean;
@ -95,8 +96,7 @@ export interface ColumnGroupType<RecordType> extends ColumnType<RecordType> {
export type ColumnsType<RecordType = unknown> = (
| ColumnGroupType<RecordType>
| ColumnType<RecordType>
)[];
| ColumnType<RecordType>)[];
export interface SelectionItem {
key: string;