Browse Source

refactor(popover): rewrite with hook (#23535)

* refactor(popover): rewrite with hook

* Update index.tsx
pull/23648/head
Tom Xu 5 years ago
committed by GitHub
parent
commit
c2dc6305f3
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 19
      components/popover/__tests__/index.test.js
  2. 53
      components/popover/index.tsx

19
components/popover/__tests__/index.test.js

@ -9,18 +9,20 @@ describe('Popover', () => {
mountTest(Popover); mountTest(Popover);
it('should show overlay when trigger is clicked', async () => { it('should show overlay when trigger is clicked', async () => {
const ref = React.createRef();
const popover = mount( const popover = mount(
<Popover content="console.log('hello world')" title="code" trigger="click"> <Popover ref={ref} content="console.log('hello world')" title="code" trigger="click">
<span>show me your code</span> <span>show me your code</span>
</Popover>, </Popover>,
); );
expect(popover.instance().getPopupDomNode()).toBe(null); expect(ref.current.getPopupDomNode()).toBe(null);
popover.find('span').simulate('click'); popover.find('span').simulate('click');
await sleep(100); await sleep(100);
const popup = popover.instance().getPopupDomNode(); const popup = ref.current.getPopupDomNode();
expect(popup).not.toBe(null); expect(popup).not.toBe(null);
expect(popup.className).toContain('ant-popover-placement-top'); expect(popup.className).toContain('ant-popover-placement-top');
expect(popup.innerHTML).toMatchSnapshot(); expect(popup.innerHTML).toMatchSnapshot();
@ -29,16 +31,17 @@ describe('Popover', () => {
it('shows content for render functions', () => { it('shows content for render functions', () => {
const renderTitle = () => 'some-title'; const renderTitle = () => 'some-title';
const renderContent = () => 'some-content'; const renderContent = () => 'some-content';
const ref = React.createRef();
const popover = mount( const popover = mount(
<Popover content={renderContent} title={renderTitle} trigger="click"> <Popover ref={ref} content={renderContent} title={renderTitle} trigger="click">
<span>show me your code</span> <span>show me your code</span>
</Popover>, </Popover>,
); );
popover.find('span').simulate('click'); popover.find('span').simulate('click');
const popup = popover.instance().getPopupDomNode(); const popup = ref.current.getPopupDomNode();
expect(popup).not.toBe(null); expect(popup).not.toBe(null);
expect(popup.innerHTML).toContain('some-title'); expect(popup.innerHTML).toContain('some-title');
expect(popup.innerHTML).toContain('some-content'); expect(popup.innerHTML).toContain('some-content');
@ -46,15 +49,17 @@ describe('Popover', () => {
}); });
it('handles empty title/content props safely', () => { it('handles empty title/content props safely', () => {
const ref = React.createRef();
const popover = mount( const popover = mount(
<Popover trigger="click"> <Popover trigger="click" ref={ref}>
<span>show me your code</span> <span>show me your code</span>
</Popover>, </Popover>,
); );
popover.find('span').simulate('click'); popover.find('span').simulate('click');
const popup = popover.instance().getPopupDomNode(); const popup = ref.current.getPopupDomNode();
expect(popup).not.toBe(null); expect(popup).not.toBe(null);
expect(popup.innerHTML).toMatchSnapshot(); expect(popup.innerHTML).toMatchSnapshot();
}); });

53
components/popover/index.tsx

@ -1,6 +1,6 @@
import * as React from 'react'; import * as React from 'react';
import Tooltip, { AbstractTooltipProps, TooltipPlacement } from '../tooltip'; import Tooltip, { AbstractTooltipProps, TooltipPlacement } from '../tooltip';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; import { ConfigContext } from '../config-provider';
import { getRenderPropValue, RenderFunction } from '../_util/getRenderPropValue'; import { getRenderPropValue, RenderFunction } from '../_util/getRenderPropValue';
export interface PopoverProps extends AbstractTooltipProps { export interface PopoverProps extends AbstractTooltipProps {
@ -8,51 +8,40 @@ export interface PopoverProps extends AbstractTooltipProps {
content?: React.ReactNode | RenderFunction; content?: React.ReactNode | RenderFunction;
} }
export default class Popover extends React.Component<PopoverProps, {}> { const Popover = React.forwardRef<unknown, PopoverProps>(
static defaultProps = { ({ prefixCls: customizePrefixCls, title, content, ...otherProps }, ref) => {
placement: 'top' as TooltipPlacement, const { getPrefixCls } = React.useContext(ConfigContext);
transitionName: 'zoom-big',
trigger: 'hover',
mouseEnterDelay: 0.1,
mouseLeaveDelay: 0.1,
overlayStyle: {},
};
private tooltip: Tooltip;
getPopupDomNode() {
return this.tooltip.getPopupDomNode();
}
getOverlay(prefixCls: string) { const getOverlay = (prefixCls: string) => {
const { title, content } = this.props;
return ( return (
<> <>
{title && <div className={`${prefixCls}-title`}>{getRenderPropValue(title)}</div>} {title && <div className={`${prefixCls}-title`}>{getRenderPropValue(title)}</div>}
<div className={`${prefixCls}-inner-content`}>{getRenderPropValue(content)}</div> <div className={`${prefixCls}-inner-content`}>{getRenderPropValue(content)}</div>
</> </>
); );
}
saveTooltip = (node: any) => {
this.tooltip = node;
}; };
renderPopover = ({ getPrefixCls }: ConfigConsumerProps) => {
const { prefixCls: customizePrefixCls, ...props } = this.props;
delete props.title;
const prefixCls = getPrefixCls('popover', customizePrefixCls); const prefixCls = getPrefixCls('popover', customizePrefixCls);
return ( return (
<Tooltip <Tooltip
{...props} {...otherProps}
prefixCls={prefixCls} prefixCls={prefixCls}
ref={this.saveTooltip} ref={ref as any}
overlay={this.getOverlay(prefixCls)} overlay={getOverlay(prefixCls)}
/> />
); );
},
);
Popover.displayName = 'Popover';
Popover.defaultProps = {
placement: 'top' as TooltipPlacement,
transitionName: 'zoom-big',
trigger: 'hover',
mouseEnterDelay: 0.1,
mouseLeaveDelay: 0.1,
overlayStyle: {},
}; };
render() { export default Popover;
return <ConfigConsumer>{this.renderPopover}</ConfigConsumer>;
}
}

Loading…
Cancel
Save