feat: ConfigProvider support popconfirm (#52126)
Some checks are pending
Publish Any Commit / build (push) Waiting to run
🔀 Sync mirror to Gitee / mirror (push) Waiting to run
✅ test / lint (push) Waiting to run
✅ test / test-react-legacy (16, 1/2) (push) Waiting to run
✅ test / test-react-legacy (16, 2/2) (push) Waiting to run
✅ test / test-react-legacy (17, 1/2) (push) Waiting to run
✅ test / test-react-legacy (17, 2/2) (push) Waiting to run
✅ test / test-node (push) Waiting to run
✅ test / test-react-latest (dom, 1/2) (push) Waiting to run
✅ test / test-react-latest (dom, 2/2) (push) Waiting to run
✅ test / test-react-latest-dist (dist, 1/2) (push) Blocked by required conditions
✅ test / test-react-latest-dist (dist, 2/2) (push) Blocked by required conditions
✅ test / test-react-latest-dist (dist-min, 1/2) (push) Blocked by required conditions
✅ test / test-react-latest-dist (dist-min, 2/2) (push) Blocked by required conditions
✅ test / test-coverage (push) Blocked by required conditions
✅ test / build (push) Waiting to run
✅ test / test lib/es module (es, 1/2) (push) Waiting to run
✅ test / test lib/es module (es, 2/2) (push) Waiting to run
✅ test / test lib/es module (lib, 1/2) (push) Waiting to run
✅ test / test lib/es module (lib, 2/2) (push) Waiting to run
👁️ Visual Regression Persist Start / test image (push) Waiting to run

* feat: ConfigProvider support popcomfirm

* replace api
This commit is contained in:
thinkasany 2024-12-25 15:29:30 +08:00 committed by GitHub
parent ca1ab9bf47
commit 8b15b0fbad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 149 additions and 25 deletions

View File

@ -157,7 +157,7 @@ const SubTokenTable: React.FC<SubTokenTableProps> = (props) => {
{title}
<Popover
title={null}
overlayStyle={{ width: 400 }}
styles={{ root: { width: 400 } }}
content={
<Typography>
{/* <SourceCode lang="jsx">{code}</SourceCode> */}

View File

@ -357,7 +357,7 @@ const Header: React.FC = () => {
<header className={headerClassName}>
{isMobile && (
<Popover
overlayClassName={styles.popoverMenu}
classNames={{ root: styles.popoverMenu }}
placement="bottomRight"
content={menu}
trigger="click"

View File

@ -271,8 +271,8 @@ describe('Avatar Render', () => {
count: 2,
popover: {
placement: 'bottomRight',
overlayClassName: 'wanpan-111',
overlayStyle: { background: 'red' },
classNames: { root: 'wanpan-111' },
styles: { root: { background: 'red' } },
content: 'Avatar.Group',
open: true,
},

View File

@ -121,7 +121,7 @@ const Group: React.FC<GroupProps> = (props) => {
const mergeProps = {
content: childrenHidden,
...max?.popover,
overlayClassName: classNames(`${groupPrefixCls}-popover`, max?.popover?.overlayClassName),
classNames: { root: classNames(`${groupPrefixCls}-popover`, max?.popover?.classNames?.root) },
placement: mergePopoverPlacement,
trigger: mergePopoverTrigger,
};

View File

@ -221,7 +221,7 @@ const ColorPicker: CompoundedComponent = (props) => {
return wrapCSSVar(
<Popover
style={styles?.popup}
overlayInnerStyle={styles?.popupOverlayInner}
styles={{ body: styles?.popupOverlayInner }}
onOpenChange={(visible) => {
if (!visible || !mergedDisabled) {
setPopupOpen(visible);
@ -253,7 +253,7 @@ const ColorPicker: CompoundedComponent = (props) => {
/>
</ContextIsolator>
}
overlayClassName={mergedPopupCls}
classNames={{ root: mergedPopupCls }}
{...popoverProps}
>
{children || (

View File

@ -36,6 +36,7 @@ import type { TreeSelectProps } from '../tree-select';
import type { RenderEmptyHandler } from './defaultRenderEmpty';
import type { TooltipProps } from '../tooltip';
import type { PopoverProps } from '../popover';
import type { PopconfirmProps } from '../popconfirm';
export const defaultPrefixCls = 'ant';
export const defaultIconPrefixCls = 'anticon';
@ -182,6 +183,11 @@ export type TooltipConfig = Pick<TooltipProps, 'className' | 'style' | 'styles'
export type PopoverConfig = Pick<PopoverProps, 'className' | 'style' | 'styles' | 'classNames'>;
export type PopconfirmConfig = Pick<
PopconfirmProps,
'className' | 'style' | 'styles' | 'classNames'
>;
export type SpinConfig = ComponentStyleConfig & Pick<SpinProps, 'indicator'>;
export type InputNumberConfig = ComponentStyleConfig & Pick<InputNumberProps, 'variant'>;
@ -297,6 +303,7 @@ export interface ConfigConsumerProps {
tour?: TourConfig;
tooltip?: TooltipConfig;
popover?: PopoverConfig;
popconfirm?: PopconfirmConfig;
upload?: ComponentStyleConfig;
notification?: NotificationConfig;
tree?: ComponentStyleConfig;

View File

@ -164,6 +164,7 @@ const {
| tour | Set Tour common props | { closeIcon?: React.ReactNode } | - | 5.14.0 |
| tooltip | Set Tooltip common props | { className?: string, style?: React.CSSProperties, classNames?:[Tooltip\["classNames"\]](/components/tooltip#api), styles?: [Tooltip\["styles"\]](/components/tooltip#api) } | - | 5.23.0 |
| popover | Set Popover common props | { className?: string, style?: React.CSSProperties, classNames?:[Popover\["classNames"\]](/components/popover#api), styles?: [Popover\["styles"\]](/components/popover#api) } | - | 5.23.0 |
| popconfirm | Set Popconfirm common props | { className?: string, style?: React.CSSProperties, classNames?:[Popconfirm\["classNames"\]](/components/popconfirm#api), styles?: [Popconfirm\["styles"\]](/components/popconfirm#api) } | - | 5.23.0 |
| transfer | Set Transfer common props | { className?: string, style?: React.CSSProperties, selectionsIcon?: React.ReactNode } | - | 5.7.0, selectionsIcon: 5.14.0 |
| tree | Set Tree common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| typography | Set Typography common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |

View File

@ -53,6 +53,7 @@ import type {
TimePickerConfig,
TooltipConfig,
PopoverConfig,
PopconfirmConfig,
TourConfig,
TransferConfig,
TreeSelectConfig,
@ -239,6 +240,7 @@ export interface ConfigProviderProps {
tour?: TourConfig;
tooltip?: TooltipConfig;
popover?: PopoverConfig;
popconfirm?: PopconfirmConfig;
}
interface ProviderChildrenProps extends ConfigProviderProps {
@ -395,6 +397,7 @@ const ProviderChildren: React.FC<ProviderChildrenProps> = (props) => {
tour,
tooltip,
popover,
popconfirm,
floatButtonGroup,
variant,
inputNumber,
@ -497,6 +500,7 @@ const ProviderChildren: React.FC<ProviderChildrenProps> = (props) => {
tour,
tooltip,
popover,
popconfirm,
floatButtonGroup,
variant,
inputNumber,

View File

@ -166,6 +166,7 @@ const {
| tour | 设置 Tour 组件的通用属性 | { closeIcon?: React.ReactNode } | - | 5.14.0 |
| tooltip | 设置 Tooltip 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?:[Tooltip\["classNames"\]](/components/tooltip-cn#api), styles?: [Tooltip\["styles"\]](/components/tooltip-cn#api) } | - | 5.23.0 |
| popover | 设置 Popover 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?:[Popover\["classNames"\]](/components/popover-cn#api), styles?: [Popover\["styles"\]](/components/popover-cn#api) } | - | 5.23.0 |
| popconfirm | 设置 Popconfirm 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?:[Popconfirm\["classNames"\]](/components/popconfirm-cn#api), styles?: [Popconfirm\["styles"\]](/components/popconfirm-cn#api) } | - | 5.23.0 |
| transfer | 设置 Transfer 组件的通用属性 | { className?: string, style?: React.CSSProperties, selectionsIcon?: React.ReactNode } | - | 5.7.0, selectionsIcon: 5.14.0 |
| tree | 设置 Tree 组件的通用属性 | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| typography | 设置 Typography 组件的通用属性 | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |

View File

@ -36,7 +36,12 @@ const NumericInput = (props: NumericInputProps) => {
);
return (
<Tooltip trigger={['focus']} title={title} placement="topLeft" overlayClassName="numeric-input">
<Tooltip
trigger={['focus']}
title={title}
placement="topLeft"
classNames={{ root: 'numeric-input' }}
>
<Input
{...props}
onChange={handleChange}

View File

@ -378,4 +378,33 @@ describe('Popconfirm', () => {
expect(document.body.querySelectorAll('.ant-btn')[0].textContent).toBe('Cancel');
expect(document.body.querySelectorAll('.ant-btn')[1].textContent).toBe('OK');
});
it('should apply custom styles to Popconfirm', () => {
const customClassNames = {
body: 'custom-body',
root: 'custom-root',
};
const customStyles = {
body: { color: 'red' },
root: { backgroundColor: 'blue' },
};
const { container } = render(
<Popconfirm classNames={customClassNames} title="" styles={customStyles} open>
<span />
</Popconfirm>,
);
const popconfirmElement = container.querySelector('.ant-popconfirm') as HTMLElement;
const popconfirmBodyElement = container.querySelector('.ant-popover-inner') as HTMLElement;
// 验证 classNames
expect(popconfirmElement.classList).toContain('custom-root');
expect(popconfirmBodyElement.classList).toContain('custom-body');
// 验证 styles
expect(popconfirmElement.style.backgroundColor).toBe('blue');
expect(popconfirmBodyElement.style.color).toBe('red');
});
});

View File

@ -0,0 +1,49 @@
import React from 'react';
import { Popconfirm } from 'antd';
import SemanticPreview from '../../../.dumi/components/SemanticPreview';
import useLocale from '../../../.dumi/hooks/useLocale';
const locales = {
cn: {
root: '根节点 (包含箭头、内容元素)',
body: '内容元素',
},
en: {
root: 'Root element (including arrows, content elements)',
body: 'Body element',
},
};
const BlockList: React.FC<React.PropsWithChildren> = (props: any) => {
const divRef = React.useRef<HTMLDivElement>(null);
return (
<div ref={divRef} style={{ position: 'absolute', marginTop: 60 }}>
<Popconfirm
title="prompt text"
open
placement="top"
autoAdjustOverflow={false}
getPopupContainer={() => divRef.current}
{...props}
/>
</div>
);
};
const App: React.FC = () => {
const [locale] = useLocale(locales);
return (
<SemanticPreview
semantics={[
{ name: 'root', desc: locale.root, version: '5.23.0' },
{ name: 'body', desc: locale.body, version: '5.23.0' },
]}
>
<BlockList />
</SemanticPreview>
);
};
export default App;

View File

@ -53,6 +53,10 @@ Common props ref[Common props](/docs/react/common-props)
<embed src="../tooltip/shared/sharedProps.en-US.md"></embed>
## Semantic DOM
<code src="./demo/_semantic.tsx" simplify="true"></code>
## Design Token
<ComponentTokenTable component="Popconfirm"></ComponentTokenTable>

View File

@ -48,10 +48,13 @@ const InternalPopconfirm = React.forwardRef<TooltipRef, PopconfirmProps>((props,
overlayClassName,
onOpenChange,
onVisibleChange,
overlayStyle,
styles,
classNames: popconfirmClassNames,
...restProps
} = props;
const { getPrefixCls } = React.useContext(ConfigContext);
const { getPrefixCls, popconfirm } = React.useContext(ConfigContext);
const [open, setOpen] = useMergedState(false, {
value: props.open ?? props.visible,
defaultValue: props.defaultOpen ?? props.defaultVisible,
@ -83,7 +86,13 @@ const InternalPopconfirm = React.forwardRef<TooltipRef, PopconfirmProps>((props,
};
const prefixCls = getPrefixCls('popconfirm', customizePrefixCls);
const overlayClassNames = classNames(prefixCls, overlayClassName);
const rootClassNames = classNames(
prefixCls,
overlayClassName,
popconfirm?.classNames?.root,
popconfirmClassNames?.root,
);
const bodyClassNames = classNames(popconfirm?.classNames?.body, popconfirmClassNames?.body);
const [wrapCSSVar] = useStyle(prefixCls);
@ -95,7 +104,19 @@ const InternalPopconfirm = React.forwardRef<TooltipRef, PopconfirmProps>((props,
onOpenChange={onInternalOpenChange}
open={open}
ref={ref}
overlayClassName={overlayClassNames}
classNames={{ root: rootClassNames, body: bodyClassNames }}
styles={{
root: {
...popconfirm?.styles?.root,
...popconfirm?.style,
...overlayStyle,
...styles?.root,
},
body: {
...popconfirm?.styles?.body,
...styles?.body,
},
}}
content={
<Overlay
okType={okType}

View File

@ -54,6 +54,10 @@ demo:
<embed src="../tooltip/shared/sharedProps.zh-CN.md"></embed>
## Semantic DOM
<code src="./demo/_semantic.tsx" simplify="true"></code>
## 主题变量Design Token
<ComponentTokenTable component="Popconfirm"></ComponentTokenTable>

View File

@ -42,7 +42,7 @@ const App: React.FC = () => {
{...selectProps}
maxTagPlaceholder={(omittedValues) => (
<Tooltip
overlayStyle={{ pointerEvents: 'none' }}
styles={{ root: { pointerEvents: 'none' } }}
title={omittedValues.map(({ label }) => label).join(', ')}
>
<span>Hover Me</span>

View File

@ -55,7 +55,7 @@ exports[`Slider should render in RTL direction 1`] = `
tabindex="0"
/>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-slider-tooltip ant-tooltip-rtl ant-tooltip-placement-top"
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-tooltip-rtl ant-slider-tooltip ant-tooltip-placement-top"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div

View File

@ -10,9 +10,9 @@ import { devUseWarning } from '../_util/warning';
import { ConfigContext } from '../config-provider';
import DisabledContext from '../config-provider/DisabledContext';
import type { AbstractTooltipProps, TooltipPlacement } from '../tooltip';
import SliderInternalContext from './Context';
import SliderTooltip from './SliderTooltip';
import useStyle from './style';
import SliderInternalContext from './Context';
import useRafLock from './useRafLock';
export type SliderMarks = RcSliderProps['marks'];
@ -319,7 +319,7 @@ const Slider = React.forwardRef<SliderRef, SliderSingleProps | SliderRangeProps>
open={open}
placement={getTooltipPlacement(tooltipPlacement ?? legacyTooltipPlacement, vertical)}
key={index}
overlayClassName={`${prefixCls}-tooltip`}
classNames={{ root: `${prefixCls}-tooltip` }}
getPopupContainer={
getTooltipPopupContainer || legacyGetTooltipPopupContainer || getPopupContainer
}
@ -350,7 +350,7 @@ const Slider = React.forwardRef<SliderRef, SliderSingleProps | SliderRangeProps>
open={mergedTipFormatter !== null && activeOpen}
placement={getTooltipPlacement(tooltipPlacement ?? legacyTooltipPlacement, vertical)}
key="tooltip"
overlayClassName={`${prefixCls}-tooltip`}
classNames={{ root: `${prefixCls}-tooltip` }}
getPopupContainer={
getTooltipPopupContainer || legacyGetTooltipPopupContainer || getPopupContainer
}

View File

@ -514,7 +514,7 @@ describe('Table.sorter', () => {
rerender(
createTable({
showSorterTooltip: {
overlayClassName: 'custom-tooltip',
classNames: { root: 'custom-tooltip' },
},
}),
);

View File

@ -215,7 +215,7 @@ describe('Tooltip', () => {
mouseLeaveDelay={0}
placement="bottomLeft"
arrowPointAtCenter
overlayClassName="point-center-element"
classNames={{ root: 'point-center-element' }}
>
<button type="button">Hello world!</button>
</Tooltip>,
@ -232,7 +232,7 @@ describe('Tooltip', () => {
mouseLeaveDelay={0}
placement="bottomLeft"
arrow={{ arrowPointAtCenter: true }}
overlayClassName="point-center-element"
classNames={{ root: 'point-center-element' }}
>
<button type="button">Hello world!</button>
</Tooltip>,
@ -402,9 +402,9 @@ describe('Tooltip', () => {
expect(document.querySelector('.ant-tooltip')).not.toBeNull();
});
it('should pass overlayInnerStyle through to the inner component', () => {
it('should pass styles={{ body: {} }} through to the inner component', () => {
const { container } = render(
<Tooltip overlayInnerStyle={{ color: 'red' }} title="xxxxx" open>
<Tooltip styles={{ body: { color: 'red' } }} title="xxxxx" open>
<div />
</Tooltip>,
);

View File

@ -189,10 +189,9 @@ const InternalTooltip = React.forwardRef<TooltipRef, TooltipProps>((props, ref)
['onVisibleChange', 'onOpenChange'],
['afterVisibleChange', 'afterOpenChange'],
['arrowPointAtCenter', 'arrow={{ pointAtCenter: true }}'],
// todo: Warnings are not available yet, because popover and popconfirm are still in use. Wait until they are merged before processing.
// ['overlayStyle', 'styles={{ root: {} }}'],
// ['overlayInnerStyle', 'styles={{ body: {} }}'],
// ['overlayClassName', 'classNames={{ root: {} }}'],
['overlayStyle', 'styles={{ root: {} }}'],
['overlayInnerStyle', 'styles={{ body: {} }}'],
['overlayClassName', 'classNames={{ root: {} }}'],
].forEach(([deprecatedName, newName]) => {
warning.deprecated(!(deprecatedName in props), deprecatedName, newName);
});