Repository: ant-design/ant-design
Pull request #53285: feat(tree-select): popup support semantic dom and deprecated some api
Author: login: aojunhao123
Created: 2025-03-25T03:24:25Z | Merged: 2025-03-25T12:34:26Z

<!--
First of all, thank you for your contribution! 😄
For requesting to pull a new feature or bugfix, please send it from a feature/bugfix branch based on the `master` branch.
Before submitting your pull request, please make sure the checklist below is confirmed.
Your pull requests will be merged after one of the collaborators approve.
Thank you!
-->

[中文版模板 / Chinese template](https://github.com/ant-design/ant-design/blob/master/.github/PULL_REQUEST_TEMPLATE_CN.md?plain=1)

### 🤔 This is a ...

- [x] 🆕 New feature
- [x] 🛠 Refactoring

### 🔗 Related Issues

> - Describe the source of related requirements, such as links to relevant issue discussions.
> - For example: close #xxxx, fix #xxxx

### 💡 Background and Solution

> - The specific problem to be addressed.
> - List the final API implementation and usage if needed.
> - If there are UI/interaction changes, consider providing screenshots or GIFs.

### 📝 Change Log

> - Read [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) like a cat tracks a laser pointer.
> - Describe the impact of the changes on developers, not the solution approach.
> - Reference: https://ant.design/changelog

| Language   | Changelog |
| ---------- | --------- |
| 🇺🇸 English |   🆕 TreeSelect component adds popup semantic node, and deprecated some api        |
| 🇨🇳 Chinese |    🆕 TreeSelect 组件新增 popup 语义节点，并且废弃部分api       |



Diff:
diff --git a/components/space/demo/compact.tsx b/components/space/demo/compact.tsx
index f4a54bf188a0..c3d3167b7aab 100644
--- a/components/space/demo/compact.tsx
+++ b/components/space/demo/compact.tsx
@@ -175,7 +175,9 @@ const App: React.FC = () => (
         showSearch
         style={{ width: '60%' }}
         value="leaf1"
-        dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+        styles={{
+          popup: { maxHeight: 400, overflow: 'auto' },
+        }}
         placeholder="Please select"
         allowClear
         treeDefaultExpandAll
diff --git a/components/tree-select/__tests__/index.test.tsx b/components/tree-select/__tests__/index.test.tsx
index f039ed874baa..d6386f4d92de 100644
--- a/components/tree-select/__tests__/index.test.tsx
+++ b/components/tree-select/__tests__/index.test.tsx
@@ -5,7 +5,7 @@ import { resetWarned } from '../../_util/warning';
 import focusTest from '../../../tests/shared/focusTest';
 import mountTest from '../../../tests/shared/mountTest';
 import rtlTest from '../../../tests/shared/rtlTest';
-import { render } from '../../../tests/utils';
+import { render, fireEvent } from '../../../tests/utils';
 
 describe('TreeSelect', () => {
   focusTest(TreeSelect, { refFocus: true });
@@ -54,20 +54,33 @@ describe('TreeSelect', () => {
     expect(container.querySelector('.ant-select-empty')?.innerHTML).toBe(content);
   });
 
+  it('legacy popupClassName', () => {
+    resetWarned();
+
+    const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
+    const { container } = render(<TreeSelect popupClassName="legacy" open />);
+    expect(errSpy).toHaveBeenCalledWith(
+      'Warning: [antd: TreeSelect] `popupClassName` is deprecated. Please use `classNames.popup` instead.',
+    );
+    expect(container.querySelector('.legacy')).toBeTruthy();
+
+    errSpy.mockRestore();
+  });
+
   it('legacy dropdownClassName', () => {
     resetWarned();
 
     const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
     const { container } = render(<TreeSelect dropdownClassName="legacy" open />);
     expect(errSpy).toHaveBeenCalledWith(
-      'Warning: [antd: TreeSelect] `dropdownClassName` is deprecated. Please use `popupClassName` instead.',
+      'Warning: [antd: TreeSelect] `dropdownClassName` is deprecated. Please use `classNames.popup` instead.',
     );
     expect(container.querySelector('.legacy')).toBeTruthy();
 
     errSpy.mockRestore();
   });
 
-  it('warning for legacy dropdownMatchSelectWidth', () => {
+  it('legacy dropdownMatchSelectWidth', () => {
     resetWarned();
 
     const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
@@ -79,6 +92,52 @@ describe('TreeSelect', () => {
     errSpy.mockRestore();
   });
 
+  it('legacy dropdownStyle', () => {
+    resetWarned();
+
+    const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
+    const { container } = render(<TreeSelect dropdownStyle={{ color: 'red' }} open />);
+    expect(errSpy).toHaveBeenCalledWith(
+      'Warning: [antd: TreeSelect] `dropdownStyle` is deprecated. Please use `styles.popup` instead.',
+    );
+    expect(container.querySelector('.ant-select-dropdown')).toBeTruthy();
+
+    errSpy.mockRestore();
+  });
+
+  it('legacy dropdownRender', () => {
+    resetWarned();
+
+    const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
+    const { container } = render(
+      <TreeSelect dropdownRender={(menu) => <div className="custom-dropdown">{menu}</div>} open />,
+    );
+    expect(errSpy).toHaveBeenCalledWith(
+      'Warning: [antd: TreeSelect] `dropdownRender` is deprecated. Please use `popupRender` instead.',
+    );
+    expect(container.querySelector('.custom-dropdown')).toBeTruthy();
+
+    errSpy.mockRestore();
+  });
+
+  it('legacy onDropdownVisibleChange', () => {
+    resetWarned();
+
+    const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
+    const onDropdownVisibleChange = jest.fn();
+
+    const { container } = render(<TreeSelect onDropdownVisibleChange={onDropdownVisibleChange} />);
+
+    expect(errSpy).toHaveBeenCalledWith(
+      'Warning: [antd: TreeSelect] `onDropdownVisibleChange` is deprecated. Please use `onOpenChange` instead.',
+    );
+
+    fireEvent.mouseDown(container.querySelector('.ant-select-selector')!);
+    expect(onDropdownVisibleChange).toHaveBeenCalled();
+
+    errSpy.mockRestore();
+  });
+
   it('support aria-*', async () => {
     const { container } = render(
       <TreeSelect
diff --git a/components/tree-select/demo/_semantic.tsx b/components/tree-select/demo/_semantic.tsx
new file mode 100644
index 000000000000..0d671490fb96
--- /dev/null
+++ b/components/tree-select/demo/_semantic.tsx
@@ -0,0 +1,74 @@
+import React from 'react';
+import { TreeSelect } from 'antd';
+
+import SemanticPreview from '../../../.dumi/components/SemanticPreview';
+import useLocale from '../../../.dumi/hooks/useLocale';
+
+const locales = {
+  cn: {
+    popup: '弹出菜单元素',
+  },
+  en: {
+    popup: 'Popup element',
+  },
+};
+const treeData = [
+  {
+    value: 'contributors',
+    title: 'contributors',
+    children: [
+      {
+        value: 'thinkasany',
+        title: 'thinkasany',
+      },
+      {
+        value: 'aojunhao123',
+        title: 'aojunhao123',
+      },
+    ],
+  },
+];
+
+const Block = (props: any) => {
+  const divRef = React.useRef<HTMLDivElement>(null);
+  const [value, setValue] = React.useState<string>();
+  const onChange = (newValue: string) => {
+    setValue(newValue);
+  };
+  return (
+    <div ref={divRef}>
+      <TreeSelect
+        {...props}
+        getPopupContainer={() => divRef.current}
+        showSearch
+        placement="bottomLeft"
+        open
+        style={{ marginBottom: 100, width: 200 }}
+        styles={{
+          popup: {
+            zIndex: 1,
+          },
+        }}
+        value={value}
+        placeholder="Please select"
+        treeDefaultExpandAll
+        onChange={onChange}
+        treeData={treeData}
+      />
+    </div>
+  );
+};
+const App: React.FC = () => {
+  const [locale] = useLocale(locales);
+
+  return (
+    <SemanticPreview
+      semantics={[{ name: 'popup', desc: locale.popup, version: '5.25.0' }]}
+      height={200}
+    >
+      <Block />
+    </SemanticPreview>
+  );
+};
+
+export default App;
diff --git a/components/tree-select/demo/async.tsx b/components/tree-select/demo/async.tsx
index ca3310974808..0c7ae9d0795a 100644
--- a/components/tree-select/demo/async.tsx
+++ b/components/tree-select/demo/async.tsx
@@ -43,7 +43,9 @@ const App: React.FC = () => {
       treeDataSimpleMode
       style={{ width: '100%' }}
       value={value}
-      dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+      styles={{
+        popup: { maxHeight: 400, overflow: 'auto' },
+      }}
       placeholder="Please select"
       onChange={onChange}
       loadData={onLoadData}
diff --git a/components/tree-select/demo/basic.tsx b/components/tree-select/demo/basic.tsx
index bd18b4eb0fac..da228bc1a7a7 100644
--- a/components/tree-select/demo/basic.tsx
+++ b/components/tree-select/demo/basic.tsx
@@ -66,7 +66,9 @@ const App: React.FC = () => {
       showSearch
       style={{ width: '100%' }}
       value={value}
-      dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+      styles={{
+        popup: { maxHeight: 400, overflow: 'auto' },
+      }}
       placeholder="Please select"
       allowClear
       treeDefaultExpandAll
diff --git a/components/tree-select/demo/multiple.tsx b/components/tree-select/demo/multiple.tsx
index d9dd976ba7b0..e6b43a39c4bc 100644
--- a/components/tree-select/demo/multiple.tsx
+++ b/components/tree-select/demo/multiple.tsx
@@ -46,7 +46,9 @@ const App: React.FC = () => {
       showSearch
       style={{ width: '100%' }}
       value={value}
-      dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+      styles={{
+        popup: { maxHeight: 400, overflow: 'auto' },
+      }}
       placeholder="Please select"
       allowClear
       multiple
diff --git a/components/tree-select/demo/placement.tsx b/components/tree-select/demo/placement.tsx
index 2b5fff4d5d41..99b5779a1428 100644
--- a/components/tree-select/demo/placement.tsx
+++ b/components/tree-select/demo/placement.tsx
@@ -56,7 +56,9 @@ const App: React.FC = () => {
 
       <TreeSelect
         showSearch
-        dropdownStyle={{ maxHeight: 400, overflow: 'auto', minWidth: 300 }}
+        styles={{
+          popup: { maxHeight: 400, overflow: 'auto', minWidth: 300 },
+        }}
         placeholder="Please select"
         popupMatchSelectWidth={false}
         placement={placement}
diff --git a/components/tree-select/demo/suffix.tsx b/components/tree-select/demo/suffix.tsx
index a5523881a656..dc70f899578f 100644
--- a/components/tree-select/demo/suffix.tsx
+++ b/components/tree-select/demo/suffix.tsx
@@ -51,7 +51,9 @@ const App: React.FC = () => {
         suffixIcon={icon}
         style={{ width: '100%' }}
         value={value}
-        dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+        styles={{
+          popup: { maxHeight: 400, overflow: 'auto' },
+        }}
         placeholder="Please select"
         allowClear
         treeDefaultExpandAll
@@ -65,7 +67,9 @@ const App: React.FC = () => {
         prefix="Prefix"
         style={{ width: '100%' }}
         value={value}
-        dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+        styles={{
+          popup: { maxHeight: 400, overflow: 'auto' },
+        }}
         placeholder="Please select"
         allowClear
         treeDefaultExpandAll
diff --git a/components/tree-select/demo/treeData.tsx b/components/tree-select/demo/treeData.tsx
index a39b803e7bf7..e0b4b595b79e 100644
--- a/components/tree-select/demo/treeData.tsx
+++ b/components/tree-select/demo/treeData.tsx
@@ -34,7 +34,9 @@ const App: React.FC = () => {
     <TreeSelect
       style={{ width: '100%' }}
       value={value}
-      dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
+      styles={{
+        popup: { maxHeight: 400, overflow: 'auto' },
+      }}
       treeData={treeData}
       placeholder="Please select"
       treeDefaultExpandAll
diff --git a/components/tree-select/index.en-US.md b/components/tree-select/index.en-US.md
index 0b9abc8281c1..9e903bf21804 100644
--- a/components/tree-select/index.en-US.md
+++ b/components/tree-select/index.en-US.md
@@ -42,10 +42,11 @@ Common props ref：[Common props](/docs/react/common-props)
 | autoClearSearchValue | If auto clear search input value when multiple select is selected/deselected | boolean | true |  |
 | defaultValue | To set the initial selected treeNode(s) | string \| string\[] | - |  |
 | disabled | Disabled or not | boolean | false |  |
-| popupClassName | The className of dropdown menu | string | - | 4.23.0 |
+| ~~popupClassName~~ | The className of dropdown menu, use `classNames.popup` instead | string | - | 4.23.0 |
 | popupMatchSelectWidth | Determine whether the popup menu and the select input are the same width. Default set `min-width` same as input. Will ignore when value less than select width. `false` will disable virtual scroll | boolean \| number | true | 5.5.0 |
-| dropdownRender | Customize dropdown content | (originNode: ReactNode, props) => ReactNode | - |  |
-| dropdownStyle | To set the style of the dropdown menu | CSSProperties | - |  |
+| ~~dropdownRender~~ | Customize dropdown content, use `popupRender` instead | (originNode: ReactNode, props) => ReactNode | - |  |
+| popupRender | Customize dropdown content | (originNode: ReactNode, props) => ReactNode | - |  |
+| ~~dropdownStyle~~ | To set the style of the dropdown menu, use `styles.popup` instead | CSSProperties | - |  |
 | fieldNames | Customize node label, value, children field name | object | { label: `label`, value: `value`, children: `children` } | 4.17.0 |
 | filterTreeNode | Whether to filter treeNodes by input value. The value of `treeNodeFilterProp` is used for filtering by default | boolean \| function(inputValue: string, treeNode: TreeNode) (should return boolean) | function |  |
 | getPopupContainer | To set the container of the dropdown menu. The default is to create a `div` element in `body`, you can reset it to the scrolling area and make a relative reposition. [example](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | function(triggerNode) | () => document.body |  |
@@ -87,7 +88,7 @@ Common props ref：[Common props](/docs/react/common-props)
 | variant | Variants of selector | `outlined` \| `borderless` \| `filled` \| `underlined` | `outlined` | 5.13.0 \| `underlined`: 5.24.0 |
 | virtual | Disable virtual scroll when set to false | boolean | true | 4.1.0 |
 | onChange | A callback function, can be executed when selected treeNodes or input value change | function(value, label, extra) | - |  |
-| onDropdownVisibleChange | Called when dropdown open | function(open) | - |  |
+| ~~onDropdownVisibleChange~~ | Called when dropdown open, use `onOpenChange` instead | function(open) | - |  |
 | onSearch | A callback function, can be executed when the search input changes | function(value: string) | - |  |
 | onSelect | A callback function, can be executed when you select a treeNode | function(value, node, extra) | - |  |
 | onTreeExpand | A callback function, can be executed when treeNode expanded | function(expandedKeys) | - |  |
@@ -115,6 +116,10 @@ Common props ref：[Common props](/docs/react/common-props)
 | title | Content showed on the treeNodes | ReactNode | `---` |  |
 | value | Will be treated as `treeNodeFilterProp` by default, should be unique in the tree | string | - |  |
 
+## Semantic DOM
+
+<code src="./demo/_semantic.tsx" simplify="true"></code>
+
 ## Design Token
 
 <ComponentTokenTable component="TreeSelect"></ComponentTokenTable>
diff --git a/components/tree-select/index.tsx b/components/tree-select/index.tsx
index 93d36b707d39..a41f8d8d072c 100644
--- a/components/tree-select/index.tsx
+++ b/components/tree-select/index.tsx
@@ -1,5 +1,5 @@
 import * as React from 'react';
-import classNames from 'classnames';
+import cls from 'classnames';
 import type { BaseSelectRef } from 'rc-select';
 import type { Placement } from 'rc-select/lib/BaseSelect';
 import type { TreeSelectProps as RcTreeSelectProps } from 'rc-tree-select';
@@ -36,6 +36,8 @@ import useStyle from './style';
 
 type RawValue = string | number;
 
+type SemanticName = 'popup';
+
 export interface LabeledValue {
   key?: string;
   value: RawValue;
@@ -59,9 +61,18 @@ export interface TreeSelectProps<ValueType = any, OptionType extends DataNode =
   size?: SizeType;
   disabled?: boolean;
   placement?: SelectCommonPlacement;
+  /** @deprecated Please use `classNames.popup` instead */
   popupClassName?: string;
-  /** @deprecated Please use `popupClassName` instead */
+  /** @deprecated Please use `classNames.popup` instead */
   dropdownClassName?: string;
+  /** @deprecated Please use `popupRender` instead */
+  dropdownRender?: (menu: React.ReactElement) => React.ReactElement;
+  popupRender?: (menu: React.ReactElement) => React.ReactElement;
+  /** @deprecated Please use `styles.popup` instead */
+  dropdownStyle?: React.CSSProperties;
+  /** @deprecated Please use `onOpenChange` instead */
+  onDropdownVisibleChange?: (visible: boolean) => void;
+  onOpenChange?: (open: boolean) => void;
   /** @deprecated Use `variant` instead. */
   bordered?: boolean;
   treeLine?: TreeProps['showLine'];
@@ -82,6 +93,8 @@ export interface TreeSelectProps<ValueType = any, OptionType extends DataNode =
    * @default "outlined"
    */
   variant?: Variant;
+  classNames?: Partial<Record<SemanticName, string>>;
+  styles?: Partial<Record<SemanticName, React.CSSProperties>>;
 }
 
 const InternalTreeSelect = <ValueType = any, OptionType extends DataNode = DataNode>(
@@ -117,10 +130,16 @@ const InternalTreeSelect = <ValueType = any, OptionType extends DataNode = DataN
     allowClear,
     variant: customVariant,
     dropdownStyle,
+    dropdownRender,
+    popupRender,
+    onDropdownVisibleChange,
+    onOpenChange,
     tagRender,
     maxCount,
     showCheckedStrategy,
     treeCheckStrictly,
+    styles,
+    classNames,
     ...restProps
   } = props;
   const {
@@ -139,27 +158,31 @@ const InternalTreeSelect = <ValueType = any, OptionType extends DataNode = DataN
   if (process.env.NODE_ENV !== 'production') {
     const warning = devUseWarning('TreeSelect');
 
+    const deprecatedProps = {
+      dropdownMatchSelectWidth: 'popupMatchSelectWidth',
+      dropdownStyle: 'styles.popup',
+      dropdownClassName: 'classNames.popup',
+      popupClassName: 'classNames.popup',
+      dropdownRender: 'popupRender',
+      onDropdownVisibleChange: 'onOpenChange',
+      bordered: 'variant',
+    };
+
+    Object.entries(deprecatedProps).forEach(([oldProp, newProp]) => {
+      warning.deprecated(!(oldProp in props), oldProp, newProp);
+    });
+
     warning(
       multiple !== false || !treeCheckable,
       'usage',
       '`multiple` will always be `true` when `treeCheckable` is true',
     );
 
-    warning.deprecated(!dropdownClassName, 'dropdownClassName', 'popupClassName');
-
-    warning.deprecated(
-      dropdownMatchSelectWidth === undefined,
-      'dropdownMatchSelectWidth',
-      'popupMatchSelectWidth',
-    );
-
     warning(
       !('showArrow' in props),
       'deprecated',
       '`showArrow` is deprecated which will be removed in next major version. It will be a default behavior, you can hide it by setting `suffixIcon` to null.',
     );
-
-    warning.deprecated(!('bordered' in props), 'bordered', 'variant');
   }
 
   const rootPrefixCls = getPrefixCls();
@@ -175,8 +198,8 @@ const InternalTreeSelect = <ValueType = any, OptionType extends DataNode = DataN
 
   const [variant, enableVariantCls] = useVariant('treeSelect', customVariant, bordered);
 
-  const mergedDropdownClassName = classNames(
-    popupClassName || dropdownClassName,
+  const mergedPopupClassName = cls(
+    classNames?.popup || popupClassName || dropdownClassName,
     `${treeSelectPrefixCls}-dropdown`,
     {
       [`${treeSelectPrefixCls}-dropdown-rtl`]: direction === 'rtl',
@@ -188,6 +211,10 @@ const InternalTreeSelect = <ValueType = any, OptionType extends DataNode = DataN
     hashId,
   );
 
+  const mergedPopupStyle = styles?.popup || dropdownStyle;
+  const mergedPopupRender = popupRender || dropdownRender;
+  const mergedOnOpenChange = onOpenChange || onDropdownVisibleChange;
+
   const isMultiple = !!(treeCheckable || multiple);
 
   const mergedMaxCount = React.useMemo(() => {
@@ -259,7 +286,7 @@ const InternalTreeSelect = <ValueType = any, OptionType extends DataNode = DataN
   const disabled = React.useContext(DisabledContext);
   const mergedDisabled = customDisabled ?? disabled;
 
-  const mergedClassName = classNames(
+  const mergedClassName = cls(
     !customizePrefixCls && treeSelectPrefixCls,
     {
       [`${prefixCls}-lg`]: mergedSize === 'large',
@@ -288,7 +315,7 @@ const InternalTreeSelect = <ValueType = any, OptionType extends DataNode = DataN
   );
 
   // ============================ zIndex ============================
-  const [zIndex] = useZIndex('SelectLike', dropdownStyle?.zIndex as number);
+  const [zIndex] = useZIndex('SelectLike', mergedPopupStyle?.zIndex as number);
 
   const returnNode = (
     <RcTreeSelect
@@ -316,8 +343,10 @@ const InternalTreeSelect = <ValueType = any, OptionType extends DataNode = DataN
       notFoundContent={mergedNotFound}
       getPopupContainer={getPopupContainer || getContextPopupContainer}
       treeMotion={null}
-      dropdownClassName={mergedDropdownClassName}
-      dropdownStyle={{ ...dropdownStyle, zIndex }}
+      dropdownClassName={mergedPopupClassName}
+      dropdownStyle={{ ...mergedPopupStyle, zIndex }}
+      dropdownRender={mergedPopupRender}
+      onDropdownVisibleChange={mergedOnOpenChange}
       choiceTransitionName={getTransitionName(rootPrefixCls, '', choiceTransitionName)}
       transitionName={getTransitionName(rootPrefixCls, 'slide-up', transitionName)}
       treeExpandAction={treeExpandAction}
diff --git a/components/tree-select/index.zh-CN.md b/components/tree-select/index.zh-CN.md
index e4a8574ef8fe..de14811b594c 100644
--- a/components/tree-select/index.zh-CN.md
+++ b/components/tree-select/index.zh-CN.md
@@ -43,10 +43,11 @@ demo:
 | autoClearSearchValue | 当多选模式下值被选择，自动清空搜索框 | boolean | true |  |
 | defaultValue | 指定默认选中的条目 | string \| string\[] | - |  |
 | disabled | 是否禁用 | boolean | false |  |
-| popupClassName | 下拉菜单的 className 属性 | string | - | 4.23.0 |
+| ~~popupClassName~~ | 下拉菜单的 className 属性，使用 `classNames.popup` 替换 | string | - | 4.23.0 |
 | popupMatchSelectWidth | 下拉菜单和选择器同宽。默认将设置 `min-width`，当值小于选择框宽度时会被忽略。false 时会关闭虚拟滚动 | boolean \| number | true | 5.5.0 |
-| dropdownRender | 自定义下拉框内容 | (originNode: ReactNode, props) => ReactNode | - |  |
-| dropdownStyle | 下拉菜单的样式 | object | - |  |
+| ~~dropdownRender~~ | 自定义下拉框内容，使用 `popupRender` 替换 | (originNode: ReactNode, props) => ReactNode | - |  |
+| popupRender | 自定义下拉框内容 | (originNode: ReactNode, props) => ReactNode | - |  |
+| ~~dropdownStyle~~ | 下拉菜单的样式，使用 `styles.popup` 替换 | object | - |  |
 | fieldNames | 自定义节点 label、value、children 的字段 | object | { label: `label`, value: `value`, children: `children` } | 4.17.0 |
 | filterTreeNode | 是否根据输入项进行筛选，默认用 treeNodeFilterProp 的值作为要筛选的 TreeNode 的属性值 | boolean \| function(inputValue: string, treeNode: TreeNode) (函数需要返回 bool 值) | function |  |
 | getPopupContainer | 菜单渲染父节点。默认渲染到 body 上，如果你遇到菜单滚动定位问题，试试修改为滚动的区域，并相对其定位。[示例](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | function(triggerNode) | () => document.body |  |
@@ -88,7 +89,8 @@ demo:
 | variant | 形态变体 | `outlined` \| `borderless` \| `filled` \| `underlined` | `outlined` | 5.13.0 \| `underlined`: 5.24.0 |
 | virtual | 设置 false 时关闭虚拟滚动 | boolean | true | 4.1.0 |
 | onChange | 选中树节点时调用此函数 | function(value, label, extra) | - |  |
-| onDropdownVisibleChange | 展开下拉菜单的回调 | function(open) | - |  |
+| ~~onDropdownVisibleChange~~ | 展开下拉菜单的回调，使用 `onOpenChange` 替换 | (open: boolean) => void | - |  |
+| onOpenChange | 展开下拉菜单的回调 | (open: boolean) => void | - |  |
 | onSearch | 文本框值变化时的回调 | function(value: string) | - |  |
 | onSelect | 被选中时调用 | function(value, node, extra) | - |  |
 | onTreeExpand | 展示节点时调用 | function(expandedKeys) | - |  |
@@ -116,6 +118,10 @@ demo:
 | title           | 树节点显示的内容                                   | ReactNode | `---`  |      |
 | value           | 默认根据此属性值进行筛选（其值在整个树范围内唯一） | string    | -      |      |
 
+## 语义化 DOM（Semantic DOM）
+
+<code src="./demo/_semantic.tsx" simplify="true"></code>
+
 ## 主题变量（Design Token）
 
 <ComponentTokenTable component="TreeSelect"></ComponentTokenTable>


Reviews:
user: login: petercat-assistant[bot]
state: COMMENTED
author_association: NONE
submitted_at: 2025-03-25T03:24:41Z
user: login: thinkasany
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-25T03:27:44Z
user: login: Wxh16144
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-25T03:28:23Z
user: login: aojunhao123
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T03:31:22Z
user: login: Wxh16144
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-25T03:32:31Z
user: login: thinkasany
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-25T03:33:14Z
user: login: thinkasany
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-25T03:33:42Z
user: login: aojunhao123
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T03:34:10Z
user: login: thinkasany
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-25T03:43:09Z
user: login: Wxh16144
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-25T03:45:48Z
user: login: aojunhao123
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T03:46:39Z
user: login: aojunhao123
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T05:38:47Z
user: login: thinkasany
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-25T06:06:17Z
user: login: zombieJ
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-25T12:34:17Z

Review comments:
diff_hunk: @@ -139,27 +158,31 @@ const InternalTreeSelect = <ValueType = any, OptionType extends DataNode = DataN
   if (process.env.NODE_ENV !== 'production') {
     const warning = devUseWarning('TreeSelect');
 
+    const deprecatedProps = {
+      dropdownMatchSelectWidth: 'popupMatchSelectWidth',
+      dropdownStyle: 'styles.popup',
+      dropdownClassName: 'classNames.popup',
+      popupClassName: 'classNames.popup',
+      dropdownRender: 'popupRender',
+      onDropdownVisibleChange: 'onOpenChange',
+      bordered: 'variant',
+    };
+
+    Object.entries(deprecatedProps).forEach(([oldProp, newProp]) => {
+      warning.deprecated(!(oldProp in props), oldProp, newProp);
path: components/tree-select/index.tsx
user: login: petercat-assistant[bot]
body: Ensure that all deprecated properties are properly warned and replaced with the new semantic alternatives. This is crucial to maintain backward compatibility while encouraging the use of updated properties.
created_at: 2025-03-25T03:24:41Z
author_association: NONE
diff_hunk: @@ -116,6 +118,10 @@ demo:
 | title           | 树节点显示的内容                                   | ReactNode | `---`  |      |
 | value           | 默认根据此属性值进行筛选（其值在整个树范围内唯一） | string    | -      |      |
 
+## 语义化DOM（Semantic DOM）
path: components/tree-select/index.zh-CN.md
user: login: thinkasany
body: 这个好像不需要中文，其他地方都没加，为了方标锚点定位精准的调过来。  dumi 对锚点定位自定义的支持不太理想。
created_at: 2025-03-25T03:27:31Z
author_association: MEMBER
diff_hunk: @@ -54,20 +54,33 @@ describe('TreeSelect', () => {
     expect(container.querySelector('.ant-select-empty')?.innerHTML).toBe(content);
   });
 
+  it('legacy popupClassName', () => {
+    resetWarned();
+
+    const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
+    const { container } = render(<TreeSelect popupClassName="legacy" open />);
+    expect(errSpy).toHaveBeenCalledWith(
+      'Warning: [antd: TreeSelect] `popupClassName` is deprecated. Please use `classNames.popup` instead.',
+    );
+    expect(container.querySelector('.legacy')).toBeTruthy();
+
+    errSpy.mockRestore();
+  });
+
   it('legacy dropdownClassName', () => {
     resetWarned();
 
     const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
     const { container } = render(<TreeSelect dropdownClassName="legacy" open />);
     expect(errSpy).toHaveBeenCalledWith(
-      'Warning: [antd: TreeSelect] `dropdownClassName` is deprecated. Please use `popupClassName` instead.',
+      'Warning: [antd: TreeSelect] `dropdownClassName` is deprecated. Please use `classNames.popup` instead.',
     );
path: components/tree-select/__tests__/index.test.tsx
user: login: Wxh16144
body: 6666
created_at: 2025-03-25T03:28:23Z
author_association: MEMBER
diff_hunk: @@ -116,6 +118,10 @@ demo:
 | title           | 树节点显示的内容                                   | ReactNode | `---`  |      |
 | value           | 默认根据此属性值进行筛选（其值在整个树范围内唯一） | string    | -      |      |
 
+## 语义化DOM（Semantic DOM）
path: components/tree-select/index.zh-CN.md
user: login: aojunhao123
body: ![QQ_1742873456643](https://github.com/user-attachments/assets/d7ec3321-1cfb-403a-95ef-bc0355db0883)
但是感觉得对齐一下，要么都加要么都不加了
created_at: 2025-03-25T03:31:22Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,70 @@
+import React from 'react';
+import { TreeSelect } from 'antd';
+
+import SemanticPreview from '../../../.dumi/components/SemanticPreview';
+import useLocale from '../../../.dumi/hooks/useLocale';
+
+const locales = {
+  cn: {
+    popup: '弹出菜单元素',
+  },
+  en: {
+    popup: 'Popup element',
+  },
+};
+const treeData = [
+  {
+    value: 'aojunhao123',
+    title: 'aojunhao123',
+    children: [
+      {
+        value: 'thinkasany',
+        title: 'thinkasany',
+      },
+    ],
+  },
+];
path: components/tree-select/demo/_semantic.tsx
user: login: Wxh16144
body: 这个 mock 可别这样写，容易被人误读。(逃～
created_at: 2025-03-25T03:32:30Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,70 @@
+import React from 'react';
+import { TreeSelect } from 'antd';
+
+import SemanticPreview from '../../../.dumi/components/SemanticPreview';
+import useLocale from '../../../.dumi/hooks/useLocale';
+
+const locales = {
+  cn: {
+    popup: '弹出菜单元素',
+  },
+  en: {
+    popup: 'Popup element',
+  },
+};
+const treeData = [
+  {
+    value: 'aojunhao123',
+    title: 'aojunhao123',
+    children: [
+      {
+        value: 'thinkasany',
+        title: 'thinkasany',
+      },
+    ],
+  },
+];
path: components/tree-select/demo/_semantic.tsx
user: login: thinkasany
body: 我也觉得我吃大亏了
created_at: 2025-03-25T03:33:12Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,70 @@
+import React from 'react';
+import { TreeSelect } from 'antd';
+
+import SemanticPreview from '../../../.dumi/components/SemanticPreview';
+import useLocale from '../../../.dumi/hooks/useLocale';
+
+const locales = {
+  cn: {
+    popup: '弹出菜单元素',
+  },
+  en: {
+    popup: 'Popup element',
+  },
+};
+const treeData = [
+  {
+    value: 'aojunhao123',
+    title: 'aojunhao123',
+    children: [
+      {
+        value: 'thinkasany',
+        title: 'thinkasany',
+      },
+    ],
+  },
+];
path: components/tree-select/demo/_semantic.tsx
user: login: thinkasany
body: 第一层要不然用个 contributors
created_at: 2025-03-25T03:33:42Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,70 @@
+import React from 'react';
+import { TreeSelect } from 'antd';
+
+import SemanticPreview from '../../../.dumi/components/SemanticPreview';
+import useLocale from '../../../.dumi/hooks/useLocale';
+
+const locales = {
+  cn: {
+    popup: '弹出菜单元素',
+  },
+  en: {
+    popup: 'Popup element',
+  },
+};
+const treeData = [
+  {
+    value: 'aojunhao123',
+    title: 'aojunhao123',
+    children: [
+      {
+        value: 'thinkasany',
+        title: 'thinkasany',
+      },
+    ],
+  },
+];
path: components/tree-select/demo/_semantic.tsx
user: login: aojunhao123
body: 想留个水印来着😂，但是数据不能太长否则展示效果很怪，我就写成这样了🤥
created_at: 2025-03-25T03:34:10Z
author_association: CONTRIBUTOR
diff_hunk: @@ -116,6 +118,10 @@ demo:
 | title           | 树节点显示的内容                                   | ReactNode | `---`  |      |
 | value           | 默认根据此属性值进行筛选（其值在整个树范围内唯一） | string    | -      |      |
 
+## 语义化DOM（Semantic DOM）
path: components/tree-select/index.zh-CN.md
user: login: thinkasany
body: 能精准跳回来不，不知道中文会不会起到干预。 dumi 这个锚点不能自定义很难受，不然肯定是你这么做比较好。
![image](https://github.com/user-attachments/assets/8270b12e-7d90-4407-9363-279093462ecd)

created_at: 2025-03-25T03:43:09Z
author_association: MEMBER
diff_hunk: @@ -139,27 +158,31 @@ const InternalTreeSelect = <ValueType = any, OptionType extends DataNode = DataN
   if (process.env.NODE_ENV !== 'production') {
     const warning = devUseWarning('TreeSelect');
 
+    const deprecatedProps = {
+      dropdownMatchSelectWidth: 'popupMatchSelectWidth',
+      dropdownStyle: 'styles.popup',
+      dropdownClassName: 'classNames.popup',
+      popupClassName: 'classNames.popup',
+      dropdownRender: 'popupRender',
+      onDropdownVisibleChange: 'onOpenChange',
+      bordered: 'variant',
+    };
path: components/tree-select/index.tsx
user: login: Wxh16144
body: 这部分如果可以的话，在边上加上注释，看一下文件的 histary， 比如 `onOpenChange` 我不太确定是否是在 v4 就加入的弃用提醒。

规则是 v5 提示弃用，v6保留一个 major， v7 删除

比如可以这样：

```tsx
 const deprecatedProps = {
      dropdownMatchSelectWidth: 'popupMatchSelectWidth',
      dropdownStyle: 'styles.popup', // v7 can be safely deleted // 这种就可以先不标注
      dropdownClassName: 'classNames.popup',
      popupClassName: 'classNames.popup',
      dropdownRender: 'popupRender',
      onDropdownVisibleChange: 'onOpenChange', // V6 can be safely deleted // 这种可以先标起来。
      bordered: 'variant',
    };
```

如果都是 v5才标记弃用的话，那就是我多虑了。直接标记为偏题吧 23333

created_at: 2025-03-25T03:45:48Z
author_association: MEMBER
diff_hunk: @@ -116,6 +118,10 @@ demo:
 | title           | 树节点显示的内容                                   | ReactNode | `---`  |      |
 | value           | 默认根据此属性值进行筛选（其值在整个树范围内唯一） | string    | -      |      |
 
+## 语义化DOM（Semantic DOM）
path: components/tree-select/index.zh-CN.md
user: login: aojunhao123
body: 我这边试了一下是可以的
![QQ_1742874380596](https://github.com/user-attachments/assets/fcbbf673-6ba5-447b-b67c-48569692e7b9)

created_at: 2025-03-25T03:46:38Z
author_association: CONTRIBUTOR
diff_hunk: @@ -139,27 +158,31 @@ const InternalTreeSelect = <ValueType = any, OptionType extends DataNode = DataN
   if (process.env.NODE_ENV !== 'production') {
     const warning = devUseWarning('TreeSelect');
 
+    const deprecatedProps = {
+      dropdownMatchSelectWidth: 'popupMatchSelectWidth',
+      dropdownStyle: 'styles.popup',
+      dropdownClassName: 'classNames.popup',
+      popupClassName: 'classNames.popup',
+      dropdownRender: 'popupRender',
+      onDropdownVisibleChange: 'onOpenChange',
+      bordered: 'variant',
+    };
path: components/tree-select/index.tsx
user: login: aojunhao123
body: `onDropdownVisibleChange` 也是v5标记废弃的
created_at: 2025-03-25T05:38:47Z
author_association: CONTRIBUTOR
diff_hunk: @@ -116,6 +118,10 @@ demo:
 | title           | 树节点显示的内容                                   | ReactNode | `---`  |      |
 | value           | 默认根据此属性值进行筛选（其值在整个树范围内唯一） | string    | -      |      |
 
+## 语义化DOM（Semantic DOM）
path: components/tree-select/index.zh-CN.md
user: login: thinkasany
body: 可以的话，``` 语义化 DOM ``` , 加个空格吧。 不过我也不确定要不要这么改，等豆酱看看，要改的话，估计所有地方都要替换一下。
created_at: 2025-03-25T06:06:12Z
author_association: MEMBER

PR comments:
user: login: bolt-new-by-stackblitz[bot]
created_at: 2025-03-25T03:24:27Z
body: <a href="https://stackblitz.com/~/github.com/ant-design/ant-design/pull/53285"><img src="https://developer.stackblitz.com/img/review_pr_small.svg" alt="Review PR in StackBlitz Codeflow" align="left" width="103" height="20"></a> _Run & review this pull request in [StackBlitz Codeflow](https://stackblitz.com/~/github.com/ant-design/ant-design/pull/53285)._

author_association: NONE
user: login: coderabbitai[bot]
created_at: 2025-03-25T03:24:32Z
body: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- This is an auto-generated comment: skip review by coderabbit.ai -->

> [!IMPORTANT]
> ## Review skipped
> 
> Auto reviews are disabled on base/target branches other than the default branch.
> 
> 
> 
> Please check the settings in the CodeRabbit UI or the `.coderabbit.yaml` file in this repository. To trigger a single review, invoke the `@coderabbitai review` command.
> 
> You can disable this status message by setting the `reviews.review_status` to `false` in the CodeRabbit configuration file.

<!-- end of auto-generated comment: skip review by coderabbit.ai -->
<!-- tips_start -->

---

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=ant-design/ant-design&utm_content=53285):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Generate unit testing code for this file.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai generate unit testing code for this file.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and generate unit testing code.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai plan` to trigger planning for file edits and PR creation.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-03-25T03:24:36Z
body: [<img width="300" alt="Preview is ready" src="https://user-images.githubusercontent.com/5378891/72400743-23dbb200-3785-11ea-9d13-1a2d92743846.png">](https://preview-53285-ant-design.surge.sh)
<!-- AUTO_PREVIEW_HOOK -->
<!-- AUTO_PREVIEW_HOOK -->
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-03-25T03:24:38Z
body: <!-- VISUAL_DIFF_SUCCESS -->

## 👁 Visual Regression Report for PR #53285 Passed ✅
> **🎯 Target branch:** feature (45fcb4ba14b597ceb242bf36fdfa4496d8024c10)
> 📖 <a href="https://antd-visual-diff.oss-accelerate.aliyuncs.com/pr-53285/visualRegressionReport/report.html" target="_blank">View Full Report ↗︎</a>
> 📖 <a href="https://antd-visual-diff.oss-accelerate.aliyuncs.com/pr-53285/visualRegressionReport/index.html" target="_blank">Alternative Report ↗︎</a>

🎊 Congrats! No visual-regression diff found.

<img src="https://github.com/ant-design/ant-design/assets/507615/2d1a77dc-dbc6-4b0f-9cbc-19a43d3c29cd" width="300" />
<!-- VISUAL_DIFF_REGRESSION_HOOK -->
<!-- VISUAL_DIFF_REGRESSION_HOOK -->
author_association: CONTRIBUTOR
user: login: petercat-assistant[bot]
created_at: 2025-03-25T03:24:39Z
body: ### Walkthrough
This pull request introduces a new feature and refactoring for the TreeSelect component in the Ant Design library. It adds support for semantic DOM in the popup and deprecates several APIs, replacing them with more semantic alternatives. The changes include updates to the component's styling and behavior, as well as modifications to the documentation to reflect these deprecations.

### Changes
| Files | Summary |
|-------|---------|
| components/tree-select/__tests__/index.test.tsx | Added tests for deprecated properties and their replacements. |
| components/tree-select/demo/_semantic.tsx | Added a new demo file showcasing semantic DOM usage. |
| components/tree-select/demo/*.tsx | Updated demo files to replace `dropdownStyle` with `styles.popup`. |
| components/tree-select/index.en-US.md, components/tree-select/index.zh-CN.md | Updated documentation to reflect deprecated properties and their replacements. |
| components/tree-select/index.tsx | Refactored component to support new semantic properties and deprecated old ones. |
author_association: NONE
user: login: pkg-pr-new[bot]
created_at: 2025-03-25T03:28:08Z
body: 
[Open in Stackblitz](https://pkg.pr.new/template/d3f7d090-d7a7-45fb-a01e-47686798846c)
<details><summary><b>More templates</b></summary><p>

- [farm-normal](https://pkg.pr.new/template/86fe36ec-1143-4ce9-afc6-6cad92f0478b)
- [rsbuild-normal](https://pkg.pr.new/template/e2781413-ef7e-4bb5-8900-185801de931b)
- [umi-normal](https://pkg.pr.new/template/6db05d4f-44f1-4044-9396-fa528b88b5f2)
- [vite-normal](https://pkg.pr.new/template/a925651a-9880-4ab7-9809-2e7ca964aaef)
- [vite-practice](https://pkg.pr.new/template/131a17be-ede6-4085-8164-a1f886667c34)
- [with-nextjs-extract-style](https://pkg.pr.new/template/3878edba-276a-4187-b0b0-60b7363ecd86)
- [with-nextjs-app-router-inline-style](https://pkg.pr.new/template/835fc2d9-7adb-4fd2-8ba8-a116866fb5e8)
- [with-nextjs-generate-css-on-demand](https://pkg.pr.new/template/d580e00f-aa9a-4f98-9aee-f8efb362be32)
- [with-nextjs-inline-style](https://pkg.pr.new/template/64dbd74a-b365-4353-a840-ce4d96732f70)

</p></details>
      
    


```
npm i https://pkg.pr.new/ant-design/ant-design/antd@53285
```


_commit: <a href="https://github.com/ant-design/ant-design/runs/39350886830"><code>6af7809</code></a>_

author_association: NONE
user: login: codecov[bot]
created_at: 2025-03-25T03:28:44Z
body: ## [Bundle](https://app.codecov.io/gh/ant-design/ant-design/pull/53285?dropdown=bundle) Report

Changes will decrease total bundle size by 6.27MB (-64.92%) :arrow_down:. This is within the [configured](https://docs.codecov.com/docs/javascript-bundle-analysis#main-features) threshold :white_check_mark:

<details><summary>Detailed changes</summary>

| Bundle name | Size | Change |
| ----------- | ---- | ------ |
| antd.min-array-push | 3.39MB | -6.27MB (-64.92%) :arrow_down: |

</details>

### Affected Assets, Files, and Routes:

<details>
<summary>view changes for bundle: antd.min-array-push</summary>

#### **Assets Changed:**
| Asset Name | Size Change | Total Size | Change (%) |
| ---------- | ----------- | ---------- | ---------- |
| **```antd-with-locales.min.js```** _(New)_ | 1.85MB | 1.85MB | 100.0% :rocket: |
| **```antd.min.js```** _(New)_ | 1.54MB | 1.54MB | 100.0% :rocket: |
| ~~**```antd-with-locales.js```**~~ _(Deleted)_ | -5.08MB | 0 bytes | -100.0% :wastebasket: |
| ~~**```antd.js```**~~ _(Deleted)_ | -4.57MB | 0 bytes | -100.0% :wastebasket: |












</details>

author_association: NONE
user: login: codecov[bot]
created_at: 2025-03-25T06:01:12Z
body: ## [Codecov](https://app.codecov.io/gh/ant-design/ant-design/pull/53285?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ant-design) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 100.00%. Comparing base [(`45fcb4b`)](https://app.codecov.io/gh/ant-design/ant-design/commit/45fcb4ba14b597ceb242bf36fdfa4496d8024c10?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ant-design) to head [(`6af7809`)](https://app.codecov.io/gh/ant-design/ant-design/commit/6af7809468b4ca566e991124529753ff0b242860?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ant-design).
> Report is 1 commits behind head on feature.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff            @@
##           feature    #53285   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          771       771           
  Lines        13899     13902    +3     
  Branches      3653      3656    +3     
=========================================
+ Hits         13899     13902    +3     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/ant-design/ant-design/pull/53285?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ant-design).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ant-design).

<details><summary> :rocket: New features to boost your workflow: </summary>

- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
</details>
author_association: NONE
user: login: thinkasany
created_at: 2025-03-25T13:25:35Z
body: rc里面 onPopupVisibleChange 好像还没改成 onOpenChange 
cc @zombieJ , @aojunhao123 
https://github.com/react-component/tree-select/blob/6fa2d684181416ea62b44eb47145f87f731f53a9/src/TreeSelect.tsx#L95
author_association: MEMBER
user: login: aojunhao123
created_at: 2025-03-25T14:20:53Z
body: 都要改的，一个个弄
author_association: CONTRIBUTOR
user: login: thinkasany
created_at: 2025-03-25T14:23:05Z
body: 顺手抄送一下，一切都在计划中稳步前进
![image](https://github.com/user-attachments/assets/71ae128f-4254-4975-9800-52b7dc5d8f3a)

author_association: MEMBER