Skip to content

Commit

Permalink
fix: Tooltip should work with disabled button (#4865)
Browse files Browse the repository at this point in the history
* Fix Tooltip won't hide at disabled button

close react-component/tooltip#18

* change button text in test case

* Add comments for display attribute

* correct test case
  • Loading branch information
afc163 authored and benjycui committed Feb 16, 2017
1 parent af62254 commit f5d6979
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 2 deletions.
10 changes: 9 additions & 1 deletion components/button/__tests__/index.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { render } from 'enzyme';
import { render, mount } from 'enzyme';
import { renderToJson } from 'enzyme-to-json';
import Button from '..';

Expand All @@ -17,4 +17,12 @@ describe('Button', () => {
);
expect(renderToJson(wrapper)).toMatchSnapshot();
});

it('have static perperty for type detecting', () => {
const wrapper = mount(
<Button>Button Text</Button>
);
// eslint-disable-next-line
expect(wrapper.type().__ANT_BUTTON).toBe(true);
});
});
1 change: 1 addition & 0 deletions components/button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export interface ButtonProps {

export default class Button extends React.Component<ButtonProps, any> {
static Group: any;
static __ANT_BUTTON = true;

static defaultProps = {
prefixCls: 'ant-btn',
Expand Down
64 changes: 64 additions & 0 deletions components/tooltip/__tests__/tooltip.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import { mount } from 'enzyme';
import Tooltip from '..';
import Button from '../../button';

describe('Tooltip', () => {
it('check `onVisibleChange` arguments', () => {
Expand Down Expand Up @@ -49,4 +50,67 @@ describe('Tooltip', () => {
expect(onVisibleChange.mock.calls.length).toBe(lastCount); // no change with lastCount
expect(wrapper.ref('tooltip').prop('visible')).toBe(false);
});

it('should hide when mouse leave native disabled button', () => {
const onVisibleChange = jest.fn();
const wrapper = mount(
<Tooltip
title="xxxxx"
mouseEnterDelay={0}
mouseLeaveDelay={0}
onVisibleChange={onVisibleChange}
>
<button disabled>Hello world!</button>
</Tooltip>
);

expect(wrapper.find('span')).toHaveLength(1);
const button = wrapper.find('span').at(0);
button.simulate('mouseenter');
expect(onVisibleChange).toBeCalledWith(true);
expect(wrapper.ref('tooltip').prop('visible')).toBe(true);

button.simulate('mouseleave');
expect(onVisibleChange).toBeCalledWith(false);
expect(wrapper.ref('tooltip').prop('visible')).toBe(false);
});

it('should hide when mouse leave antd disabled Button', () => {
const onVisibleChange = jest.fn();
const wrapper = mount(
<Tooltip
title="xxxxx"
mouseEnterDelay={0}
mouseLeaveDelay={0}
onVisibleChange={onVisibleChange}
>
<Button disabled>Hello world!</Button>
</Tooltip>
);

expect(wrapper.getDOMNode().tagName).toBe('SPAN');
const button = wrapper.find('span').at(0);
button.simulate('mouseenter');
expect(onVisibleChange).toBeCalledWith(true);
expect(wrapper.ref('tooltip').prop('visible')).toBe(true);

button.simulate('mouseleave');
expect(onVisibleChange).toBeCalledWith(false);
expect(wrapper.ref('tooltip').prop('visible')).toBe(false);
});

it('should render disabled Button style properly', () => {
const wrapper1 = mount(
<Tooltip title="xxxxx">
<Button disabled>Hello world!</Button>
</Tooltip>
);
const wrapper2 = mount(
<Tooltip title="xxxxx">
<Button disabled style={{ display: 'block' }}>Hello world!</Button>
</Tooltip>
);
expect(wrapper1.getDOMNode().style.display).toBe('inline-block');
expect(wrapper2.getDOMNode().style.display).toBe('block');
});
});
30 changes: 29 additions & 1 deletion components/tooltip/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,32 @@ export default class Tooltip extends React.Component<TooltipProps, any> {
});
}

// Fix Tooltip won't hide at disabled button
// mouse events don't trigger at disabled button in Chrome
// https://github.com/react-component/tooltip/issues/18
getDisabledCompatibleChildren(element) {
if ((element.type.__ANT_BUTTON || element.type === 'button') && element.props.disabled) {
// reserve display style for <Button style={{ display: 'block '}}></Button>
// Note:
// If people override ant-btn's style.display by css,
// it will be affected cause we reset it to 'inline-block'
const displayStyle = (element.props.style && element.props.style.display)
? element.props.style.display : 'inline-block';
const child = cloneElement(element, {
style: {
...element.props.style,
pointerEvents: 'none',
},
});
return (
<span style={{ display: displayStyle, cursor: 'not-allowed' }}>
{child}
</span>
);
}
return element;
}

isNoTitle() {
const { title, overlay } = this.props;
return !title && !overlay; // overlay for old version compatibility
Expand Down Expand Up @@ -132,7 +158,9 @@ export default class Tooltip extends React.Component<TooltipProps, any> {
visible = false;
}

const child = React.isValidElement(children) ? children : <span>{children}</span>;
const child = this.getDisabledCompatibleChildren(
React.isValidElement(children) ? children : <span>{children}</span>
);
const childProps = child.props;
const childCls = classNames(childProps.className, {
[openClassName || `${prefixCls}-open`]: true,
Expand Down

0 comments on commit f5d6979

Please sign in to comment.