Merge branch 'feature' into tree-select-showSearch

This commit is contained in:
zombiej 2019-04-08 22:23:16 +08:00
commit 58768b90f6
12 changed files with 87 additions and 41 deletions

1
.npmignore Normal file
View File

@ -0,0 +1 @@
~*

View File

@ -62,20 +62,23 @@ export interface BaseButtonProps {
children?: React.ReactNode;
}
// Typescript will make optional not optional if use Pick with union.
// Should change to `AnchorButtonProps | NativeButtonProps` and `any` to `HTMLAnchorElement | HTMLButtonElement` if it fixed.
// ref: https://github.com/ant-design/ant-design/issues/15930
export type AnchorButtonProps = {
href: string;
target?: string;
onClick?: React.MouseEventHandler<HTMLAnchorElement>;
onClick?: React.MouseEventHandler<any>;
} & BaseButtonProps &
Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, 'type'>;
Omit<React.AnchorHTMLAttributes<any>, 'type'>;
export type NativeButtonProps = {
htmlType?: ButtonHTMLType;
onClick?: React.MouseEventHandler<HTMLButtonElement>;
onClick?: React.MouseEventHandler<any>;
} & BaseButtonProps &
Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'type'>;
Omit<React.ButtonHTMLAttributes<any>, 'type'>;
export type ButtonProps = AnchorButtonProps | NativeButtonProps;
export type ButtonProps = Partial<AnchorButtonProps & NativeButtonProps>;
interface ButtonState {
loading?: boolean | { delay?: number };

View File

@ -7,6 +7,8 @@ import { selectDate, openPanel, clearInput, nextYear, nextMonth, hasSelected } f
import focusTest from '../../../tests/shared/focusTest';
describe('DatePicker', () => {
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
focusTest(DatePicker);
beforeEach(() => {
@ -15,6 +17,11 @@ describe('DatePicker', () => {
afterEach(() => {
MockDate.reset();
errorSpy.mockReset();
});
afterAll(() => {
errorSpy.mockRestore();
});
it('support name prop', () => {
@ -210,4 +217,22 @@ describe('DatePicker', () => {
wrapper.find('.ant-calendar-input').simulate('change', { target: { value: '02/07/18' } });
expect(wrapper.find('.ant-calendar-picker-input').getDOMNode().value).toBe('02/07/2018');
});
describe('warning use if use invalidate moment', () => {
const invalidateTime = moment('I AM INVALIDATE');
it('defaultValue', () => {
mount(<DatePicker defaultValue={invalidateTime} />);
expect(errorSpy).toHaveBeenCalledWith(
'Warning: [antd: DatePicker] `defaultValue` provides invalidate moment time. If you want to set empty value, use `null` instead.',
);
});
it('value', () => {
mount(<DatePicker value={invalidateTime} />);
expect(errorSpy).toHaveBeenCalledWith(
'Warning: [antd: DatePicker] `value` provides invalidate moment time. If you want to set empty value, use `null` instead.',
);
});
});
});

View File

@ -1,10 +1,13 @@
import * as React from 'react';
import { polyfill } from 'react-lifecycles-compat';
import TimePickerPanel from 'rc-time-picker/lib/Panel';
import classNames from 'classnames';
import * as moment from 'moment';
import enUS from './locale/en_US';
import LocaleReceiver from '../locale-provider/LocaleReceiver';
import { generateShowHourMinuteSecond } from '../time-picker';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import warning from '../_util/warning';
type PickerType = 'date' | 'week' | 'month';
@ -43,8 +46,21 @@ function getColumns({ showHour, showMinute, showSecond, use12Hours }: any) {
return column;
}
function checkValidate(value: any, propName: string) {
const values: any[] = Array.isArray(value) ? value : [value];
values.forEach(val => {
if (!val) return;
warning(
!moment.isMoment(val) || val.isValid(),
'DatePicker',
`\`${propName}\` provides invalidate moment time. If you want to set empty value, use \`null\` instead.`,
);
});
}
export default function wrapPicker(Picker: React.ComponentClass<any>, pickerType: PickerType): any {
return class PickerWrapper extends React.Component<any, any> {
class PickerWrapper extends React.Component<any, any> {
static defaultProps = {
transitionName: 'slide-up',
popupStyle: {},
@ -54,6 +70,15 @@ export default function wrapPicker(Picker: React.ComponentClass<any>, pickerType
locale: {},
};
static getDerivedStateFromProps({ value, defaultValue }: any) {
checkValidate(defaultValue, 'defaultValue');
checkValidate(value, 'value');
return {};
}
// Since we need call `getDerivedStateFromProps` for check. Need leave an empty `state` here.
state = {};
private picker: any;
componentDidMount() {
@ -199,5 +224,8 @@ export default function wrapPicker(Picker: React.ComponentClass<any>, pickerType
</LocaleReceiver>
);
}
};
}
polyfill(PickerWrapper);
return PickerWrapper;
}

View File

@ -304,8 +304,7 @@ export default class FormItem extends React.Component<FormItemProps, any> {
// Resolve duplicated ids bug between different forms
// https://github.com/ant-design/ant-design/issues/7351
onLabelClick = (e: any) => {
const { label } = this.props;
onLabelClick = () => {
const id = this.props.id || this.getId();
if (!id) {
return;
@ -313,17 +312,8 @@ export default class FormItem extends React.Component<FormItemProps, any> {
const formItemNode = ReactDOM.findDOMNode(this) as Element;
const control = formItemNode.querySelector(`[id="${id}"]`) as HTMLElement;
if (control) {
// Only prevent in default situation
// Avoid preventing event in `label={<a href="xx">link</a>}``
if (typeof label === 'string') {
e.preventDefault();
}
if (control.focus) {
control.focus();
}
if (control && control.focus) {
control.focus();
}
};

View File

@ -9,10 +9,6 @@ Semantic vector graphics.
## List of icons
> Click the icon and copy the code.
We are still adding two-tone icons right now.
```__react
import IconDisplay from 'site/theme/template/IconDisplay';
ReactDOM.render(<IconDisplay />, mountNode);

View File

@ -14,10 +14,6 @@ toc: false
## 图标列表
> 点击图标即可复制代码。
新版图标可能略有缺失,我们还在持续补充中。
```__react
import IconDisplay from 'site/theme/template/IconDisplay';
ReactDOM.render(<IconDisplay />, mountNode);

View File

@ -218,8 +218,14 @@
position: absolute;
width: 6px;
height: 1.5px;
// background + background-image to makes before & after cross have same color.
// Since `linear-gradient` not work on IE9, we should hack it.
// ref: https://github.com/ant-design/ant-design/issues/15910
background: @menu-bg;
background: ~'@{menu-item-color} \9';
background-image: linear-gradient(to right, @menu-item-color, @menu-item-color);
background-image: ~'none \9';
border-radius: 2px;
transition: background 0.3s @ease-in-out, transform 0.3s @ease-in-out,
top 0.3s @ease-in-out;

View File

@ -18,6 +18,9 @@
"contributors": [
"ant"
],
"publishConfig": {
"registry": "https://registry.npmjs.org/"
},
"repository": {
"type": "git",
"url": "https://github.com/ant-design/ant-design"

View File

@ -104,7 +104,7 @@ module.exports = {
'app.publish.old-version-guide': 'If you need documentation of older version, please visit ',
'app.publish.old-version-tips': ', or switch version with the select at header navigation.',
'app.docs.color.pick-primary': 'Pick your primary color',
'app.docs.components.icon.pick-theme': 'Select the Icon Theme',
'app.docs.components.icon.search.placeholder': 'Search icon here, click icon to copy code',
'app.docs.components.icon.outlined': 'Outlined',
'app.docs.components.icon.filled': 'Filled',
'app.docs.components.icon.two-tone': 'Two Tone',

View File

@ -18,11 +18,6 @@ interface IconDisplayState {
}
class IconDisplay extends React.Component<IconDisplayProps, IconDisplayState> {
constructor(props: IconDisplayProps) {
super(props);
this.handleSearchIcon = debounce(this.handleSearchIcon, 300);
}
static categories: Categories = categories;
static newIconNames: string[] = [];
@ -38,6 +33,11 @@ class IconDisplay extends React.Component<IconDisplayProps, IconDisplayState> {
searchKey: '',
};
constructor(props: IconDisplayProps) {
super(props);
this.handleSearchIcon = debounce(this.handleSearchIcon, 300);
}
getComputedDisplayList() {
return Object.keys(IconDisplay.categories)
.map((category: CategoriesKeys) => ({
@ -89,8 +89,7 @@ class IconDisplay extends React.Component<IconDisplayProps, IconDisplayState> {
} = this.props;
const list = this.getComputedDisplayList();
return (
<div>
<h3>{messages['app.docs.components.icon.pick-theme']}</h3>
<>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<Radio.Group value={this.state.theme} onChange={this.handleChangeTheme} size="large">
<Radio.Button value="outlined">
@ -103,18 +102,17 @@ class IconDisplay extends React.Component<IconDisplayProps, IconDisplayState> {
<Icon component={TwoToneIcon} /> {messages['app.docs.components.icon.two-tone']}
</Radio.Button>
</Radio.Group>
<Input.Search
placeholder="icon name"
placeholder={messages['app.docs.components.icon.search.placeholder']}
style={{ marginLeft: 10, flex: 1 }}
allowClear
onChange={e => this.handleSearchIcon(e.currentTarget.value)}
size="large"
autoFocus
/>
</div>
{this.renderCategories(list)}
</div>
</>
);
}
}

View File

@ -101,7 +101,7 @@ module.exports = {
'app.publish.old-version-guide': '如果您还需要使用旧版,请查阅 ',
'app.publish.old-version-tips': ',也可通过页面右上角的文档版本选择框进行切换。',
'app.docs.color.pick-primary': '选择你的主色',
'app.docs.components.icon.pick-theme': '选择图标主题风格',
'app.docs.components.icon.search.placeholder': '在此搜索图标,点击图标可复制代码',
'app.docs.components.icon.outlined': '线框风格',
'app.docs.components.icon.filled': '实底风格',
'app.docs.components.icon.two-tone': '双色风格',