Skip to content

Commit

Permalink
fix(table): fix multiple sort error (#1872)
Browse files Browse the repository at this point in the history
* fix(table): fix multiple sort error

* fix(link): hide text-decoration

* fix(drawer): add scrollbar

Co-authored-by: maxin <maxin@growingio.com>
  • Loading branch information
nnmax and maxin committed Mar 2, 2022
1 parent 472a6f8 commit c967085
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 26 deletions.
2 changes: 1 addition & 1 deletion src/drawer/style/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@
height: 100%;
margin-bottom: 20px;
padding: 0 36px;
overflow-y: auto;
.scrollbar();
color: @gray-5;
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/link/style/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@
&:active,
&:not(:focus-visible):focus {
color: @blue-3;
text-decoration: none;
outline: 0;
}
&:focus-visible {
color: @blue-3;
text-decoration: none;
outline: auto;
}

Expand Down
3 changes: 2 additions & 1 deletion src/table/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ function Table<RecordType>(props: TableProps<RecordType>, ref: React.ForwardedRe
const sortState = sortStates.find(({ key }) => key === columnKey);
const filterState = filterStates.find(({ key }) => key === columnKey);
let newColumn = column;
if (sortState || filterState || !isNil(column.info)) {
if (column.sorter || filterState || !isNil(column.info)) {
newColumn = {
...newColumn,
title: (
Expand All @@ -195,6 +195,7 @@ function Table<RecordType>(props: TableProps<RecordType>, ref: React.ForwardedRe
updateSorterStates={updateSorterStates}
updateFilterStates={updateFilterStates}
onTriggerStateUpdate={onTriggerStateUpdate}
columnKey={columnKey}
/>
),
};
Expand Down
39 changes: 24 additions & 15 deletions src/table/Title.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,42 +5,51 @@ import { isEmpty, isString, isUndefined } from 'lodash';
import Button from '../button';
import Tooltip from '../tooltip';
import FilterPopover from './FilterPopover';
import { Key, SortOrder, TitleProps } from './interface';
import { Key, SortOrder, SortState, TitleProps } from './interface';

const getNextSortDirection = (sortDirections: SortOrder[], current: SortOrder): SortOrder =>
current === null ? sortDirections[0] : sortDirections[sortDirections.indexOf(current) + 1];

const Title = <RecordType,>(props: TitleProps<RecordType>): React.ReactElement => {
const { prefixCls, column, onTriggerStateUpdate } = props;
const { prefixCls, column, onTriggerStateUpdate, sorterState, updateSorterStates, columnKey } = props;

const { align } = column;
const { align, sorter, sortDirections = ['ascend', 'descend', null], sortPriorityOrder } = column;

const renderSorter = (): React.ReactNode => {
const { sorterState, updateSorterStates } = props;
if (isUndefined(sorterState)) {
return null;
}
const { sortDirections = ['ascend', 'descend', null] } = column;
const { sortOrder: sorterOrder } = sorterState;
const { sortOrder } = sorterState ?? {};

if (!sorter) return null;

const handleSorterChange = (): void => {
const changedSorterState = {
...sorterState,
sortOrder: getNextSortDirection(sortDirections, sorterOrder ?? null),
};
const nextSortOrder = getNextSortDirection(sortDirections, sortOrder ?? null);
const changedSorterState: SortState<RecordType> = sorterState
? {
...sorterState,
sortOrder: nextSortOrder,
}
: {
sortOrder: nextSortOrder,
column,
isControlled: 'sortOrder' in column,
key: columnKey,
sortDirections,
sortPriorityOrder,
};

onTriggerStateUpdate({ sorterState: updateSorterStates(changedSorterState) });
};

return (
<Button.IconButton className={`${prefixCls}-sorter-button`} type="text" size="small" onClick={handleSorterChange}>
<>
<UpFilled
className={classNames(`${prefixCls}-sorter-button-up`, {
active: sorterOrder === 'ascend',
active: sortOrder === 'ascend',
})}
/>
<DownFilled
className={classNames(`${prefixCls}-sorter-button-down`, {
active: sorterOrder === 'descend',
active: sortOrder === 'descend',
})}
/>
</>
Expand Down
79 changes: 77 additions & 2 deletions src/table/demos/Table.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ export const Sortable = () => {
dataIndex: 'age',
title: 'Age',
// sortDirections: ['descend'],
sorter: (first, second) => second.age - first.age,
sorter: (first, second) => first.age - second.age,
},
{
dataIndex: 'address',
Expand All @@ -233,6 +233,81 @@ export const Sortable = () => {

// ----------------------- Sortable -----------------------//

// ----------------------- Multiple Sortable -----------------------//

export const MultipleSortable = () => {
const columns: ColumnsType<DataSourceType> = [
{
dataIndex: 'id',
title: 'Id',
},
{
dataIndex: 'name',
title: 'Name',
sortPriorityOrder: 1,
sorter: (first, second) => {
if (first.name < second.name) return -1;
if (first.name > second.name) return 1;
return 0;
},
},
{
dataIndex: 'age',
title: 'Age',
sortPriorityOrder: 2,
sorter: (first, second) => first.age - second.age,
},
{
dataIndex: 'address',
title: 'Address',
},
];

const data: DataSourceType[] = [
{
id: '1',
name: 'John Brown',
age: 11,
address: '北京市朝阳公园',
},
{
id: '2',
name: 'Jim Green',
age: 22,
address: '北京市朝阳公园',
},
{
id: '3',
name: 'Joe Black',
age: 33,
address: '北京市朝阳公园',
},
{
id: '4',
name: 'Jim Red',
age: 33,
address: '北京市朝阳公园',
},
{
id: '5',
name: 'Jim Red',
age: 55,
address: '北京市朝阳公园',
},
];
return (
<>
{' '}
<h4>多列排序</h4>
<p>`column` 支持 `sortPriorityOrder` 字段以配置多列排序优先级</p>
<Divider style={{ width: '100%' }} />
<Table<DataSourceType> pagination={false} dataSource={data} columns={columns} rowKey="id" />
</>
);
};

// ----------------------- Multiple Sortable -----------------------//

// ----------------------- Controlled Sortable -----------------------//

export const ControlledSortable = () => {
Expand Down Expand Up @@ -277,7 +352,7 @@ export const ControlledSortable = () => {
info: '您可以通过设置 `sortDirections: ["ascend", "descend", "ascend"]` 来禁止排序恢复到默认状态',
sortDirections: ['ascend', 'descend', 'ascend'],
sortOrder: sortedInfo.columnKey === 'age' ? sortedInfo.sortOrder : undefined,
sorter: (first, second) => second.age - first.age,
sorter: (first, second) => first.age - second.age,
},
{
dataIndex: 'address',
Expand Down
8 changes: 8 additions & 0 deletions src/table/demos/TablePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ export default function TablePage() {
<Canvas>
<Story id="upgraded-table--sortable" />
</Canvas>
<Subheading>Multiple Sortable</Subheading>
<Canvas>
<Story id="upgraded-table--multiple-sortable" />
</Canvas>
<Subheading>Controlled Sortable</Subheading>
<Canvas>
<Story id="upgraded-table--controlled-sortable" />
</Canvas>
<Subheading>{formatMessage({ defaultMessage: 'spanningtable' })}</Subheading>
<Canvas>
<Story id="upgraded-table--spanning-table" />
Expand Down
18 changes: 12 additions & 6 deletions src/table/hook/useSorter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const collectSortStates = <RecordType,>(
let sortStates: SortState<RecordType>[] = [];

const push = (column: ColumnsType<RecordType>[number], key: React.Key, state?: Partial<SortState<RecordType>>) => {
const { sortPriorityOrder = 0, sortDirections = ['ascend', 'descend', null], sortOrder } = column;
const { sortPriorityOrder, sortDirections = ['ascend', 'descend', null], sortOrder } = column;
sortStates.push({
column,
key,
Expand All @@ -39,7 +39,7 @@ const collectSortStates = <RecordType,>(
} else if ('sorter' in column) {
if ('sortOrder' in column) {
push(column, columnKey);
} else if (init) {
} else if (init && defaultSortOrder) {
push(column, columnKey, {
sortOrder: defaultSortOrder,
isControlled: false,
Expand Down Expand Up @@ -112,9 +112,11 @@ const useSorter = <RecordType,>(
const updateSorterStates = useCallback(
(incomingSortState: SortState<RecordType>) => {
setSorter(incomingSortState);
setSortStates((oldSortStates) =>
oldSortStates.map((_sortState) => {
setSortStates((oldSortStates) => {
const keys: React.Key[] = [];
const states = oldSortStates.map((_sortState) => {
const innerSortState = _sortState;
keys.push(innerSortState.key);
// if update column haven't sortPriorityOrder, clear all active sortOrder state.
// if update column haven sortPriorityOrder, only update sortOrder which column haven't sortPriorityOrder.
if (
Expand All @@ -130,8 +132,12 @@ const useSorter = <RecordType,>(
innerSortState.sortOrder = incomingSortState.sortOrder;
}
return innerSortState;
})
);
});
if (keys.indexOf(incomingSortState.key) === -1) {
return [...states, incomingSortState];
}
return states;
});
if (isFunction(onChange)) {
onChange(incomingSortState);
}
Expand Down
2 changes: 1 addition & 1 deletion src/table/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ interface ColumnType<RecordType> extends GioColumnType<RecordType> {

/**
* 排序优先级,数值越大越靠前
* @default 0
*/
sortPriorityOrder?: number;

Expand Down Expand Up @@ -112,6 +111,7 @@ interface TitleProps<RecordType> {
updateSorterStates: (sortState: SortState<RecordType>) => SortState<RecordType>;
updateFilterStates: (filterState: FilterState<RecordType>) => Record<string, string[]>;
onTriggerStateUpdate: (onTriggerStateUpdateProps?: OnTriggerStateUpdateProps<RecordType>) => void;
columnKey: Key;
}

interface RowSelection<RecordType> {
Expand Down

1 comment on commit c967085

@vercel
Copy link

@vercel vercel bot commented on c967085 Mar 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.