diff --git a/.eslintrc.js b/.eslintrc.js index e2f3c0ec5d..93b5d49312 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -63,6 +63,7 @@ if (process.env.RUN_ENV === 'DEMO') { 'eol-last': 0, 'prefer-rest-params': 0, 'react/no-multi-comp': 0, + 'react/prefer-stateless-function': 0, 'jsx-a11y/href-no-hash': 0, 'import/newline-after-import': 0, }); diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index aa409ddba7..a99277c711 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,3 +1,7 @@ + + diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md index 05b878ee2e..45663296a5 100644 --- a/CHANGELOG.en-US.md +++ b/CHANGELOG.en-US.md @@ -14,7 +14,28 @@ timeline: true * Major version release is not included in this schedule for breaking change and new features. --- +## 3.3.2 +`2018-03-24` + +- 🐞 `Carousel`: Upgrade `react-slick` version to fix width calculation. [#3659](https://github.com/ant-design/ant-design/issues/3659) +- 💄 `Rate`: Adjust `disabled` style. [#9747](https://github.com/ant-design/ant-design/issues/9747) +- 💄 `Modal`: Adjust `confirm-modal` style to fix multiple line display issue. [#9374](https://github.com/ant-design/ant-design/issues/9374) +- 💄 `Menu`: Adjust style to fix mouse trigger event region. [#9666](https://github.com/ant-design/ant-design/pull/9666) [@dgeibi](https://github.com/dgeibi) +- 🐞 `Upload`: Fix type of `file` on `beforeUpload` function. [#9775](https://github.com/ant-design/ant-design/issues/9775) +- 🐞 `Button`: Fix `two-chinese-words` space not re-calculate when text changed. [4502ad8](https://github.com/ant-design/ant-design/commit/4502ad8376e536c450fa4f27d2a5855be5a153e7) + +## 3.3.1 + +`2018-03-18` + +- 💄 Tweak danger button focus style. +- 🐞 Fix a show error when the value of enterButton is a button element. [#9639](https://github.com/ant-design/ant-design/issues/9639) +- 🐞 Fix missing key of `column.title` in Table .[#9658](https://github.com/ant-design/ant-design/issues/9658) [@terence55](https://github.com/terence55) +- 🐞 Fix `scroll: { x: true }` not working if `.ant-table-scroll table` width is `auto`. [#9704](https://github.com/ant-design/ant-design/pull/9704) +- 🐞 Fix when the helper message disappears, the input box will shake. [#8831](https://github.com/ant-design/ant-design/issues/8831) +- 🐞 Fix isMoment call in `TimePicker` will report error in parcel. [85c78e4](https://github.com/ant-design/ant-design/commit/85c78e49a91737c2841dc42621db21ca248b62b4) +- 🐞 Tweak `Table` border radius. [#9674](https://github.com/ant-design/ant-design/pull/9674) ## 3.3.0 `2018-03-12` diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index 9c1a7d3595..4e4f6449a5 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -14,6 +14,28 @@ timeline: true * 主版本号:含有破坏性更新和新特性,不在发布周期内。 --- +## 3.3.2 + +`2018-03-24` + +- 🐞 `Carousel`: 升级 `react-slick` 版本以修复宽度计算错误。 [#3659](https://github.com/ant-design/ant-design/issues/3659) +- 💄 `Rate`: 调整 `disabled` 样式。 [#9747](https://github.com/ant-design/ant-design/issues/9747) +- 💄 `Modal`: 调整 `confirm-modal` 样式以修复标题多行展示问题。 [#9374](https://github.com/ant-design/ant-design/issues/9374) +- 💄 `Menu`: 调整样式以修复鼠标事件范围。[#9666](https://github.com/ant-design/ant-design/pull/9666) [@dgeibi](https://github.com/dgeibi) +- 🐞 `Upload`: 修复 `beforeUpload` 的 `file` 类型错误。 [#9775](https://github.com/ant-design/ant-design/issues/9775) +- 🐞 `Button`: 修复文本改变时,空格插入没有重新计算 [4502ad8](https://github.com/ant-design/ant-design/commit/4502ad8376e536c450fa4f27d2a5855be5a153e7) + +## 3.3.1 + +`2018-03-18` + +- 💄 调整 danger Button 的 `focus` 样式。 +- 🐞 修复 enterButton 的值为 button 元素时显示错误的问题。 [#9639](https://github.com/ant-design/ant-design/issues/9639) +- 🐞 修复 Table 中的 `column.title` 的缺少 key 的问题。 [#9658](https://github.com/ant-design/ant-design/issues/9658) [@terence55](https://github.com/terence55) +- 🐞 修复 `scroll: { x: true }` 在 `.ant-table-scroll table`宽度为 `auto`的情况下不工作的问题。[#9704](https://github.com/ant-design/ant-design/pull/9704) +- 🐞 修复表单校验文字消失的时候输入框会抖一下的问题。 [#8831](https://github.com/ant-design/ant-design/issues/8831) +- 🐞 修复 `TimePicker` 里的 isMoment 调用在 parcel 里会报错的问题。[85c78e4](https://github.com/ant-design/ant-design/commit/85c78e49a91737c2841dc42621db21ca248b62b4) +- 💄 调整 Table 的圆角样式。 [#9674](https://github.com/ant-design/ant-design/pull/9674) ## 3.3.0 diff --git a/README-zh_CN.md b/README-zh_CN.md index d1404dddef..7ac74ca806 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -11,7 +11,7 @@ [![Dependency Status](https://img.shields.io/gemnasium/react-component/trigger.svg?style=flat-square)](https://gemnasium.com/ant-design/ant-design) [![npm package](https://img.shields.io/npm/v/antd.svg?style=flat-square)](https://www.npmjs.org/package/antd) -[![NPM downloads](http://img.shields.io/npm/dm/antd.svg?style=flat-square)](https://npmjs.org/package/antd) +[![NPM downloads](http://img.shields.io/npm/dm/antd.svg?style=flat-square)](http://www.npmtrends.com/antd) [![Percentage of issues still open](http://isitmaintained.com/badge/open/ant-design/ant-design.svg)](http://isitmaintained.com/project/ant-design/ant-design "Percentage of issues still open") [![Gitter](https://badges.gitter.im/ant-design/ant-design-english.svg)](https://gitter.im/ant-design/ant-design-english?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) (English) [![Join the chat at https://gitter.im/ant-design/ant-design](https://img.shields.io/gitter/room/ant-design/ant-design.svg?style=flat-square)](https://gitter.im/ant-design/ant-design?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)(中文) @@ -25,7 +25,7 @@ - 提炼自企业级中后台产品的交互语言和视觉风格。 - 开箱即用的高质量 React 组件。 - 使用 TypeScript 构建,提供完整的类型定义文件。 -- 基于 npm + webpack + [dva](https://github.com/dvajs/dva) 的企业级开发框架。 +- 全链路开发和设计工具体系。 ## 支持环境 diff --git a/README.md b/README.md index 96d57afb81..c27f1f6c2c 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ [![Dependency Status](https://img.shields.io/gemnasium/react-component/trigger.svg?style=flat-square)](https://gemnasium.com/ant-design/ant-design) [![npm package](https://img.shields.io/npm/v/antd.svg?style=flat-square)](https://www.npmjs.org/package/antd) -[![NPM downloads](http://img.shields.io/npm/dm/antd.svg?style=flat-square)](https://npmcharts.com/compare/antd?minimal=true) +[![NPM downloads](http://img.shields.io/npm/dm/antd.svg?style=flat-square)](http://www.npmtrends.com/antd) [![Percentage of issues still open](http://isitmaintained.com/badge/open/ant-design/ant-design.svg)](http://isitmaintained.com/project/ant-design/ant-design "Percentage of issues still open") [![Gitter](https://badges.gitter.im/ant-design/ant-design-english.svg)](https://gitter.im/ant-design/ant-design-english?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) (English) [![Join the chat at https://gitter.im/ant-design/ant-design](https://img.shields.io/gitter/room/ant-design/ant-design.svg?style=flat-square)](https://gitter.im/ant-design/ant-design?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)(中文) @@ -29,7 +29,7 @@ An enterprise-class UI design language and React-based implementation. - An enterprise-class UI design system for desktop applications. - A set of high-quality React components out of the box. - Written in TypeScript with predictable static types. -- Work with great development and design resources and tools. +- The whole package of development and design resources and tools. ## Environment Support diff --git a/components/affix/index.tsx b/components/affix/index.tsx index c1c72d5d10..784f045f06 100644 --- a/components/affix/index.tsx +++ b/components/affix/index.tsx @@ -95,6 +95,7 @@ export default class Affix extends React.Component { }; private fixedNode: HTMLElement; + private placeholderNode: HTMLElement; setAffixStyle(e: any, affixStyle: React.CSSProperties | null) { const { onChange = noop, target = getDefaultTarget } = this.props; @@ -123,6 +124,21 @@ export default class Affix extends React.Component { this.setState({ placeholderStyle: placeholderStyle as React.CSSProperties }); } + syncPlaceholderStyle(e: any) { + const { affixStyle } = this.state; + if (!affixStyle) { + return; + } + this.placeholderNode.style.cssText = ''; + this.setAffixStyle(e, { + ...affixStyle, + width: this.placeholderNode.offsetWidth, + }); + this.setPlaceholderStyle({ + width: this.placeholderNode.offsetWidth, + }); + } + @throttleByAnimationFrameDecorator() updatePosition(e: any) { let { offsetTop, offsetBottom, offset, target = getDefaultTarget } = this.props; @@ -194,6 +210,10 @@ export default class Affix extends React.Component { } this.setPlaceholderStyle(null); } + + if (e.type === 'resize') { + this.syncPlaceholderStyle(e); + } } componentDidMount() { @@ -245,6 +265,10 @@ export default class Affix extends React.Component { this.fixedNode = node; } + savePlaceholderNode = (node: HTMLDivElement) => { + this.placeholderNode = node; + } + render() { const className = classNames({ [this.props.prefixCls || 'ant-affix']: this.state.affixStyle, @@ -253,7 +277,7 @@ export default class Affix extends React.Component { const props = omit(this.props, ['prefixCls', 'offsetTop', 'offsetBottom', 'target', 'onChange']); const placeholderStyle = { ...this.state.placeholderStyle, ...this.props.style }; return ( -
+
{this.props.children}
diff --git a/components/alert/index.en-US.md b/components/alert/index.en-US.md index 144c6f27aa..55d18369b6 100644 --- a/components/alert/index.en-US.md +++ b/components/alert/index.en-US.md @@ -15,6 +15,7 @@ Alert component for feedback. | Property | Description | Type | Default | | -------- | ----------- | ---- | ------- | +| afterClose | Called when close animation is finished | () => void | - | | banner | Whether to show as banner | boolean | false | | closable | Whether Alert can be closed | boolean | - | | closeText | Close text to show | string\|ReactNode | - | @@ -23,4 +24,4 @@ Alert component for feedback. | showIcon | Whether to show icon | boolean | false, in `banner` mode default is true | | iconType | Icon type, effective when `showIcon` is `true` | string | - | | type | Type of Alert styles, options: `success`, `info`, `warning`, `error` | string | `info`, in `banner` mode default is `warning` | -| onClose | Callback when Alert is closed | Function | - | +| onClose | Callback when Alert is closed | (e: MouseEvent) => void | - | diff --git a/components/alert/index.tsx b/components/alert/index.tsx index bd93a2aca0..9e5cf954df 100755 --- a/components/alert/index.tsx +++ b/components/alert/index.tsx @@ -22,7 +22,7 @@ export interface AlertProps { /** Callback when close Alert */ onClose?: React.MouseEventHandler; /** Trigger when animation ending of Alert */ - afterClose?: Function; + afterClose?: () => void; /** Whether to show icon */ showIcon?: boolean; iconType?: string; diff --git a/components/alert/index.zh-CN.md b/components/alert/index.zh-CN.md index e8feb7c0c7..9f48464322 100644 --- a/components/alert/index.zh-CN.md +++ b/components/alert/index.zh-CN.md @@ -16,6 +16,7 @@ title: Alert | 参数 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | +| afterClose | 关闭动画结束后的回掉 | () => void | - | | banner | 是否用作顶部公告 | boolean | false | | closable | 默认不显示关闭按钮 | boolean | 无 | | closeText | 自定义关闭按钮 | string\|ReactNode | 无 | @@ -24,4 +25,4 @@ title: Alert | showIcon | 是否显示辅助图标 | boolean | false,`banner` 模式下默认值为 true | | iconType | 自定义图标类型,`showIcon` 为 `true` 时有效 | string | - | | type | 指定警告提示的样式,有四种选择 `success`、`info`、`warning`、`error` | string | `info`,`banner` 模式下默认值为 `warning` | -| onClose | 关闭时触发的回调函数 | Function | 无 | +| onClose | 关闭时触发的回调函数 | (e: MouseEvent) => void | 无 | diff --git a/components/badge/style/index.less b/components/badge/style/index.less index 336e4dbc38..2adf79faa1 100644 --- a/components/badge/style/index.less +++ b/components/badge/style/index.less @@ -113,7 +113,10 @@ top: auto; display: block; position: relative; - transform: none !important; + } + + &-not-a-wrapper .@{badge-prefix-cls}-count { + transform: none; } } diff --git a/components/button/__tests__/index.test.js b/components/button/__tests__/index.test.js index 4c13f3d29b..388ae1eb01 100644 --- a/components/button/__tests__/index.test.js +++ b/components/button/__tests__/index.test.js @@ -28,6 +28,24 @@ describe('Button', () => { expect(wrapper2).toMatchSnapshot(); }); + it('renders Chinese characters correctly in HOC', () => { + const Text = props => {props.children}; + const wrapper = mount( + + ); + expect(wrapper.find('.ant-btn').hasClass('ant-btn-two-chinese-chars')).toBe(true); + wrapper.setProps({ + children: 大按钮, + }); + wrapper.update(); + expect(wrapper.find('.ant-btn').hasClass('ant-btn-two-chinese-chars')).toBe(false); + wrapper.setProps({ + children: 按钮, + }); + wrapper.update(); + expect(wrapper.find('.ant-btn').hasClass('ant-btn-two-chinese-chars')).toBe(true); + }); + it('have static perperty for type detecting', () => { const wrapper = mount( diff --git a/components/button/button.tsx b/components/button/button.tsx index 72a4aac006..ddecbccf03 100644 --- a/components/button/button.tsx +++ b/components/button/button.tsx @@ -95,13 +95,7 @@ export default class Button extends React.Component { } componentDidMount() { - // Fix for HOC usage like - const buttonText = (findDOMNode(this) as HTMLElement).innerText; - if (this.isNeedInserted() && isTwoCNChar(buttonText)) { - this.setState({ - hasTwoCNChar: true, - }); - } + this.fixTwoCNChar(); } componentWillReceiveProps(nextProps: ButtonProps) { @@ -119,6 +113,10 @@ export default class Button extends React.Component { } } + componentDidUpdate() { + this.fixTwoCNChar(); + } + componentWillUnmount() { if (this.timeout) { clearTimeout(this.timeout); @@ -128,6 +126,23 @@ export default class Button extends React.Component { } } + fixTwoCNChar() { + // Fix for HOC usage like + const node = (findDOMNode(this) as HTMLElement); + const buttonText = node.textContent || node.innerText; + if (this.isNeedInserted() && isTwoCNChar(buttonText)) { + if (!this.state.hasTwoCNChar) { + this.setState({ + hasTwoCNChar: true, + }); + } + } else if (this.state.hasTwoCNChar) { + this.setState({ + hasTwoCNChar: false, + }); + } + } + handleClick = (e: React.MouseEvent) => { // Add click effect this.setState({ clicked: true }); diff --git a/components/button/style/mixin.less b/components/button/style/mixin.less index 3e1f2dee97..d1f349509a 100644 --- a/components/button/style/mixin.less +++ b/components/button/style/mixin.less @@ -54,11 +54,14 @@ .button-variant-danger(@color; @background; @border) { .button-color(@color; @background; @border); - &:hover, - &:focus { + &:hover { .button-color(@btn-primary-color; ~`colorPalette("@{color}", 5)`; ~`colorPalette("@{color}", 5)`); } + &:focus { + .button-color(~`colorPalette("@{color}", 5)`; #fff; ~`colorPalette("@{color}", 5)`); + } + &:active, &.active { .button-color(@btn-primary-color; ~`colorPalette("@{color}", 7)`; ~`colorPalette("@{color}", 7)`); @@ -202,6 +205,7 @@ &:active, &.active { background: @btn-default-bg; + text-decoration: none; } } diff --git a/components/carousel/__tests__/__snapshots__/demo.test.js.snap b/components/carousel/__tests__/__snapshots__/demo.test.js.snap index 56dde97843..d6e574f96d 100644 --- a/components/carousel/__tests__/__snapshots__/demo.test.js.snap +++ b/components/carousel/__tests__/__snapshots__/demo.test.js.snap @@ -6,6 +6,7 @@ exports[`renders ./components/carousel/demo/autoplay.md correctly 1`] = ` >
`; + +exports[`Cascader support controlled mode 1`] = ` + + + Zhejiang / Hangzhou / West Lake + + + + + +`; diff --git a/components/cascader/__tests__/index.test.js b/components/cascader/__tests__/index.test.js index 549c30e175..fe37c9ce0c 100644 --- a/components/cascader/__tests__/index.test.js +++ b/components/cascader/__tests__/index.test.js @@ -46,6 +46,16 @@ describe('Cascader', () => { expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot(); }); + it('support controlled mode', () => { + const wrapper = mount( + + ); + wrapper.setProps({ + value: ['zhejiang', 'hangzhou', 'xihu'], + }); + expect(wrapper.render()).toMatchSnapshot(); + }); + it('popup correctly with defaultValue', () => { const wrapper = mount( diff --git a/components/date-picker/__tests__/DatePicker.test.js b/components/date-picker/__tests__/DatePicker.test.js index c698e35df8..d7de7f5316 100644 --- a/components/date-picker/__tests__/DatePicker.test.js +++ b/components/date-picker/__tests__/DatePicker.test.js @@ -17,7 +17,7 @@ describe('DatePicker', () => { focusTest(DatePicker); beforeEach(() => { - MockDate.set(new Date('2016-11-22')); + MockDate.set(moment('2016-11-22')); }); afterEach(() => { diff --git a/components/form/FormItem.tsx b/components/form/FormItem.tsx index 04caeb4699..4e17e3930d 100644 --- a/components/form/FormItem.tsx +++ b/components/form/FormItem.tsx @@ -56,6 +56,8 @@ export default class FormItem extends React.Component { context: FormItemContext; + state = { helpShow: false }; + componentDidMount() { warning( this.getControls(this.props.children, true).length <= 1, @@ -89,7 +91,7 @@ export default class FormItem extends React.Component { const child = childrenArray[i] as React.ReactElement; if (child.type && - (child.type as any === FormItem || (child.type as any).displayName === 'FormItem')) { + (child.type as any === FormItem || (child.type as any).displayName === 'FormItem')) { continue; } if (!child.props) { @@ -126,6 +128,10 @@ export default class FormItem extends React.Component { return this.getChildProp(FIELD_DATA_PROP); } + onHelpAnimEnd = (_key: string, helpShow: boolean) => { + this.setState({ helpShow }); + } + renderHelp() { const prefixCls = this.props.prefixCls; const help = this.getHelpMsg(); @@ -135,7 +141,13 @@ export default class FormItem extends React.Component {
) : null; return ( - + {children} ); @@ -298,7 +310,7 @@ export default class FormItem extends React.Component { const style = props.style; const itemClassName = { [`${prefixCls}-item`]: true, - [`${prefixCls}-item-with-help`]: !!this.getHelpMsg(), + [`${prefixCls}-item-with-help`]: !!this.getHelpMsg() || this.state.helpShow, [`${prefixCls}-item-no-colon`]: !props.colon, [`${props.className}`]: !!props.className, }; diff --git a/components/form/demo/advanced-search.md b/components/form/demo/advanced-search.md index b199e6ead8..c4ce4f0e31 100644 --- a/components/form/demo/advanced-search.md +++ b/components/form/demo/advanced-search.md @@ -107,8 +107,8 @@ ReactDOM.render( display: flex; } -.ant-advanced-search-form .ant-form-item-label { - overflow: visible; +.ant-advanced-search-form .ant-form-item-control-wrapper { + flex: 1; } ```` diff --git a/components/form/demo/form-in-modal.md b/components/form/demo/form-in-modal.md index 758953f392..d74ed59afe 100644 --- a/components/form/demo/form-in-modal.md +++ b/components/form/demo/form-in-modal.md @@ -18,41 +18,43 @@ import { Button, Modal, Form, Input, Radio } from 'antd'; const FormItem = Form.Item; const CollectionCreateForm = Form.create()( - (props) => { - const { visible, onCancel, onCreate, form } = props; - const { getFieldDecorator } = form; - return ( - -
- - {getFieldDecorator('title', { - rules: [{ required: true, message: 'Please input the title of collection!' }], - })( - - )} - - - {getFieldDecorator('description')()} - - - {getFieldDecorator('modifier', { - initialValue: 'public', - })( - - Public - Private - - )} - -
-
- ); + class extends React.Component { + render() { + const { visible, onCancel, onCreate, form } = this.props; + const { getFieldDecorator } = form; + return ( + +
+ + {getFieldDecorator('title', { + rules: [{ required: true, message: 'Please input the title of collection!' }], + })( + + )} + + + {getFieldDecorator('description')()} + + + {getFieldDecorator('modifier', { + initialValue: 'public', + })( + + Public + Private + + )} + +
+
+ ); + } } ); @@ -67,7 +69,7 @@ class CollectionsPage extends React.Component { this.setState({ visible: false }); } handleCreate = () => { - const form = this.form; + const form = this.formRef.props.form; form.validateFields((err, values) => { if (err) { return; @@ -78,15 +80,15 @@ class CollectionsPage extends React.Component { this.setState({ visible: false }); }); } - saveFormRef = (form) => { - this.form = form; + saveFormRef = (formRef) => { + this.formRef = formRef; } render() { return (
&:last-child, @@ -93,7 +92,6 @@ input[type="checkbox"] { &-with-help { margin-bottom: @form-item-margin-bottom - @font-size-base * @line-height-base - @form-help-margin-top; - transition: none; } &-label { @@ -375,7 +373,7 @@ form { margin-bottom: 24px; } - > div { + > .@{form-prefix-cls}-item-control-wrapper, > .@{form-prefix-cls}-item-label { display: inline-block; vertical-align: middle; } diff --git a/components/input-number/__tests__/index.test.js b/components/input-number/__tests__/index.test.js new file mode 100644 index 0000000000..b47c2658e7 --- /dev/null +++ b/components/input-number/__tests__/index.test.js @@ -0,0 +1,4 @@ +import InputNumber from '..'; +import focusTest from '../../../tests/shared/focusTest'; + +focusTest(InputNumber); diff --git a/components/input/Search.tsx b/components/input/Search.tsx index 0a054c0ac0..6badf06234 100644 --- a/components/input/Search.tsx +++ b/components/input/Search.tsx @@ -39,21 +39,38 @@ export default class Search extends React.Component { this.input = node; } + getButtonOrIcon() { + const { enterButton, prefixCls, size } = this.props; + if (!enterButton) { + return ; + } + const enterButtonAsElement = enterButton as React.ReactElement; + if (enterButtonAsElement.type === Button || enterButtonAsElement.type === 'button') { + return React.cloneElement(enterButtonAsElement, enterButtonAsElement.type === Button ? { + className: `${prefixCls}-button`, + size, + onClick: this.onSearch, + } : { + onClick: this.onSearch, + }); + } + return ( + + ); + } + render() { - const { className, prefixCls, inputPrefixCls, size, enterButton, suffix, ...others } = this.props; + const { className, prefixCls, inputPrefixCls, size, suffix, enterButton, ...others } = this.props; delete (others as any).onSearch; - const buttonOrIcon = enterButton - ? ( - - ) : ; + const buttonOrIcon = this.getButtonOrIcon(); const searchSuffix = suffix ? [suffix, buttonOrIcon] : buttonOrIcon; const inputClassName = classNames(prefixCls, className, { [`${prefixCls}-enter-button`]: !!enterButton, diff --git a/components/input/__tests__/Search.test.js b/components/input/__tests__/Search.test.js index c83483765c..a67ed93bd0 100644 --- a/components/input/__tests__/Search.test.js +++ b/components/input/__tests__/Search.test.js @@ -1,6 +1,23 @@ +import React from 'react'; +import { mount } from 'enzyme'; import Search from '../Search'; +import Button from '../../button'; import focusTest from '../../../tests/shared/focusTest'; describe('Input.Search', () => { focusTest(Search); + + it('should support custom button', () => { + const wrapper = mount( + ok} /> + ); + expect(wrapper.render()).toMatchSnapshot(); + }); + + it('should support custom Button', () => { + const wrapper = mount( + ok} /> + ); + expect(wrapper.render()).toMatchSnapshot(); + }); }); diff --git a/components/input/__tests__/__snapshots__/Search.test.js.snap b/components/input/__tests__/__snapshots__/Search.test.js.snap new file mode 100644 index 0000000000..a08deb5a97 --- /dev/null +++ b/components/input/__tests__/__snapshots__/Search.test.js.snap @@ -0,0 +1,42 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Input.Search should support custom Button 1`] = ` + + + + + + +`; + +exports[`Input.Search should support custom button 1`] = ` + + + + + + +`; diff --git a/components/input/style/mixin.less b/components/input/style/mixin.less index 14a73557fc..93ac274a99 100644 --- a/components/input/style/mixin.less +++ b/components/input/style/mixin.less @@ -327,6 +327,9 @@ z-index: 2; line-height: 0; color: @input-color; + :not(.anticon) { + line-height: @line-height-base; + } } .@{inputClass}-prefix { diff --git a/components/list/__tests__/__snapshots__/demo.test.js.snap b/components/list/__tests__/__snapshots__/demo.test.js.snap index 9c4b9b45f7..df54b8902e 100644 --- a/components/list/__tests__/__snapshots__/demo.test.js.snap +++ b/components/list/__tests__/__snapshots__/demo.test.js.snap @@ -1396,7 +1396,6 @@ exports[`renders ./components/list/demo/vertical.md correctly 1`] = `
  • - 10 / page + 10 / sayfa
  • { render() { const { inlineCollapsed } = this.context; const props = this.props; - return - - ; + const item = ; + if (inlineCollapsed && props.level === 1) { + return + {item} + ; + } + return item; } } diff --git a/components/menu/style/index.less b/components/menu/style/index.less index 5595ddf1b9..8b10809ea8 100644 --- a/components/menu/style/index.less +++ b/components/menu/style/index.less @@ -63,8 +63,6 @@ &:before { position: absolute; background-color: transparent; - width: 100%; - height: 100%; top: 0; left: 0; bottom: 0; @@ -286,6 +284,9 @@ &:hover { color: @menu-highlight-color; } + &:before { + bottom: -2px; + } } } diff --git a/components/modal/style/confirm.less b/components/modal/style/confirm.less index 5618cb00bf..916fab29c6 100644 --- a/components/modal/style/confirm.less +++ b/components/modal/style/confirm.less @@ -25,6 +25,10 @@ font-weight: 500; font-size: @font-size-lg; line-height: 22px; + display: block; + // create BFC to avoid + // https://user-images.githubusercontent.com/507615/37702510-ba844e06-2d2d-11e8-9b67-8e19be57f445.png + overflow: auto; } .@{confirm-prefix-cls}-content { @@ -38,7 +42,6 @@ font-size: 22px; margin-right: 16px; float: left; - min-height: 48px; } } diff --git a/components/pagination/__tests__/__snapshots__/demo.test.js.snap b/components/pagination/__tests__/__snapshots__/demo.test.js.snap index f24bf83db3..162ab5543c 100644 --- a/components/pagination/__tests__/__snapshots__/demo.test.js.snap +++ b/components/pagination/__tests__/__snapshots__/demo.test.js.snap @@ -8,7 +8,6 @@ exports[`renders ./components/pagination/demo/basic.md correctly 1`] = `
  • @@ -477,7 +475,6 @@ exports[`renders ./components/pagination/demo/mini.md correctly 1`] = `
  • +
    +
    +
    +
    + 30 +
    +
    +
    +
    +`; + +exports[`Slider should show tooltip when hovering slider handler 2`] = ` +
    +
    +
    +
    +
    + 30 +
    +
    +
    +
    +`; diff --git a/components/slider/__tests__/index.test.js b/components/slider/__tests__/index.test.js new file mode 100644 index 0000000000..7fec69ccaf --- /dev/null +++ b/components/slider/__tests__/index.test.js @@ -0,0 +1,15 @@ +import React from 'react'; +import { render, mount } from 'enzyme'; +import Slider from '..'; + +describe('Slider', () => { + it('should show tooltip when hovering slider handler', () => { + const wrapper = mount( + + ); + wrapper.find('.ant-slider-handle').at(0).simulate('mouseEnter'); + expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot(); + wrapper.find('.ant-slider-handle').at(0).simulate('mouseLeave'); + expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot(); + }); +}); diff --git a/components/style/themes/default.less b/components/style/themes/default.less index 8a98f88bd7..e01b12a7cf 100644 --- a/components/style/themes/default.less +++ b/components/style/themes/default.less @@ -71,8 +71,8 @@ // LINK @link-color : @primary-color; -@link-hover-color : @primary-5; -@link-active-color : @primary-7; +@link-hover-color : color(~`colorPalette("@{link-color}", 5)`); +@link-active-color : color(~`colorPalette("@{link-color}", 7)`); @link-decoration : none; @link-hover-decoration : none; @@ -423,6 +423,7 @@ // --- @switch-height: 22px; @switch-sm-height: 16px; +@switch-sm-checked-margin-left: -(@switch-sm-height - 3px); @switch-disabled-opacity: 0.4; @switch-color: @primary-color; @@ -431,6 +432,7 @@ @pagination-item-size: 32px; @pagination-item-size-sm: 24px; @pagination-font-family: Arial; +@pagination-font-weight-active: 500; // Breadcrumb // --- diff --git a/components/switch/style/index.less b/components/switch/style/index.less index 49cffbbe56..a369799c4e 100644 --- a/components/switch/style/index.less +++ b/components/switch/style/index.less @@ -107,7 +107,7 @@ &:before, &:after { left: 100%; - margin-left: -12.5px; + margin-left: @switch-sm-checked-margin-left; } .@{switch-prefix-cls}-inner { diff --git a/components/table/Table.tsx b/components/table/Table.tsx index 21be897fed..de20597118 100755 --- a/components/table/Table.tsx +++ b/components/table/Table.tsx @@ -754,7 +754,7 @@ export default class Table extends React.Component, TableState< ); } column.title = ( - + {column.title} {sortButton} {filterDropdown} diff --git a/components/table/__tests__/__snapshots__/Table.pagination.test.js.snap b/components/table/__tests__/__snapshots__/Table.pagination.test.js.snap index 57e6c063b8..5354cd57f3 100644 --- a/components/table/__tests__/__snapshots__/Table.pagination.test.js.snap +++ b/components/table/__tests__/__snapshots__/Table.pagination.test.js.snap @@ -79,7 +79,6 @@ exports[`Table.pagination renders pagination correctly 1`] = `
  • -
    -
    - -
    -
    -
    - - - - - -
    -
    -
    @@ -1632,6 +1587,113 @@ exports[`renders ./components/table/demo/dynamic-settings.md correctly 1`] = `
    +
    +
    + +
    +
    +
    + +
    + + + + +
    +
    +
    +
    +
    - diff --git a/components/table/demo/fixed-columns.md b/components/table/demo/fixed-columns.md index 1873bcd1ea..1663d87bc4 100644 --- a/components/table/demo/fixed-columns.md +++ b/components/table/demo/fixed-columns.md @@ -15,7 +15,7 @@ title: ## en-US -To fix some columns and scroll inside other columns, and you must set `scoll.x` meanwhile. +To fix some columns and scroll inside other columns, and you must set `scroll.x` meanwhile. > Specify the width of columns if header and cell do not align properly. diff --git a/components/table/index.en-US.md b/components/table/index.en-US.md index 01755b01a7..96f198eee3 100644 --- a/components/table/index.en-US.md +++ b/components/table/index.en-US.md @@ -91,12 +91,12 @@ Same as `onRow` `onHeaderRow` `onCell` `onHeaderCell` onMouseEnter: () => {}, // mouse enter row onXxxx... }; - )} + }} onHeaderRow={(column) => { return { onClick: () => {}, // click header row }; - )} + }} /> ``` @@ -120,6 +120,7 @@ One of the Table `columns` prop for describing the table's columns, Column has t | fixed | Set column to be fixed: `true`(same as left) `'left'` `'right'` | boolean\|string | `false` | | key | Unique key of this column, you can ignore this prop if you've set a unique `dataIndex` | string | - | | render | Renderer of the table cell. The return value should be a ReactNode, or an object for [colSpan/rowSpan config](#components-table-demo-colspan-rowspan) | Function(text, record, index) {} | - | +| align | specify how content is aligned | 'left' \| 'right' \| 'center' | 'left' | | sorter | Sort function for local sort, see [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)'s compareFunction. If you need sort buttons only, set to `true` | Function\|boolean | - | | sortOrder | Order of sorted values: `'ascend'` `'descend'` `false` | boolean\|string | - | | title | Title of this column | string\|ReactNode | - | diff --git a/components/table/index.zh-CN.md b/components/table/index.zh-CN.md index b27280ba27..a432d69e9e 100644 --- a/components/table/index.zh-CN.md +++ b/components/table/index.zh-CN.md @@ -93,12 +93,12 @@ const columns = [{ onMouseEnter: () => {}, // 鼠标移入行 onXxxx... }; - )} + }} onHeaderRow={(column) => { return { onClick: () => {}, // 点击表头行 }; - )} + }} /> ``` @@ -121,6 +121,7 @@ const columns = [{ | fixed | 列是否固定,可选 `true`(等效于 left) `'left'` `'right'` | boolean\|string | false | | key | React 需要的 key,如果已经设置了唯一的 `dataIndex`,可以忽略这个属性 | string | - | | render | 生成复杂数据的渲染函数,参数分别为当前行的值,当前行数据,行索引,@return里面可以设置表格[行/列合并](#components-table-demo-colspan-rowspan) | Function(text, record, index) {} | - | +| align | 设置列内容的对齐方式 | 'left' \| 'right' \| 'center' | 'left' | | sorter | 排序函数,本地排序使用一个函数(参考 [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) 的 compareFunction),需要服务端排序可设为 true | Function\|boolean | - | | sortOrder | 排序的受控属性,外界可用此控制列的排序,可设置为 `'ascend'` `'descend'` `false` | boolean\|string | - | | title | 列头显示文字 | string\|ReactNode | - | diff --git a/components/table/interface.tsx b/components/table/interface.tsx index 6d4ed441fd..960e1d4e3e 100644 --- a/components/table/interface.tsx +++ b/components/table/interface.tsx @@ -13,6 +13,7 @@ export interface ColumnProps { key?: React.Key; dataIndex?: string; render?: (text: any, record: T, index: number) => React.ReactNode; + align?: 'left' | 'right' | 'center'; filters?: ColumnFilterItem[]; onFilter?: (value: any, record: T) => boolean; filterMultiple?: boolean; diff --git a/components/table/style/index.less b/components/table/style/index.less index da2317bf24..26e76318ef 100644 --- a/components/table/style/index.less +++ b/components/table/style/index.less @@ -11,7 +11,6 @@ .@{table-prefix-cls} { .reset-component; position: relative; - border-radius: @border-radius-base @border-radius-base 0 0; clear: both; &-body { @@ -34,14 +33,6 @@ font-weight: 500; border-bottom: @border-width-base @border-style-base @border-color-split; - &:first-child { - border-top-left-radius: @border-radius-base; - } - - &:last-child { - border-top-right-radius: @border-radius-base; - } - &[colspan] { text-align: center; border-bottom: 0; @@ -78,6 +69,16 @@ } } + &-thead > tr:first-child > th { + &:first-child { + border-top-left-radius: @border-radius-base; + } + + &:last-child { + border-top-right-radius: @border-radius-base; + } + } + &-tbody > tr > td { border-bottom: @border-width-base @border-style-base @border-color-split; transition: all .3s; @@ -138,7 +139,8 @@ overflow: hidden; .@{table-prefix-cls}-bordered & { &, - table { + table, + .@{table-prefix-cls}-thead > tr:first-child > th { border-radius: 0; } } @@ -256,11 +258,11 @@ } &-up:after { - bottom: -2px; + bottom: 0; } &-down:after { - top: 2px; + top: 0; } .@{iconfont-css-prefix}-caret-up, @@ -488,7 +490,6 @@ overflow: auto; overflow-x: hidden; table { - width: auto; min-width: 100%; } } diff --git a/components/time-picker/index.tsx b/components/time-picker/index.tsx index 51a8870c37..e77356aed6 100644 --- a/components/time-picker/index.tsx +++ b/components/time-picker/index.tsx @@ -4,6 +4,7 @@ import RcTimePicker from 'rc-time-picker/lib/TimePicker'; import classNames from 'classnames'; import LocaleReceiver from '../locale-provider/LocaleReceiver'; import defaultLocale from './locale/en_US'; +import interopDefault from '../_util/interopDefault'; export function generateShowHourMinuteSecond(format: string) { // Ref: http://momentjs.com/docs/#/parsing/string-format/ @@ -74,7 +75,7 @@ export default class TimePicker extends React.Component { constructor(props: TimePickerProps) { super(props); const value = props.value || props.defaultValue; - if (value && !moment.isMoment(value)) { + if (value && !interopDefault(moment).isMoment(value)) { throw new Error( 'The value/defaultValue of TimePicker must be a moment object after `antd@2.0`, ' + 'see: https://u.ant.design/time-picker-value', diff --git a/components/tree-select/index.en-US.md b/components/tree-select/index.en-US.md index 74654b5520..65635afee0 100644 --- a/components/tree-select/index.en-US.md +++ b/components/tree-select/index.en-US.md @@ -25,7 +25,7 @@ Any data whose entries are defined in a hierarchical manner is fit to use this c | dropdownStyle | To set the style of the dropdown menu | object | - | | filterTreeNode | Whether to filter treeNodes by input value. The value of `treeNodeFilterProp` is used for filtering by default. | boolean\|Function(inputValue: string, treeNode: TreeNode) (should return boolean) | Function | | getPopupContainer | To set the container of the dropdown menu. The default is to create a `div` element in `body`, you can reset it to the scrolling area and make a relative reposition. [example](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | Function(triggerNode) | () => document.body | -| labelInValue | whether to embed label in value, turn the format of value from `string` to `{key: string, label: ReactNode, halfChecked: string[]}` | boolean | false | +| labelInValue | whether to embed label in value, turn the format of value from `string` to `{value: string, label: ReactNode, halfChecked: string[]}` | boolean | false | | loadData | Load data asynchronously. | function(node) | - | | multiple | Support multiple or not, will be `true` when enable `treeCheckable`. | boolean | false | | placeholder | Placeholder of the select input | string | - | diff --git a/components/tree-select/index.zh-CN.md b/components/tree-select/index.zh-CN.md index aaa30fe66e..dd508033d6 100644 --- a/components/tree-select/index.zh-CN.md +++ b/components/tree-select/index.zh-CN.md @@ -25,7 +25,7 @@ title: TreeSelect | dropdownStyle | 下拉菜单的样式 | object | - | | filterTreeNode | 是否根据输入项进行筛选,默认用 treeNodeFilterProp 的值作为要筛选的 TreeNode 的属性值 | boolean\|Function(inputValue: string, treeNode: TreeNode) (函数需要返回bool值) | Function | | getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。[示例](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | Function(triggerNode) | () => document.body | -| labelInValue | 是否把每个选项的 label 包装到 value 中,会把 value 类型从 `string` 变为 `{key: string, label: ReactNode, halfChecked(treeCheckStrictly 时有效): string[] }` 的格式 | boolean | false | +| labelInValue | 是否把每个选项的 label 包装到 value 中,会把 value 类型从 `string` 变为 `{value: string, label: ReactNode, halfChecked(treeCheckStrictly 时有效): string[] }` 的格式 | boolean | false | | loadData | 异步加载数据 | function(node) | - | | multiple | 支持多选(当设置 treeCheckable 时自动变为true) | boolean | false | | placeholder | 选择框默认文字 | string | - | diff --git a/components/upload/Upload.tsx b/components/upload/Upload.tsx index a4c0211f68..721428b30a 100644 --- a/components/upload/Upload.tsx +++ b/components/upload/Upload.tsx @@ -180,13 +180,14 @@ export default class Upload extends React.Component { } beforeUpload = (file: UploadFile, fileList: UploadFile[]) => { + const newFile = fileToObject(file); if (!this.props.beforeUpload) { return true; } - const result = this.props.beforeUpload(file, fileList); + const result = this.props.beforeUpload(newFile, fileList); if (result === false) { this.onChange({ - file, + file: newFile, fileList: uniqBy(fileList.concat(this.state.fileList), (item: any) => item.uid), }); return false; diff --git a/docs/react/customize-theme.en-US.md b/docs/react/customize-theme.en-US.md index de9a6de82e..1b0ce282a9 100644 --- a/docs/react/customize-theme.en-US.md +++ b/docs/react/customize-theme.en-US.md @@ -23,7 +23,7 @@ You can use this [example](https://github.com/ant-design/antd-init/tree/master/e ### 1) Using `theme` property (recommended way) -Specify the `theme` property in the `package.json` or `.roadhogrc` file, whose value can be either an object or the path to a JS file that contains the custom values of specific variables: +Specify the `theme` property in the `package.json` or `.webpackrc` file, whose value can be either an object or the path to a JS file that contains the custom values of specific variables: - example of directly specifying the custom values as an object: ```js "theme": { diff --git a/docs/react/customize-theme.zh-CN.md b/docs/react/customize-theme.zh-CN.md index f773399fc5..005d69c095 100644 --- a/docs/react/customize-theme.zh-CN.md +++ b/docs/react/customize-theme.zh-CN.md @@ -24,7 +24,7 @@ antd 的样式使用了 [Less](http://lesscss.org/) 作为开发语言,并定 ### 1) theme 属性(推荐) -配置在 `package.json` 或 `.roadhogrc` 下的 `theme` 字段。theme 可以为配置为一个对象或文件路径。 +配置在 `package.json` 或 `.webpackrc` 下的 `theme` 字段。theme 可以配置为一个对象或文件路径。 ```js "theme": { diff --git a/docs/react/getting-started.en-US.md b/docs/react/getting-started.en-US.md index d282d285fa..d8ba9418c1 100644 --- a/docs/react/getting-started.en-US.md +++ b/docs/react/getting-started.en-US.md @@ -5,25 +5,23 @@ title: Getting Started Ant Design React is dedicated to providing a **good development experience** for programmers. Make sure that you had installed [Node.js](https://nodejs.org/)(> v6.5) correctly. +> Before delving into Ant Design React, a good knowledge base of [React](http://facebook.github.io/react/) and [JavaScript ES2015](http://babeljs.io/docs/learn-es2015/) is needed. + --- -Before delving into Ant Design React, a good knowledge of [React](http://facebook.github.io/react/) and [JavaScript ES2015](http://babeljs.io/docs/learn-es2015/) is needed. +## Playground -## First Example - -The following CodeSandbox demo is the simplest use case, and it's also a good habit to fork this demo to provide a re-producible demo while reporting a bug. Please don't use this demo as a scaffold in production. +The following CodeSandbox demo is the simplest use case, and it's also a good habit to fork this demo to provide a re-producible demo while reporting a bug. - [antd CodeSandbox](https://u.ant.design/codesandbox-repro) -## Standard Development Flow +## First Local Development During development, you may need to compile and debug JSX and ES2015 code, and even proxy some of the requests to mock data or other external services. All of these can be done with quick feedback provided through hot reloading of changes. -Such features, together with packaging the production version, are covered in this work flow. - ### 1. Installation -[antd-init](https://github.com/ant-design/antd-init/) is a demo only scaffold tool. If you want to create real world projects, [dva-cli](https://github.com/dvajs/dva-cli) is our recommendation. +[antd-init](https://github.com/ant-design/antd-init/) is a demo-only scaffold tool. If you want to create real world projects, [dva-cli](https://github.com/dvajs/dva-cli) and [create-react-app](https://github.com/facebookincubator/create-react-app) is our recommendation. ```bash $ npm install antd-init -g @@ -31,8 +29,9 @@ $ npm install antd-init -g Read [the documentation of `antd-init`](https://github.com/ant-design/antd-init/) and [the documentation of `ant-tool`](http://ant-tool.github.io/) to explore more features. -> Also, you can use scaffold/demo which is provided by community: +> Also, you can try other scaffolds which is provided below: > +> - [Ant Design Pro](http://pro.ant.design/) > - [antd-admin](https://github.com/zuiidea/antd-admin) > - [reactSPA](https://github.com/JasonBai007/reactSPA) > - [react-redux-antd by Justin-lu](https://github.com/Justin-lu/react-redux-antd) diff --git a/docs/react/getting-started.zh-CN.md b/docs/react/getting-started.zh-CN.md index 9586b1de8b..2740284c72 100644 --- a/docs/react/getting-started.zh-CN.md +++ b/docs/react/getting-started.zh-CN.md @@ -5,24 +5,25 @@ title: 快速上手 Ant Design React 致力于提供给程序员**愉悦**的开发体验。 +> 在开始之前,推荐先学习 [React](http://facebook.github.io/react/) 和 [ES2015](http://babeljs.io/docs/learn-es2015/),并正确安装和配置了 [Node.js](https://nodejs.org/) v6.5 或以上。 +> 官方指南假设你已了解关于 HTML、CSS 和 JavaScript 的中级知识,并且已经完全掌握了 React 全家桶的正确开发方式。如果你刚开始学习前端或者 React,将 UI 框架作为你的第一步可能不是最好的主意。 + --- -在开始之前,推荐先学习 [React](http://facebook.github.io/react/) 和 [ES2015](http://babeljs.io/docs/learn-es2015/),并正确安装和配置了 [Node.js](https://nodejs.org/) v6.5 或以上。 +## 在线演示 -## 第一个例子 - -最简单的使用方式参照以下 CodeSandbox 演示,也推荐 Fork 本例来进行 `Bug Report`,注意不要在实际项目中这样使用。 +最简单的使用方式参照以下 CodeSandbox 演示,也推荐 Fork 本例来进行 `Bug Report`。 - [antd CodeSandbox](https://u.ant.design/codesandbox-repro) -## 标准开发 +## 第一个本地实例 实际项目开发中,你会需要对 ES2015 和 JSX 代码的构建、调试、代理、打包部署等一系列工程化的需求。 我们提供了一套 `npm` + `webpack` 的开发工具链来辅助开发,下面我们用一个简单的实例来说明。 ### 1. 安装脚手架工具 -[antd-init](https://github.com/ant-design/antd-init/) 是一个用于演示 antd 如何使用的脚手架工具,真实项目建议使用 [dva-cli](https://github.com/dvajs/dva-cli)。 +[antd-init](https://github.com/ant-design/antd-init/) 是一个用于演示 antd 如何使用的脚手架工具,实际业务项目建议使用 [dva-cli](https://github.com/dvajs/dva-cli) 和 [create-react-app](https://github.com/facebookincubator/create-react-app) 进行搭建。 ```bash $ npm install antd-init -g @@ -30,8 +31,9 @@ $ npm install antd-init -g 更多功能请参考 [脚手架工具](https://github.com/ant-design/antd-init/) 和 [开发工具文档](http://ant-tool.github.io/)。 -> 除了官方提供的脚手架,您也可以使用社区提供的脚手架和范例: +> 您也可以使用以下脚手架和范例: > +> - [Ant Design Pro](http://pro.ant.design/) > - [antd-admin](https://github.com/zuiidea/antd-admin) > - [reactSPA](https://github.com/JasonBai007/reactSPA) > - [react-redux-antd by Justin-lu](https://github.com/Justin-lu/react-redux-antd) diff --git a/docs/react/introduce.en-US.md b/docs/react/introduce.en-US.md index 92343f5139..7ff90855df 100644 --- a/docs/react/introduce.en-US.md +++ b/docs/react/introduce.en-US.md @@ -30,7 +30,7 @@ Following the Ant Design specification, we developed a React UI library `antd` t - An enterprise-class UI design language for web applications. - A set of high-quality React components out of the box. - Written in TypeScript with complete defined types. -- A npm + webpack + [dva](https://github.com/dvajs/dva) front-end development workflow. +- The whole package of development and design resources and tools. ## Environment Support diff --git a/docs/react/introduce.zh-CN.md b/docs/react/introduce.zh-CN.md index 3d4b1a3230..8b818cdb55 100644 --- a/docs/react/introduce.zh-CN.md +++ b/docs/react/introduce.zh-CN.md @@ -30,7 +30,7 @@ title: Ant Design of React - 提炼自企业级中后台产品的交互语言和视觉风格。 - 开箱即用的高质量 React 组件。 - 使用 TypeScript 构建,提供完整的类型定义文件。 -- 基于 npm + webpack + babel 的工作流,支持 ES2015 和 TypeScript。 +- 全链路开发和设计工具体系。 ## 支持环境 diff --git a/docs/react/practical-projects.en-US.md b/docs/react/practical-projects.en-US.md index 4e24cb23be..cd30ad2687 100644 --- a/docs/react/practical-projects.en-US.md +++ b/docs/react/practical-projects.en-US.md @@ -64,12 +64,14 @@ $ npm install antd babel-plugin-import --save Edit `.webpackrc` to integrate `babel-plugin-import`. ```diff +{ + "extraBabelPlugins": [ + ["import", { "libraryName": "antd", "libraryDirectory": "es", "style": "css" }] -+ ], ++ ] +} ``` -> Notice: dva-cli's build and dev is based on roadhog, view [roadhog#Configuration](https://github.com/sorrycc/roadhog/blob/master/README_en-us.md#configuration) for more `.roadhogrc` Configuration. +> Notice: dva-cli's build and dev is based on roadhog, view [roadhog#Configuration](https://github.com/sorrycc/roadhog/blob/master/README_en-us.md#configuration) for more `.webpackrc` Configuration. ## Define Router @@ -149,8 +151,6 @@ dva manages the domain model with `model`, with reducers for synchronous state u Let's create a model `models/products.js` by typing: ```javascript -import dva from 'dva'; - export default { namespace: 'products', state: [], diff --git a/docs/react/practical-projects.zh-CN.md b/docs/react/practical-projects.zh-CN.md index c2bad9fff5..3ae7dafcd9 100644 --- a/docs/react/practical-projects.zh-CN.md +++ b/docs/react/practical-projects.zh-CN.md @@ -66,12 +66,14 @@ $ npm install antd babel-plugin-import --save 编辑 `.webpackrc`,使 `babel-plugin-import` 插件生效。 ```diff +{ + "extraBabelPlugins": [ + ["import", { "libraryName": "antd", "libraryDirectory": "es", "style": "css" }] -+ ], ++ ] +} ``` -> 注:dva-cli 基于 roadhog 实现 build 和 dev,更多 `.roadhogrc` 的配置详见 [roadhog#配置](https://github.com/sorrycc/roadhog#配置) +> 注:dva-cli 基于 roadhog 实现 build 和 dev,更多 `.webpackrc` 的配置详见 [roadhog#配置](https://github.com/sorrycc/roadhog#配置) ## 定义路由 @@ -151,8 +153,6 @@ dva 通过 model 的概念把一个领域的模型管理起来,包含同步更 新建 model `models/products.js` : ```javascript -import dva from 'dva'; - export default { namespace: 'products', state: [], diff --git a/docs/react/recommendation.en-US.md b/docs/react/recommendation.en-US.md index 723b99965f..330611df8e 100644 --- a/docs/react/recommendation.en-US.md +++ b/docs/react/recommendation.en-US.md @@ -25,6 +25,7 @@ Code highlight | [react-syntax-highlighter](https://github.com/conorhastings/rea Markdown renderer | [react-markdown](http://rexxars.github.io/react-markdown/) Infinite Scroll | [react-virtualized](https://github.com/bvaughn/react-virtualized) Map | [react-google-maps](https://github.com/tomchentw/react-google-maps) [google-map-react](https://github.com/istarkov/google-map-react) [react-amap](https://github.com/ElemeFE/react-amap) +Context Menu | [react-contextmenu](https://github.com/vkbansal/react-contextmenu/) [react-contexify](https://github.com/fkhadra/react-contexify) Emoji | [emoji-mart](https://github.com/missive/emoji-mart)