mirror of
https://github.com/ant-design/ant-design.git
synced 2025-06-11 11:32:52 +08:00
chore: support deprecated visible in v5 but warning with this (#37422)
* chore: tags deprecated support * chore: Slider Tooltip test * chore: Table dropdown visible legacy * chore: drawer warning of legacy * chore: Modal legacy prop * chore: dropdown open legacy prop * chore: Tooltiop visible legacy info * fix: format logic * test: Update test for 18 * chore: fix lint
This commit is contained in:
parent
f85c68f4be
commit
44d8076304
@ -106,7 +106,7 @@ describe('Drawer', () => {
|
|||||||
expect(container.querySelector('.ant-drawer-content-wrapper-hidden')).toBeTruthy();
|
expect(container.querySelector('.ant-drawer-content-wrapper-hidden')).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('test afterVisibleChange', async () => {
|
it('test afterOpenChange', async () => {
|
||||||
const afterOpenChange = jest.fn();
|
const afterOpenChange = jest.fn();
|
||||||
const { container, rerender } = render(<DrawerTest open afterOpenChange={afterOpenChange} />);
|
const { container, rerender } = render(<DrawerTest open afterOpenChange={afterOpenChange} />);
|
||||||
rerender(<DrawerTest open={false} afterOpenChange={afterOpenChange} />);
|
rerender(<DrawerTest open={false} afterOpenChange={afterOpenChange} />);
|
||||||
@ -119,6 +119,31 @@ describe('Drawer', () => {
|
|||||||
expect(afterOpenChange).toHaveBeenCalledTimes(1);
|
expect(afterOpenChange).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('test legacy afterVisibleChange', async () => {
|
||||||
|
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
|
|
||||||
|
const afterVisibleChange = jest.fn();
|
||||||
|
const { container, rerender } = render(
|
||||||
|
<DrawerTest open afterVisibleChange={afterVisibleChange} />,
|
||||||
|
);
|
||||||
|
rerender(<DrawerTest visible={false} afterVisibleChange={afterVisibleChange} />);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
|
fireEvent.animationEnd(container.querySelector('.ant-drawer-content-wrapper')!);
|
||||||
|
|
||||||
|
expect(afterVisibleChange).toHaveBeenCalledTimes(1);
|
||||||
|
expect(errorSpy).toHaveBeenCalledWith(
|
||||||
|
'Warning: [antd: Drawer] `visible` is deprecated, please use `open` instead.',
|
||||||
|
);
|
||||||
|
expect(errorSpy).toHaveBeenCalledWith(
|
||||||
|
'Warning: [antd: Drawer] `afterVisibleChange` is deprecated, please use `afterOpenChange` instead.',
|
||||||
|
);
|
||||||
|
|
||||||
|
errorSpy.mockRestore();
|
||||||
|
});
|
||||||
|
|
||||||
it('should support children ref', () => {
|
it('should support children ref', () => {
|
||||||
const fn = jest.fn();
|
const fn = jest.fn();
|
||||||
|
|
||||||
|
@ -39,6 +39,12 @@ export interface DrawerProps extends RcDrawerProps {
|
|||||||
extra?: React.ReactNode;
|
extra?: React.ReactNode;
|
||||||
|
|
||||||
afterOpenChange?: (open: boolean) => void;
|
afterOpenChange?: (open: boolean) => void;
|
||||||
|
|
||||||
|
// Deprecated
|
||||||
|
/** @deprecated Please use `open` instead */
|
||||||
|
visible?: boolean;
|
||||||
|
/** @deprecated Please use `afterOpenChange` instead */
|
||||||
|
afterVisibleChange?: (open: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultPushState: PushState = { distance: 180 };
|
const defaultPushState: PushState = { distance: 180 };
|
||||||
@ -56,6 +62,7 @@ function Drawer(props: DrawerProps) {
|
|||||||
bodyStyle,
|
bodyStyle,
|
||||||
drawerStyle,
|
drawerStyle,
|
||||||
open,
|
open,
|
||||||
|
afterOpenChange,
|
||||||
children,
|
children,
|
||||||
title,
|
title,
|
||||||
headerStyle,
|
headerStyle,
|
||||||
@ -65,6 +72,11 @@ function Drawer(props: DrawerProps) {
|
|||||||
prefixCls: customizePrefixCls,
|
prefixCls: customizePrefixCls,
|
||||||
getContainer: customizeGetContainer,
|
getContainer: customizeGetContainer,
|
||||||
extra,
|
extra,
|
||||||
|
|
||||||
|
// Deprecated
|
||||||
|
visible,
|
||||||
|
afterVisibleChange,
|
||||||
|
|
||||||
...rest
|
...rest
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
@ -86,17 +98,6 @@ function Drawer(props: DrawerProps) {
|
|||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
|
||||||
[
|
|
||||||
['visible', 'open'],
|
|
||||||
['afterVisibleChange', 'afterOpenChange'],
|
|
||||||
].forEach(([deprecatedName, newName]) => {
|
|
||||||
warning(
|
|
||||||
!(deprecatedName in props),
|
|
||||||
'Drawer',
|
|
||||||
`\`${deprecatedName}\` is deprecated which will be removed in next major version, please use \`${newName}\` instead.`,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
function renderHeader() {
|
function renderHeader() {
|
||||||
if (!title && !closable) {
|
if (!title && !closable) {
|
||||||
return null;
|
return null;
|
||||||
@ -149,7 +150,7 @@ function Drawer(props: DrawerProps) {
|
|||||||
warning(
|
warning(
|
||||||
!(deprecatedName in props),
|
!(deprecatedName in props),
|
||||||
'Drawer',
|
'Drawer',
|
||||||
`\`${deprecatedName}\` is removed, please use \`${newName}\` instead.`,
|
`\`${deprecatedName}\` is deprecated, please use \`${newName}\` instead.`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -187,13 +188,14 @@ function Drawer(props: DrawerProps) {
|
|||||||
maskMotion={maskMotion}
|
maskMotion={maskMotion}
|
||||||
motion={panelMotion}
|
motion={panelMotion}
|
||||||
{...rest}
|
{...rest}
|
||||||
open={open}
|
open={open ?? visible}
|
||||||
mask={mask}
|
mask={mask}
|
||||||
push={push}
|
push={push}
|
||||||
width={mergedWidth}
|
width={mergedWidth}
|
||||||
height={mergedHeight}
|
height={mergedHeight}
|
||||||
rootClassName={drawerClassName}
|
rootClassName={drawerClassName}
|
||||||
getContainer={getContainer}
|
getContainer={getContainer}
|
||||||
|
afterOpenChange={afterOpenChange ?? afterVisibleChange}
|
||||||
>
|
>
|
||||||
<div className={`${prefixCls}-wrapper-body`} style={{ ...drawerStyle }}>
|
<div className={`${prefixCls}-wrapper-body`} style={{ ...drawerStyle }}>
|
||||||
{renderHeader()}
|
{renderHeader()}
|
||||||
|
@ -6,6 +6,7 @@ import mountTest from '../../../tests/shared/mountTest';
|
|||||||
import rtlTest from '../../../tests/shared/rtlTest';
|
import rtlTest from '../../../tests/shared/rtlTest';
|
||||||
import { act, fireEvent, render, sleep } from '../../../tests/utils';
|
import { act, fireEvent, render, sleep } from '../../../tests/utils';
|
||||||
import Menu from '../../menu';
|
import Menu from '../../menu';
|
||||||
|
import { resetWarned } from '../../_util/warning';
|
||||||
|
|
||||||
let triggerProps: TriggerProps;
|
let triggerProps: TriggerProps;
|
||||||
|
|
||||||
@ -167,4 +168,37 @@ describe('Dropdown', () => {
|
|||||||
|
|
||||||
jest.useRealTimers();
|
jest.useRealTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('legacy visible', () => {
|
||||||
|
resetWarned();
|
||||||
|
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
|
const onOpenChange = jest.fn();
|
||||||
|
const onVisibleChange = jest.fn();
|
||||||
|
|
||||||
|
const { container } = render(
|
||||||
|
<Dropdown
|
||||||
|
visible
|
||||||
|
onOpenChange={onOpenChange}
|
||||||
|
onVisibleChange={onVisibleChange}
|
||||||
|
trigger={['click']}
|
||||||
|
overlay={<div className="bamboo" />}
|
||||||
|
>
|
||||||
|
<a className="little" />
|
||||||
|
</Dropdown>,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(document.querySelector('.bamboo')).toBeTruthy();
|
||||||
|
expect(errorSpy).toHaveBeenCalledWith(
|
||||||
|
'Warning: [antd: Dropdown] `visible` is deprecated, please use `open` instead.',
|
||||||
|
);
|
||||||
|
expect(errorSpy).toHaveBeenCalledWith(
|
||||||
|
'Warning: [antd: Dropdown] `onVisibleChange` is deprecated, please use `onOpenChange` instead.',
|
||||||
|
);
|
||||||
|
|
||||||
|
fireEvent.click(container.querySelector('.little')!);
|
||||||
|
expect(onOpenChange).toHaveBeenCalled();
|
||||||
|
expect(onVisibleChange).toHaveBeenCalled();
|
||||||
|
|
||||||
|
errorSpy.mockRestore();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -68,6 +68,12 @@ export interface DropdownProps {
|
|||||||
mouseLeaveDelay?: number;
|
mouseLeaveDelay?: number;
|
||||||
openClassName?: string;
|
openClassName?: string;
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
|
|
||||||
|
// Deprecated
|
||||||
|
/** @deprecated Please use `open` instead */
|
||||||
|
visible?: boolean;
|
||||||
|
/** @deprecated Please use `onOpenChange` instead */
|
||||||
|
onVisibleChange?: (open: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DropdownInterface extends React.FC<DropdownProps> {
|
interface DropdownInterface extends React.FC<DropdownProps> {
|
||||||
@ -82,17 +88,6 @@ const Dropdown: DropdownInterface = props => {
|
|||||||
direction,
|
direction,
|
||||||
} = React.useContext(ConfigContext);
|
} = React.useContext(ConfigContext);
|
||||||
|
|
||||||
[
|
|
||||||
['visible', 'open'],
|
|
||||||
['onVisibleChange', 'onOpenChange'],
|
|
||||||
].forEach(([deprecatedName, newName]) => {
|
|
||||||
warning(
|
|
||||||
!(deprecatedName in props),
|
|
||||||
'Dropdown',
|
|
||||||
`\`${deprecatedName}\` is deprecated, please use \`${newName}\` instead.`,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
const getTransitionName = () => {
|
const getTransitionName = () => {
|
||||||
const rootPrefixCls = getPrefixCls();
|
const rootPrefixCls = getPrefixCls();
|
||||||
const { placement = '', transitionName } = props;
|
const { placement = '', transitionName } = props;
|
||||||
@ -134,8 +129,25 @@ const Dropdown: DropdownInterface = props => {
|
|||||||
overlayClassName,
|
overlayClassName,
|
||||||
open,
|
open,
|
||||||
onOpenChange,
|
onOpenChange,
|
||||||
|
|
||||||
|
// Deprecated
|
||||||
|
visible,
|
||||||
|
onVisibleChange,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
[
|
||||||
|
['visible', 'open'],
|
||||||
|
['onVisibleChange', 'onOpenChange'],
|
||||||
|
].forEach(([deprecatedName, newName]) => {
|
||||||
|
warning(
|
||||||
|
!(deprecatedName in props),
|
||||||
|
'Dropdown',
|
||||||
|
`\`${deprecatedName}\` is deprecated, please use \`${newName}\` instead.`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const prefixCls = getPrefixCls('dropdown', customizePrefixCls);
|
const prefixCls = getPrefixCls('dropdown', customizePrefixCls);
|
||||||
const [wrapSSR, hashId] = useStyle(prefixCls);
|
const [wrapSSR, hashId] = useStyle(prefixCls);
|
||||||
|
|
||||||
@ -160,11 +172,12 @@ const Dropdown: DropdownInterface = props => {
|
|||||||
|
|
||||||
// =========================== Open ============================
|
// =========================== Open ============================
|
||||||
const [mergedOpen, setOpen] = useMergedState(false, {
|
const [mergedOpen, setOpen] = useMergedState(false, {
|
||||||
value: open,
|
value: open ?? visible,
|
||||||
});
|
});
|
||||||
|
|
||||||
const onInnerOpenChange = useEvent((nextOpen: boolean) => {
|
const onInnerOpenChange = useEvent((nextOpen: boolean) => {
|
||||||
onOpenChange?.(nextOpen);
|
onOpenChange?.(nextOpen);
|
||||||
|
onVisibleChange?.(nextOpen);
|
||||||
setOpen(nextOpen);
|
setOpen(nextOpen);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -82,6 +82,10 @@ export interface ModalProps {
|
|||||||
modalRender?: (node: React.ReactNode) => React.ReactNode;
|
modalRender?: (node: React.ReactNode) => React.ReactNode;
|
||||||
focusTriggerAfterClose?: boolean;
|
focusTriggerAfterClose?: boolean;
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
|
|
||||||
|
// Legacy
|
||||||
|
/** @deprecated Please use `open` instead. */
|
||||||
|
visible?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
type getContainerFunc = () => HTMLElement;
|
type getContainerFunc = () => HTMLElement;
|
||||||
@ -148,14 +152,6 @@ const Modal: React.FC<ModalProps> = props => {
|
|||||||
onOk?.(e);
|
onOk?.(e);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
|
||||||
warning(
|
|
||||||
!('visible' in props),
|
|
||||||
'Modal',
|
|
||||||
`\`visible\` is removed in v5, please use \`open\` instead.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
prefixCls: customizePrefixCls,
|
prefixCls: customizePrefixCls,
|
||||||
className,
|
className,
|
||||||
@ -165,6 +161,10 @@ const Modal: React.FC<ModalProps> = props => {
|
|||||||
getContainer,
|
getContainer,
|
||||||
closeIcon,
|
closeIcon,
|
||||||
focusTriggerAfterClose = true,
|
focusTriggerAfterClose = true,
|
||||||
|
|
||||||
|
// Deprecated
|
||||||
|
visible,
|
||||||
|
|
||||||
...restProps
|
...restProps
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
@ -178,11 +178,9 @@ const Modal: React.FC<ModalProps> = props => {
|
|||||||
[`${prefixCls}-wrap-rtl`]: direction === 'rtl',
|
[`${prefixCls}-wrap-rtl`]: direction === 'rtl',
|
||||||
});
|
});
|
||||||
|
|
||||||
warning(
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
!('visible' in props),
|
warning(!('visible' in props), 'Modal', '`visible` is deprecated, please use `open` instead.');
|
||||||
'Modal',
|
}
|
||||||
`\`visible\` is deprecated, please use \`open\` instead.`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return wrapSSR(
|
return wrapSSR(
|
||||||
<NoFormStyle status override>
|
<NoFormStyle status override>
|
||||||
@ -199,7 +197,7 @@ const Modal: React.FC<ModalProps> = props => {
|
|||||||
onOk: handleOk,
|
onOk: handleOk,
|
||||||
onCancel: handleCancel,
|
onCancel: handleCancel,
|
||||||
})}
|
})}
|
||||||
visible={open}
|
visible={open ?? visible}
|
||||||
mousePosition={mousePosition}
|
mousePosition={mousePosition}
|
||||||
onClose={handleCancel}
|
onClose={handleCancel}
|
||||||
closeIcon={renderCloseIcon(prefixCls, closeIcon)}
|
closeIcon={renderCloseIcon(prefixCls, closeIcon)}
|
||||||
@ -215,7 +213,6 @@ const Modal: React.FC<ModalProps> = props => {
|
|||||||
Modal.defaultProps = {
|
Modal.defaultProps = {
|
||||||
width: 520,
|
width: 520,
|
||||||
confirmLoading: false,
|
confirmLoading: false,
|
||||||
open: false,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Modal;
|
export default Modal;
|
||||||
|
@ -96,11 +96,13 @@ describe('Modal', () => {
|
|||||||
resetWarned();
|
resetWarned();
|
||||||
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
|
|
||||||
render(<Modal {...({ visible: true } as any)} />);
|
render(<Modal visible />);
|
||||||
expect(errSpy).toHaveBeenCalledWith(
|
expect(errSpy).toHaveBeenCalledWith(
|
||||||
'Warning: [antd: Modal] `visible` is removed in v5, please use `open` instead.',
|
'Warning: [antd: Modal] `visible` is deprecated, please use `open` instead.',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
expect(document.querySelector('.ant-modal')).toBeTruthy();
|
||||||
|
|
||||||
errSpy.mockRestore();
|
errSpy.mockRestore();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -168,27 +168,58 @@ describe('Slider', () => {
|
|||||||
|
|
||||||
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
|
|
||||||
const { rerender } = render(<TSSlider tooltipPrefixCls="xxx" />);
|
const { container, rerender } = render(<TSSlider tooltipPrefixCls="xxx" />);
|
||||||
expect(errSpy).toHaveBeenCalledWith(
|
expect(errSpy).toHaveBeenCalledWith(
|
||||||
'Warning: [antd: Slider] `tooltipPrefixCls` is removed in v5, please use `tooltip.prefixCls` instead.',
|
'Warning: [antd: Slider] `tooltipPrefixCls` is deprecated, please use `tooltip.prefixCls` instead.',
|
||||||
);
|
);
|
||||||
|
|
||||||
rerender(<TSSlider getTooltipPopupContainer={() => document.body} />);
|
rerender(<TSSlider getTooltipPopupContainer={() => document.body} />);
|
||||||
expect(errSpy).toHaveBeenCalledWith(
|
expect(errSpy).toHaveBeenCalledWith(
|
||||||
'Warning: [antd: Slider] `getTooltipPopupContainer` is removed in v5, please use `tooltip.getPopupContainer` instead.',
|
'Warning: [antd: Slider] `getTooltipPopupContainer` is deprecated, please use `tooltip.getPopupContainer` instead.',
|
||||||
);
|
);
|
||||||
|
|
||||||
rerender(<TSSlider tipFormatter={(v: any) => v} />);
|
rerender(<TSSlider tipFormatter={(v: any) => v} />);
|
||||||
expect(errSpy).toHaveBeenCalledWith(
|
expect(errSpy).toHaveBeenCalledWith(
|
||||||
'Warning: [antd: Slider] `tipFormatter` is removed in v5, please use `tooltip.formatter` instead.',
|
'Warning: [antd: Slider] `tipFormatter` is deprecated, please use `tooltip.formatter` instead.',
|
||||||
);
|
);
|
||||||
|
|
||||||
rerender(<TSSlider tooltipVisible />);
|
rerender(<TSSlider tooltipVisible />);
|
||||||
expect(errSpy).toHaveBeenCalledWith(
|
expect(errSpy).toHaveBeenCalledWith(
|
||||||
'Warning: [antd: Slider] `tooltipVisible` is removed in v5, please use `tooltip.open` instead.',
|
'Warning: [antd: Slider] `tooltipVisible` is deprecated, please use `tooltip.open` instead.',
|
||||||
);
|
);
|
||||||
|
|
||||||
rerender(<TSSlider tooltipPlacement="left" />);
|
rerender(<TSSlider tooltipPlacement="left" />);
|
||||||
expect(errSpy).toHaveBeenCalledWith(
|
expect(errSpy).toHaveBeenCalledWith(
|
||||||
'Warning: [antd: Slider] `tooltipPlacement` is removed in v5, please use `tooltip.placement` instead.',
|
'Warning: [antd: Slider] `tooltipPlacement` is deprecated, please use `tooltip.placement` instead.',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// All should work
|
||||||
|
const holder = document.createElement('div');
|
||||||
|
holder.id = 'holder';
|
||||||
|
document.body.appendChild(holder);
|
||||||
|
|
||||||
|
const getTooltipPopupContainer = jest.fn(() => container);
|
||||||
|
|
||||||
|
rerender(
|
||||||
|
<TSSlider
|
||||||
|
tooltipPrefixCls="bamboo"
|
||||||
|
getTooltipPopupContainer={getTooltipPopupContainer}
|
||||||
|
tipFormatter={() => 'little'}
|
||||||
|
tooltipPlacement="bottom"
|
||||||
|
tooltipVisible
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(getTooltipPopupContainer).toHaveBeenCalled();
|
||||||
|
expect(container.querySelector('.bamboo')).toBeTruthy();
|
||||||
|
expect(container.querySelector('.bamboo-inner')!.textContent).toEqual('little');
|
||||||
|
|
||||||
|
holder.parentNode?.removeChild(holder);
|
||||||
|
|
||||||
errSpy.mockRestore();
|
errSpy.mockRestore();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -23,12 +23,15 @@ export type HandleGeneratorFn = (config: {
|
|||||||
info: HandleGeneratorInfo;
|
info: HandleGeneratorInfo;
|
||||||
}) => React.ReactElement;
|
}) => React.ReactElement;
|
||||||
|
|
||||||
|
export type Formatter = (value?: number) => React.ReactNode;
|
||||||
|
const defaultFormatter: Formatter = val => (typeof val === 'number' ? val.toString() : '');
|
||||||
|
|
||||||
export interface SliderTooltipProps {
|
export interface SliderTooltipProps {
|
||||||
prefixCls?: string;
|
prefixCls?: string;
|
||||||
open?: boolean;
|
open?: boolean;
|
||||||
placement?: TooltipPlacement;
|
placement?: TooltipPlacement;
|
||||||
getPopupContainer?: (triggerNode: HTMLElement) => HTMLElement;
|
getPopupContainer?: (triggerNode: HTMLElement) => HTMLElement;
|
||||||
formatter?: null | ((value?: number) => React.ReactNode);
|
formatter?: null | Formatter;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SliderBaseProps {
|
export interface SliderBaseProps {
|
||||||
@ -47,6 +50,21 @@ export interface SliderBaseProps {
|
|||||||
style?: React.CSSProperties;
|
style?: React.CSSProperties;
|
||||||
tooltip?: SliderTooltipProps;
|
tooltip?: SliderTooltipProps;
|
||||||
autoFocus?: boolean;
|
autoFocus?: boolean;
|
||||||
|
|
||||||
|
// Deprecated
|
||||||
|
/** @deprecated `tooltipPrefixCls` is deprecated. Please use `tooltip.prefixCls` instead. */
|
||||||
|
tooltipPrefixCls?: string;
|
||||||
|
/** @deprecated `tipFormatter` is deprecated. Please use `tooltip.formatter` instead. */
|
||||||
|
tipFormatter?: null | ((value?: number) => React.ReactNode);
|
||||||
|
/** @deprecated `tooltipVisible` is deprecated. Please use `tooltip.open` instead. */
|
||||||
|
tooltipVisible?: boolean;
|
||||||
|
/**
|
||||||
|
* @deprecated `getTooltipPopupContainer` is deprecated. Please use `tooltip.getPopupContainer`
|
||||||
|
* instead.
|
||||||
|
*/
|
||||||
|
getTooltipPopupContainer?: (triggerNode: HTMLElement) => HTMLElement;
|
||||||
|
/** @deprecated `tooltipPlacement` is deprecated. Please use `tooltip.placement` instead. */
|
||||||
|
tooltipPlacement?: TooltipPlacement;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SliderSingleProps extends SliderBaseProps {
|
export interface SliderSingleProps extends SliderBaseProps {
|
||||||
@ -77,6 +95,21 @@ export type Opens = { [index: number]: boolean };
|
|||||||
|
|
||||||
const Slider = React.forwardRef<unknown, SliderSingleProps | SliderRangeProps>(
|
const Slider = React.forwardRef<unknown, SliderSingleProps | SliderRangeProps>(
|
||||||
(props, ref: any) => {
|
(props, ref: any) => {
|
||||||
|
const {
|
||||||
|
prefixCls: customizePrefixCls,
|
||||||
|
range,
|
||||||
|
className,
|
||||||
|
|
||||||
|
// Deprecated Props
|
||||||
|
tooltipPrefixCls: legacyTooltipPrefixCls,
|
||||||
|
tipFormatter: legacyTipFormatter,
|
||||||
|
tooltipVisible: legacyTooltipVisible,
|
||||||
|
getTooltipPopupContainer: legacyGetTooltipPopupContainer,
|
||||||
|
tooltipPlacement: legacyTooltipPlacement,
|
||||||
|
|
||||||
|
...restProps
|
||||||
|
} = props;
|
||||||
|
|
||||||
const { getPrefixCls, direction, getPopupContainer } = React.useContext(ConfigContext);
|
const { getPrefixCls, direction, getPopupContainer } = React.useContext(ConfigContext);
|
||||||
const [opens, setOpens] = React.useState<Opens>({});
|
const [opens, setOpens] = React.useState<Opens>({});
|
||||||
|
|
||||||
@ -84,9 +117,9 @@ const Slider = React.forwardRef<unknown, SliderSingleProps | SliderRangeProps>(
|
|||||||
setOpens((prev: Opens) => ({ ...prev, [index]: open }));
|
setOpens((prev: Opens) => ({ ...prev, [index]: open }));
|
||||||
};
|
};
|
||||||
|
|
||||||
const getTooltipPlacement = (tooltipPlacement?: TooltipPlacement, vertical?: boolean) => {
|
const getTooltipPlacement = (placement?: TooltipPlacement, vertical?: boolean) => {
|
||||||
if (tooltipPlacement) {
|
if (placement) {
|
||||||
return tooltipPlacement;
|
return placement;
|
||||||
}
|
}
|
||||||
if (!vertical) {
|
if (!vertical) {
|
||||||
return 'top';
|
return 'top';
|
||||||
@ -94,7 +127,6 @@ const Slider = React.forwardRef<unknown, SliderSingleProps | SliderRangeProps>(
|
|||||||
return direction === 'rtl' ? 'left' : 'right';
|
return direction === 'rtl' ? 'left' : 'right';
|
||||||
};
|
};
|
||||||
|
|
||||||
const { prefixCls: customizePrefixCls, range, className, ...restProps } = props;
|
|
||||||
const prefixCls = getPrefixCls('slider', customizePrefixCls);
|
const prefixCls = getPrefixCls('slider', customizePrefixCls);
|
||||||
|
|
||||||
const [wrapSSR, hashId] = useStyle(prefixCls);
|
const [wrapSSR, hashId] = useStyle(prefixCls);
|
||||||
@ -133,7 +165,7 @@ const Slider = React.forwardRef<unknown, SliderSingleProps | SliderRangeProps>(
|
|||||||
warning(
|
warning(
|
||||||
!(deprecatedName in props),
|
!(deprecatedName in props),
|
||||||
'Slider',
|
'Slider',
|
||||||
`\`${deprecatedName}\` is removed in v5, please use \`tooltip.${newName}\` instead.`,
|
`\`${deprecatedName}\` is deprecated, please use \`tooltip.${newName}\` instead.`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -145,9 +177,6 @@ const Slider = React.forwardRef<unknown, SliderSingleProps | SliderRangeProps>(
|
|||||||
const { tooltip = {}, vertical } = props;
|
const { tooltip = {}, vertical } = props;
|
||||||
|
|
||||||
const tooltipProps: SliderTooltipProps = {
|
const tooltipProps: SliderTooltipProps = {
|
||||||
formatter(value) {
|
|
||||||
return typeof value === 'number' ? value.toString() : '';
|
|
||||||
},
|
|
||||||
...tooltip,
|
...tooltip,
|
||||||
};
|
};
|
||||||
const {
|
const {
|
||||||
@ -158,8 +187,18 @@ const Slider = React.forwardRef<unknown, SliderSingleProps | SliderRangeProps>(
|
|||||||
formatter: tipFormatter,
|
formatter: tipFormatter,
|
||||||
} = tooltipProps;
|
} = tooltipProps;
|
||||||
|
|
||||||
const isTipFormatter = tipFormatter ? opens[index] || dragging : false;
|
let mergedTipFormatter = tipFormatter;
|
||||||
const open = tooltipOpen || (tooltipOpen === undefined && isTipFormatter);
|
if (tipFormatter || tipFormatter === null) {
|
||||||
|
mergedTipFormatter = tipFormatter;
|
||||||
|
} else if (legacyTipFormatter || legacyTipFormatter === null) {
|
||||||
|
mergedTipFormatter = legacyTipFormatter;
|
||||||
|
} else {
|
||||||
|
mergedTipFormatter = defaultFormatter;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isTipFormatter = mergedTipFormatter ? opens[index] || dragging : false;
|
||||||
|
const open =
|
||||||
|
tooltipOpen ?? legacyTooltipVisible ?? (tooltipOpen === undefined && isTipFormatter);
|
||||||
|
|
||||||
const passedProps = {
|
const passedProps = {
|
||||||
...node.props,
|
...node.props,
|
||||||
@ -167,18 +206,23 @@ const Slider = React.forwardRef<unknown, SliderSingleProps | SliderRangeProps>(
|
|||||||
onMouseLeave: () => toggleTooltipOpen(index, false),
|
onMouseLeave: () => toggleTooltipOpen(index, false),
|
||||||
};
|
};
|
||||||
|
|
||||||
const tooltipPrefixCls = getPrefixCls('tooltip', customizeTooltipPrefixCls);
|
const tooltipPrefixCls = getPrefixCls(
|
||||||
|
'tooltip',
|
||||||
|
customizeTooltipPrefixCls ?? legacyTooltipPrefixCls,
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SliderTooltip
|
<SliderTooltip
|
||||||
prefixCls={tooltipPrefixCls}
|
prefixCls={tooltipPrefixCls}
|
||||||
title={tipFormatter ? tipFormatter(info.value) : ''}
|
title={mergedTipFormatter ? mergedTipFormatter(info.value) : ''}
|
||||||
open={open}
|
open={open}
|
||||||
placement={getTooltipPlacement(tooltipPlacement, vertical)}
|
placement={getTooltipPlacement(tooltipPlacement ?? legacyTooltipPlacement, vertical)}
|
||||||
transitionName={`${rootPrefixCls}-zoom-down`}
|
transitionName={`${rootPrefixCls}-zoom-down`}
|
||||||
key={index}
|
key={index}
|
||||||
overlayClassName={`${prefixCls}-tooltip`}
|
overlayClassName={`${prefixCls}-tooltip`}
|
||||||
getPopupContainer={getTooltipPopupContainer || getPopupContainer}
|
getPopupContainer={
|
||||||
|
getTooltipPopupContainer || legacyGetTooltipPopupContainer || getPopupContainer
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{React.cloneElement(node, passedProps)}
|
{React.cloneElement(node, passedProps)}
|
||||||
</SliderTooltip>
|
</SliderTooltip>
|
||||||
|
@ -140,28 +140,13 @@ function InternalTable<RecordType extends object = any>(
|
|||||||
showSorterTooltip = true,
|
showSorterTooltip = true,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
warning(
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
!(typeof rowKey === 'function' && rowKey.length > 1),
|
|
||||||
'Table',
|
|
||||||
'`index` parameter of `rowKey` function is deprecated. There is no guarantee that it will work as expected.',
|
|
||||||
);
|
|
||||||
warning(
|
|
||||||
!('filterDropdownVisible' in props || 'onFilterDropdownVisibleChange' in props),
|
|
||||||
'Table',
|
|
||||||
'`filterDropdownVisible` and `onFilterDropdownVisibleChange` is deprecated, ' +
|
|
||||||
'please use `filterDropdownOpen` and `onFilterDropdownOpenChange` instead.',
|
|
||||||
);
|
|
||||||
|
|
||||||
[
|
|
||||||
['filterDropdownVisible', 'filterDropdownOpen'],
|
|
||||||
['onFilterDropdownVisibleChange', 'onFilterDropdownOpenChange'],
|
|
||||||
].forEach(([deprecatedName, newName]) => {
|
|
||||||
warning(
|
warning(
|
||||||
!(deprecatedName in props),
|
!(typeof rowKey === 'function' && rowKey.length > 1),
|
||||||
'Table',
|
'Table',
|
||||||
`\`${deprecatedName}\` is deprecated which will be removed in next major version.Please use \`${newName}\` instead. `,
|
'`index` parameter of `rowKey` function is deprecated. There is no guarantee that it will work as expected.',
|
||||||
);
|
);
|
||||||
});
|
}
|
||||||
|
|
||||||
const baseColumns = React.useMemo(
|
const baseColumns = React.useMemo(
|
||||||
() => columns || (convertChildrenToColumns(children) as ColumnsType<RecordType>),
|
() => columns || (convertChildrenToColumns(children) as ColumnsType<RecordType>),
|
||||||
@ -277,7 +262,8 @@ function InternalTable<RecordType extends object = any>(
|
|||||||
/**
|
/**
|
||||||
* Controlled state in `columns` is not a good idea that makes too many code (1000+ line?) to read
|
* Controlled state in `columns` is not a good idea that makes too many code (1000+ line?) to read
|
||||||
* state out and then put it back to title render. Move these code into `hooks` but still too
|
* state out and then put it back to title render. Move these code into `hooks` but still too
|
||||||
* complex. We should provides Table props like `sorter` & `filter` to handle control in next big version.
|
* complex. We should provides Table props like `sorter` & `filter` to handle control in next big
|
||||||
|
* version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// ============================ Sorter =============================
|
// ============================ Sorter =============================
|
||||||
|
@ -12,6 +12,7 @@ import Tooltip from '../../tooltip';
|
|||||||
import type { SelectProps } from '../../select';
|
import type { SelectProps } from '../../select';
|
||||||
import type { ColumnGroupType, ColumnType, TableProps } from '..';
|
import type { ColumnGroupType, ColumnType, TableProps } from '..';
|
||||||
import type { ColumnFilterItem, FilterDropdownProps, FilterValue } from '../interface';
|
import type { ColumnFilterItem, FilterDropdownProps, FilterValue } from '../interface';
|
||||||
|
import { resetWarned } from '../../_util/warning';
|
||||||
|
|
||||||
// https://github.com/Semantic-Org/Semantic-UI-React/blob/72c45080e4f20b531fda2e3e430e384083d6766b/test/specs/modules/Dropdown/Dropdown-test.js#L73
|
// https://github.com/Semantic-Org/Semantic-UI-React/blob/72c45080e4f20b531fda2e3e430e384083d6766b/test/specs/modules/Dropdown/Dropdown-test.js#L73
|
||||||
const nativeEvent = { nativeEvent: { stopImmediatePropagation: () => {} } };
|
const nativeEvent = { nativeEvent: { stopImmediatePropagation: () => {} } };
|
||||||
@ -281,6 +282,7 @@ describe('Table.filter', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test('filterDropdownOpen');
|
test('filterDropdownOpen');
|
||||||
|
test('filterDropdownVisible');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('if the filter is visible it should ignore the selectedKeys changes', () => {
|
it('if the filter is visible it should ignore the selectedKeys changes', () => {
|
||||||
@ -333,19 +335,31 @@ describe('Table.filter', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('fires change event when visible change', () => {
|
it('fires change event when visible change', () => {
|
||||||
|
resetWarned();
|
||||||
|
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
|
|
||||||
const onFilterDropdownOpenChange = jest.fn();
|
const onFilterDropdownOpenChange = jest.fn();
|
||||||
|
const onFilterDropdownVisibleChange = jest.fn();
|
||||||
const { container } = render(
|
const { container } = render(
|
||||||
createTable({
|
createTable({
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
...column,
|
...column,
|
||||||
onFilterDropdownOpenChange,
|
onFilterDropdownOpenChange,
|
||||||
|
onFilterDropdownVisibleChange,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
fireEvent.click(container.querySelector('.ant-dropdown-trigger')!);
|
fireEvent.click(container.querySelector('.ant-dropdown-trigger')!);
|
||||||
expect(onFilterDropdownOpenChange).toHaveBeenCalledWith(true);
|
expect(onFilterDropdownOpenChange).toHaveBeenCalledWith(true);
|
||||||
|
expect(onFilterDropdownVisibleChange).toHaveBeenCalledWith(true);
|
||||||
|
|
||||||
|
expect(errSpy).toHaveBeenCalledWith(
|
||||||
|
'Warning: [antd: Table] `onFilterDropdownVisibleChange` is deprecated. Please use `onFilterDropdownOpenChange` instead.',
|
||||||
|
);
|
||||||
|
|
||||||
|
errSpy.mockRestore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be controlled by filteredValue', () => {
|
it('can be controlled by filteredValue', () => {
|
||||||
|
@ -28,6 +28,7 @@ import type {
|
|||||||
} from '../../interface';
|
} from '../../interface';
|
||||||
import FilterSearch from './FilterSearch';
|
import FilterSearch from './FilterSearch';
|
||||||
import FilterDropdownMenuWrapper from './FilterWrapper';
|
import FilterDropdownMenuWrapper from './FilterWrapper';
|
||||||
|
import warning from '../../../_util/warning';
|
||||||
|
|
||||||
type FilterTreeDataNode = FieldDataNode<{ title: React.ReactNode; key: React.Key }>;
|
type FilterTreeDataNode = FieldDataNode<{ title: React.ReactNode; key: React.Key }>;
|
||||||
|
|
||||||
@ -141,6 +142,10 @@ function FilterDropdown<RecordType>(props: FilterDropdownProps<RecordType>) {
|
|||||||
onFilterDropdownOpenChange,
|
onFilterDropdownOpenChange,
|
||||||
filterResetToDefaultFilteredValue,
|
filterResetToDefaultFilteredValue,
|
||||||
defaultFilteredValue,
|
defaultFilteredValue,
|
||||||
|
|
||||||
|
// Deprecated
|
||||||
|
filterDropdownVisible,
|
||||||
|
onFilterDropdownVisibleChange,
|
||||||
} = column;
|
} = column;
|
||||||
const [visible, setVisible] = React.useState(false);
|
const [visible, setVisible] = React.useState(false);
|
||||||
|
|
||||||
@ -151,9 +156,27 @@ function FilterDropdown<RecordType>(props: FilterDropdownProps<RecordType>) {
|
|||||||
const triggerVisible = (newVisible: boolean) => {
|
const triggerVisible = (newVisible: boolean) => {
|
||||||
setVisible(newVisible);
|
setVisible(newVisible);
|
||||||
onFilterDropdownOpenChange?.(newVisible);
|
onFilterDropdownOpenChange?.(newVisible);
|
||||||
|
onFilterDropdownVisibleChange?.(newVisible);
|
||||||
};
|
};
|
||||||
|
|
||||||
const mergedVisible = typeof filterDropdownOpen === 'boolean' ? filterDropdownOpen : visible;
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
[
|
||||||
|
['filterDropdownVisible', 'filterDropdownOpen', filterDropdownVisible],
|
||||||
|
[
|
||||||
|
'onFilterDropdownVisibleChange',
|
||||||
|
'onFilterDropdownOpenChange',
|
||||||
|
onFilterDropdownVisibleChange,
|
||||||
|
],
|
||||||
|
].forEach(([deprecatedName, newName, prop]) => {
|
||||||
|
warning(
|
||||||
|
prop === undefined || prop === null,
|
||||||
|
'Table',
|
||||||
|
`\`${deprecatedName}\` is deprecated. Please use \`${newName}\` instead.`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const mergedVisible = filterDropdownOpen ?? filterDropdownVisible ?? visible;
|
||||||
|
|
||||||
// ===================== Select Keys =====================
|
// ===================== Select Keys =====================
|
||||||
const propFilteredKeys = filterState?.filteredKeys;
|
const propFilteredKeys = filterState?.filteredKeys;
|
||||||
|
@ -120,6 +120,12 @@ export interface ColumnType<RecordType> extends Omit<RcColumnType<RecordType>, '
|
|||||||
|
|
||||||
// Responsive
|
// Responsive
|
||||||
responsive?: Breakpoint[];
|
responsive?: Breakpoint[];
|
||||||
|
|
||||||
|
// Deprecated
|
||||||
|
/** @deprecated Please use `filterDropdownOpen` instead */
|
||||||
|
filterDropdownVisible?: boolean;
|
||||||
|
/** @deprecated Please use `onFilterDropdownOpenChange` instead */
|
||||||
|
onFilterDropdownVisibleChange?: (visible: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ColumnGroupType<RecordType> extends Omit<ColumnType<RecordType>, 'dataIndex'> {
|
export interface ColumnGroupType<RecordType> extends Omit<ColumnType<RecordType>, 'dataIndex'> {
|
||||||
|
@ -86,10 +86,11 @@ describe('Tag', () => {
|
|||||||
resetWarned();
|
resetWarned();
|
||||||
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
|
|
||||||
render(<Tag visible />);
|
const { container } = render(<Tag visible={false} />);
|
||||||
expect(errSpy).toHaveBeenCalledWith(
|
expect(errSpy).toHaveBeenCalledWith(
|
||||||
'Warning: [antd: Tag] `visible` is removed, please use `visible && <Tag />` instead.',
|
'Warning: [antd: Tag] `visible` is deprecated, please use `visible && <Tag />` instead.',
|
||||||
);
|
);
|
||||||
|
expect(container.querySelector('.ant-tag-hidden')).toBeTruthy();
|
||||||
|
|
||||||
errSpy.mockRestore();
|
errSpy.mockRestore();
|
||||||
});
|
});
|
||||||
|
@ -20,6 +20,8 @@ export interface TagProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|||||||
color?: LiteralUnion<PresetColorType | PresetStatusColorType, string>;
|
color?: LiteralUnion<PresetColorType | PresetStatusColorType, string>;
|
||||||
closable?: boolean;
|
closable?: boolean;
|
||||||
closeIcon?: React.ReactNode;
|
closeIcon?: React.ReactNode;
|
||||||
|
/** @deprecated `visible` will be removed in next major version. */
|
||||||
|
visible?: boolean;
|
||||||
onClose?: (e: React.MouseEvent<HTMLElement>) => void;
|
onClose?: (e: React.MouseEvent<HTMLElement>) => void;
|
||||||
style?: React.CSSProperties;
|
style?: React.CSSProperties;
|
||||||
icon?: React.ReactNode;
|
icon?: React.ReactNode;
|
||||||
@ -51,6 +53,21 @@ const InternalTag: React.ForwardRefRenderFunction<HTMLSpanElement, TagProps> = (
|
|||||||
const { getPrefixCls, direction } = React.useContext(ConfigContext);
|
const { getPrefixCls, direction } = React.useContext(ConfigContext);
|
||||||
const [visible, setVisible] = React.useState(true);
|
const [visible, setVisible] = React.useState(true);
|
||||||
|
|
||||||
|
// Warning for deprecated usage
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
warning(
|
||||||
|
!('visible' in props),
|
||||||
|
'Tag',
|
||||||
|
'`visible` is deprecated, please use `visible && <Tag />` instead.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if ('visible' in props) {
|
||||||
|
setVisible(props.visible!);
|
||||||
|
}
|
||||||
|
}, [props.visible]);
|
||||||
|
|
||||||
const isPresetColor = (): boolean => {
|
const isPresetColor = (): boolean => {
|
||||||
if (!color) {
|
if (!color) {
|
||||||
return false;
|
return false;
|
||||||
@ -103,12 +120,6 @@ const InternalTag: React.ForwardRefRenderFunction<HTMLSpanElement, TagProps> = (
|
|||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
warning(
|
|
||||||
!('visible' in props),
|
|
||||||
'Tag',
|
|
||||||
'`visible` is removed, please use `visible && <Tag />` instead.',
|
|
||||||
);
|
|
||||||
|
|
||||||
const isNeedWave =
|
const isNeedWave =
|
||||||
'onClick' in props || (children && (children as React.ReactElement<any>).type === 'a');
|
'onClick' in props || (children && (children as React.ReactElement<any>).type === 'a');
|
||||||
const iconNode = icon || null;
|
const iconNode = icon || null;
|
||||||
|
@ -4,13 +4,14 @@ import type { TooltipPlacement } from '..';
|
|||||||
import Tooltip from '..';
|
import Tooltip from '..';
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import rtlTest from '../../../tests/shared/rtlTest';
|
import rtlTest from '../../../tests/shared/rtlTest';
|
||||||
import { fireEvent, render, sleep, waitFor } from '../../../tests/utils';
|
import { fireEvent, render, sleep, waitFor, act } from '../../../tests/utils';
|
||||||
import Button from '../../button';
|
import Button from '../../button';
|
||||||
import DatePicker from '../../date-picker';
|
import DatePicker from '../../date-picker';
|
||||||
import Input from '../../input';
|
import Input from '../../input';
|
||||||
import Group from '../../input/Group';
|
import Group from '../../input/Group';
|
||||||
import Switch from '../../switch';
|
import Switch from '../../switch';
|
||||||
import Radio from '../../radio';
|
import Radio from '../../radio';
|
||||||
|
import { resetWarned } from '../../_util/warning';
|
||||||
|
|
||||||
describe('Tooltip', () => {
|
describe('Tooltip', () => {
|
||||||
mountTest(Tooltip);
|
mountTest(Tooltip);
|
||||||
@ -451,34 +452,61 @@ describe('Tooltip', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('deprecated warning', () => {
|
it('deprecated warning', () => {
|
||||||
|
resetWarned();
|
||||||
|
jest.useFakeTimers();
|
||||||
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
|
|
||||||
const { rerender } = render(
|
// defaultVisible
|
||||||
<Tooltip visible>
|
const { container, rerender } = render(
|
||||||
|
<Tooltip defaultVisible title="bamboo">
|
||||||
|
<a />
|
||||||
|
</Tooltip>,
|
||||||
|
);
|
||||||
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(errSpy).toHaveBeenCalledWith(
|
||||||
|
'Warning: [antd: Tooltip] `defaultVisible` is deprecated, please use `defaultOpen` instead.',
|
||||||
|
);
|
||||||
|
expect(document.querySelector('.ant-tooltip')).toBeTruthy();
|
||||||
|
|
||||||
|
// visible
|
||||||
|
rerender(
|
||||||
|
<Tooltip visible title="bamboo">
|
||||||
<a />
|
<a />
|
||||||
</Tooltip>,
|
</Tooltip>,
|
||||||
);
|
);
|
||||||
expect(errSpy).toHaveBeenCalledWith(
|
expect(errSpy).toHaveBeenCalledWith(
|
||||||
'Warning: [antd: Tooltip] `visible` is deprecated, please use `open` instead.',
|
'Warning: [antd: Tooltip] `visible` is deprecated, please use `open` instead.',
|
||||||
);
|
);
|
||||||
|
|
||||||
rerender(
|
rerender(
|
||||||
<Tooltip defaultVisible>
|
<Tooltip visible={false} title="bamboo">
|
||||||
<a />
|
<a />
|
||||||
</Tooltip>,
|
</Tooltip>,
|
||||||
);
|
);
|
||||||
expect(errSpy).toHaveBeenCalledWith(
|
act(() => {
|
||||||
'Warning: [antd: Tooltip] `defaultVisible` is deprecated, please use `defaultOpen` instead.',
|
jest.runAllTimers();
|
||||||
);
|
});
|
||||||
|
if (container.querySelector('.ant-zoom-big-fast-leave-active')) {
|
||||||
|
fireEvent.animationEnd(container.querySelector('.ant-zoom-big-fast-leave-active')!);
|
||||||
|
}
|
||||||
|
expect(document.querySelector('.ant-tooltip-hidden')).toBeTruthy();
|
||||||
|
|
||||||
|
// onVisibleChange
|
||||||
rerender(
|
rerender(
|
||||||
<Tooltip onVisibleChange={() => {}}>
|
<Tooltip onVisibleChange={() => {}} title="bamboo">
|
||||||
<a />
|
<a />
|
||||||
</Tooltip>,
|
</Tooltip>,
|
||||||
);
|
);
|
||||||
expect(errSpy).toHaveBeenCalledWith(
|
expect(errSpy).toHaveBeenCalledWith(
|
||||||
'Warning: [antd: Tooltip] `onVisibleChange` is deprecated, please use `onOpenChange` instead.',
|
'Warning: [antd: Tooltip] `onVisibleChange` is deprecated, please use `onOpenChange` instead.',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// afterVisibleChange
|
||||||
rerender(
|
rerender(
|
||||||
<Tooltip afterVisibleChange={() => {}}>
|
<Tooltip afterVisibleChange={() => {}} title="bamboo">
|
||||||
<a />
|
<a />
|
||||||
</Tooltip>,
|
</Tooltip>,
|
||||||
);
|
);
|
||||||
@ -486,6 +514,28 @@ describe('Tooltip', () => {
|
|||||||
'Warning: [antd: Tooltip] `afterVisibleChange` is deprecated, please use `afterOpenChange` instead.',
|
'Warning: [antd: Tooltip] `afterVisibleChange` is deprecated, please use `afterOpenChange` instead.',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Event Trigger
|
||||||
|
const onVisibleChange = jest.fn();
|
||||||
|
const afterVisibleChange = jest.fn();
|
||||||
|
rerender(
|
||||||
|
<Tooltip
|
||||||
|
visible
|
||||||
|
onVisibleChange={onVisibleChange}
|
||||||
|
afterVisibleChange={afterVisibleChange}
|
||||||
|
title="bamboo"
|
||||||
|
>
|
||||||
|
<a />
|
||||||
|
</Tooltip>,
|
||||||
|
);
|
||||||
|
|
||||||
|
fireEvent.mouseLeave(container.querySelector('a')!);
|
||||||
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
});
|
||||||
|
expect(onVisibleChange).toHaveBeenCalled();
|
||||||
|
expect(afterVisibleChange).toHaveBeenCalled();
|
||||||
|
|
||||||
|
jest.useRealTimers();
|
||||||
errSpy.mockRestore();
|
errSpy.mockRestore();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -51,30 +51,20 @@ interface LegacyTooltipProps
|
|||||||
'children' | 'visible' | 'defaultVisible' | 'onVisibleChange' | 'afterVisibleChange'
|
'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'];
|
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'];
|
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'];
|
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'];
|
afterOpenChange?: RcTooltipProps['afterVisibleChange'];
|
||||||
|
|
||||||
|
// Legacy
|
||||||
|
/** @deprecated Please use `open` instead. */
|
||||||
|
visible?: RcTooltipProps['visible'];
|
||||||
|
/** @deprecated Please use `defaultOpen` instead. */
|
||||||
|
defaultVisible?: RcTooltipProps['defaultVisible'];
|
||||||
|
/** @deprecated Please use `onOpenChange` instead. */
|
||||||
|
onVisibleChange?: RcTooltipProps['onVisibleChange'];
|
||||||
|
/** @deprecated Please use `afterOpenChange` instead. */
|
||||||
|
afterVisibleChange?: RcTooltipProps['afterVisibleChange'];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AbstractTooltipProps extends LegacyTooltipProps {
|
export interface AbstractTooltipProps extends LegacyTooltipProps {
|
||||||
@ -166,28 +156,42 @@ function getDisabledCompatibleChildren(element: React.ReactElement<any>, prefixC
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Tooltip = React.forwardRef<unknown, TooltipProps>((props, ref) => {
|
const Tooltip = React.forwardRef<unknown, TooltipProps>((props, ref) => {
|
||||||
|
const {
|
||||||
|
prefixCls: customizePrefixCls,
|
||||||
|
openClassName,
|
||||||
|
getTooltipContainer,
|
||||||
|
overlayClassName,
|
||||||
|
color,
|
||||||
|
overlayInnerStyle,
|
||||||
|
children,
|
||||||
|
afterOpenChange,
|
||||||
|
afterVisibleChange,
|
||||||
|
} = props;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
getPopupContainer: getContextPopupContainer,
|
getPopupContainer: getContextPopupContainer,
|
||||||
getPrefixCls,
|
getPrefixCls,
|
||||||
direction,
|
direction,
|
||||||
} = React.useContext(ConfigContext);
|
} = React.useContext(ConfigContext);
|
||||||
|
|
||||||
[
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
['visible', 'open'],
|
[
|
||||||
['defaultVisible', 'defaultOpen'],
|
['visible', 'open'],
|
||||||
['onVisibleChange', 'onOpenChange'],
|
['defaultVisible', 'defaultOpen'],
|
||||||
['afterVisibleChange', 'afterOpenChange'],
|
['onVisibleChange', 'onOpenChange'],
|
||||||
].forEach(([deprecatedName, newName]) => {
|
['afterVisibleChange', 'afterOpenChange'],
|
||||||
warning(
|
].forEach(([deprecatedName, newName]) => {
|
||||||
!(deprecatedName in props),
|
warning(
|
||||||
'Tooltip',
|
!(deprecatedName in props),
|
||||||
`\`${deprecatedName}\` is deprecated, please use \`${newName}\` instead.`,
|
'Tooltip',
|
||||||
);
|
`\`${deprecatedName}\` is deprecated, please use \`${newName}\` instead.`,
|
||||||
});
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const [open, setOpen] = useMergedState(false, {
|
const [open, setOpen] = useMergedState(false, {
|
||||||
value: props.open,
|
value: props.open ?? props.visible,
|
||||||
defaultValue: props.defaultOpen,
|
defaultValue: props.defaultOpen ?? props.defaultVisible,
|
||||||
});
|
});
|
||||||
|
|
||||||
const isNoTitle = () => {
|
const isNoTitle = () => {
|
||||||
@ -256,15 +260,6 @@ const Tooltip = React.forwardRef<unknown, TooltipProps>((props, ref) => {
|
|||||||
|
|
||||||
const { getPopupContainer, overlayStyle, ...otherProps } = props;
|
const { getPopupContainer, overlayStyle, ...otherProps } = props;
|
||||||
|
|
||||||
const {
|
|
||||||
prefixCls: customizePrefixCls,
|
|
||||||
openClassName,
|
|
||||||
getTooltipContainer,
|
|
||||||
overlayClassName,
|
|
||||||
color,
|
|
||||||
overlayInnerStyle,
|
|
||||||
children,
|
|
||||||
} = props;
|
|
||||||
const prefixCls = getPrefixCls('tooltip', customizePrefixCls);
|
const prefixCls = getPrefixCls('tooltip', customizePrefixCls);
|
||||||
const rootPrefixCls = getPrefixCls();
|
const rootPrefixCls = getPrefixCls();
|
||||||
|
|
||||||
@ -272,7 +267,7 @@ const Tooltip = React.forwardRef<unknown, TooltipProps>((props, ref) => {
|
|||||||
|
|
||||||
let tempOpen = open;
|
let tempOpen = open;
|
||||||
// Hide tooltip when there is no title
|
// Hide tooltip when there is no title
|
||||||
if (!('open' in props) && isNoTitle()) {
|
if (!('open' in props) && !('visible' in props) && isNoTitle()) {
|
||||||
tempOpen = false;
|
tempOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,6 +315,7 @@ const Tooltip = React.forwardRef<unknown, TooltipProps>((props, ref) => {
|
|||||||
overlay={getOverlay()}
|
overlay={getOverlay()}
|
||||||
visible={tempOpen}
|
visible={tempOpen}
|
||||||
onVisibleChange={onOpenChange}
|
onVisibleChange={onOpenChange}
|
||||||
|
afterVisibleChange={afterOpenChange ?? afterVisibleChange}
|
||||||
onPopupAlign={onPopupAlign}
|
onPopupAlign={onPopupAlign}
|
||||||
overlayInnerStyle={formattedOverlayInnerStyle}
|
overlayInnerStyle={formattedOverlayInnerStyle}
|
||||||
arrowContent={<span className={`${prefixCls}-arrow-content`} />}
|
arrowContent={<span className={`${prefixCls}-arrow-content`} />}
|
||||||
|
@ -106,7 +106,7 @@
|
|||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ant-design/colors": "^6.0.0",
|
"@ant-design/colors": "^6.0.0",
|
||||||
"@ant-design/cssinjs": "^0.0.0-alpha.40",
|
"@ant-design/cssinjs": "^0.0.0-alpha.44",
|
||||||
"@ant-design/icons": "^4.7.0",
|
"@ant-design/icons": "^4.7.0",
|
||||||
"@ant-design/react-slick": "~0.29.1",
|
"@ant-design/react-slick": "~0.29.1",
|
||||||
"@babel/runtime": "^7.18.3",
|
"@babel/runtime": "^7.18.3",
|
||||||
|
Loading…
Reference in New Issue
Block a user