refactor(slider): rewrite with hook (#23474)

* refactor(slider): rewrite with hook

* improve test

* Revert "improve test"

This reverts commit 48cd83d0ccc1089cee06f5e4959b434857bb116a.

* improve test

* improve test 2
This commit is contained in:
Tom Xu 2020-04-22 15:58:57 +08:00 committed by GitHub
parent c550cb050b
commit b7e877aeef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 55 additions and 113 deletions

View File

@ -8,7 +8,7 @@ import focusTest from '../../../tests/shared/focusTest';
describe('DatePicker', () => {
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
focusTest(DatePicker, true);
focusTest(DatePicker, { refFocus: true });
beforeEach(() => {
MockDate.set(moment('2016-11-22'));

View File

@ -9,7 +9,7 @@ import focusTest from '../../../tests/shared/focusTest';
const { RangePicker } = DatePicker;
describe('RangePicker', () => {
focusTest(RangePicker, true);
focusTest(RangePicker, { refFocus: true });
beforeEach(() => {
setMockDate();

View File

@ -15,7 +15,7 @@ describe('WeekPicker', () => {
resetMockDate();
});
focusTest(WeekPicker, true);
focusTest(WeekPicker, { refFocus: true });
it('should support style prop', () => {
const wrapper = mount(<WeekPicker style={{ width: 400 }} />);

View File

@ -6,7 +6,7 @@ import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
describe('InputNumber', () => {
focusTest(InputNumber, true);
focusTest(InputNumber, { refFocus: true });
mountTest(InputNumber);
rtlTest(InputNumber);

View File

@ -10,64 +10,23 @@ import { sleep } from '../../../tests/utils';
describe('Slider', () => {
mountTest(Slider);
rtlTest(Slider);
focusTest(Slider);
focusTest(Slider, { refFocus: true });
it('should show tooltip when hovering slider handler', () => {
const wrapper = mount(<Slider defaultValue={30} />);
wrapper
.find('.ant-slider-handle')
.at(0)
.simulate('mouseEnter');
expect(
render(
wrapper
.find('Trigger')
.instance()
.getComponent(),
),
).toMatchSnapshot();
wrapper
.find('.ant-slider-handle')
.at(0)
.simulate('mouseLeave');
expect(
render(
wrapper
.find('Trigger')
.instance()
.getComponent(),
),
).toMatchSnapshot();
wrapper.find('.ant-slider-handle').at(0).simulate('mouseEnter');
expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot();
wrapper.find('.ant-slider-handle').at(0).simulate('mouseLeave');
expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot();
});
it('when tooltipVisible is true, tooltip should show always, or should never show', () => {
let wrapper = mount(<Slider defaultValue={30} tooltipVisible />);
expect(
wrapper
.find('.ant-tooltip-content')
.at(0)
.hasClass('ant-tooltip-hidden'),
).toBe(false);
wrapper
.find('.ant-slider-handle')
.at(0)
.simulate('mouseEnter');
expect(
wrapper
.find('.ant-tooltip-content')
.at(0)
.hasClass('ant-tooltip-hidden'),
).toBe(false);
wrapper
.find('.ant-slider-handle')
.at(0)
.simulate('click');
expect(
wrapper
.find('.ant-tooltip-content')
.at(0)
.hasClass('ant-tooltip-hidden'),
).toBe(false);
expect(wrapper.find('.ant-tooltip-content').at(0).hasClass('ant-tooltip-hidden')).toBe(false);
wrapper.find('.ant-slider-handle').at(0).simulate('mouseEnter');
expect(wrapper.find('.ant-tooltip-content').at(0).hasClass('ant-tooltip-hidden')).toBe(false);
wrapper.find('.ant-slider-handle').at(0).simulate('click');
expect(wrapper.find('.ant-tooltip-content').at(0).hasClass('ant-tooltip-hidden')).toBe(false);
wrapper = mount(<Slider defaultValue={30} tooltipVisible={false} />);
expect(wrapper.find('.ant-tooltip-content').length).toBe(0);
});

View File

@ -57,36 +57,18 @@ export interface SliderProps {
getTooltipPopupContainer?: (triggerNode: HTMLElement) => HTMLElement;
}
export interface SliderState {
visibles: { [index: number]: boolean };
}
export type Visibles = { [index: number]: boolean };
export default class Slider extends React.Component<SliderProps, SliderState> {
static defaultProps = {
tipFormatter(value: number) {
return typeof value === 'number' ? value.toString() : '';
},
const Slider = React.forwardRef<unknown, SliderProps>((props, ref) => {
const [visibles, setVisibles] = React.useState<Visibles>({});
const toggleTooltipVisible = (index: number, visible: boolean) => {
const temp = { ...visibles };
temp[index] = visible;
setVisibles(temp);
};
rcSlider: any;
constructor(props: SliderProps) {
super(props);
this.state = {
visibles: {},
};
}
toggleTooltipVisible = (index: number, visible: boolean) => {
this.setState(({ visibles }) => ({
visibles: {
...visibles,
[index]: visible,
},
}));
};
handleWithTooltip: HandleGeneratorFn = ({
const handleWithTooltip: HandleGeneratorFn = ({
tooltipPrefixCls,
prefixCls,
info: { value, dragging, index, ...restProps },
@ -97,8 +79,7 @@ export default class Slider extends React.Component<SliderProps, SliderState> {
tooltipPlacement,
getTooltipPopupContainer,
vertical,
} = this.props;
const { visibles } = this.state;
} = props;
const isTipFormatter = tipFormatter ? visibles[index] || dragging : false;
const visible = tooltipVisible || (tooltipVisible === undefined && isTipFormatter);
return (
@ -115,33 +96,21 @@ export default class Slider extends React.Component<SliderProps, SliderState> {
<RcHandle
{...restProps}
value={value}
onMouseEnter={() => this.toggleTooltipVisible(index, true)}
onMouseLeave={() => this.toggleTooltipVisible(index, false)}
onMouseEnter={() => toggleTooltipVisible(index, true)}
onMouseLeave={() => toggleTooltipVisible(index, false)}
/>
</SliderTooltip>
);
};
saveSlider = (node: any) => {
this.rcSlider = node;
};
focus() {
this.rcSlider.focus();
}
blur() {
this.rcSlider.blur();
}
renderSlider = ({ getPrefixCls, direction }: ConfigConsumerProps) => {
const renderSlider = ({ getPrefixCls, direction }: ConfigConsumerProps) => {
const {
prefixCls: customizePrefixCls,
tooltipPrefixCls: customizeTooltipPrefixCls,
range,
className,
...restProps
} = this.props;
} = props;
const prefixCls = getPrefixCls('slider', customizePrefixCls);
const tooltipPrefixCls = getPrefixCls('tooltip', customizeTooltipPrefixCls);
const cls = classNames(className, {
@ -156,9 +125,9 @@ export default class Slider extends React.Component<SliderProps, SliderState> {
<RcRange
{...restProps}
className={cls}
ref={this.saveSlider}
ref={ref}
handle={(info: HandleGeneratorInfo) =>
this.handleWithTooltip({
handleWithTooltip({
tooltipPrefixCls,
prefixCls,
info,
@ -173,9 +142,9 @@ export default class Slider extends React.Component<SliderProps, SliderState> {
<RcSlider
{...restProps}
className={cls}
ref={this.saveSlider}
ref={ref}
handle={(info: HandleGeneratorInfo) =>
this.handleWithTooltip({
handleWithTooltip({
tooltipPrefixCls,
prefixCls,
info,
@ -187,7 +156,13 @@ export default class Slider extends React.Component<SliderProps, SliderState> {
);
};
render() {
return <ConfigConsumer>{this.renderSlider}</ConfigConsumer>;
}
}
return <ConfigConsumer>{renderSlider}</ConfigConsumer>;
});
Slider.defaultProps = {
tipFormatter(value: number) {
return typeof value === 'number' ? value.toString() : '';
},
};
export default Slider;

View File

@ -18,7 +18,7 @@ describe('TimePicker', () => {
errorSpy.mockRestore();
});
focusTest(TimePicker, true);
focusTest(TimePicker, { refFocus: true });
mountTest(TimePicker);
rtlTest(TimePicker);

View File

@ -3,7 +3,7 @@ import { mount } from 'enzyme';
import { sleep } from '../utils';
// eslint-disable-next-line jest/no-export
export default function focusTest(Component, refFocus = false) {
export default function focusTest(Component, { refFocus = false } = {}) {
describe('focus and blur', () => {
let focused = false;
let blurred = false;
@ -38,6 +38,14 @@ export default function focusTest(Component, refFocus = false) {
document.body.removeChild(container);
});
const getElement = wrapper => {
let ele = wrapper.find('input').first();
if (ele.length === 0) {
ele = wrapper.find('div[tabIndex]').first();
}
return ele;
};
if (refFocus) {
it('Ref: focus() and onFocus', () => {
const onFocus = jest.fn();
@ -50,7 +58,7 @@ export default function focusTest(Component, refFocus = false) {
ref.current.focus();
expect(focused).toBeTruthy();
wrapper.find('input').first().simulate('focus');
getElement(wrapper).simulate('focus');
expect(onFocus).toHaveBeenCalled();
});
@ -65,7 +73,7 @@ export default function focusTest(Component, refFocus = false) {
ref.current.blur();
expect(blurred).toBeTruthy();
wrapper.find('input').first().simulate('blur');
getElement(wrapper).simulate('blur');
expect(onBlur).toHaveBeenCalled();
});
@ -75,7 +83,7 @@ export default function focusTest(Component, refFocus = false) {
expect(focused).toBeTruthy();
wrapper.find('input').first().simulate('focus');
getElement(wrapper).simulate('focus');
expect(onFocus).toHaveBeenCalled();
});
} else {