mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-24 02:59:58 +08:00
feat: Cascader support multiple mode (#31936)
* chore: Update cascader version * chore: replace cascader * chore: default allowClear * chore: Update docs * test: Back of part * test: More snapshot * test: more and more * test: Failed of defaultValue * test: all basic test case * test: All snapshot * chore: Update cascader * chore: disable react/jsx-no-bind * chore: fix lint * chore: fix less order * chore: fix deps * docs: Update multiple demo * docs: Add multiple example * test: Update snapshot * test: update snapshot
This commit is contained in:
parent
d86e1b5153
commit
282b7c8575
@ -94,6 +94,7 @@ module.exports = {
|
|||||||
'react/sort-comp': 0,
|
'react/sort-comp': 0,
|
||||||
'react/display-name': 0,
|
'react/display-name': 0,
|
||||||
'react/static-property-placement': 0,
|
'react/static-property-placement': 0,
|
||||||
|
'react/jsx-no-bind': 0, // Should not check test file
|
||||||
'react/no-find-dom-node': 0,
|
'react/no-find-dom-node': 0,
|
||||||
'react/no-unused-prop-types': 0,
|
'react/no-unused-prop-types': 0,
|
||||||
'react/default-props-match-prop-types': 0,
|
'react/default-props-match-prop-types': 0,
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,12 +1,31 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { render, mount } from 'enzyme';
|
import { mount } from 'enzyme';
|
||||||
import KeyCode from 'rc-util/lib/KeyCode';
|
import KeyCode from 'rc-util/lib/KeyCode';
|
||||||
import Cascader from '..';
|
import Cascader from '..';
|
||||||
import ConfigProvider from '../../config-provider';
|
import ConfigProvider from '../../config-provider';
|
||||||
|
import excludeAllWarning from '../../../tests/shared/excludeWarning';
|
||||||
import focusTest from '../../../tests/shared/focusTest';
|
import focusTest from '../../../tests/shared/focusTest';
|
||||||
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 { sleep } from '../../../tests/utils';
|
|
||||||
|
function toggleOpen(wrapper) {
|
||||||
|
wrapper.find('.ant-select-selector').simulate('mousedown');
|
||||||
|
}
|
||||||
|
|
||||||
|
function isOpen(wrapper) {
|
||||||
|
return !!wrapper.find('Trigger').props().popupVisible;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDropdown(wrapper) {
|
||||||
|
return wrapper.find('.ant-select-dropdown');
|
||||||
|
}
|
||||||
|
|
||||||
|
function clickOption(wrapper, menuIndex, itemIndex, type = 'click') {
|
||||||
|
const menu = wrapper.find('ul.ant-cascader-menu').at(menuIndex);
|
||||||
|
const itemList = menu.find('li.ant-cascader-menu-item');
|
||||||
|
|
||||||
|
itemList.at(itemIndex).simulate(type);
|
||||||
|
}
|
||||||
|
|
||||||
const options = [
|
const options = [
|
||||||
{
|
{
|
||||||
@ -48,13 +67,15 @@ function filter(inputValue, path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe('Cascader', () => {
|
describe('Cascader', () => {
|
||||||
focusTest(Cascader);
|
excludeAllWarning();
|
||||||
|
|
||||||
|
focusTest(Cascader, { refFocus: true });
|
||||||
mountTest(Cascader);
|
mountTest(Cascader);
|
||||||
rtlTest(Cascader);
|
rtlTest(Cascader);
|
||||||
|
|
||||||
it('popup correctly when panel is hidden', () => {
|
it('popup correctly when panel is hidden', () => {
|
||||||
const wrapper = mount(<Cascader options={options} />);
|
const wrapper = mount(<Cascader options={options} />);
|
||||||
expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot();
|
expect(isOpen(wrapper)).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('popup correctly when panel is open', () => {
|
it('popup correctly when panel is open', () => {
|
||||||
@ -62,8 +83,8 @@ describe('Cascader', () => {
|
|||||||
const wrapper = mount(
|
const wrapper = mount(
|
||||||
<Cascader options={options} onPopupVisibleChange={onPopupVisibleChange} />,
|
<Cascader options={options} onPopupVisibleChange={onPopupVisibleChange} />,
|
||||||
);
|
);
|
||||||
wrapper.find('input').simulate('click');
|
toggleOpen(wrapper);
|
||||||
expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot();
|
expect(isOpen(wrapper)).toBeTruthy();
|
||||||
expect(onPopupVisibleChange).toHaveBeenCalledWith(true);
|
expect(onPopupVisibleChange).toHaveBeenCalledWith(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -77,83 +98,71 @@ describe('Cascader', () => {
|
|||||||
|
|
||||||
it('popup correctly with defaultValue', () => {
|
it('popup correctly with defaultValue', () => {
|
||||||
const wrapper = mount(<Cascader options={options} defaultValue={['zhejiang', 'hangzhou']} />);
|
const wrapper = mount(<Cascader options={options} defaultValue={['zhejiang', 'hangzhou']} />);
|
||||||
wrapper.find('input').simulate('click');
|
toggleOpen(wrapper);
|
||||||
expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot();
|
expect(getDropdown(wrapper).render()).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support popupVisible', () => {
|
it('should support popupVisible', () => {
|
||||||
const wrapper = mount(<Cascader options={options} defaultValue={['zhejiang', 'hangzhou']} />);
|
const wrapper = mount(<Cascader options={options} defaultValue={['zhejiang', 'hangzhou']} />);
|
||||||
expect(wrapper.find('Trigger').instance().getComponent().props.visible).toBe(false);
|
expect(isOpen(wrapper)).toBeFalsy();
|
||||||
wrapper.setProps({ popupVisible: true });
|
wrapper.setProps({ popupVisible: true });
|
||||||
expect(wrapper.find('Trigger').instance().getComponent().props.visible).toBe(true);
|
expect(isOpen(wrapper)).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be selected', () => {
|
it('can be selected', () => {
|
||||||
const onChange = jest.fn();
|
const onChange = jest.fn();
|
||||||
const wrapper = mount(<Cascader options={options} onChange={onChange} />);
|
const wrapper = mount(<Cascader options={options} onChange={onChange} />);
|
||||||
wrapper.find('input').simulate('click');
|
|
||||||
let popupWrapper = mount(wrapper.find('Trigger').instance().getComponent());
|
toggleOpen(wrapper);
|
||||||
popupWrapper
|
expect(isOpen(wrapper)).toBeTruthy();
|
||||||
.find('.ant-cascader-menu')
|
|
||||||
.at(0)
|
clickOption(wrapper, 0, 0);
|
||||||
.find('.ant-cascader-menu-item')
|
expect(getDropdown(wrapper).render()).toMatchSnapshot();
|
||||||
.at(0)
|
|
||||||
.simulate('click');
|
clickOption(wrapper, 1, 0);
|
||||||
expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot();
|
expect(getDropdown(wrapper).render()).toMatchSnapshot();
|
||||||
popupWrapper = mount(wrapper.find('Trigger').instance().getComponent());
|
|
||||||
popupWrapper
|
clickOption(wrapper, 2, 0);
|
||||||
.find('.ant-cascader-menu')
|
expect(getDropdown(wrapper).render()).toMatchSnapshot();
|
||||||
.at(1)
|
|
||||||
.find('.ant-cascader-menu-item')
|
expect(onChange).toHaveBeenCalledTimes(1);
|
||||||
.at(0)
|
|
||||||
.simulate('click');
|
|
||||||
expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot();
|
|
||||||
popupWrapper = mount(wrapper.find('Trigger').instance().getComponent());
|
|
||||||
popupWrapper
|
|
||||||
.find('.ant-cascader-menu')
|
|
||||||
.at(2)
|
|
||||||
.find('.ant-cascader-menu-item')
|
|
||||||
.at(0)
|
|
||||||
.simulate('click');
|
|
||||||
expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot();
|
|
||||||
expect(onChange).toHaveBeenCalledWith(['zhejiang', 'hangzhou', 'xihu'], expect.anything());
|
expect(onChange).toHaveBeenCalledWith(['zhejiang', 'hangzhou', 'xihu'], expect.anything());
|
||||||
});
|
});
|
||||||
|
|
||||||
it('backspace should work with `Cascader[showSearch]`', () => {
|
it('backspace should work with `Cascader[showSearch]`', () => {
|
||||||
const wrapper = mount(<Cascader options={options} showSearch />);
|
const wrapper = mount(<Cascader options={options} showSearch />);
|
||||||
wrapper.find('input').simulate('change', { target: { value: '123' } });
|
wrapper.find('input').simulate('change', { target: { value: '123' } });
|
||||||
expect(wrapper.state('inputValue')).toBe('123');
|
expect(isOpen(wrapper)).toBeTruthy();
|
||||||
wrapper.find('input').simulate('keydown', { keyCode: KeyCode.BACKSPACE });
|
|
||||||
// Simulate onKeyDown will not trigger onChange by default, so the value is still '123'
|
wrapper.find('input').simulate('keydown', { which: KeyCode.BACKSPACE });
|
||||||
expect(wrapper.state('inputValue')).toBe('123');
|
expect(isOpen(wrapper)).toBeTruthy();
|
||||||
|
|
||||||
|
wrapper.find('input').simulate('change', { target: { value: '' } });
|
||||||
|
expect(isOpen(wrapper)).toBeTruthy();
|
||||||
|
|
||||||
|
wrapper.find('input').simulate('keydown', { which: KeyCode.BACKSPACE });
|
||||||
|
expect(isOpen(wrapper)).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should highlight keyword and filter when search in Cascader', () => {
|
it('should highlight keyword and filter when search in Cascader', () => {
|
||||||
const wrapper = mount(<Cascader options={options} showSearch={{ filter }} />);
|
const wrapper = mount(<Cascader options={options} showSearch={{ filter }} />);
|
||||||
wrapper.find('input').simulate('click');
|
|
||||||
wrapper.find('input').simulate('change', { target: { value: 'z' } });
|
wrapper.find('input').simulate('change', { target: { value: 'z' } });
|
||||||
expect(wrapper.state('inputValue')).toBe('z');
|
expect(getDropdown(wrapper).render()).toMatchSnapshot();
|
||||||
const popupWrapper = mount(wrapper.find('Trigger').instance().getComponent());
|
|
||||||
expect(popupWrapper.render()).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should highlight keyword and filter when search in Cascader with same field name of label and value', () => {
|
it('should highlight keyword and filter when search in Cascader with same field name of label and value', () => {
|
||||||
const customOptions = [
|
const customOptions = [
|
||||||
{
|
{
|
||||||
name: 'Zhejiang',
|
name: 'Zhejiang',
|
||||||
value: 'Zhejiang',
|
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
name: 'Hangzhou',
|
name: 'Hangzhou',
|
||||||
value: 'Hangzhou',
|
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
name: 'West Lake',
|
name: 'West Lake',
|
||||||
value: 'West Lake',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Xia Sha',
|
name: 'Xia Sha',
|
||||||
value: 'Xia Sha',
|
|
||||||
disabled: true,
|
disabled: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -171,81 +180,35 @@ describe('Cascader', () => {
|
|||||||
showSearch={{ filter: customFilter }}
|
showSearch={{ filter: customFilter }}
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
wrapper.find('input').simulate('click');
|
|
||||||
wrapper.find('input').simulate('change', { target: { value: 'z' } });
|
wrapper.find('input').simulate('change', { target: { value: 'z' } });
|
||||||
expect(wrapper.state('inputValue')).toBe('z');
|
expect(getDropdown(wrapper).render()).toMatchSnapshot();
|
||||||
const popupWrapper = mount(wrapper.find('Trigger').instance().getComponent());
|
|
||||||
expect(popupWrapper.render()).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render not found content', () => {
|
it('should render not found content', () => {
|
||||||
const wrapper = mount(<Cascader options={options} showSearch={{ filter }} />);
|
const wrapper = mount(<Cascader options={options} showSearch={{ filter }} />);
|
||||||
wrapper.find('input').simulate('click');
|
|
||||||
wrapper.find('input').simulate('change', { target: { value: '__notfoundkeyword__' } });
|
wrapper.find('input').simulate('change', { target: { value: '__notfoundkeyword__' } });
|
||||||
expect(wrapper.state('inputValue')).toBe('__notfoundkeyword__');
|
expect(getDropdown(wrapper).render()).toMatchSnapshot();
|
||||||
const popupWrapper = mount(wrapper.find('Trigger').instance().getComponent());
|
|
||||||
expect(popupWrapper.render()).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support to clear selection', async () => {
|
it('should support to clear selection', () => {
|
||||||
const wrapper = mount(<Cascader options={options} defaultValue={['zhejiang', 'hangzhou']} />);
|
const wrapper = mount(<Cascader options={options} defaultValue={['zhejiang', 'hangzhou']} />);
|
||||||
const willUnmount = jest.spyOn(wrapper.instance(), 'componentWillUnmount');
|
expect(wrapper.find('.ant-select-selection-item').text()).toEqual('Zhejiang / Hangzhou');
|
||||||
const clearTimeoutSpy = jest.spyOn(global, 'clearTimeout');
|
wrapper.find('.ant-select-clear').at(0).simulate('mouseDown');
|
||||||
expect(wrapper.find('.ant-cascader-picker-label').text()).toBe('Zhejiang / Hangzhou');
|
expect(wrapper.exists('.ant-select-selection-item')).toBeFalsy();
|
||||||
wrapper.find('.ant-cascader-picker-clear').at(0).simulate('click');
|
|
||||||
await sleep(300);
|
|
||||||
expect(wrapper.find('.ant-cascader-picker-label').text()).toBe('');
|
|
||||||
wrapper.unmount();
|
|
||||||
expect(willUnmount).toHaveBeenCalled();
|
|
||||||
expect(clearTimeoutSpy).toHaveBeenCalled();
|
|
||||||
clearTimeoutSpy.mockRestore();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should close popup when clear selection', () => {
|
|
||||||
const onPopupVisibleChange = jest.fn();
|
|
||||||
const wrapper = mount(
|
|
||||||
<Cascader
|
|
||||||
options={options}
|
|
||||||
popupVisible
|
|
||||||
defaultValue={['zhejiang', 'hangzhou']}
|
|
||||||
onPopupVisibleChange={onPopupVisibleChange}
|
|
||||||
/>,
|
|
||||||
);
|
|
||||||
wrapper.find('.ant-cascader-picker-clear').at(0).simulate('click');
|
|
||||||
expect(onPopupVisibleChange).toHaveBeenCalledWith(false);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should clear search input when clear selection', () => {
|
it('should clear search input when clear selection', () => {
|
||||||
const wrapper = mount(
|
const wrapper = mount(
|
||||||
<Cascader options={options} defaultValue={['zhejiang', 'hangzhou']} showSearch />,
|
<Cascader options={options} defaultValue={['zhejiang', 'hangzhou']} showSearch />,
|
||||||
);
|
);
|
||||||
wrapper.find('input').simulate('click');
|
|
||||||
wrapper.find('input').simulate('change', { target: { value: 'xxx' } });
|
wrapper.find('input').simulate('change', { target: { value: 'xxx' } });
|
||||||
expect(wrapper.state('inputValue')).toBe('xxx');
|
|
||||||
wrapper.find('.ant-cascader-picker-clear').at(0).simulate('click');
|
|
||||||
expect(wrapper.state('inputValue')).toBe('');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not trigger visible change when click search input', () => {
|
wrapper.find('.ant-select-clear').at(0).simulate('mouseDown');
|
||||||
const onPopupVisibleChange = jest.fn();
|
expect(wrapper.find('input').props().value).toEqual('');
|
||||||
const wrapper = mount(
|
|
||||||
<Cascader options={options} showSearch onPopupVisibleChange={onPopupVisibleChange} />,
|
|
||||||
);
|
|
||||||
wrapper.find('input').simulate('focus');
|
|
||||||
expect(onPopupVisibleChange).toHaveBeenCalledTimes(0);
|
|
||||||
wrapper.find('input').simulate('click');
|
|
||||||
expect(onPopupVisibleChange).toHaveBeenCalledTimes(1);
|
|
||||||
wrapper.find('input').simulate('click');
|
|
||||||
expect(onPopupVisibleChange).toHaveBeenCalledTimes(1);
|
|
||||||
wrapper.find('input').simulate('blur');
|
|
||||||
wrapper.setState({ popupVisible: false });
|
|
||||||
wrapper.find('input').simulate('click');
|
|
||||||
expect(onPopupVisibleChange).toHaveBeenCalledTimes(2);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should change filtered item when options are changed', () => {
|
it('should change filtered item when options are changed', () => {
|
||||||
const wrapper = mount(<Cascader options={options} showSearch={{ filter }} />);
|
const wrapper = mount(<Cascader options={options} showSearch={{ filter }} />);
|
||||||
wrapper.find('input').simulate('click');
|
|
||||||
wrapper.find('input').simulate('change', { target: { value: 'a' } });
|
wrapper.find('input').simulate('change', { target: { value: 'a' } });
|
||||||
expect(wrapper.find('.ant-cascader-menu-item').length).toBe(2);
|
expect(wrapper.find('.ant-cascader-menu-item').length).toBe(2);
|
||||||
wrapper.setProps({ options: [options[0]] });
|
wrapper.setProps({ options: [options[0]] });
|
||||||
@ -254,12 +217,12 @@ describe('Cascader', () => {
|
|||||||
|
|
||||||
it('should select item immediately when searching and pressing down arrow key', () => {
|
it('should select item immediately when searching and pressing down arrow key', () => {
|
||||||
const wrapper = mount(<Cascader options={options} showSearch={{ filter }} />);
|
const wrapper = mount(<Cascader options={options} showSearch={{ filter }} />);
|
||||||
wrapper.find('input').simulate('click');
|
|
||||||
wrapper.find('input').simulate('change', { target: { value: 'a' } });
|
wrapper.find('input').simulate('change', { target: { value: 'a' } });
|
||||||
expect(wrapper.find('.ant-cascader-menu-item').length).toBe(2);
|
expect(wrapper.find('.ant-cascader-menu-item').length).toBe(2);
|
||||||
expect(wrapper.find('.ant-cascader-menu-item-active').length).toBe(0);
|
expect(wrapper.find('.ant-cascader-menu-item-active').length).toBe(0);
|
||||||
|
|
||||||
wrapper.find('input').simulate('keyDown', {
|
wrapper.find('input').simulate('keyDown', {
|
||||||
keyCode: KeyCode.DOWN,
|
which: KeyCode.DOWN,
|
||||||
});
|
});
|
||||||
expect(wrapper.find('.ant-cascader-menu-item-active').length).toBe(1);
|
expect(wrapper.find('.ant-cascader-menu-item-active').length).toBe(1);
|
||||||
});
|
});
|
||||||
@ -299,31 +262,40 @@ describe('Cascader', () => {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const onChange = jest.fn();
|
||||||
|
|
||||||
const wrapper = mount(
|
const wrapper = mount(
|
||||||
<Cascader
|
<Cascader
|
||||||
options={customerOptions}
|
options={customerOptions}
|
||||||
|
onChange={onChange}
|
||||||
fieldNames={{
|
fieldNames={{
|
||||||
children: 'items',
|
children: 'items',
|
||||||
label: 'name',
|
label: 'name',
|
||||||
value: 'code',
|
value: 'code',
|
||||||
}}
|
}}
|
||||||
|
open
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
wrapper.instance().handleChange(['zhejiang', 'hangzhou', 'xihu'], customerOptions);
|
|
||||||
expect(wrapper.find('.ant-cascader-picker-label').text().split('/').length).toBe(3);
|
clickOption(wrapper, 0, 0);
|
||||||
|
clickOption(wrapper, 1, 0);
|
||||||
|
clickOption(wrapper, 2, 0);
|
||||||
|
expect(wrapper.find('.ant-select-selection-item').text()).toEqual(
|
||||||
|
'Zhejiang / Hangzhou / West Lake',
|
||||||
|
);
|
||||||
|
expect(onChange).toHaveBeenCalledWith(['zhejiang', 'hangzhou', 'xihu'], expect.anything());
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show not found content when options.length is 0', () => {
|
it('should show not found content when options.length is 0', () => {
|
||||||
const customerOptions = [];
|
const customerOptions = [];
|
||||||
const wrapper = mount(<Cascader options={customerOptions} />);
|
const wrapper = mount(<Cascader options={customerOptions} />);
|
||||||
wrapper.find('input').simulate('click');
|
toggleOpen(wrapper);
|
||||||
const popupWrapper = mount(wrapper.find('Trigger').instance().getComponent());
|
expect(getDropdown(wrapper).render()).toMatchSnapshot();
|
||||||
expect(popupWrapper.render()).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('not found content shoule be disabled', () => {
|
it('not found content should be disabled', () => {
|
||||||
const wrapper = mount(<Cascader options={[]} />);
|
const wrapper = mount(<Cascader options={[]} open />);
|
||||||
wrapper.find('input').simulate('click');
|
|
||||||
expect(wrapper.find('.ant-cascader-menu-item-disabled').length).toBe(1);
|
expect(wrapper.find('.ant-cascader-menu-item-disabled').length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -336,37 +308,33 @@ describe('Cascader', () => {
|
|||||||
|
|
||||||
it('limit with positive number', () => {
|
it('limit with positive number', () => {
|
||||||
const wrapper = mount(<Cascader options={options} showSearch={{ filter, limit: 1 }} />);
|
const wrapper = mount(<Cascader options={options} showSearch={{ filter, limit: 1 }} />);
|
||||||
wrapper.find('input').simulate('click');
|
|
||||||
wrapper.find('input').simulate('change', { target: { value: 'a' } });
|
wrapper.find('input').simulate('change', { target: { value: 'a' } });
|
||||||
expect(wrapper.find('.ant-cascader-menu-item').length).toBe(1);
|
expect(wrapper.find('.ant-cascader-menu-item')).toHaveLength(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('not limit', () => {
|
it('not limit', () => {
|
||||||
const wrapper = mount(<Cascader options={options} showSearch={{ filter, limit: false }} />);
|
const wrapper = mount(<Cascader options={options} showSearch={{ filter, limit: false }} />);
|
||||||
wrapper.find('input').simulate('click');
|
|
||||||
wrapper.find('input').simulate('change', { target: { value: 'a' } });
|
wrapper.find('input').simulate('change', { target: { value: 'a' } });
|
||||||
expect(wrapper.find('.ant-cascader-menu-item').length).toBe(2);
|
expect(wrapper.find('.ant-cascader-menu-item')).toHaveLength(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('negative limit', () => {
|
it('negative limit', () => {
|
||||||
const wrapper = mount(<Cascader options={options} showSearch={{ filter, limit: -1 }} />);
|
const wrapper = mount(<Cascader options={options} showSearch={{ filter, limit: -1 }} />);
|
||||||
wrapper.find('input').simulate('click');
|
wrapper.find('input').simulate('click');
|
||||||
wrapper.find('input').simulate('change', { target: { value: 'a' } });
|
wrapper.find('input').simulate('change', { target: { value: 'a' } });
|
||||||
expect(wrapper.find('.ant-cascader-menu-item').length).toBe(2);
|
expect(wrapper.find('.ant-cascader-menu-item')).toHaveLength(2);
|
||||||
expect(errorSpy).toHaveBeenCalledWith(
|
|
||||||
"Warning: [antd: Cascader] 'limit' of showSearch should be positive number or false.",
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should warning if not find `value` in `options`', () => {
|
// FIXME: Move to `rc-tree-select` instead
|
||||||
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
// it('should warning if not find `value` in `options`', () => {
|
||||||
mount(<Cascader options={[{ label: 'a', value: 'a', children: [{ label: 'b' }] }]} />);
|
// const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
expect(errorSpy).toHaveBeenCalledWith(
|
// mount(<Cascader options={[{ label: 'a', value: 'a', children: [{ label: 'b' }] }]} />);
|
||||||
'Warning: [antd: Cascader] Not found `value` in `options`.',
|
// expect(errorSpy).toHaveBeenCalledWith(
|
||||||
);
|
// 'Warning: [antd: Cascader] Not found `value` in `options`.',
|
||||||
errorSpy.mockRestore();
|
// );
|
||||||
});
|
// errorSpy.mockRestore();
|
||||||
|
// });
|
||||||
|
|
||||||
// https://github.com/ant-design/ant-design/issues/17690
|
// https://github.com/ant-design/ant-design/issues/17690
|
||||||
it('should not breaks when children is null', () => {
|
it('should not breaks when children is null', () => {
|
||||||
@ -388,40 +356,24 @@ describe('Cascader', () => {
|
|||||||
}).not.toThrow();
|
}).not.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
// https://github.com/ant-design/ant-design/issues/18176
|
|
||||||
it('have a notFoundContent that fit trigger input width', () => {
|
|
||||||
const wrapper = mount(
|
|
||||||
<Cascader
|
|
||||||
popupVisible
|
|
||||||
options={[]}
|
|
||||||
fieldNames={{ label: 'name', value: 'code', children: 'items' }}
|
|
||||||
/>,
|
|
||||||
);
|
|
||||||
const popupWrapper = mount(wrapper.find('Trigger').instance().getComponent());
|
|
||||||
expect(popupWrapper.render()).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('placeholder works correctly', () => {
|
it('placeholder works correctly', () => {
|
||||||
const wrapper = mount(<Cascader options={[]} />);
|
const wrapper = mount(<Cascader options={[]} />);
|
||||||
expect(wrapper.find('input').prop('placeholder')).toBe('Please select');
|
expect(wrapper.find('.ant-select-selection-placeholder').text()).toEqual('');
|
||||||
|
|
||||||
const customPlaceholder = 'Custom placeholder';
|
const customPlaceholder = 'Custom placeholder';
|
||||||
wrapper.setProps({
|
wrapper.setProps({
|
||||||
placeholder: customPlaceholder,
|
placeholder: customPlaceholder,
|
||||||
});
|
});
|
||||||
expect(wrapper.find('input').prop('placeholder')).toBe(customPlaceholder);
|
expect(wrapper.find('.ant-select-selection-placeholder').text()).toEqual(customPlaceholder);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('popup correctly with defaultValue RTL', () => {
|
it('popup correctly with defaultValue RTL', () => {
|
||||||
const wrapper = mount(
|
const wrapper = mount(
|
||||||
<ConfigProvider direction="rtl">
|
<ConfigProvider direction="rtl">
|
||||||
<Cascader options={options} defaultValue={['zhejiang', 'hangzhou']} />
|
<Cascader options={options} defaultValue={['zhejiang', 'hangzhou']} open />
|
||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
);
|
);
|
||||||
wrapper.find('Cascader').find('input').simulate('click');
|
expect(wrapper.render()).toMatchSnapshot();
|
||||||
expect(
|
|
||||||
render(wrapper.find('Cascader').find('Trigger').instance().getComponent()),
|
|
||||||
).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be selected in RTL direction', () => {
|
it('can be selected in RTL direction', () => {
|
||||||
@ -471,81 +423,54 @@ describe('Cascader', () => {
|
|||||||
</ConfigProvider>,
|
</ConfigProvider>,
|
||||||
);
|
);
|
||||||
|
|
||||||
wrapper.find('Cascader').find('input').simulate('click');
|
toggleOpen(wrapper);
|
||||||
let popupWrapper = mount(wrapper.find('Cascader').find('Trigger').instance().getComponent());
|
clickOption(wrapper, 0, 0);
|
||||||
popupWrapper
|
expect(getDropdown(wrapper).render()).toMatchSnapshot();
|
||||||
.find('.ant-cascader-menu')
|
|
||||||
.at(0)
|
toggleOpen(wrapper);
|
||||||
.find('.ant-cascader-menu-item')
|
clickOption(wrapper, 1, 0);
|
||||||
.at(0)
|
expect(getDropdown(wrapper).render()).toMatchSnapshot();
|
||||||
.simulate('click');
|
|
||||||
expect(
|
toggleOpen(wrapper);
|
||||||
render(wrapper.find('Cascader').find('Trigger').instance().getComponent()),
|
clickOption(wrapper, 2, 0);
|
||||||
).toMatchSnapshot();
|
expect(getDropdown(wrapper).render()).toMatchSnapshot();
|
||||||
popupWrapper = mount(wrapper.find('Cascader').find('Trigger').instance().getComponent());
|
|
||||||
popupWrapper
|
expect(onChange).toHaveBeenCalledTimes(1);
|
||||||
.find('.ant-cascader-menu')
|
|
||||||
.at(1)
|
|
||||||
.find('.ant-cascader-menu-item')
|
|
||||||
.at(0)
|
|
||||||
.simulate('click');
|
|
||||||
expect(
|
|
||||||
render(wrapper.find('Cascader').find('Trigger').instance().getComponent()),
|
|
||||||
).toMatchSnapshot();
|
|
||||||
popupWrapper = mount(wrapper.find('Cascader').find('Trigger').instance().getComponent());
|
|
||||||
popupWrapper
|
|
||||||
.find('.ant-cascader-menu')
|
|
||||||
.at(2)
|
|
||||||
.find('.ant-cascader-menu-item')
|
|
||||||
.at(0)
|
|
||||||
.simulate('click');
|
|
||||||
expect(onChange).toHaveBeenCalledWith(['zhejiang', 'hangzhou', 'xihu'], expect.anything());
|
expect(onChange).toHaveBeenCalledWith(['zhejiang', 'hangzhou', 'xihu'], expect.anything());
|
||||||
});
|
});
|
||||||
|
|
||||||
it('defaultValue works correctly when no match options', () => {
|
it('defaultValue works correctly when no match options', () => {
|
||||||
const wrapper = mount(<Cascader options={options} defaultValue={['options1', 'options2']} />);
|
const wrapper = mount(<Cascader options={options} defaultValue={['options1', 'options2']} />);
|
||||||
expect(wrapper.find('.ant-cascader-picker-label').text()).toBe('options1 / options2');
|
expect(wrapper.find('.ant-select-selection-item').text()).toEqual('options1 / options2');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be selected when showSearch', () => {
|
it('can be selected when showSearch', () => {
|
||||||
const onChange = jest.fn();
|
const onChange = jest.fn();
|
||||||
const wrapper = mount(<Cascader options={options} onChange={onChange} showSearch />);
|
const wrapper = mount(<Cascader options={options} onChange={onChange} showSearch />);
|
||||||
wrapper.find('input').simulate('click');
|
|
||||||
wrapper.find('input').simulate('change', { target: { value: 'Zh' } });
|
wrapper.find('input').simulate('change', { target: { value: 'Zh' } });
|
||||||
const popupWrapper = mount(wrapper.find('Cascader').find('Trigger').instance().getComponent());
|
expect(wrapper.find('.ant-cascader-menu').length).toBe(1);
|
||||||
expect(popupWrapper.find('.ant-cascader-menu').length).toBe(1);
|
clickOption(wrapper, 0, 0);
|
||||||
popupWrapper
|
|
||||||
.find('.ant-cascader-menu')
|
|
||||||
.at(0)
|
|
||||||
.find('.ant-cascader-menu-item')
|
|
||||||
.at(0)
|
|
||||||
.simulate('click');
|
|
||||||
expect(onChange).toHaveBeenCalledWith(['zhejiang', 'hangzhou', 'xihu'], expect.anything());
|
expect(onChange).toHaveBeenCalledWith(['zhejiang', 'hangzhou', 'xihu'], expect.anything());
|
||||||
});
|
});
|
||||||
|
|
||||||
it('options should open after press esc and then search', () => {
|
it('options should open after press esc and then search', () => {
|
||||||
const wrapper = mount(<Cascader options={options} showSearch />);
|
const wrapper = mount(<Cascader options={options} showSearch />);
|
||||||
wrapper.find('input').simulate('change', { target: { value: 'jin' } });
|
wrapper.find('input').simulate('change', { target: { value: 'jin' } });
|
||||||
wrapper.find('input').simulate('keydown', { keyCode: KeyCode.ESC });
|
expect(isOpen(wrapper)).toBeTruthy();
|
||||||
|
wrapper.find('input').simulate('keydown', { which: KeyCode.ESC });
|
||||||
|
expect(isOpen(wrapper)).toBeFalsy();
|
||||||
wrapper.find('input').simulate('change', { target: { value: 'jin' } });
|
wrapper.find('input').simulate('change', { target: { value: 'jin' } });
|
||||||
expect(wrapper.state('popupVisible')).toBe(true);
|
expect(isOpen(wrapper)).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('onChange works correctly when the label of fieldNames is the same as value', () => {
|
it('onChange works correctly when the label of fieldNames is the same as value', () => {
|
||||||
const onChange = jest.fn();
|
const onChange = jest.fn();
|
||||||
const sameNames = { label: 'label', value: 'label', children: 'children' };
|
const sameNames = { label: 'label', value: 'label' };
|
||||||
const wrapper = mount(
|
const wrapper = mount(
|
||||||
<Cascader options={options} onChange={onChange} showSearch fieldNames={sameNames} />,
|
<Cascader options={options} onChange={onChange} showSearch fieldNames={sameNames} />,
|
||||||
);
|
);
|
||||||
wrapper.find('input').simulate('click');
|
|
||||||
wrapper.find('input').simulate('change', { target: { value: 'est' } });
|
wrapper.find('input').simulate('change', { target: { value: 'est' } });
|
||||||
const popupWrapper = mount(wrapper.find('Cascader').find('Trigger').instance().getComponent());
|
clickOption(wrapper, 0, 0);
|
||||||
popupWrapper
|
|
||||||
.find('.ant-cascader-menu')
|
|
||||||
.at(0)
|
|
||||||
.find('.ant-cascader-menu-item')
|
|
||||||
.at(0)
|
|
||||||
.simulate('click');
|
|
||||||
expect(onChange).toHaveBeenCalledWith(['Zhejiang', 'Hangzhou', 'West Lake'], expect.anything());
|
expect(onChange).toHaveBeenCalledWith(['Zhejiang', 'Hangzhou', 'West Lake'], expect.anything());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
67
components/cascader/demo/multiple.md
Normal file
67
components/cascader/demo/multiple.md
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
---
|
||||||
|
order: 5.1
|
||||||
|
title:
|
||||||
|
zh-CN: 多选
|
||||||
|
en-US: Multiple
|
||||||
|
---
|
||||||
|
|
||||||
|
## zh-CN
|
||||||
|
|
||||||
|
一次性选择多个选项。
|
||||||
|
|
||||||
|
## en-US
|
||||||
|
|
||||||
|
Select multiple options
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
import { Cascader } from 'antd';
|
||||||
|
|
||||||
|
const options = [
|
||||||
|
{
|
||||||
|
label: 'Light',
|
||||||
|
value: 'light',
|
||||||
|
children: new Array(20)
|
||||||
|
.fill(null)
|
||||||
|
.map((_, index) => ({ label: `Number ${index}`, value: index })),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Bamboo',
|
||||||
|
value: 'bamboo',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
label: 'Little',
|
||||||
|
value: 'little',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
label: 'Toy Fish',
|
||||||
|
value: 'fish',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Toy Cards',
|
||||||
|
value: 'cards',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Toy Bird',
|
||||||
|
value: 'bird',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
function onChange(value) {
|
||||||
|
console.log(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<Cascader
|
||||||
|
style={{ width: 233 }}
|
||||||
|
options={options}
|
||||||
|
onChange={onChange}
|
||||||
|
multiple
|
||||||
|
maxTagCount="responsive"
|
||||||
|
/>,
|
||||||
|
mountNode,
|
||||||
|
);
|
||||||
|
```
|
@ -36,18 +36,18 @@ Cascade selection box.
|
|||||||
| getPopupContainer | Parent Node which the selector should be rendered to. Default to `body`. When position issues happen, try to modify it into scrollable content and position it relative. [example](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | function(triggerNode) | () => document.body | |
|
| getPopupContainer | Parent Node which the selector should be rendered to. Default to `body`. When position issues happen, try to modify it into scrollable content and position it relative. [example](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | function(triggerNode) | () => document.body | |
|
||||||
| loadData | To load option lazily, and it cannot work with `showSearch` | (selectedOptions) => void | - | |
|
| loadData | To load option lazily, and it cannot work with `showSearch` | (selectedOptions) => void | - | |
|
||||||
| notFoundContent | Specify content to show when no result matches | string | `Not Found` | |
|
| notFoundContent | Specify content to show when no result matches | string | `Not Found` | |
|
||||||
|
| open | Set visible of cascader popup | boolean | - | 4.17.0 |
|
||||||
| options | The data options of cascade | [Option](#Option)\[] | - | |
|
| options | The data options of cascade | [Option](#Option)\[] | - | |
|
||||||
| placeholder | The input placeholder | string | `Please select` | |
|
| placeholder | The input placeholder | string | `Please select` | |
|
||||||
| popupClassName | The additional className of popup overlay | string | - | |
|
| popupClassName | The additional className of popup overlay | string | - | |
|
||||||
| popupPlacement | Use preset popup align config from builtinPlacements:`bottomLeft` `bottomRight` `topLeft` `topRight` | string | `bottomLeft` | |
|
| popupPlacement | Use preset popup align config from builtinPlacements:`bottomLeft` `bottomRight` `topLeft` `topRight` | string | `bottomLeft` | |
|
||||||
| popupVisible | Set visible of cascader popup | boolean | - | |
|
|
||||||
| showSearch | Whether show search input in single mode | boolean \| [Object](#showSearch) | false | |
|
| showSearch | Whether show search input in single mode | boolean \| [Object](#showSearch) | false | |
|
||||||
| size | The input size | `large` \| `middle` \| `small` | - | |
|
| size | The input size | `large` \| `middle` \| `small` | - | |
|
||||||
| style | The additional style | CSSProperties | - | |
|
| style | The additional style | CSSProperties | - | |
|
||||||
| suffixIcon | The custom suffix icon | ReactNode | - | |
|
| suffixIcon | The custom suffix icon | ReactNode | - | |
|
||||||
| value | The selected value | string\[] \| number\[] | - | |
|
| value | The selected value | string\[] \| number\[] | - | |
|
||||||
| onChange | Callback when finishing cascader select | (value, selectedOptions) => void | - | |
|
| onChange | Callback when finishing cascader select | (value, selectedOptions) => void | - | |
|
||||||
| onPopupVisibleChange | Callback when popup shown or hidden | (value) => void | - | |
|
| onDropdownVisibleChange | Callback when popup shown or hidden | (value) => void | - | 4.17.0 |
|
||||||
|
|
||||||
### showSearch
|
### showSearch
|
||||||
|
|
||||||
|
@ -1,716 +1,215 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import RcCascader from 'rc-cascader';
|
|
||||||
import arrayTreeFilter from 'array-tree-filter';
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
import RcCascader from 'rc-cascader';
|
||||||
|
import type { CascaderProps as RcCascaderProps } from 'rc-cascader';
|
||||||
|
import type { ShowSearchType, FieldNames } from 'rc-cascader/lib/interface';
|
||||||
import omit from 'rc-util/lib/omit';
|
import omit from 'rc-util/lib/omit';
|
||||||
import KeyCode from 'rc-util/lib/KeyCode';
|
|
||||||
import CloseCircleFilled from '@ant-design/icons/CloseCircleFilled';
|
|
||||||
import DownOutlined from '@ant-design/icons/DownOutlined';
|
|
||||||
import RightOutlined from '@ant-design/icons/RightOutlined';
|
import RightOutlined from '@ant-design/icons/RightOutlined';
|
||||||
import RedoOutlined from '@ant-design/icons/RedoOutlined';
|
import RedoOutlined from '@ant-design/icons/RedoOutlined';
|
||||||
import LeftOutlined from '@ant-design/icons/LeftOutlined';
|
import LeftOutlined from '@ant-design/icons/LeftOutlined';
|
||||||
|
import { ConfigContext } from '../config-provider';
|
||||||
import Input from '../input';
|
import type { SizeType } from '../config-provider/SizeContext';
|
||||||
import {
|
import SizeContext from '../config-provider/SizeContext';
|
||||||
ConfigConsumer,
|
import getIcons from '../select/utils/iconUtil';
|
||||||
ConfigConsumerProps,
|
|
||||||
RenderEmptyHandler,
|
|
||||||
DirectionType,
|
|
||||||
} from '../config-provider';
|
|
||||||
import LocaleReceiver from '../locale-provider/LocaleReceiver';
|
|
||||||
import devWarning from '../_util/devWarning';
|
|
||||||
import SizeContext, { SizeType } from '../config-provider/SizeContext';
|
|
||||||
import { replaceElement } from '../_util/reactNode';
|
|
||||||
import { getTransitionName } from '../_util/motion';
|
import { getTransitionName } from '../_util/motion';
|
||||||
|
|
||||||
export interface CascaderOptionType {
|
// Align the design since we use `rc-select` in root. This help:
|
||||||
value?: string | number;
|
// - List search content will show all content
|
||||||
label?: React.ReactNode;
|
// - Hover opacity style
|
||||||
disabled?: boolean;
|
// - Search filter match case
|
||||||
isLeaf?: boolean;
|
|
||||||
loading?: boolean;
|
export type FieldNamesType = FieldNames;
|
||||||
children?: Array<CascaderOptionType>;
|
|
||||||
[key: string]: any;
|
export type FilledFieldNamesType = Required<FieldNamesType>;
|
||||||
|
|
||||||
|
function highlightKeyword(str: string, lowerKeyword: string, prefixCls: string | undefined) {
|
||||||
|
const cells = str
|
||||||
|
.toLowerCase()
|
||||||
|
.split(lowerKeyword)
|
||||||
|
.reduce((list, cur, index) => (index === 0 ? [cur] : [...list, lowerKeyword, cur]), []);
|
||||||
|
const fillCells: React.ReactNode[] = [];
|
||||||
|
let start = 0;
|
||||||
|
|
||||||
|
cells.forEach((cell, index) => {
|
||||||
|
const end = start + cell.length;
|
||||||
|
let originWorld: React.ReactNode = str.slice(start, end);
|
||||||
|
start = end;
|
||||||
|
|
||||||
|
if (index % 2 === 1) {
|
||||||
|
originWorld = (
|
||||||
|
<span className={`${prefixCls}-menu-item-keyword`} key="seperator">
|
||||||
|
{originWorld}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fillCells.push(originWorld);
|
||||||
|
});
|
||||||
|
|
||||||
|
return fillCells;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FieldNamesType {
|
const defaultSearchRender: ShowSearchType['render'] = (inputValue, path, prefixCls, fieldNames) => {
|
||||||
value?: string | number;
|
const optionList: React.ReactNode[] = [];
|
||||||
label?: string;
|
|
||||||
children?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface FilledFieldNamesType {
|
// We do lower here to save perf
|
||||||
value: string | number;
|
const lower = inputValue.toLowerCase();
|
||||||
label: string;
|
|
||||||
children: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type CascaderExpandTrigger = 'click' | 'hover';
|
path.forEach((node, index) => {
|
||||||
|
if (index !== 0) {
|
||||||
|
optionList.push(' / ');
|
||||||
|
}
|
||||||
|
|
||||||
export type CascaderValueType = (string | number)[];
|
let label = (node as any)[fieldNames.label!];
|
||||||
|
const type = typeof label;
|
||||||
|
if (type === 'string' || type === 'number') {
|
||||||
|
label = highlightKeyword(String(label), lower, prefixCls);
|
||||||
|
}
|
||||||
|
|
||||||
export interface ShowSearchType {
|
optionList.push(label);
|
||||||
filter?: (inputValue: string, path: CascaderOptionType[], names: FilledFieldNamesType) => boolean;
|
});
|
||||||
render?: (
|
return optionList;
|
||||||
inputValue: string,
|
};
|
||||||
path: CascaderOptionType[],
|
|
||||||
prefixCls: string | undefined,
|
|
||||||
names: FilledFieldNamesType,
|
|
||||||
) => React.ReactNode;
|
|
||||||
sort?: (
|
|
||||||
a: CascaderOptionType[],
|
|
||||||
b: CascaderOptionType[],
|
|
||||||
inputValue: string,
|
|
||||||
names: FilledFieldNamesType,
|
|
||||||
) => number;
|
|
||||||
matchInputWidth?: boolean;
|
|
||||||
limit?: number | false;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CascaderProps {
|
export interface CascaderProps extends Omit<RcCascaderProps, 'checkable'> {
|
||||||
/** 可选项数据源 */
|
multiple?: boolean;
|
||||||
options: CascaderOptionType[];
|
|
||||||
/** 默认的选中项 */
|
|
||||||
defaultValue?: CascaderValueType;
|
|
||||||
/** 指定选中项 */
|
|
||||||
value?: CascaderValueType;
|
|
||||||
/** 选择完成后的回调 */
|
|
||||||
onChange?: (value: CascaderValueType, selectedOptions?: CascaderOptionType[]) => void;
|
|
||||||
/** 选择后展示的渲染函数 */
|
|
||||||
displayRender?: (label: string[], selectedOptions?: CascaderOptionType[]) => React.ReactNode;
|
|
||||||
/** 自定义样式 */
|
|
||||||
style?: React.CSSProperties;
|
|
||||||
/** 自定义类名 */
|
|
||||||
className?: string;
|
|
||||||
/** 自定义浮层类名 */
|
|
||||||
popupClassName?: string;
|
|
||||||
/** 浮层预设位置:`bottomLeft` `bottomRight` `topLeft` `topRight` */
|
|
||||||
popupPlacement?: string;
|
|
||||||
/** 输入框占位文本 */
|
|
||||||
placeholder?: string;
|
|
||||||
/** 输入框大小,可选 `large` `default` `small` */
|
|
||||||
size?: SizeType;
|
size?: SizeType;
|
||||||
/** 输入框 name */
|
|
||||||
name?: string;
|
|
||||||
/** 输入框 id */
|
|
||||||
id?: string;
|
|
||||||
/** Whether has border style */
|
|
||||||
bordered?: boolean;
|
bordered?: boolean;
|
||||||
/** 禁用 */
|
|
||||||
disabled?: boolean;
|
|
||||||
/** 是否支持清除 */
|
|
||||||
allowClear?: boolean;
|
|
||||||
/** 自动获取焦点 */
|
|
||||||
autoFocus?: boolean;
|
|
||||||
showSearch?: boolean | ShowSearchType;
|
|
||||||
notFoundContent?: React.ReactNode;
|
|
||||||
loadData?: (selectedOptions?: CascaderOptionType[]) => void;
|
|
||||||
/** 次级菜单的展开方式,可选 'click' 和 'hover' */
|
|
||||||
expandTrigger?: CascaderExpandTrigger;
|
|
||||||
expandIcon?: React.ReactNode;
|
|
||||||
/** 当此项为 true 时,点选每级菜单选项值都会发生变化 */
|
|
||||||
changeOnSelect?: boolean;
|
|
||||||
/** 浮层可见变化时回调 */
|
|
||||||
onPopupVisibleChange?: (popupVisible: boolean) => void;
|
|
||||||
prefixCls?: string;
|
|
||||||
inputPrefixCls?: string;
|
|
||||||
getPopupContainer?: (triggerNode: HTMLElement) => HTMLElement;
|
|
||||||
popupVisible?: boolean;
|
|
||||||
/** Use this after antd@3.7.0 */
|
|
||||||
fieldNames?: FieldNamesType;
|
|
||||||
suffixIcon?: React.ReactNode;
|
|
||||||
dropdownRender?: (menus: React.ReactNode) => React.ReactNode;
|
|
||||||
|
|
||||||
// Miss prop defines.
|
|
||||||
autoComplete?: string;
|
|
||||||
transitionName?: string;
|
|
||||||
children?: React.ReactElement;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CascaderState {
|
interface CascaderRef {
|
||||||
inputFocused: boolean;
|
focus: () => void;
|
||||||
inputValue: string;
|
blur: () => void;
|
||||||
value: CascaderValueType;
|
|
||||||
popupVisible: boolean | undefined;
|
|
||||||
flattenOptions: CascaderOptionType[][] | undefined;
|
|
||||||
prevProps: CascaderProps;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CascaderLocale {
|
const Cascader = React.forwardRef((props: CascaderProps, ref: React.Ref<CascaderRef>) => {
|
||||||
placeholder?: string;
|
const {
|
||||||
}
|
prefixCls: customizePrefixCls,
|
||||||
|
size: customizeSize,
|
||||||
|
className,
|
||||||
|
multiple,
|
||||||
|
bordered = true,
|
||||||
|
transitionName,
|
||||||
|
choiceTransitionName = '',
|
||||||
|
dropdownClassName,
|
||||||
|
expandIcon,
|
||||||
|
showSearch,
|
||||||
|
allowClear = true,
|
||||||
|
notFoundContent,
|
||||||
|
direction,
|
||||||
|
...rest
|
||||||
|
} = props;
|
||||||
|
|
||||||
// We limit the filtered item count by default
|
const restProps = omit(rest, ['suffixIcon' as any]);
|
||||||
const defaultLimit = 50;
|
|
||||||
|
|
||||||
// keep value when filtering
|
const {
|
||||||
const keepFilteredValueField = '__KEEP_FILTERED_OPTION_VALUE';
|
// getPopupContainer: getContextPopupContainer,
|
||||||
|
getPrefixCls,
|
||||||
|
renderEmpty,
|
||||||
|
direction: rootDirection,
|
||||||
|
// virtual,
|
||||||
|
// dropdownMatchSelectWidth,
|
||||||
|
} = React.useContext(ConfigContext);
|
||||||
|
|
||||||
function highlightKeyword(str: string, keyword: string, prefixCls: string | undefined) {
|
const mergedDirection = direction || rootDirection;
|
||||||
return str.split(keyword).map((node: string, index: number) =>
|
const isRtl = mergedDirection === 'rtl';
|
||||||
index === 0
|
|
||||||
? node
|
|
||||||
: [
|
|
||||||
<span className={`${prefixCls}-menu-item-keyword`} key="seperator">
|
|
||||||
{keyword}
|
|
||||||
</span>,
|
|
||||||
node,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function defaultFilterOption(
|
// =================== No Found ====================
|
||||||
inputValue: string,
|
const mergedNotFoundContent = notFoundContent || renderEmpty('Cascader');
|
||||||
path: CascaderOptionType[],
|
|
||||||
names: FilledFieldNamesType,
|
|
||||||
) {
|
|
||||||
return path.some(option => (option[names.label] as string).indexOf(inputValue) > -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function defaultRenderFilteredOption(
|
// ==================== Prefix =====================
|
||||||
inputValue: string,
|
const rootPrefixCls = getPrefixCls();
|
||||||
path: CascaderOptionType[],
|
const prefixCls = getPrefixCls('select', customizePrefixCls);
|
||||||
prefixCls: string | undefined,
|
const cascaderPrefixCls = getPrefixCls('cascader', customizePrefixCls);
|
||||||
names: FilledFieldNamesType,
|
|
||||||
) {
|
// =================== Dropdown ====================
|
||||||
return path.map((option, index) => {
|
const mergedDropdownClassName = classNames(dropdownClassName, `${cascaderPrefixCls}-dropdown`, {
|
||||||
const label = option[names.label];
|
[`${cascaderPrefixCls}-dropdown-rtl`]: mergedDirection === 'rtl',
|
||||||
const node =
|
|
||||||
(label as string).indexOf(inputValue) > -1
|
|
||||||
? highlightKeyword(label as string, inputValue, prefixCls)
|
|
||||||
: label;
|
|
||||||
return index === 0 ? node : [' / ', node];
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
function defaultSortFilteredOption(
|
// ==================== Search =====================
|
||||||
a: CascaderOptionType[],
|
const mergedShowSearch = React.useMemo(() => {
|
||||||
b: CascaderOptionType[],
|
if (!showSearch) {
|
||||||
inputValue: string,
|
return showSearch;
|
||||||
names: FilledFieldNamesType,
|
|
||||||
) {
|
|
||||||
function callback(elem: CascaderOptionType) {
|
|
||||||
return (elem[names.label] as string).indexOf(inputValue) > -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.findIndex(callback) - b.findIndex(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getFieldNames({ fieldNames }: CascaderProps) {
|
|
||||||
return fieldNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getFilledFieldNames(props: CascaderProps) {
|
|
||||||
const fieldNames = getFieldNames(props) || {};
|
|
||||||
const names: FilledFieldNamesType = {
|
|
||||||
children: fieldNames.children || 'children',
|
|
||||||
label: fieldNames.label || 'label',
|
|
||||||
value: fieldNames.value || 'value',
|
|
||||||
};
|
|
||||||
return names;
|
|
||||||
}
|
|
||||||
|
|
||||||
function flattenTree(
|
|
||||||
options: CascaderOptionType[],
|
|
||||||
props: CascaderProps,
|
|
||||||
ancestor: CascaderOptionType[] = [],
|
|
||||||
) {
|
|
||||||
const names: FilledFieldNamesType = getFilledFieldNames(props);
|
|
||||||
let flattenOptions: CascaderOptionType[][] = [];
|
|
||||||
const childrenName = names.children;
|
|
||||||
options.forEach(option => {
|
|
||||||
const path = ancestor.concat(option);
|
|
||||||
if (props.changeOnSelect || !option[childrenName] || !option[childrenName].length) {
|
|
||||||
flattenOptions.push(path);
|
|
||||||
}
|
}
|
||||||
if (option[childrenName]) {
|
|
||||||
flattenOptions = flattenOptions.concat(flattenTree(option[childrenName], props, path));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return flattenOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
const defaultDisplayRender = (label: string[]) => label.join(' / ');
|
let searchConfig: ShowSearchType = {
|
||||||
|
render: defaultSearchRender,
|
||||||
function warningValueNotExist(list: CascaderOptionType[], fieldNames: FieldNamesType = {}) {
|
|
||||||
(list || []).forEach(item => {
|
|
||||||
const valueFieldName = fieldNames.value || 'value';
|
|
||||||
devWarning(valueFieldName in item, 'Cascader', 'Not found `value` in `options`.');
|
|
||||||
warningValueNotExist(item[fieldNames.children || 'children'], fieldNames);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getEmptyNode(
|
|
||||||
renderEmpty: RenderEmptyHandler,
|
|
||||||
names: FilledFieldNamesType,
|
|
||||||
notFoundContent?: React.ReactNode,
|
|
||||||
) {
|
|
||||||
return {
|
|
||||||
[names.value]: 'ANT_CASCADER_NOT_FOUND',
|
|
||||||
[names.label]: notFoundContent || renderEmpty('Cascader'),
|
|
||||||
disabled: true,
|
|
||||||
isEmptyNode: true,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
class Cascader extends React.Component<CascaderProps, CascaderState> {
|
|
||||||
static defaultProps = {
|
|
||||||
options: [],
|
|
||||||
disabled: false,
|
|
||||||
allowClear: true,
|
|
||||||
bordered: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
static getDerivedStateFromProps(nextProps: CascaderProps, { prevProps }: CascaderState) {
|
|
||||||
const newState: Partial<CascaderState> = {
|
|
||||||
prevProps: nextProps,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if ('value' in nextProps) {
|
if (typeof showSearch === 'object') {
|
||||||
newState.value = nextProps.value || [];
|
searchConfig = {
|
||||||
}
|
...searchConfig,
|
||||||
if ('popupVisible' in nextProps) {
|
...showSearch,
|
||||||
newState.popupVisible = nextProps.popupVisible;
|
};
|
||||||
}
|
|
||||||
if (nextProps.showSearch && prevProps.options !== nextProps.options) {
|
|
||||||
newState.flattenOptions = flattenTree(nextProps.options, nextProps);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== 'production' && nextProps.options) {
|
return searchConfig;
|
||||||
warningValueNotExist(nextProps.options, getFieldNames(nextProps));
|
}, [showSearch]);
|
||||||
}
|
|
||||||
|
|
||||||
return newState;
|
// ===================== Size ======================
|
||||||
|
const size = React.useContext(SizeContext);
|
||||||
|
const mergedSize = customizeSize || size;
|
||||||
|
|
||||||
|
// ===================== Icon ======================
|
||||||
|
let mergedExpandIcon = expandIcon;
|
||||||
|
if (!expandIcon) {
|
||||||
|
mergedExpandIcon = isRtl ? <LeftOutlined /> : <RightOutlined />;
|
||||||
}
|
}
|
||||||
|
|
||||||
cachedOptions: CascaderOptionType[] = [];
|
const loadingIcon = (
|
||||||
|
<span className={`${prefixCls}-menu-item-loading-icon`}>
|
||||||
clearSelectionTimeout: any;
|
<RedoOutlined spin />
|
||||||
|
</span>
|
||||||
private input: Input;
|
|
||||||
|
|
||||||
constructor(props: CascaderProps) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
value: props.value || props.defaultValue || [],
|
|
||||||
inputValue: '',
|
|
||||||
inputFocused: false,
|
|
||||||
popupVisible: props.popupVisible,
|
|
||||||
flattenOptions: props.showSearch ? flattenTree(props.options, props) : undefined,
|
|
||||||
prevProps: props,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
if (this.clearSelectionTimeout) {
|
|
||||||
clearTimeout(this.clearSelectionTimeout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setValue = (value: CascaderValueType, selectedOptions: CascaderOptionType[] = []) => {
|
|
||||||
if (!('value' in this.props)) {
|
|
||||||
this.setState({ value });
|
|
||||||
}
|
|
||||||
const { onChange } = this.props;
|
|
||||||
onChange?.(value, selectedOptions);
|
|
||||||
};
|
|
||||||
|
|
||||||
getLabel() {
|
|
||||||
const { options, displayRender = defaultDisplayRender } = this.props;
|
|
||||||
const names = getFilledFieldNames(this.props);
|
|
||||||
const { value } = this.state;
|
|
||||||
const unwrappedValue = Array.isArray(value[0]) ? value[0] : value;
|
|
||||||
const selectedOptions: CascaderOptionType[] = arrayTreeFilter(
|
|
||||||
options,
|
|
||||||
(o: CascaderOptionType, level: number) => o[names.value] === unwrappedValue[level],
|
|
||||||
{ childrenKeyName: names.children },
|
|
||||||
);
|
|
||||||
const label = selectedOptions.length ? selectedOptions.map(o => o[names.label]) : value;
|
|
||||||
return displayRender(label, selectedOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
saveInput = (node: Input) => {
|
|
||||||
this.input = node;
|
|
||||||
};
|
|
||||||
|
|
||||||
handleChange = (value: any, selectedOptions: CascaderOptionType[]) => {
|
|
||||||
this.setState({ inputValue: '' });
|
|
||||||
if (selectedOptions[0].__IS_FILTERED_OPTION) {
|
|
||||||
const unwrappedValue =
|
|
||||||
selectedOptions[0][keepFilteredValueField] === undefined
|
|
||||||
? value[0]
|
|
||||||
: selectedOptions[0][keepFilteredValueField];
|
|
||||||
const unwrappedSelectedOptions = selectedOptions[0].path;
|
|
||||||
this.setValue(unwrappedValue, unwrappedSelectedOptions);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.setValue(value, selectedOptions);
|
|
||||||
};
|
|
||||||
|
|
||||||
handlePopupVisibleChange = (popupVisible: boolean) => {
|
|
||||||
if (!('popupVisible' in this.props)) {
|
|
||||||
this.setState(state => ({
|
|
||||||
popupVisible,
|
|
||||||
inputFocused: popupVisible,
|
|
||||||
inputValue: popupVisible ? state.inputValue : '',
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
const { onPopupVisibleChange } = this.props;
|
|
||||||
onPopupVisibleChange?.(popupVisible);
|
|
||||||
};
|
|
||||||
|
|
||||||
handleInputBlur = () => {
|
|
||||||
this.setState({
|
|
||||||
inputFocused: false,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
handleInputClick = (e: React.MouseEvent<HTMLInputElement>) => {
|
|
||||||
const { inputFocused, popupVisible } = this.state;
|
|
||||||
// Prevent `Trigger` behaviour.
|
|
||||||
if (inputFocused || popupVisible) {
|
|
||||||
e.stopPropagation();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
|
||||||
// SPACE => https://github.com/ant-design/ant-design/issues/16871
|
|
||||||
if (e.keyCode === KeyCode.BACKSPACE || e.keyCode === KeyCode.SPACE) {
|
|
||||||
e.stopPropagation();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
||||||
const { popupVisible } = this.state;
|
|
||||||
const inputValue = e.target.value;
|
|
||||||
if (!popupVisible) {
|
|
||||||
this.handlePopupVisibleChange(true);
|
|
||||||
}
|
|
||||||
this.setState({ inputValue });
|
|
||||||
};
|
|
||||||
|
|
||||||
clearSelection = (e: React.MouseEvent<HTMLElement>) => {
|
|
||||||
const { inputValue } = this.state;
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
if (!inputValue) {
|
|
||||||
this.handlePopupVisibleChange(false);
|
|
||||||
this.clearSelectionTimeout = setTimeout(() => {
|
|
||||||
this.setValue([]);
|
|
||||||
}, 200);
|
|
||||||
} else {
|
|
||||||
this.setState({ inputValue: '' });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
generateFilteredOptions(prefixCls: string | undefined, renderEmpty: RenderEmptyHandler) {
|
|
||||||
const { showSearch, notFoundContent } = this.props;
|
|
||||||
const names: FilledFieldNamesType = getFilledFieldNames(this.props);
|
|
||||||
const {
|
|
||||||
filter = defaultFilterOption,
|
|
||||||
render = defaultRenderFilteredOption,
|
|
||||||
sort = defaultSortFilteredOption,
|
|
||||||
limit = defaultLimit,
|
|
||||||
} = showSearch as ShowSearchType;
|
|
||||||
const { flattenOptions = [], inputValue } = this.state;
|
|
||||||
|
|
||||||
// Limit the filter if needed
|
|
||||||
let filtered: Array<CascaderOptionType[]>;
|
|
||||||
if (limit > 0) {
|
|
||||||
filtered = [];
|
|
||||||
let matchCount = 0;
|
|
||||||
|
|
||||||
// Perf optimization to filter items only below the limit
|
|
||||||
flattenOptions.some(path => {
|
|
||||||
const match = filter(this.state.inputValue, path, names);
|
|
||||||
if (match) {
|
|
||||||
filtered.push(path);
|
|
||||||
matchCount += 1;
|
|
||||||
}
|
|
||||||
return matchCount >= limit;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
devWarning(
|
|
||||||
typeof limit !== 'number',
|
|
||||||
'Cascader',
|
|
||||||
"'limit' of showSearch should be positive number or false.",
|
|
||||||
);
|
|
||||||
filtered = flattenOptions.filter(path => filter(this.state.inputValue, path, names));
|
|
||||||
}
|
|
||||||
|
|
||||||
filtered = filtered.sort((a, b) => sort(a, b, inputValue, names));
|
|
||||||
|
|
||||||
if (filtered.length > 0) {
|
|
||||||
// Fix issue: https://github.com/ant-design/ant-design/issues/26554
|
|
||||||
const field = names.value === names.label ? keepFilteredValueField : names.value;
|
|
||||||
|
|
||||||
return filtered.map(
|
|
||||||
(path: CascaderOptionType[]) =>
|
|
||||||
({
|
|
||||||
__IS_FILTERED_OPTION: true,
|
|
||||||
path,
|
|
||||||
[field]: path.map((o: CascaderOptionType) => o[names.value]),
|
|
||||||
[names.label]: render(inputValue, path, prefixCls, names),
|
|
||||||
disabled: path.some((o: CascaderOptionType) => !!o.disabled),
|
|
||||||
isEmptyNode: true,
|
|
||||||
} as CascaderOptionType),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return [getEmptyNode(renderEmpty, names, notFoundContent)];
|
|
||||||
}
|
|
||||||
|
|
||||||
focus() {
|
|
||||||
this.input.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
blur() {
|
|
||||||
this.input.blur();
|
|
||||||
}
|
|
||||||
|
|
||||||
getPopupPlacement(direction: DirectionType = 'ltr') {
|
|
||||||
const { popupPlacement } = this.props;
|
|
||||||
if (popupPlacement !== undefined) {
|
|
||||||
return popupPlacement;
|
|
||||||
}
|
|
||||||
return direction === 'rtl' ? 'bottomRight' : 'bottomLeft';
|
|
||||||
}
|
|
||||||
|
|
||||||
renderCascader = (
|
|
||||||
{
|
|
||||||
getPopupContainer: getContextPopupContainer,
|
|
||||||
getPrefixCls,
|
|
||||||
renderEmpty,
|
|
||||||
direction,
|
|
||||||
}: ConfigConsumerProps,
|
|
||||||
locale: CascaderLocale,
|
|
||||||
) => (
|
|
||||||
<SizeContext.Consumer>
|
|
||||||
{size => {
|
|
||||||
const { props, state } = this;
|
|
||||||
const {
|
|
||||||
prefixCls: customizePrefixCls,
|
|
||||||
inputPrefixCls: customizeInputPrefixCls,
|
|
||||||
children,
|
|
||||||
placeholder = locale.placeholder || 'Please select',
|
|
||||||
size: customizeSize,
|
|
||||||
disabled,
|
|
||||||
className,
|
|
||||||
style,
|
|
||||||
allowClear,
|
|
||||||
showSearch = false,
|
|
||||||
suffixIcon,
|
|
||||||
expandIcon,
|
|
||||||
notFoundContent,
|
|
||||||
popupClassName,
|
|
||||||
bordered,
|
|
||||||
dropdownRender,
|
|
||||||
...otherProps
|
|
||||||
} = props;
|
|
||||||
|
|
||||||
const mergedSize = customizeSize || size;
|
|
||||||
|
|
||||||
const { value, inputFocused } = state;
|
|
||||||
|
|
||||||
const isRtlLayout = direction === 'rtl';
|
|
||||||
|
|
||||||
const prefixCls = getPrefixCls('cascader', customizePrefixCls);
|
|
||||||
const inputPrefixCls = getPrefixCls('input', customizeInputPrefixCls);
|
|
||||||
|
|
||||||
const sizeCls = classNames({
|
|
||||||
[`${inputPrefixCls}-lg`]: mergedSize === 'large',
|
|
||||||
[`${inputPrefixCls}-sm`]: mergedSize === 'small',
|
|
||||||
});
|
|
||||||
const clearIcon =
|
|
||||||
(allowClear && !disabled && value.length > 0) || state.inputValue ? (
|
|
||||||
<CloseCircleFilled
|
|
||||||
className={`${prefixCls}-picker-clear`}
|
|
||||||
onClick={this.clearSelection}
|
|
||||||
/>
|
|
||||||
) : null;
|
|
||||||
const arrowCls = classNames({
|
|
||||||
[`${prefixCls}-picker-arrow`]: true,
|
|
||||||
[`${prefixCls}-picker-arrow-expand`]: state.popupVisible,
|
|
||||||
});
|
|
||||||
const pickerCls = classNames(
|
|
||||||
`${prefixCls}-picker`,
|
|
||||||
{
|
|
||||||
[`${prefixCls}-picker-rtl`]: isRtlLayout,
|
|
||||||
[`${prefixCls}-picker-with-value`]: state.inputValue,
|
|
||||||
[`${prefixCls}-picker-disabled`]: disabled,
|
|
||||||
[`${prefixCls}-picker-${mergedSize}`]: !!mergedSize,
|
|
||||||
[`${prefixCls}-picker-show-search`]: !!showSearch,
|
|
||||||
[`${prefixCls}-picker-focused`]: inputFocused,
|
|
||||||
[`${prefixCls}-picker-borderless`]: !bordered,
|
|
||||||
},
|
|
||||||
className,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Fix bug of https://github.com/facebook/react/pull/5004
|
|
||||||
// and https://fb.me/react-unknown-prop
|
|
||||||
const inputProps = omit(
|
|
||||||
// Not know why these props left
|
|
||||||
otherProps as typeof otherProps & {
|
|
||||||
filterOption: any;
|
|
||||||
renderFilteredOption: any;
|
|
||||||
sortFilteredOption: any;
|
|
||||||
defaultValue: any;
|
|
||||||
},
|
|
||||||
[
|
|
||||||
'onChange',
|
|
||||||
'options',
|
|
||||||
'popupPlacement',
|
|
||||||
'transitionName',
|
|
||||||
'displayRender',
|
|
||||||
'onPopupVisibleChange',
|
|
||||||
'changeOnSelect',
|
|
||||||
'expandTrigger',
|
|
||||||
'popupVisible',
|
|
||||||
'getPopupContainer',
|
|
||||||
'loadData',
|
|
||||||
'filterOption',
|
|
||||||
'renderFilteredOption',
|
|
||||||
'sortFilteredOption',
|
|
||||||
'fieldNames',
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
let { options } = props;
|
|
||||||
const names: FilledFieldNamesType = getFilledFieldNames(this.props);
|
|
||||||
if (options && options.length > 0) {
|
|
||||||
if (state.inputValue) {
|
|
||||||
options = this.generateFilteredOptions(prefixCls, renderEmpty);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
options = [getEmptyNode(renderEmpty, names, notFoundContent)];
|
|
||||||
}
|
|
||||||
// Dropdown menu should keep previous status until it is fully closed.
|
|
||||||
if (!state.popupVisible) {
|
|
||||||
options = this.cachedOptions;
|
|
||||||
} else {
|
|
||||||
this.cachedOptions = options;
|
|
||||||
}
|
|
||||||
|
|
||||||
const dropdownMenuColumnStyle: { width?: number; height?: string } = {};
|
|
||||||
const isNotFound = (options || []).length === 1 && options[0].isEmptyNode;
|
|
||||||
if (isNotFound) {
|
|
||||||
dropdownMenuColumnStyle.height = 'auto'; // Height of one row.
|
|
||||||
}
|
|
||||||
// The default value of `matchInputWidth` is `true`
|
|
||||||
const resultListMatchInputWidth = (showSearch as ShowSearchType).matchInputWidth !== false;
|
|
||||||
if (resultListMatchInputWidth && (state.inputValue || isNotFound) && this.input) {
|
|
||||||
dropdownMenuColumnStyle.width = this.input.input.offsetWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
let inputIcon: React.ReactNode;
|
|
||||||
if (suffixIcon) {
|
|
||||||
inputIcon = replaceElement(
|
|
||||||
suffixIcon,
|
|
||||||
<span className={`${prefixCls}-picker-arrow`}>{suffixIcon}</span>,
|
|
||||||
() => ({
|
|
||||||
className: classNames({
|
|
||||||
[(suffixIcon as any).props.className!]: (suffixIcon as any).props.className,
|
|
||||||
[`${prefixCls}-picker-arrow`]: true,
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
inputIcon = <DownOutlined className={arrowCls} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
const label = this.getLabel();
|
|
||||||
const input: React.ReactElement = children || (
|
|
||||||
<span style={style} className={pickerCls}>
|
|
||||||
<span
|
|
||||||
className={`${prefixCls}-picker-label`}
|
|
||||||
title={typeof label === 'string' && label ? label : undefined}
|
|
||||||
>
|
|
||||||
{label}
|
|
||||||
</span>
|
|
||||||
<Input
|
|
||||||
{...inputProps}
|
|
||||||
tabIndex={-1}
|
|
||||||
ref={this.saveInput}
|
|
||||||
prefixCls={inputPrefixCls}
|
|
||||||
placeholder={value && value.length > 0 ? undefined : placeholder}
|
|
||||||
className={`${prefixCls}-input ${sizeCls}`}
|
|
||||||
value={state.inputValue}
|
|
||||||
disabled={disabled}
|
|
||||||
readOnly={!showSearch}
|
|
||||||
autoComplete={inputProps.autoComplete || 'off'}
|
|
||||||
onClick={showSearch ? this.handleInputClick : undefined}
|
|
||||||
onBlur={showSearch ? this.handleInputBlur : undefined}
|
|
||||||
onKeyDown={this.handleKeyDown}
|
|
||||||
onChange={showSearch ? this.handleInputChange : undefined}
|
|
||||||
/>
|
|
||||||
{clearIcon}
|
|
||||||
{inputIcon}
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
|
|
||||||
let expandIconNode;
|
|
||||||
if (expandIcon) {
|
|
||||||
expandIconNode = expandIcon;
|
|
||||||
} else {
|
|
||||||
expandIconNode = isRtlLayout ? <LeftOutlined /> : <RightOutlined />;
|
|
||||||
}
|
|
||||||
|
|
||||||
const loadingIcon = (
|
|
||||||
<span className={`${prefixCls}-menu-item-loading-icon`}>
|
|
||||||
<RedoOutlined spin />
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
|
|
||||||
const getPopupContainer = props.getPopupContainer || getContextPopupContainer;
|
|
||||||
const rest = omit(props as typeof props & { inputIcon: any; loadingIcon: any }, [
|
|
||||||
'inputIcon',
|
|
||||||
'expandIcon',
|
|
||||||
'loadingIcon',
|
|
||||||
'bordered',
|
|
||||||
'className',
|
|
||||||
]);
|
|
||||||
const rcCascaderPopupClassName = classNames(popupClassName, {
|
|
||||||
[`${prefixCls}-menu-${direction}`]: direction === 'rtl',
|
|
||||||
[`${prefixCls}-menu-empty`]:
|
|
||||||
options.length === 1 && options[0].value === 'ANT_CASCADER_NOT_FOUND',
|
|
||||||
});
|
|
||||||
const rootPrefixCls = getPrefixCls();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<RcCascader
|
|
||||||
{...rest}
|
|
||||||
prefixCls={prefixCls}
|
|
||||||
getPopupContainer={getPopupContainer}
|
|
||||||
options={options}
|
|
||||||
value={value}
|
|
||||||
popupVisible={state.popupVisible}
|
|
||||||
onPopupVisibleChange={this.handlePopupVisibleChange}
|
|
||||||
onChange={this.handleChange}
|
|
||||||
dropdownMenuColumnStyle={dropdownMenuColumnStyle}
|
|
||||||
expandIcon={expandIconNode}
|
|
||||||
loadingIcon={loadingIcon}
|
|
||||||
popupClassName={rcCascaderPopupClassName}
|
|
||||||
popupPlacement={this.getPopupPlacement(direction)}
|
|
||||||
// rc-cascader should update ts define to fix this case
|
|
||||||
dropdownRender={dropdownRender as any}
|
|
||||||
transitionName={getTransitionName(rootPrefixCls, 'slide-up', props.transitionName)}
|
|
||||||
>
|
|
||||||
{input}
|
|
||||||
</RcCascader>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</SizeContext.Consumer>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
render() {
|
// =================== Multiple ====================
|
||||||
return (
|
const checkable = React.useMemo(
|
||||||
<ConfigConsumer>
|
() => (multiple ? <span className={`${cascaderPrefixCls}-checkbox-inner`} /> : false),
|
||||||
{(configArgument: ConfigConsumerProps) => (
|
[multiple],
|
||||||
<LocaleReceiver>{locale => this.renderCascader(configArgument, locale)}</LocaleReceiver>
|
);
|
||||||
)}
|
|
||||||
</ConfigConsumer>
|
// ===================== Icons =====================
|
||||||
);
|
const { suffixIcon, removeIcon, clearIcon } = getIcons({
|
||||||
}
|
...props,
|
||||||
}
|
multiple,
|
||||||
|
prefixCls,
|
||||||
|
});
|
||||||
|
|
||||||
|
// ==================== Render =====================
|
||||||
|
return (
|
||||||
|
<RcCascader
|
||||||
|
prefixCls={prefixCls}
|
||||||
|
className={classNames(
|
||||||
|
!customizePrefixCls && cascaderPrefixCls,
|
||||||
|
{
|
||||||
|
[`${prefixCls}-lg`]: mergedSize === 'large',
|
||||||
|
[`${prefixCls}-sm`]: mergedSize === 'small',
|
||||||
|
[`${prefixCls}-rtl`]: isRtl,
|
||||||
|
[`${prefixCls}-borderless`]: !bordered,
|
||||||
|
},
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...(restProps as any)}
|
||||||
|
direction={mergedDirection}
|
||||||
|
notFoundContent={mergedNotFoundContent}
|
||||||
|
allowClear={allowClear}
|
||||||
|
showSearch={mergedShowSearch}
|
||||||
|
expandIcon={mergedExpandIcon}
|
||||||
|
inputIcon={suffixIcon}
|
||||||
|
removeIcon={removeIcon}
|
||||||
|
clearIcon={clearIcon}
|
||||||
|
loadingIcon={loadingIcon}
|
||||||
|
checkable={checkable}
|
||||||
|
dropdownClassName={mergedDropdownClassName}
|
||||||
|
dropdownPrefixCls={customizePrefixCls || cascaderPrefixCls}
|
||||||
|
choiceTransitionName={getTransitionName(rootPrefixCls, '', choiceTransitionName)}
|
||||||
|
transitionName={getTransitionName(rootPrefixCls, 'slide-up', transitionName)}
|
||||||
|
ref={ref}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
Cascader.displayName = 'Cascader';
|
||||||
|
|
||||||
export default Cascader;
|
export default Cascader;
|
||||||
|
@ -37,18 +37,18 @@ cover: https://gw.alipayobjects.com/zos/alicdn/UdS8y8xyZ/Cascader.svg
|
|||||||
| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。[示例](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | function(triggerNode) | () => document.body | |
|
| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。[示例](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | function(triggerNode) | () => document.body | |
|
||||||
| loadData | 用于动态加载选项,无法与 `showSearch` 一起使用 | (selectedOptions) => void | - | |
|
| loadData | 用于动态加载选项,无法与 `showSearch` 一起使用 | (selectedOptions) => void | - | |
|
||||||
| notFoundContent | 当下拉列表为空时显示的内容 | string | `Not Found` | |
|
| notFoundContent | 当下拉列表为空时显示的内容 | string | `Not Found` | |
|
||||||
|
| open | 控制浮层显隐 | boolean | - | 4.17.0 |
|
||||||
| options | 可选项数据源 | [Option](#Option)\[] | - | |
|
| options | 可选项数据源 | [Option](#Option)\[] | - | |
|
||||||
| placeholder | 输入框占位文本 | string | `请选择` | |
|
| placeholder | 输入框占位文本 | string | `请选择` | |
|
||||||
| popupClassName | 自定义浮层类名 | string | - | |
|
| popupClassName | 自定义浮层类名 | string | - | |
|
||||||
| popupPlacement | 浮层预设位置:`bottomLeft` `bottomRight` `topLeft` `topRight` | string | `bottomLeft` | |
|
| popupPlacement | 浮层预设位置:`bottomLeft` `bottomRight` `topLeft` `topRight` | string | `bottomLeft` | |
|
||||||
| popupVisible | 控制浮层显隐 | boolean | - | |
|
|
||||||
| showSearch | 在选择框中显示搜索框 | boolean \| [Object](#showSearch) | false | |
|
| showSearch | 在选择框中显示搜索框 | boolean \| [Object](#showSearch) | false | |
|
||||||
| size | 输入框大小 | `large` \| `middle` \| `small` | - | |
|
| size | 输入框大小 | `large` \| `middle` \| `small` | - | |
|
||||||
| style | 自定义样式 | CSSProperties | - | |
|
| style | 自定义样式 | CSSProperties | - | |
|
||||||
| suffixIcon | 自定义的选择框后缀图标 | ReactNode | - | |
|
| suffixIcon | 自定义的选择框后缀图标 | ReactNode | - | |
|
||||||
| value | 指定选中项 | string\[] \| number\[] | - | |
|
| value | 指定选中项 | string\[] \| number\[] | - | |
|
||||||
| onChange | 选择完成后的回调 | (value, selectedOptions) => void | - | |
|
| onChange | 选择完成后的回调 | (value, selectedOptions) => void | - | |
|
||||||
| onPopupVisibleChange | 显示/隐藏浮层的回调 | (value) => void | - | |
|
| onDropdownVisibleChange | 显示/隐藏浮层的回调 | (value) => void | - | 4.17.0 |
|
||||||
|
|
||||||
### showSearch
|
### showSearch
|
||||||
|
|
||||||
|
@ -1,172 +1,38 @@
|
|||||||
@import '../../style/themes/index';
|
@import '../../style/themes/index';
|
||||||
@import '../../style/mixins/index';
|
@import '../../style/mixins/index';
|
||||||
@import '../../input/style/mixin';
|
@import '../../input/style/mixin';
|
||||||
|
@import '../../checkbox/style/mixin';
|
||||||
|
|
||||||
@cascader-prefix-cls: ~'@{ant-prefix}-cascader';
|
@cascader-prefix-cls: ~'@{ant-prefix}-cascader';
|
||||||
|
|
||||||
|
.antCheckboxFn(@checkbox-prefix-cls: ~'@{cascader-prefix-cls}-checkbox');
|
||||||
|
|
||||||
.@{cascader-prefix-cls} {
|
.@{cascader-prefix-cls} {
|
||||||
.reset-component();
|
width: 184px;
|
||||||
|
|
||||||
&-input.@{ant-prefix}-input {
|
&-checkbox {
|
||||||
// Keep it static for https://github.com/ant-design/ant-design/issues/16738
|
top: 0;
|
||||||
position: static;
|
margin-right: @padding-xs;
|
||||||
width: 100%;
|
|
||||||
// https://github.com/ant-design/ant-design/issues/17582
|
|
||||||
padding-right: 24px;
|
|
||||||
// Add important to fix https://github.com/ant-design/ant-design/issues/5078
|
|
||||||
// because input.less will compile after cascader.less
|
|
||||||
background-color: transparent !important;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-picker-show-search &-input.@{ant-prefix}-input {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-picker {
|
|
||||||
.reset-component();
|
|
||||||
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
background-color: @cascader-bg;
|
|
||||||
border-radius: @border-radius-base;
|
|
||||||
outline: 0;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: color 0.3s;
|
|
||||||
|
|
||||||
&-with-value &-label {
|
|
||||||
color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-disabled {
|
|
||||||
color: @disabled-color;
|
|
||||||
background: @input-disabled-bg;
|
|
||||||
cursor: not-allowed;
|
|
||||||
.@{cascader-prefix-cls}-input {
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:focus .@{cascader-prefix-cls}-input {
|
|
||||||
.active();
|
|
||||||
}
|
|
||||||
|
|
||||||
&-borderless .@{cascader-prefix-cls}-input {
|
|
||||||
border-color: transparent !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-show-search&-focused {
|
|
||||||
color: @disabled-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-label {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 20px;
|
|
||||||
margin-top: -10px;
|
|
||||||
padding: 0 20px 0 @control-padding-horizontal;
|
|
||||||
overflow: hidden;
|
|
||||||
line-height: 20px;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-clear {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
right: @control-padding-horizontal;
|
|
||||||
z-index: 2;
|
|
||||||
width: 12px;
|
|
||||||
height: 12px;
|
|
||||||
margin-top: -6px;
|
|
||||||
color: @disabled-color;
|
|
||||||
font-size: @font-size-sm;
|
|
||||||
line-height: 12px;
|
|
||||||
background: @component-background;
|
|
||||||
cursor: pointer;
|
|
||||||
opacity: 0;
|
|
||||||
transition: color 0.3s ease, opacity 0.15s ease;
|
|
||||||
&:hover {
|
|
||||||
color: @text-color-secondary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover &-clear {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// arrow
|
|
||||||
&-arrow {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
right: @control-padding-horizontal;
|
|
||||||
z-index: 1;
|
|
||||||
width: 12px;
|
|
||||||
height: 12px;
|
|
||||||
margin-top: -6px;
|
|
||||||
color: @disabled-color;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 12px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://github.com/ant-design/ant-design/pull/12407#issuecomment-424657810
|
|
||||||
&-picker-label:hover + &-input {
|
|
||||||
&:not(.@{cascader-prefix-cls}-picker-disabled &) {
|
|
||||||
.hover();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&-picker-small &-picker-clear,
|
|
||||||
&-picker-small &-picker-arrow {
|
|
||||||
right: @control-padding-horizontal-sm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&-menus {
|
&-menus {
|
||||||
position: absolute;
|
display: flex;
|
||||||
z-index: @zindex-dropdown;
|
flex-wrap: nowrap;
|
||||||
font-size: @cascader-dropdown-font-size;
|
align-items: flex-start;
|
||||||
white-space: nowrap;
|
|
||||||
background: @cascader-menu-bg;
|
|
||||||
border-radius: @border-radius-base;
|
|
||||||
box-shadow: @box-shadow-base;
|
|
||||||
|
|
||||||
ul,
|
&.@{cascader-prefix-cls}-menu-empty {
|
||||||
ol {
|
.@{cascader-prefix-cls}-menu {
|
||||||
margin: 0;
|
width: 100%;
|
||||||
list-style: none;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-empty,
|
|
||||||
&-hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
&.@{ant-prefix}-slide-up-enter.@{ant-prefix}-slide-up-enter-active&-placement-bottomLeft,
|
|
||||||
&.@{ant-prefix}-slide-up-appear.@{ant-prefix}-slide-up-appear-active&-placement-bottomLeft {
|
|
||||||
animation-name: antSlideUpIn;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.@{ant-prefix}-slide-up-enter.@{ant-prefix}-slide-up-enter-active&-placement-topLeft,
|
|
||||||
&.@{ant-prefix}-slide-up-appear.@{ant-prefix}-slide-up-appear-active&-placement-topLeft {
|
|
||||||
animation-name: antSlideDownIn;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.@{ant-prefix}-slide-up-leave.@{ant-prefix}-slide-up-leave-active&-placement-bottomLeft {
|
|
||||||
animation-name: antSlideUpOut;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.@{ant-prefix}-slide-up-leave.@{ant-prefix}-slide-up-leave-active&-placement-topLeft {
|
|
||||||
animation-name: antSlideDownOut;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&-menu {
|
&-menu {
|
||||||
display: inline-block;
|
|
||||||
min-width: 111px;
|
min-width: 111px;
|
||||||
height: 180px;
|
height: 180px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
margin: -@dropdown-edge-child-vertical-padding 0;
|
||||||
padding: @cascader-dropdown-edge-child-vertical-padding 0;
|
padding: @cascader-dropdown-edge-child-vertical-padding 0;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
@ -174,67 +40,62 @@
|
|||||||
border-right: @border-width-base @border-style-base @cascader-menu-border-color-split;
|
border-right: @border-width-base @border-style-base @cascader-menu-border-color-split;
|
||||||
-ms-overflow-style: -ms-autohiding-scrollbar; // https://github.com/ant-design/ant-design/issues/11857
|
-ms-overflow-style: -ms-autohiding-scrollbar; // https://github.com/ant-design/ant-design/issues/11857
|
||||||
|
|
||||||
&:first-child {
|
&-item {
|
||||||
border-radius: @border-radius-base 0 0 @border-radius-base;
|
display: flex;
|
||||||
}
|
flex-wrap: nowrap;
|
||||||
&:last-child {
|
align-items: center;
|
||||||
margin-right: -1px;
|
padding: @cascader-dropdown-vertical-padding @control-padding-horizontal;
|
||||||
border-right-color: transparent;
|
overflow: hidden;
|
||||||
border-radius: 0 @border-radius-base @border-radius-base 0;
|
line-height: @cascader-dropdown-line-height;
|
||||||
}
|
white-space: nowrap;
|
||||||
&:only-child {
|
text-overflow: ellipsis;
|
||||||
border-radius: @border-radius-base;
|
cursor: pointer;
|
||||||
}
|
transition: all 0.3s;
|
||||||
}
|
|
||||||
&-menu-item {
|
|
||||||
padding: @cascader-dropdown-vertical-padding @control-padding-horizontal;
|
|
||||||
overflow: hidden;
|
|
||||||
line-height: @cascader-dropdown-line-height;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.3s;
|
|
||||||
&:hover {
|
|
||||||
background: @item-hover-bg;
|
|
||||||
}
|
|
||||||
&-disabled {
|
|
||||||
color: @disabled-color;
|
|
||||||
cursor: not-allowed;
|
|
||||||
&:hover {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.@{cascader-prefix-cls}-menu-empty & {
|
|
||||||
color: @disabled-color;
|
|
||||||
cursor: default;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
&-active:not(&-disabled) {
|
|
||||||
&,
|
|
||||||
&:hover {
|
|
||||||
font-weight: @select-item-selected-font-weight;
|
|
||||||
background-color: @cascader-item-selected-bg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&-expand {
|
|
||||||
position: relative;
|
|
||||||
padding-right: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-expand &-expand-icon,
|
&:hover {
|
||||||
&-loading-icon {
|
background: @item-hover-bg;
|
||||||
position: absolute;
|
}
|
||||||
right: @control-padding-horizontal;
|
|
||||||
color: @text-color-secondary;
|
|
||||||
font-size: 10px;
|
|
||||||
|
|
||||||
.@{cascader-prefix-cls}-menu-item-disabled& {
|
&-disabled {
|
||||||
color: @disabled-color;
|
color: @disabled-color;
|
||||||
|
cursor: not-allowed;
|
||||||
|
&:hover {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
& &-keyword {
|
.@{cascader-prefix-cls}-menu-empty & {
|
||||||
color: @highlight-color;
|
color: @disabled-color;
|
||||||
|
cursor: default;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-active:not(&-disabled) {
|
||||||
|
&,
|
||||||
|
&:hover {
|
||||||
|
font-weight: @select-item-selected-font-weight;
|
||||||
|
background-color: @cascader-item-selected-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-content {
|
||||||
|
flex: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-expand &-expand-icon,
|
||||||
|
&-loading-icon {
|
||||||
|
margin-left: @padding-xss;
|
||||||
|
color: @text-color-secondary;
|
||||||
|
font-size: 10px;
|
||||||
|
|
||||||
|
.@{cascader-prefix-cls}-menu-item-disabled& {
|
||||||
|
color: @disabled-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-keyword {
|
||||||
|
color: @highlight-color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,4 +3,4 @@ import './index.less';
|
|||||||
|
|
||||||
// style dependencies
|
// style dependencies
|
||||||
import '../../empty/style';
|
import '../../empty/style';
|
||||||
import '../../input/style';
|
import '../../select/style';
|
||||||
|
@ -1,95 +1,17 @@
|
|||||||
@import '../../style/themes/index';
|
@import (reference) './index';
|
||||||
@import '../../style/mixins/index';
|
|
||||||
@import '../../input/style/mixin';
|
|
||||||
|
|
||||||
@cascader-prefix-cls: ~'@{ant-prefix}-cascader';
|
.@{cascader-prefix-cls}-rtl {
|
||||||
@picker-rtl-cls: ~'@{cascader-prefix-cls}-picker-rtl';
|
.@{cascader-prefix-cls}-menu-item {
|
||||||
@menu-rtl-cls: ~'@{cascader-prefix-cls}-menu-rtl';
|
&-expand-icon,
|
||||||
|
|
||||||
.@{cascader-prefix-cls} {
|
|
||||||
&-input.@{ant-prefix}-input {
|
|
||||||
.@{picker-rtl-cls} & {
|
|
||||||
padding-right: @input-padding-horizontal-base;
|
|
||||||
padding-left: 24px;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&-picker {
|
|
||||||
&-rtl {
|
|
||||||
direction: rtl;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-label {
|
|
||||||
.@{picker-rtl-cls} & {
|
|
||||||
padding: 0 @control-padding-horizontal 0 20px;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&-clear {
|
|
||||||
.@{picker-rtl-cls} & {
|
|
||||||
right: auto;
|
|
||||||
left: @control-padding-horizontal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&-arrow {
|
|
||||||
.@{picker-rtl-cls} & {
|
|
||||||
right: auto;
|
|
||||||
left: @control-padding-horizontal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&-picker-small &-picker-clear,
|
|
||||||
&-picker-small &-picker-arrow {
|
|
||||||
.@{picker-rtl-cls}& {
|
|
||||||
right: auto;
|
|
||||||
left: @control-padding-horizontal-sm;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&-menu {
|
|
||||||
&-rtl & {
|
|
||||||
direction: rtl;
|
|
||||||
border-right: none;
|
|
||||||
border-left: @border-width-base @border-style-base @border-color-split;
|
|
||||||
&:first-child {
|
|
||||||
border-radius: 0 @border-radius-base @border-radius-base 0;
|
|
||||||
}
|
|
||||||
&:last-child {
|
|
||||||
margin-right: 0;
|
|
||||||
margin-left: -1px;
|
|
||||||
border-left-color: transparent;
|
|
||||||
border-radius: @border-radius-base 0 0 @border-radius-base;
|
|
||||||
}
|
|
||||||
&:only-child {
|
|
||||||
border-radius: @border-radius-base;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&-menu-item {
|
|
||||||
&-expand {
|
|
||||||
.@{menu-rtl-cls} & {
|
|
||||||
padding-right: @control-padding-horizontal;
|
|
||||||
padding-left: 24px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&-expand &-expand-icon,
|
|
||||||
&-loading-icon {
|
&-loading-icon {
|
||||||
.@{menu-rtl-cls} & {
|
margin-right: @padding-xss;
|
||||||
right: auto;
|
margin-left: 0;
|
||||||
left: @control-padding-horizontal;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&-loading-icon {
|
.@{cascader-prefix-cls}-checkbox {
|
||||||
.@{menu-rtl-cls} & {
|
top: 0;
|
||||||
transform: scaleY(-1);
|
margin-right: 0;
|
||||||
}
|
margin-left: @padding-xs;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9985,231 +9985,339 @@ exports[`ConfigProvider components Carousel prefixCls 1`] = `
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`ConfigProvider components Cascader configProvider 1`] = `
|
exports[`ConfigProvider components Cascader configProvider 1`] = `
|
||||||
<span
|
<div
|
||||||
class="config-cascader-picker config-cascader-picker-show-search"
|
class="config-select config-cascader config-select-single config-select-allow-clear config-select-show-arrow config-select-show-search"
|
||||||
tabindex="0"
|
|
||||||
>
|
>
|
||||||
<span
|
<div
|
||||||
class="config-cascader-picker-label"
|
class="config-select-selector"
|
||||||
/>
|
|
||||||
<input
|
|
||||||
autocomplete="off"
|
|
||||||
class="config-input config-cascader-input "
|
|
||||||
placeholder="Please select"
|
|
||||||
tabindex="-1"
|
|
||||||
type="text"
|
|
||||||
value=""
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
aria-label="down"
|
|
||||||
class="anticon anticon-down config-cascader-picker-arrow"
|
|
||||||
role="img"
|
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
class="config-select-selection-search"
|
||||||
data-icon="down"
|
|
||||||
fill="currentColor"
|
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<input
|
||||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
aria-activedescendant="undefined_list_0"
|
||||||
|
aria-autocomplete="list"
|
||||||
|
aria-controls="undefined_list"
|
||||||
|
aria-haspopup="listbox"
|
||||||
|
aria-owns="undefined_list"
|
||||||
|
autocomplete="off"
|
||||||
|
class="config-select-selection-search-input"
|
||||||
|
role="combobox"
|
||||||
|
type="search"
|
||||||
|
value=""
|
||||||
/>
|
/>
|
||||||
</svg>
|
</span>
|
||||||
|
<span
|
||||||
|
class="config-select-selection-placeholder"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
aria-hidden="true"
|
||||||
|
class="config-select-arrow"
|
||||||
|
style="user-select:none;-webkit-user-select:none"
|
||||||
|
unselectable="on"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-label="down"
|
||||||
|
class="anticon anticon-down config-select-suffix"
|
||||||
|
role="img"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
data-icon="down"
|
||||||
|
fill="currentColor"
|
||||||
|
focusable="false"
|
||||||
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`ConfigProvider components Cascader configProvider componentSize large 1`] = `
|
exports[`ConfigProvider components Cascader configProvider componentSize large 1`] = `
|
||||||
<span
|
<div
|
||||||
class="config-cascader-picker config-cascader-picker-large config-cascader-picker-show-search"
|
class="config-select config-cascader config-select-lg config-select-single config-select-allow-clear config-select-show-arrow config-select-show-search"
|
||||||
tabindex="0"
|
|
||||||
>
|
>
|
||||||
<span
|
<div
|
||||||
class="config-cascader-picker-label"
|
class="config-select-selector"
|
||||||
/>
|
|
||||||
<input
|
|
||||||
autocomplete="off"
|
|
||||||
class="config-input config-input-lg config-cascader-input config-input-lg"
|
|
||||||
placeholder="Please select"
|
|
||||||
tabindex="-1"
|
|
||||||
type="text"
|
|
||||||
value=""
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
aria-label="down"
|
|
||||||
class="anticon anticon-down config-cascader-picker-arrow"
|
|
||||||
role="img"
|
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
class="config-select-selection-search"
|
||||||
data-icon="down"
|
|
||||||
fill="currentColor"
|
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<input
|
||||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
aria-activedescendant="undefined_list_0"
|
||||||
|
aria-autocomplete="list"
|
||||||
|
aria-controls="undefined_list"
|
||||||
|
aria-haspopup="listbox"
|
||||||
|
aria-owns="undefined_list"
|
||||||
|
autocomplete="off"
|
||||||
|
class="config-select-selection-search-input"
|
||||||
|
role="combobox"
|
||||||
|
type="search"
|
||||||
|
value=""
|
||||||
/>
|
/>
|
||||||
</svg>
|
</span>
|
||||||
|
<span
|
||||||
|
class="config-select-selection-placeholder"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
aria-hidden="true"
|
||||||
|
class="config-select-arrow"
|
||||||
|
style="user-select:none;-webkit-user-select:none"
|
||||||
|
unselectable="on"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-label="down"
|
||||||
|
class="anticon anticon-down config-select-suffix"
|
||||||
|
role="img"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
data-icon="down"
|
||||||
|
fill="currentColor"
|
||||||
|
focusable="false"
|
||||||
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`ConfigProvider components Cascader configProvider componentSize middle 1`] = `
|
exports[`ConfigProvider components Cascader configProvider componentSize middle 1`] = `
|
||||||
<span
|
<div
|
||||||
class="config-cascader-picker config-cascader-picker-middle config-cascader-picker-show-search"
|
class="config-select config-cascader config-select-single config-select-allow-clear config-select-show-arrow config-select-show-search"
|
||||||
tabindex="0"
|
|
||||||
>
|
>
|
||||||
<span
|
<div
|
||||||
class="config-cascader-picker-label"
|
class="config-select-selector"
|
||||||
/>
|
|
||||||
<input
|
|
||||||
autocomplete="off"
|
|
||||||
class="config-input config-cascader-input "
|
|
||||||
placeholder="Please select"
|
|
||||||
tabindex="-1"
|
|
||||||
type="text"
|
|
||||||
value=""
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
aria-label="down"
|
|
||||||
class="anticon anticon-down config-cascader-picker-arrow"
|
|
||||||
role="img"
|
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
class="config-select-selection-search"
|
||||||
data-icon="down"
|
|
||||||
fill="currentColor"
|
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<input
|
||||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
aria-activedescendant="undefined_list_0"
|
||||||
|
aria-autocomplete="list"
|
||||||
|
aria-controls="undefined_list"
|
||||||
|
aria-haspopup="listbox"
|
||||||
|
aria-owns="undefined_list"
|
||||||
|
autocomplete="off"
|
||||||
|
class="config-select-selection-search-input"
|
||||||
|
role="combobox"
|
||||||
|
type="search"
|
||||||
|
value=""
|
||||||
/>
|
/>
|
||||||
</svg>
|
</span>
|
||||||
|
<span
|
||||||
|
class="config-select-selection-placeholder"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
aria-hidden="true"
|
||||||
|
class="config-select-arrow"
|
||||||
|
style="user-select:none;-webkit-user-select:none"
|
||||||
|
unselectable="on"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-label="down"
|
||||||
|
class="anticon anticon-down config-select-suffix"
|
||||||
|
role="img"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
data-icon="down"
|
||||||
|
fill="currentColor"
|
||||||
|
focusable="false"
|
||||||
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`ConfigProvider components Cascader configProvider virtual and dropdownMatchSelectWidth 1`] = `
|
exports[`ConfigProvider components Cascader configProvider virtual and dropdownMatchSelectWidth 1`] = `
|
||||||
<span
|
<div
|
||||||
class="ant-cascader-picker ant-cascader-picker-show-search"
|
class="ant-select ant-cascader ant-select-single ant-select-allow-clear ant-select-show-arrow ant-select-show-search"
|
||||||
tabindex="0"
|
|
||||||
>
|
>
|
||||||
<span
|
<div
|
||||||
class="ant-cascader-picker-label"
|
class="ant-select-selector"
|
||||||
/>
|
|
||||||
<input
|
|
||||||
autocomplete="off"
|
|
||||||
class="ant-input ant-cascader-input "
|
|
||||||
placeholder="Please select"
|
|
||||||
tabindex="-1"
|
|
||||||
type="text"
|
|
||||||
value=""
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
aria-label="down"
|
|
||||||
class="anticon anticon-down ant-cascader-picker-arrow"
|
|
||||||
role="img"
|
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
class="ant-select-selection-search"
|
||||||
data-icon="down"
|
|
||||||
fill="currentColor"
|
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<input
|
||||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
aria-activedescendant="undefined_list_0"
|
||||||
|
aria-autocomplete="list"
|
||||||
|
aria-controls="undefined_list"
|
||||||
|
aria-haspopup="listbox"
|
||||||
|
aria-owns="undefined_list"
|
||||||
|
autocomplete="off"
|
||||||
|
class="ant-select-selection-search-input"
|
||||||
|
role="combobox"
|
||||||
|
type="search"
|
||||||
|
value=""
|
||||||
/>
|
/>
|
||||||
</svg>
|
</span>
|
||||||
|
<span
|
||||||
|
class="ant-select-selection-placeholder"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
aria-hidden="true"
|
||||||
|
class="ant-select-arrow"
|
||||||
|
style="user-select:none;-webkit-user-select:none"
|
||||||
|
unselectable="on"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-label="down"
|
||||||
|
class="anticon anticon-down ant-select-suffix"
|
||||||
|
role="img"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
data-icon="down"
|
||||||
|
fill="currentColor"
|
||||||
|
focusable="false"
|
||||||
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`ConfigProvider components Cascader normal 1`] = `
|
exports[`ConfigProvider components Cascader normal 1`] = `
|
||||||
<span
|
<div
|
||||||
class="ant-cascader-picker ant-cascader-picker-show-search"
|
class="ant-select ant-cascader ant-select-single ant-select-allow-clear ant-select-show-arrow ant-select-show-search"
|
||||||
tabindex="0"
|
|
||||||
>
|
>
|
||||||
<span
|
<div
|
||||||
class="ant-cascader-picker-label"
|
class="ant-select-selector"
|
||||||
/>
|
|
||||||
<input
|
|
||||||
autocomplete="off"
|
|
||||||
class="ant-input ant-cascader-input "
|
|
||||||
placeholder="Please select"
|
|
||||||
tabindex="-1"
|
|
||||||
type="text"
|
|
||||||
value=""
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
aria-label="down"
|
|
||||||
class="anticon anticon-down ant-cascader-picker-arrow"
|
|
||||||
role="img"
|
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
class="ant-select-selection-search"
|
||||||
data-icon="down"
|
|
||||||
fill="currentColor"
|
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<input
|
||||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
aria-activedescendant="undefined_list_0"
|
||||||
|
aria-autocomplete="list"
|
||||||
|
aria-controls="undefined_list"
|
||||||
|
aria-haspopup="listbox"
|
||||||
|
aria-owns="undefined_list"
|
||||||
|
autocomplete="off"
|
||||||
|
class="ant-select-selection-search-input"
|
||||||
|
role="combobox"
|
||||||
|
type="search"
|
||||||
|
value=""
|
||||||
/>
|
/>
|
||||||
</svg>
|
</span>
|
||||||
|
<span
|
||||||
|
class="ant-select-selection-placeholder"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
aria-hidden="true"
|
||||||
|
class="ant-select-arrow"
|
||||||
|
style="user-select:none;-webkit-user-select:none"
|
||||||
|
unselectable="on"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-label="down"
|
||||||
|
class="anticon anticon-down ant-select-suffix"
|
||||||
|
role="img"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
data-icon="down"
|
||||||
|
fill="currentColor"
|
||||||
|
focusable="false"
|
||||||
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`ConfigProvider components Cascader prefixCls 1`] = `
|
exports[`ConfigProvider components Cascader prefixCls 1`] = `
|
||||||
<span
|
<div
|
||||||
class="prefix-Cascader-picker prefix-Cascader-picker-show-search"
|
class="prefix-Cascader prefix-Cascader-single prefix-Cascader-allow-clear prefix-Cascader-show-arrow prefix-Cascader-show-search"
|
||||||
tabindex="0"
|
|
||||||
>
|
>
|
||||||
<span
|
<div
|
||||||
class="prefix-Cascader-picker-label"
|
class="prefix-Cascader-selector"
|
||||||
/>
|
|
||||||
<input
|
|
||||||
autocomplete="off"
|
|
||||||
class="ant-input prefix-Cascader-input "
|
|
||||||
placeholder="Please select"
|
|
||||||
tabindex="-1"
|
|
||||||
type="text"
|
|
||||||
value=""
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
aria-label="down"
|
|
||||||
class="anticon anticon-down prefix-Cascader-picker-arrow"
|
|
||||||
role="img"
|
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
class="prefix-Cascader-selection-search"
|
||||||
data-icon="down"
|
|
||||||
fill="currentColor"
|
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<input
|
||||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
aria-activedescendant="undefined_list_0"
|
||||||
|
aria-autocomplete="list"
|
||||||
|
aria-controls="undefined_list"
|
||||||
|
aria-haspopup="listbox"
|
||||||
|
aria-owns="undefined_list"
|
||||||
|
autocomplete="off"
|
||||||
|
class="prefix-Cascader-selection-search-input"
|
||||||
|
role="combobox"
|
||||||
|
type="search"
|
||||||
|
value=""
|
||||||
/>
|
/>
|
||||||
</svg>
|
</span>
|
||||||
|
<span
|
||||||
|
class="prefix-Cascader-selection-placeholder"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
aria-hidden="true"
|
||||||
|
class="prefix-Cascader-arrow"
|
||||||
|
style="user-select:none;-webkit-user-select:none"
|
||||||
|
unselectable="on"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-label="down"
|
||||||
|
class="anticon anticon-down prefix-Cascader-suffix"
|
||||||
|
role="img"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
data-icon="down"
|
||||||
|
fill="currentColor"
|
||||||
|
focusable="false"
|
||||||
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`ConfigProvider components Checkbox configProvider 1`] = `
|
exports[`ConfigProvider components Checkbox configProvider 1`] = `
|
||||||
|
@ -222,42 +222,60 @@ exports[`renders ./components/empty/demo/config-provider.md correctly 1`] = `
|
|||||||
<h4>
|
<h4>
|
||||||
Cascader
|
Cascader
|
||||||
</h4>
|
</h4>
|
||||||
<span
|
<div
|
||||||
class="ant-cascader-picker ant-cascader-picker-show-search"
|
class="ant-select ant-cascader ant-select-single ant-select-allow-clear ant-select-show-arrow ant-select-show-search"
|
||||||
style="width:200px"
|
style="width:200px"
|
||||||
tabindex="0"
|
|
||||||
>
|
>
|
||||||
<span
|
<div
|
||||||
class="ant-cascader-picker-label"
|
class="ant-select-selector"
|
||||||
/>
|
|
||||||
<input
|
|
||||||
autocomplete="off"
|
|
||||||
class="ant-input ant-cascader-input "
|
|
||||||
placeholder="Please select"
|
|
||||||
tabindex="-1"
|
|
||||||
type="text"
|
|
||||||
value=""
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
aria-label="down"
|
|
||||||
class="anticon anticon-down ant-cascader-picker-arrow"
|
|
||||||
role="img"
|
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
class="ant-select-selection-search"
|
||||||
data-icon="down"
|
|
||||||
fill="currentColor"
|
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<input
|
||||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
aria-activedescendant="undefined_list_0"
|
||||||
|
aria-autocomplete="list"
|
||||||
|
aria-controls="undefined_list"
|
||||||
|
aria-haspopup="listbox"
|
||||||
|
aria-owns="undefined_list"
|
||||||
|
autocomplete="off"
|
||||||
|
class="ant-select-selection-search-input"
|
||||||
|
role="combobox"
|
||||||
|
type="search"
|
||||||
|
value=""
|
||||||
/>
|
/>
|
||||||
</svg>
|
</span>
|
||||||
|
<span
|
||||||
|
class="ant-select-selection-placeholder"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
aria-hidden="true"
|
||||||
|
class="ant-select-arrow"
|
||||||
|
style="user-select:none;-webkit-user-select:none"
|
||||||
|
unselectable="on"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-label="down"
|
||||||
|
class="anticon anticon-down ant-select-suffix"
|
||||||
|
role="img"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
data-icon="down"
|
||||||
|
fill="currentColor"
|
||||||
|
focusable="false"
|
||||||
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</div>
|
||||||
<h4>
|
<h4>
|
||||||
Transfer
|
Transfer
|
||||||
</h4>
|
</h4>
|
||||||
|
@ -3430,65 +3430,92 @@ exports[`renders ./components/form/demo/register.md correctly 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="ant-form-item-control-input-content"
|
class="ant-form-item-control-input-content"
|
||||||
>
|
>
|
||||||
<span
|
<div
|
||||||
class="ant-cascader-picker"
|
class="ant-select ant-cascader ant-select-single ant-select-allow-clear ant-select-show-arrow"
|
||||||
tabindex="0"
|
|
||||||
>
|
>
|
||||||
<span
|
<div
|
||||||
class="ant-cascader-picker-label"
|
class="ant-select-selector"
|
||||||
title="Zhejiang / Hangzhou / West Lake"
|
|
||||||
>
|
>
|
||||||
Zhejiang / Hangzhou / West Lake
|
<span
|
||||||
</span>
|
class="ant-select-selection-search"
|
||||||
<input
|
|
||||||
autocomplete="off"
|
|
||||||
class="ant-input ant-cascader-input "
|
|
||||||
id="register_residence"
|
|
||||||
readonly=""
|
|
||||||
tabindex="-1"
|
|
||||||
type="text"
|
|
||||||
value=""
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
aria-label="close-circle"
|
|
||||||
class="anticon anticon-close-circle ant-cascader-picker-clear"
|
|
||||||
role="img"
|
|
||||||
tabindex="-1"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
data-icon="close-circle"
|
|
||||||
fill="currentColor"
|
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<input
|
||||||
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 01-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"
|
aria-activedescendant="register_residence_list_0"
|
||||||
|
aria-autocomplete="list"
|
||||||
|
aria-controls="register_residence_list"
|
||||||
|
aria-haspopup="listbox"
|
||||||
|
aria-owns="register_residence_list"
|
||||||
|
autocomplete="off"
|
||||||
|
class="ant-select-selection-search-input"
|
||||||
|
id="register_residence"
|
||||||
|
readonly=""
|
||||||
|
role="combobox"
|
||||||
|
style="opacity:0"
|
||||||
|
type="search"
|
||||||
|
unselectable="on"
|
||||||
|
value=""
|
||||||
/>
|
/>
|
||||||
</svg>
|
</span>
|
||||||
|
<span
|
||||||
|
class="ant-select-selection-item"
|
||||||
|
title="Zhejiang / Hangzhou / West Lake"
|
||||||
|
>
|
||||||
|
Zhejiang / Hangzhou / West Lake
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
aria-hidden="true"
|
||||||
|
class="ant-select-arrow"
|
||||||
|
style="user-select:none;-webkit-user-select:none"
|
||||||
|
unselectable="on"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-label="down"
|
||||||
|
class="anticon anticon-down ant-select-suffix"
|
||||||
|
role="img"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
data-icon="down"
|
||||||
|
fill="currentColor"
|
||||||
|
focusable="false"
|
||||||
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
aria-label="down"
|
aria-hidden="true"
|
||||||
class="anticon anticon-down ant-cascader-picker-arrow"
|
class="ant-select-clear"
|
||||||
role="img"
|
style="user-select:none;-webkit-user-select:none"
|
||||||
|
unselectable="on"
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
aria-label="close-circle"
|
||||||
data-icon="down"
|
class="anticon anticon-close-circle"
|
||||||
fill="currentColor"
|
role="img"
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<svg
|
||||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
aria-hidden="true"
|
||||||
/>
|
data-icon="close-circle"
|
||||||
</svg>
|
fill="currentColor"
|
||||||
|
focusable="false"
|
||||||
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 01-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -4596,42 +4623,62 @@ exports[`renders ./components/form/demo/size.md correctly 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="ant-form-item-control-input-content"
|
class="ant-form-item-control-input-content"
|
||||||
>
|
>
|
||||||
<span
|
<div
|
||||||
class="ant-cascader-picker ant-cascader-picker-default"
|
class="ant-select ant-cascader ant-select-single ant-select-allow-clear ant-select-show-arrow"
|
||||||
tabindex="0"
|
|
||||||
>
|
>
|
||||||
<span
|
<div
|
||||||
class="ant-cascader-picker-label"
|
class="ant-select-selector"
|
||||||
/>
|
|
||||||
<input
|
|
||||||
autocomplete="off"
|
|
||||||
class="ant-input ant-cascader-input "
|
|
||||||
placeholder="Please select"
|
|
||||||
readonly=""
|
|
||||||
tabindex="-1"
|
|
||||||
type="text"
|
|
||||||
value=""
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
aria-label="down"
|
|
||||||
class="anticon anticon-down ant-cascader-picker-arrow"
|
|
||||||
role="img"
|
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
class="ant-select-selection-search"
|
||||||
data-icon="down"
|
|
||||||
fill="currentColor"
|
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<input
|
||||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
aria-activedescendant="undefined_list_0"
|
||||||
|
aria-autocomplete="list"
|
||||||
|
aria-controls="undefined_list"
|
||||||
|
aria-haspopup="listbox"
|
||||||
|
aria-owns="undefined_list"
|
||||||
|
autocomplete="off"
|
||||||
|
class="ant-select-selection-search-input"
|
||||||
|
readonly=""
|
||||||
|
role="combobox"
|
||||||
|
style="opacity:0"
|
||||||
|
type="search"
|
||||||
|
unselectable="on"
|
||||||
|
value=""
|
||||||
/>
|
/>
|
||||||
</svg>
|
</span>
|
||||||
|
<span
|
||||||
|
class="ant-select-selection-placeholder"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
aria-hidden="true"
|
||||||
|
class="ant-select-arrow"
|
||||||
|
style="user-select:none;-webkit-user-select:none"
|
||||||
|
unselectable="on"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-label="down"
|
||||||
|
class="anticon anticon-down ant-select-suffix"
|
||||||
|
role="img"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
data-icon="down"
|
||||||
|
fill="currentColor"
|
||||||
|
focusable="false"
|
||||||
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -7396,42 +7443,62 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="ant-form-item-control-input-content"
|
class="ant-form-item-control-input-content"
|
||||||
>
|
>
|
||||||
<span
|
<div
|
||||||
class="ant-cascader-picker"
|
class="ant-select ant-cascader ant-select-single ant-select-allow-clear ant-select-show-arrow"
|
||||||
tabindex="0"
|
|
||||||
>
|
>
|
||||||
<span
|
<div
|
||||||
class="ant-cascader-picker-label"
|
class="ant-select-selector"
|
||||||
/>
|
|
||||||
<input
|
|
||||||
autocomplete="off"
|
|
||||||
class="ant-input ant-cascader-input "
|
|
||||||
placeholder="Please select"
|
|
||||||
readonly=""
|
|
||||||
tabindex="-1"
|
|
||||||
type="text"
|
|
||||||
value=""
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
aria-label="down"
|
|
||||||
class="anticon anticon-down ant-cascader-picker-arrow"
|
|
||||||
role="img"
|
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
class="ant-select-selection-search"
|
||||||
data-icon="down"
|
|
||||||
fill="currentColor"
|
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<input
|
||||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
aria-activedescendant="undefined_list_0"
|
||||||
|
aria-autocomplete="list"
|
||||||
|
aria-controls="undefined_list"
|
||||||
|
aria-haspopup="listbox"
|
||||||
|
aria-owns="undefined_list"
|
||||||
|
autocomplete="off"
|
||||||
|
class="ant-select-selection-search-input"
|
||||||
|
readonly=""
|
||||||
|
role="combobox"
|
||||||
|
style="opacity:0"
|
||||||
|
type="search"
|
||||||
|
unselectable="on"
|
||||||
|
value=""
|
||||||
/>
|
/>
|
||||||
</svg>
|
</span>
|
||||||
|
<span
|
||||||
|
class="ant-select-selection-placeholder"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
aria-hidden="true"
|
||||||
|
class="ant-select-arrow"
|
||||||
|
style="user-select:none;-webkit-user-select:none"
|
||||||
|
unselectable="on"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-label="down"
|
||||||
|
class="anticon anticon-down ant-select-suffix"
|
||||||
|
role="img"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
data-icon="down"
|
||||||
|
fill="currentColor"
|
||||||
|
focusable="false"
|
||||||
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span
|
<span
|
||||||
class="ant-form-item-children-icon"
|
class="ant-form-item-children-icon"
|
||||||
|
@ -436,43 +436,65 @@ exports[`renders ./components/input-number/demo/addon.md correctly 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="ant-input-number-group-addon"
|
class="ant-input-number-group-addon"
|
||||||
>
|
>
|
||||||
<span
|
<div
|
||||||
class="ant-cascader-picker"
|
class="ant-select ant-cascader ant-select-single ant-select-allow-clear ant-select-show-arrow"
|
||||||
style="width:150px"
|
style="width:150px"
|
||||||
tabindex="0"
|
|
||||||
>
|
>
|
||||||
<span
|
<div
|
||||||
class="ant-cascader-picker-label"
|
class="ant-select-selector"
|
||||||
/>
|
|
||||||
<input
|
|
||||||
autocomplete="off"
|
|
||||||
class="ant-input ant-cascader-input "
|
|
||||||
placeholder="cascader"
|
|
||||||
readonly=""
|
|
||||||
tabindex="-1"
|
|
||||||
type="text"
|
|
||||||
value=""
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
aria-label="down"
|
|
||||||
class="anticon anticon-down ant-cascader-picker-arrow"
|
|
||||||
role="img"
|
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
class="ant-select-selection-search"
|
||||||
data-icon="down"
|
|
||||||
fill="currentColor"
|
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<input
|
||||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
aria-activedescendant="undefined_list_0"
|
||||||
|
aria-autocomplete="list"
|
||||||
|
aria-controls="undefined_list"
|
||||||
|
aria-haspopup="listbox"
|
||||||
|
aria-owns="undefined_list"
|
||||||
|
autocomplete="off"
|
||||||
|
class="ant-select-selection-search-input"
|
||||||
|
readonly=""
|
||||||
|
role="combobox"
|
||||||
|
style="opacity:0"
|
||||||
|
type="search"
|
||||||
|
unselectable="on"
|
||||||
|
value=""
|
||||||
/>
|
/>
|
||||||
</svg>
|
</span>
|
||||||
|
<span
|
||||||
|
class="ant-select-selection-placeholder"
|
||||||
|
>
|
||||||
|
cascader
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
aria-hidden="true"
|
||||||
|
class="ant-select-arrow"
|
||||||
|
style="user-select:none;-webkit-user-select:none"
|
||||||
|
unselectable="on"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-label="down"
|
||||||
|
class="anticon anticon-down ant-select-suffix"
|
||||||
|
role="img"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
data-icon="down"
|
||||||
|
fill="currentColor"
|
||||||
|
focusable="false"
|
||||||
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-input-number"
|
class="ant-input-number"
|
||||||
|
@ -261,43 +261,65 @@ exports[`renders ./components/input/demo/addon.md correctly 1`] = `
|
|||||||
<span
|
<span
|
||||||
class="ant-input-group-addon"
|
class="ant-input-group-addon"
|
||||||
>
|
>
|
||||||
<span
|
<div
|
||||||
class="ant-cascader-picker"
|
class="ant-select ant-cascader ant-select-single ant-select-allow-clear ant-select-show-arrow"
|
||||||
style="width:150px"
|
style="width:150px"
|
||||||
tabindex="0"
|
|
||||||
>
|
>
|
||||||
<span
|
<div
|
||||||
class="ant-cascader-picker-label"
|
class="ant-select-selector"
|
||||||
/>
|
|
||||||
<input
|
|
||||||
autocomplete="off"
|
|
||||||
class="ant-input ant-cascader-input "
|
|
||||||
placeholder="cascader"
|
|
||||||
readonly=""
|
|
||||||
tabindex="-1"
|
|
||||||
type="text"
|
|
||||||
value=""
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
aria-label="down"
|
|
||||||
class="anticon anticon-down ant-cascader-picker-arrow"
|
|
||||||
role="img"
|
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
class="ant-select-selection-search"
|
||||||
data-icon="down"
|
|
||||||
fill="currentColor"
|
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<input
|
||||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
aria-activedescendant="undefined_list_0"
|
||||||
|
aria-autocomplete="list"
|
||||||
|
aria-controls="undefined_list"
|
||||||
|
aria-haspopup="listbox"
|
||||||
|
aria-owns="undefined_list"
|
||||||
|
autocomplete="off"
|
||||||
|
class="ant-select-selection-search-input"
|
||||||
|
readonly=""
|
||||||
|
role="combobox"
|
||||||
|
style="opacity:0"
|
||||||
|
type="search"
|
||||||
|
unselectable="on"
|
||||||
|
value=""
|
||||||
/>
|
/>
|
||||||
</svg>
|
</span>
|
||||||
|
<span
|
||||||
|
class="ant-select-selection-placeholder"
|
||||||
|
>
|
||||||
|
cascader
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
aria-hidden="true"
|
||||||
|
class="ant-select-arrow"
|
||||||
|
style="user-select:none;-webkit-user-select:none"
|
||||||
|
unselectable="on"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-label="down"
|
||||||
|
class="anticon anticon-down ant-select-suffix"
|
||||||
|
role="img"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
data-icon="down"
|
||||||
|
fill="currentColor"
|
||||||
|
focusable="false"
|
||||||
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
<input
|
<input
|
||||||
class="ant-input"
|
class="ant-input"
|
||||||
@ -690,64 +712,91 @@ Array [
|
|||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>,
|
</div>,
|
||||||
<span
|
<div
|
||||||
class="ant-cascader-picker"
|
class="ant-select ant-cascader ant-select-single ant-select-allow-clear ant-select-show-arrow"
|
||||||
tabindex="0"
|
|
||||||
>
|
>
|
||||||
<span
|
<div
|
||||||
class="ant-cascader-picker-label"
|
class="ant-select-selector"
|
||||||
title="Zhejiang / Hangzhou / West Lake"
|
|
||||||
>
|
>
|
||||||
Zhejiang / Hangzhou / West Lake
|
<span
|
||||||
</span>
|
class="ant-select-selection-search"
|
||||||
<input
|
|
||||||
autocomplete="off"
|
|
||||||
class="ant-input ant-cascader-input "
|
|
||||||
readonly=""
|
|
||||||
tabindex="-1"
|
|
||||||
type="text"
|
|
||||||
value=""
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
aria-label="close-circle"
|
|
||||||
class="anticon anticon-close-circle ant-cascader-picker-clear"
|
|
||||||
role="img"
|
|
||||||
tabindex="-1"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
data-icon="close-circle"
|
|
||||||
fill="currentColor"
|
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<input
|
||||||
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 01-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"
|
aria-activedescendant="undefined_list_0"
|
||||||
|
aria-autocomplete="list"
|
||||||
|
aria-controls="undefined_list"
|
||||||
|
aria-haspopup="listbox"
|
||||||
|
aria-owns="undefined_list"
|
||||||
|
autocomplete="off"
|
||||||
|
class="ant-select-selection-search-input"
|
||||||
|
readonly=""
|
||||||
|
role="combobox"
|
||||||
|
style="opacity:0"
|
||||||
|
type="search"
|
||||||
|
unselectable="on"
|
||||||
|
value=""
|
||||||
/>
|
/>
|
||||||
</svg>
|
</span>
|
||||||
|
<span
|
||||||
|
class="ant-select-selection-item"
|
||||||
|
title="Zhejiang / Hangzhou / West Lake"
|
||||||
|
>
|
||||||
|
Zhejiang / Hangzhou / West Lake
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
aria-hidden="true"
|
||||||
|
class="ant-select-arrow"
|
||||||
|
style="user-select:none;-webkit-user-select:none"
|
||||||
|
unselectable="on"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-label="down"
|
||||||
|
class="anticon anticon-down ant-select-suffix"
|
||||||
|
role="img"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
data-icon="down"
|
||||||
|
fill="currentColor"
|
||||||
|
focusable="false"
|
||||||
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
aria-label="down"
|
aria-hidden="true"
|
||||||
class="anticon anticon-down ant-cascader-picker-arrow"
|
class="ant-select-clear"
|
||||||
role="img"
|
style="user-select:none;-webkit-user-select:none"
|
||||||
|
unselectable="on"
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
aria-label="close-circle"
|
||||||
data-icon="down"
|
class="anticon anticon-close-circle"
|
||||||
fill="currentColor"
|
role="img"
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<svg
|
||||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
aria-hidden="true"
|
||||||
/>
|
data-icon="close-circle"
|
||||||
</svg>
|
fill="currentColor"
|
||||||
|
focusable="false"
|
||||||
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 01-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</span>,
|
</div>,
|
||||||
<div
|
<div
|
||||||
class="ant-picker ant-picker-range"
|
class="ant-picker ant-picker-range"
|
||||||
>
|
>
|
||||||
@ -2390,43 +2439,65 @@ exports[`renders ./components/input/demo/group.md correctly 1`] = `
|
|||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<span
|
<div
|
||||||
class="ant-cascader-picker"
|
class="ant-select ant-cascader ant-select-single ant-select-allow-clear ant-select-show-arrow"
|
||||||
style="width:70%"
|
style="width:70%"
|
||||||
tabindex="0"
|
|
||||||
>
|
>
|
||||||
<span
|
<div
|
||||||
class="ant-cascader-picker-label"
|
class="ant-select-selector"
|
||||||
/>
|
|
||||||
<input
|
|
||||||
autocomplete="off"
|
|
||||||
class="ant-input ant-cascader-input "
|
|
||||||
placeholder="Select Address"
|
|
||||||
readonly=""
|
|
||||||
tabindex="-1"
|
|
||||||
type="text"
|
|
||||||
value=""
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
aria-label="down"
|
|
||||||
class="anticon anticon-down ant-cascader-picker-arrow"
|
|
||||||
role="img"
|
|
||||||
>
|
>
|
||||||
<svg
|
<span
|
||||||
aria-hidden="true"
|
class="ant-select-selection-search"
|
||||||
data-icon="down"
|
|
||||||
fill="currentColor"
|
|
||||||
focusable="false"
|
|
||||||
height="1em"
|
|
||||||
viewBox="64 64 896 896"
|
|
||||||
width="1em"
|
|
||||||
>
|
>
|
||||||
<path
|
<input
|
||||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
aria-activedescendant="undefined_list_0"
|
||||||
|
aria-autocomplete="list"
|
||||||
|
aria-controls="undefined_list"
|
||||||
|
aria-haspopup="listbox"
|
||||||
|
aria-owns="undefined_list"
|
||||||
|
autocomplete="off"
|
||||||
|
class="ant-select-selection-search-input"
|
||||||
|
readonly=""
|
||||||
|
role="combobox"
|
||||||
|
style="opacity:0"
|
||||||
|
type="search"
|
||||||
|
unselectable="on"
|
||||||
|
value=""
|
||||||
/>
|
/>
|
||||||
</svg>
|
</span>
|
||||||
|
<span
|
||||||
|
class="ant-select-selection-placeholder"
|
||||||
|
>
|
||||||
|
Select Address
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
aria-hidden="true"
|
||||||
|
class="ant-select-arrow"
|
||||||
|
style="user-select:none;-webkit-user-select:none"
|
||||||
|
unselectable="on"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-label="down"
|
||||||
|
class="anticon anticon-down ant-select-suffix"
|
||||||
|
role="img"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
data-icon="down"
|
||||||
|
fill="currentColor"
|
||||||
|
focusable="false"
|
||||||
|
height="1em"
|
||||||
|
viewBox="64 64 896 896"
|
||||||
|
width="1em"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
@ -117,7 +117,7 @@
|
|||||||
"copy-to-clipboard": "^3.2.0",
|
"copy-to-clipboard": "^3.2.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"moment": "^2.25.3",
|
"moment": "^2.25.3",
|
||||||
"rc-cascader": "~1.4.0",
|
"rc-cascader": "~2.0.0-alpha.17",
|
||||||
"rc-checkbox": "~2.3.0",
|
"rc-checkbox": "~2.3.0",
|
||||||
"rc-collapse": "~3.1.0",
|
"rc-collapse": "~3.1.0",
|
||||||
"rc-dialog": "~8.6.0",
|
"rc-dialog": "~8.6.0",
|
||||||
|
@ -2,6 +2,7 @@ import glob from 'glob';
|
|||||||
import { render } from 'enzyme';
|
import { render } from 'enzyme';
|
||||||
import MockDate from 'mockdate';
|
import MockDate from 'mockdate';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
import { excludeWarning } from './excludeWarning';
|
||||||
|
|
||||||
type CheerIO = ReturnType<typeof render>;
|
type CheerIO = ReturnType<typeof render>;
|
||||||
type CheerIOElement = CheerIO[0];
|
type CheerIOElement = CheerIO[0];
|
||||||
@ -57,6 +58,8 @@ export default function demoTest(component: string, options: Options = {}) {
|
|||||||
testMethod = test.skip;
|
testMethod = test.skip;
|
||||||
}
|
}
|
||||||
testMethod(`renders ${file} correctly`, () => {
|
testMethod(`renders ${file} correctly`, () => {
|
||||||
|
const errSpy = excludeWarning();
|
||||||
|
|
||||||
MockDate.set(moment('2016-11-22').valueOf());
|
MockDate.set(moment('2016-11-22').valueOf());
|
||||||
const demo = require(`../.${file}`).default; // eslint-disable-line global-require, import/no-dynamic-require
|
const demo = require(`../.${file}`).default; // eslint-disable-line global-require, import/no-dynamic-require
|
||||||
const wrapper = render(demo);
|
const wrapper = render(demo);
|
||||||
@ -66,6 +69,8 @@ export default function demoTest(component: string, options: Options = {}) {
|
|||||||
|
|
||||||
expect(wrapper).toMatchSnapshot();
|
expect(wrapper).toMatchSnapshot();
|
||||||
MockDate.reset();
|
MockDate.reset();
|
||||||
|
|
||||||
|
errSpy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
27
tests/shared/excludeWarning.tsx
Normal file
27
tests/shared/excludeWarning.tsx
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
const originError = console.error;
|
||||||
|
|
||||||
|
/** This function will remove `useLayoutEffect` server side warning. Since it's useless. */
|
||||||
|
export function excludeWarning() {
|
||||||
|
const errorSpy = jest.spyOn(console, 'error').mockImplementation((msg, ...rest) => {
|
||||||
|
if (String(msg).includes('useLayoutEffect does nothing on the server')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
originError(msg, ...rest);
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
errorSpy.mockRestore();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function excludeAllWarning() {
|
||||||
|
let cleanUp: Function;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
cleanUp = excludeWarning();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
cleanUp();
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user