mirror of
https://github.com/ant-design/ant-design.git
synced 2025-06-07 01:13:58 +08:00
Merge branch 'master' into feature-3.7.0
This commit is contained in:
commit
8eb8c686ce
26
.travis.yml
26
.travis.yml
@ -5,20 +5,24 @@ language: node_js
|
||||
node_js:
|
||||
- 8
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- node_modules
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
include:
|
||||
- env: TEST_TYPE=lint
|
||||
- env: REACT=16 TEST_TYPE=test:dist
|
||||
- env: REACT=16 TEST_TYPE=test:lib
|
||||
- env: REACT=16 TEST_TYPE=test:es
|
||||
- env: REACT=16 TEST_TYPE=test:dom
|
||||
- env: REACT=16 TEST_TYPE=test:node
|
||||
- env: REACT=15 TEST_TYPE=test:dist
|
||||
- env: REACT=15 TEST_TYPE=test:lib
|
||||
- env: REACT=15 TEST_TYPE=test:es
|
||||
- env: REACT=15 TEST_TYPE=test:dom
|
||||
- env: REACT=15 TEST_TYPE=test:node
|
||||
- env: TEST_TYPE=lint
|
||||
- env: REACT=16 TEST_TYPE=test:dist
|
||||
- env: REACT=16 TEST_TYPE=test:lib
|
||||
- env: REACT=16 TEST_TYPE=test:es
|
||||
- env: REACT=16 TEST_TYPE=test:dom
|
||||
- env: REACT=16 TEST_TYPE=test:node
|
||||
- env: REACT=15 TEST_TYPE=test:dist
|
||||
- env: REACT=15 TEST_TYPE=test:lib
|
||||
- env: REACT=15 TEST_TYPE=test:es
|
||||
- env: REACT=15 TEST_TYPE=test:dom
|
||||
- env: REACT=15 TEST_TYPE=test:node
|
||||
|
||||
before_script:
|
||||
- scripts/install-react.sh
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
@alert-message-color: @heading-color;
|
||||
@alert-text-color: @text-color;
|
||||
@alert-close-color: @text-color-secondary;
|
||||
|
||||
.@{alert-prefix-cls} {
|
||||
.reset-component;
|
||||
@ -70,7 +71,7 @@
|
||||
cursor: pointer;
|
||||
|
||||
.@{iconfont-css-prefix}-cross {
|
||||
color: @text-color-secondary;
|
||||
color: @alert-close-color;
|
||||
transition: color .3s;
|
||||
&:hover {
|
||||
color: #404040;
|
||||
@ -87,7 +88,7 @@
|
||||
padding: 15px 15px 15px 64px;
|
||||
position: relative;
|
||||
border-radius: @border-radius-base;
|
||||
color: @text-color;
|
||||
color: @alert-text-color;
|
||||
line-height: @line-height-base;
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ import RangeCalendar from 'rc-calendar/lib/RangeCalendar';
|
||||
import RcDatePicker from 'rc-calendar/lib/Picker';
|
||||
import classNames from 'classnames';
|
||||
import Icon from '../icon';
|
||||
import Tag from '../tag';
|
||||
import warning from '../_util/warning';
|
||||
import interopDefault from '../_util/interopDefault';
|
||||
import { RangePickerValue, RangePickerPresetRange } from './interface';
|
||||
@ -211,14 +212,15 @@ export default class RangePicker extends React.Component<any, RangePickerState>
|
||||
const operations = Object.keys(ranges || {}).map((range) => {
|
||||
const value = ranges[range];
|
||||
return (
|
||||
<a
|
||||
<Tag
|
||||
key={range}
|
||||
color="blue"
|
||||
onClick={() => this.handleRangeClick(value)}
|
||||
onMouseEnter={() => this.setState({ hoverValue: value })}
|
||||
onMouseLeave={this.handleRangeMouseLeave}
|
||||
>
|
||||
{range}
|
||||
</a>
|
||||
</Tag>
|
||||
);
|
||||
});
|
||||
const rangeNode = (
|
||||
|
@ -50,7 +50,7 @@ describe('RangePicker', () => {
|
||||
);
|
||||
|
||||
const rangeCalendarWrapper = mount(wrapper.find('Trigger').instance().getComponent());
|
||||
rangeCalendarWrapper.find('.ant-calendar-range-quick-selector a')
|
||||
rangeCalendarWrapper.find('.ant-calendar-range-quick-selector Tag')
|
||||
.simulate('click');
|
||||
expect(render(wrapper.find('Trigger').instance().getComponent()))
|
||||
.toMatchSnapshot();
|
||||
@ -69,7 +69,7 @@ describe('RangePicker', () => {
|
||||
);
|
||||
|
||||
let rangeCalendarWrapper = mount(wrapper.find('Trigger').instance().getComponent());
|
||||
rangeCalendarWrapper.find('.ant-calendar-range-quick-selector a')
|
||||
rangeCalendarWrapper.find('.ant-calendar-range-quick-selector Tag')
|
||||
.simulate('mouseEnter');
|
||||
rangeCalendarWrapper = mount(wrapper.find('Trigger').instance().getComponent());
|
||||
expect(rangeCalendarWrapper.find('.ant-calendar-selected-day').length).toBe(2);
|
||||
@ -152,7 +152,7 @@ describe('RangePicker', () => {
|
||||
/>
|
||||
);
|
||||
wrapper.find('.ant-calendar-picker-input').simulate('click');
|
||||
wrapper.find('.ant-calendar-range-quick-selector a').simulate('click');
|
||||
wrapper.find('.ant-calendar-range-quick-selector Tag').simulate('click');
|
||||
expect(
|
||||
wrapper.find('.ant-calendar-range-picker-input').first().getDOMNode().value
|
||||
).toBe(range[0].format(format));
|
||||
@ -171,7 +171,7 @@ describe('RangePicker', () => {
|
||||
/>
|
||||
);
|
||||
wrapper.find('.ant-calendar-picker-input').simulate('click');
|
||||
wrapper.find('.ant-calendar-range-quick-selector a').simulate('click');
|
||||
wrapper.find('.ant-calendar-range-quick-selector Tag').simulate('click');
|
||||
expect(
|
||||
wrapper.find('.ant-calendar-range-picker-input').first().getDOMNode().value
|
||||
).toBe(range[0].format(format));
|
||||
@ -200,7 +200,7 @@ describe('RangePicker', () => {
|
||||
/>
|
||||
);
|
||||
wrapper.find('.ant-calendar-picker-input').simulate('click');
|
||||
wrapper.find('.ant-calendar-range-quick-selector a').simulate('click');
|
||||
wrapper.find('.ant-calendar-range-quick-selector Tag').simulate('click');
|
||||
expect(handleOk).toBeCalledWith(range);
|
||||
});
|
||||
|
||||
|
@ -2990,9 +2990,12 @@ exports[`RangePicker switch to corresponding month panel when click presetted ra
|
||||
<div
|
||||
class="ant-calendar-footer-extra ant-calendar-range-quick-selector"
|
||||
>
|
||||
<a>
|
||||
<div
|
||||
class="ant-tag ant-tag-blue"
|
||||
data-show="true"
|
||||
>
|
||||
My Birthday
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-calendar-footer-btn"
|
||||
|
@ -36,8 +36,7 @@ import locale from 'antd/lib/date-picker/locale/zh_CN';
|
||||
```jsx
|
||||
// The default locale is en-US, if you want to use other locale, just set locale in entry file globaly.
|
||||
import moment from 'moment';
|
||||
import 'moment/src/locale/zh-cn';
|
||||
// import 'moment/locale/zh-cn'; if you are using webpack 1
|
||||
import 'moment/locale/zh-cn';
|
||||
|
||||
<DatePicker defaultValue={moment('2015-01-01', 'YYYY-MM-DD')} />
|
||||
```
|
||||
|
@ -37,8 +37,7 @@ import locale from 'antd/lib/date-picker/locale/zh_CN';
|
||||
```jsx
|
||||
// 默认语言为 en-US,如果你需要设置其他语言,推荐在入口文件全局设置 locale
|
||||
import moment from 'moment';
|
||||
import 'moment/src/locale/zh-cn';
|
||||
// import 'moment/locale/zh-cn'; if you are using webpack 1
|
||||
mport 'moment/locale/zh-cn';
|
||||
|
||||
<DatePicker defaultValue={moment('2015-01-01', 'YYYY-MM-DD')} />
|
||||
```
|
||||
|
@ -4,3 +4,4 @@ import './index.less';
|
||||
// style dependencies
|
||||
import '../../input/style';
|
||||
import '../../time-picker/style';
|
||||
import '../../tag/style';
|
||||
|
@ -66,6 +66,10 @@ const generateId = (() => {
|
||||
};
|
||||
})();
|
||||
|
||||
const isNumeric = (n: any) => {
|
||||
return !isNaN(parseFloat(n)) && isFinite(n);
|
||||
};
|
||||
|
||||
export default class Sider extends React.Component<SiderProps, SiderState> {
|
||||
static __ANT_LAYOUT_SIDER: any = true;
|
||||
|
||||
@ -191,7 +195,7 @@ export default class Sider extends React.Component<SiderProps, SiderState> {
|
||||
'defaultCollapsed', 'onCollapse', 'breakpoint', 'onBreakpoint']);
|
||||
const rawWidth = this.state.collapsed ? collapsedWidth : width;
|
||||
// use "px" as fallback unit for width
|
||||
const siderWidth = typeof rawWidth === 'number' ? `${rawWidth}px` : String(rawWidth || 0);
|
||||
const siderWidth = isNumeric(rawWidth) ? `${rawWidth}px` : String(rawWidth);
|
||||
// special trigger when collapsedWidth == 0
|
||||
const zeroWidthTrigger = parseFloat(String(collapsedWidth || 0)) === 0 ? (
|
||||
<span onClick={this.toggle} className={`${prefixCls}-zero-width-trigger`}>
|
||||
|
14
components/layout/__tests__/__snapshots__/index.test.js.snap
Normal file
14
components/layout/__tests__/__snapshots__/index.test.js.snap
Normal file
@ -0,0 +1,14 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Layout renders string width correctly 1`] = `
|
||||
<div
|
||||
class="ant-layout-sider ant-layout-sider-dark"
|
||||
style="flex:0 0 200px;max-width:200px;min-width:200px;width:200px"
|
||||
>
|
||||
<div
|
||||
class="ant-layout-sider-children"
|
||||
>
|
||||
Sider
|
||||
</div>
|
||||
</div>
|
||||
`;
|
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import { mount, render } from 'enzyme';
|
||||
import Layout from '..';
|
||||
|
||||
const { Sider, Content } = Layout;
|
||||
@ -69,6 +69,13 @@ describe('Layout', () => {
|
||||
);
|
||||
expect(wrapper.find('.ant-layout-sider').hasClass('ant-layout-sider-light'));
|
||||
});
|
||||
|
||||
it('renders string width correctly', () => {
|
||||
const wrapper = render(
|
||||
<Sider width="200">Sider</Sider>
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Sider onBreakpoint', () => {
|
||||
|
@ -3,7 +3,11 @@
|
||||
&-light {
|
||||
background: @layout-sider-background-light;
|
||||
}
|
||||
&-light > &-trigger {
|
||||
&-light &-trigger {
|
||||
color: @layout-trigger-color-light;
|
||||
background: @layout-trigger-background-light;
|
||||
}
|
||||
&-light &-zero-width-trigger {
|
||||
color: @layout-trigger-color-light;
|
||||
background: @layout-trigger-background-light;
|
||||
}
|
||||
|
@ -14,8 +14,7 @@ title: LocaleProvider
|
||||
```jsx
|
||||
import { LocaleProvider } from 'antd';
|
||||
import fr_FR from 'antd/lib/locale-provider/fr_FR';
|
||||
import 'moment/src/locale/fr';
|
||||
// import 'moment/locale/fr'; if you are using webpack 1
|
||||
import 'moment/locale/fr';
|
||||
|
||||
...
|
||||
|
||||
|
@ -15,9 +15,7 @@ LocaleProvider 使用 React 的 [context](https://facebook.github.io/react/docs/
|
||||
```jsx
|
||||
import { LocaleProvider } from 'antd';
|
||||
import zh_CN from 'antd/lib/locale-provider/zh_CN';
|
||||
import 'moment/src/locale/zh-cn';
|
||||
// import 'moment/locale/zh-cn'; if you are using webpack 1
|
||||
|
||||
import 'moment/locale/zh-cn';
|
||||
...
|
||||
|
||||
return <LocaleProvider locale={zh_CN}><App /></LocaleProvider>;
|
||||
|
@ -14,6 +14,8 @@ export default {
|
||||
filterConfirm: '확인',
|
||||
filterReset: '초기화',
|
||||
emptyText: '데이터 없음',
|
||||
selectAll: '모두 선택',
|
||||
selectInvert: '선택 반전',
|
||||
},
|
||||
Modal: {
|
||||
okText: '확인',
|
||||
|
@ -2746,26 +2746,20 @@ exports[`renders ./components/table/demo/edit-cell.md correctly 1`] = `
|
||||
class="ant-table-tbody"
|
||||
>
|
||||
<tr
|
||||
class="ant-table-row ant-table-row-level-0"
|
||||
class="ant-table-row editable-row ant-table-row-level-0"
|
||||
>
|
||||
<td
|
||||
class=""
|
||||
>
|
||||
<span
|
||||
class="ant-table-row-indent indent-level-0"
|
||||
style="padding-left:0px"
|
||||
/>
|
||||
<div
|
||||
class="editable-cell"
|
||||
class="editable-cell-value-wrap"
|
||||
style="padding-right:24px"
|
||||
>
|
||||
<div
|
||||
style="padding-right:24px"
|
||||
>
|
||||
Edward King 0
|
||||
<i
|
||||
class="anticon anticon-edit editable-cell-icon"
|
||||
/>
|
||||
</div>
|
||||
<span
|
||||
class="ant-table-row-indent indent-level-0"
|
||||
style="padding-left:0px"
|
||||
/>
|
||||
Edward King 0
|
||||
</div>
|
||||
</td>
|
||||
<td
|
||||
@ -2789,26 +2783,20 @@ exports[`renders ./components/table/demo/edit-cell.md correctly 1`] = `
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="ant-table-row ant-table-row-level-0"
|
||||
class="ant-table-row editable-row ant-table-row-level-0"
|
||||
>
|
||||
<td
|
||||
class=""
|
||||
>
|
||||
<span
|
||||
class="ant-table-row-indent indent-level-0"
|
||||
style="padding-left:0px"
|
||||
/>
|
||||
<div
|
||||
class="editable-cell"
|
||||
class="editable-cell-value-wrap"
|
||||
style="padding-right:24px"
|
||||
>
|
||||
<div
|
||||
style="padding-right:24px"
|
||||
>
|
||||
Edward King 1
|
||||
<i
|
||||
class="anticon anticon-edit editable-cell-icon"
|
||||
/>
|
||||
</div>
|
||||
<span
|
||||
class="ant-table-row-indent indent-level-0"
|
||||
style="padding-left:0px"
|
||||
/>
|
||||
Edward King 1
|
||||
</div>
|
||||
</td>
|
||||
<td
|
||||
|
@ -14,60 +14,110 @@ title:
|
||||
Table with editable cells.
|
||||
|
||||
````jsx
|
||||
import { Table, Input, Icon, Button, Popconfirm } from 'antd';
|
||||
import { Table, Input, Button, Popconfirm, Form } from 'antd';
|
||||
|
||||
const FormItem = Form.Item;
|
||||
const EditableContext = React.createContext();
|
||||
|
||||
const EditableRow = ({ form, index, ...props }) => (
|
||||
<EditableContext.Provider value={form}>
|
||||
<tr {...props} />
|
||||
</EditableContext.Provider>
|
||||
);
|
||||
|
||||
const EditableFormRow = Form.create()(EditableRow);
|
||||
|
||||
class EditableCell extends React.Component {
|
||||
state = {
|
||||
value: this.props.value,
|
||||
editable: false,
|
||||
editing: false,
|
||||
}
|
||||
|
||||
handleChange = (e) => {
|
||||
const value = e.target.value;
|
||||
this.setState({ value });
|
||||
}
|
||||
|
||||
check = () => {
|
||||
this.setState({ editable: false });
|
||||
if (this.props.onChange) {
|
||||
this.props.onChange(this.state.value);
|
||||
componentDidMount() {
|
||||
if (this.props.editable) {
|
||||
document.addEventListener('click', this.handleClickOutside, true);
|
||||
}
|
||||
}
|
||||
|
||||
edit = () => {
|
||||
this.setState({ editable: true });
|
||||
componentWillUnmount() {
|
||||
if (this.props.editable) {
|
||||
document.removeEventListener('click', this.handleClickOutside, true);
|
||||
}
|
||||
}
|
||||
|
||||
toggleEdit = () => {
|
||||
const editing = !this.state.editing;
|
||||
this.setState({ editing }, () => {
|
||||
if (editing) {
|
||||
this.input.focus();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
handleClickOutside = (e) => {
|
||||
const { editing } = this.state;
|
||||
if (editing && this.cell !== e.target && !this.cell.contains(e.target)) {
|
||||
this.save();
|
||||
}
|
||||
}
|
||||
|
||||
save = () => {
|
||||
const { record, handleSave } = this.props;
|
||||
this.form.validateFields((error, values) => {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
this.toggleEdit();
|
||||
handleSave({ ...record, ...values });
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { value, editable } = this.state;
|
||||
const { editing } = this.state;
|
||||
const {
|
||||
editable,
|
||||
dataIndex,
|
||||
title,
|
||||
record,
|
||||
index,
|
||||
handleSave,
|
||||
...restProps
|
||||
} = this.props;
|
||||
return (
|
||||
<div className="editable-cell">
|
||||
{
|
||||
editable ? (
|
||||
<Input
|
||||
value={value}
|
||||
onChange={this.handleChange}
|
||||
onPressEnter={this.check}
|
||||
suffix={(
|
||||
<Icon
|
||||
type="check"
|
||||
className="editable-cell-icon-check"
|
||||
onClick={this.check}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
) : (
|
||||
<div style={{ paddingRight: 24 }}>
|
||||
{value || ' '}
|
||||
<Icon
|
||||
type="edit"
|
||||
className="editable-cell-icon"
|
||||
onClick={this.edit}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<td ref={node => (this.cell = node)} {...restProps}>
|
||||
{editable ? (
|
||||
<EditableContext.Consumer>
|
||||
{(form) => {
|
||||
this.form = form;
|
||||
return (
|
||||
editing ? (
|
||||
<FormItem style={{ margin: 0 }}>
|
||||
{form.getFieldDecorator(dataIndex, {
|
||||
rules: [{
|
||||
required: true,
|
||||
message: `${title} is required.`,
|
||||
}],
|
||||
initialValue: record[dataIndex],
|
||||
})(
|
||||
<Input
|
||||
ref={node => (this.input = node)}
|
||||
onPressEnter={this.save}
|
||||
/>
|
||||
)}
|
||||
</FormItem>
|
||||
) : (
|
||||
<div
|
||||
className="editable-cell-value-wrap"
|
||||
style={{ paddingRight: 24 }}
|
||||
onClick={this.toggleEdit}
|
||||
>
|
||||
{restProps.children}
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}}
|
||||
</EditableContext.Consumer>
|
||||
) : restProps.children}
|
||||
</td>
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -79,12 +129,7 @@ class EditableTable extends React.Component {
|
||||
title: 'name',
|
||||
dataIndex: 'name',
|
||||
width: '30%',
|
||||
render: (text, record) => (
|
||||
<EditableCell
|
||||
value={text}
|
||||
onChange={this.onCellChange(record.key, 'name')}
|
||||
/>
|
||||
),
|
||||
editable: true,
|
||||
}, {
|
||||
title: 'age',
|
||||
dataIndex: 'age',
|
||||
@ -98,7 +143,7 @@ class EditableTable extends React.Component {
|
||||
return (
|
||||
this.state.dataSource.length > 1
|
||||
? (
|
||||
<Popconfirm title="Sure to delete?" onConfirm={() => this.onDelete(record.key)}>
|
||||
<Popconfirm title="Sure to delete?" onConfirm={() => this.handleDelete(record.key)}>
|
||||
<a href="javascript:;">Delete</a>
|
||||
</Popconfirm>
|
||||
) : null
|
||||
@ -122,18 +167,7 @@ class EditableTable extends React.Component {
|
||||
};
|
||||
}
|
||||
|
||||
onCellChange = (key, dataIndex) => {
|
||||
return (value) => {
|
||||
const dataSource = [...this.state.dataSource];
|
||||
const target = dataSource.find(item => item.key === key);
|
||||
if (target) {
|
||||
target[dataIndex] = value;
|
||||
this.setState({ dataSource });
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
onDelete = (key) => {
|
||||
handleDelete = (key) => {
|
||||
const dataSource = [...this.state.dataSource];
|
||||
this.setState({ dataSource: dataSource.filter(item => item.key !== key) });
|
||||
}
|
||||
@ -152,15 +186,52 @@ class EditableTable extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
handleSave = (row) => {
|
||||
const newData = [...this.state.dataSource];
|
||||
const index = newData.findIndex(item => row.key === item.key);
|
||||
const item = newData[index];
|
||||
newData.splice(index, 1, {
|
||||
...item,
|
||||
...row,
|
||||
});
|
||||
this.setState({ dataSource: newData });
|
||||
}
|
||||
|
||||
render() {
|
||||
const { dataSource } = this.state;
|
||||
const columns = this.columns;
|
||||
const components = {
|
||||
body: {
|
||||
row: EditableFormRow,
|
||||
cell: EditableCell,
|
||||
},
|
||||
};
|
||||
const columns = this.columns.map((col) => {
|
||||
if (!col.editable) {
|
||||
return col;
|
||||
}
|
||||
return {
|
||||
...col,
|
||||
onCell: record => ({
|
||||
record,
|
||||
editable: col.editable,
|
||||
dataIndex: col.dataIndex,
|
||||
title: col.title,
|
||||
handleSave: this.handleSave,
|
||||
}),
|
||||
};
|
||||
});
|
||||
return (
|
||||
<div>
|
||||
<Button onClick={this.handleAdd} type="primary" style={{ marginBottom: 16 }}>
|
||||
Add a row
|
||||
</Button>
|
||||
<Table bordered dataSource={dataSource} columns={columns} />
|
||||
<Table
|
||||
components={components}
|
||||
rowClassName={() => 'editable-row'}
|
||||
bordered
|
||||
dataSource={dataSource}
|
||||
columns={columns}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -174,26 +245,14 @@ ReactDOM.render(<EditableTable />, mountNode);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.editable-cell-icon,
|
||||
.editable-cell-icon-check {
|
||||
.editable-cell-value-wrap {
|
||||
padding: 5px 12px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.editable-cell-icon {
|
||||
line-height: 14px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 50%;
|
||||
margin-top: -7px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
td:hover .editable-cell-icon {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.editable-cell-icon:hover,
|
||||
.editable-cell-icon-check:hover {
|
||||
color: #108ee9;
|
||||
.editable-row:hover .editable-cell-value-wrap {
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 4px;
|
||||
padding: 4px 11px;
|
||||
}
|
||||
````
|
||||
|
@ -1,164 +1,74 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Tabs tabPosition remove card 1`] = `
|
||||
<Tabs
|
||||
hideAdd={false}
|
||||
prefixCls="ant-tabs"
|
||||
tabBarExtraContent="xxx"
|
||||
tabPosition="left"
|
||||
<div
|
||||
class="ant-tabs ant-tabs-left ant-tabs-vertical ant-tabs-line"
|
||||
>
|
||||
<Tabs
|
||||
className="ant-tabs-vertical ant-tabs-line"
|
||||
destroyInactiveTabPane={false}
|
||||
hideAdd={false}
|
||||
onChange={[Function]}
|
||||
prefixCls="ant-tabs"
|
||||
renderTabBar={[Function]}
|
||||
renderTabContent={[Function]}
|
||||
style={Object {}}
|
||||
tabBarExtraContent="xxx"
|
||||
tabBarPosition="left"
|
||||
tabPosition="left"
|
||||
<div
|
||||
class="ant-tabs-bar"
|
||||
role="tablist"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
className="ant-tabs ant-tabs-left ant-tabs-vertical ant-tabs-line"
|
||||
style={Object {}}
|
||||
class="ant-tabs-nav-container"
|
||||
>
|
||||
<ScrollableInkTabBar
|
||||
activeKey="1"
|
||||
extraContent={
|
||||
<div
|
||||
className="ant-tabs-extra-content"
|
||||
>
|
||||
xxx
|
||||
</div>
|
||||
}
|
||||
inkBarAnimated={true}
|
||||
key="tabBar"
|
||||
onKeyDown={[Function]}
|
||||
onNextClick={[Function]}
|
||||
onPrevClick={[Function]}
|
||||
onTabClick={[Function]}
|
||||
panels={
|
||||
<TabPane
|
||||
placeholder={null}
|
||||
tab="foo"
|
||||
>
|
||||
foo
|
||||
</TabPane>
|
||||
}
|
||||
prefixCls="ant-tabs"
|
||||
scrollAnimated={true}
|
||||
styles={Object {}}
|
||||
tabBarPosition="left"
|
||||
<span
|
||||
class="ant-tabs-tab-prev ant-tabs-tab-btn-disabled"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
<span
|
||||
class="ant-tabs-tab-prev-icon"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="ant-tabs-tab-next ant-tabs-tab-btn-disabled"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
<span
|
||||
class="ant-tabs-tab-next-icon"
|
||||
/>
|
||||
</span>
|
||||
<div
|
||||
class="ant-tabs-nav-wrap"
|
||||
>
|
||||
<div
|
||||
className="ant-tabs-bar"
|
||||
onKeyDown={[Function]}
|
||||
role="tablist"
|
||||
tabIndex="0"
|
||||
class="ant-tabs-nav-scroll"
|
||||
>
|
||||
<div
|
||||
className="ant-tabs-nav-container"
|
||||
key="content"
|
||||
>
|
||||
<span
|
||||
className="ant-tabs-tab-prev ant-tabs-tab-btn-disabled"
|
||||
onClick={null}
|
||||
onTransitionEnd={[Function]}
|
||||
unselectable="unselectable"
|
||||
>
|
||||
<span
|
||||
className="ant-tabs-tab-prev-icon"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
className="ant-tabs-tab-next ant-tabs-tab-btn-disabled"
|
||||
onClick={null}
|
||||
unselectable="unselectable"
|
||||
>
|
||||
<span
|
||||
className="ant-tabs-tab-next-icon"
|
||||
/>
|
||||
</span>
|
||||
<div
|
||||
className="ant-tabs-nav-wrap"
|
||||
>
|
||||
<div
|
||||
className="ant-tabs-nav-scroll"
|
||||
>
|
||||
<div
|
||||
className="ant-tabs-nav ant-tabs-nav-animated"
|
||||
>
|
||||
<div
|
||||
className="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
|
||||
key="inkBar"
|
||||
/>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-selected="true"
|
||||
className="ant-tabs-tab-active ant-tabs-tab"
|
||||
key="1"
|
||||
onClick={[Function]}
|
||||
role="tab"
|
||||
style={
|
||||
Object {
|
||||
"marginRight": undefined,
|
||||
}
|
||||
}
|
||||
>
|
||||
foo
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="ant-tabs-extra-content"
|
||||
key="extra"
|
||||
style={Object {}}
|
||||
>
|
||||
xxx
|
||||
</div>
|
||||
</div>
|
||||
</ScrollableInkTabBar>
|
||||
<TabContent
|
||||
activeKey="1"
|
||||
animated={true}
|
||||
animatedWithMargin={true}
|
||||
destroyInactiveTabPane={false}
|
||||
key="tabContent"
|
||||
onChange={[Function]}
|
||||
prefixCls="ant-tabs"
|
||||
tabBarPosition="left"
|
||||
>
|
||||
<div
|
||||
className="ant-tabs-content ant-tabs-content-animated"
|
||||
style={
|
||||
Object {
|
||||
"marginTop": "0%",
|
||||
}
|
||||
}
|
||||
>
|
||||
<TabPane
|
||||
active={true}
|
||||
destroyInactiveTabPane={false}
|
||||
key="1"
|
||||
placeholder={null}
|
||||
rootPrefixCls="ant-tabs"
|
||||
tab="foo"
|
||||
class="ant-tabs-nav ant-tabs-nav-animated"
|
||||
>
|
||||
<div
|
||||
aria-hidden="false"
|
||||
className="ant-tabs-tabpane ant-tabs-tabpane-active"
|
||||
role="tabpanel"
|
||||
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
|
||||
/>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-selected="true"
|
||||
class="ant-tabs-tab-active ant-tabs-tab"
|
||||
role="tab"
|
||||
>
|
||||
foo
|
||||
</div>
|
||||
</TabPane>
|
||||
</div>
|
||||
</div>
|
||||
</TabContent>
|
||||
</div>
|
||||
</div>
|
||||
</Tabs>
|
||||
</Tabs>
|
||||
<div
|
||||
class="ant-tabs-extra-content"
|
||||
>
|
||||
xxx
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tabs-content ant-tabs-content-animated"
|
||||
style="margin-top:0%"
|
||||
>
|
||||
<div
|
||||
aria-hidden="false"
|
||||
class="ant-tabs-tabpane ant-tabs-tabpane-active"
|
||||
role="tabpanel"
|
||||
>
|
||||
foo
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import { mount, render } from 'enzyme';
|
||||
import Tabs from '..';
|
||||
|
||||
const { TabPane } = Tabs;
|
||||
@ -31,7 +31,7 @@ describe('Tabs', () => {
|
||||
|
||||
describe('tabPosition', () => {
|
||||
it('remove card', () => {
|
||||
const wrapper = mount(
|
||||
const wrapper = render(
|
||||
<Tabs tabPosition="left" tabBarExtraContent="xxx">
|
||||
<TabPane tab="foo" key="1">foo</TabPane>
|
||||
</Tabs>
|
||||
|
@ -77,6 +77,8 @@ export interface TreeProps {
|
||||
checkStrictly?: boolean;
|
||||
/** 是否支持选中 */
|
||||
checkable?: boolean;
|
||||
/** 是否禁用树 */
|
||||
disabled?: boolean;
|
||||
/** 默认展开所有树节点 */
|
||||
defaultExpandAll?: boolean;
|
||||
/** 默认展开对应树节点 */
|
||||
|
@ -268,9 +268,9 @@ We have completed a simple application, but you may still have lots of questions
|
||||
|
||||
You can:
|
||||
|
||||
- Visit [dva official website](https://github.com/dvajs/dva).
|
||||
- Be familiar with the [8 Concepts](https://github.com/dvajs/dva/blob/master/docs/Concepts.md), and understand how they are connected together
|
||||
- Know all [dva APIs](https://github.com/dvajs/dva/blob/master/docs/API.md)
|
||||
- Checkout [dva knowledgemap](https://github.com/dvajs/dva-knowledgemap), including all the basic knowledge with ES6, React, dva
|
||||
- Visit [dva official website](https://dvajs.com/).
|
||||
- Be familiar with the [8 Concepts](https://dvajs.com/guide/concepts.html), and understand how they are connected together
|
||||
- Know all [dva APIs](https://dvajs.com/api/)
|
||||
- Checkout [dva knowledgemap](https://dvajs.com/knowledgemap/), including all the basic knowledge with ES6, React, dva
|
||||
- Checkout [more FAQ](https://github.com/dvajs/dva/issues?q=is%3Aissue+is%3Aclosed+label%3Afaq)
|
||||
- If your project is created with [dva-cli](https://github.com/dvajs/dva-cli) , checkout how to [Configure it](https://github.com/sorrycc/roadhog#configuration)
|
||||
|
@ -270,9 +270,9 @@ File sizes after gzip:
|
||||
|
||||
你可以:
|
||||
|
||||
- 访问 [dva 官网](https://github.com/dvajs/dva)
|
||||
- 理解 dva 的 [8 个概念](https://github.com/dvajs/dva/blob/master/docs/Concepts_zh-CN.md) ,以及他们是如何串起来的
|
||||
- 掌握 dva 的[所有 API](https://github.com/dvajs/dva/blob/master/docs/API_zh-CN.md)
|
||||
- 查看 [dva 知识地图](https://github.com/dvajs/dva-knowledgemap) ,包含 ES6, React, dva 等所有基础知识
|
||||
- 访问 [dva 官网](https://dvajs.com/)
|
||||
- 理解 dva 的 [8 个概念](https://dvajs.com/guide/concepts.html) ,以及他们是如何串起来的
|
||||
- 掌握 dva 的[所有 API](https://dvajs.com/api/)
|
||||
- 查看 [dva 知识地图](https://dvajs.com/knowledgemap/) ,包含 ES6, React, dva 等所有基础知识
|
||||
- 查看 [更多 FAQ](https://github.com/dvajs/dva/issues?q=is%3Aissue+is%3Aclosed+label%3Afaq),看看别人通常会遇到什么问题
|
||||
- 如果你基于 dva-cli 创建项目,最好了解他的 [配置方式](https://github.com/sorrycc/roadhog/blob/master/README_zh-cn.md#配置)
|
||||
|
@ -90,11 +90,11 @@ $ yarn add react-app-rewired --dev
|
||||
```diff
|
||||
/* package.json */
|
||||
"scripts": {
|
||||
- "start": "react-scripts start",
|
||||
- "start": "react-scripts-ts start",
|
||||
+ "start": "react-app-rewired start --scripts-version react-scripts-ts",
|
||||
- "build": "react-scripts build",
|
||||
- "build": "react-scripts-ts build",
|
||||
+ "build": "react-app-rewired build --scripts-version react-scripts-ts",
|
||||
- "test": "react-scripts test --env=jsdom",
|
||||
- "test": "react-scripts-ts test --env=jsdom",
|
||||
+ "test": "react-app-rewired test --env=jsdom --scripts-version react-scripts-ts",
|
||||
}
|
||||
```
|
||||
|
@ -89,11 +89,11 @@ $ yarn add react-app-rewired --dev
|
||||
```diff
|
||||
/* package.json */
|
||||
"scripts": {
|
||||
- "start": "react-scripts start",
|
||||
- "start": "react-scripts-ts start",
|
||||
+ "start": "react-app-rewired start --scripts-version react-scripts-ts",
|
||||
- "build": "react-scripts build",
|
||||
- "build": "react-scripts-ts build",
|
||||
+ "build": "react-app-rewired build --scripts-version react-scripts-ts",
|
||||
- "test": "react-scripts test --env=jsdom",
|
||||
- "test": "react-scripts-ts test --env=jsdom",
|
||||
+ "test": "react-app-rewired test --env=jsdom --scripts-version react-scripts-ts",
|
||||
}
|
||||
```
|
||||
|
11
tests/__mocks__/react.js
vendored
Normal file
11
tests/__mocks__/react.js
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
const React = require.requireActual('react');
|
||||
|
||||
if (!React.createContext) {
|
||||
React.createContext = () => {
|
||||
const Provider = ({ children }) => children;
|
||||
const Consumer = ({ children }) => children();
|
||||
return { Provider, Consumer };
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = React;
|
Loading…
Reference in New Issue
Block a user