Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions docs/demo/dropdown-render.md

This file was deleted.

8 changes: 8 additions & 0 deletions docs/demo/popup-render.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
title: popup-render
nav:
title: Demo
path: /demo
---

<code src="../../examples/popup-render.tsx"></code>
2 changes: 1 addition & 1 deletion examples/dropdown-render.tsx → examples/popup-render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ const Demo = () => {
<div>
{menus}
<hr />
Hey, DropdownRender, Long DropdownRender, Long DropdownRender
Hey, popupRender, Long popupRender, Long popupRender
</div>
)}
>
Expand Down
6 changes: 3 additions & 3 deletions examples/visible.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ const addressOptions = [

const Demo = () => {
const [value, setValue] = useState<string[]>([]);
const [popupVisible, setPopupVisible] = useState(false);
const [open, setOpen] = useState(false);

const getLabel = () => {
return arrayTreeFilter(addressOptions, (o, level) => o.value === value[level])
Expand All @@ -69,10 +69,10 @@ const Demo = () => {

return (
<Cascader
popupVisible={popupVisible}
open={open}
value={value}
options={addressOptions}
onPopupVisibleChange={open => setPopupVisible(open)}
onPopupVisibleChange={open => setOpen(open)}
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

⚠️ Potential issue

🧩 Analysis chain

事件处理器更新不完整

根据 PR 的目标是废弃旧 API,onPopupVisibleChange 也应该更新为新的 API 名称。

-  onPopupVisibleChange={open => setOpen(open)}
+  onDropdownVisibleChange={open => setOpen(open)}

🏁 Script executed:

#!/bin/bash
# 检查 src/Cascader.tsx 中 onPopupVisibleChange 和 onDropdownVisibleChange 的使用情况
grep -n "onPopupVisibleChange\|onDropdownVisibleChange" src/Cascader.tsx

Length of output: 267


请更新所有事件处理器引用

根据最新的检查,在 examples/visible.tsx(第 75 行)以及 src/Cascader.tsx 中(例如第 109、212、363 和 455 行)的代码依然使用了旧 API onPopupVisibleChange。而本次 PR 的目标是废弃旧 API,因此需要将所有相关引用统一更新为新版 API onDropdownVisibleChange

示例修改差异:

-  onPopupVisibleChange={open => setOpen(open)}
+  onDropdownVisibleChange={open => setOpen(open)}

请同步检查并更新 src/Cascader.tsx 中所有涉及该事件处理器的位置,以确保整个代码库的一致性。

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
onPopupVisibleChange={open => setOpen(open)}
onDropdownVisibleChange={open => setOpen(open)}

onChange={value => setValue(value)}
>
<input value={getLabel()} readOnly />
Expand Down
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"build": "dumi build",
"compile": "father build",
"coverage": "father test --coverage",
"tsc": "bunx tsc --noEmit",
"deploy": "UMI_ENV=gh npm run build && gh-pages -d dist",
"lint": "eslint src/ examples/ --ext .tsx,.ts,.jsx,.jsx",
"now-build": "npm run build",
Expand All @@ -43,9 +44,9 @@
},
"dependencies": {
"@rc-component/select": "~1.0.0",
"@rc-component/tree": "~1.0.0",
"@rc-component/util": "^1.2.1",
"classnames": "^2.3.1",
"rc-tree": "~5.13.1"
"classnames": "^2.3.1"
},
"devDependencies": {
"@rc-component/father-plugin": "^2.0.2",
Expand All @@ -55,8 +56,8 @@
"@types/classnames": "^2.2.6",
"@types/enzyme": "^3.1.15",
"@types/jest": "^29.4.0",
"@types/react": "^17.0.38",
"@types/react-dom": "^18.0.11",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
Comment on lines +59 to +60
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

React 类型定义版本升级与 React 版本不匹配
@types/react@types/react-dom 已升级到 ^19.0.0,但项目中 reactreact-dom 依旧为 ^16.0.0。这种不一致可能导致类型错误或运行时问题。建议同步更新 reactreact-dom 至兼容的新版,或验证当前组合能否正常工作。

"@types/warning": "^3.0.0",
"@umijs/fabric": "^4.0.0",
"array-tree-filter": "^3.0.2",
Expand Down
61 changes: 25 additions & 36 deletions src/Cascader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import {
toRawValues,
} from './utils/commonUtil';
import { formatStrategyValues, toPathOptions } from './utils/treeUtil';
import warningProps, { warningNullOptions } from './utils/warningPropsUtil';
import { warningNullOptions } from './utils/warningPropsUtil';

export interface BaseOptionType {
disabled?: boolean;
Expand Down Expand Up @@ -71,9 +71,9 @@ interface BaseCascaderProps<
OptionType extends DefaultOptionType = DefaultOptionType,
ValueField extends keyof OptionType = keyof OptionType,
> extends Omit<
BaseSelectPropsWithoutPrivate,
'tokenSeparators' | 'labelInValue' | 'mode' | 'showSearch'
> {
BaseSelectPropsWithoutPrivate,
'tokenSeparators' | 'labelInValue' | 'mode' | 'showSearch'
> {
// MISC
id?: string;
prefixCls?: string;
Expand All @@ -99,18 +99,12 @@ interface BaseCascaderProps<
// Options
options?: OptionType[];
/** @private Internal usage. Do not use in your production. */
dropdownPrefixCls?: string;
popupPrefixCls?: string;
loadData?: (selectOptions: OptionType[]) => void;

// Open
/** @deprecated Use `open` instead */
popupVisible?: boolean;

popupClassName?: string;
dropdownMenuColumnStyle?: React.CSSProperties;
popupMenuColumnStyle?: React.CSSProperties;

/** @deprecated Use `placement` instead */
popupPlacement?: Placement;
placement?: Placement;
builtinPlacements?: BuildInPlacements;

Expand All @@ -135,8 +129,8 @@ export type ValueType<
ValueField extends keyof OptionType = keyof OptionType,
> = keyof OptionType extends ValueField
? unknown extends OptionType['value']
? OptionType[ValueField]
: OptionType['value']
? OptionType[ValueField]
: OptionType['value']
: OptionType[ValueField];

export type GetValueType<
Expand Down Expand Up @@ -167,6 +161,9 @@ export interface CascaderProps<
}

export type SingleValueType = (string | number)[];

export type LegacyKey = string | number;

export type InternalValueType = SingleValueType | SingleValueType[];

export interface InternalFieldNames extends Required<FieldNames> {
Expand Down Expand Up @@ -210,18 +207,15 @@ const Cascader = React.forwardRef<CascaderRef, InternalCascaderProps>((props, re

// Options
options,
dropdownPrefixCls,
popupPrefixCls,
loadData,

// Open
popupVisible,
open,

popupClassName,
dropdownMenuColumnStyle,
popupMenuColumnStyle,
popupStyle: customPopupStyle,

popupPlacement,
placement,

onPopupVisibleChange,
Expand Down Expand Up @@ -281,7 +275,7 @@ const Cascader = React.forwardRef<CascaderRef, InternalCascaderProps>((props, re
mergedSearchValue,
mergedOptions,
mergedFieldNames,
dropdownPrefixCls || prefixCls,
popupPrefixCls || prefixCls,
searchConfig,
changeOnSelect || multiple,
);
Expand Down Expand Up @@ -374,18 +368,13 @@ const Cascader = React.forwardRef<CascaderRef, InternalCascaderProps>((props, re
onInternalSelect(valueCells);
};

// ============================ Open ============================
const mergedOpen = open !== undefined ? open : popupVisible;

const mergedPlacement = placement || popupPlacement;

const onInternalPopupVisibleChange = (nextVisible: boolean) => {
onPopupVisibleChange?.(nextVisible);
};


// ========================== Warning ===========================
if (process.env.NODE_ENV !== 'production') {
warningProps(props);
warningNullOptions(mergedOptions, mergedFieldNames);
}

Expand All @@ -400,12 +389,12 @@ const Cascader = React.forwardRef<CascaderRef, InternalCascaderProps>((props, re
onSelect: onInternalSelect,
checkable,
searchOptions,
dropdownPrefixCls,
popupPrefixCls,
loadData,
expandTrigger,
expandIcon,
loadingIcon,
dropdownMenuColumnStyle,
popupMenuColumnStyle,
optionRender,
}),
[
Expand All @@ -417,12 +406,12 @@ const Cascader = React.forwardRef<CascaderRef, InternalCascaderProps>((props, re
onInternalSelect,
checkable,
searchOptions,
dropdownPrefixCls,
popupPrefixCls,
loadData,
expandTrigger,
expandIcon,
loadingIcon,
dropdownMenuColumnStyle,
popupMenuColumnStyle,
optionRender,
],
);
Expand All @@ -435,12 +424,12 @@ const Cascader = React.forwardRef<CascaderRef, InternalCascaderProps>((props, re
const popupStyle: React.CSSProperties =
// Search to match width
(mergedSearchValue && searchConfig.matchInputWidth) ||
// Empty keep the width
emptyOptions
// Empty keep the width
emptyOptions
? {}
: {
minWidth: 'auto',
};
minWidth: 'auto',
};

return (
<CascaderContext.Provider value={cascaderContext}>
Expand Down Expand Up @@ -468,9 +457,9 @@ const Cascader = React.forwardRef<CascaderRef, InternalCascaderProps>((props, re
OptionList={OptionList}
emptyOptions={emptyOptions}
// Open
open={mergedOpen}
open={open}
popupClassName={popupClassName}
placement={mergedPlacement}
placement={placement}
onPopupVisibleChange={onInternalPopupVisibleChange}
// Children
getRawInputElement={() => children as React.ReactElement}
Expand Down
4 changes: 2 additions & 2 deletions src/OptionList/Column.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export default function Column<OptionType extends DefaultOptionType = DefaultOpt
expandTrigger,
expandIcon,
loadingIcon,
dropdownMenuColumnStyle,
popupMenuColumnStyle,
optionRender,
} = React.useContext(CascaderContext);

Expand Down Expand Up @@ -155,7 +155,7 @@ export default function Column<OptionType extends DefaultOptionType = DefaultOpt
[`${menuItemPrefixCls}-disabled`]: isOptionDisabled(disabled),
[`${menuItemPrefixCls}-loading`]: isLoading,
})}
style={dropdownMenuColumnStyle}
style={popupMenuColumnStyle}
role="menuitemcheckbox"
title={title}
aria-checked={checked}
Expand Down
12 changes: 6 additions & 6 deletions src/OptionList/List.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import classNames from 'classnames';
import type { useBaseProps } from '@rc-component/select';
import type { RefOptionListProps } from '@rc-component/select/lib/OptionList';
import * as React from 'react';
import type { DefaultOptionType, SingleValueType } from '../Cascader';
import type { DefaultOptionType, LegacyKey, SingleValueType } from '../Cascader';
import CascaderContext from '../context';
import {
getFullPathKeys,
Expand Down Expand Up @@ -54,17 +54,17 @@ const RawOptionList = React.forwardRef<RefOptionListProps, RawOptionListProps>((
changeOnSelect,
onSelect,
searchOptions,
dropdownPrefixCls,
popupPrefixCls,
loadData,
expandTrigger,
} = React.useContext(CascaderContext);

const mergedPrefixCls = dropdownPrefixCls || prefixCls;
const mergedPrefixCls = popupPrefixCls || prefixCls;

// ========================= loadData =========================
const [loadingKeys, setLoadingKeys] = React.useState<React.Key[]>([]);
const [loadingKeys, setLoadingKeys] = React.useState<LegacyKey[]>([]);

const internalLoadData = (valueCells: React.Key[]) => {
const internalLoadData = (valueCells: LegacyKey[]) => {
// Do not load when search
if (!loadData || searchValue) {
return;
Expand Down Expand Up @@ -108,7 +108,7 @@ const RawOptionList = React.forwardRef<RefOptionListProps, RawOptionListProps>((
const [activeValueCells, setActiveValueCells] = useActive(multiple, open);

// =========================== Path ===========================
const onPathOpen = (nextValueCells: React.Key[]) => {
const onPathOpen = (nextValueCells: LegacyKey[]) => {
setActiveValueCells(nextValueCells);

// Trigger loadData
Expand Down
5 changes: 3 additions & 2 deletions src/OptionList/useActive.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import * as React from 'react';
import CascaderContext from '../context';
import { LegacyKey } from '@/Cascader';

/**
* Control the active open options path.
*/
const useActive = (
multiple?: boolean,
open?: boolean,
): [React.Key[], (activeValueCells: React.Key[]) => void] => {
): [LegacyKey[], (activeValueCells: LegacyKey[]) => void] => {
const { values } = React.useContext(CascaderContext);

const firstValueCells = values[0];

// Record current dropdown active options
// This also control the open status
const [activeValueCells, setActiveValueCells] = React.useState<React.Key[]>([]);
const [activeValueCells, setActiveValueCells] = React.useState<LegacyKey[]>([]);

React.useEffect(
() => {
Expand Down
10 changes: 5 additions & 5 deletions src/OptionList/useKeyboard.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import type { RefOptionListProps } from '@rc-component/select/lib/OptionList';
import KeyCode from '@rc-component/util/lib/KeyCode';
import * as React from 'react';
import type { DefaultOptionType, InternalFieldNames, SingleValueType } from '../Cascader';
import type { DefaultOptionType, InternalFieldNames, LegacyKey, SingleValueType } from '../Cascader';
import { SEARCH_MARK } from '../hooks/useSearchOptions';
import { getFullPathKeys, toPathKey } from '../utils/commonUtil';

export default (
ref: React.Ref<RefOptionListProps>,
options: DefaultOptionType[],
fieldNames: InternalFieldNames,
activeValueCells: React.Key[],
setActiveValueCells: (activeValueCells: React.Key[]) => void,
activeValueCells: LegacyKey[],
setActiveValueCells: (activeValueCells: LegacyKey[]) => void,
onKeyBoardSelect: (valueCells: SingleValueType, option: DefaultOptionType) => void,
contextProps: {
direction?: 'ltr' | 'rtl';
Expand All @@ -28,7 +28,7 @@ export default (
let currentOptions = options;

const mergedActiveIndexes: number[] = [];
const mergedActiveValueCells: React.Key[] = [];
const mergedActiveValueCells: LegacyKey[] = [];

const len = activeValueCells.length;

Expand Down Expand Up @@ -64,7 +64,7 @@ export default (
}, [activeValueCells, fieldNames, options]);

// Update active value cells and scroll to target element
const internalSetActiveValueCells = (next: React.Key[]) => {
const internalSetActiveValueCells = (next: LegacyKey[]) => {
setActiveValueCells(next);
};

Expand Down
4 changes: 2 additions & 2 deletions src/Panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -153,12 +153,12 @@ export default function Panel<
onSelect: onInternalSelect,
checkable,
searchOptions: [],
dropdownPrefixCls: undefined,
popupPrefixCls: undefined,
loadData,
expandTrigger,
expandIcon,
loadingIcon,
dropdownMenuColumnStyle: undefined,
popupMenuColumnStyle: undefined,
}),
[
mergedOptions,
Expand Down
Loading
Loading