Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for ReadonlyArray in table #29080

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion components/table/ColumnGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ColumnProps } from './Column';
export interface ColumnGroupProps<RecordType> extends Omit<ColumnType<RecordType>, 'children'> {
children:
| React.ReactElement<ColumnProps<RecordType>>
| React.ReactElement<ColumnProps<RecordType>>[];
| readonly React.ReactElement<ColumnProps<RecordType>>[];
}

/* istanbul ignore next */
Expand Down
25 changes: 15 additions & 10 deletions components/table/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@ interface ChangeEventInfo<RecordType> {
pageSize?: number;
total?: number;
};
filters: Record<string, (Key | boolean)[] | null>;
sorter: SorterResult<RecordType> | SorterResult<RecordType>[];
filters: Record<string, readonly (Key | boolean)[] | null>;
sorter: SorterResult<RecordType> | readonly SorterResult<RecordType>[];

filterStates: FilterState<RecordType>[];
sorterStates: SortState<RecordType>[];
filterStates: readonly FilterState<RecordType>[];
sorterStates: readonly SortState<RecordType>[];

resetPagination: Function;
}
Expand All @@ -84,8 +84,8 @@ export interface TableProps<RecordType>

onChange?: (
pagination: TablePaginationConfig,
filters: Record<string, (Key | boolean)[] | null>,
sorter: SorterResult<RecordType> | SorterResult<RecordType>[],
filters: Record<string, readonly (Key | boolean)[] | null>,
sorter: SorterResult<RecordType> | readonly SorterResult<RecordType>[],
extra: TableCurrentDataSource<RecordType>,
) => void;
rowSelection?: TableRowSelection<RecordType>;
Expand All @@ -94,7 +94,7 @@ export interface TableProps<RecordType>
scroll?: RcTableProps<RecordType>['scroll'] & {
scrollToFirstRowOnChange?: boolean;
};
sortDirections?: SortOrder[];
sortDirections?: readonly SortOrder[];
showSorterTooltip?: boolean;
}

Expand Down Expand Up @@ -152,7 +152,7 @@ function Table<RecordType extends object = any>(props: TableProps<RecordType>) {
);
const mergedSize = customizeSize || size;
const tableLocale = { ...contextLocale.Table, ...locale } as TableLocale;
const rawData: RecordType[] = dataSource || EMPTY_LIST;
const rawData: readonly RecordType[] = dataSource || EMPTY_LIST;

const { getPrefixCls } = React.useContext(ConfigContext);
const prefixCls = getPrefixCls('table', customizePrefixCls);
Expand Down Expand Up @@ -236,7 +236,12 @@ function Table<RecordType extends object = any>(props: TableProps<RecordType>) {
}
};

/** Controlled state in `columns` is not a good idea that makes too many code (1000+ line?) to read state out and then put it back to title render. Move these code into `hooks` but still too complex. We should provides Table props like `sorter` & `filter` to handle control in next big version. */
/**
* Controlled state in `columns` is not a good idea that makes too many code (1000+ line?) to
* read state out and then put it back to title render. Move these code into `hooks` but still
* too complex. We should provides Table props like `sorter` & `filter` to handle control in next
* big version.
*/

// ============================ Sorter =============================
const onSorterChange = (
Expand Down Expand Up @@ -327,7 +332,7 @@ function Table<RecordType extends object = any>(props: TableProps<RecordType>) {
changeEventInfo.resetPagination = resetPagination;

// ============================= Data =============================
const pageData = React.useMemo<RecordType[]>(() => {
const pageData = React.useMemo<readonly RecordType[]>(() => {
if (pagination === false || !mergedPagination.pageSize) {
return mergedData;
}
Expand Down
10 changes: 5 additions & 5 deletions components/table/hooks/useFilter/FilterDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { ConfigContext } from '../../../config-provider/context';

const { SubMenu, Item: MenuItem } = Menu;

function hasSubMenu(filters: ColumnFilterItem[]) {
function hasSubMenu(filters: readonly ColumnFilterItem[]) {
return filters.some(({ children }) => children);
}

Expand All @@ -34,9 +34,9 @@ function renderFilterItems({
filterMultiple,
locale,
}: {
filters: ColumnFilterItem[];
filters: readonly ColumnFilterItem[];
prefixCls: string;
filteredKeys: Key[];
filteredKeys: readonly Key[];
filterMultiple: boolean;
locale: TableLocale;
}) {
Expand Down Expand Up @@ -139,7 +139,7 @@ function FilterDropdown<RecordType>(props: FilterDropdownProps<RecordType>) {
const propFilteredKeys = filterState && filterState.filteredKeys;
const [getFilteredKeysSync, setFilteredKeysSync] = useSyncState(propFilteredKeys || []);

const onSelectKeys = ({ selectedKeys }: { selectedKeys?: Key[] }) => {
const onSelectKeys = ({ selectedKeys }: { selectedKeys?: readonly Key[] }) => {
setFilteredKeysSync(selectedKeys!);
};

Expand All @@ -166,7 +166,7 @@ function FilterDropdown<RecordType>(props: FilterDropdownProps<RecordType>) {
);

// ======================= Submit ========================
const internalTriggerFilter = (keys: Key[] | undefined | null) => {
const internalTriggerFilter = (keys: readonly Key[] | undefined | null) => {
const mergedKeys = keys && keys.length ? keys : null;
if (mergedKeys === null && (!filterState || !filterState.filteredKeys)) {
return null;
Expand Down
26 changes: 13 additions & 13 deletions components/table/hooks/useFilter/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ import FilterDropdown from './FilterDropdown';
export interface FilterState<RecordType> {
column: ColumnType<RecordType>;
key: Key;
filteredKeys?: Key[] | null;
filteredKeys?: readonly Key[] | null;
forceFiltered?: boolean;
}

function collectFilterStates<RecordType>(
columns: ColumnsType<RecordType>,
init: boolean,
pos?: string,
): FilterState<RecordType>[] {
): readonly FilterState<RecordType>[] {
let filterStates: FilterState<RecordType>[] = [];

(columns || []).forEach((column, index) => {
Expand Down Expand Up @@ -64,7 +64,7 @@ function injectFilter<RecordType>(
prefixCls: string,
dropdownPrefixCls: string,
columns: ColumnsType<RecordType>,
filterStates: FilterState<RecordType>[],
filterStates: readonly FilterState<RecordType>[],
triggerFilter: (filterState: FilterState<RecordType>) => void,
getPopupContainer: GetPopupContainer | undefined,
locale: TableLocale,
Expand Down Expand Up @@ -120,7 +120,7 @@ function injectFilter<RecordType>(
});
}

function flattenKeys(filters?: ColumnFilterItem[]) {
function flattenKeys(filters?: readonly ColumnFilterItem[]) {
let keys: (string | number | boolean)[] = [];
(filters || []).forEach(({ value, children }) => {
keys.push(value);
Expand All @@ -131,8 +131,8 @@ function flattenKeys(filters?: ColumnFilterItem[]) {
return keys;
}

function generateFilterInfo<RecordType>(filterStates: FilterState<RecordType>[]) {
const currentFilters: Record<string, (Key | boolean)[] | null> = {};
function generateFilterInfo<RecordType>(filterStates: readonly FilterState<RecordType>[]) {
const currentFilters: Record<string, readonly (Key | boolean)[] | null> = {};

filterStates.forEach(({ key, filteredKeys, column }) => {
const { filters, filterDropdown } = column;
Expand All @@ -150,8 +150,8 @@ function generateFilterInfo<RecordType>(filterStates: FilterState<RecordType>[])
}

export function getFilterData<RecordType>(
data: RecordType[],
filterStates: FilterState<RecordType>[],
data: readonly RecordType[],
filterStates: readonly FilterState<RecordType>[],
) {
return filterStates.reduce((currentData, filterState) => {
const {
Expand All @@ -178,8 +178,8 @@ interface FilterConfig<RecordType> {
mergedColumns: ColumnsType<RecordType>;
locale: TableLocale;
onFilterChange: (
filters: Record<string, (Key | boolean)[] | null>,
filterStates: FilterState<RecordType>[],
filters: Record<string, readonly (Key | boolean)[] | null>,
filterStates: readonly FilterState<RecordType>[],
) => void;
getPopupContainer?: GetPopupContainer;
}
Expand All @@ -193,10 +193,10 @@ function useFilter<RecordType>({
locale: tableLocale,
}: FilterConfig<RecordType>): [
TransformColumns<RecordType>,
FilterState<RecordType>[],
() => Record<string, (Key | boolean)[] | null>,
readonly FilterState<RecordType>[],
() => Record<string, readonly (Key | boolean)[] | null>,
] {
const [filterStates, setFilterStates] = React.useState<FilterState<RecordType>[]>(
const [filterStates, setFilterStates] = React.useState<readonly FilterState<RecordType>[]>(
collectFilterStates(mergedColumns, true),
);

Expand Down
6 changes: 3 additions & 3 deletions components/table/hooks/useLazyKVMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import * as React from 'react';
import { Key, GetRowKey } from '../interface';

interface MapCache<RecordType> {
data?: RecordType[];
data?: readonly RecordType[];
childrenColumnName?: string;
kvMap?: Map<Key, RecordType>;
getRowKey?: Function;
}

export default function useLazyKVMap<RecordType>(
data: RecordType[],
data: readonly RecordType[],
childrenColumnName: string,
getRowKey: GetRowKey<RecordType>,
) {
Expand All @@ -25,7 +25,7 @@ export default function useLazyKVMap<RecordType>(
const kvMap = new Map<Key, RecordType>();

/* eslint-disable no-inner-declarations */
function dig(records: RecordType[]) {
function dig(records: readonly RecordType[]) {
records.forEach((record, index) => {
const rowKey = getRowKey(record, index);
kvMap.set(rowKey, record);
Expand Down
2 changes: 1 addition & 1 deletion components/table/hooks/usePagination.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default function usePagination(
total: number,
pagination: TablePaginationConfig | false | undefined,
onChange: (current: number, pageSize: number) => void,
): [TablePaginationConfig, () => void] {
): readonly [TablePaginationConfig, () => void] {
const { total: paginationTotal = 0, ...paginationObj } =
pagination && typeof pagination === 'object' ? pagination : {};

Expand Down
14 changes: 7 additions & 7 deletions components/table/hooks/useSelection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ function getFixedType<RecordType>(column: ColumnsType<RecordType>[number]): Fixe

interface UseSelectionConfig<RecordType> {
prefixCls: string;
pageData: RecordType[];
data: RecordType[];
pageData: readonly RecordType[];
data: readonly RecordType[];
getRowKey: GetRowKey<RecordType>;
getRecordByKey: (key: Key) => RecordType;
expandType: ExpandType;
Expand All @@ -54,9 +54,9 @@ export type INTERNAL_SELECTION_ITEM =
| typeof SELECTION_NONE;

function flattenData<RecordType>(
data: RecordType[] | undefined,
data: readonly RecordType[] | undefined,
childrenColumnName: string,
): RecordType[] {
): readonly RecordType[] {
let list: RecordType[] = [];
(data || []).forEach(record => {
list.push(record);
Expand All @@ -75,7 +75,7 @@ function flattenData<RecordType>(
export default function useSelection<RecordType>(
rowSelection: TableRowSelection<RecordType> | undefined,
config: UseSelectionConfig<RecordType>,
): [TransformColumns<RecordType>, Set<Key>] {
): readonly [TransformColumns<RecordType>, Set<Key>] {
const {
preserveSelectedRowKeys,
selectedRowKeys,
Expand Down Expand Up @@ -165,7 +165,7 @@ export default function useSelection<RecordType>(
return [mergedSelectedKeys || [], []];
}
const { checkedKeys, halfCheckedKeys } = conductCheck(
mergedSelectedKeys,
mergedSelectedKeys as React.Key[],
true,
keyEntities as any,
isCheckboxDisabled as any,
Expand Down Expand Up @@ -257,7 +257,7 @@ export default function useSelection<RecordType>(
return null;
}

const selectionList: INTERNAL_SELECTION_ITEM[] =
const selectionList: readonly INTERNAL_SELECTION_ITEM[] =
selections === true ? [SELECTION_ALL, SELECTION_INVERT, SELECTION_NONE] : selections;

return selectionList.map((selection: INTERNAL_SELECTION_ITEM) => {
Expand Down
27 changes: 14 additions & 13 deletions components/table/hooks/useSorter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ function getSortFunction<RecordType>(
return false;
}

function nextSortDirection(sortDirections: SortOrder[], current: SortOrder | null) {
function nextSortDirection(sortDirections: readonly SortOrder[], current: SortOrder | null) {
if (!current) {
return sortDirections[0];
}
Expand Down Expand Up @@ -104,9 +104,9 @@ function collectSortStates<RecordType>(
function injectSorter<RecordType>(
prefixCls: string,
columns: ColumnsType<RecordType>,
sorterSates: SortState<RecordType>[],
sorterSates: readonly SortState<RecordType>[],
triggerSorter: (sorterSates: SortState<RecordType>) => void,
defaultSortDirections: SortOrder[],
defaultSortDirections: readonly SortOrder[],
tableLocale?: TableLocale,
tableShowSorterTooltip?: boolean,
pos?: string,
Expand All @@ -116,7 +116,8 @@ function injectSorter<RecordType>(
let newColumn: ColumnsType<RecordType>[number] = column;

if (newColumn.sorter) {
const sortDirections: SortOrder[] = newColumn.sortDirections || defaultSortDirections;
const sortDirections: readonly SortOrder[] =
newColumn.sortDirections || defaultSortDirections;
const showSorterTooltip =
newColumn.showSorterTooltip === undefined
? tableShowSorterTooltip
Expand Down Expand Up @@ -223,8 +224,8 @@ function stateToInfo<RecordType>(sorterStates: SortState<RecordType>) {
}

function generateSorterInfo<RecordType>(
sorterStates: SortState<RecordType>[],
): SorterResult<RecordType> | SorterResult<RecordType>[] {
sorterStates: readonly SortState<RecordType>[],
): SorterResult<RecordType> | readonly SorterResult<RecordType>[] {
const list = sorterStates.filter(({ sortOrder }) => sortOrder).map(stateToInfo);

// =========== Legacy compatible support ===========
Expand All @@ -244,10 +245,10 @@ function generateSorterInfo<RecordType>(
}

export function getSortData<RecordType>(
data: RecordType[],
sortStates: SortState<RecordType>[],
data: readonly RecordType[],
sortStates: readonly SortState<RecordType>[],
childrenColumnName: string,
): RecordType[] {
): readonly RecordType[] {
const innerSorterStates = sortStates
.slice()
.sort((a, b) => (b.multiplePriority as number) - (a.multiplePriority as number));
Expand Down Expand Up @@ -301,10 +302,10 @@ interface SorterConfig<RecordType> {
prefixCls: string;
mergedColumns: ColumnsType<RecordType>;
onSorterChange: (
sorterResult: SorterResult<RecordType> | SorterResult<RecordType>[],
sorterResult: SorterResult<RecordType> | readonly SorterResult<RecordType>[],
sortStates: SortState<RecordType>[],
) => void;
sortDirections: SortOrder[];
sortDirections: readonly SortOrder[];
tableLocale?: TableLocale;
showSorterTooltip?: boolean;
}
Expand All @@ -318,9 +319,9 @@ export default function useFilterSorter<RecordType>({
showSorterTooltip,
}: SorterConfig<RecordType>): [
TransformColumns<RecordType>,
SortState<RecordType>[],
readonly SortState<RecordType>[],
ColumnTitleProps<RecordType>,
() => SorterResult<RecordType> | SorterResult<RecordType>[],
() => SorterResult<RecordType> | readonly SorterResult<RecordType>[],
] {
const [sortStates, setSortStates] = React.useState<SortState<RecordType>[]>(
collectSortStates(mergedColumns, true),
Expand Down
2 changes: 1 addition & 1 deletion components/table/hooks/useTitleColumns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function fillTitle<RecordType>(

export default function useTitleColumns<RecordType>(
columnTitleProps: ColumnTitleProps<RecordType>,
): [TransformColumns<RecordType>] {
): readonly [TransformColumns<RecordType>] {
const filledColumns = React.useCallback(
(columns: ColumnsType<RecordType>) => fillTitle(columns, columnTitleProps),
[columnTitleProps],
Expand Down