mirror of
https://gitee.com/ant-design/ant-design.git
synced 2024-12-02 03:59:01 +08:00
feat: switch visible to open for Tooltip (#37241)
* feat: switch visible to open for Tooltip & Popover & Popconfirm * fix lint * fix: merge state * chore: Update ts part * test: add legacy test * test: fix test case Co-authored-by: 二货机器人 <smith3816@gmail.com>
This commit is contained in:
parent
8b93cf5b10
commit
6b658dab76
@ -417,7 +417,7 @@ describe('ConfigProvider', () => {
|
||||
// Popconfirm
|
||||
testPair('Popconfirm', props => (
|
||||
<div>
|
||||
<Popconfirm {...props} visible>
|
||||
<Popconfirm {...props} open>
|
||||
<span>Bamboo</span>
|
||||
</Popconfirm>
|
||||
</div>
|
||||
@ -426,7 +426,7 @@ describe('ConfigProvider', () => {
|
||||
// Popover
|
||||
testPair('Popover', props => (
|
||||
<div>
|
||||
<Popover {...props} visible>
|
||||
<Popover {...props} open>
|
||||
<span>Light</span>
|
||||
</Popover>
|
||||
</div>
|
||||
@ -555,7 +555,7 @@ describe('ConfigProvider', () => {
|
||||
|
||||
// Tooltip
|
||||
testPair('Tooltip', props => (
|
||||
<Tooltip {...props} title="Bamboo" visible>
|
||||
<Tooltip {...props} title="Bamboo" open>
|
||||
<span>Light</span>
|
||||
</Tooltip>
|
||||
));
|
||||
|
@ -177,7 +177,7 @@ const App: React.FC = () => (
|
||||
<DatePicker open />
|
||||
<TimePicker open defaultOpenValue={moment()} />
|
||||
<RangePicker open style={{ width: 200 }} />
|
||||
<Popconfirm title="Question?" visible>
|
||||
<Popconfirm title="Question?" open>
|
||||
<a>Click to confirm</a>
|
||||
</Popconfirm>
|
||||
<Transfer dataSource={[]} showSearch targetKeys={[]} render={(item: any) => item.title} />
|
||||
|
@ -55,9 +55,9 @@ export default class MenuItem extends React.Component<MenuItemProps> {
|
||||
|
||||
if (!siderCollapsed && !inlineCollapsed) {
|
||||
tooltipProps.title = null;
|
||||
// Reset `visible` to fix control mode tooltip display not correct
|
||||
// Reset `open` to fix control mode tooltip display not correct
|
||||
// ref: https://github.com/ant-design/ant-design/issues/16742
|
||||
tooltipProps.visible = false;
|
||||
tooltipProps.open = false;
|
||||
}
|
||||
const childrenLength = toArray(children).length;
|
||||
|
||||
|
@ -23,7 +23,7 @@ describe('Popconfirm', () => {
|
||||
});
|
||||
|
||||
it('should popup Popconfirm dialog', () => {
|
||||
const onVisibleChange = jest.fn();
|
||||
const onOpenChange = jest.fn();
|
||||
|
||||
const wrapper = mount(
|
||||
<Popconfirm
|
||||
@ -32,7 +32,7 @@ describe('Popconfirm', () => {
|
||||
cancelText="No"
|
||||
mouseEnterDelay={0}
|
||||
mouseLeaveDelay={0}
|
||||
onVisibleChange={onVisibleChange}
|
||||
onOpenChange={onOpenChange}
|
||||
>
|
||||
<span>Delete</span>
|
||||
</Popconfirm>,
|
||||
@ -40,11 +40,11 @@ describe('Popconfirm', () => {
|
||||
|
||||
const triggerNode = wrapper.find('span').at(0);
|
||||
triggerNode.simulate('click');
|
||||
expect(onVisibleChange).toHaveBeenLastCalledWith(true, undefined);
|
||||
expect(onOpenChange).toHaveBeenLastCalledWith(true, undefined);
|
||||
expect(wrapper.find('.popconfirm-test').length).toBe(1);
|
||||
|
||||
triggerNode.simulate('click');
|
||||
expect(onVisibleChange).toHaveBeenLastCalledWith(false, undefined);
|
||||
expect(onOpenChange).toHaveBeenLastCalledWith(false, undefined);
|
||||
});
|
||||
|
||||
it('should show overlay when trigger is clicked', async () => {
|
||||
@ -88,7 +88,7 @@ describe('Popconfirm', () => {
|
||||
expect(popup.innerHTML).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should be controlled by visible', () => {
|
||||
it('should be controlled by open', () => {
|
||||
const ref = React.createRef();
|
||||
jest.useFakeTimers();
|
||||
const popconfirm = mount(
|
||||
@ -97,10 +97,10 @@ describe('Popconfirm', () => {
|
||||
</Popconfirm>,
|
||||
);
|
||||
expect(ref.current.getPopupDomNode()).toBeFalsy();
|
||||
popconfirm.setProps({ visible: true });
|
||||
popconfirm.setProps({ open: true });
|
||||
expect(ref.current.getPopupDomNode()).toBeTruthy();
|
||||
expect(ref.current.getPopupDomNode().className).not.toContain('ant-popover-hidden');
|
||||
popconfirm.setProps({ visible: false });
|
||||
popconfirm.setProps({ open: false });
|
||||
popconfirm.update(); // https://github.com/enzymejs/enzyme/issues/2305
|
||||
act(() => {
|
||||
jest.runAllTimers();
|
||||
@ -112,14 +112,9 @@ describe('Popconfirm', () => {
|
||||
it('should trigger onConfirm and onCancel', () => {
|
||||
const confirm = jest.fn();
|
||||
const cancel = jest.fn();
|
||||
const onVisibleChange = jest.fn();
|
||||
const onOpenChange = jest.fn();
|
||||
const popconfirm = mount(
|
||||
<Popconfirm
|
||||
title="code"
|
||||
onConfirm={confirm}
|
||||
onCancel={cancel}
|
||||
onVisibleChange={onVisibleChange}
|
||||
>
|
||||
<Popconfirm title="code" onConfirm={confirm} onCancel={cancel} onOpenChange={onOpenChange}>
|
||||
<span>show me your code</span>
|
||||
</Popconfirm>,
|
||||
);
|
||||
@ -127,11 +122,11 @@ describe('Popconfirm', () => {
|
||||
triggerNode.simulate('click');
|
||||
popconfirm.find('.ant-btn-primary').simulate('click');
|
||||
expect(confirm).toHaveBeenCalled();
|
||||
expect(onVisibleChange).toHaveBeenLastCalledWith(false, eventObject);
|
||||
expect(onOpenChange).toHaveBeenLastCalledWith(false, eventObject);
|
||||
triggerNode.simulate('click');
|
||||
popconfirm.find('.ant-btn').at(0).simulate('click');
|
||||
expect(cancel).toHaveBeenCalled();
|
||||
expect(onVisibleChange).toHaveBeenLastCalledWith(false, eventObject);
|
||||
expect(onOpenChange).toHaveBeenLastCalledWith(false, eventObject);
|
||||
});
|
||||
|
||||
it('should support onConfirm to return Promise', async () => {
|
||||
@ -139,20 +134,20 @@ describe('Popconfirm', () => {
|
||||
new Promise(res => {
|
||||
setTimeout(res, 300);
|
||||
});
|
||||
const onVisibleChange = jest.fn();
|
||||
const onOpenChange = jest.fn();
|
||||
const popconfirm = mount(
|
||||
<Popconfirm title="code" onConfirm={confirm} onVisibleChange={onVisibleChange}>
|
||||
<Popconfirm title="code" onConfirm={confirm} onOpenChange={onOpenChange}>
|
||||
<span>show me your code</span>
|
||||
</Popconfirm>,
|
||||
);
|
||||
|
||||
const triggerNode = popconfirm.find('span').at(0);
|
||||
triggerNode.simulate('click');
|
||||
expect(onVisibleChange).toHaveBeenCalledTimes(1);
|
||||
expect(onOpenChange).toHaveBeenCalledTimes(1);
|
||||
|
||||
popconfirm.find('.ant-btn').at(0).simulate('click');
|
||||
await sleep(400);
|
||||
expect(onVisibleChange).toHaveBeenCalledWith(false, eventObject);
|
||||
expect(onOpenChange).toHaveBeenCalledWith(false, eventObject);
|
||||
});
|
||||
|
||||
it('should support customize icon', () => {
|
||||
@ -171,7 +166,7 @@ describe('Popconfirm', () => {
|
||||
const btnPrefixCls = 'custom-btn';
|
||||
const wrapper = mount(
|
||||
<Popconfirm
|
||||
visible
|
||||
open
|
||||
title="x"
|
||||
prefixCls="custom-popconfirm"
|
||||
okButtonProps={{ prefixCls: btnPrefixCls }}
|
||||
@ -185,10 +180,10 @@ describe('Popconfirm', () => {
|
||||
expect(wrapper.find('.custom-btn').length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('should support defaultVisible', () => {
|
||||
it('should support defaultOpen', () => {
|
||||
const ref = React.createRef();
|
||||
mount(
|
||||
<Popconfirm ref={ref} title="code" defaultVisible>
|
||||
<Popconfirm ref={ref} title="code" defaultOpen>
|
||||
<span>show me your code</span>
|
||||
</Popconfirm>,
|
||||
);
|
||||
@ -209,22 +204,17 @@ describe('Popconfirm', () => {
|
||||
});
|
||||
|
||||
it('should be closed by pressing ESC', () => {
|
||||
const onVisibleChange = jest.fn();
|
||||
const onOpenChange = jest.fn();
|
||||
const wrapper = mount(
|
||||
<Popconfirm
|
||||
title="title"
|
||||
mouseEnterDelay={0}
|
||||
mouseLeaveDelay={0}
|
||||
onVisibleChange={onVisibleChange}
|
||||
>
|
||||
<Popconfirm title="title" mouseEnterDelay={0} mouseLeaveDelay={0} onOpenChange={onOpenChange}>
|
||||
<span>Delete</span>
|
||||
</Popconfirm>,
|
||||
);
|
||||
const triggerNode = wrapper.find('span').at(0);
|
||||
triggerNode.simulate('click');
|
||||
expect(onVisibleChange).toHaveBeenLastCalledWith(true, undefined);
|
||||
expect(onOpenChange).toHaveBeenLastCalledWith(true, undefined);
|
||||
triggerNode.simulate('keydown', { key: 'Escape', keyCode: 27 });
|
||||
expect(onVisibleChange).toHaveBeenLastCalledWith(false, eventObject);
|
||||
expect(onOpenChange).toHaveBeenLastCalledWith(false, eventObject);
|
||||
});
|
||||
|
||||
it('should not warn memory leaking if setState in async callback', async () => {
|
||||
|
@ -18,31 +18,31 @@ import { Button, Popconfirm } from 'antd';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [open, setOpen] = useState(false);
|
||||
const [confirmLoading, setConfirmLoading] = useState(false);
|
||||
|
||||
const showPopconfirm = () => {
|
||||
setVisible(true);
|
||||
setOpen(true);
|
||||
};
|
||||
|
||||
const handleOk = () => {
|
||||
setConfirmLoading(true);
|
||||
|
||||
setTimeout(() => {
|
||||
setVisible(false);
|
||||
setOpen(false);
|
||||
setConfirmLoading(false);
|
||||
}, 2000);
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
console.log('Clicked cancel button');
|
||||
setVisible(false);
|
||||
setOpen(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<Popconfirm
|
||||
title="Title"
|
||||
visible={visible}
|
||||
open={open}
|
||||
onConfirm={handleOk}
|
||||
okButtonProps={{ loading: confirmLoading }}
|
||||
onCancel={handleCancel}
|
||||
|
@ -18,7 +18,7 @@ import { message, Popconfirm, Switch } from 'antd';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [open, setOpen] = useState(false);
|
||||
const [condition, setCondition] = useState(true);
|
||||
|
||||
const changeCondition = (checked: boolean) => {
|
||||
@ -26,18 +26,18 @@ const App: React.FC = () => {
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
setVisible(false);
|
||||
setOpen(false);
|
||||
message.success('Next step.');
|
||||
};
|
||||
|
||||
const cancel = () => {
|
||||
setVisible(false);
|
||||
setOpen(false);
|
||||
message.error('Click on cancel.');
|
||||
};
|
||||
|
||||
const handleVisibleChange = (newVisible: boolean) => {
|
||||
if (!newVisible) {
|
||||
setVisible(newVisible);
|
||||
const handleOpenChange = (newOpen: boolean) => {
|
||||
if (!newOpen) {
|
||||
setOpen(newOpen);
|
||||
return;
|
||||
}
|
||||
// Determining condition before show the popconfirm.
|
||||
@ -45,7 +45,7 @@ const App: React.FC = () => {
|
||||
if (condition) {
|
||||
confirm(); // next step
|
||||
} else {
|
||||
setVisible(newVisible);
|
||||
setOpen(newOpen);
|
||||
}
|
||||
};
|
||||
|
||||
@ -53,8 +53,8 @@ const App: React.FC = () => {
|
||||
<div>
|
||||
<Popconfirm
|
||||
title="Are you sure delete this task?"
|
||||
visible={visible}
|
||||
onVisibleChange={handleVisibleChange}
|
||||
open={open}
|
||||
onOpenChange={handleOpenChange}
|
||||
onConfirm={confirm}
|
||||
onCancel={cancel}
|
||||
okText="Yes"
|
||||
|
@ -25,11 +25,7 @@ const App: React.FC = () => {
|
||||
});
|
||||
|
||||
return (
|
||||
<Popconfirm
|
||||
title="Title"
|
||||
onConfirm={confirm}
|
||||
onVisibleChange={() => console.log('visible change')}
|
||||
>
|
||||
<Popconfirm title="Title" onConfirm={confirm} onOpenChange={() => console.log('open change')}>
|
||||
<Button type="primary">Open Popconfirm with Promise</Button>
|
||||
</Popconfirm>
|
||||
);
|
||||
|
@ -23,56 +23,65 @@ export interface PopconfirmProps extends AbstractTooltipProps {
|
||||
cancelButtonProps?: ButtonProps;
|
||||
showCancel?: boolean;
|
||||
icon?: React.ReactNode;
|
||||
/**
|
||||
* @deprecated `onVisibleChange` is deprecated which will be removed in next major version. Please
|
||||
* use `onOpenChange` instead.
|
||||
*/
|
||||
onVisibleChange?: (
|
||||
visible: boolean,
|
||||
e?: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLDivElement>,
|
||||
) => void;
|
||||
onOpenChange?: (
|
||||
open: boolean,
|
||||
e?: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLDivElement>,
|
||||
) => void;
|
||||
}
|
||||
|
||||
export interface PopconfirmState {
|
||||
visible?: boolean;
|
||||
open?: boolean;
|
||||
}
|
||||
|
||||
const Popconfirm = React.forwardRef<unknown, PopconfirmProps>((props, ref) => {
|
||||
const { getPrefixCls } = React.useContext(ConfigContext);
|
||||
const [visible, setVisible] = useMergedState(false, {
|
||||
value: props.visible,
|
||||
defaultValue: props.defaultVisible,
|
||||
const [open, setOpen] = useMergedState(false, {
|
||||
value: props.open !== undefined ? props.open : props.visible,
|
||||
defaultValue: props.defaultOpen !== undefined ? props.defaultOpen : props.defaultVisible,
|
||||
});
|
||||
|
||||
// const isDestroyed = useDestroyed();
|
||||
|
||||
const settingVisible = (
|
||||
const settingOpen = (
|
||||
value: boolean,
|
||||
e?: React.MouseEvent<HTMLButtonElement> | React.KeyboardEvent<HTMLDivElement>,
|
||||
) => {
|
||||
setVisible(value, true);
|
||||
setOpen(value, true);
|
||||
props.onVisibleChange?.(value, e);
|
||||
props.onOpenChange?.(value, e);
|
||||
};
|
||||
|
||||
const close = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
settingVisible(false, e);
|
||||
settingOpen(false, e);
|
||||
};
|
||||
|
||||
const onConfirm = (e: React.MouseEvent<HTMLButtonElement>) => props.onConfirm?.call(this, e);
|
||||
|
||||
const onCancel = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
settingVisible(false, e);
|
||||
settingOpen(false, e);
|
||||
props.onCancel?.call(this, e);
|
||||
};
|
||||
|
||||
const onKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
|
||||
if (e.keyCode === KeyCode.ESC && visible) {
|
||||
settingVisible(false, e);
|
||||
if (e.keyCode === KeyCode.ESC && open) {
|
||||
settingOpen(false, e);
|
||||
}
|
||||
};
|
||||
|
||||
const onVisibleChange = (value: boolean) => {
|
||||
const onOpenChange = (value: boolean) => {
|
||||
const { disabled } = props;
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
settingVisible(value);
|
||||
settingOpen(value);
|
||||
};
|
||||
|
||||
const {
|
||||
@ -91,8 +100,8 @@ const Popconfirm = React.forwardRef<unknown, PopconfirmProps>((props, ref) => {
|
||||
{...restProps}
|
||||
prefixCls={prefixCls}
|
||||
placement={placement}
|
||||
onVisibleChange={onVisibleChange}
|
||||
visible={visible}
|
||||
onOpenChange={onOpenChange}
|
||||
open={open}
|
||||
_overlay={
|
||||
<Overlay
|
||||
{...props}
|
||||
|
@ -90,7 +90,7 @@ describe('Popover', () => {
|
||||
it(`should be rendered correctly in RTL direction`, () => {
|
||||
const wrapper = render(
|
||||
<ConfigProvider direction="rtl">
|
||||
<Popover title="RTL" visible>
|
||||
<Popover title="RTL" open>
|
||||
<span>show me your Rtl demo</span>
|
||||
</Popover>
|
||||
</ConfigProvider>,
|
||||
|
@ -7,25 +7,25 @@ title:
|
||||
|
||||
## zh-CN
|
||||
|
||||
使用 `visible` 属性控制浮层显示。
|
||||
使用 `open` 属性控制浮层显示。
|
||||
|
||||
## en-US
|
||||
|
||||
Use `visible` prop to control the display of the card.
|
||||
Use `open` prop to control the display of the card.
|
||||
|
||||
```tsx
|
||||
import { Button, Popover } from 'antd';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
const hide = () => {
|
||||
setVisible(false);
|
||||
setOpen(false);
|
||||
};
|
||||
|
||||
const handleVisibleChange = (newVisible: boolean) => {
|
||||
setVisible(newVisible);
|
||||
const handleOpenChange = (newOpen: boolean) => {
|
||||
setOpen(newOpen);
|
||||
};
|
||||
|
||||
return (
|
||||
@ -33,8 +33,8 @@ const App: React.FC = () => {
|
||||
content={<a onClick={hide}>Close</a>}
|
||||
title="Title"
|
||||
trigger="click"
|
||||
visible={visible}
|
||||
onVisibleChange={handleVisibleChange}
|
||||
open={open}
|
||||
onOpenChange={handleOpenChange}
|
||||
>
|
||||
<Button type="primary">Click me</Button>
|
||||
</Popover>
|
||||
|
@ -26,14 +26,14 @@ const App: React.FC = () => {
|
||||
setHovered(false);
|
||||
};
|
||||
|
||||
const handleHoverChange = (visible: boolean) => {
|
||||
setHovered(visible);
|
||||
const handleHoverChange = (open: boolean) => {
|
||||
setHovered(open);
|
||||
setClicked(false);
|
||||
};
|
||||
|
||||
const handleClickChange = (visible: boolean) => {
|
||||
const handleClickChange = (open: boolean) => {
|
||||
setHovered(false);
|
||||
setClicked(visible);
|
||||
setClicked(open);
|
||||
};
|
||||
|
||||
const hoverContent = <div>This is hover content.</div>;
|
||||
@ -44,8 +44,8 @@ const App: React.FC = () => {
|
||||
content={hoverContent}
|
||||
title="Hover title"
|
||||
trigger="hover"
|
||||
visible={hovered}
|
||||
onVisibleChange={handleHoverChange}
|
||||
open={hovered}
|
||||
onOpenChange={handleHoverChange}
|
||||
>
|
||||
<Popover
|
||||
content={
|
||||
@ -56,8 +56,8 @@ const App: React.FC = () => {
|
||||
}
|
||||
title="Click title"
|
||||
trigger="click"
|
||||
visible={clicked}
|
||||
onVisibleChange={handleClickChange}
|
||||
open={clicked}
|
||||
onOpenChange={handleClickChange}
|
||||
>
|
||||
<Button>Hover and click / 悬停并单击</Button>
|
||||
</Popover>
|
||||
|
@ -6,7 +6,7 @@ import type { TooltipProps } from '../tooltip';
|
||||
import Tooltip from '../tooltip';
|
||||
|
||||
const SliderTooltip = React.forwardRef<unknown, TooltipProps>((props, ref) => {
|
||||
const { visible } = props;
|
||||
const { open } = props;
|
||||
const innerRef = useRef<any>(null);
|
||||
|
||||
const rafRef = useRef<number | null>(null);
|
||||
@ -24,14 +24,14 @@ const SliderTooltip = React.forwardRef<unknown, TooltipProps>((props, ref) => {
|
||||
}
|
||||
|
||||
React.useEffect(() => {
|
||||
if (visible) {
|
||||
if (open) {
|
||||
keepAlign();
|
||||
} else {
|
||||
cancelKeepAlign();
|
||||
}
|
||||
|
||||
return cancelKeepAlign;
|
||||
}, [visible, props.title]);
|
||||
}, [open, props.title]);
|
||||
|
||||
return <Tooltip ref={composeRef(innerRef, ref)} {...props} />;
|
||||
});
|
||||
|
@ -161,7 +161,7 @@ describe('Slider', () => {
|
||||
render(
|
||||
<SliderTooltip
|
||||
title="30"
|
||||
visible
|
||||
open
|
||||
ref={node => {
|
||||
ref = node;
|
||||
}}
|
||||
|
@ -196,7 +196,7 @@ const Slider = React.forwardRef<unknown, SliderSingleProps | SliderRangeProps>(
|
||||
<SliderTooltip
|
||||
prefixCls={tooltipPrefixCls}
|
||||
title={tipFormatter ? tipFormatter(info.value) : ''}
|
||||
visible={open}
|
||||
open={open}
|
||||
placement={getTooltipPlacement(tooltipPlacement, vertical)}
|
||||
transitionName={`${rootPrefixCls}-zoom-down`}
|
||||
key={index}
|
||||
|
@ -895,7 +895,7 @@ describe('Table.filter', () => {
|
||||
|
||||
it('renders custom filter icon with right Tooltip title', () => {
|
||||
const filterIcon = () => (
|
||||
<Tooltip title="title" visible>
|
||||
<Tooltip title="title" open>
|
||||
Tooltip
|
||||
</Tooltip>
|
||||
);
|
||||
|
@ -21,7 +21,8 @@ describe('Tooltip', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('check `onVisibleChange` arguments', () => {
|
||||
it('check `onOpenChange` arguments', () => {
|
||||
const onOpenChange = jest.fn();
|
||||
const onVisibleChange = jest.fn();
|
||||
const ref = React.createRef();
|
||||
|
||||
@ -30,6 +31,7 @@ describe('Tooltip', () => {
|
||||
title=""
|
||||
mouseEnterDelay={0}
|
||||
mouseLeaveDelay={0}
|
||||
onOpenChange={onOpenChange}
|
||||
onVisibleChange={onVisibleChange}
|
||||
ref={ref}
|
||||
>
|
||||
@ -40,11 +42,13 @@ describe('Tooltip', () => {
|
||||
// `title` is empty.
|
||||
const divElement = container.querySelector('#hello');
|
||||
fireEvent.mouseEnter(divElement);
|
||||
expect(onOpenChange).not.toHaveBeenCalled();
|
||||
expect(onVisibleChange).not.toHaveBeenCalled();
|
||||
expect(ref.current.props.visible).toBe(false);
|
||||
expect(container.querySelector('.ant-tooltip-open')).toBeNull();
|
||||
|
||||
fireEvent.mouseLeave(divElement);
|
||||
expect(onOpenChange).not.toHaveBeenCalled();
|
||||
expect(onVisibleChange).not.toHaveBeenCalled();
|
||||
expect(ref.current.props.visible).toBe(false);
|
||||
expect(container.querySelector('.ant-tooltip-open')).toBeNull();
|
||||
@ -55,6 +59,7 @@ describe('Tooltip', () => {
|
||||
title="Have a nice day!"
|
||||
mouseEnterDelay={0}
|
||||
mouseLeaveDelay={0}
|
||||
onOpenChange={onOpenChange}
|
||||
onVisibleChange={onVisibleChange}
|
||||
ref={ref}
|
||||
>
|
||||
@ -62,42 +67,49 @@ describe('Tooltip', () => {
|
||||
</Tooltip>,
|
||||
);
|
||||
fireEvent.mouseEnter(divElement);
|
||||
expect(onOpenChange).toHaveBeenLastCalledWith(true);
|
||||
expect(onVisibleChange).toHaveBeenLastCalledWith(true);
|
||||
|
||||
expect(ref.current.props.visible).toBe(true);
|
||||
expect(container.querySelector('.ant-tooltip-open')).not.toBeNull();
|
||||
|
||||
fireEvent.mouseLeave(divElement);
|
||||
expect(onOpenChange).toHaveBeenLastCalledWith(false);
|
||||
expect(onVisibleChange).toHaveBeenLastCalledWith(false);
|
||||
expect(ref.current.props.visible).toBe(false);
|
||||
expect(container.querySelector('.ant-tooltip-open')).toBeNull();
|
||||
|
||||
// add `visible` props.
|
||||
// add `open` props.
|
||||
rerender(
|
||||
<Tooltip
|
||||
title="Have a nice day!"
|
||||
mouseEnterDelay={0}
|
||||
mouseLeaveDelay={0}
|
||||
onOpenChange={onOpenChange}
|
||||
onVisibleChange={onVisibleChange}
|
||||
ref={ref}
|
||||
visible={false}
|
||||
open={false}
|
||||
>
|
||||
<div id="hello">Hello world!</div>
|
||||
</Tooltip>,
|
||||
);
|
||||
fireEvent.mouseEnter(divElement);
|
||||
expect(onOpenChange).toHaveBeenLastCalledWith(true);
|
||||
expect(onVisibleChange).toHaveBeenLastCalledWith(true);
|
||||
const lastCount = onVisibleChange.mock.calls.length;
|
||||
const lastCount = onOpenChange.mock.calls.length;
|
||||
expect(ref.current.props.visible).toBe(false);
|
||||
expect(container.querySelector('.ant-tooltip-open')).toBeNull();
|
||||
|
||||
// always trigger onVisibleChange
|
||||
// always trigger onOpenChange
|
||||
fireEvent.mouseLeave(divElement);
|
||||
expect(onVisibleChange.mock.calls.length).toBe(lastCount); // no change with lastCount
|
||||
expect(onOpenChange.mock.calls.length).toBe(lastCount); // no change with lastCount
|
||||
expect(onVisibleChange.mock.calls.length).toBe(lastCount);
|
||||
expect(ref.current.props.visible).toBe(false);
|
||||
expect(container.querySelector('.ant-tooltip-open')).toBeNull();
|
||||
});
|
||||
|
||||
it('should hide when mouse leave native disabled button', () => {
|
||||
const onOpenChange = jest.fn();
|
||||
const onVisibleChange = jest.fn();
|
||||
const ref = React.createRef();
|
||||
|
||||
@ -106,6 +118,7 @@ describe('Tooltip', () => {
|
||||
title="xxxxx"
|
||||
mouseEnterDelay={0}
|
||||
mouseLeaveDelay={0}
|
||||
onOpenChange={onOpenChange}
|
||||
onVisibleChange={onVisibleChange}
|
||||
ref={ref}
|
||||
>
|
||||
@ -119,11 +132,13 @@ describe('Tooltip', () => {
|
||||
const button = container.getElementsByTagName('span')[0];
|
||||
|
||||
fireEvent.mouseEnter(button);
|
||||
expect(onOpenChange).toHaveBeenCalledWith(true);
|
||||
expect(onVisibleChange).toHaveBeenCalledWith(true);
|
||||
expect(ref.current.props.visible).toBe(true);
|
||||
expect(container.querySelector('.ant-tooltip-open')).not.toBeNull();
|
||||
|
||||
fireEvent.mouseLeave(button);
|
||||
expect(onOpenChange).toHaveBeenCalledWith(false);
|
||||
expect(onVisibleChange).toHaveBeenCalledWith(false);
|
||||
expect(ref.current.props.visible).toBe(false);
|
||||
expect(container.querySelector('.ant-tooltip-open')).toBeNull();
|
||||
@ -132,6 +147,7 @@ describe('Tooltip', () => {
|
||||
describe('should hide when mouse leave antd disabled component', () => {
|
||||
function testComponent(name, Component) {
|
||||
it(name, () => {
|
||||
const onOpenChange = jest.fn();
|
||||
const onVisibleChange = jest.fn();
|
||||
const ref = React.createRef();
|
||||
const { container } = render(
|
||||
@ -139,6 +155,7 @@ describe('Tooltip', () => {
|
||||
title="xxxxx"
|
||||
mouseEnterDelay={0}
|
||||
mouseLeaveDelay={0}
|
||||
onOpenChange={onOpenChange}
|
||||
onVisibleChange={onVisibleChange}
|
||||
ref={ref}
|
||||
>
|
||||
@ -150,11 +167,13 @@ describe('Tooltip', () => {
|
||||
const button = container.getElementsByTagName('span')[0];
|
||||
|
||||
fireEvent.mouseEnter(button);
|
||||
expect(onOpenChange).toHaveBeenCalledWith(true);
|
||||
expect(onVisibleChange).toHaveBeenCalledWith(true);
|
||||
expect(ref.current.props.visible).toBe(true);
|
||||
expect(container.querySelector('.ant-tooltip-open')).not.toBeNull();
|
||||
|
||||
fireEvent.mouseLeave(button);
|
||||
expect(onOpenChange).toHaveBeenCalledWith(false);
|
||||
expect(onVisibleChange).toHaveBeenCalledWith(false);
|
||||
expect(ref.current.props.visible).toBe(false);
|
||||
expect(container.querySelector('.ant-tooltip-open')).toBeNull();
|
||||
@ -235,11 +254,17 @@ describe('Tooltip', () => {
|
||||
});
|
||||
|
||||
it('should works for date picker', async () => {
|
||||
const onOpenChange = jest.fn();
|
||||
const onVisibleChange = jest.fn();
|
||||
const ref = React.createRef();
|
||||
|
||||
const { container } = render(
|
||||
<Tooltip title="date picker" onVisibleChange={onVisibleChange} ref={ref}>
|
||||
<Tooltip
|
||||
title="date picker"
|
||||
onOpenChange={onOpenChange}
|
||||
onVisibleChange={onVisibleChange}
|
||||
ref={ref}
|
||||
>
|
||||
<DatePicker />
|
||||
</Tooltip>,
|
||||
);
|
||||
@ -249,22 +274,30 @@ describe('Tooltip', () => {
|
||||
|
||||
fireEvent.mouseEnter(picker);
|
||||
await sleep(100);
|
||||
expect(onOpenChange).toHaveBeenCalledWith(true);
|
||||
expect(onVisibleChange).toHaveBeenCalledWith(true);
|
||||
expect(ref.current.props.visible).toBe(true);
|
||||
expect(container.querySelector('.ant-tooltip-open')).not.toBeNull();
|
||||
|
||||
fireEvent.mouseLeave(picker);
|
||||
await sleep(100);
|
||||
expect(onOpenChange).toHaveBeenCalledWith(false);
|
||||
expect(onVisibleChange).toHaveBeenCalledWith(false);
|
||||
expect(ref.current.props.visible).toBe(false);
|
||||
expect(container.querySelector('.ant-tooltip-open')).toBeNull();
|
||||
});
|
||||
|
||||
it('should works for input group', async () => {
|
||||
const onOpenChange = jest.fn();
|
||||
const onVisibleChange = jest.fn();
|
||||
const ref = React.createRef();
|
||||
const { container } = render(
|
||||
<Tooltip title="hello" onVisibleChange={onVisibleChange} ref={ref}>
|
||||
<Tooltip
|
||||
title="hello"
|
||||
onOpenChange={onOpenChange}
|
||||
onVisibleChange={onVisibleChange}
|
||||
ref={ref}
|
||||
>
|
||||
<Group>
|
||||
<Input style={{ width: '50%' }} />
|
||||
<Input style={{ width: '50%' }} />
|
||||
@ -276,12 +309,14 @@ describe('Tooltip', () => {
|
||||
const inputGroup = container.getElementsByClassName('ant-input-group')[0];
|
||||
fireEvent.mouseEnter(inputGroup);
|
||||
await sleep(100);
|
||||
expect(onOpenChange).toHaveBeenCalledWith(true);
|
||||
expect(onVisibleChange).toHaveBeenCalledWith(true);
|
||||
expect(ref.current.props.visible).toBe(true);
|
||||
expect(container.querySelector('.ant-tooltip-open')).not.toBeNull();
|
||||
|
||||
fireEvent.mouseLeave(inputGroup);
|
||||
await sleep(100);
|
||||
expect(onOpenChange).toHaveBeenCalledWith(false);
|
||||
expect(onVisibleChange).toHaveBeenCalledWith(false);
|
||||
expect(ref.current.props.visible).toBe(false);
|
||||
expect(container.querySelector('.ant-tooltip-open')).toBeNull();
|
||||
@ -290,7 +325,7 @@ describe('Tooltip', () => {
|
||||
// https://github.com/ant-design/ant-design/issues/20891
|
||||
it('should display zero', () => {
|
||||
const { container } = render(
|
||||
<Tooltip title={0} visible>
|
||||
<Tooltip title={0} open>
|
||||
<div />
|
||||
</Tooltip>,
|
||||
);
|
||||
@ -300,7 +335,7 @@ describe('Tooltip', () => {
|
||||
it('autoAdjustOverflow should be object or undefined', () => {
|
||||
expect(() => {
|
||||
render(
|
||||
<Tooltip title={0} visible autoAdjustOverflow={{ adjustX: 0, adjustY: 0 }}>
|
||||
<Tooltip title={0} open autoAdjustOverflow={{ adjustX: 0, adjustY: 0 }}>
|
||||
<div />
|
||||
</Tooltip>,
|
||||
);
|
||||
@ -308,7 +343,7 @@ describe('Tooltip', () => {
|
||||
|
||||
expect(() => {
|
||||
render(
|
||||
<Tooltip title={0} visible autoAdjustOverflow={undefined}>
|
||||
<Tooltip title={0} open autoAdjustOverflow={undefined}>
|
||||
<div />
|
||||
</Tooltip>,
|
||||
);
|
||||
@ -386,12 +421,14 @@ describe('Tooltip', () => {
|
||||
});
|
||||
|
||||
it('should work with loading switch', () => {
|
||||
const onOpenChange = jest.fn();
|
||||
const onVisibleChange = jest.fn();
|
||||
const { container } = render(
|
||||
<Tooltip
|
||||
title="loading tips"
|
||||
mouseEnterDelay={0}
|
||||
mouseLeaveDelay={0}
|
||||
onOpenChange={onOpenChange}
|
||||
onVisibleChange={onVisibleChange}
|
||||
>
|
||||
<Switch loading defaultChecked />
|
||||
@ -400,17 +437,20 @@ describe('Tooltip', () => {
|
||||
const wrapperEl = container.querySelectorAll('.ant-tooltip-disabled-compatible-wrapper');
|
||||
expect(wrapperEl).toHaveLength(1);
|
||||
fireEvent.mouseEnter(container.getElementsByTagName('span')[0]);
|
||||
expect(onOpenChange).toHaveBeenLastCalledWith(true);
|
||||
expect(onVisibleChange).toHaveBeenLastCalledWith(true);
|
||||
expect(container.querySelector('.ant-tooltip-open')).not.toBeNull();
|
||||
});
|
||||
|
||||
it('should work with disabled Radio', () => {
|
||||
const onOpenChange = jest.fn();
|
||||
const onVisibleChange = jest.fn();
|
||||
const { container } = render(
|
||||
<Tooltip
|
||||
title="loading tips"
|
||||
mouseEnterDelay={0}
|
||||
mouseLeaveDelay={0}
|
||||
onOpenChange={onOpenChange}
|
||||
onVisibleChange={onVisibleChange}
|
||||
>
|
||||
<Radio disabled />
|
||||
@ -419,11 +459,13 @@ describe('Tooltip', () => {
|
||||
const wrapperEl = container.querySelectorAll('.ant-tooltip-disabled-compatible-wrapper');
|
||||
expect(wrapperEl).toHaveLength(1);
|
||||
fireEvent.mouseEnter(container.getElementsByTagName('span')[0]);
|
||||
expect(onOpenChange).toHaveBeenLastCalledWith(true);
|
||||
expect(onVisibleChange).toHaveBeenLastCalledWith(true);
|
||||
expect(container.querySelector('.ant-tooltip-open')).not.toBeNull();
|
||||
});
|
||||
|
||||
it('should work with Fragment children', () => {
|
||||
const onOpenChange = jest.fn();
|
||||
const onVisibleChange = jest.fn();
|
||||
const ref = React.createRef();
|
||||
|
||||
@ -432,6 +474,7 @@ describe('Tooltip', () => {
|
||||
title="Have a nice day!"
|
||||
mouseEnterDelay={0}
|
||||
mouseLeaveDelay={0}
|
||||
onOpenChange={onOpenChange}
|
||||
onVisibleChange={onVisibleChange}
|
||||
ref={ref}
|
||||
>
|
||||
@ -444,13 +487,54 @@ describe('Tooltip', () => {
|
||||
|
||||
const divElement = container.querySelector('.hello');
|
||||
fireEvent.mouseEnter(divElement);
|
||||
expect(onOpenChange).toHaveBeenLastCalledWith(true);
|
||||
expect(onVisibleChange).toHaveBeenLastCalledWith(true);
|
||||
expect(ref.current.props.visible).toBe(true);
|
||||
expect(container.querySelector('.ant-tooltip-open')).not.toBeNull();
|
||||
|
||||
fireEvent.mouseLeave(divElement);
|
||||
expect(onOpenChange).toHaveBeenLastCalledWith(false);
|
||||
expect(onVisibleChange).toHaveBeenLastCalledWith(false);
|
||||
expect(ref.current.props.visible).toBe(false);
|
||||
expect(container.querySelector('.ant-tooltip-open')).toBeNull();
|
||||
});
|
||||
|
||||
it('deprecated warning', () => {
|
||||
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
const { rerender } = render(
|
||||
<Tooltip visible>
|
||||
<a />
|
||||
</Tooltip>,
|
||||
);
|
||||
expect(errSpy).toHaveBeenCalledWith(
|
||||
'Warning: [antd: Tooltip] `visible` is deprecated which will be removed in next major version, please use `open` instead.',
|
||||
);
|
||||
rerender(
|
||||
<Tooltip defaultVisible>
|
||||
<a />
|
||||
</Tooltip>,
|
||||
);
|
||||
expect(errSpy).toHaveBeenCalledWith(
|
||||
'Warning: [antd: Tooltip] `defaultVisible` is deprecated which will be removed in next major version, please use `defaultOpen` instead.',
|
||||
);
|
||||
rerender(
|
||||
<Tooltip onVisibleChange={() => {}}>
|
||||
<a />
|
||||
</Tooltip>,
|
||||
);
|
||||
expect(errSpy).toHaveBeenCalledWith(
|
||||
'Warning: [antd: Tooltip] `onVisibleChange` is deprecated which will be removed in next major version, please use `onOpenChange` instead.',
|
||||
);
|
||||
rerender(
|
||||
<Tooltip afterVisibleChange={() => {}}>
|
||||
<a />
|
||||
</Tooltip>,
|
||||
);
|
||||
expect(errSpy).toHaveBeenCalledWith(
|
||||
'Warning: [antd: Tooltip] `afterVisibleChange` is deprecated which will be removed in next major version, please use `afterOpenChange` instead.',
|
||||
);
|
||||
|
||||
errSpy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
@ -28,7 +28,7 @@ The following APIs are shared by Tooltip, Popconfirm, Popover.
|
||||
| arrowPointAtCenter | Whether the arrow is pointed at the center of target | boolean | false | |
|
||||
| autoAdjustOverflow | Whether to adjust popup placement automatically when popup is off screen | boolean | true | |
|
||||
| color | The background color | string | - | 4.3.0 |
|
||||
| defaultVisible | Whether the floating tooltip card is visible by default | boolean | false | |
|
||||
| defaultOpen | Whether the floating tooltip card is open by default | boolean | false | 4.23.0 |
|
||||
| destroyTooltipOnHide | Whether destroy tooltip when hidden, parent container of tooltip will be destroyed when `keepParent` is false | boolean \| { keepParent?: boolean } | false | |
|
||||
| getPopupContainer | The DOM container of the tip, the default behavior is to create a `div` element in `body` | function(triggerNode) | () => document.body | |
|
||||
| mouseEnterDelay | Delay in seconds, before tooltip is shown on mouse enter | number | 0.1 | |
|
||||
@ -38,9 +38,9 @@ The following APIs are shared by Tooltip, Popconfirm, Popover.
|
||||
| overlayInnerStyle | Style of the tooltip inner content | object | - | |
|
||||
| placement | The position of the tooltip relative to the target, which can be one of `top` `left` `right` `bottom` `topLeft` `topRight` `bottomLeft` `bottomRight` `leftTop` `leftBottom` `rightTop` `rightBottom` | string | `top` | |
|
||||
| trigger | Tooltip trigger mode. Could be multiple by passing an array | `hover` \| `focus` \| `click` \| `contextMenu` \| Array<string> | `hover` | |
|
||||
| visible | Whether the floating tooltip card is visible or not | boolean | false | |
|
||||
| open | Whether the floating tooltip card is open or not | boolean | false | 4.23.0 |
|
||||
| zIndex | Config `z-index` of Tooltip | number | - | |
|
||||
| onVisibleChange | Callback executed when visibility of the tooltip card is changed | (visible) => void | - | |
|
||||
| onOpenChange | Callback executed when visibility of the tooltip card is changed | (open) => void | - | 4.23.0 |
|
||||
|
||||
## Note
|
||||
|
||||
|
@ -11,6 +11,7 @@ import { getTransitionName } from '../_util/motion';
|
||||
import getPlacements, { AdjustOverflow, PlacementsConfig } from '../_util/placements';
|
||||
import { cloneElement, isValidElement, isFragment } from '../_util/reactNode';
|
||||
import type { LiteralUnion } from '../_util/type';
|
||||
import warning from '../_util/warning';
|
||||
|
||||
export { AdjustOverflow, PlacementsConfig };
|
||||
|
||||
@ -39,8 +40,41 @@ export interface TooltipAlignConfig {
|
||||
useCssBottom?: boolean;
|
||||
useCssTransform?: boolean;
|
||||
}
|
||||
// remove this after RcTooltip switch visible to open.
|
||||
interface LegacyTooltipProps
|
||||
extends Partial<
|
||||
Omit<
|
||||
RcTooltipProps,
|
||||
'children' | 'visible' | 'defaultVisible' | 'onVisibleChange' | 'afterVisibleChange'
|
||||
>
|
||||
> {
|
||||
/**
|
||||
* @deprecated `visible` is deprecated which will be removed in next major version. Please use
|
||||
* `open` instead.
|
||||
*/
|
||||
visible?: RcTooltipProps['visible'];
|
||||
open?: RcTooltipProps['visible'];
|
||||
/**
|
||||
* @deprecated `defaultVisible` is deprecated which will be removed in next major version. Please
|
||||
* use `defaultOpen` instead.
|
||||
*/
|
||||
defaultVisible?: RcTooltipProps['defaultVisible'];
|
||||
defaultOpen?: RcTooltipProps['defaultVisible'];
|
||||
/**
|
||||
* @deprecated `onVisibleChange` is deprecated which will be removed in next major version. Please
|
||||
* use `onOpenChange` instead.
|
||||
*/
|
||||
onVisibleChange?: RcTooltipProps['onVisibleChange'];
|
||||
onOpenChange?: RcTooltipProps['onVisibleChange'];
|
||||
/**
|
||||
* @deprecated `afterVisibleChange` is deprecated which will be removed in next major version.
|
||||
* Please use `afterOpenChange` instead.
|
||||
*/
|
||||
afterVisibleChange?: RcTooltipProps['afterVisibleChange'];
|
||||
afterOpenChange?: RcTooltipProps['afterVisibleChange'];
|
||||
}
|
||||
|
||||
export interface AbstractTooltipProps extends Partial<Omit<RcTooltipProps, 'children'>> {
|
||||
export interface AbstractTooltipProps extends LegacyTooltipProps {
|
||||
style?: React.CSSProperties;
|
||||
className?: string;
|
||||
color?: LiteralUnion<PresetColorType, string>;
|
||||
@ -135,9 +169,25 @@ const Tooltip = React.forwardRef<unknown, TooltipProps>((props, ref) => {
|
||||
direction,
|
||||
} = React.useContext(ConfigContext);
|
||||
|
||||
const [visible, setVisible] = useMergedState(false, {
|
||||
value: props.visible,
|
||||
defaultValue: props.defaultVisible,
|
||||
// Warning for deprecated usage
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
[
|
||||
['visible', 'open'],
|
||||
['defaultVisible', 'defaultOpen'],
|
||||
['onVisibleChange', 'onOpenChange'],
|
||||
['afterVisibleChange', 'afterOpenChange'],
|
||||
].forEach(([deprecatedName, newName]) => {
|
||||
warning(
|
||||
!(deprecatedName in props),
|
||||
'Tooltip',
|
||||
`\`${deprecatedName}\` is deprecated which will be removed in next major version, please use \`${newName}\` instead.`,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
const [open, setOpen] = useMergedState(false, {
|
||||
value: props.open !== undefined ? props.open : props.visible,
|
||||
defaultValue: props.defaultOpen !== undefined ? props.defaultOpen : props.defaultVisible,
|
||||
});
|
||||
|
||||
const isNoTitle = () => {
|
||||
@ -145,10 +195,11 @@ const Tooltip = React.forwardRef<unknown, TooltipProps>((props, ref) => {
|
||||
return !title && !overlay && title !== 0; // overlay for old version compatibility
|
||||
};
|
||||
|
||||
const onVisibleChange = (vis: boolean) => {
|
||||
setVisible(isNoTitle() ? false : vis);
|
||||
const onOpenChange = (vis: boolean) => {
|
||||
setOpen(isNoTitle() ? false : vis);
|
||||
|
||||
if (!isNoTitle()) {
|
||||
props.onOpenChange?.(vis);
|
||||
props.onVisibleChange?.(vis);
|
||||
}
|
||||
};
|
||||
@ -217,10 +268,10 @@ const Tooltip = React.forwardRef<unknown, TooltipProps>((props, ref) => {
|
||||
const prefixCls = getPrefixCls('tooltip', customizePrefixCls);
|
||||
const rootPrefixCls = getPrefixCls();
|
||||
|
||||
let tempVisible = visible;
|
||||
let tempOpen = open;
|
||||
// Hide tooltip when there is no title
|
||||
if (!('visible' in props) && isNoTitle()) {
|
||||
tempVisible = false;
|
||||
if (!('open' in props) && !('visible' in props) && isNoTitle()) {
|
||||
tempOpen = false;
|
||||
}
|
||||
|
||||
const child = getDisabledCompatibleChildren(
|
||||
@ -254,8 +305,8 @@ const Tooltip = React.forwardRef<unknown, TooltipProps>((props, ref) => {
|
||||
ref={ref}
|
||||
builtinPlacements={getTooltipPlacements()}
|
||||
overlay={getOverlay()}
|
||||
visible={tempVisible}
|
||||
onVisibleChange={onVisibleChange}
|
||||
visible={tempOpen}
|
||||
onVisibleChange={onOpenChange}
|
||||
onPopupAlign={onPopupAlign}
|
||||
overlayInnerStyle={formattedOverlayInnerStyle}
|
||||
arrowContent={<span className={`${prefixCls}-arrow-content`} style={arrowContentStyle} />}
|
||||
@ -264,7 +315,7 @@ const Tooltip = React.forwardRef<unknown, TooltipProps>((props, ref) => {
|
||||
motionDeadline: 1000,
|
||||
}}
|
||||
>
|
||||
{tempVisible ? cloneElement(child, { className: childCls }) : child}
|
||||
{tempOpen ? cloneElement(child, { className: childCls }) : child}
|
||||
</RcTooltip>
|
||||
);
|
||||
});
|
||||
|
@ -30,7 +30,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/Vyyeu8jq2/Tooltp.svg
|
||||
| arrowPointAtCenter | 箭头是否指向目标元素中心 | boolean | false | |
|
||||
| autoAdjustOverflow | 气泡被遮挡时自动调整位置 | boolean | true | |
|
||||
| color | 背景颜色 | string | - | 4.3.0 |
|
||||
| defaultVisible | 默认是否显隐 | boolean | false | |
|
||||
| defaultOpen | 默认是否显隐 | boolean | false | 4.23.0 |
|
||||
| destroyTooltipOnHide | 关闭后是否销毁 Tooltip,当 `keepParent` 为 `false` 时销毁父容器 | boolean \| { keepParent?: boolean } | false | |
|
||||
| getPopupContainer | 浮层渲染父节点,默认渲染到 body 上 | function(triggerNode) | () => document.body | |
|
||||
| mouseEnterDelay | 鼠标移入后延时多少才显示 Tooltip,单位:秒 | number | 0.1 | |
|
||||
@ -40,9 +40,9 @@ cover: https://gw.alipayobjects.com/zos/alicdn/Vyyeu8jq2/Tooltp.svg
|
||||
| overlayInnerStyle | 卡片内容区域的样式对象 | object | - | |
|
||||
| placement | 气泡框位置,可选 `top` `left` `right` `bottom` `topLeft` `topRight` `bottomLeft` `bottomRight` `leftTop` `leftBottom` `rightTop` `rightBottom` | string | `top` | |
|
||||
| trigger | 触发行为,可选 `hover` \| `focus` \| `click` \| `contextMenu`,可使用数组设置多个触发行为 | string \| string\[] | `hover` | |
|
||||
| visible | 用于手动控制浮层显隐 | boolean | false | |
|
||||
| open | 用于手动控制浮层显隐 | boolean | false | 4.23.0 |
|
||||
| zIndex | 设置 Tooltip 的 `z-index` | number | - | |
|
||||
| onVisibleChange | 显示隐藏的回调 | (visible) => void | - | |
|
||||
| onOpenChange | 显示隐藏的回调 | (open) => void | - | 4.23.0 |
|
||||
|
||||
## 注意
|
||||
|
||||
|
@ -20,7 +20,7 @@ const EllipsisTooltip = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<Tooltip visible={isEllipsis ? undefined : false} {...tooltipProps}>
|
||||
<Tooltip open={isEllipsis ? undefined : false} {...tooltipProps}>
|
||||
{children}
|
||||
</Tooltip>
|
||||
);
|
||||
|
@ -36,7 +36,7 @@ class Demo extends React.Component {
|
||||
state = {
|
||||
codeExpand: false,
|
||||
copied: false,
|
||||
copyTooltipVisible: false,
|
||||
copyTooltipOpen: false,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
@ -47,12 +47,12 @@ class Demo extends React.Component {
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
const { codeExpand, copied, copyTooltipVisible } = this.state;
|
||||
const { codeExpand, copied, copyTooltipOpen } = this.state;
|
||||
const { expand, theme, showRiddleButton, react18 } = this.props;
|
||||
return (
|
||||
(codeExpand || expand) !== (nextState.codeExpand || nextProps.expand) ||
|
||||
copied !== nextState.copied ||
|
||||
copyTooltipVisible !== nextState.copyTooltipVisible ||
|
||||
copyTooltipOpen !== nextState.copyTooltipOpen ||
|
||||
nextProps.theme !== theme ||
|
||||
nextProps.showRiddleButton !== showRiddleButton ||
|
||||
nextProps.react18 !== react18
|
||||
@ -90,16 +90,16 @@ class Demo extends React.Component {
|
||||
});
|
||||
};
|
||||
|
||||
onCopyTooltipVisibleChange = visible => {
|
||||
if (visible) {
|
||||
onCopyTooltipOpenChange = open => {
|
||||
if (open) {
|
||||
this.setState({
|
||||
copyTooltipVisible: visible,
|
||||
copyTooltipOpen: open,
|
||||
copied: false,
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.setState({
|
||||
copyTooltipVisible: visible,
|
||||
copyTooltipOpen: open,
|
||||
});
|
||||
};
|
||||
|
||||
@ -139,7 +139,7 @@ class Demo extends React.Component {
|
||||
showRiddleButton,
|
||||
react18,
|
||||
} = props;
|
||||
const { copied, copyTooltipVisible } = state;
|
||||
const { copied, copyTooltipOpen } = state;
|
||||
if (!this.liveDemo) {
|
||||
this.liveDemo = meta.iframe ? (
|
||||
<BrowserFrame>
|
||||
@ -448,16 +448,13 @@ ReactDOM.render(<Demo />, document.getElementById('container'));
|
||||
</Tooltip>
|
||||
<CopyToClipboard text={sourceCode} onCopy={() => this.handleCodeCopied(meta.id)}>
|
||||
<Tooltip
|
||||
visible={copyTooltipVisible}
|
||||
onVisibleChange={this.onCopyTooltipVisibleChange}
|
||||
open={copyTooltipOpen}
|
||||
onOpenChange={this.onCopyTooltipOpenChange}
|
||||
title={<FormattedMessage id={`app.demo.${copied ? 'copied' : 'copy'}`} />}
|
||||
>
|
||||
{React.createElement(
|
||||
copied && copyTooltipVisible ? CheckOutlined : SnippetsOutlined,
|
||||
{
|
||||
className: 'code-box-code-copy code-box-code-action',
|
||||
},
|
||||
)}
|
||||
{React.createElement(copied && copyTooltipOpen ? CheckOutlined : SnippetsOutlined, {
|
||||
className: 'code-box-code-copy code-box-code-action',
|
||||
})}
|
||||
</Tooltip>
|
||||
</CopyToClipboard>
|
||||
<Tooltip
|
||||
|
@ -140,7 +140,7 @@ const PicSearcher: React.FC<PicSearcherProps> = ({ intl }) => {
|
||||
<div className="icon-pic-searcher">
|
||||
<Popover
|
||||
content={messages[`app.docs.components.icon.pic-searcher.intro`]}
|
||||
visible={state.popoverVisible}
|
||||
open={state.popoverVisible}
|
||||
>
|
||||
<AntdIcons.CameraOutlined className="icon-pic-btn" onClick={toggleModal} />
|
||||
</Popover>
|
||||
|
@ -302,9 +302,9 @@ const Header: React.FC<HeaderProps & WrappedComponentProps<'intl'>> = props => {
|
||||
placement="bottomRight"
|
||||
content={menu}
|
||||
trigger="click"
|
||||
visible={menuVisible}
|
||||
open={menuVisible}
|
||||
arrowPointAtCenter
|
||||
onVisibleChange={onMenuVisibleChange}
|
||||
onOpenChange={onMenuVisibleChange}
|
||||
>
|
||||
<MenuOutlined className="nav-phone-icon" onClick={handleShowMenu} />
|
||||
</Popover>
|
||||
|
Loading…
Reference in New Issue
Block a user