();
// ======================== Errors ========================
// >>>>> Collect sub field errors
diff --git a/components/form/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/form/__tests__/__snapshots__/demo-extend.test.ts.snap
index 9db6e3f363b5..d87c5060b794 100644
--- a/components/form/__tests__/__snapshots__/demo-extend.test.ts.snap
+++ b/components/form/__tests__/__snapshots__/demo-extend.test.ts.snap
@@ -5071,6 +5071,7 @@ Array [
>
diff --git a/components/form/__tests__/__snapshots__/demo.test.ts.snap b/components/form/__tests__/__snapshots__/demo.test.ts.snap
index 9fc8e69a86fb..04a2c6020b18 100644
--- a/components/form/__tests__/__snapshots__/demo.test.ts.snap
+++ b/components/form/__tests__/__snapshots__/demo.test.ts.snap
@@ -2554,6 +2554,7 @@ Array [
>
diff --git a/components/form/__tests__/__snapshots__/index.test.tsx.snap b/components/form/__tests__/__snapshots__/index.test.tsx.snap
index b72605a3cc4c..549ad2459d9e 100644
--- a/components/form/__tests__/__snapshots__/index.test.tsx.snap
+++ b/components/form/__tests__/__snapshots__/index.test.tsx.snap
@@ -929,6 +929,7 @@ exports[`Form form should support disabled 1`] = `
>
diff --git a/components/form/__tests__/index.test.tsx b/components/form/__tests__/index.test.tsx
index 55ac755b8801..a70229ed1d26 100644
--- a/components/form/__tests__/index.test.tsx
+++ b/components/form/__tests__/index.test.tsx
@@ -1558,20 +1558,21 @@ describe('Form', () => {
const App2 = () => ;
const wrapper2 = render();
- // 时间范围组件中会有两个 input 框,因此虽然上述只有 18 个组件,但,实际有 19 个 带有 disabled 属性的表单组件
- expect(wrapper2.container.querySelectorAll('[disabled]').length).toBe(19);
+ // 时间范围组件中会有两个 input 框,Upload 为叠加
+ // 因此虽然上述只有 18 个组件,但实际有 20 个 带有 disabled 属性的表单组件
+ expect(wrapper2.container.querySelectorAll('[disabled]').length).toBe(20);
const App3 = () => ;
const wrapper3 = render();
- expect(wrapper3.container.querySelectorAll('[disabled]').length).toBe(19);
+ expect(wrapper3.container.querySelectorAll('[disabled]').length).toBe(20);
const App4 = () => ;
const wrapper4 = render();
- expect(wrapper4.container.querySelectorAll('[disabled]').length).toBe(19);
+ expect(wrapper4.container.querySelectorAll('[disabled]').length).toBe(20);
const App5 = () => ;
diff --git a/components/table/__tests__/Table.filter.test.tsx b/components/table/__tests__/Table.filter.test.tsx
index f39a701bc9a8..d8eee4b032b9 100644
--- a/components/table/__tests__/Table.filter.test.tsx
+++ b/components/table/__tests__/Table.filter.test.tsx
@@ -968,7 +968,7 @@ describe('Table.filter', () => {
filterDropdown: ({ setSelectedKeys, selectedKeys, confirm }) => (
{
setSelectedKeys(e.target.value ? [e.target.value] : []);
}}
diff --git a/components/table/demo/custom-filter-panel.md b/components/table/demo/custom-filter-panel.md
index be69bd5f2bdd..cf2b72530ea0 100644
--- a/components/table/demo/custom-filter-panel.md
+++ b/components/table/demo/custom-filter-panel.md
@@ -88,7 +88,7 @@ const App: React.FC = () => {
setSelectedKeys(e.target.value ? [e.target.value] : [])}
onPressEnter={() => handleSearch(selectedKeys as string[], confirm, dataIndex)}
style={{ marginBottom: 8, display: 'block' }}
diff --git a/components/table/hooks/useFilter/FilterDropdown.tsx b/components/table/hooks/useFilter/FilterDropdown.tsx
index 23a734358a48..567a566ef390 100644
--- a/components/table/hooks/useFilter/FilterDropdown.tsx
+++ b/components/table/hooks/useFilter/FilterDropdown.tsx
@@ -21,6 +21,7 @@ import useSyncState from '../../../_util/hooks/useSyncState';
import type {
ColumnFilterItem,
ColumnType,
+ FilterKey,
FilterSearchType,
GetPopupContainer,
Key,
@@ -29,7 +30,7 @@ import type {
import FilterSearch from './FilterSearch';
import FilterDropdownMenuWrapper from './FilterWrapper';
-type FilterTreeDataNode = FieldDataNode<{ title: React.ReactNode; key: React.Key }>;
+type FilterTreeDataNode = FieldDataNode<{ title: React.ReactNode; key: string }>;
interface FilterRestProps {
confirm?: Boolean;
@@ -121,6 +122,10 @@ export interface FilterDropdownProps {
filterResetToDefaultFilteredValue?: boolean;
}
+function wrapStringListType(keys?: FilterKey) {
+ return (keys as string[]) || [];
+}
+
function FilterDropdown(props: FilterDropdownProps) {
const {
tablePrefixCls,
@@ -166,20 +171,22 @@ function FilterDropdown(props: FilterDropdownProps) {
}
// ===================== Select Keys =====================
const propFilteredKeys = filterState?.filteredKeys;
- const [getFilteredKeysSync, setFilteredKeysSync] = useSyncState(propFilteredKeys || []);
+ const [getFilteredKeysSync, setFilteredKeysSync] = useSyncState(
+ wrapStringListType(propFilteredKeys),
+ );
- const onSelectKeys = ({ selectedKeys }: { selectedKeys: Key[] }) => {
+ const onSelectKeys = ({ selectedKeys }: { selectedKeys: string[] }) => {
setFilteredKeysSync(selectedKeys);
};
const onCheck = (
- keys: Key[],
+ keys: string[],
{ node, checked }: { node: EventDataNode; checked: boolean },
) => {
if (!filterMultiple) {
onSelectKeys({ selectedKeys: checked && node.key ? [node.key] : [] });
} else {
- onSelectKeys({ selectedKeys: keys as Key[] });
+ onSelectKeys({ selectedKeys: keys });
}
};
@@ -187,7 +194,7 @@ function FilterDropdown(props: FilterDropdownProps) {
if (!visible) {
return;
}
- onSelectKeys({ selectedKeys: propFilteredKeys || [] });
+ onSelectKeys({ selectedKeys: wrapStringListType(propFilteredKeys) });
}, [propFilteredKeys]);
// ====================== Open Keys ======================
@@ -210,7 +217,7 @@ function FilterDropdown(props: FilterDropdownProps) {
}, [visible]);
// ======================= Submit ========================
- const internalTriggerFilter = (keys: Key[] | undefined | null) => {
+ const internalTriggerFilter = (keys: string[] | undefined | null) => {
const mergedKeys = keys && keys.length ? keys : null;
if (mergedKeys === null && (!filterState || !filterState.filteredKeys)) {
return null;
@@ -245,7 +252,7 @@ function FilterDropdown(props: FilterDropdownProps) {
setSearchValue('');
if (filterResetToDefaultFilteredValue) {
- setFilteredKeysSync((defaultFilteredValue || []).map(key => String(key)));
+ setFilteredKeysSync((defaultFilteredValue || []).map((key) => String(key)));
} else {
setFilteredKeysSync([]);
}
@@ -261,7 +268,7 @@ function FilterDropdown(props: FilterDropdownProps) {
const onVisibleChange = (newVisible: boolean) => {
if (newVisible && propFilteredKeys !== undefined) {
// Sync filteredKeys on appear in controlled mode (propFilteredKeys !== undefiend)
- setFilteredKeysSync(propFilteredKeys || []);
+ setFilteredKeysSync(wrapStringListType(propFilteredKeys));
}
triggerVisible(newVisible);
@@ -279,7 +286,7 @@ function FilterDropdown(props: FilterDropdownProps) {
const onCheckAll = (e: CheckboxChangeEvent) => {
if (e.target.checked) {
- const allFilterKeys = flattenKeys(column?.filters).map(key => String(key));
+ const allFilterKeys = flattenKeys(column?.filters).map((key) => String(key));
setFilteredKeysSync(allFilterKeys);
} else {
setFilteredKeysSync([]);
@@ -291,7 +298,7 @@ function FilterDropdown(props: FilterDropdownProps) {
const key = String(filter.value);
const item: FilterTreeDataNode = {
title: filter.text,
- key: filter.value !== undefined ? key : index,
+ key: filter.value !== undefined ? key : String(index),
};
if (filter.children) {
item.children = getTreeData({ filters: filter.children });
@@ -302,7 +309,7 @@ function FilterDropdown(props: FilterDropdownProps) {
...node,
text: node.title,
value: node.key,
- children: node.children?.map(item => getFilterData(item)) || [],
+ children: node.children?.map((item) => getFilterData(item)) || [],
});
let dropdownContent: React.ReactNode;
@@ -310,7 +317,7 @@ function FilterDropdown(props: FilterDropdownProps) {
if (typeof column.filterDropdown === 'function') {
dropdownContent = column.filterDropdown({
prefixCls: `${dropdownPrefixCls}-custom`,
- setSelectedKeys: (selectedKeys: Key[]) => onSelectKeys({ selectedKeys }),
+ setSelectedKeys: (selectedKeys: string[]) => onSelectKeys({ selectedKeys }),
selectedKeys: getFilteredKeysSync(),
confirm: doFilter,
clearFilters: onReset,
@@ -323,7 +330,7 @@ function FilterDropdown(props: FilterDropdownProps) {
} else if (column.filterDropdown) {
dropdownContent = column.filterDropdown;
} else {
- const selectedKeys = (getFilteredKeysSync() || []) as any;
+ const selectedKeys = getFilteredKeysSync() || [];
const getFilterComponent = () => {
if ((column.filters || []).length === 0) {
return (
@@ -380,7 +387,7 @@ function FilterDropdown(props: FilterDropdownProps) {
defaultExpandAll
filterTreeNode={
searchValue.trim()
- ? node => {
+ ? (node) => {
if (typeof filterSearch === 'function') {
return filterSearch(searchValue, getFilterData(node));
}
@@ -429,7 +436,7 @@ function FilterDropdown(props: FilterDropdownProps) {
const getResetDisabled = () => {
if (filterResetToDefaultFilteredValue) {
return isEqual(
- (defaultFilteredValue || []).map(key => String(key)),
+ (defaultFilteredValue || []).map((key) => String(key)),
selectedKeys,
);
}
@@ -491,7 +498,7 @@ function FilterDropdown(props: FilterDropdownProps) {
className={classNames(`${prefixCls}-trigger`, {
active: filtered,
})}
- onClick={e => {
+ onClick={(e) => {
e.stopPropagation();
}}
>
diff --git a/components/table/hooks/useFilter/index.tsx b/components/table/hooks/useFilter/index.tsx
index 8fb7e55659bd..11b56fe00d45 100644
--- a/components/table/hooks/useFilter/index.tsx
+++ b/components/table/hooks/useFilter/index.tsx
@@ -9,6 +9,7 @@ import type {
FilterValue,
GetPopupContainer,
Key,
+ SafeKey,
TableLocale,
TransformColumns,
} from '../../interface';
@@ -144,14 +145,17 @@ function generateFilterInfo(filterStates: FilterState[])
const currentFilters: Record = {};
filterStates.forEach(({ key, filteredKeys, column }) => {
+ const keyAsString = key as SafeKey;
const { filters, filterDropdown } = column;
if (filterDropdown) {
- currentFilters[key] = filteredKeys || null;
+ currentFilters[keyAsString] = filteredKeys || null;
} else if (Array.isArray(filteredKeys)) {
const keys = flattenKeys(filters);
- currentFilters[key] = keys.filter(originKey => filteredKeys.includes(String(originKey)));
+ currentFilters[keyAsString] = keys.filter((originKey) =>
+ filteredKeys.includes(String(originKey)),
+ );
} else {
- currentFilters[key] = null;
+ currentFilters[keyAsString] = null;
}
});
@@ -168,10 +172,10 @@ export function getFilterData(
filteredKeys,
} = filterState;
if (onFilter && filteredKeys && filteredKeys.length) {
- return currentData.filter(record =>
- filteredKeys.some(key => {
+ return currentData.filter((record) =>
+ filteredKeys.some((key) => {
const keys = flattenKeys(filters);
- const keyIndex = keys.findIndex(k => String(k) === String(key));
+ const keyIndex = keys.findIndex((k) => String(k) === String(key));
const realKey = keyIndex !== -1 ? keys[keyIndex] : key;
return onFilter(realKey, record);
}),
diff --git a/components/table/interface.tsx b/components/table/interface.tsx
index d68a85fd8374..994a86d59ef6 100644
--- a/components/table/interface.tsx
+++ b/components/table/interface.tsx
@@ -17,6 +17,8 @@ export { GetRowKey, ExpandableConfig };
export type Key = React.Key;
+export type SafeKey = Exclude;
+
export type RowSelectionType = 'checkbox' | 'radio';
export type SelectionItemSelectFn = (currentRowKeys: Key[]) => void;
@@ -52,7 +54,7 @@ export type CompareFn = (a: T, b: T, sortOrder?: SortOrder) => number;
export interface ColumnFilterItem {
text: React.ReactNode;
- value: string | number | boolean;
+ value: React.Key | boolean;
children?: ColumnFilterItem[];
}
@@ -71,7 +73,7 @@ export type ColumnTitle =
| ((props: ColumnTitleProps) => React.ReactNode);
export type FilterValue = (Key | boolean)[];
-export type FilterKey = Key[] | null;
+export type FilterKey = (string | number)[] | null;
export type FilterSearchType> =
| boolean
| ((input: string, record: RecordType) => boolean);
@@ -121,7 +123,7 @@ export interface ColumnType extends Omit, '
filterIcon?: React.ReactNode | ((filtered: boolean) => React.ReactNode);
filterMode?: 'menu' | 'tree';
filterSearch?: FilterSearchType;
- onFilter?: (value: string | number | boolean, record: RecordType) => boolean;
+ onFilter?: (value: React.Key | boolean, record: RecordType) => boolean;
/**
* @deprecated `filterDropdownVisible` is deprecated which will be removed in next major version.
* Please use `filterDropdownOpen` instead.
diff --git a/components/transfer/demo/tree-transfer.md b/components/transfer/demo/tree-transfer.md
index 69121faeb197..1fb2d5be51c2 100644
--- a/components/transfer/demo/tree-transfer.md
+++ b/components/transfer/demo/tree-transfer.md
@@ -26,7 +26,7 @@ interface TreeTransferProps {
}
// Customize Table Transfer
-const isChecked = (selectedKeys: (string | number)[], eventKey: string | number) =>
+const isChecked = (selectedKeys: React.Key[], eventKey: React.Key) =>
selectedKeys.includes(eventKey);
const generateTree = (treeNodes: DataNode[] = [], checkedKeys: string[] = []): DataNode[] =>
diff --git a/components/tree/index.zh-CN.md b/components/tree/index.zh-CN.md
index cb44f7056e5f..06bd8eaec4e6 100644
--- a/components/tree/index.zh-CN.md
+++ b/components/tree/index.zh-CN.md
@@ -17,7 +17,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/Xh-oWqg9k/Tree.svg
### Tree props
| 参数 | 说明 | 类型 | 默认值 | 版本 |
-| --- | --- | --- | --- | --- | --- |
+| --- | --- | --- | --- | --- |
| allowDrop | 是否允许拖拽时放置在该节点 | ({ dropNode, dropPosition }) => boolean | - | |
| autoExpandParent | 是否自动展开父节点 | boolean | false | |
| blockNode | 是否节点占据一行 | boolean | false | |
diff --git a/package.json b/package.json
index 2573cdfc3380..b1fd488c397a 100644
--- a/package.json
+++ b/package.json
@@ -131,7 +131,7 @@
"rc-dialog": "~9.0.2",
"rc-drawer": "~6.3.0",
"rc-dropdown": "~4.0.1",
- "rc-field-form": "~1.34.2",
+ "rc-field-form": "~1.38.2",
"rc-image": "~5.13.0",
"rc-input": "~0.1.4",
"rc-input-number": "~7.3.11",