feat: [v6] Retire deprecated api for dropdown (#52234)

* feat: Retire deprecated api for dropdown

* feat: Retire deprecated api for dropdown

* feat: Retire deprecated api for dropdown

* feat: opt code
This commit is contained in:
kiner-tang(星河) 2025-01-13 17:34:07 +08:00 committed by GitHub
parent af707aa26b
commit b51ec67e50
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 56 additions and 167 deletions

View File

@ -6938,11 +6938,7 @@ exports[`renders components/dropdown/demo/render-panel.tsx extend context correc
</div>
`;
exports[`renders components/dropdown/demo/render-panel.tsx extend context correctly 2`] = `
[
"Warning: [antd: Dropdown] \`visible\` is deprecated. Please use \`open\` instead.",
]
`;
exports[`renders components/dropdown/demo/render-panel.tsx extend context correctly 2`] = `[]`;
exports[`renders components/dropdown/demo/selectable.tsx extend context correctly 1`] = `
Array [

View File

@ -1,43 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Dropdown overlay is function and has custom transitionName 1`] = `
Array [
<button
class="ant-dropdown-trigger ant-dropdown-open"
type="button"
>
button
</button>,
<div
class="ant-dropdown move-up-appear move-up-appear-prepare move-up ant-dropdown-placement-bottomLeft"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div>
menu
</div>
</div>,
]
`;
exports[`Dropdown overlay is string 1`] = `
Array [
<button
class="ant-dropdown-trigger ant-dropdown-open"
type="button"
>
button
</button>,
<div
class="ant-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up ant-dropdown-placement-bottomLeft"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<span>
string
</span>
</div>,
]
`;
exports[`Dropdown rtl render component should be rendered correctly in RTL direction 1`] = `
<span
class="ant-dropdown-trigger ant-dropdown-rtl"
@ -90,3 +52,42 @@ Array [
</div>,
]
`;
exports[`Dropdown support custom transitionName 1`] = `
Array [
<button
class="ant-dropdown-trigger ant-dropdown-open"
type="button"
>
button
</button>,
<div
class="ant-dropdown move-up-appear move-up-appear-prepare move-up ant-dropdown-placement-bottomLeft"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<ul
class="ant-dropdown-menu ant-dropdown-menu-root ant-dropdown-menu-vertical ant-dropdown-menu-light"
data-menu-list="true"
role="menu"
tabindex="0"
>
<li
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-1"
role="menuitem"
tabindex="-1"
>
<span
class="ant-dropdown-menu-title-content"
>
foo
</span>
</li>
</ul>
<div
aria-hidden="true"
style="display: none;"
/>
</div>,
]
`;

View File

@ -137,15 +137,7 @@ describe('DropdownButton', () => {
'ant-btn',
);
});
it('should console Error when `overlay` in props', () => {
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
render(<DropdownButton overlay={<div>test</div>} />);
expect(errSpy).toHaveBeenCalledWith(
'Warning: [antd: Dropdown] `overlay` is deprecated. Please use `menu` instead.',
);
errSpy.mockRestore();
});
it('should not console Error when `overlay` not in props', () => {
it('should not console Error when `menu` not in props', () => {
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
render(<DropdownButton />);
expect(errSpy).not.toHaveBeenCalled();

View File

@ -3,7 +3,6 @@ import type { TriggerProps } from '@rc-component/trigger';
import type { DropDownProps } from '..';
import Dropdown from '..';
import { resetWarned } from '../../_util/warning';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
import { act, fireEvent, render, waitFakeTimer } from '../../../tests/utils';
@ -44,18 +43,9 @@ describe('Dropdown', () => {
</Dropdown>
));
it('overlay is function and has custom transitionName', () => {
it('support custom transitionName', () => {
const { asFragment } = render(
<Dropdown overlay={() => <div>menu</div>} transitionName="move-up" open>
<button type="button">button</button>
</Dropdown>,
);
expect(Array.from(asFragment().childNodes)).toMatchSnapshot();
});
it('overlay is string', () => {
const { asFragment } = render(
<Dropdown overlay={'string' as any} open>
<Dropdown menu={{ items }} transitionName="move-up" open>
<button type="button">button</button>
</Dropdown>,
);
@ -205,55 +195,6 @@ describe('Dropdown', () => {
jest.useRealTimers();
});
it('legacy visible', () => {
resetWarned();
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
const onOpenChange = jest.fn();
const onVisibleChange = jest.fn();
const { container, rerender } = render(
<Dropdown
visible
onOpenChange={onOpenChange}
onVisibleChange={onVisibleChange}
trigger={['click']}
menu={{
items: [
{
label: <div className="bamboo" />,
key: 'bamboo',
},
],
}}
>
<a className="little" />
</Dropdown>,
);
expect(document.querySelector('.bamboo')).toBeTruthy();
expect(errorSpy).toHaveBeenCalledWith(
'Warning: [antd: Dropdown] `visible` is deprecated. Please use `open` instead.',
);
expect(errorSpy).toHaveBeenCalledWith(
'Warning: [antd: Dropdown] `onVisibleChange` is deprecated. Please use `onOpenChange` instead.',
);
fireEvent.click(container.querySelector('.little')!);
expect(onOpenChange).toHaveBeenCalled();
expect(onVisibleChange).toHaveBeenCalled();
rerender(
<Dropdown overlay={<div>menu</div>}>
<a className="little" />
</Dropdown>,
);
expect(errorSpy).toHaveBeenCalledWith(
'Warning: [antd: Dropdown] `overlay` is deprecated. Please use `menu` instead.',
);
errorSpy.mockRestore();
});
it('not block ref', () => {
const divRef = React.createRef<HTMLDivElement>();
render(

View File

@ -52,7 +52,6 @@ const DropdownButton: CompoundedComponent = (props) => {
menu,
arrow,
autoFocus,
overlay,
trigger,
align,
open,
@ -96,10 +95,6 @@ const DropdownButton: CompoundedComponent = (props) => {
const classes = classNames(buttonPrefixCls, compactItemClassnames, className);
if ('overlay' in props) {
dropdownProps.overlay = overlay;
}
if ('open' in props) {
dropdownProps.open = open;
}

View File

@ -37,8 +37,6 @@ const _Placements = [
type Placement = (typeof _Placements)[number];
type DropdownPlacement = Exclude<Placement, 'topCenter' | 'bottomCenter'>;
type OverlayFunc = () => React.ReactElement;
export type DropdownArrowOptions = {
pointAtCenter?: boolean;
};
@ -68,14 +66,6 @@ export interface DropdownProps {
openClassName?: string;
children?: React.ReactNode;
autoAdjustOverflow?: boolean | AdjustOverflow;
// Deprecated
/** @deprecated Please use `menu` instead */
overlay?: React.ReactElement | OverlayFunc;
/** @deprecated Please use `open` instead */
visible?: boolean;
/** @deprecated Please use `onOpenChange` instead */
onVisibleChange?: (open: boolean) => void;
}
type CompoundedComponent = React.FC<DropdownProps> & {
@ -98,13 +88,10 @@ const Dropdown: CompoundedComponent = (props) => {
open,
onOpenChange,
// Deprecated
visible,
onVisibleChange,
mouseEnterDelay = 0.15,
mouseLeaveDelay = 0.1,
autoAdjustOverflow = true,
placement = '',
overlay,
transitionName,
} = props;
const {
@ -117,17 +104,6 @@ const Dropdown: CompoundedComponent = (props) => {
// Warning for deprecated usage
const warning = devUseWarning('Dropdown');
if (process.env.NODE_ENV !== 'production') {
[
['visible', 'open'],
['onVisibleChange', 'onOpenChange'],
].forEach(([deprecatedName, newName]) => {
warning.deprecated(!(deprecatedName in props), deprecatedName, newName);
});
warning.deprecated(!('overlay' in props), 'overlay', 'menu');
}
const memoTransitionName = React.useMemo<string>(() => {
const rootPrefixCls = getPrefixCls();
@ -161,13 +137,6 @@ const Dropdown: CompoundedComponent = (props) => {
`You are using '${placement}' placement in Dropdown, which is deprecated. Try to use '${newPlacement}' instead.`,
);
}
[
['visible', 'open'],
['onVisibleChange', 'onOpenChange'],
].forEach(([deprecatedName, newName]) => {
warning.deprecated(!(deprecatedName in props), deprecatedName, newName);
});
}
const prefixCls = getPrefixCls('dropdown', customizePrefixCls);
@ -198,12 +167,11 @@ const Dropdown: CompoundedComponent = (props) => {
// =========================== Open ============================
const [mergedOpen, setOpen] = useMergedState(false, {
value: open ?? visible,
value: open,
});
const onInnerOpenChange = useEvent((nextOpen: boolean) => {
onOpenChange?.(nextOpen, { source: 'trigger' });
onVisibleChange?.(nextOpen);
setOpen(nextOpen);
});
@ -241,10 +209,6 @@ const Dropdown: CompoundedComponent = (props) => {
let overlayNode: React.ReactNode;
if (menu?.items) {
overlayNode = <Menu {...menu} />;
} else if (typeof overlay === 'function') {
overlayNode = overlay();
} else {
overlayNode = overlay;
}
if (dropdownRender) {
overlayNode = dropdownRender(overlayNode);

View File

@ -46,18 +46,18 @@ Common props ref[Common props](/docs/react/common-props)
| --- | --- | --- | --- | --- |
| arrow | Whether the dropdown arrow should be visible | boolean \| { pointAtCenter: boolean } | false | |
| autoAdjustOverflow | Whether to adjust dropdown placement automatically when dropdown is off screen | boolean | true | 5.2.0 |
| autoFocus | Focus element in `overlay` when opened | boolean | false | 4.21.0 |
| autoFocus | Focus element in `overlay` when opened | boolean | false | |
| disabled | Whether the dropdown menu is disabled | boolean | - | |
| destroyPopupOnHide | Whether destroy dropdown when hidden | boolean | false | |
| dropdownRender | Customize dropdown content | (menus: ReactNode) => ReactNode | - | 4.24.0 |
| dropdownRender | Customize dropdown content | (menus: ReactNode) => ReactNode | - | |
| getPopupContainer | To set the container of the dropdown menu. The default is to create a div element in body, but you can reset it to the scrolling area and make a relative reposition. [Example on CodePen](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | (triggerNode: HTMLElement) => HTMLElement | () => document.body | |
| menu | The menu props | [MenuProps](/components/menu/#api) | - | 4.24.0 |
| menu | The menu props | [MenuProps](/components/menu/#api) | - | |
| overlayClassName | The class name of the dropdown root element | string | - | |
| overlayStyle | The style of the dropdown root element | CSSProperties | - | |
| placement | Placement of popup menu: `bottom` `bottomLeft` `bottomRight` `top` `topLeft` `topRight` | string | `bottomLeft` | |
| trigger | The trigger mode which executes the dropdown action. Note that hover can't be used on touchscreens | Array&lt;`click`\|`hover`\|`contextMenu`> | \[`hover`] | |
| open | Whether the dropdown menu is currently open. Use `visible` under 4.23.0 ([why?](/docs/react/faq#why-open)) | boolean | - | 4.23.0 |
| onOpenChange | Called when the open state is changed. Not trigger when hidden by click item. Use `onVisibleChange` under 4.23.0 ([why?](/docs/react/faq#why-open)) | (open: boolean, info: { source: 'trigger' \| 'menu' }) => void | - | `info.source`: 5.11.0 |
| open | Whether the dropdown menu is currently open | boolean | - | |
| onOpenChange | Called when the open state is changed. Not trigger when hidden by click item | (open: boolean, info: { source: 'trigger' \| 'menu' }) => void | - | `info.source`: 5.11.0 |
### Dropdown.Button
@ -67,7 +67,7 @@ Same props from Dropdown. And includes additional props:
| --- | --- | --- | --- | --- |
| buttonsRender | Custom buttons inside Dropdown.Button | (buttons: ReactNode\[]) => ReactNode\[] | - | |
| loading | Set the loading status of button, the same as [Button](/components/button/#api) | boolean \| { delay: number, icon: ReactNode } | false | icon: 5.23.0 |
| danger | Set the danger status of button | boolean | - | 4.23.0 |
| danger | Set the danger status of button | boolean | - | |
| icon | Icon (appears on the right) | ReactNode | - | |
| size | Size of the button, the same as [Button](/components/button/#api) | string | `default` | |
| type | Type of the button, the same as [Button](/components/button/#api) | string | `default` | |

View File

@ -50,18 +50,18 @@ demo:
| --- | --- | --- | --- | --- |
| arrow | 下拉框箭头是否显示 | boolean \| { pointAtCenter: boolean } | false | |
| autoAdjustOverflow | 下拉框被遮挡时自动调整位置 | boolean | true | 5.2.0 |
| autoFocus | 打开后自动聚焦下拉框 | boolean | false | 4.21.0 |
| autoFocus | 打开后自动聚焦下拉框 | boolean | false | |
| disabled | 菜单是否禁用 | boolean | - | |
| destroyPopupOnHide | 关闭后是否销毁 Dropdown | boolean | false | |
| dropdownRender | 自定义下拉框内容 | (menus: ReactNode) => ReactNode | - | 4.24.0 |
| dropdownRender | 自定义下拉框内容 | (menus: ReactNode) => ReactNode | - | |
| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。[示例](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | (triggerNode: HTMLElement) => HTMLElement | () => document.body | |
| menu | 菜单配置项 | [MenuProps](/components/menu-cn#api) | - | 4.24.0 |
| menu | 菜单配置项 | [MenuProps](/components/menu-cn#api) | - | |
| overlayClassName | 下拉根元素的类名称 | string | - | |
| overlayStyle | 下拉根元素的样式 | CSSProperties | - | |
| placement | 菜单弹出位置:`bottom` `bottomLeft` `bottomRight` `top` `topLeft` `topRight` | string | `bottomLeft` | |
| trigger | 触发下拉的行为,移动端不支持 hover | Array&lt;`click`\|`hover`\|`contextMenu`> | \[`hover`] | |
| open | 菜单是否显示,小于 4.23.0 使用 `visible`[为什么?](/docs/react/faq#弹层类组件为什么要统一至-open-属性) | boolean | - | 4.23.0 |
| onOpenChange | 菜单显示状态改变时调用,点击菜单按钮导致的消失不会触发。小于 4.23.0 使用 `onVisibleChange`[为什么?](/docs/react/faq#弹层类组件为什么要统一至-open-属性) | (open: boolean, info: { source: 'trigger' \| 'menu' }) => void | - | `info.source`: 5.11.0 |
| open | 菜单是否显示 | boolean | - | |
| onOpenChange | 菜单显示状态改变时调用,点击菜单按钮导致的消失不会触发 | (open: boolean, info: { source: 'trigger' \| 'menu' }) => void | - | `info.source`: 5.11.0 |
### Dropdown.Button
@ -71,7 +71,7 @@ demo:
| --- | --- | --- | --- | --- |
| buttonsRender | 自定义左右两个按钮 | (buttons: ReactNode\[]) => ReactNode\[] | - | |
| loading | 设置按钮载入状态,和 [Button](/components/button-cn#api) 一致 | boolean \| { delay: number, icon: ReactNode } | false | icon: 5.23.0 |
| danger | 设置危险按钮 | boolean | - | 4.23.0 |
| danger | 设置危险按钮 | boolean | - | |
| icon | 右侧的 icon | ReactNode | - | |
| size | 按钮大小,和 [Button](/components/button-cn#api) 一致 | string | `default` | |
| type | 按钮类型,和 [Button](/components/button-cn#api) 一致 | string | `default` | |