diff --git a/components/cascader/__tests__/index.test.tsx b/components/cascader/__tests__/index.test.tsx
index 77cdcdfafd..aada06b0dd 100644
--- a/components/cascader/__tests__/index.test.tsx
+++ b/components/cascader/__tests__/index.test.tsx
@@ -1,4 +1,5 @@
import React from 'react';
+import { Button, Input, Space } from 'antd';
import type { SingleValueType } from 'rc-cascader/lib/Cascader';
import type { DefaultOptionType } from '..';
@@ -803,4 +804,41 @@ describe('Cascader', () => {
errSpy.mockRestore();
});
+
+ it('Cascader ContextIsolator', () => {
+ const { container } = render(
+
+ {
+ return (
+
+ {menu}
+
+
+
+ );
+ }}
+ options={[
+ { value: 'jack', label: 'Jack' },
+ { value: 'lucy', label: 'Lucy' },
+ ]}
+ />
+
+ ,
+ );
+
+ const compactButton = container.querySelector('.test-button');
+ const popupElement = document.querySelector('.ant-select-dropdown');
+ // selector should have compact
+ expect(compactButton).toBeInTheDocument();
+ expect(compactButton!.className.includes('compact')).toBeTruthy();
+ // popupRender element haven't compact
+ expect(popupElement).toBeInTheDocument();
+ const button = popupElement!.querySelector('button');
+ const input = popupElement!.querySelector('input');
+ expect(button!.className.includes('compact')).toBeFalsy();
+ expect(input!.className.includes('compact')).toBeFalsy();
+ });
});
diff --git a/components/cascader/index.tsx b/components/cascader/index.tsx
index 281713f24e..e5bcbaa36b 100644
--- a/components/cascader/index.tsx
+++ b/components/cascader/index.tsx
@@ -31,6 +31,7 @@ import useVariant from '../form/hooks/useVariants';
import mergedBuiltinPlacements from '../select/mergedBuiltinPlacements';
import useSelectStyle from '../select/style';
import useIcons from '../select/useIcons';
+import usePopupRender from '../select/usePopupRender';
import useShowArrow from '../select/useShowArrow';
import { useCompactItemContext } from '../space/Compact';
import useBase from './hooks/useBase';
@@ -292,7 +293,8 @@ const Cascader = React.forwardRef>((props, ref)
cssVarCls,
);
- const mergedPopupRender = popupRender || dropdownRender;
+ const mergedPopupRender = usePopupRender(popupRender || dropdownRender);
+
const mergedPopupMenuColumnStyle = popupMenuColumnStyle || dropdownMenuColumnStyle;
const mergedOnOpenChange = onOpenChange || onDropdownVisibleChange;
const mergedPopupStyle = styles?.popup?.root || contextStyles.popup?.root || dropdownStyle;
diff --git a/components/select/__tests__/index.test.tsx b/components/select/__tests__/index.test.tsx
index 2f7ece51e7..921cf335ad 100644
--- a/components/select/__tests__/index.test.tsx
+++ b/components/select/__tests__/index.test.tsx
@@ -1,14 +1,15 @@
import React from 'react';
import { CloseOutlined } from '@ant-design/icons';
+import { Button, Input, Space } from 'antd';
import type { SelectProps } from '..';
import Select from '..';
-import Form from '../../form';
import { resetWarned } from '../../_util/warning';
import focusTest from '../../../tests/shared/focusTest';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
import { act, fireEvent, render } from '../../../tests/utils';
+import Form from '../../form';
const { Option } = Select;
@@ -290,4 +291,42 @@ describe('Select', () => {
errSpy.mockRestore();
});
});
+
+ it('Select ContextIsolator', () => {
+ const { container } = render(
+
+ ,
+ );
+
+ const compactButton = container.querySelector('.test-button');
+ const popupElement = document.querySelector('.ant-select-dropdown');
+ // selector should have compact
+ expect(compactButton).toBeInTheDocument();
+ expect(compactButton!.className.includes('compact')).toBeTruthy();
+ // popupRender element haven't compact
+ expect(popupElement).toBeInTheDocument();
+ const button = popupElement!.querySelector('button');
+ const input = popupElement!.querySelector('input');
+ expect(button!.className.includes('compact')).toBeFalsy();
+ expect(input!.className.includes('compact')).toBeFalsy();
+ });
});
diff --git a/components/select/index.tsx b/components/select/index.tsx
index c69049cef1..8614293704 100755
--- a/components/select/index.tsx
+++ b/components/select/index.tsx
@@ -29,6 +29,7 @@ import { useToken } from '../theme/internal';
import mergedBuiltinPlacements from './mergedBuiltinPlacements';
import useStyle from './style';
import useIcons from './useIcons';
+import usePopupRender from './usePopupRender';
import useShowArrow from './useShowArrow';
type RawValue = string | number;
@@ -203,7 +204,9 @@ const InternalSelect = <
popupMatchSelectWidth ?? dropdownMatchSelectWidth ?? contextPopupMatchSelectWidth;
const mergedPopupStyle = styles?.popup?.root || contextStyles.popup?.root || dropdownStyle;
- const mergedPopupRender = popupRender || dropdownRender;
+
+ const mergedPopupRender = usePopupRender(popupRender || dropdownRender);
+
const mergedOnOpenChange = onOpenChange || onDropdownVisibleChange;
// ===================== Form Status =====================
diff --git a/components/select/usePopupRender.tsx b/components/select/usePopupRender.tsx
new file mode 100644
index 0000000000..e3a24086cb
--- /dev/null
+++ b/components/select/usePopupRender.tsx
@@ -0,0 +1,18 @@
+import React from 'react';
+
+import ContextIsolator from '../_util/ContextIsolator';
+
+type RenderFunction = (...args: T) => React.ReactNode;
+
+function usePopupRender(
+ renderFn?: RenderFunction,
+): ((...args: T) => React.ReactElement) | undefined {
+ return React.useMemo(() => {
+ if (!renderFn) {
+ return undefined;
+ }
+ return (...args: T) => {renderFn(...args)};
+ }, [renderFn]);
+}
+
+export default usePopupRender;
diff --git a/components/tree-select/__tests__/index.test.tsx b/components/tree-select/__tests__/index.test.tsx
index 3fc73b042a..d477f777ad 100644
--- a/components/tree-select/__tests__/index.test.tsx
+++ b/components/tree-select/__tests__/index.test.tsx
@@ -1,11 +1,12 @@
import React from 'react';
+import { Button, Input, Space } from 'antd';
import TreeSelect, { TreeNode } from '..';
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, fireEvent } from '../../../tests/utils';
+import { fireEvent, render } from '../../../tests/utils';
describe('TreeSelect', () => {
focusTest(TreeSelect, { refFocus: true });
@@ -162,4 +163,41 @@ describe('TreeSelect', () => {
errSpy.mockRestore();
});
+
+ it('TreeSelect ContextIsolator', () => {
+ const { container } = render(
+
+ {
+ return (
+
+ {menu}
+
+
+
+ );
+ }}
+ treeData={[
+ { value: 'jack', title: 'Jack', children: [{ value: 'Emily', title: 'Emily' }] },
+ { value: 'lucy', title: 'Lucy' },
+ ]}
+ />
+
+ ,
+ );
+ const compactButton = container.querySelector('.test-button');
+ const popupElement = document.querySelector('.ant-select-dropdown');
+ // selector should have compact
+ expect(compactButton).toBeInTheDocument();
+ expect(compactButton!.className.includes('compact')).toBeTruthy();
+ // popupRender element haven't compact
+ expect(popupElement).toBeInTheDocument();
+ const button = popupElement!.querySelector('button');
+ const input = popupElement!.querySelector('input');
+ expect(button!.className.includes('compact')).toBeFalsy();
+ expect(input!.className.includes('compact')).toBeFalsy();
+ });
});
diff --git a/components/tree-select/index.tsx b/components/tree-select/index.tsx
index 99fbc85814..d825cb28c1 100644
--- a/components/tree-select/index.tsx
+++ b/components/tree-select/index.tsx
@@ -16,6 +16,7 @@ import { getMergedStatus, getStatusClassNames } from '../_util/statusUtils';
import { devUseWarning } from '../_util/warning';
import { ConfigContext } from '../config-provider';
import type { Variant } from '../config-provider';
+import { useComponentConfig } from '../config-provider/context';
import DefaultRenderEmpty from '../config-provider/defaultRenderEmpty';
import DisabledContext from '../config-provider/DisabledContext';
import useCSSVarCls from '../config-provider/hooks/useCSSVarCls';
@@ -26,6 +27,7 @@ import useVariant from '../form/hooks/useVariants';
import mergedBuiltinPlacements from '../select/mergedBuiltinPlacements';
import useSelectStyle from '../select/style';
import useIcons from '../select/useIcons';
+import usePopupRender from '../select/usePopupRender';
import useShowArrow from '../select/useShowArrow';
import { useCompactItemContext } from '../space/Compact';
import { useToken } from '../theme/internal';
@@ -33,7 +35,6 @@ import type { AntTreeNodeProps, TreeProps } from '../tree';
import type { SwitcherIcon } from '../tree/Tree';
import SwitcherIconCom from '../tree/utils/iconUtil';
import useStyle from './style';
-import { useComponentConfig } from '../config-provider/context';
type RawValue = string | number;
@@ -226,7 +227,9 @@ const InternalTreeSelect =