diff --git a/.eslintrc.js b/.eslintrc.js index 3c85116424..5e2173a4e2 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -28,7 +28,9 @@ const eslintrc = { 'react/sort-comp': 0, 'react/prop-types': 0, 'react/jsx-first-prop-new-line': 0, + "react/jsx-filename-extension": [1, { extensions: ['.js', '.jsx', '.md'] }], 'import/no-unresolved': 0, + 'import/no-extraneous-dependencies': 0, 'no-param-reassign': 0, 'no-return-assign': 0, 'max-len': 0, @@ -50,6 +52,8 @@ if (process.env.RUN_ENV === 'DEMO') { 'prefer-rest-params': 0, 'react/no-multi-comp': 0, 'react/prefer-es6-class': 0, + 'jsx-a11y/href-no-hash': 0, + 'import/newline-after-import': 0, }); } diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e613b1d5e..588858250e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,11 +9,22 @@ timeline: true --- +## 1.10.0 + +`2016-08-20` + +- Affix 和 BackTop 新增 `target` 属性,支持指定滚动容器。[#2718](https://github.com/ant-design/ant-design/issues/2718) +- 文档页面加上编辑按钮,方便社区贡献。[#2325](https://github.com/ant-design/ant-design/issues/2325) +- 升级 rc-cascader 依赖,修复一个 `loadData` 属性和表单结合使用的问题。[#2767](https://github.com/ant-design/ant-design/issues/2767) +- 修复 `editable-card` 类型的 Tabs 没有关闭图标的问题。[#2747](https://github.com/ant-design/ant-design/issues/2747) +- Menu 修正默认 `z-index`。[#2762](https://github.com/ant-design/ant-design/issues/2762) +- 修正 Select 组件在 IE 下的一些样式问题。[#2741](https://github.com/ant-design/ant-design/issues/2741) + ## 1.9.1 `2016-08-16` -- 修复 Tabs 的 `type="editable-card"` 模式,activeKey 错误的问题。[#2725](https://github.com/ant-design/ant-design/issues/2725) +- 修复 `editable-card` 类型的 Tabs 设置 `activeKey` 无效的问题。[#2725](https://github.com/ant-design/ant-design/issues/2725) - 修复一个 Table 的样式兼容性问题。[#2723](https://github.com/ant-design/ant-design/issues/2723) - 更新 axure 部件库。[#2714](https://github.com/ant-design/ant-design/issues/2714) diff --git a/components/affix/demo/target.md b/components/affix/demo/target.md new file mode 100644 index 0000000000..e2a21d1f56 --- /dev/null +++ b/components/affix/demo/target.md @@ -0,0 +1,29 @@ +--- +order: 4 +title: 参考对象 +--- + +用 `target` 设置 `Affix` 需要监听其滚动事件的元素,默认为 `window`。 + +````jsx +import { Affix, Button } from 'antd'; + +const Demo = () => { + return ( +
+
+
+
+
+
+ document.getElementById('affix-target')} offsetTop={20}> + + +
+
+
+ ); +}; + +ReactDOM.render(, mountNode); +```` diff --git a/components/affix/index.tsx b/components/affix/index.tsx index 1bd409d4f9..d4b70ec732 100644 --- a/components/affix/index.tsx +++ b/components/affix/index.tsx @@ -6,32 +6,42 @@ import warning from 'warning'; import assign from 'object-assign'; import shallowequal from 'shallowequal'; -function getScroll(w, top?: boolean) { - let ret = w[`page${top ? 'Y' : 'X'}Offset`]; - const method = `scroll${top ? 'Top' : 'Left'}`; - if (typeof ret !== 'number') { - const d = w.document; - // ie6,7,8 standard mode - ret = d.documentElement[method]; - if (typeof ret !== 'number') { - // quirks mode - ret = d.body[method]; - } +function getScroll(target, top) { + const prop = top ? 'pageYOffset' : 'pageXOffset'; + const method = top ? 'scrollTop' : 'scrollLeft'; + const isWindow = target === window; + + let ret = isWindow ? target[prop] : target[method]; + // ie6,7,8 standard mode + if (isWindow && typeof ret !== 'number') { + ret = window.document.documentElement[method]; } + return ret; } -function getOffset(element) { - const rect = element.getBoundingClientRect(); - const body = document.body; - const clientTop = element.clientTop || body.clientTop || 0; - const clientLeft = element.clientLeft || body.clientLeft || 0; - const scrollTop = getScroll(window, true); - const scrollLeft = getScroll(window); +function getTargetRect(target): any { + return target !== window ? + target.getBoundingClientRect() : + { top: 0, left: 0, bottom: 0 }; +} + +function getOffset(element, target) { + const elemRect = element.getBoundingClientRect(); + const targetRect = getTargetRect(target); + + const scrollTop = getScroll(target, true); + const scrollLeft = getScroll(target, false); + + const docElem = window.document.body; + const clientTop = docElem.clientTop || 0; + const clientLeft = docElem.clientLeft || 0; return { - top: rect.top + scrollTop - clientTop, - left: rect.left + scrollLeft - clientLeft, + top: elemRect.top - targetRect.top + + scrollTop - clientTop, + left: elemRect.left - targetRect.left + + scrollLeft - clientLeft, }; } @@ -45,15 +55,20 @@ export interface AffixProps { offsetBottom?: number; style?: React.CSSProperties; onChange?: (affixed?: boolean) => any; + target?: () => Window | HTMLElement; } export default class Affix extends React.Component { static propTypes = { offsetTop: React.PropTypes.number, offsetBottom: React.PropTypes.number, + target: React.PropTypes.func, }; static defaultProps = { + target() { + return window; + }, onChange() {}, }; @@ -73,8 +88,10 @@ export default class Affix extends React.Component { } setAffixStyle(e, affixStyle) { + const { onChange, target } = this.props; const originalAffixStyle = this.state.affixStyle; - if (e.type === 'scroll' && originalAffixStyle && affixStyle) { + const isWindow = target() === window; + if (e.type === 'scroll' && originalAffixStyle && affixStyle && isWindow) { return; } if (shallowequal(affixStyle, originalAffixStyle)) { @@ -84,7 +101,7 @@ export default class Affix extends React.Component { const affixed = !!this.state.affixStyle; if ((affixStyle && !originalAffixStyle) || (!affixStyle && originalAffixStyle)) { - this.props.onChange(affixed); + onChange(affixed); } }); } @@ -100,24 +117,25 @@ export default class Affix extends React.Component { this.setState({ placeholderStyle }); } - handleScroll = (e) => { - let { offsetTop, offsetBottom, offset } = this.props; + updatePosition = (e) => { + let { offsetTop, offsetBottom, offset, target } = this.props; + const targetNode = target(); // Backwards support offsetTop = offsetTop || offset; - const scrollTop = getScroll(window, true); + const scrollTop = getScroll(targetNode, true); const affixNode = ReactDOM.findDOMNode(this) as HTMLElement; - const fixedNode = ReactDOM.findDOMNode(this.refs.fixedNode) as HTMLElement; - const elemOffset = getOffset(affixNode); + const elemOffset = getOffset(affixNode, targetNode); const elemSize = { - width: fixedNode.offsetWidth, - height: fixedNode.offsetHeight, + width: this.refs.fixedNode.offsetWidth, + height: this.refs.fixedNode.offsetHeight, }; const offsetMode = { top: null as boolean, bottom: null as boolean, }; + // Default to `offsetTop=0`. if (typeof offsetTop !== 'number' && typeof offsetBottom !== 'number') { offsetMode.top = true; offsetTop = 0; @@ -126,25 +144,31 @@ export default class Affix extends React.Component { offsetMode.bottom = typeof offsetBottom === 'number'; } + const targetRect = getTargetRect(targetNode); + const targetInnerHeight = + (targetNode as Window).innerHeight || (targetNode as HTMLElement).clientHeight; if (scrollTop > elemOffset.top - offsetTop && offsetMode.top) { // Fixed Top this.setAffixStyle(e, { position: 'fixed', - top: offsetTop, - left: elemOffset.left, + top: targetRect.top + offsetTop, + left: targetRect.left + elemOffset.left, width: affixNode.offsetWidth, }); this.setPlaceholderStyle(e, { width: affixNode.offsetWidth, height: affixNode.offsetHeight, }); - } else if (scrollTop < elemOffset.top + elemSize.height + offsetBottom - window.innerHeight && - offsetMode.bottom) { + } else if ( + scrollTop < elemOffset.top + elemSize.height + offsetBottom - targetInnerHeight && + offsetMode.bottom + ) { // Fixed Bottom + const targetBottomOffet = targetNode === window ? 0 : (window.innerHeight - targetRect.bottom); this.setAffixStyle(e, { position: 'fixed', - bottom: offsetBottom, - left: elemOffset.left, + bottom: targetBottomOffet + offsetBottom, + left: targetRect.left + elemOffset.left, width: affixNode.offsetWidth, }); this.setPlaceholderStyle(e, { @@ -159,17 +183,37 @@ export default class Affix extends React.Component { componentDidMount() { warning(!('offset' in this.props), '`offset` prop of Affix is deprecated, use `offsetTop` instead.'); - this.scrollEvent = addEventListener(window, 'scroll', this.handleScroll); - this.resizeEvent = addEventListener(window, 'resize', this.handleScroll); + + const target = this.props.target; + this.setTargetEventListeners(target); + } + + componentWillReceiveProps(nextProps) { + if (this.props.target !== nextProps.target) { + this.clearScrollEventListeners(); + this.setTargetEventListeners(nextProps.target); + + // Mock Event object. + this.updatePosition({}); + } } componentWillUnmount() { - if (this.scrollEvent) { - this.scrollEvent.remove(); - } - if (this.resizeEvent) { - this.resizeEvent.remove(); - } + this.clearScrollEventListeners(); + } + + setTargetEventListeners(getTarget) { + const target = getTarget(); + this.scrollEvent = addEventListener(target, 'scroll', this.updatePosition); + this.resizeEvent = addEventListener(target, 'resize', this.updatePosition); + } + + clearScrollEventListeners() { + ['scrollEvent', 'resizeEvent'].forEach((name) => { + if (this[name]) { + this[name].remove(); + } + }); } render() { @@ -180,6 +224,7 @@ export default class Affix extends React.Component { const props = assign({}, this.props); delete props.offsetTop; delete props.offsetBottom; + delete props.target; return (
diff --git a/components/affix/index.zh-CN.md b/components/affix/index.zh-CN.md index 1ac87fcf2e..bb4a4f54ab 100644 --- a/components/affix/index.zh-CN.md +++ b/components/affix/index.zh-CN.md @@ -20,4 +20,5 @@ english: Affix |-------------|----------------|--------------------|--------------| | offsetTop | 距离窗口顶部达到指定偏移量后触发 | Number | | | offsetBottom | 距离窗口底部达到指定偏移量后触发 | Number | | +| target | 设置 `Affix` 需要监听其滚动事件的元素,值为一个返回对应 DOM 元素的函数 | Function | () => window | | onChange | 固定状态改变时触发的回调函数 | Function(affixed) | 无 | diff --git a/components/auto-complete/demo/basic.md b/components/auto-complete/demo/basic.md index eded8408bb..8f4b6651e5 100644 --- a/components/auto-complete/demo/basic.md +++ b/components/auto-complete/demo/basic.md @@ -1,6 +1,6 @@ --- order: 0 -title: +title: zh-CN: 基本使用 en-US: Basic Usage --- diff --git a/components/auto-complete/demo/options.md b/components/auto-complete/demo/options.md index 34d8d5ff5f..57b9fe2435 100644 --- a/components/auto-complete/demo/options.md +++ b/components/auto-complete/demo/options.md @@ -1,6 +1,6 @@ --- order: 2 -title: +title: zh-CN: 自定义选项 en-US: Customized --- @@ -16,6 +16,7 @@ Items in dataSource could be an `AutoComplete.Option`. ````jsx import { AutoComplete } from 'antd'; + const Option = AutoComplete.Option; const Complete = React.createClass({ diff --git a/components/auto-complete/index.tsx b/components/auto-complete/index.tsx index 063ce0092f..8e92ccd1be 100644 --- a/components/auto-complete/index.tsx +++ b/components/auto-complete/index.tsx @@ -3,7 +3,7 @@ import Select, { Option, OptGroup } from '../select'; import classNames from 'classnames'; export interface AutoCompleteProps { - size?: string; + size?: 'large' | 'small' | 'default'; className?: string; notFoundContent?: Element; dataSource: Array; diff --git a/components/back-top/index.tsx b/components/back-top/index.tsx index 111de53212..f8a5873056 100644 --- a/components/back-top/index.tsx +++ b/components/back-top/index.tsx @@ -5,24 +5,28 @@ import addEventListener from 'rc-util/lib/Dom/addEventListener'; import classNames from 'classnames'; import omit from 'object.omit'; -function getScroll(w, top) { - let ret = w[`page${top ? 'Y' : 'X'}Offset`]; - const method = `scroll${top ? 'Top' : 'Left'}`; - if (typeof ret !== 'number') { - const d = w.document; - // ie6,7,8 standard mode - ret = d.documentElement[method]; - if (typeof ret !== 'number') { - // quirks mode - ret = d.body[method]; - } +function getScroll(target, top) { + if (typeof window === 'undefined') { + return 0; } + + const prop = top ? 'pageYOffset' : 'pageXOffset'; + const method = top ? 'scrollTop' : 'scrollLeft'; + const isWindow = target === window; + + let ret = isWindow ? target[prop] : target[method]; + // ie6,7,8 standard mode + if (isWindow && typeof ret !== 'number') { + ret = window.document.documentElement[method]; + } + return ret; } interface BackTopProps { visibilityHeight?: number; onClick?: (event) => void; + target?: () => HTMLElement | Window; prefixCls?: string; className?: string; } @@ -31,6 +35,9 @@ export default class BackTop extends React.Component { static defaultProps = { onClick() {}, visibilityHeight: 400, + target() { + return window; + }, prefixCls: 'ant-back-top', }; @@ -38,9 +45,9 @@ export default class BackTop extends React.Component { constructor(props) { super(props); - const scrollTop = getScroll(window, true); + const scrollTop = getScroll(props.target(), true); this.state = { - visible: scrollTop > this.props.visibilityHeight, + visible: scrollTop > props.visibilityHeight, }; } @@ -53,19 +60,25 @@ export default class BackTop extends React.Component { } setScrollTop(value) { - document.body.scrollTop = value; - document.documentElement.scrollTop = value; + const targetNode = this.props.target(); + if (targetNode === window) { + document.body.scrollTop = value; + document.documentElement.scrollTop = value; + } else { + (targetNode as HTMLElement).scrollTop = value; + } } handleScroll = () => { - const scrollTop = getScroll(window, true); + const { visibilityHeight, target } = this.props; + const scrollTop = getScroll(target(), true); this.setState({ - visible: scrollTop > this.props.visibilityHeight, + visible: scrollTop > visibilityHeight, }); } componentDidMount() { - this.scrollEvent = addEventListener(window, 'scroll', this.handleScroll); + this.scrollEvent = addEventListener(this.props.target(), 'scroll', this.handleScroll); } componentWillUnmount() { diff --git a/components/badge/demo/99plus.md b/components/badge/demo/99plus.md index e3e12700bf..b284cdcdbc 100644 --- a/components/badge/demo/99plus.md +++ b/components/badge/demo/99plus.md @@ -18,10 +18,10 @@ import { Badge } from 'antd'; ReactDOM.render(
- + - +
, mountNode); ```` diff --git a/components/badge/demo/basic.md b/components/badge/demo/basic.md index 93c123fe87..ea20e74954 100644 --- a/components/badge/demo/basic.md +++ b/components/badge/demo/basic.md @@ -18,7 +18,7 @@ import { Badge } from 'antd'; ReactDOM.render( - + , mountNode); ```` diff --git a/components/badge/demo/change.md b/components/badge/demo/change.md index 2919fcfba6..e7110f6932 100644 --- a/components/badge/demo/change.md +++ b/components/badge/demo/change.md @@ -44,10 +44,10 @@ const Test = React.createClass({ return (
- + - +
diff --git a/components/badge/demo/link.md b/components/badge/demo/link.md index 9b2da4b871..45aa19a15f 100644 --- a/components/badge/demo/link.md +++ b/components/badge/demo/link.md @@ -19,7 +19,7 @@ import { Badge } from 'antd'; ReactDOM.render( - + , mountNode); diff --git a/components/badge/demo/overflow.md b/components/badge/demo/overflow.md index 245f64c2a4..c0a786dd4b 100644 --- a/components/badge/demo/overflow.md +++ b/components/badge/demo/overflow.md @@ -18,10 +18,10 @@ import { Badge } from 'antd'; ReactDOM.render(
- + - +
, mountNode); ```` diff --git a/components/badge/demo/status.md b/components/badge/demo/status.md new file mode 100644 index 0000000000..de0ca28b84 --- /dev/null +++ b/components/badge/demo/status.md @@ -0,0 +1,36 @@ +--- +order: 7 +title: + zh-CN: 状态点 + en-US: Status +--- + +## zh-CN + +用于表示状态的小圆点。 + +## en-US + +Standalone badge with status. + +````jsx +import { Badge } from 'antd'; + +ReactDOM.render( +
+
Status:  
+ + + + + +
+
+
+
+
+ +
, + mountNode +); +```` diff --git a/components/badge/index.en-US.md b/components/badge/index.en-US.md index 9b40049c6a..1f13f4ead7 100644 --- a/components/badge/index.en-US.md +++ b/components/badge/index.en-US.md @@ -14,7 +14,7 @@ Badge normally appears in proximity to notification or head picture with eye-cat ```jsx -
+ ``` @@ -28,3 +28,5 @@ Badge normally appears in proximity to notification or head picture with eye-cat | count | Number to show in badge | Number | | | overflowCount | Max count to show | Number | 99 | | dot | whether to show red dot without number | Boolean | false | +| status | Set Badge as a status dot | Enum{ 'success', 'processing, 'default', 'error', 'warning' } | '' | +| text | If `status` is set, `text` is to set the text of status dot | String | '' | diff --git a/components/badge/index.tsx b/components/badge/index.tsx index e326905133..3864a63294 100644 --- a/components/badge/index.tsx +++ b/components/badge/index.tsx @@ -13,6 +13,8 @@ interface BadgeProps { style?: React.CSSProperties; prefixCls?: string; className?: string; + status?: 'success' | 'processing' | 'default' | 'error' | 'warning'; + text?: string; } export default class Badge extends React.Component { @@ -21,6 +23,7 @@ export default class Badge extends React.Component { count: null, dot: false, overflowCount: 99, + // status: 'default', }; static propTypes = { @@ -33,18 +36,25 @@ export default class Badge extends React.Component { }; render() { - let { count, prefixCls, overflowCount, className, style, children, dot } = this.props; + let { count, prefixCls, overflowCount, className, style, children, dot, status, text } = this.props; + const isDot = dot || status; count = count > overflowCount ? `${overflowCount}+` : count; // dot mode don't need count - if (dot) { + if (isDot) { count = ''; } // null undefined "" "0" 0 - const hidden = (!count || count === '0') && !dot; - const scrollNumberCls = prefixCls + (dot ? '-dot' : '-count'); + const hidden = (!count || count === '0') && !isDot; + const scrollNumberCls = classNames({ + [`${prefixCls}-dot`]: isDot, + [`${prefixCls}-count`]: !isDot, + [`${prefixCls}-status`]: status, + [`${prefixCls}-status-${status}`]: status, + [`${prefixCls}-status-with-text`]: text, + }); const badgeCls = classNames({ [className]: !!className, [prefixCls]: true, @@ -70,6 +80,10 @@ export default class Badge extends React.Component { /> } + { + hidden || !text ? null : + {text} + } ); } diff --git a/components/badge/index.zh-CN.md b/components/badge/index.zh-CN.md index 4a93a7e40e..9a3284d631 100644 --- a/components/badge/index.zh-CN.md +++ b/components/badge/index.zh-CN.md @@ -15,7 +15,7 @@ english: Badge ```jsx - + ``` @@ -28,4 +28,6 @@ english: Badge |----------------|----------------------------------|------------|---------|--------| | count | 展示的数字,大于 overflowCount 时显示为 `${overflowCount}+`,为 0 时隐藏 | Number | | | | overflowCount | 展示封顶的数字值 | Number | | 99 | -| dot | 不展示数字,只有一个小红点 | boolean | | false | +| dot | 不展示数字,只有一个小红点 | Boolean | | false | +| status | 设置 Badge 为状态点 | Enum | 'success'、'processing'、'default'、'error'、'warning' | '' | +| text | 在设置了 `status` 的前提下有效,设置状态点的文本 | String | | '' | diff --git a/components/badge/style/index.less b/components/badge/style/index.less index 84f4f114f4..af5bcb6d1a 100644 --- a/components/badge/style/index.less +++ b/components/badge/style/index.less @@ -47,6 +47,38 @@ box-shadow: 0 0 0 1px #fff; } + &-status { + width: 6px; + height: 6px; + + &-success { + background-color: @success-color; + } + &-processing { + background-color: @primary-color; + animation: antStatusProcessing 1.2s infinite ease-in-out; + } + &-default { + background-color: @normal-color; + } + &-error { + background-color: @error-color; + } + &-warning { + background-color: @warning-color; + } + + &-with-text { + top: 5px; + } + + &-text { + color: @text-color; + font-size: @font-size-base; + margin-left: 8px; // 8 - (6 / 2) === 5 + } + } + &-zoom-appear, &-zoom-enter { animation: antZoomBadgeIn .3s @ease-out-back; @@ -66,6 +98,16 @@ } } +@keyframes antStatusProcessing { + 0%, + 100% { + opacity: 1; + } + 50% { + opacity: 0; + } +} + a & { &-count:hover { background: tint(@error-color, 20%); diff --git a/components/button/button.tsx b/components/button/button.tsx index 10a7a189a9..b95679b4ec 100644 --- a/components/button/button.tsx +++ b/components/button/button.tsx @@ -35,6 +35,7 @@ interface ButtonProps { shape?: ButtonShape; size?: ButtonSize; onClick?: React.FormEventHandler; + onMouseUp?: React.FormEventHandler; loading?: boolean; disabled?: boolean; style?: React.CSSProperties; diff --git a/components/calendar/Header.tsx b/components/calendar/Header.tsx index f2f3a4d9d4..9715e1dadd 100644 --- a/components/calendar/Header.tsx +++ b/components/calendar/Header.tsx @@ -7,7 +7,19 @@ const Option = Select.Option; function noop() {} -export default class Header extends React.Component { +export interface HeaderProps { + prefixCls?: string; + locale?: any; + fullscreen?: boolean; + yearSelectOffset?: number; + yearSelectTotal?: number; + type?: string; + onValueChange?: (value) => void; + onTypeChange?: (type: string) => void; + value: any; +} + +export default class Header extends React.Component { static defaultProps = { prefixCls: `${PREFIX_CLS}-header`, yearSelectOffset: 10, diff --git a/components/calendar/index.tsx b/components/calendar/index.tsx index 677977aaab..bb185e838e 100644 --- a/components/calendar/index.tsx +++ b/components/calendar/index.tsx @@ -16,7 +16,27 @@ function zerofixed(v) { return `${v}`; } -export default class Calendar extends React.Component { +interface CalendarContext { + antLocale?: { + Calendar?: any + }; +} + +export interface CalendarProps { + prefixCls?: string; + className?: string; + value?: Date; + defaultValue?: Date; + mode?: 'month' | 'year'; + fullscreen?: boolean; + dateCellRender?: (date) => React.ReactNode; + monthCellRender?: (month) => React.ReactNode; + locale?: any; + style?: React.CSSProperties; + onPanelChange?: (date: Date, mode: string) => void; +} + +export default class Calendar extends React.Component { static defaultProps = { monthCellRender: noop, dateCellRender: noop, @@ -43,6 +63,8 @@ export default class Calendar extends React.Component { antLocale: PropTypes.object, }; + context: CalendarContext; + constructor(props) { super(props); this.state = { diff --git a/components/calendar/locale/en_US.tsx b/components/calendar/locale/en_US.tsx index 1fde2c098a..6847cc35d8 100644 --- a/components/calendar/locale/en_US.tsx +++ b/components/calendar/locale/en_US.tsx @@ -1 +1,2 @@ -module.exports = require('../../date-picker/locale/en_US'); +import en_US from '../../date-picker/locale/en_US'; +export default en_US; diff --git a/components/calendar/locale/ru_RU.tsx b/components/calendar/locale/ru_RU.tsx index aea2dd9a41..c1feaedaea 100644 --- a/components/calendar/locale/ru_RU.tsx +++ b/components/calendar/locale/ru_RU.tsx @@ -1 +1,2 @@ -module.exports = require('../../date-picker/locale/ru_RU'); +import ru_RU from '../../date-picker/locale/ru_RU'; +export default ru_RU; diff --git a/components/calendar/locale/zh_CN.tsx b/components/calendar/locale/zh_CN.tsx index 1880b1a980..9c83ec8453 100644 --- a/components/calendar/locale/zh_CN.tsx +++ b/components/calendar/locale/zh_CN.tsx @@ -1 +1,2 @@ -module.exports = require('../../date-picker/locale/zh_CN'); +import zh_CN from '../../date-picker/locale/zh_CN'; +export default zh_CN; diff --git a/components/carousel/index.tsx b/components/carousel/index.tsx index 721af47654..af7feeba4a 100644 --- a/components/carousel/index.tsx +++ b/components/carousel/index.tsx @@ -2,8 +2,9 @@ // https://github.com/WickyNilliams/enquire.js/issues/82 import assign from 'object-assign'; if (typeof window !== 'undefined') { - const matchMediaPolyfill = function matchMediaPolyfill() { + const matchMediaPolyfill = function matchMediaPolyfill(mediaQuery: string): MediaQueryList { return { + media: mediaQuery, matches: false, addListener() { }, @@ -23,7 +24,7 @@ export interface CarouselProps { /** 动画效果函数,可取 scrollx, fade */ effect?: CarouselEffect; /** 是否显示面板指示点 */ - dots?: SlickCarouselboolean; + dots?: boolean; /** 垂直显示 */ vertical?: boolean; /** 是否自动切换 */ diff --git a/components/checkbox/Group.tsx b/components/checkbox/Group.tsx index 24cc6fb05b..7d923ba552 100644 --- a/components/checkbox/Group.tsx +++ b/components/checkbox/Group.tsx @@ -59,12 +59,13 @@ export default class CheckboxGroup extends React.Component { + // https://github.com/Microsoft/TypeScript/issues/7960 + return (options as Array).map(option => { if (typeof option === 'string') { return { label: option, value: option, - }; + } as CheckboxOptionType; } return option; }); diff --git a/components/checkbox/demo/disable.md b/components/checkbox/demo/disabled.md similarity index 100% rename from components/checkbox/demo/disable.md rename to components/checkbox/demo/disabled.md diff --git a/components/date-picker/Calendar.tsx b/components/date-picker/Calendar.tsx index ce7939bad1..bb60c4cf48 100644 --- a/components/date-picker/Calendar.tsx +++ b/components/date-picker/Calendar.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import CalendarLocale from 'rc-calendar/lib/locale/zh_CN'; import RcCalendar from 'rc-calendar'; -export default class Calendar extends React.Component { +export default class Calendar extends React.Component { static defaultProps = { locale: CalendarLocale, prefixCls: 'ant-calendar', diff --git a/components/date-picker/RangePicker.tsx b/components/date-picker/RangePicker.tsx index 5755828661..0ef673c41f 100644 --- a/components/date-picker/RangePicker.tsx +++ b/components/date-picker/RangePicker.tsx @@ -5,7 +5,7 @@ import RcDatePicker from 'rc-calendar/lib/Picker'; import classNames from 'classnames'; import Icon from '../icon'; -export default class RangePicker extends React.Component { +export default class RangePicker extends React.Component { static defaultProps = { defaultValue: [], }; @@ -74,7 +74,7 @@ export default class RangePicker extends React.Component { let pickerChangeHandler = { onChange: this.handleChange, }; - let calendarHandler = { + let calendarHandler: Object = { onOk: this.handleChange, }; if (props.timePicker) { diff --git a/components/date-picker/createPicker.tsx b/components/date-picker/createPicker.tsx index 0aea0d27fa..d34fd5d59a 100644 --- a/components/date-picker/createPicker.tsx +++ b/components/date-picker/createPicker.tsx @@ -6,6 +6,11 @@ import classNames from 'classnames'; import assign from 'object-assign'; import Icon from '../icon'; +export interface PickerProps { + parseDateFromValue?: Function; + value?: string | Date; +} + export default function createPicker(TheCalendar) { // use class typescript error const CalenderWrapper = React.createClass({ @@ -16,7 +21,7 @@ export default function createPicker(TheCalendar) { }; }, - componentWillReceiveProps(nextProps) { + componentWillReceiveProps(nextProps: PickerProps) { if ('value' in nextProps) { this.setState({ value: nextProps.parseDateFromValue(nextProps.value), @@ -60,10 +65,10 @@ export default function createPicker(TheCalendar) { }); // 需要选择时间时,点击 ok 时才触发 onChange - let pickerChangeHandler = { + let pickerChangeHandler: Object = { onChange: this.handleChange, }; - let calendarHandler = { + let calendarHandler: Object = { onOk: this.handleChange, // fix https://github.com/ant-design/ant-design/issues/1902 onSelect: (value, cause) => { @@ -95,7 +100,7 @@ export default function createPicker(TheCalendar) { ); // default width for showTime - const pickerStyle = {}; + const pickerStyle = { width: undefined }; if (props.showTime) { pickerStyle.width = 180; } diff --git a/components/date-picker/demo/locale.md b/components/date-picker/demo/locale.md index 8e1ebcc655..eabd7a8511 100644 --- a/components/date-picker/demo/locale.md +++ b/components/date-picker/demo/locale.md @@ -7,11 +7,11 @@ title: ## zh-CN -通过 `locale` 配置时区、语言等, 默认支持 `en_US`,`zh_CN`。 +通过 `locale` 配置时区、语言等, 默认支持 `en_US`,`zh_CN`。不同版本带有不同的时区配置,如果所在时区与默认配置不同,需要自行设置。上面的 demo 就是在东八区使用 en_US 版本的例子。 ## en-US -Use locale to set the properties like time zone, language and etc. en_US, zh_CN are supported by default. +Use locale to set the properties like time zone, language and etc. `en_US`, `zh_CN` are supported by default. There are different time zone configuration in different versions, you must set it by yourself if your time zone does not match the default setting. The example above is to show how to use the `en_US` version at GMT+8 time zone. ````jsx @@ -19,7 +19,7 @@ import { DatePicker } from 'antd'; import enUS from 'antd/lib/date-picker/locale/en_US'; const customLocale = { - timezoneOffset: 0 * 60, + timezoneOffset: 8 * 60, firstDayOfWeek: 0, minimalDaysInFirstWeek: 1, }; diff --git a/components/date-picker/index.tsx b/components/date-picker/index.tsx index 9c33a6efb4..108cc7824e 100644 --- a/components/date-picker/index.tsx +++ b/components/date-picker/index.tsx @@ -1,15 +1,49 @@ +import * as React from 'react'; +import assign from 'object-assign'; import RcCalendar from 'rc-calendar'; import MonthCalendar from 'rc-calendar/lib/MonthCalendar'; import createPicker from './createPicker'; import wrapPicker from './wrapPicker'; import RangePicker from './RangePicker'; import Calendar from './Calendar'; +import { TimePickerProps } from '../time-picker'; -const DatePicker = wrapPicker(createPicker(RcCalendar)); -const MonthPicker = wrapPicker(createPicker(MonthCalendar), 'yyyy-MM'); +interface PickerProps { + format?: string; + disabled?: boolean; + style?: React.CSSProperties; + popupStyle?: React.CSSProperties; + locale?: any; + size?: 'large' | 'small' | 'default'; + getCalendarContainer?: (trigger) => React.ReactNode; +} -DatePicker.Calendar = Calendar; -DatePicker.RangePicker = wrapPicker(RangePicker); -DatePicker.MonthPicker = MonthPicker; +interface SinglePickerProps { + value?: string | Date; + defaultValue?: string | Date; + onChange?: (date: Date, dateString: string) => void; +} + +export interface DatePickerProps extends PickerProps, SinglePickerProps { + showTime?: TimePickerProps; +} +const DatePicker = wrapPicker(createPicker(RcCalendar)) as React.ClassicComponentClass; + +export interface MonthPickerProps extends PickerProps, SinglePickerProps { +} +const MonthPicker = wrapPicker(createPicker(MonthCalendar), 'yyyy-MM') as React.ClassicComponentClass; + +export interface RangePickerProps extends PickerProps { + value?: [string | Date, string | Date]; + defaultValue?: [string | Date, string | Date]; + onChange?: (dates: [Date, Date], dateStrings: [String, String]) => void; + showTime?: TimePickerProps; +} + +assign(DatePicker, { + RangePicker: wrapPicker(RangePicker) as React.ClassicComponentClass, + Calendar, + MonthPicker, +}); export default DatePicker; diff --git a/components/date-picker/wrapPicker.tsx b/components/date-picker/wrapPicker.tsx index 5eece135f8..bfb93b465c 100644 --- a/components/date-picker/wrapPicker.tsx +++ b/components/date-picker/wrapPicker.tsx @@ -7,7 +7,7 @@ import classNames from 'classnames'; import defaultLocale from './locale/zh_CN'; import assign from 'object-assign'; -export default function wrapPicker(Picker, defaultFormat) { +export default function wrapPicker(Picker, defaultFormat?) { const PickerWrapper = React.createClass({ getDefaultProps() { return { @@ -46,7 +46,7 @@ export default function wrapPicker(Picker, defaultFormat) { getFormatter() { const format = this.props.format; - const formatter = new DateTimeFormat(format, this.getLocale().lang.format); + const formatter = new DateTimeFormat(format as string, this.getLocale().lang.format); return formatter; }, diff --git a/components/dropdown/demo/basic.md b/components/dropdown/demo/basic.md index 2c7e45a9d0..2f6b962545 100644 --- a/components/dropdown/demo/basic.md +++ b/components/dropdown/demo/basic.md @@ -19,13 +19,13 @@ import { Menu, Dropdown, Icon } from 'antd'; const menu = ( - 第一个菜单项 + 第一个菜单项 - 第二个菜单项 + 第二个菜单项 - 第三个菜单项 + 第三个菜单项 ); diff --git a/components/dropdown/demo/item.md b/components/dropdown/demo/item.md index 4668428509..8ab8c165a6 100644 --- a/components/dropdown/demo/item.md +++ b/components/dropdown/demo/item.md @@ -19,10 +19,10 @@ import { Menu, Dropdown, Icon } from 'antd'; const menu = ( - 第一个菜单项 + 第一个菜单项 - 第二个菜单项 + 第二个菜单项 第三个菜单项(不可用) diff --git a/components/dropdown/dropdown-button.tsx b/components/dropdown/dropdown-button.tsx index acdacad89b..0fe00bb589 100644 --- a/components/dropdown/dropdown-button.tsx +++ b/components/dropdown/dropdown-button.tsx @@ -5,7 +5,18 @@ import Dropdown from './dropdown'; const ButtonGroup = Button.Group; import classNames from 'classnames'; import splitObject from '../_util/splitObject'; -export default class DropdownButton extends React.Component { + +export interface DropdownButtonProps { + type?: 'primary' | 'ghost' | 'dash'; + onClick?: React.FormEventHandler; + trigger?: 'click' | 'hover'; + overlay: React.ReactNode; + visible?: boolean; + onVisibleChange?: (visible: boolean) => void; + style?: React.CSSProperties; +} + +export default class DropdownButton extends React.Component { static defaultProps = { align: { points: ['tr', 'br'], diff --git a/components/dropdown/dropdown.tsx b/components/dropdown/dropdown.tsx index e10fa7280e..53b6e5f576 100644 --- a/components/dropdown/dropdown.tsx +++ b/components/dropdown/dropdown.tsx @@ -2,13 +2,16 @@ import * as React from 'react'; import RcDropdown from 'rc-dropdown'; export interface DropDownProps { - trigger: string[]; + trigger?: Array<'click' | 'hover'>; overlay: React.ReactNode; - visible: boolean; - onVisibleChange: (visible: boolean) => void; + style?: React.CSSProperties; + onVisibleChange?: (visible: boolean) => void; + visible?: boolean; + align?: Object; } export default class Dropdown extends React.Component { + static Button: React.ReactNode; static defaultProps = { transitionName: 'slide-up', prefixCls: 'ant-dropdown', diff --git a/components/dropdown/index.zh-CN.md b/components/dropdown/index.zh-CN.md index e8be508a1c..7e01eddb93 100644 --- a/components/dropdown/index.zh-CN.md +++ b/components/dropdown/index.zh-CN.md @@ -31,9 +31,9 @@ english: Dropdown | 参数 | 说明 | 类型 | 默认值 | |-------------|------------------|--------------------|--------------| -| type | 按钮类型,和 [Button](/components/button) 一致 | String | 'default' | -| onClick | 点击左侧按钮的回调,和 [Button](/components/button) 一致 | Function | - | +| type | 按钮类型,和 [Button](/components/button/) 一致 | String | 'default' | +| onClick | 点击左侧按钮的回调,和 [Button](/components/button/) 一致 | Function | - | | trigger | 触发下拉的行为 | ['click'] or ['hover'] | ['hover'] | -| overlay | 菜单 | [Menu](/components/menu) | - | +| overlay | 菜单 | [Menu](/components/menu/) | - | | visible | 菜单是否显示 | Boolean | - | | onVisibleChange | 菜单显示状态改变时调用,参数为 { visible } | Function | - | diff --git a/components/form/Form.tsx b/components/form/Form.tsx index 140dad9637..0190340e96 100644 --- a/components/form/Form.tsx +++ b/components/form/Form.tsx @@ -1,10 +1,83 @@ import * as React from 'react'; +import { PropTypes } from 'react'; import classNames from 'classnames'; import PureRenderMixin from 'react-addons-pure-render-mixin'; import omit from 'object.omit'; import warning from 'warning'; +import assign from 'object-assign'; +import FormItem from './FormItem'; +import createDOMForm from 'rc-form/lib/createDOMForm'; +import { FIELD_META_PROP } from './constants'; -export default class Form extends React.Component { +export interface FormCreateOption { + onFieldsChange?: (props: any, fields: Array) => void; + mapPropsToFields?: (props: any) => void; +} + +export interface FormProps { + horizontal?: boolean; + inline?: boolean; + vertical?: boolean; + form?: Object; + onSubmit?: React.FormEventHandler; + style?: React.CSSProperties; + className?: string; + prefixCls?: string; +} + +// function create +export type WrappedFormUtils = { + /** 获取一组输入控件的值,如不传入参数,则获取全部组件的值 */ + getFieldsValue(fieldNames?: Array): Object; + /** 获取一个输入控件的值*/ + getFieldValue(fieldName: string): any; + /** 设置一组输入控件的值*/ + setFieldsValue(obj: Object): void; + /** 设置一组输入控件的值*/ + setFields(obj: Object): void; + /** 校验并获取一组输入域的值与 Error */ + validateFields(fieldNames?: Array, options?: Object, callback?: (erros: any, values: any) => void): any; + /** 与 `validateFields` 相似,但校验完后,如果校验不通过的菜单域不在可见范围内,则自动滚动进可见范围 */ + validateFieldsAndScroll( + fieldNames?: Array, + options?: Object, + callback?: (erros: any, values: any) => void + ): void; + /** 获取某个输入控件的 Error */ + getFieldError(name: string): Object[]; + /** 判断一个输入控件是否在校验状态*/ + isFieldValidating(name: string): boolean; + /** 重置一组输入控件的值与状态,如不传入参数,则重置所有组件 */ + resetFields(names?: Array): void; + + getFieldProps(id: string, options: { + /** 子节点的值的属性,如 Checkbox 的是 'checked' */ + valuePropName?: string; + /** 子节点的初始值,类型、可选值均由子节点决定 */ + initialValue?: any; + /** 收集子节点的值的时机 */ + trigger?: string; + /** 校验子节点值的时机 */ + validateTrigger?: string; + /** 校验规则,参见 [async-validator](https://github.com/yiminghe/async-validator) */ + rules?: Array; + /** 必填输入控件唯一标志 */ + id?: string; + }): Array; +} + +export interface FormComponentProps { + form: WrappedFormUtils; +} + +class FormComponent extends React.Component { +} + +export interface ComponentDecorator { + (component: T): T; +} + +export default class Form extends React.Component { static defaultProps = { prefixCls: 'ant-form', onSubmit(e) { @@ -21,6 +94,33 @@ export default class Form extends React.Component { onSubmit: React.PropTypes.func, }; + static Item = FormItem; + + static create = (options?: FormCreateOption): ComponentDecorator => { + const formWrapper = createDOMForm(assign({}, options, { + fieldNameProp: 'id', + fieldMetaProp: FIELD_META_PROP, + })); + + /* eslint-disable react/prefer-es6-class */ + return (Component) => formWrapper(React.createClass({ + propTypes: { + form: PropTypes.object.isRequired, + }, + childContextTypes: { + form: PropTypes.object.isRequired, + }, + getChildContext() { + return { + form: this.props.form, + }; + }, + render() { + return ; + }, + })); + }; + constructor(props) { super(props); diff --git a/components/form/FormItem.tsx b/components/form/FormItem.tsx index 5e237bfc09..cb741ea1f2 100644 --- a/components/form/FormItem.tsx +++ b/components/form/FormItem.tsx @@ -3,9 +3,35 @@ import classNames from 'classnames'; import PureRenderMixin from 'react-addons-pure-render-mixin'; import Row from '../row'; import Col from '../col'; +import { WrappedFormUtils } from './Form'; import { FIELD_META_PROP } from './constants'; -export default class FormItem extends React.Component { +export interface FormItemLabelColOption { + span: number; + offset: number; +} + +export interface FormItemProps { + prefixCls?: string; + id?: string; + label?: string; + labelCol?: FormItemLabelColOption; + wrapperCol?: FormItemLabelColOption; + help?: React.ReactNode; + extra?: string; + validateStatus?: 'success' | 'warning' | 'error' | 'validating'; + hasFeedback?: boolean; + className?: string; + required?: boolean; + style?: React.CSSProperties; + colon?: boolean; +} + +export interface FormItemContext { + form: WrappedFormUtils; +} + +export default class FormItem extends React.Component { static defaultProps = { hasFeedback: false, prefixCls: 'ant-form', @@ -14,7 +40,7 @@ export default class FormItem extends React.Component { static propTypes = { prefixCls: React.PropTypes.string, - label: React.PropTypes.node, + label: React.PropTypes.string, labelCol: React.PropTypes.object, help: React.PropTypes.oneOfType([React.PropTypes.node, React.PropTypes.bool]), validateStatus: React.PropTypes.oneOf(['', 'success', 'warning', 'error', 'validating']), @@ -30,6 +56,8 @@ export default class FormItem extends React.Component { form: React.PropTypes.object, }; + context: FormItemContext; + shouldComponentUpdate(...args) { return PureRenderMixin.shouldComponentUpdate.apply(this, args); } @@ -46,14 +74,14 @@ export default class FormItem extends React.Component { getOnlyControl() { const children = React.Children.toArray(this.props.children); - const child = children.filter((c) => { + const child = children.filter((c: React.ReactElement) => { return c.props && FIELD_META_PROP in c.props; })[0]; return child !== undefined ? child : null; } getChildProp(prop) { - const child = this.getOnlyControl(); + const child = this.getOnlyControl() as React.ReactElement; return child && child.props && child.props[prop]; } @@ -173,7 +201,7 @@ export default class FormItem extends React.Component { renderChildren() { const props = this.props; - const children = React.Children.map(props.children, (child) => { + const children = React.Children.map(props.children, (child: React.ReactElement) => { if (child && typeof child.type === 'function' && !child.props.size) { return React.cloneElement(child, { size: 'large' }); } diff --git a/components/form/ValueMixin.tsx b/components/form/ValueMixin.tsx deleted file mode 100644 index 53083b2f62..0000000000 --- a/components/form/ValueMixin.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import assign from 'object-assign'; -const ValueMixin = { - setValue(field, e) { - let v = e; - const target = e && e.target; - if (target) { - if ((`${target.nodeName}`).toLowerCase() === 'input' && - target.type === 'checkbox') { - v = target.checked; - } else { - v = e.target.value; - } - } - const newFormData = {}; - newFormData[field] = v; - this.setState({ - formData: assign({}, this.state.formData, newFormData), - }); - }, -}; - -export default ValueMixin; diff --git a/components/form/demo/validate-basic.md b/components/form/demo/validate-basic.md index d1dcd7136b..32f9113453 100644 --- a/components/form/demo/validate-basic.md +++ b/components/form/demo/validate-basic.md @@ -1,6 +1,6 @@ --- order: 11 -title: +title: zh-CN: 表单校验 en-US: Basic validate --- @@ -31,7 +31,7 @@ let BasicDemo = React.createClass({ handleSubmit(e) { e.preventDefault(); this.props.form.validateFields((errors, values) => { - if (!!errors) { + if (errors) { console.log('Errors in form!!!'); return; } diff --git a/components/form/demo/validate-customized.md b/components/form/demo/validate-customized.md index 92aa9a52df..e7752decd3 100644 --- a/components/form/demo/validate-customized.md +++ b/components/form/demo/validate-customized.md @@ -1,6 +1,6 @@ --- order: 13 -title: +title: zh-CN: 自定义校验规则 en-US: Customized validation --- @@ -40,7 +40,7 @@ let Demo = React.createClass({ handleSubmit() { this.props.form.validateFields((errors, values) => { - if (!!errors) { + if (errors) { console.log('Errors in form!!!'); return; } @@ -60,17 +60,14 @@ let Demo = React.createClass({ } else { strength = 'H'; } - if (type === 'pass') { - this.setState({ passBarShow: true, passStrength: strength }); - } else { - this.setState({ rePassBarShow: true, rePassStrength: strength }); - } + this.setState({ + [`${type}BarShow`]: true, + [`${type}Strength`]: strength, + }); } else { - if (type === 'pass') { - this.setState({ passBarShow: false }); - } else { - this.setState({ rePassBarShow: false }); - } + this.setState({ + [`${type}BarShow`]: false, + }); } }, @@ -113,9 +110,9 @@ let Demo = React.createClass({ return (
    -
  • -
  • -
  • +
  • +
  • +
  • {level[strength]} diff --git a/components/form/demo/validate-other.md b/components/form/demo/validate-other.md index a063d0c2bf..84057d328a 100644 --- a/components/form/demo/validate-other.md +++ b/components/form/demo/validate-other.md @@ -1,6 +1,6 @@ --- order: 12 -title: +title: zh-CN: 校验其他组件 en-US: Others components related to validation --- @@ -37,7 +37,7 @@ let Demo = React.createClass({ handleSubmit(e) { e.preventDefault(); this.props.form.validateFieldsAndScroll((errors, values) => { - if (!!errors) { + if (errors) { console.log('Errors in form!!!'); return; } diff --git a/components/form/index.en-US.md b/components/form/index.en-US.md index d5b68f2f16..f2aba47f66 100644 --- a/components/form/index.en-US.md +++ b/components/form/index.en-US.md @@ -101,7 +101,8 @@ The return value of `getFieldProps` contains `id`、`value`(or any other props ` ### Form.Item -> If Form.Item has multiple children, `help`, `required`, and `validateStatus` can't be generated automatically. +> * If Form.Item has multiple children, `help`, `required`, and `validateStatus` can't be generated automatically. +> * Form controls must be child of Form.Item, otherwise, you need to set `help`, `required` and `validateStatus` by yourself. | Property | Description | Type | Optional | Default Value | |-----------|------------------------------------------|-----------|-------|--------| diff --git a/components/form/index.tsx b/components/form/index.tsx index f1300440e0..d0b8553235 100644 --- a/components/form/index.tsx +++ b/components/form/index.tsx @@ -1,40 +1,3 @@ -import React, { PropTypes } from 'react'; -import createDOMForm from 'rc-form/lib/createDOMForm'; import Form from './Form'; -import FormItem from './FormItem'; -import ValueMixin from './ValueMixin'; -import assign from 'object-assign'; -import { FIELD_META_PROP } from './constants'; - -Form.create = (o = {}) => { - const options = assign({}, o, { - fieldNameProp: 'id', - fieldMetaProp: FIELD_META_PROP, - }); - const formWrapper = createDOMForm(options); - - /* eslint-disable react/prefer-es6-class */ - return (Component) => formWrapper(React.createClass({ - propTypes: { - form: PropTypes.object.isRequired, - }, - childContextTypes: { - form: PropTypes.object.isRequired, - }, - getChildContext() { - return { - form: this.props.form, - }; - }, - render() { - return ; - }, - })); -}; - -Form.Item = FormItem; - -// @Deprecated -Form.ValueMixin = ValueMixin; export default Form; diff --git a/components/form/index.zh-CN.md b/components/form/index.zh-CN.md index 93207469cd..3b0b470a9c 100644 --- a/components/form/index.zh-CN.md +++ b/components/form/index.zh-CN.md @@ -103,7 +103,8 @@ CustomizedForm = Form.create({})(CustomizedForm); ### Form.Item -> 一个 Form.Item 建议只放一个 child,有多个 child 时,`help` `required` `validateStatus` 无法自动生成。 +> * 一个 Form.Item 建议只放一个 child,有多个 child 时,`help` `required` `validateStatus` 无法自动生成。 +> * 只有当表单域为 Form.Item 的子元素时,才会自动生成 `help` `required` `validateStatus`,其它情况请自行设置。 | 参数 | 说明 | 类型 | 可选值 | 默认值 | |-----------|------------------------------------------|-----------|-------|--------| diff --git a/components/icon/index.en-US.md b/components/icon/index.en-US.md new file mode 100644 index 0000000000..fbde34db92 --- /dev/null +++ b/components/icon/index.en-US.md @@ -0,0 +1,125 @@ +--- +category: Components +chinese: 图标 +type: Basic +english: Icon +toc: false +--- + +Meaningful vector graphics. + +## Icons naming convention + +We provide semantic name for every icon, and naming rules are as follows: + +- Scanning line icon has the similar name with its solid one,but it's distinguished by `-o`, for example, `question-circle`(a full circle) and `question-circle-o`(an empty circle); + +- Naming sequence:`[icon's name]-[shape, optional]-[Scanning line or not]-[direction, optional]`. + +## How to use + +Use tag to create an icon and set its type in the type prop, for example: + +```html + +``` + +Finally, it will be rendered as follow: + +```html + +``` + +## Local deployment of icons font + +By default, icon components uses [iconfont.cn](http://iconfont.cn), publicly available repository of a huge set of icons. In case you need to use a locally deployed version of the icon font, you can refer to [this example](https://github.com/ant-design/antd-init/tree/master/examples/local-iconfont)。 + +## List of icons + +> Click the icon and copy the code。 + +### 一. Directional Icons + +```__react +import IconSet from 'site/theme/template/IconSet'; +const icons1 = ['step-backward', 'step-forward', 'fast-backward', 'fast-forward', 'shrink', 'arrow-salt', 'down', 'up', 'left', 'right', 'caret-down', 'caret-up', 'caret-left', 'caret-right', 'caret-circle-right', 'caret-circle-left', 'caret-circle-o-right', 'caret-circle-o-left', 'circle-right', 'circle-left', 'circle-o-right', 'circle-o-left', 'double-right', 'double-left', 'verticle-right', 'verticle-left', 'forward', 'backward', 'rollback', 'enter', 'retweet', 'swap', 'swap-left', 'swap-right', 'arrow-right', 'arrow-up', 'arrow-down', 'arrow-left', 'play-circle', 'play-circle-o', 'circle-up', 'circle-down', 'circle-o-up', 'circle-o-down', 'caret-circle-o-up', 'caret-circle-o-down', 'caret-circle-up', 'caret-circle-down']; + +ReactDOM.render(, mountNode); +``` + +### 二. Suggested Icons + +```__react +const icons2 = ['question', 'question-circle-o', 'question-circle', 'plus', 'plus-circle-o', 'plus-circle', 'pause', 'pause-circle-o', 'pause-circle', 'minus', 'minus-circle-o', 'minus-circle', 'plus-square', 'minus-square', 'info', 'info-circle-o', 'info-circle', 'exclamation', 'exclamation-circle-o', 'exclamation-circle', 'cross', 'cross-circle-o', 'cross-circle', 'check', 'check-circle-o', 'check-circle', 'clock-circle-o', 'clock-circle']; + +ReactDOM.render(, mountNode); +``` + +### 三. Universal Icons + +```__react +const icons3 = ['lock', 'unlock', 'android', 'apple', 'area-chart', 'bar-chart', 'bars', 'book', 'calendar', 'cloud', 'cloud-download', 'code', 'copy', 'credit-card', 'delete', 'desktop', 'download', 'edit', 'ellipsis', 'file', 'file-text', 'file-unknown', 'file-pdf','file-excel', 'file-jpg', 'file-ppt', 'folder', 'folder-open', 'github', 'hdd', 'frown', 'meh', 'inbox', 'laptop', 'appstore-o', 'appstore', 'line-chart', 'link', 'logout', 'mail', 'menu-fold', 'menu-unfold', 'mobile', 'notification', 'paper-clip', 'picture', 'pie-chart', 'poweroff', 'reload', 'search', 'setting', 'share-alt', 'shopping-cart', 'smile', 'tablet', 'tag', 'tags', 'to-top', 'upload', 'user', 'video-camera', 'windows', 'ie', 'chrome', 'home', 'loading', 'smile-circle', 'meh-circle', 'frown-circle', 'tags-o', 'tag-o', 'cloud-upload-o', 'cloud-download-o', 'cloud-upload', 'cloud-o', 'star-o', 'star', 'heart-o', 'heart', 'environment', 'environment-o', 'eye', 'eye-o', 'camera', 'camera-o', 'aliwangwang', 'aliwangwang-o', 'save', 'team', 'solution', 'phone', 'filter', 'exception', 'export', 'customerservice', 'qrcode', 'scan', 'like', 'dislike', 'message', 'pay-circle', 'pay-circle-o', 'calculator', 'pushpin', 'pushpin-o']; + +ReactDOM.render(, mountNode); +``` + + + diff --git a/components/icon/index.tsx b/components/icon/index.tsx index 54f5cee4ff..26b4bb0b11 100644 --- a/components/icon/index.tsx +++ b/components/icon/index.tsx @@ -1,6 +1,13 @@ import * as React from 'react'; -export default props => { +export interface IconProps { + type: string; + className?: string; + title?: string; + onClick?: (e) => void; +} + +export default (props: IconProps) => { const { type, className = '' } = props; return ; }; diff --git a/components/icon/index.md b/components/icon/index.zh-CN.md similarity index 100% rename from components/icon/index.md rename to components/icon/index.zh-CN.md diff --git a/components/input-number/demo/basic.md b/components/input-number/demo/basic.md index 3d1c63dfaf..bafc92bcd1 100644 --- a/components/input-number/demo/basic.md +++ b/components/input-number/demo/basic.md @@ -1,10 +1,18 @@ --- order: 0 -title: 基本 +title: + zh-CN: 基本 + en-US: Basic --- +## zh-CN + 数字输入框。 +## en-US + +Numeric-only input box. + ````jsx import { InputNumber } from 'antd'; diff --git a/components/input-number/demo/digit.md b/components/input-number/demo/digit.md index e3cdc4b978..d7e1eb4ff3 100644 --- a/components/input-number/demo/digit.md +++ b/components/input-number/demo/digit.md @@ -1,10 +1,18 @@ --- order: 3 -title: 小数 +title: + zh-CN: 小数 + en-US: Decimals --- +## zh-CN + 和原生的数字输入框一样,value 的精度由 step 的小数位数决定。 +## en-US + +A numeric-only input box whose values can be increased or decreased using a decimal step. The number of decimals (also known as precision) is determined by the step prop. + ````jsx import { InputNumber } from 'antd'; diff --git a/components/input-number/demo/disabled.md b/components/input-number/demo/disabled.md index a81d30b478..b1012df468 100644 --- a/components/input-number/demo/disabled.md +++ b/components/input-number/demo/disabled.md @@ -1,10 +1,18 @@ --- order: 2 -title: 不可用 +title: + zh-CN: 不可用 + en-US: Disabled --- +## zh-CN + 点击按钮切换可用状态。 +## en-US + +Click the button to toggle between available and disabled states. + ````jsx import { InputNumber, Button } from 'antd'; diff --git a/components/input-number/demo/size.md b/components/input-number/demo/size.md index 519c33344c..0b2f5c3504 100644 --- a/components/input-number/demo/size.md +++ b/components/input-number/demo/size.md @@ -1,10 +1,18 @@ --- order: 1 -title: 三种大小 +title: + zh-CN: 三种大小 + en-US: Sizes --- +## zh-CN + 三种大小的数字输入框,当 size 分别为 `large` 和 `small` 时,输入框高度为 `32px` 和 `22px` ,默认高度为 `28px` +## en-US + +There are three sizes available to a numeric input box. By default, the size is `28px`. The two additional sizes are `large` and `small` which means `32px` and `22px`, respectively. + ````jsx import { InputNumber } from 'antd'; diff --git a/components/input-number/index.en-US.md b/components/input-number/index.en-US.md new file mode 100644 index 0000000000..55e3a02015 --- /dev/null +++ b/components/input-number/index.en-US.md @@ -0,0 +1,25 @@ +--- +category: Components +chinese: 数字输入框 +type: Form Controls +english: InputNumber +--- + +Enter a number within certain range with the mouse or keyboard. + +## When to use + +When a numeric value needs to be provided. + +## API + +| property | description | type | default | +|-------------|----------------|--------------------|--------------| +| min | min value | Number | -Infinity | +| max | max vale | Number | Infinity | +| value | current value | Number | | +| step | The number to which the current value is increased or decreased. It can be an integer or decimal. | Number or String | 1 | +| defaultValue | initial value | Number | | +| onChange | The callback triggered when the value is changed. | Function | | +| disabled | disable the input | Boolean | false | +| size | width of input box | String | none | diff --git a/components/input-number/index.tsx b/components/input-number/index.tsx index 973026df01..fe0739a747 100644 --- a/components/input-number/index.tsx +++ b/components/input-number/index.tsx @@ -3,7 +3,19 @@ import classNames from 'classnames'; import RcInputNumber from 'rc-input-number'; import splitObject from '../_util/splitObject'; -export default class InputNumber extends React.Component { +export interface InputNumberProps { + prefixCls?: string; + min?: number; + max?: number; + value?: number; + step?: number | string; + defaultValue?: number; + onChange?: (value: number) => void; + disabled?: boolean; + size?: 'large' | 'small' | 'default'; +} + +export default class InputNumber extends React.Component { static defaultProps = { prefixCls: 'ant-input-number', step: 1, diff --git a/components/input-number/index.md b/components/input-number/index.zh-CN.md similarity index 100% rename from components/input-number/index.md rename to components/input-number/index.zh-CN.md diff --git a/components/input/Group.tsx b/components/input/Group.tsx index 36b7cbdf7b..560d3b08d7 100644 --- a/components/input/Group.tsx +++ b/components/input/Group.tsx @@ -1,7 +1,14 @@ import * as React from 'react'; import classNames from 'classnames'; -export default function Group(props) { +export interface GroupProps { + className?: string; + size?: 'large' | 'small' | 'default'; + children?: any; + style?: React.CSSProperties; +} + +const Group: React.StatelessComponent = (props) => { const className = classNames({ 'ant-input-group': true, 'ant-input-group-lg': props.size === 'large', @@ -13,8 +20,10 @@ export default function Group(props) { {props.children} ); -} +}; Group.propTypes = { children: React.PropTypes.any, }; + +export default Group; diff --git a/components/input/Input.tsx b/components/input/Input.tsx index 91f6fc0e6d..fbfbbd3192 100644 --- a/components/input/Input.tsx +++ b/components/input/Input.tsx @@ -27,7 +27,32 @@ function clearNextFrameAction(nextFrameId) { } } -export default class Input extends Component { +interface AutoSizeType { + minRows?: number; + maxRows?: number; +}; + +export interface InputProps { + prefixCls?: string; + className?: string; + type: string; + id?: number | string; + value?: any; + defaultValue?: any; + placeholder?: string; + size?: 'large' | 'default' | 'small'; + disabled?: boolean; + readOnly?: boolean; + addonBefore?: React.ReactNode; + addonAfter?: React.ReactNode; + onPressEnter?: React.FormEventHandler; + onKeyDown?: React.FormEventHandler; + onChange?: React.FormEventHandler; + autosize?: boolean | AutoSizeType; +} + +export default class Input extends Component { + static Group: any; static defaultProps = { defaultValue: '', disabled: false, @@ -58,6 +83,12 @@ export default class Input extends Component { onKeyDown: PropTypes.func, }; + nextFrameActionId: number; + refs: { + [key: string]: any; + input: any; + }; + constructor(props) { super(props); this.state = { @@ -98,8 +129,8 @@ export default class Input extends Component { if (type !== 'textarea' || !autosize || !this.refs.input) { return; } - const minRows = autosize ? autosize.minRows : null; - const maxRows = autosize ? autosize.maxRows : null; + const minRows = autosize ? (autosize as AutoSizeType).minRows : null; + const maxRows = autosize ? (autosize as AutoSizeType).maxRows : null; const textareaStyles = calculateNodeHeight(this.refs.input, false, minRows, maxRows); this.setState({ textareaStyles }); } diff --git a/components/input/demo/addon.md b/components/input/demo/addon.md index 17e2d131dd..9dd46faf6a 100644 --- a/components/input/demo/addon.md +++ b/components/input/demo/addon.md @@ -1,10 +1,18 @@ --- order: 2 -title: 前置/后置标签 +title: + zh-CN: 前置/后置标签 + en-US: Pre / Post tab --- +## zh-CN + 用于配置一些固定组合。 +## en-US + +Using pre & post tabs example. + ````jsx import { Input, Select } from 'antd'; const Option = Select.Option; diff --git a/components/input/demo/autosize-textarea.md b/components/input/demo/autosize-textarea.md index 4eb61799c0..fb04ab8066 100644 --- a/components/input/demo/autosize-textarea.md +++ b/components/input/demo/autosize-textarea.md @@ -1,18 +1,28 @@ --- order: 6 -title: 适应文本高度的文本域 +title: + zh-CN: 适应文本高度的文本域 + en-US: Autosizing the height to fit the content --- +## zh-CN + `autosize` 属性适用于 `textarea` 节点,并且只有高度会自动变化。另外 `autosize` 可以设定为一个对象,指定最小行数和最大行数。 +## en-US + +`autosize` prop for a `textarea` type of `Input` makes the height to automatically adjust based on the content. +An options object can be provided to `autosize` to specify the minimum and maximum number of lines the textarea will automatically adjust. + + ````jsx import { Input } from 'antd'; ReactDOM.render(
    - +
    - +
    , mountNode); ```` diff --git a/components/input/demo/basic.md b/components/input/demo/basic.md index 09920af1b2..aa8f8a916c 100644 --- a/components/input/demo/basic.md +++ b/components/input/demo/basic.md @@ -1,10 +1,18 @@ --- order: 0 -title: 基本使用 +title: + zh-CN: 基本使用 + en-US: Basic usage --- +## zh-CN + 基本使用。 +## en-US + +Basic usage example + ````jsx import { Input } from 'antd'; diff --git a/components/input/demo/group.md b/components/input/demo/group.md index 1184e5cd15..01e98cae3c 100644 --- a/components/input/demo/group.md +++ b/components/input/demo/group.md @@ -1,10 +1,18 @@ --- order: 3 -title: 输入框组合 +title: + zh-CN: 输入框组合 + en-US: Input Group --- +## zh-CN + 输入框的组合展现。 +## en-US + +Input.Group example + ````jsx import { Input, Col } from 'antd'; const InputGroup = Input.Group; diff --git a/components/input/demo/search-input.md b/components/input/demo/search-input.md index b2c021a43d..76aa93e1f0 100644 --- a/components/input/demo/search-input.md +++ b/components/input/demo/search-input.md @@ -1,10 +1,18 @@ --- order: 4 -title: 搜索框 +title: + zh-CN: 搜索框 + en-US: Search box --- +## zh-CN + 带有搜索按钮的输入框。 +## en-US + +Example of creating a search box by grouping a standard input with a search button. + ````jsx import { Input, Button } from 'antd'; import classNames from 'classnames'; diff --git a/components/input/demo/size.md b/components/input/demo/size.md index 604a0bf1b4..7781a1aaaa 100644 --- a/components/input/demo/size.md +++ b/components/input/demo/size.md @@ -1,20 +1,30 @@ --- order: 1 -title: 三种大小 +title: + zh-CN: 三种大小 + en-US: Three sizes of Input --- +## zh-CN + 我们为 `` 输入框定义了三种尺寸(大、默认、小),高度分别为 `32px`、`28px` 和 `22px`。 注意: 在表单里面,我们只使用大尺寸的输入框。 +## en-US + +There are three sizes of an Input box: `large` (32px)、`default` (28px) and `small` (22px). + +Note: Inside of forms, only the large size is used. + ````jsx import { Input } from 'antd'; ReactDOM.render(
    - - - + + +
    , mountNode); ```` @@ -24,4 +34,4 @@ ReactDOM.render( width: 200px; margin: 0 8px 8px 0; } -```` \ No newline at end of file +```` diff --git a/components/input/demo/textarea.md b/components/input/demo/textarea.md index 2a30e75a11..6b8aa5bf3d 100644 --- a/components/input/demo/textarea.md +++ b/components/input/demo/textarea.md @@ -1,10 +1,18 @@ --- order: 5 -title: 文本域 +title: + zh-CN: 文本域 + en-US: Textarea --- +## zh-CN + 用于多行输入,指定 `type` 为一个特殊的 `textarea`。 +## en-US + +For multi-line user input cases, an input whose `type` prop has the value of `"textarea"` can be used. + ````jsx import { Input } from 'antd'; diff --git a/components/input/index.en-US.md b/components/input/index.en-US.md new file mode 100644 index 0000000000..4a20089569 --- /dev/null +++ b/components/input/index.en-US.md @@ -0,0 +1,47 @@ +--- +category: Components +chinese: 输入框 +type: Form Controls +english: Input +--- + +A basic widget for getting the user input is a text field. +Keyboard and mouse can be used for providing or changing data. + +## When to Use + +- A user input in a form field is needed. +- A search input is required. + +## API + +### Input + +| Property | Description | Type | Available Values | Default | +|----------------|-----------------------|----------|------------------|---------------| +| type | The type of input. For a multi-line input, the 'textarea' value can be used. | string | 'text' or 'textarea' | 'text' | +| id | The identifier. | number or string | | | +| value | The content value. | any | | | +| defaultValue | The initial value. | any | | | +| size | The size of the input box. The implicit value is 'default'. Note: in the context of a form, the 'large' size is used. | string | {'large','default','small'} | 'default' | +| disabled | Tell if the input is disabled. | bool | | false | +| addonBefore | The label text displayed before (on the left side of) the input field. | node | | | +| addonAfter | The label text displayed after (on the right side of) the input field. | node | | | +| onPressEnter | The callback function that is triggered when pressing Enter key. | function(e) | | | +| autosize | Height autosize feature, available when type="textarea". | bool or object | `true` or `{ minRows: 2, maxRows: 6 }` | false | + +> When `Input` is used in a `Form.Item` context, if the `Form.Item` has the `id` and `options` props defined +then `value`, `defaultValue`, and `id` props are automatically set. + +#### Input.Group + +| Property | Description | Type | Available Values | Default | +|-----------|----------------------------------|--------|-----------------------------|-----------| +| size | The size of `Input.Group` specifies the size of the included `Input` fields. | string | {'large','default','small'} | 'default' | + +```html + + + + +``` diff --git a/components/input/index.md b/components/input/index.zh-CN.md similarity index 100% rename from components/input/index.md rename to components/input/index.zh-CN.md diff --git a/components/layout/col.tsx b/components/layout/col.tsx index 482dfb0231..bad0db3a6f 100644 --- a/components/layout/col.tsx +++ b/components/layout/col.tsx @@ -1,17 +1,39 @@ -import { PropTypes } from 'react'; import * as React from 'react'; +import { PropTypes } from 'react'; import classNames from 'classnames'; import assign from 'object-assign'; -const stringOrNumber = PropTypes.oneOfType([PropTypes.string, PropTypes.number]); -const objectOrNumber = PropTypes.oneOfType([PropTypes.object, PropTypes.number]); import splitObject from '../_util/splitObject'; -export default function Col(props) { +const stringOrNumber = PropTypes.oneOfType([PropTypes.string, PropTypes.number]); +const objectOrNumber = PropTypes.oneOfType([PropTypes.object, PropTypes.number]); + +interface ColSize { + span?: number; + order?: number; + offset?: number; + push?: number; + pull?: number; +} + +export interface ColProps { + className?: string; + span?: number; + order?: number; + offset?: number; + push?: number; + pull?: number; + xs?: ColSize; + sm?: ColSize; + md?: ColSize; + lg?: ColSize; +} + +const Col: React.StatelessComponent = (props) => { const [{ span, order, offset, push, pull, className, children }, others] = splitObject(props, ['span', 'order', 'offset', 'push', 'pull', 'className', 'children']); let sizeClassObj = {}; ['xs', 'sm', 'md', 'lg'].forEach(size => { - let sizeProps = {}; + let sizeProps: ColSize = {}; if (typeof props[size] === 'number') { sizeProps.span = props[size]; } else if (typeof props[size] === 'object') { @@ -38,7 +60,7 @@ export default function Col(props) { }, sizeClassObj)); return
    {children}
    ; -} +}; Col.propTypes = { span: stringOrNumber, @@ -53,3 +75,5 @@ Col.propTypes = { md: objectOrNumber, lg: objectOrNumber, }; + +export default Col; diff --git a/components/layout/index.en-US.md b/components/layout/index.en-US.md index 39b064b445..cecd2409d0 100644 --- a/components/layout/index.en-US.md +++ b/components/layout/index.en-US.md @@ -92,8 +92,8 @@ Ant Design layout component if it can not meet your needs, you can use the excel |------------|-----------------|--------------------|-------------| | gutter | grid spacing | number | 0 | | type | layout mode, the optional `flex`, effective modern browser | string | | -| align | the vertical alignment of the layout of flex: `top`` middle` `bottom` | string | `top` | -| justify | horizontal arrangement of the layout of flex: `start`` end` `center`` space-around` `space-between` | string | `start` | +| align | the vertical alignment of the layout of flex: `top` ` middle` `bottom` | string | `top` | +| justify | horizontal arrangement of the layout of flex: `start` ` end` `center` ` space-around` `space-between` | string | `start` | ### Col diff --git a/components/layout/index.zh-CN.md b/components/layout/index.zh-CN.md index 68de72ee63..8a4a107f56 100644 --- a/components/layout/index.zh-CN.md +++ b/components/layout/index.zh-CN.md @@ -1,6 +1,6 @@ --- category: Components -chinese: 布局 +chinese: 栅格 type: Basic cols: 1 english: Layout diff --git a/components/layout/row.tsx b/components/layout/row.tsx index a57a6a7af2..1da9010380 100644 --- a/components/layout/row.tsx +++ b/components/layout/row.tsx @@ -1,8 +1,19 @@ -import React, { Children, cloneElement } from 'react'; +import * as React from 'react'; +import { Children, cloneElement } from 'react'; import classNames from 'classnames'; import assign from 'object-assign'; import splitObject from '../_util/splitObject'; -export default class Row extends React.Component { + +export interface RowProps { + className?: string; + gutter?: number; + type?: 'flex'; + align?: 'top' | 'middle' | 'bottom'; + justify?: 'start' | 'end' | 'center' | 'space-around' | 'space-between'; + style?: React.CSSProperties; +} + +export default class Row extends React.Component { static defaultProps = { gutter: 0, }; @@ -28,7 +39,7 @@ export default class Row extends React.Component { marginLeft: gutter / -2, marginRight: gutter / -2, }, style) : style; - const cols = Children.map(children, col => { + const cols = Children.map(children, (col: React.ReactElement) => { if (!col) { return null; } diff --git a/components/locale-provider/demo/all.md b/components/locale-provider/demo/all.md index 6283844933..2cd9a74c8a 100644 --- a/components/locale-provider/demo/all.md +++ b/components/locale-provider/demo/all.md @@ -7,7 +7,7 @@ title: ## zh-CN -此处列出 Ant Design 中需要国际化支持的组件,你可以在演示里切换语言。 +此处列出 Ant Design 中需要国际化支持的组件,你可以在演示里切换语言。涉及时间的组件请注意时区设置 [DatePicker](/components/date-picker/#components-date-picker-demo-locale)。 ## en-US @@ -32,6 +32,12 @@ const columns = [{ dataIndex: 'age', }]; +const customLocale = { + timezoneOffset: 8 * 60, + firstDayOfWeek: 1, + minimalDaysInFirstWeek: 1, +}; + const Page = React.createClass({ getInitialState() { return { @@ -112,6 +118,10 @@ const App = React.createClass({ this.setState({ locale: e.target.value }); }, render() { + const locale = { ...this.state.locale }; + if (locale.DatePicker) { + locale.DatePicker = { ...locale.DatePicker, ...customLocale }; + } return (
    @@ -121,7 +131,7 @@ const App = React.createClass({ 中文
    - +
    ); }, diff --git a/components/mention/demo/controlled.md b/components/mention/demo/controlled.md index 3fca9863f6..e8b0f5df37 100644 --- a/components/mention/demo/controlled.md +++ b/components/mention/demo/controlled.md @@ -29,7 +29,7 @@ let App = React.createClass({ handleSubmit(e) { e.preventDefault(); this.props.form.validateFields((errors, values) => { - if (!!errors) { + if (errors) { console.log('Errors in form!!!'); return; } diff --git a/components/menu/demo/horizontal.md b/components/menu/demo/horizontal.md index 41c246f8f2..68966cc171 100644 --- a/components/menu/demo/horizontal.md +++ b/components/menu/demo/horizontal.md @@ -45,7 +45,7 @@ const App = React.createClass({ - 导航四 - 链接 + 导航四 - 链接
); diff --git a/components/menu/style/index.less b/components/menu/style/index.less index 29870504cc..de8b7253bf 100644 --- a/components/menu/style/index.less +++ b/components/menu/style/index.less @@ -89,6 +89,12 @@ } } + &-horizontal, + &-inline, + &-vertical { + z-index: auto; + } + &-inline, &-vertical { border-right: 1px solid @border-color-split; diff --git a/components/modal/confirm.tsx b/components/modal/confirm.tsx index d83d4680a1..5ba9c46bfd 100644 --- a/components/modal/confirm.tsx +++ b/components/modal/confirm.tsx @@ -7,7 +7,12 @@ import classNames from 'classnames'; import { getConfirmLocale } from './locale'; import assign from 'object-assign'; -class ActionButton extends React.Component { +export interface ActionButtonProps { + type: 'primary' | 'ghost' | 'dashed'; + actionFn: Function; + closeModal: Function; +} +class ActionButton extends React.Component { constructor(props) { super(props); this.state = { diff --git a/components/modal/demo/footer.md b/components/modal/demo/footer.md index 6f2800e39a..4e2944a17c 100644 --- a/components/modal/demo/footer.md +++ b/components/modal/demo/footer.md @@ -1,6 +1,6 @@ --- order: 2 -title: +title: zh-CN: 自定义页脚 en-US: Customized footer --- @@ -45,9 +45,11 @@ const Test = React.createClass({ - Return, -

- - {list} - -
- ); - }, -}); - -ReactDOM.render(, mountNode); -```` diff --git a/components/queue-anim/demo/change.md b/components/queue-anim/demo/change.md deleted file mode 100644 index e424055726..0000000000 --- a/components/queue-anim/demo/change.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -order: 5 -title: 添加与删除 ---- - -场景里有增加或删除条目时也会触发动画。 - -````jsx -import { QueueAnim, Button } from 'antd'; - -const Test = React.createClass({ - getInitialState() { - return { - show: true, - items: [ -
  • , -
  • , -
  • , - ], - }; - }, - onClick() { - this.setState({ - show: !this.state.show, - }); - }, - onAdd() { - const items = this.state.items; - items.push(
  • ); - this.setState({ - show: true, - items, - }); - }, - onRemove() { - const items = this.state.items; - items.splice(items.length - 1, 1); - this.setState({ - show: true, - items, - }); - }, - render() { - return ( -
    -

    - - - -

    -
    -
    -
    -
    - - {this.state.show ? this.state.items : null} - -
    -
    -
    -
    - ); - }, -}); - -ReactDOM.render(, mountNode); -```` diff --git a/components/queue-anim/demo/custom.md b/components/queue-anim/demo/custom.md deleted file mode 100644 index a005f68d1e..0000000000 --- a/components/queue-anim/demo/custom.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -order: 3 -title: 自定义动画进出场 ---- - -通过 `animConfig` 来自定义动画进出场。 - -````jsx -import { QueueAnim, Button } from 'antd'; - -const Test = React.createClass({ - getInitialState() { - return { - show: true, - }; - }, - onClick() { - this.setState({ - show: !this.state.show, - }); - }, - render() { - const list = this.state.show ? [ -
    -
      -
    • -
    • -
    • -
    -
    , -
    -
    -
    -
      -
    • -
    • -
    • -
    -
    -
    , - ] : null; - return ( -
    -

    - -

    - - {list} - -
    - ); - }, -}); - -ReactDOM.render(, mountNode); -```` diff --git a/components/queue-anim/demo/enter-leave.md b/components/queue-anim/demo/enter-leave.md deleted file mode 100644 index 91aadb5b78..0000000000 --- a/components/queue-anim/demo/enter-leave.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -order: 2 -title: 进场和离场 ---- - -通过把属性设置一个数组来分别表示进出场的效果,`type`、`animConfig`、`delay`、`duration`、`interval`、`ease` 等属性均支持配置为数组。 - -````jsx -import { QueueAnim, Button } from 'antd'; - -const Test = React.createClass({ - getInitialState() { - return { - show: true, - }; - }, - onClick() { - this.setState({ - show: !this.state.show, - }); - }, - render() { - const list = this.state.show ? [ -
    -
      -
    • -
    • -
    • -
    -
    , -
    -
    -
    -
      -
    • -
    • -
    • -
    -
    -
    , - ] : null; - return ( -
    -

    - -

    - - {list} - -
    - ); - }, -}); - -ReactDOM.render(, mountNode); -```` diff --git a/components/queue-anim/demo/form.md b/components/queue-anim/demo/form.md deleted file mode 100644 index 36f211fcea..0000000000 --- a/components/queue-anim/demo/form.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -order: 4 -title: 表单动画进出场 ---- - -表单组合的进场与出场动画。 - -````jsx -import { QueueAnim, Button, Radio, Input, Form, Row, Col } from 'antd'; -const FormItem = Form.Item; -const RadioGroup = Radio.Group; - -const Test = React.createClass({ - getInitialState() { - return { - show: true, - }; - }, - onClick() { - this.setState({ - show: !this.state.show, - }); - }, - render() { - const formItemLayout = { - labelCol: { span: 6 }, - wrapperCol: { span: 14 }, - }; - return ( -
    -

    - -

    - - {this.state.show ? [ - -

    大眼萌 minion

    -
    , - - - , - - - 男的 - 女的 - - , - - - , - - - - - , - ] : null} -
    -
    - ); - }, -}); - -ReactDOM.render(, mountNode); -```` diff --git a/components/queue-anim/demo/page.md b/components/queue-anim/demo/page.md deleted file mode 100644 index 6ace0d5ad1..0000000000 --- a/components/queue-anim/demo/page.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -order: 6 -title: 一个复杂些的例子 ---- - -模拟一个完整的页面。 - -````jsx -import { QueueAnim, Button } from 'antd'; - -const Test = React.createClass({ - getInitialState() { - return { - show: true, - }; - }, - onClick() { - this.setState({ - show: !this.state.show, - }); - }, - render() { - const page = this.state.show ? [ -
    -
    - logo - logo -
    - -
  • -
  • -
  • -
  • -
  • -
    -
    , - -
    我是标题
    -
    - -
  • -
  • -
  • -
    -
    -
    我是标题
    -
    - -
    - -
  • -
  • -
  • -
  • -
  • -
    -
    -
    -
    , - -
    -
    , - ] : null; - return ( -
    -

    - -

    - {page} -
    - ); - }, -}); - -ReactDOM.render(, mountNode); -```` diff --git a/components/queue-anim/demo/router.md b/components/queue-anim/demo/router.md deleted file mode 100644 index 6e4379d14f..0000000000 --- a/components/queue-anim/demo/router.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -order: 7 -iframe: true -title: Router 默认进出场 ---- - -router 组合的进场与出场动画。 - -````jsx -const ReactRouter = require('react-router'); -let { Router, Route, Link, hashHistory } = ReactRouter; -import { QueueAnim, Menu } from 'antd'; - -function App(props) { - const key = props.location.pathname; - const keys = key.replace('/', '') ? [key.replace('/', '')] : ['home']; - return ( -
    - - - 首页 - - - Page 1 - - - Page 2 - - - - {React.cloneElement(props.children || , { key })} - -
    - ); -} - -function Home() { - return ( -
    - -
    - -
  • -
  • -
  • -
    -
    -
    - -
  • -
  • -
  • -
    -
    -
    - -
  • -
  • -
  • -
    -
    -
    -
    - ); -} - -function Page1() { - return ( -
    - -
    - -
  • -
  • -
  • -
    -
    -
    - -
    - -
  • -
  • -
  • -
    -
    -
    -
    -
    - ); -} - -function Page2() { - return ( -
    -
    -
    - -
    - -
  • -
  • -
  • -
  • -
  • -
  • -
    -
    -
    -
    -
    - ); -} - -ReactDOM.render(( - - - - - - -), mountNode); -```` - -````css -#components-queue-anim-demo-router iframe { - height: 260px; -} -#components-queue-anim-demo-router .demo-router-wrap { - position: relative; - width: 100%; - margin: auto; - height:200px; - overflow: hidden; -} -#components-queue-anim-demo-router .queue-anim-leaving { - position: absolute; - width:100%; -} -```` diff --git a/components/queue-anim/demo/simple.md b/components/queue-anim/demo/simple.md deleted file mode 100644 index 7c79f6fd91..0000000000 --- a/components/queue-anim/demo/simple.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -order: 0 -title: 默认 ---- - -最简单的进场例子。 - -````jsx -import { QueueAnim } from 'antd'; - -ReactDOM.render( - -
    依次进场
    -
    依次进场
    -
    依次进场
    -
    依次进场
    -
    依次进场
    -
    依次进场
    -
    -, mountNode); -```` - -````css -.code-box-demo > div { - overflow: hidden; -} - -.code-box-demo .buttons { - text-align: center; - margin: 0 auto; - margin-bottom: 20px; -} -```` diff --git a/components/queue-anim/index.md b/components/queue-anim/index.md deleted file mode 100644 index aaa559d4ec..0000000000 --- a/components/queue-anim/index.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -category: Components -chinese: 进出场动画 -type: Other -english: QueueAnim ---- - -通过简单的配置对一组元素添加串行的进场动画效果。 - -## 何时使用 - -- 从内容A到内容B的转变过程时能有效的吸引用户注意力,突出视觉中心,提高整体视觉效果。 -- 小的信息元素排布或块状较多的情况下,根据一定的路径层次依次进场,区分维度层级,来凸显量级,使页面转场更加流畅和舒适,提高整体视觉效果和产品的质感。 -- 特别适合首页和需要视觉展示效果的宣传页,以及单页应用的切换页面动效。 - - -## API - -> 此组件 `antd@1.0.0+` 后标记为废弃,您可以直接使用 `import QueueAnim from 'rc-queue-anim'` 来代替,相关文档也已移到 [ant-motioin](http://motion.ant.design/components/queue-anim)。 - -> [ant-motioin](http://motion.ant.design/) 是一个动效设计语言,欢迎关注。 - -元素依次进场。 - -```html - -
    依次进场
    -
    依次进场
    -
    依次进场
    -
    依次进场
    -
    -``` - -> 每个子标签必须带 key,如果未设置 key 将不执行动画。 - -|参数 |类型 |默认 |详细 | -|------------|----------------|---------|----------------| -| type | string / array | `right` | 动画内置参数
    `left` `right` `top` `bottom` `scale` `scaleBig` `scaleX` `scaleY`| -| animConfig | object / array | null | 配置动画参数
    如 `{opacity:[1, 0],translateY:[0, -30]}` 具体参考 [velocity](http://julian.com/research/velocity) 的写法| -| delay | number / array | 0 | 整个动画的延时,以毫秒为单位 | -| duration | number / array | 500 | 每个动画的时间,以毫秒为单位 | -| interval | number / array | 100 | 每个动画的间隔时间,以毫秒为单位 | -| leaveReverse | boolean | false | 出场时是否倒放,从最后一个 dom 开始往上播放 | -| ease | string / array | `easeOutQuart` | 动画的缓动函数,[查看详细](http://julian.com/research/velocity/#easing) | -| animatingClassName | array | `['queue-anim-entering', 'queue-anim-leaving']` | 进出场动画进行中的类名 | -| component | string | `div` | QueueAnim 替换的标签名 | - -> 当以上数据类型为 Array 时,`['left', 'top']` 第一个为进场动画属性, 第二个为离场属性。 diff --git a/components/queue-anim/index.tsx b/components/queue-anim/index.tsx deleted file mode 100644 index 65340f2f85..0000000000 --- a/components/queue-anim/index.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import * as React from 'react'; -import RcQueueAnim from 'rc-queue-anim'; -import warning from 'warning'; - -export default class QueueAnim extends React.Component { - componentDidMount() { - warning(false, '`QueueAnim` is deprecated, ' + - 'you can import QueueAnim from \'rc-queue-anim\' directly.' + - 'The Demo will be moved to http://motion.ant.design/component/queue-anim'); - } - render() { - return ; - } -} diff --git a/components/queue-anim/style/index.tsx b/components/queue-anim/style/index.tsx deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/components/radio/index.tsx b/components/radio/index.tsx index 334e01818a..355a3a2913 100644 --- a/components/radio/index.tsx +++ b/components/radio/index.tsx @@ -4,4 +4,5 @@ import Button from './radioButton'; Radio.Button = Button; Radio.Group = Group; +export { Button, Group }; export default Radio; diff --git a/components/select/index.tsx b/components/select/index.tsx index 9fcf9aa32f..8eb00c61a1 100644 --- a/components/select/index.tsx +++ b/components/select/index.tsx @@ -31,6 +31,9 @@ export interface SelectProps { defaultActiveFirstOption?: boolean; labelInValue?: boolean; getPopupContainer?: (triggerNode: React.ReactNode) => React.ReactNode; + style?: React.CSSProperties; + dropdownMenuStyle?: React.CSSProperties; + onChange?: (value) => void; } export interface SelectContext { @@ -39,6 +42,8 @@ export interface SelectContext { }; } +export { Option, OptGroup } + export default class Select extends React.Component { static Option = Option; static OptGroup = OptGroup; diff --git a/components/select/style/index.less b/components/select/style/index.less index 8fcfd686d0..1e55156bfe 100644 --- a/components/select/style/index.less +++ b/components/select/style/index.less @@ -152,16 +152,16 @@ } &-lg { - .ant-select-selection--single { + .@{select-prefix-cls}-selection--single { height: 32px; - .ant-select-selection__rendered { + .@{select-prefix-cls}-selection__rendered { line-height: 30px; } } - .ant-select-selection--multiple { + .@{select-prefix-cls}-selection--multiple { min-height: 32px; - .ant-select-selection__rendered { + .@{select-prefix-cls}-selection__rendered { li { height: 24px; line-height: 24px; @@ -171,18 +171,18 @@ } &-sm { - .ant-select-selection { + .@{select-prefix-cls}-selection { border-radius: @border-radius-sm; } - .ant-select-selection--single { + .@{select-prefix-cls}-selection--single { height: 22px; - .ant-select-selection__rendered { + .@{select-prefix-cls}-selection__rendered { line-height: 20px; } } - .ant-select-selection--multiple { + .@{select-prefix-cls}-selection--multiple { min-height: 22px; - .ant-select-selection__rendered { + .@{select-prefix-cls}-selection__rendered { li { height: 14px; line-height: 14px; @@ -223,14 +223,17 @@ &-search--inline { float: left; width: 100%; + height: 100%; .@{select-prefix-cls}-search__field__wrap { width: 100%; + height: 100%; } .@{select-prefix-cls}-search__field { border: 0; font-size: 100%; + height: 100%; background: transparent; outline: 0; border-radius: @border-radius-base; @@ -361,6 +364,9 @@ position: absolute; left: 0; right: 0; + > ul { + height: 100%; + } } } } diff --git a/components/spin/index.tsx b/components/spin/index.tsx index 300334a245..0b290057b0 100644 --- a/components/spin/index.tsx +++ b/components/spin/index.tsx @@ -103,7 +103,7 @@ export default class Spin extends React.Component { const spinElement = (
    -
    {tip || '加载中...'}
    + {tip ?
    {tip}
    : null}
    ); diff --git a/components/spin/style/index.less b/components/spin/style/index.less index 7f8e3fc312..8f41c46b07 100644 --- a/components/spin/style/index.less +++ b/components/spin/style/index.less @@ -106,11 +106,6 @@ .square(@spin-dot-size-lg); } - &-text, - &&-show-text &-dot { - display: none; - } - &&-show-text &-text { display: block; } diff --git a/components/steps/demo/step-next.md b/components/steps/demo/step-next.md index d553920b67..2edab70db3 100644 --- a/components/steps/demo/step-next.md +++ b/components/steps/demo/step-next.md @@ -16,7 +16,7 @@ Let's generate 3~6 steps randomly, and proceed to a random step. ````jsx import { Steps, Button } from 'antd'; const Step = Steps.Step; -const array = Array.apply(null, Array(Math.floor(Math.random() * 3) + 3)); +const array = [...Array(Math.floor(Math.random() * 3) + 3)]; const steps = array.map((item, i) => ({ title: `步骤${i + 1}`, })); diff --git a/components/style/themes/default.less b/components/style/themes/default.less index 8bf9f773df..8bd5980024 100644 --- a/components/style/themes/default.less +++ b/components/style/themes/default.less @@ -4,6 +4,7 @@ @success-color : #87d068; @error-color : #f50; @warning-color : #fa0; +@normal-color : #d9d9d9; // ------ Base & Require ------ @body-background : #fff; diff --git a/components/table/Table.tsx b/components/table/Table.tsx index 8911710007..6d13edb3da 100644 --- a/components/table/Table.tsx +++ b/components/table/Table.tsx @@ -96,6 +96,7 @@ interface TableContext { export default class Table extends React.Component { static propTypes = { dataSource: React.PropTypes.array, + columns: React.PropTypes.array.isRequired, prefixCls: React.PropTypes.string, useFixedHeader: React.PropTypes.bool, rowSelection: React.PropTypes.object, @@ -311,11 +312,11 @@ export default class Table extends React.Component { return; } return (a, b) => { - let result = sortColumn.sorter(a, b); + const result = sortColumn.sorter(a, b); if (result !== 0) { return (sortOrder === 'descend') ? -result : result; } - return a.indexForSort - b.indexForSort; + return 0; }; } @@ -774,9 +775,6 @@ export default class Table extends React.Component { let data = this.props.dataSource || []; // 优化本地排序 data = data.slice(0); - for (let i = 0; i < data.length; i++) { - data[i] = assign({}, data[i], { indexForSort: i }); - } const sorterFn = this.getSorterFn(); if (sorterFn) { data = data.sort(sorterFn); diff --git a/components/table/demo/basic.md b/components/table/demo/basic.md index 4fdfd2ea8e..a0d8919a4c 100644 --- a/components/table/demo/basic.md +++ b/components/table/demo/basic.md @@ -35,9 +35,9 @@ const columns = [{ render: (text, record) => ( 操作一{record.name} - + 操作二 - + 更多 diff --git a/components/table/filterDropdown.tsx b/components/table/filterDropdown.tsx index a60621a427..dbb560fe64 100644 --- a/components/table/filterDropdown.tsx +++ b/components/table/filterDropdown.tsx @@ -5,7 +5,11 @@ import Icon from '../icon'; import Checkbox from '../checkbox'; import Radio from '../radio'; -const FilterDropdownMenuWrapper = ({ onClick, children }) => ( +export interface FilterDropdownMenuWrapperProps { + onClick?: Function; + children?: any; +} +const FilterDropdownMenuWrapper: React.StatelessComponent = ({ onClick, children }) => (
    {children}
    ); diff --git a/components/tabs/demo/basic.md b/components/tabs/demo/basic.md index 0c5563f1e0..13c38066e7 100644 --- a/components/tabs/demo/basic.md +++ b/components/tabs/demo/basic.md @@ -1,6 +1,8 @@ --- order: 0 -title: 基本 +title: + zh-CN: 基本 + en-US: Basic --- ## zh-CN diff --git a/components/tabs/demo/card-top.md b/components/tabs/demo/card-top.md index 175e4a86bf..981225531d 100644 --- a/components/tabs/demo/card-top.md +++ b/components/tabs/demo/card-top.md @@ -1,7 +1,10 @@ --- order: 10 -title: 卡片式页签容器 +title: + zh-CN: 卡片式页签容器 + en-US: Container of card type Tab --- + ## zh-CN 用于容器顶部,需要一点额外的样式覆盖。 diff --git a/components/tabs/demo/card.md b/components/tabs/demo/card.md index 0522273d4c..9984606983 100644 --- a/components/tabs/demo/card.md +++ b/components/tabs/demo/card.md @@ -1,6 +1,8 @@ --- order: 8 -title: 卡片式页签 +title: + zh-CN: 卡片式页签 + en-US: Card type tab --- ## zh-CN diff --git a/components/tabs/demo/custom-add-trigger.md b/components/tabs/demo/custom-add-trigger.md index 00bdb92df3..2499d801a1 100644 --- a/components/tabs/demo/custom-add-trigger.md +++ b/components/tabs/demo/custom-add-trigger.md @@ -1,6 +1,8 @@ --- order: 11 -title: 自定义新增页签触发器 +title: + zh-CN: 自定义新增页签触发器 + en-US: Customized trigger of new tab --- ## zh-CN diff --git a/components/tabs/demo/disabled.md b/components/tabs/demo/disabled.md index 1a0919f36a..62e7121379 100644 --- a/components/tabs/demo/disabled.md +++ b/components/tabs/demo/disabled.md @@ -1,6 +1,8 @@ --- order: 1 -title: 禁用 +title: + zh-CN: 禁用 + en-US: Disabled --- ## zh-CN diff --git a/components/tabs/demo/editable-card.md b/components/tabs/demo/editable-card.md index b29f3be5ae..d57ed47559 100644 --- a/components/tabs/demo/editable-card.md +++ b/components/tabs/demo/editable-card.md @@ -1,6 +1,8 @@ --- order: 9 -title: 新增和关闭页签 +title: + zh-CN: 新增和关闭页签 + en-US: Add & close tab --- ## zh-CN diff --git a/components/tabs/demo/extra.md b/components/tabs/demo/extra.md index dd4eec5309..038c4b21b4 100644 --- a/components/tabs/demo/extra.md +++ b/components/tabs/demo/extra.md @@ -1,6 +1,8 @@ --- order: 4 -title: 附加内容 +title: + zh-CN: 附加内容 + en-US: Extra content --- ## zh-CN diff --git a/components/tabs/demo/icon.md b/components/tabs/demo/icon.md index 3d98f22b06..55d464731f 100644 --- a/components/tabs/demo/icon.md +++ b/components/tabs/demo/icon.md @@ -1,6 +1,8 @@ --- order: 2 -title: 图标 +title: + zh-CN: 图标 + en-US: Icon --- ## zh-CN diff --git a/components/tabs/demo/position.md b/components/tabs/demo/position.md index 06e734e927..86b61a77cf 100644 --- a/components/tabs/demo/position.md +++ b/components/tabs/demo/position.md @@ -1,6 +1,8 @@ --- order: 6 -title: 位置 +title: + zh-CN: 位置 + en-US: Position --- ## zh-CN diff --git a/components/tabs/demo/size.md b/components/tabs/demo/size.md index bb079f93f4..b2b14af949 100644 --- a/components/tabs/demo/size.md +++ b/components/tabs/demo/size.md @@ -1,6 +1,8 @@ --- order: 5 -title: 迷你型 +title: + zh-CN: 迷你型 + en-US: Mini tab --- ## zh-CN diff --git a/components/tabs/demo/slide.md b/components/tabs/demo/slide.md index e04f49b6e2..f3bc06e656 100644 --- a/components/tabs/demo/slide.md +++ b/components/tabs/demo/slide.md @@ -1,6 +1,8 @@ --- order: 3 -title: 滑动 +title: + zh-CN: 滑动 + en-US: Slide --- ## zh-CN diff --git a/components/tabs/index.tsx b/components/tabs/index.tsx index 1fcf5121b9..1a612c2170 100644 --- a/components/tabs/index.tsx +++ b/components/tabs/index.tsx @@ -73,19 +73,19 @@ export default class Tabs extends React.Component { animation = null; } // only card type tabs can be added and closed + let childrenWithCross; if (type === 'editable-card') { - children = Array.isArray(children) ? children : [children]; - children = (children as Array).map((child, index) => { - if (Array.isArray(child)) { - return child; - } - return cloneElement(child, { - tab:
    - {child.props.tab} - this.removeTab(child.key, e) } /> -
    , + childrenWithCross = []; + React.Children.forEach(children, (child: React.ReactElement, index) => { + childrenWithCross.push(cloneElement(child, { + tab: ( +
    + {child.props.tab} + this.removeTab(child.key, e)} /> +
    + ), key: child.key || index, - }); + })); }); // Add new tab handler if (!hideAdd) { @@ -110,8 +110,8 @@ export default class Tabs extends React.Component { tabBarExtraContent={tabBarExtraContent} onChange={this.handleChange} animation={animation} - > - {children} + > + {childrenWithCross || children} ); } diff --git a/components/tag/demo/basic.md b/components/tag/demo/basic.md index 183f69a4f2..00cd4676c5 100644 --- a/components/tag/demo/basic.md +++ b/components/tag/demo/basic.md @@ -1,10 +1,18 @@ --- order: 0 -title: 基本 +title: + zh-CN: 基本 + en-US: Basic --- +## zh-CN + 简单的标签展示,添加 closable 表示可关闭。 +## en-US + +Simple demo of tag, 'closable' property represents which can be closed. + ````jsx import { Tag } from 'antd'; @@ -13,8 +21,8 @@ function onClose(e) { } ReactDOM.render(
    - 标签一 - 标签二 - 标签三 + Tag 1 + Tag 2 + Tag 3
    , mountNode); ```` diff --git a/components/tag/demo/colorful.md b/components/tag/demo/colorful.md index b4f653e6bd..9fa67d2f53 100644 --- a/components/tag/demo/colorful.md +++ b/components/tag/demo/colorful.md @@ -1,17 +1,24 @@ --- order: 1 -title: 各种类型 +title: + zh-CN: 各种类型 + en-US: Colorful tags --- +## zh-CN + 四种颜色的标签。 +## en-US +Colorful tags. + ````jsx import { Tag } from 'antd'; ReactDOM.render(
    - 蓝色 - 绿色 - 黄色 - 红色 + Blue + Green + Yellow + Red
    , mountNode); ```` diff --git a/components/tag/demo/control.md b/components/tag/demo/control.md index 2a3bc093bf..f18d88b4f9 100644 --- a/components/tag/demo/control.md +++ b/components/tag/demo/control.md @@ -1,11 +1,21 @@ --- order: 2 -title: 动态添加和删除 +title: + zh-CN: 动态添加和删除 + en-US: Dynamically add and remove --- +## zh-CN + 用数组生成一组标签,可以动态添加和删除。 -> 使用 `afterClose` 删除时有动画效果。 +使用 `afterClose` 删除时有动画效果。 + +## en-US + +Generating a set of tag by array, you can dynamically add and remove. + +Using 'afterClose' property, There are animated when a tag was removed. ````jsx import { Tag, Button } from 'antd'; @@ -15,9 +25,9 @@ const App = React.createClass({ getInitialState() { return { tags: [ - { key: 1, name: '不可移除' }, - { key: 2, name: '标签二' }, - { key: 3, name: '标签三' }, + { key: 1, name: 'Unremovable' }, + { key: 2, name: 'Tag 2' }, + { key: 3, name: 'Tag 3' }, ], }; }, @@ -29,7 +39,7 @@ const App = React.createClass({ addTag() { const tags = [...this.state.tags]; index += 1; - tags.push({ key: index, name: `新标签${index}` }); + tags.push({ key: index, name: `New tag ${index}` }); this.setState({ tags }); }, render() { @@ -41,7 +51,7 @@ const App = React.createClass({ {tag.name} )} - +
    ); }, diff --git a/components/tag/index.en-US.md b/components/tag/index.en-US.md new file mode 100644 index 0000000000..2aaf3737e7 --- /dev/null +++ b/components/tag/index.en-US.md @@ -0,0 +1,22 @@ +--- +category: Components +type: Views +english: Tag +--- + +Tag for categorizing or markuping. + +## When to use + +- It can be used to tag by dimension or property. + +- categorizing + +## API + +| Property | Description | Type | Default | +|--------------|-----------------------|----------|--------------| +| closable | Tag can be closed. | boolean | false | +| onClose | Callback when tag was closed | function(event)| - | +| afterClose | Callback when closed animation is complete | function(event)| - | +| color | Tag's color: `blue` `green` `yellow` `red` | string | - | \ No newline at end of file diff --git a/components/tag/index.tsx b/components/tag/index.tsx index fcb48a56c2..f2a8e8f237 100644 --- a/components/tag/index.tsx +++ b/components/tag/index.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import ReactDOM from 'react-dom'; +import * as ReactDOM from 'react-dom'; import Animate from 'rc-animate'; import Icon from '../icon'; import classNames from 'classnames'; @@ -40,7 +40,7 @@ export default class Tag extends React.Component { if (e.defaultPrevented) { return; } - const dom = ReactDOM.findDOMNode(this); + const dom = ReactDOM.findDOMNode(this) as HTMLElement; dom.style.width = `${dom.getBoundingClientRect().width}px`; // It's Magic Code, don't know why dom.style.width = `${dom.getBoundingClientRect().width}px`; diff --git a/components/tag/index.md b/components/tag/index.zh-CN.md similarity index 100% rename from components/tag/index.md rename to components/tag/index.zh-CN.md diff --git a/components/time-picker/index.tsx b/components/time-picker/index.tsx index 211a566a4d..e35fe70c19 100644 --- a/components/time-picker/index.tsx +++ b/components/time-picker/index.tsx @@ -8,6 +8,7 @@ import assign from 'object-assign'; // TimePicker export interface TimePickerProps { + size: 'large' | 'default' | 'small'; /** 默认时间 */ value?: string | Date; /** 初始默认时间 */ @@ -15,7 +16,7 @@ export interface TimePickerProps { /** 展示的时间格式 : "HH:mm:ss"、"HH:mm"、"mm:ss" */ format?: string; /** 时间发生变化的回调 */ - onChange?: (Date: Date) => void; + onChange?: (date: Date, dateString: string) => void; /** 禁用全部操作 */ disabled?: boolean; /** 没有值的时候显示的内容 */ @@ -33,6 +34,13 @@ export interface TimePickerProps { style?: React.CSSProperties; } + +export interface TimePickerContext { + antLocale?: { + TimePicker?: any, + }; +} + export default class TimePicker extends React.Component { static defaultProps = { format: 'HH:mm:ss', @@ -56,8 +64,10 @@ export default class TimePicker extends React.Component { antLocale: React.PropTypes.object, }; + context: TimePickerContext; + getFormatter() { - return new DateTimeFormat(this.props.format, this.getLocale().format); + return new DateTimeFormat(this.props.format as string, this.getLocale().format); } /** @@ -95,7 +105,7 @@ export default class TimePicker extends React.Component { handleChange = (value) => { this.props.onChange( value ? new Date(value.getTime()) : null, - value ? this.getFormatter().format(value) : '', + value ? this.getFormatter().format(value) : '' ); } diff --git a/components/timeline/Timeline.tsx b/components/timeline/Timeline.tsx index 63ea13125f..2ebefb2301 100644 --- a/components/timeline/Timeline.tsx +++ b/components/timeline/Timeline.tsx @@ -10,6 +10,7 @@ export interface TimelineProps { } export default class Timeline extends React.Component { + static Item: React.ReactNode; static defaultProps = { prefixCls: 'ant-timeline', }; @@ -28,7 +29,7 @@ export default class Timeline extends React.Component { return (
      { - React.Children.map(children, (ele, idx) => + React.Children.map(children, (ele: React.ReactElement, idx) => React.cloneElement(ele, { last: idx === children.length - 1, }) diff --git a/components/timeline/TimelineItem.tsx b/components/timeline/TimelineItem.tsx index a9a4595c60..1077a07be9 100644 --- a/components/timeline/TimelineItem.tsx +++ b/components/timeline/TimelineItem.tsx @@ -7,6 +7,7 @@ export interface TimeLineItemProps { /** 指定圆圈颜色 */ color?: string; dot?: React.ReactNode; + pending?: boolean; style?: React.CSSProperties; } diff --git a/components/tooltip/index.tsx b/components/tooltip/index.tsx index 164073bf0d..4049179d62 100644 --- a/components/tooltip/index.tsx +++ b/components/tooltip/index.tsx @@ -1,7 +1,8 @@ import * as React from 'react'; -const { cloneElement } = React; +import { cloneElement } from 'react'; import RcTooltip from 'rc-tooltip'; import getPlacements from '../popover/placements'; +import classNames from 'classnames'; const placements = getPlacements({ verticalArrowShift: 8, @@ -32,6 +33,7 @@ export interface TooltipProps { visible?: boolean; trigger?: 'hover' | 'focus' | 'click'; overlay?: React.ReactNode; + openClassName?: string; } export default class Tooltip extends React.Component { @@ -44,6 +46,11 @@ export default class Tooltip extends React.Component { onVisibleChange() {}, }; + refs: { + [key: string]: any; + tooltip: any; + }; + constructor(props) { super(props); this.state = { @@ -101,9 +108,13 @@ export default class Tooltip extends React.Component { if ('visible' in this.props) { visible = this.props.visible; } - const openClassName = this.props.openClassName || `${prefixCls}-open`; - const childrenCls = (children && children.props && children.props.className) - ? `${children.props.className} ${openClassName}` : openClassName; + + const childrenProps = children ? (children as React.ReactElement).props : {}; + const childrenCls = classNames({ + [childrenProps.className]: !!childrenProps.className, + [this.props.openClassName || `${prefixCls}-open`]: true, + }); + return ( { {...this.props} onVisibleChange={this.onVisibleChange} > - {visible ? cloneElement(children, { className: childrenCls }) : children} + {visible ? cloneElement((children as React.ReactElement), { className: childrenCls }) : children} ); } diff --git a/components/tree/index.tsx b/components/tree/index.tsx index 0c176acb8e..b1e9a93525 100644 --- a/components/tree/index.tsx +++ b/components/tree/index.tsx @@ -1,8 +1,8 @@ import * as React from 'react'; -import RcTree from 'rc-tree'; +import RcTree, { TreeNode } from 'rc-tree'; import animation from '../_util/openAnimation'; -export interface TreeNodeProps { +export interface AntTreeNodeProps { disabled?: boolean; disableCheckbox?: boolean; title?: string | React.ReactNode; @@ -10,20 +10,23 @@ export interface TreeNodeProps { isLeaf?: boolean; } -export class TreeNode extends React.Component { +export class AntTreeNode extends React.Component { + render() { + return ; + } } -export interface TreeNodeEvent { +export interface AntTreeNodeEvent { event: 'check' | 'select'; - node: TreeNode; + node: AntTreeNode; checked?: boolean; - checkedNodes?: Array; + checkedNodes?: Array; selected?: boolean; - selectedNodes?: Array; + selectedNodes?: Array; } -export interface TreeNodeMouseEvent { - node: TreeNode; +export interface AntTreeNodeMouseEvent { + node: AntTreeNode; event: React.MouseEventHandler; } @@ -32,9 +35,9 @@ export interface TreeProps { className?: string; /** 是否支持多选 */ multiple?: boolean; - /**是否自动展开父节点 */ + /** 是否自动展开父节点 */ autoExpandParent?: boolean; - /**checkable状态下节点选择完全受控(父子节点选中状态不再关联)*/ + /** checkable状态下节点选择完全受控(父子节点选中状态不再关联)*/ checkStrictly?: boolean; /** 是否支持选中 */ checkable?: boolean; @@ -53,35 +56,35 @@ export interface TreeProps { /** 默认选中的树节点 */ defaultSelectedKeys?: Array; /** 展开/收起节点时触发 */ - onExpand?: (expandedKeys: Array, info: { node: TreeNode, expanded: boolean }) => void | PromiseLike; + onExpand?: (expandedKeys: Array, info: { node: AntTreeNode, expanded: boolean }) => void | PromiseLike; /** 点击复选框触发 */ - onCheck?: (checkedKeys: Array, e: TreeNodeEvent) => void; + onCheck?: (checkedKeys: Array, e: AntTreeNodeEvent) => void; /** 点击树节点触发 */ - onSelect?: (selectedKeys: Array, e: TreeNodeEvent) => void; - /** filter some treeNodes as you need. it should return true */ - filterTreeNode?: (node: TreeNode) => boolean; + onSelect?: (selectedKeys: Array, e: AntTreeNodeEvent) => void; + /** filter some AntTreeNodes as you need. it should return true */ + filterAntTreeNode?: (node: AntTreeNode) => boolean; /** 异步加载数据 */ - loadData?: (node: TreeNode) => PromiseLike; + loadData?: (node: AntTreeNode) => PromiseLike; /** 响应右键点击 */ - onRightClick?: (options: TreeNodeMouseEvent) => void; + onRightClick?: (options: AntTreeNodeMouseEvent) => void; /** 设置节点可拖拽(IE>8)*/ draggable?: boolean; /** 开始拖拽时调用 */ - onDragStart?: (options: TreeNodeMouseEvent) => void; + onDragStart?: (options: AntTreeNodeMouseEvent) => void; /** dragenter 触发时调用 */ - onDragEnter?: (options: TreeNodeMouseEvent) => void; + onDragEnter?: (options: AntTreeNodeMouseEvent) => void; /** dragover 触发时调用 */ - onDragOver?: (options: TreeNodeMouseEvent) => void; + onDragOver?: (options: AntTreeNodeMouseEvent) => void; /** dragleave 触发时调用 */ - onDragLeave?: (options: TreeNodeMouseEvent) => void; + onDragLeave?: (options: AntTreeNodeMouseEvent) => void; /** drop 触发时调用 */ - onDrop?: (options: TreeNodeMouseEvent) => void; + onDrop?: (options: AntTreeNodeMouseEvent) => void; style?: React.CSSProperties; prefixCls?: string; } export default class Tree extends React.Component { - static TreeNode = RcTree.TreeNode; + static TreeNode = TreeNode; static defaultProps = { prefixCls: 'ant-tree', diff --git a/components/upload/demo/basic.md b/components/upload/demo/basic.md index 93c38b7484..61a7f67f19 100644 --- a/components/upload/demo/basic.md +++ b/components/upload/demo/basic.md @@ -1,10 +1,18 @@ --- order: 0 -title: 点击上传 +title: + zh-CN: 点击上传 + en-US: Upload by clicking --- +## zh-CN + 经典款式,用户点击按钮弹出文件选择框。 +## en-US + +Classic mode. File selection dialog pops up when upload button is clicked + ````jsx import { Upload, message, Button, Icon } from 'antd'; diff --git a/components/upload/demo/beforeUpload.md b/components/upload/demo/beforeUpload.md index ca06510fae..66e3b03a48 100644 --- a/components/upload/demo/beforeUpload.md +++ b/components/upload/demo/beforeUpload.md @@ -1,12 +1,19 @@ --- order: 7 -title: 限制用户上传的文件 +title: + zh-CN: 限制用户上传的文件 + en-US: Filter uploads files --- +## zh-CN + 可以通过 `beforeUpload` 在文件上传之前进行干预,如限制用户只能上传 JPG 文件。 也支持异步检查,`beforeUpload` 的返回值可以是一个 Promise:[示例](http://react-component.github.io/upload/examples/beforeUpload.html)。 +## en-US +You can use `beforeUpload` to check whether user can upload, for example, limit file type only to be JPG. Checking can also be asynchronous. The return value can also be a Promise for function `beforeUpload` + ````jsx import { Upload, Button, Icon, message } from 'antd'; @@ -15,7 +22,7 @@ const props = { beforeUpload(file) { const isJPG = file.type === 'image/jpeg'; if (!isJPG) { - message.error('只能上传 JPG 文件哦!'); + message.error('you can only upload JPG file~'); } return isJPG; }, @@ -24,7 +31,7 @@ const props = { ReactDOM.render( , mountNode); diff --git a/components/upload/demo/defaultFileList.md b/components/upload/demo/defaultFileList.md index f9a8d9610e..4adb96bee3 100644 --- a/components/upload/demo/defaultFileList.md +++ b/components/upload/demo/defaultFileList.md @@ -1,10 +1,19 @@ --- order: 1 -title: 传入已上传的文件 +title: + zh-CN: 传入已上传的文件 + en-US: Set files that have been uploaded --- +## zh-CN + 对已上传的文件进行编辑。 +## en-US + +Edit uploaded files + + ````jsx import { Upload, Button, Icon } from 'antd'; @@ -32,7 +41,7 @@ const props = { ReactDOM.render( , mountNode); diff --git a/components/upload/demo/drag.md b/components/upload/demo/drag.md index 2a562a3205..0fda933bd2 100644 --- a/components/upload/demo/drag.md +++ b/components/upload/demo/drag.md @@ -1,10 +1,19 @@ --- order: 3 -title: 拖拽上传 +title: + zh-CN: 拖拽上传 + en-US: Upload files by dragging and dropping --- +## zh-CN + 可以把文件拖入指定区域,完成上传,同样支持点击上传。 +## en-US + +You can drag files to a specific area, to upload. Meanwhile you can also upload by selecting. + + ````jsx import { Upload, Icon, message } from 'antd'; const Dragger = Upload.Dragger; @@ -37,8 +46,8 @@ ReactDOM.render(

      -

      点击或将文件拖拽到此区域上传

      -

      支持单个或批量上传,严禁上传公司内部资料及其他违禁文件

      +

      Click or drag file to this area to upload

      +

      Support for a single or bulk upload. Strictly prohibit from uploading company data or other band files

    diff --git a/components/upload/demo/fileList.md b/components/upload/demo/fileList.md index 3df1ce3224..6ed31b8d18 100644 --- a/components/upload/demo/fileList.md +++ b/components/upload/demo/fileList.md @@ -1,8 +1,12 @@ --- order: 2 -title: 完全控制的上传列表 +title: + zh-CN: 完全控制的上传列表 + en-US: Complete control over file list --- +## zh-CN + 使用 `fileList` 对列表进行完全控制,可以实现各种自定义功能,以下演示三种情况: 1) 上传列表数量的限制。 @@ -11,6 +15,14 @@ title: 完全控制的上传列表 3) 按照服务器返回信息筛选成功上传的文件。 +## en-US + +You can gain full control over filelist by configuring `fileList`. You can accomplish all kinds of customed functions. The following shows three circumstances: + +1. limit the number of uploaded files +2. read from response and show file link +3. filter successfully uploaded files according to response from server + ````jsx import { Upload, Button, Icon } from 'antd'; @@ -28,20 +40,20 @@ const MyUpload = React.createClass({ handleChange(info) { let fileList = info.fileList; - // 1. 上传列表数量的限制 - // 只显示最近上传的一个,旧的会被新的顶掉 + // 1. Limit the number of uploaded files + // Only to show two recent uploaded files, and old ones will be replaced by the new fileList = fileList.slice(-2); - // 2. 读取远程路径并显示链接 + // 2. read from response and show file link fileList = fileList.map((file) => { if (file.response) { - // 组件会将 file.url 作为链接进行展示 + // Component will show file.url as link file.url = file.response.url; } return file; }); - // 3. 按照服务器返回信息筛选成功上传的文件 + // 3. filter successfully uploaded files according to response from server fileList = fileList.filter((file) => { if (file.response) { return file.response.status === 'success'; @@ -60,7 +72,7 @@ const MyUpload = React.createClass({ return ( ); diff --git a/components/upload/demo/multiple.md b/components/upload/demo/multiple.md index be410c9616..b34c6dbd2f 100644 --- a/components/upload/demo/multiple.md +++ b/components/upload/demo/multiple.md @@ -1,11 +1,19 @@ --- order: 5 hidden: true -title: 多文件选择 +title: + zh-CN: 多文件选择 + en-US: Multifile Selection --- +## zh-CN + 按住 ctrl 可选择多个文件,`ie10+` 支持。 +## en-US + +You can select multiple files with CTRL holding down. `IE10+` supported. + ````jsx import { Upload, message, Button, Icon } from 'antd'; @@ -17,9 +25,9 @@ const props = { console.log(info.file, info.fileList); } if (info.file.status === 'done') { - message.success(`${info.file.name} 上传成功。`); + message.success(`${info.file.name} upload sucessfully。`); } else if (info.file.status === 'error') { - message.error(`${info.file.name} 上传失败。`); + message.error(`${info.file.name} upload unsuccessfully。`); } }, }; @@ -27,7 +35,7 @@ const props = { ReactDOM.render( , mountNode); diff --git a/components/upload/demo/picture-card.md b/components/upload/demo/picture-card.md index 03f280bd2c..6e810e88e4 100644 --- a/components/upload/demo/picture-card.md +++ b/components/upload/demo/picture-card.md @@ -1,10 +1,18 @@ --- order: 8 -title: 图片卡片样式 +title: + zh-CN: 图片卡片样式 + en-US: Pictures with card tyle --- +## zh-CN + 上传文件为图片,可展示本地缩略图。 +## en-US + +If uploade file is picture, a thumbnail can be shown. + ````jsx import { Upload, Icon, Modal } from 'antd'; @@ -42,11 +50,11 @@ const ImageUploadList = React.createClass({
    -
    上传照片
    +
    upload pictures
    - + example - 示例 + sample example @@ -60,7 +68,7 @@ ReactDOM.render(, mountNode); ```` ````css -/* 配合样式可以做出上传按钮和示例效果 */ +/* you can make up upload button and sample style by using stylesheets */ .ant-upload-select-picture-card i { font-size: 28px; color: #999; diff --git a/components/upload/demo/picture-style.md b/components/upload/demo/picture-style.md index 95bcde1d01..d3d8b1fe7e 100644 --- a/components/upload/demo/picture-style.md +++ b/components/upload/demo/picture-style.md @@ -1,11 +1,19 @@ --- order: 6 -title: 图片列表样式 +title: + zh-CN: 图片列表样式 + en-US: Pictures with list style --- -上传文件为图片,可展示本地缩略图。 +## zh-CN + +上传文件为图片,可展示本地缩略图。`IE8/9` 不支持浏览器本地缩略图展示([Ref](https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL)),可以写 `thumbUrl` 属性来代替。 + +## en-US + +If uploade file is picture, a thumbnail can be shown. `IE8/9` do not support local thumbnail show. Please use `thumbUrl` instead. + -`IE8/9` 不支持浏览器本地缩略图展示([Ref](https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL)),可以写 `thumbUrl` 属性来代替。 ````jsx import { Upload, Button, Icon } from 'antd'; @@ -32,14 +40,14 @@ ReactDOM.render(


    @@ -47,7 +55,7 @@ ReactDOM.render( ```` ````css -/* 加几行样式将上传项变成平铺样式 */ +/* tile uploaded pictures */ .upload-list-inline .ant-upload-list-item { display: inline-block; width: 200px; diff --git a/components/upload/index.en-US.md b/components/upload/index.en-US.md new file mode 100644 index 0000000000..06d1b8373c --- /dev/null +++ b/components/upload/index.en-US.md @@ -0,0 +1,74 @@ +--- +category: Components +type: Form Controls +english: Upload +--- + +Upload file by selecting or dragging + +## When to use + +Uploading is the process of publishing information (web pages, text, pictures, video, etc.) to a remote server via a web page or upload tool. + +- When you need to upload one or more files. +- When you need to show the process of uploading. +- When you need to upload files by dragging and dropping. + + +## API + +| Property | Description | Type | Default| +|------------|----------------------------------------------------| ----------- |--------| +| name | Optional. The name of uploading file | String | file | +| defaultFileList | Optional. Default list of files that have been uploaded. | Array[Object] | - | +| fileList | Optional. List of files that have been uploaded. | Array[Object] | - | +| action | Required. Uploading URL | String | - | +| data | Optional. Uploading params or function which can return uploading params. | Object or function(file) | - | +| headers | Optional. Set request headers, valid above IE10. | Object | - | +| showUploadList | Optional. Whether to show uploadList. | Boolean | true | +| multiple | Optional. Whether to support selected multiple file. `IE10+` supported. You can select multiple files with CTRL holding down while multiple is set to be true | Boolean | false | +| accept | Optional. File types that can be accepted. See [input accept Attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-accept) | String | - | +| beforeUpload | Optional. Hook function which takes an argument: the uploaded file, will be executed before uploading. Uploading will be stopped with `false` or a rejected Promise returned. **Warning:this function is not supported by old IE**。 | Function | - | +| onChange | Optional. A callback function, can be executed when uploading state is changing. See [onChange](#onChange) | Function | - | +| listType | Optional. Built-in stylesheets, support for two types: `text` or `picture` | String | 'text'| +| onPreview | A callback function, will be executed when file link is clicked. | Function(file) | - | +| onRemove | A callback function, will be executed when removing file button is clicked | Function(file) | - | +| supportServerRender | Need to be turned on while the server side is rendering.| Boolean | false | + +### onChange + +> The function will be called when uploading is in progress, completed or failed + +When uploading state change, it returns: + +```js +{ + file: { /* ... */ }, + fileList: [ /* ... */ ], + event: { /* ... */ }, +} +``` + +1. `file` File object for the current operation. + + ```js + { + uid: 'uid', // unique identifier,negative is recommend,to prevent interference with internal generated id + name: 'xx.png' // file name + status: 'done', // options:uploading, done, error, removed + response: '{"status": "success"}', // response from server + } + ``` + + If multiple files are uploaded, this parameter will be Array Object `[file, ...]` + +2. `fileList` current list of files +3. `event` response from server, including uploading progress, supported by advanced browsers. + +## show download links + +please set property `url` of property `fileList` to control content of link + +## IE note + +- [https://github.com/react-component/upload#ie89-note](https://github.com/react-component/upload#ie89-note) diff --git a/components/upload/index.tsx b/components/upload/index.tsx index 4996f5db83..710411e8af 100644 --- a/components/upload/index.tsx +++ b/components/upload/index.tsx @@ -84,6 +84,7 @@ export default class Upload extends React.Component { recentUploadStatus: boolean | PromiseLike; progressTimer: any; refs: { + [key: string]: any; upload: any; }; diff --git a/components/upload/index.md b/components/upload/index.zh-CN.md similarity index 96% rename from components/upload/index.md rename to components/upload/index.zh-CN.md index 5d7d71174e..86017d2951 100644 --- a/components/upload/index.md +++ b/components/upload/index.zh-CN.md @@ -19,7 +19,7 @@ english: Upload | 参数 | 说明 | 类型 | 默认值| |------------|--------------------------------------------------------------| ----------- |-------| -| name | 可选参数, 上传的文件 | String | file | + | name | 可选参数, 上传的文件 | String | file | | defaultFileList | 可选参数,默认已经上传的文件列表 | Array[Object] | 无 | | fileList | 可选参数,已经上传的文件列表 | Array[Object] | 无 | | action | 必选参数, 上传的地址 | String | 无 | diff --git a/components/upload/uploadList.tsx b/components/upload/uploadList.tsx index ca166289c3..97d3d84200 100644 --- a/components/upload/uploadList.tsx +++ b/components/upload/uploadList.tsx @@ -76,7 +76,7 @@ export default class UploadList extends React.Component { className={`${prefixCls}-list-item-thumbnail`} onClick={e => this.handlePreview(file, e)} href={file.url} - target="_blank" + target="_blank" rel="noopener noreferrer" > {file.name} @@ -104,7 +104,7 @@ export default class UploadList extends React.Component { ? ( this.handlePreview(file, e)} > @@ -125,7 +125,7 @@ export default class UploadList extends React.Component { this.handlePreview(file, e)} > diff --git a/components/validation/index.tsx b/components/validation/index.tsx deleted file mode 100644 index c2ce6f081e..0000000000 --- a/components/validation/index.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import * as React from 'react'; -import warning from 'warning'; - -export default class Validation extends React.Component { - componentDidMount() { - warning(false, '`Validation` is removed, please use `Form` which has supported validation after antd@0.12.0,' + - ' or you can just import Validation from \'rc-form-validation\' for compatibility'); - } - render() { - return null; - } -} - -Validation.Validator = () => {}; -Validation.FieldMixin = { - setField() {}, -}; diff --git a/components/validation/style/index.tsx b/components/validation/style/index.tsx deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/custom-typings.d.ts b/custom-typings.d.ts index 6bec462f9c..609f79d503 100644 --- a/custom-typings.d.ts +++ b/custom-typings.d.ts @@ -8,11 +8,11 @@ declare module 'react-addons-pure-render-mixin' { } declare module 'gregorian-calendar-format' { - export default function({}): string; + export default function(format: string, localeFormat: Object): void; } declare module 'gregorian-calendar' { - export default function({}): string; + export default function({}): void; } declare module 'gregorian-calendar/lib/locale/en_US' { @@ -127,7 +127,7 @@ declare module 'rc-cascader' { } declare module 'array-tree-filter' { - export default function(): any; + export default function(tree: any, filter: any): any; } declare module 'rc-checkbox' { @@ -143,16 +143,25 @@ declare module 'rc-dropdown' { } declare module 'rc-editor-mention' { - export default function(): any; + export const Nav: any; + export const toString: any; + export const toEditorState: any; + export const getMentions: any; + const exports: any; + export default exports; } declare module 'rc-progress' { - export default function(): any; + export const Circle: any; + const exports: any; + export default exports; } declare module 'rc-menu' { export const SubMenu: any; export const Item: any; + export const Divider: any; + export const ItemGroup: any; export default function(): any; } @@ -162,6 +171,7 @@ declare module 'rc-tabs' { } declare module 'rc-tree' { + export const TreeNode: any; export default function(): any; } @@ -178,11 +188,19 @@ declare module 'rc-input-number' { } declare module 'rc-pagination' { - export default function(): any; + const exports: any; + export default exports; +} + +declare module 'rc-pagination/lib/locale/zh_CN' { + const exports: any; + export default exports; } declare module 'rc-notification' { - export default function(): any; + export function newInstance(config: Object): any; + const exports: any; + export default exports; } declare module 'rc-dialog' { @@ -228,9 +246,11 @@ declare module 'rc-upload' { } declare module 'rc-collapse' { - export default function(): any; + export const Panel: any; + const exports: any; + export default exports; } declare module 'rc-form/lib/createDOMForm' { - export default function(): any; + export default function(Object): any; } diff --git a/docs/resource/download.zh-CN.md b/docs/resource/download.zh-CN.md index 3dbb6fb436..69b0249cc8 100644 --- a/docs/resource/download.zh-CN.md +++ b/docs/resource/download.zh-CN.md @@ -10,17 +10,10 @@ english: Download - Axure Components v2.0.1 + Ant Design Library v2.0.1 一套强大的 Ant Design 的 Axure 部件库 - - - - Axure Box v1.3 - 强大的 Ant Design 组件拼装方式 - - diff --git a/index.d.ts b/index.d.ts deleted file mode 100644 index fc8e724c57..0000000000 --- a/index.d.ts +++ /dev/null @@ -1,2011 +0,0 @@ -// originated by: bang88 , Bruce Mitchener - -import * as React from 'react' - - -// Affix -interface AffixProps { - /** - * 距离窗口顶部达到指定偏移量后触发 - */ - offsetTop?:number, - offsetBottom?:number, - style?:React.CSSProperties -} -/** - * # Affix - * 将页面元素钉在可视范围。 - * ## 何时使用 - * 当内容区域比较长,需要滚动页面时,这部分内容对应的操作或者导航需要在滚动范围内始终展现。常用于侧边菜单和按钮组合。 - * 页面可视范围过小时,慎用此功能以免遮挡页面内容。 - */ -export class Affix extends React.Component { -} - -type AlertType = 'success' | 'info' | 'warning' | 'error' - -// Alert -interface AlertProps { - /** - * 必选参数,指定警告提示的样式,有四种选择`success`、`info`、`warn`、`error` - */ - type:AlertType, - /**可选参数,默认不显示关闭按钮 */ - closable?:boolean, - /**可选参数,自定义关闭按钮 */ - closeText?:React.ReactNode, - /**必选参数,警告提示内容 */ - message:React.ReactNode, - /**可选参数,警告提示的辅助性文字介绍 */ - description?:React.ReactNode, - /** 固定状态改变时触发的回调函数 */ - onChange?:(affixed: boolean) => void, - /**可选参数,关闭时触发的回调函数 */ - onClose?:Function, - /**可选参数,是否显示辅助图标 */ - showIcon?:boolean, - - style?:React.CSSProperties -} - -/** - * # Alert - * 警告提示,展现需要关注的信息。 - - * ## 何时使用 - - * - 当某个页面需要向用户显示警告的信息时。 - * - 非浮层的静态展现形式,始终展现,不会自动消失,用户可以点击关闭。 - * */ -export class Alert extends React.Component { -} - - -interface BadgeProps { - /** 展示的数字,大于 overflowCount 时显示为 `${overflowCount}+`,为 0 时隐藏*/ - count:number, - /** 展示封顶的数字值*/ - overflowCount?:number, - /** 不展示数字,只有一个小红点*/ - dot?:boolean, - - style?:React.CSSProperties -} -// Badge -/** - * #Badge - * - * 图标右上角的圆形徽标数字。 - - * ## 何时使用 - - * 一般出现在通知图标或头像的右上角,用于显示需要处理的消息条数,通过醒目视觉形式吸引用户处理。 - * - */ -export class Badge extends React.Component { -} - -type ButtonType = 'primary' | 'ghost' | 'dashed' -type ButtonShape = 'circle' | 'circle-outline' -type ButtonSize = 'small' | 'large' -// Button -interface ButtonProps { - /** 设置按钮类型,可选值为 `primary` `ghost` 或者不设 */ - type?:ButtonType, - /** 设置 `button` 原生的 `type` 值,可选值请参考 HTML标准*/ - htmlType?:string, - - icon?:string, - /** 设置按钮形状,可选值为 `circle` `circle-outline` 或者不设*/ - shape?:ButtonShape, - /** 设置按钮大小,可选值为 `small` `large` 或者不设*/ - size?:ButtonSize, - /** `click` 事件的 handler*/ - onClick?:React.FormEventHandler, - /** 设置按钮载入状态*/ - loading?:boolean, - - disabled?:boolean, - - style?:React.CSSProperties -} - - -interface ButtonGroupProps { - /** 设置按钮大小,可选值为 `small` `large` 或者不设*/ - size?:ButtonSize, - - style?:React.CSSProperties -} - -/** - 可以将多个 `Button` 放入 `Button.Group` 的容器中。 - - 通过设置 `size` 为 `large` `small` 分别把按钮组合设为大、小尺寸。若不设置 `size`,则尺寸为中。*/ -declare class ButtonGroup extends React.Component { -} - -/** - * #Button - 按钮用于开始一个即时操作。 - - ## 何时使用 - - 标记了一个(或封装一组)操作命令,响应用户点击行为,触发相应的业务逻辑。*/ -export class Button extends React.Component { - static Group:typeof ButtonGroup -} - -// Breadcrumb - -interface BreadcrumbItemProps { - /** 链接,如不传则不可点击 */ - href?:string -} -export class BreadcrumbItem extends React.Component { -} - -interface BreadcrumbProps { - prefixCls?:string, - /** router 的路由栈信息 */ - routes?:Array, - /** 路由的参数*/ - params?:Object, - /** 分隔符自定义*/ - separator?:string | React.ReactNode, - linkRender?:(path:string, name:string) => React.ReactNode, - nameRender?:(name:string) => React.ReactNode - - style?:React.CSSProperties -} -/** - * #Breadcrumb - 显示当前页面在系统层级结构中的位置,并能向上返回。 - - ## 何时使用 - - - 当系统拥有超过两级以上的层级结构时; - - 当需要告知用户“你在哪里”时; - - 当需要向上导航的功能时。*/ -export class Breadcrumb extends React.Component { - static Item:typeof BreadcrumbItem -} - -export interface GregorianCalendar { - getMonth():number, - getYear():number, - getDayOfMonth():string, - getHourOfDay():string, - getMinutes():number, - getSeconds():number, - getMilliSeconds():number, - getWeekOfYear():number, - getWeekOfMonth():number, - getDayOfYear():number, - getDayOfWeek():number, - getDayOfWeekInMonth():number, - getWeekYear():number, - getWeeksInWeekYear():number -} - -type CalendarMode = 'month' | 'year'; - -// Calendar -interface CalendarProps { - /** 自定义渲染月单元格*/ - monthCellRender?:(value:GregorianCalendar, locale:any) => React.ReactNode, - /** 自定义渲染日期单元格*/ - dateCellRender?:(value:GregorianCalendar) => React.ReactNode, - /** 是否全屏显示*/ - fullscreen?:boolean, - /** 国际化配置*/ - locale?:Object, - prefixCls?:string, - className?:string, - /** 日期面板变化回调*/ - onPanelChange?:(value:GregorianCalendar, mode:CalendarMode) => void, - /** 展示日期*/ - value?:Date, - /** 默认展示日期*/ - defaultValue?:Date, - /** 初始模式,`month/year`*/ - mode?:CalendarMode, - - style?:React.CSSProperties -} -/** - * #Calendar - 按照日历形式展示数据的容器。 - - ## 何时使用 - - 当数据是日期或按照日期划分时,例如日程、课表、价格日历等,农历等。目前支持年/月切换。 - */ -export class Calendar extends React.Component { -} - -type CarouselEffect = 'scrollx' | 'fade' -// Carousel -interface CarouselProps { - /** 动画效果函数,可取 scrollx, fade*/ - effect?:CarouselEffect, - /** 是否显示面板指示点*/ - dots?:boolean, - /** 垂直显示*/ - vertical?:boolean, - /** 是否自动切换*/ - autoplay?:boolean, - /** 动画效果*/ - easing?:string, - /** 切换面板的回调*/ - beforeChange?:(from:number, to:number) => void, - /** 切换面板的回调*/ - afterChange?:(current:number) => void, - - style?:React.CSSProperties -} -/** - * #Carousel - 旋转木马,一组轮播的区域。 - - ## 何时使用 - - - 当有一组平级的内容。 - - 当内容空间不足时,可以用走马灯的形式进行收纳,进行轮播展现。 - - 常用于一组图片或卡片轮播。 - */ -export class Carousel extends React.Component { -} - -export interface CascaderOptionType { - value:string, - label:string, - disabled?:boolean, - children?:Array -} - -type CascaderExpandTrigger = 'click' | 'hover' -// Cascader -interface CascaderProps { - /** 可选项数据源*/ - options:Array, - /** 默认的选中项*/ - defaultValue?:Array, - /** 指定选中项*/ - value?:Array, - /** 选择完成后的回调*/ - onChange?:(value:string, selectedOptions:CascaderOptionType) => void, - /** 选择后展示的渲染函数*/ - displayRender?:(label:Array) => React.ReactNode, - /** 自定义样式*/ - style?:React.CSSProperties, - /** 自定义类名*/ - className?:string, - /** 自定义浮层类名*/ - popupClassName?:string, - /** 浮层预设位置:`bottomLeft` `bottomRight` `topLeft` `topRight` */ - popupPlacement?:string, - /** 输入框占位文本*/ - placeholder?:string, - /** 输入框大小,可选 `large` `default` `small` */ - size?:string, - /** 禁用*/ - disabled?:boolean, - /** 是否支持清除*/ - allowClear?:boolean, - - expandTrigger?:CascaderExpandTrigger, - - changeOnSelect?:boolean -} -/** - * #Cascader - 级联选择框。 - - - ## 何时使用 - - - 需要从一组相关联的数据集合进行选择,例如省市区,公司层级,事物分类等。 - - 从一个较大的数据集合中进行选择时,用多级分类进行分隔,方便选择。 - - 比起 Select 组件,可以在同一个浮层中完成选择,有较好的体验。*/ -export class Cascader extends React.Component { -} - -// Checkbox -interface CheckboxProps { - /** 指定当前是否选中*/ - checked?:boolean, - /** 初始是否选中*/ - defaultChecked?:boolean, - /** 变化时回调函数*/ - onChange?:React.FormEventHandler, - - style?:React.CSSProperties -} - -export interface CheckboxOptionType { - label:string, - value:string, - disabled?:boolean -} - -interface CheckboxGroupProps { - /** 默认选中的选项*/ - defaultValue?:Array, - /** 指定选中的选项*/ - value?:Array, - /** 指定可选项*/ - options?:Array | Array, - /** 变化时回调函数*/ - onChange?:(checkedValue:Array) => void, - - disabled?:boolean, - - style?:React.CSSProperties -} -/** Checkbox 组*/ -declare class CheckboxGroup extends React.Component { -} -/** - * #Checkbox - 多选框。 - - ## 何时使用 - - - 在一组可选项中进行多项选择时; - - 单独使用可以表示两种状态之间的切换,和 `switch` 类似。区别在于切换 `switch` 会直接触发状态改变,而 `checkbox` 一般用于状态标记,需要和提交操作配合。 - */ -export class Checkbox extends React.Component { - static Group:typeof CheckboxGroup -} - -// Collapse - -interface CollapseProps { - /** 当前激活 tab 面板的 key*/ - activeKey?:Array | string, - /** 初始化选中面板的key */ - defaultActiveKey?:Array, - /** accordion 为 true 的时候,一次只可以打开一个面板 */ - accordion?:boolean, - /** 切换面板的回调*/ - onChange?:(key:string) => void, - - style?:React.CSSProperties -} - -interface CollapsePanelProps { - /** 对应 activeKey */ - key:string, - /** 面板头内容*/ - header:React.ReactNode, - - style?:React.CSSProperties -} - -declare class CollapsePanel extends React.Component { -} -/** - * #Collapse - 可以折叠/展开的内容区域。 - - ## 何时使用 - - - 对复杂区域进行分组和隐藏,保持页面的整洁。 - - `手风琴` 是一种特殊的折叠面板,只允许单个内容区域展开。*/ -export class Collapse extends React.Component { - static Panel:typeof CollapsePanel -} - -type DatePickerDateType = string | Date; - -// DatePicker -interface DatePickerProps { - - value?:DatePickerDateType, - defaultValue?:DatePickerDateType, - /** 展示的日期格式,配置参考 [GregorianCalendarFormat](https://github.com/yiminghe/gregorian-calendar-format)*/ - format?:string, - /** 不可选择的日期*/ - disabledDate?:Function, - /** 时间发生变化的回调,发生在用户选择时间时*/ - onChange?:(date:Date, dateString:string) => void, - /** 禁用*/ - disabled?:boolean, - style?:React.CSSProperties, - /** 格外的弹出日历样式*/ - popupStyle?:React.CSSProperties, - /** 输入框大小,`large` 高度为 32px,`small` 为 22px,默认是 28px*/ - size?:'large' | 'small', - /** 国际化配置*/ - locale?:Object, - /** 增加时间选择功能*/ - showTime?:boolean, - /** 点击确定按钮的回调*/ - onOk?:(value:Date) => void, - /** 定义浮层的容器,默认为 body 上新建 div*/ - getCalendarContainer?:Function - -} - -interface RangePickProps { - value?:Array, - defaultValue?:Array, - format?:string, - onChange?:(date:Array, dateString:Array) => void, - style:React.CSSProperties, - showTime:boolean | Object - -} -declare class RangePicker extends React.Component { -} - -interface MonthPickProps { - value?:DatePickerDateType, - defaultValue?:DatePickerDateType, - /** 展示的日期格式,配置参考 [GregorianCalendarFormat](https://github.com/yiminghe/gregorian-calendar-format)*/ - format?:string, - /** 时间发生变化的回调,发生在用户选择时间时*/ - onChange?:(date:Date) => void, - /** 禁用*/ - disabled?:boolean, - style?:React.CSSProperties, - /** 格外的弹出日历样式*/ - popupStyle?:React.CSSProperties, - /** 输入框大小,`large` 高度为 32px,`small` 为 22px,默认是 28px*/ - size?:'large' | 'small', - /** 国际化配置*/ - locale?:Object, - /** 定义浮层的容器,默认为 body 上新建 div*/ - getCalendarContainer?:Function -} -declare class MonthPicker extends React.Component { -} -/** - * #DatePicker - 输入或选择日期的控件。 - - ## 何时使用 - - 当用户需要输入一个日期,可以点击标准输入框,弹出日期面板进行选择。*/ -export class DatePicker extends React.Component { - static RangePicker:typeof RangePicker - static MonthPicker:typeof MonthPicker -} - -// Dropdown - -interface DropdownProps { - /** 触发下拉的行为 ['click'] or ['hover']*/ - trigger?:Array, - /** 菜单节点*/ - overlay:React.ReactNode, - - style?:React.CSSProperties -} - -interface DropdownButtonProps { - /** 按钮类型*/ - type?:'primary' | 'ghost' | 'dash', - /** 点击左侧按钮的回调*/ - onClick?:React.FormEventHandler, - /** 触发下拉的行为*/ - trigger?:'click' | 'hover', - /** 菜单节点*/ - overlay:React.ReactNode, - - visible?:boolean, - - onVisibleChange?:(visible:boolean) => void, - - style?:React.CSSProperties -} - -declare class DropdownButton extends React.Component { -} -/** - * #Dropdown - 向下弹出的列表。 - - ## 何时使用 - - 当页面上的操作命令过多时,用此组件可以收纳操作元素。点击或移入触点,会出现一个下拉菜单。可在列表中进行选择,并执行相应的命令。 - */ -export class Dropdown extends React.Component { - static Button:typeof DropdownButton -} - -export interface FormItemLabelColOption { - span:number, - offset:number -} - -// Form -interface FormItemProps { - prefixCls?:string, - /** label 标签的文本*/ - label?:string, - /** label 标签布局,通 `` 组件,设置 `span` `offset` 值,如 `{span: 3, offset: 12}`*/ - labelCol?:FormItemLabelColOption, - /** 需要为输入控件设置布局样式时,使用该属性,用法同 labelCol*/ - wrapperCol?:FormItemLabelColOption, - /** 提示信息,如不设置,则会根据校验规则自动生成 */ - help?:string, - /** 额外的提示信息,和 help 类似,当需要错误信息和提示文案同时出现时,可以使用这个。*/ - extra?:string, - /** 是否必填,如不设置,则会根据校验规则自动生成 */ - validateStatus?:'success' | 'warning' | 'error' | 'validating', - /** 配合 validateStatus 属性使用,是否展示校验状态图标 */ - hasFeedback?:boolean, - - className?:string, - - required?:boolean, - - style?:React.CSSProperties -} -/** - 表单一定会包含表单域,表单域可以是输入控件,标准表单域,标签,下拉菜单,文本域等。 - - 这里我们分别封装了表单域 `` 和输入控件 ``。*/ -export class FormItem extends React.Component { -} - -interface FormComponentProps { - form:CreateFormOptions -} -export class FormComponent extends React.Component { -} - -// function create -type CreateFormOptions = { - /** 获取一组输入控件的值,如不传入参数,则获取全部组件的值*/ - getFieldsValue():(fieldNames?:Array) => any - /** 获取一个输入控件的值*/ - getFieldValue():(fieldName:string) => any - /** 设置一组输入控件的值*/ - setFieldsValue():(obj:Object) => void - /** 设置一组输入控件的值*/ - setFields():(obj:Object) => void - /** 校验并获取一组输入域的值与 Error*/ - validateFields():(fieldNames?:Array, options?:Object, callback?:(erros:any, values:any) => void) => any - /** 与 `validateFields` 相似,但校验完后,如果校验不通过的菜单域不在可见范围内,则自动滚动进可见范围 */ - validateFieldsAndScroll():(fieldNames?:Array, options?:Object, callback?:(erros:any, values:any) => void) => any - /** 获取某个输入控件的 Error */ - getFieldError():(name:string) => Object - /** 判断一个输入控件是否在校验状态*/ - isFieldValidating():(name:string) => Object - /**重置一组输入控件的值与状态,如不传入参数,则重置所有组件*/ - resetFields():(names?:Array) => void - - getFieldsValue():(id:string, options:{ - /** 子节点的值的属性,如 Checkbox 的是 'checked'*/ - valuePropName?:string, - /** 子节点的初始值,类型、可选值均由子节点决定*/ - initialValue?:any, - /** 收集子节点的值的时机*/ - trigger?:string, - /** 校验子节点值的时机*/ - validateTrigger?:string, - /** 校验规则,参见 [async-validator](https://github.com/yiminghe/async-validator) */ - rules?:Array, - /** 必填输入控件唯一标志*/ - id?:string - }) => Array -} - -interface ComponentDecorator { - (component:T):T; -} -interface FormProps { - prefixCls?:string, - /** 水平排列布局*/ - horizontal?:boolean, - /** 行内排列布局*/ - inline?:boolean, - /** 经 `Form.create()` 包装过的组件会自带 `this.props.form` 属性,直接传给 Form 即可*/ - form?:Object, - /** 数据验证成功后回调事件*/ - onSubmit?:React.FormEventHandler, - - style?:React.CSSProperties -} - -interface FormCreateOption { - /** - * 当 `Form.Item` 子节点的值发生改变时触发,可以把对应的值转存到 Redux store - */ - onFieldsChange?:(props:any, fields:Array) => void, - /** 把 props 转为对应的值,可用于把 Redux store 中的值读出 */ - mapPropsToFields?:(props:any) => void -} -/** - * #Form - 具有数据收集、校验和提交功能的表单,包含复选框、单选框、输入框、下拉选择框等元素。 - - ## 表单 - - 我们为 `form` 提供了以下两种排列方式: - - - 水平排列:可以实现 `label` 标签和表单控件的水平排列; - - 行内排列:使其表现为 `inline-block` 级别的控件。 - */ -export class Form extends React.Component { - static Item:typeof FormItem - - static create(options?:FormCreateOption):ComponentDecorator -} - - -// Icon -interface IconProps { - /** 图标类型*/ - type:string, - - style?:React.CSSProperties -} -/** - * #Icon - 有含义的矢量图形,每一个图标打倒一个敌人。 - - ## 图标的命名规范 - - 我们为每个图标赋予了语义化的命名,命名规则如下: - - - 实心和描线图标保持同名,用 `-o` 来区分,比如 `question-circle`(实心) 和 `question-circle-o`(描线); - - - 命名顺序:`[icon名]-[形状可选]-[描线与否]-[方向可选]`。 - - ## 如何使用 - - 使用 `` 标签声明组件,指定图标对应的 type 属性,示例代码如下: - - ```html - - ``` - - 最终会渲染为: - - ```html - - ```*/ -export class Icon extends React.Component { -} - -// Input -interface InputProps { - /** 【必须】声明 input 类型,同原生 input 标签的 type 属性*/ - type?:string, - id?:string, - /** 控件大小,默认值为 default 。注:标准表单内的输入框大小限制为 large。 {'large','default','small'}*/ - size?:string, - /** 是否禁用状态,默认为 false*/ - disabled?:boolean, - value?:any, - /** 设置初始默认值*/ - defaultValue?:any, - className?:string, - /** 带标签的 input,设置前置标签*/ - addonBefore?:React.ReactNode, - /** 带标签的 input,设置后置标签*/ - addonAfter?:React.ReactNode, - prefixCls?:string, - placeholder?:string, - onChange?:React.FormEventHandler, - style:React.CSSProperties -} -export class Input extends React.Component { -} - -// InputNumber -interface InputNumberProps { - /** 最小值*/ - min:number, - /** 最大值*/ - max:number, - /** 当前值*/ - value?:number, - /** 每次改变步数*/ - step?:number, - /** 初始值*/ - defaultValue?:number, - /** 变化回调*/ - onChange?:React.FormEventHandler, - /** 禁用*/ - disabled?:boolean, - /** 输入框大小*/ - size?:string, - - style?:React.CSSProperties - -} -/** - * #InputNumber - 通过鼠标或键盘,输入范围内的数值。 - - ## 何时使用 - - 当需要获取标准数值时。*/ -export class InputNumber extends React.Component { -} - - -// Layout -// Row -interface RowProps { - gutter?:number, - type?:'flex', - align?:'top' | 'middle' | 'bottom', - justify?:'start' | 'end' | 'center' | 'space-around' | 'space-between', - style?:React.CSSProperties, - className?:string, -} -export class Row extends React.Component { -} - -// Col -interface ColProps { - span?:number, - lg?: number, - md?:number, - sm?:number, - xs?:number, - order?:number, - offset?:string, - push?:string, - pull?:string, - className?:string, - style?:React.CSSProperties -} -/** - 在多数业务情况下,Ant Design需要在设计区域内解决大量信息收纳的问题,因此在12栅格系统的基础上,我们将整个设计建议区域按照24等分的原则进行划分。 - - 划分之后的信息区块我们称之为“盒子”。建议横向排列的盒子数量最多四个,最少一个。“盒子”在整个屏幕上占比见上图。设计部分基于盒子的单位定制盒子内部的排版规则,以保证视觉层面的舒适感。 - - ## 概述 - - 布局的栅格化系统,我们是基于行(row)和列(col)来定义信息区块的外部框架,以保证页面的每个区域能够稳健地排布起来。下面简单介绍一下它的工作原理: - - * 通过`row`在水平方向建立一组`column`(简写col) - * 你的内容应当放置于`col`内,并且,只有`col`可以作为`row`的直接元素 - * 栅格系统中的列是指1到24的值来表示其跨越的范围。例如,三个等宽的列可以使用`.col-8`来创建 - * 如果一个`row`中的`col`总和超过24,那么多余的`col`会作为一个整体另起一行排列 - - ## Flex 布局 - - 我们的栅格化系统支持 Flex 布局,允许子元素在父节点内的水平对齐方式 - 居左、居中、居右、等宽排列、分散排列。子元素与子元素之间,支持顶部对齐、垂直居中对齐、底部对齐的方式。同时,支持使用 order 来定义元素的排列顺序。 - - Flex 布局是基于 24 栅格来定义每一个“盒子”的宽度,但排版则不拘泥于栅格。*/ -export class Col extends React.Component { -} - -// Menu -interface MenuItemProps { - /** - * (是否禁用) - * - * @type {boolean} - */ - disabled?:boolean, - key?:string, - style?:React.CSSProperties - -} -export class MenuItem extends React.Component { -} - -interface MenuSubMenuProps { - disabled?:boolean, - key?:string, - /** - * (子菜单项值) - * - * @type {(string | React.ReactNode)} - */ - title:string | React.ReactNode, - /** - * (子菜单的菜单项) - * - * @type {(MenuItem | MenuSubMenu)} - */ - children?:Array, - - onTitleClick?:Function, - - style?:React.CSSProperties -} -export class MenuSubMenu extends React.Component { -} - -interface MenuItemGroupProps { - /** - * (分组标题) - * - * @type {(string | React.ReactNode)} - */ - title:string | React.ReactNode, - /** - * (分组的菜单项) - * - * @type {MenuItem} - */ - children?:Array, - - style?:React.CSSProperties -} -export class MenuItemGroup extends React.Component { -} - -interface MenuProps { - id?: string, - /** 主题颜色*/ - theme?:'light' | 'dark', - /** 菜单类型 enum: `vertical` `horizontal` `inline`*/ - mode?:'vertical' | 'horizontal' | 'inline', - /** 当前选中的菜单项 key 数组*/ - selectedKeys?:Array, - /** 初始选中的菜单项 key 数组*/ - defaultSelectedKeys?:Array, - /** 当前展开的菜单项 key 数组*/ - openKeys?:Array, - /** 初始展开的菜单项 key 数组*/ - defaultOpenKeys?:Array, - - onOpen?:Function, - - onClose?:Function, - - /** - * 被选中时调用 - * - * @type {(item: any, key: string, selectedKeys: Array) => void} - */ - onSelect?:(item:any, key:string, selectedKeys:Array) => void, - /** 取消选中时调用*/ - onDeselect?:(item:any, key:string, selectedKeys:Array) => void, - /** 点击 menuitem 调用此函数*/ - onClick?:(item:any, key:string) => void, - /** 根节点样式*/ - style?:React.CSSProperties -} -/** - # Menu - 为页面和功能提供导航的菜单列表。 - - ## 何时使用 - - 导航菜单是一个网站的灵魂,用户依赖导航在各个页面中进行跳转。一般分为顶部导航和侧边导航,顶部导航提供全局性的类目和功能,侧边导航提供多级结构来收纳和排列网站架构。 - - 更多布局和导航的范例可以参考:[常用布局](/spec/layout)。*/ -export class Menu extends React.Component { - static Item:typeof MenuItem - static SubMenu:typeof MenuSubMenu - static ItemGroup:typeof MenuItemGroup - static Divider:typeof React.Component -} - -// Message -type MessageFunc = (/** 提示内容*/ - content:string, - /** 自动关闭的延时*/ - duration?:number) => void -/** - * #Message - 全局展示操作反馈信息。 - - ## 何时使用 - - - 可提供成功、警告和错误等反馈信息。 - - 顶部居中显示并自动消失,是一种不打断用户操作的轻量级提示方式。*/ -export const message:{ - - success:MessageFunc - error:MessageFunc - info:MessageFunc - loading:MessageFunc - config:(options:{ - /** - * 消息距离顶部的位置 - * - * @type {number} - */ - top:number, - duration?:number - }) => void - destroy:() => void -} - -// Modal -type ModalFunc = (options:{ - visible?:boolean, - title?:React.ReactNode | string, - content?:React.ReactNode | string, - onOk?:Function, - onCancel?:Function, - width?:string | number, - iconClassName?:string, - okText?:string, - cancelText?:string -}) => void - -interface ModalProps { - /** 对话框是否可见*/ - visible?:boolean, - /** 确定按钮 loading*/ - confirmLoading?:boolean, - /** 标题*/ - title?:React.ReactNode | string, - /** 是否显示右上角的关闭按钮*/ - closable?:boolean, - /** 点击确定回调*/ - onOk?:Function, - /** 点击遮罩层或右上角叉或取消按钮的回调*/ - onCancel?:Function, - /** 宽度*/ - width?:string | number, - /** 底部内容*/ - footer?:React.ReactNode | string, - /** 确认按钮文字*/ - okText?:string, - /** 取消按钮文字*/ - cancelText?:string, - /** 点击蒙层是否允许关闭*/ - maskClosable?:boolean, - - style?:React.CSSProperties, - - wrapClassName?:string -} - -/** - # Modal - 模态对话框。 - - ## 何时使用 - - 需要用户处理事务,又不希望跳转页面以致打断工作流程时,可以使用 `Modal` 在当前页面正中打开一个浮层,承载相应的操作。 - - 另外当需要一个简洁的确认框询问用户时,可以使用精心封装好的 `ant.Modal.confirm()` 等方法。*/ -export class Modal extends React.Component { - static info:ModalFunc - static success:ModalFunc - static error:ModalFunc - static confirm:ModalFunc -} - -// Notification -type NotificationFunc = (config:{ - /** 通知提醒标题,必选 */ - message:React.ReactNode | string, - /** 通知提醒内容,必选*/ - description:React.ReactNode | string, - /** 自定义关闭按钮*/ - btn?:React.ReactNode | string, - /** 当前通知唯一标志*/ - key?:string, - /** 点击默认关闭按钮时触发的回调函数*/ - onClose?:Function, - /** 默认 4.5 秒后自动关闭,配置为 null 则不自动关闭*/ - duration?:number -}) => void -/** - * #notification - 全局展示通知提醒信息。 - - ## 何时使用 - - 在系统右上角显示通知提醒信息。经常用于以下情况: - - - 较为复杂的通知内容。 - - 带有交互的通知,给出用户下一步的行动点。 - - 系统主动推送。*/ -export const notification:{ - success:NotificationFunc - error:NotificationFunc - info:NotificationFunc - warn:NotificationFunc - close:(key:string) => void - destroy:() => void - config:(options:{ - /** 消息距离顶部的位置*/ - top:number - }) => void - -} - - -// Pagination -interface PaginationProps { - /** 当前页数*/ - current?:number, - /** 默认的当前页数*/ - defaultCurrent?:number, - /** 数据总数*/ - total:number, - /** 初始的每页条数*/ - defaultPageSize?:number, - /** 每页条数*/ - pageSize?:number, - /** 页码改变的回调,参数是改变后的页码*/ - onChange?:Function, - /** 是否可以改变 pageSize */ - showSizeChanger?:boolean, - /** 指定每页可以显示多少条*/ - pageSizeOptions?:Array - /** pageSize 变化的回调 */ - onShowSizeChange?:Function, - /** 是否可以快速跳转至某页*/ - showQuickJumper?:boolean, - /** 当为「small」时,是小尺寸分页 */ - size?:string, - /** 当添加该属性时,显示为简单分页*/ - simple?:Object, - /** 用于显示总共有多少条数据*/ - showTotal?:Function, - - style?:React.CSSProperties -} -/** - * #Pagination - 采用分页的形式分隔长列表,每次只加载一个页面。 - - ## 何时使用 - - - 当加载/渲染所有数据将花费很多时间时; - - 可切换页码浏览数据。*/ -export class Pagination extends React.Component { -} - - -interface PopconfirmProps { - /** - * 气泡框位置,可选 `top/left/right/bottom` - * - * @type {(Placement | string)} - */ - placement?:'top' | 'left' | 'right' | 'bottom', - /** 确认框的描述*/ - title?:string, - /** 点击确认的回调*/ - onConfirm?:Function, - onCancel?:Function, - /** 显示隐藏的回调*/ - onVisibleChange?:(visible:boolean) => void, - /** 确认按钮文字*/ - okText?:string, - /** 取消按钮文字*/ - cancelText?:string, - - style?:React.CSSProperties -} -/** - * #Popconfirm - 点击元素,弹出气泡式的确认框。 - - ## 何时使用 - - 目标元素的操作需要用户进一步的确认时,在目标元素附近弹出浮层提示,询问用户。 - - 和 `confirm` 弹出的全屏居中模态对话框相比,交互形式更轻量。 - */ -export class Popconfirm extends React.Component { -} - -type PopoverPlacement = 'top' | 'left' | 'right' | 'bottom' | 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'leftTop' | 'leftBottom' | 'rightTop' | 'rightBottom' -type PropverTrigger = 'hover' | 'focus' | 'click' - -interface PopoverProps { - /** 触发行为,可选 `hover/focus/click` */ - trigger?:PropverTrigger, - /** 气泡框位置,可选 `top/left/right/bottom` `topLeft/topRight/bottomLeft/bottomRight` `leftTop/leftBottom/rightTop/rightBottom`*/ - placement?:PopoverPlacement - /** 卡片标题*/ - title?:React.ReactNode | string, - /** 卡片内容*/ - overlayClassName?:string, - - overlayStyle?:React.CSSProperties, - - prefixCls?:string, - /** 用于手动控制浮层显隐*/ - visible?:boolean, - /** 显示隐藏改变的回调*/ - onVisibleChange?:Function, - - getTooltipContainer?:Function, - - content?:React.ReactNode, - - style?:React.CSSProperties -} -/** - * #Popover - 点击/鼠标移入元素,弹出气泡式的卡片浮层。 - - ## 何时使用 - - 当目标元素有进一步的描述和相关操作时,可以收纳到卡片中,根据用户的操作行为进行展现。 - - 和 `Tooltip` 的区别是,用户可以对浮层上的元素进行操作,因此它可以承载更复杂的内容,比如链接或按钮等。 - */ -export class Popover extends React.Component { -} - -// Progress -type ProgressStatus = 'success' | 'active' | 'exception' -type ProgressType = 'line' | 'circle' - -interface ProgressProps { - type?:ProgressType, - percent?:number, - format?:(percent:number) => string, - status?:ProgressStatus, - showInfo?:boolean, - strokeWidth?:number, - width?:number, - style?:React.CSSProperties -} -/** - * #Progress - 展示操作的当前进度。 - - ## 何时使用 - - 在操作需要较长时间才能完成时,为用户显示该操作的当前进度和状态。 - - * 当一个操作会打断当前界面,或者需要在后台运行,且耗时可能超过2秒时; - * 当需要显示一个操作完成的百分比时。*/ -export class Progress extends React.Component { - -} - -// Radio -type RadioGroupSize = 'large' | 'default' | 'small' - -interface RadioGroupProps { - /** 选项变化时的回调函数*/ - onChange?:React.FormEventHandler, - /** 用于设置当前选中的值*/ - value?:string, - /** 默认选中的值*/ - defaultValue?:string, - /** 大小,只对按钮样式生效*/ - size?:RadioGroupSize, - - style?:React.CSSProperties -} -export class RadioGroup extends React.Component { -} - -interface RadioProps { - /** 指定当前是否选中*/ - checked?:boolean, - /** 初始是否选中*/ - defaultChecked?:boolean, - /** 根据 value 进行比较,判断是否选中 */ - value?:any, - - style?:React.CSSProperties -} -/** - * #Radio - 单选框。 - - ## 何时使用 - - - 用于在多个备选项中选中单个状态。 - - 和 Select 的区别是,Radio 所有选项默认可见,方便用户在比较中选择,因此选项不宜过多。 - */ -export class Radio extends React.Component { - static Group:typeof RadioGroup - static Button:typeof RadioButton -} - -interface RadioButtonProps { - value:string, - style?:React.CSSProperties -} - -export class RadioButton extends React.Component { -} - - -// Select -interface SelectOptionProps { - /** 是否禁用*/ - disabled?:boolean, - /** 如果 react 需要你设置此项,此项值与 value 的值相同,然后可以省略 value 设置*/ - key?:string, - /** 默认根据此属性值进行筛选*/ - value:string -} -export class SelectOption extends React.Component { -} - -interface SelectOptGroupProps { - /** 组名*/ - label:string | React.ReactNode, - key?:string -} -export class SelectOptGroup extends React.Component { -} - -interface SelectProps { - /** 指定当前选中的条目*/ - value?:string | Array, - /** 指定默认选中的条目*/ - defaultValue?:string | Array, - /** 支持多选*/ - multiple?:boolean, - /** 支持清除, 单选模式有效*/ - allowClear?:boolean, - /** 是否根据输入项进行筛选,可为一个函数,返回满足要求的 option 即可*/ - filterOption?:boolean | Function, - /** 可以把随意输入的条目作为 tag,输入项不需要与下拉选项匹配*/ - tags?:boolean, - /** 被选中时调用,参数为选中项的 value 值 */ - onSelect?:(value:any, option:any) => void, - /** 取消选中时调用,参数为选中项的 option value 值,仅在 multiple 或 tags 模式下生效*/ - onDeselect?:(value:any, option:any) => void, - /** 选中option,或input的value变化(combobox 模式下)时,调用此函数*/ - onChange?:(value:any, label:any) => void, - /** 文本框值变化时回调*/ - onSearch?:(value:string) => void, - /** 选择框默认文字*/ - placeholder?:string, - /** 搜索框默认文字*/ - searchPlaceholder?:string, - /** 当下拉列表为空时显示的内容*/ - notFoundContent?:string, - /** 下拉菜单和选择器同宽*/ - dropdownMatchSelectWidth?:boolean, - /** 搜索时过滤对应的 option 属性,如设置为 children 表示对内嵌内容进行搜索*/ - optionFilterProp?:string, - /** 输入框自动提示模式*/ - combobox?:SVGSymbolElement, - /** 选择框大小,可选 `large` `small` */ - size?:string, - /** 在下拉中显示搜索框*/ - showSearch?:boolean, - /** 是否禁用*/ - disabled?:boolean, - style?:React.CSSProperties -} -/** - * #Select - 类似 Select2 的选择器。 - - ## 何时使用 - - 弹出一个下拉菜单给用户选择操作,用于代替原生的选择器,或者需要一个更优雅的多选器时。*/ -export class Select extends React.Component { - static Option:typeof SelectOption - static OptGroup:typeof SelectOptGroup -} - -interface SliderMark { - [key:string]:any -} - -// Slider -interface SliderProps { - /** 最小值*/ - min?:number, - /** 最大值*/ - max?:number, - /** 步长,取值必须大于 0,并且可被 (max - min) 整除。当 `marks` 不为空对象时,可以设置 `step` 为 `null`,此时 Slider 的可选值仅有 marks 标出来的部分。*/ - step?:number, - /** 分段标记,key 的类型必须为 `Number` 且取值在闭区间 [min, max] 内*/ - marks?:SliderMark, - /** 设置当前取值。当 `range` 为 `false` 时,使用 `Number`,否则用 `[Number, Number]`*/ - value?:number | Array, - /** 设置当前取值。当 `range` 为 `false` 时,使用 `Number`,否则用 `[Number, Number]`*/ - defaultValue?:number | Array, - /** `marks` 不为空对象时有效,值为 true 时表示值为包含关系,false 表示并列*/ - included?:boolean, - /** 值为 `true` 时,滑块为禁用状态*/ - disabled?:boolean, - /** 当 `range` 为 `true` 时,该属性可以设置是否允许两个滑块交换位置。*/ - allowCross?:boolean, - /** 当 Slider 的值发生改变时,会触发 onChange 事件,并把改变后的值作为参数传入。*/ - onChange?:Function, - /** 与 `onmouseup` 触发时机一致,把当前值作为参数传入。*/ - onAfterChange?:Function, - /** Slider 会把当前值传给 `tipFormatter`,并在 Tooltip 中显示 `tipFormatter` 的返回值,若为 null,则隐藏 Tooltip。*/ - tipFormatter?:Function | any, - range?:boolean, - - style?:React.CSSProperties -} -/** - * #Slider - 滑动型输入器,展示当前值和可选范围。 - - ## 何时使用 - - 当用户需要在数值区间/自定义区间内进行选择时,可为连续或离散值。*/ -export class Slider extends React.Component { -} - -// Spin -interface SpinProps { - /** spin组件中点的大小,可选值为 small default large*/ - size?:'small' | 'default' | 'large', - /** 用于内嵌其他组件的模式,可以关闭 loading 效果*/ - spinning?:boolean, - - tip?:string, - - style?:React.CSSProperties -} -/** - * #Spin - 用于页面和区块的加载中状态。 - - ## 何时使用 - - 页面局部处于等待异步数据或正在渲染过程时,合适的加载动效会有效缓解用户的焦虑。 - */ -export class Spin extends React.Component { -} - -// Steps -type StepStatus = 'wait' | 'process' | 'finish' | 'error' - -interface StepProps { - /** 可选参数,指定状态。当不配置该属性时,会使用父Steps元素的current来自动指定状态。*/ - status?:StepStatus, - /** 必要参数,标题。*/ - title:string | React.ReactNode, - /** 可选参数,步骤的详情描述。*/ - description?:string | React.ReactNode, - /** 可选参数,步骤的Icon。如果不指定,则使用默认的样式。*/ - icon?:string | React.ReactNode, - - style?:React.CSSProperties -} -export class Step extends React.Component { -} - -interface StepsProps { - status?:StepStatus, - /** 可选参数,指定当前处理正在执行状态的步骤,从0开始记数。在子Step元素中,可以通过status属性覆盖状态。*/ - current?:number, - /** 可选参数,指定大小(目前只支持普通和迷你两种大小)。 small, default */ - size?:'default' | 'small', - /** 可选参数,指定步骤条方向(目前支持水平和竖直两种方向,默认水平方向)。*/ - direction?:string, - /** 可选参数,指定步骤的详细描述文字的最大宽度。*/ - maxDescriptionWidth?:number, - - style?:React.CSSProperties - -} -/** - * #Steps - 引导用户按照流程完成任务的导航条。 - - ## 何时使用 - - 当任务复杂或者存在先后关系时,将其分解成一系列步骤,从而简化任务。*/ -export class Steps extends React.Component { - static Step:typeof Step -} - -// Switch -interface SwitchProps { - /** 指定当前是否选中*/ - checked?:boolean, - /** 初始是否选中*/ - defaultChecked?:boolean, - /** 变化时回调函数*/ - onChange?:(checked:boolean) => void, - /** 选中时的内容*/ - checkedChildren?:React.ReactNode, - /** 非选中时的内容*/ - unCheckedChildren?:React.ReactNode, - /** 开关大小*/ - size?:string, - - style?:React.CSSProperties -} -/** - * #Switch - 开关选择器。 - - ## 何时使用 - - - 需要表示开关状态/两种状态之间的切换时; - - 和 `checkbox `的区别是,切换 `switch` 会直接触发状态改变,而 `checkbox` 一般用于状态标记,需要和提交操作配合。 - */ -export class Switch extends React.Component { -} - -// Table -type RowSelectionType = 'checkbox' | 'radio' - -type SelectedRowKeys = Array - -interface RowSelection { - type?:RowSelectionType, - selectedRowKeys?:SelectedRowKeys, - onChange?:(selectedRowKeys:SelectedRowKeys, selectedRows:any) => void, - getCheckboxProps?:(record:any) => void, - onSelect?:(record:any, selected:any, selectedRows:any) => void, - onSelectAll?:(rselectedecord:any, selectedRows:any, changeRows:any) => void, - style?:React.CSSProperties -} - -type Columns = Array -interface Column { - /** React 需要的 key,建议设置*/ - key:string | number, - /** 列头显示文字*/ - title?:string | React.ReactNode, - /** 列数据在数据项中对应的 key*/ - dataIndex?:string, - /** 生成复杂数据的渲染函数,参数分别为当前列的值,当前列数据,列索引,@return里面可以设置表格[行/列合并](#demo-colspan-rowspan)*/ - render?:(text?:any, record?:any, index?:number) => React.ReactNode, - /** 表头的筛选菜单项*/ - filters?:Array, - /** 本地模式下,确定筛选的运行函数*/ - onFilter?:Function, - /** 是否多选*/ - filterMultiple?:boolean, - /** 排序函数,本地排序使用一个函数,需要服务端排序可设为 true */ - sorter?:boolean | Function, - /** 表头列合并,设置为 0 时,不渲染*/ - colSpan?:number, - /** 列宽度*/ - width?:string | number, - /** 列的 className*/ - className?:string, - - fixed?:boolean | 'left' | 'right', - - filteredValue?:Array, - - sortOrder?:boolean | 'ascend' | 'descend' -} - -interface TableProps { - /** 列表项是否可选择*/ - rowSelection?:RowSelection, - /** 分页器*/ - pagination?:Object, - /** 正常或迷你类型 : `default` or `small` */ - size?:string, - /** 数据数组*/ - dataSource:Array, - /** 表格列的配置描述*/ - columns:Columns, - /** 表格行 key 的取值*/ - rowKey?:(record:any, index:number) => string, - /** 额外的展开行*/ - expandedRowRender?:Function, - /** 默认展开的行*/ - defaultExpandedRowKeys?:Array, - /** 分页、排序、筛选变化时触发*/ - onChange?:(pagination:Object, filters:any, sorter:any) => void, - /** 页面是否加载中*/ - loading?:boolean, - /** 默认文案设置,目前包括排序、过滤、空数据文案: `{ filterConfirm: '确定', filterReset: '重置', emptyText: '暂无数据' }` */ - locale?:Object, - /** 展示树形数据时,每层缩进的宽度,以 px 为单位*/ - indentSize?:number, - /** 处理行点击事件*/ - onRowClick?:(record:any, index:number) => void, - /** 是否固定表头*/ - useFixedHeader?:boolean, - /** 是否展示外边框和列边框*/ - bordered?:boolean, - /** 是否显示表头*/ - showHeader?:boolean, - /** 表格底部自定义渲染函数*/ - footer?:(currentPageData:Object) => void, - - style?:React.CSSProperties -} -/** - * #Table - 展示行列数据。 - - ## 何时使用 - - - 当有大量结构化的数据需要展现时; - - 当需要对数据进行排序、搜索、分页、自定义操作等复杂行为时。*/ -export class Table extends React.Component { -} - -// Tabs -interface TabPaneProps { - /** 选项卡头显示文字*/ - tab:React.ReactNode | string, - - style?:React.CSSProperties -} -export class TabPane extends React.Component { -} - -type TabsType = 'line' | 'card' | 'editable-card' -type TabsPosition = 'top' | 'right' | 'bottom' | 'left'; - -interface TabsProps extends React.Props { - /** 当前激活 tab 面板的 key */ - activeKey?:string, - /** 初始化选中面板的 key,如果没有设置 activeKey*/ - defaultActiveKey?:string, - /** 是否隐藏加号图标,在 `type="editable-card"` 时有效 */ - hideAdd?: boolean, - /** 切换面板的回调*/ - onChange?:(activeKey:string) => void, - /** tab 被点击的回调 */ - onTabClick?:Function, - /** tab bar 上额外的元素 */ - tabBarExtraContent?:React.ReactNode, - /** 页签的基本样式,可选 `line`、`card` `editable-card` 类型*/ - type?:TabsType, - /** 页签位置,可选值有 `top` `right` `bottom` `left`*/ - tabPosition?:TabsPosition, - /** 新增和删除页签的回调,在 `type="editable-card"` 时有效*/ - onEdit?:(targetKey:string, action:any) => void, - /** 大小,提供 default 和 small 两种大小 */ - size?:string, - - style?:React.CSSProperties -} -/** - * #Tabs - 选项卡切换组件。 - - ## 何时使用 - - 提供平级的区域将大块内容进行收纳和展现,保持界面整洁。 - - Ant Design 依次提供了三级选项卡,分别用于不同的场景。 - - - 卡片式的页签,提供可关闭的样式,常用于容器顶部。 - - 标准线条式页签,用于容器内部的主功能切换,这是最常用的 Tabs。 - - [RadioButton](/components/radio/#demo-radiobutton) 可作为更次级的页签来使用。*/ -export class Tabs extends React.Component { - static TabPane:typeof TabPane -} - -// Tag -interface TagProps { - /** 标签是否可以关闭*/ - closable?:boolean, - /** 关闭时的回调*/ - onClose?:Function, - /** 动画关闭后的回调*/ - afterClose?:Function, - /** 标签的色彩*/ - color?:string, - - style?:React.CSSProperties -} -/** - * #Tag - 进行标记和分类的小标签。 - - ## 何时使用 - - - 用于标记事物的属性和维度。 - - 进行分类。*/ -export class Tag extends React.Component { -} - -// TimePicker -interface TimePickerProps { - /** 默认时间*/ - value?:string | Date, - /** 初始默认时间*/ - defaultValue?:string | Date, - /** 展示的时间格式 : "HH:mm:ss"、"HH:mm"、"mm:ss" */ - format?:string, - /** 时间发生变化的回调*/ - onChange?:(Date:Date) => void, - /** 禁用全部操作*/ - disabled?:boolean, - /** 没有值的时候显示的内容*/ - placeholder?:string, - /** 国际化配置*/ - locale?:Object, - /** 隐藏禁止选择的选项*/ - hideDisabledOptions?:boolean, - /** 禁止选择部分小时选项*/ - disabledHours?:Function, - /** 禁止选择部分分钟选项*/ - disabledMinutes?:Function, - /** 禁止选择部分秒选项*/ - disabledSeconds?:Function, - - style?:React.CSSProperties -} -/** - * #TimePicker - 输入或选择时间的控件。 - - 何时使用 - -------- - - 当用户需要输入一个时间,可以点击标准输入框,弹出时间面板进行选择。 - */ -export class TimePicker extends React.Component { -} - -// Timeline -interface TimeLineItemProps { - /** 指定圆圈颜色。*/ - color?:string, - dot?:React.ReactNode, - style?:React.CSSProperties -} -export class TimeLineItem extends React.Component { -} - -interface TimelineProps { - /** 指定最后一个幽灵节点是否存在或内容*/ - pending?:boolean | React.ReactNode, - - style?:React.CSSProperties -} -/** - * #Timeline - 垂直展示的时间流信息。 - - ## 何时使用 - - - 当有一系列信息需要从上至下按时间排列时; - - 需要有一条时间轴进行视觉上的串联时;*/ -export class Timeline extends React.Component { - static Item:typeof TimeLineItem -} - -// Tooltip -interface TooltipProps { - /** 气泡框位置,可选 `top` `left` `right` `bottom` `topLeft` `topRight` `bottomLeft` `bottomRight` `leftTop` `leftBottom` `rightTop` `rightBottom`*/ - placement?:PopoverPlacement, - /** 提示文字*/ - title?:string | React.ReactNode, - - style?:React.CSSProperties -} -/** - * #Tooltip - 简单的文字提示气泡框。 - - ## 何时使用 - - 鼠标移入则显示提示,移出消失,气泡浮层不承载复杂文本和操作。 - - 可用来代替系统默认的 `title` 提示,提供一个`按钮/文字/操作`的文案解释。*/ -export class Tooltip extends React.Component { -} - -interface TransferItem { - key:number | string, - title:string, - description?:string, - chosen:boolean, -} - -// Transfer -interface TransferProps { - /** 数据源*/ - dataSource:Array, - /** 每行数据渲染函数*/ - render?:(record:TransferItem) => any, - /** 显示在右侧框数据的key集合*/ - targetKeys:Array, - /** 变化时回调函数*/ - onChange?:(targetKeys:Array, direction:string, moveKeys:any) => void, - /** 两个穿梭框的自定义样式*/ - listStyle?:React.CSSProperties, - /** 自定义类*/ - className?:string, - /** 标题集合,顺序从左至右*/ - titles?:Array, - /** 操作文案集合,顺序从上至下*/ - operations?:Array, - /** 是否显示搜索框*/ - showSearch?:boolean, - /** 搜索框的默认值*/ - searchPlaceholder?:string, - /** 当列表为空时显示的内容*/ - notFoundContent?:React.ReactNode | string - /** 底部渲染函数*/ - footer?:(props:any) => any, - - style?:React.CSSProperties -} -/** - * #Transfer - 双栏穿梭选择框。 - - ## 何时使用 - - 用直观的方式在两栏中移动元素,完成选择行为。 - */ -export class Transfer extends React.Component { -} - - -// Tree -interface TreeNodeProps { - disabled?:boolean, - disableCheckbox?:boolean, - title?:string | React.ReactNode, - key?:string, - isLeaf?:boolean -} -export class TreeNode extends React.Component { -} - -interface TreeNodeEvent { - event:'check' | 'select', - node:TreeNode, - - checked?:boolean, - checkedNodes?:Array, - - selected?:boolean, - selectedNodes?:Array, -} - -interface TreeNodeMouseEvent { - node:TreeNode, - event:React.MouseEventHandler, -} - -interface TreeProps { - showLine?:boolean, - className?:string, - /** 是否支持多选*/ - multiple?:boolean, - /**是否自动展开父节点 */ - autoExpandParent?:boolean, - /**checkable状态下节点选择完全受控(父子节点选中状态不再关联)*/ - checkStrictly?:boolean, - /** 是否支持选中*/ - checkable?:boolean, - /** 默认展开所有树节点*/ - defaultExpandAll?:boolean, - /** 默认展开指定的树节点*/ - defaultExpandedKeys?:Array, - /** (受控)展开指定的树节点*/ - expandedKeys?:Array, - /** (受控)选中复选框的树节点*/ - checkedKeys?:Array, - /** 默认选中复选框的树节点*/ - defaultCheckedKeys?:Array, - /** (受控)设置选中的树节点*/ - selectedKeys?:Array, - /** 默认选中的树节点*/ - defaultSelectedKeys?:Array, - /** 展开/收起节点时触发 */ - onExpand?:(expandedKeys:Array, {node: TreeNode, expanded: boolean}) => void | PromiseLike, - /** 点击复选框触发*/ - onCheck?:(checkedKeys:Array, e:TreeNodeEvent) => void, - /** 点击树节点触发*/ - onSelect?:(selectedKeys:Array, e:TreeNodeEvent) => void, - /** filter some treeNodes as you need. it should return true */ - filterTreeNode?:(node:TreeNode) => boolean, - /** 异步加载数据*/ - loadData?:(node:TreeNode) => PromiseLike, - /** 响应右键点击*/ - onRightClick?:(options:TreeNodeMouseEvent) => void, - /** 设置节点可拖拽(IE>8)*/ - draggable?:boolean, - /** 开始拖拽时调用*/ - onDragStart?:(options:TreeNodeMouseEvent) => void, - /** dragenter 触发时调用*/ - onDragEnter?:(options:TreeNodeMouseEvent) => void, - /** dragover 触发时调用 */ - onDragOver?:(options:TreeNodeMouseEvent) => void, - /** dragleave 触发时调用*/ - onDragLeave?:(options:TreeNodeMouseEvent) => void, - /** drop 触发时调用*/ - onDrop?:(options:TreeNodeMouseEvent) => void, - - style?:React.CSSProperties -} -/** - * #Tree - * 文件夹、组织架构、生物分类、国家地区等等,世间万物的大多数结构都是树形结构。使用`树控件`可以完整展现其中的层级关系,并具有展开收起选择等交互功能。 - */ -export class Tree extends React.Component { - static TreeNode:typeof TreeNode -} - - -// TreeSelect -interface TreeSelectTreeNodeProps { - disabled?:boolean, - /** 此项必须设置(其值在整个树范围内唯一)*/ - key:string, - /** 默认根据此属性值进行筛选*/ - value?:string, - /** 树节点显示的内容*/ - title?:React.ReactNode | string, - /** 是否是叶子节点*/ - isLeaf?:boolean -} -export class TreeSelectTreeNode extends React.Component { -} - -interface TreeData { - key:string - value:string, - label:React.ReactNode, - children?:Array -} - -interface TreeSelectProps { - style?:React.CSSProperties, - /** 指定当前选中的条目*/ - value?:string | Array, - /** 指定默认选中的条目*/ - defaultValue?:string | Array, - /** 支持多选*/ - multiple?:boolean, - /** 可以把随意输入的条目作为 tag,输入项不需要与下拉选项匹配*/ - tags?:boolean, - /** 被选中时调用,参数为选中项的 value 值*/ - onSelect?:(value:any) => void, - /** 选中option,或input的value变化(combobox 模式下)时,调用此函数*/ - onChange?:(value:any, label:any) => void, - /** 显示清除按钮*/ - allowClear?:boolean, - /** 文本框值变化时回调*/ - onSearch?:(value:any) => void, - /** 选择框默认文字*/ - placeholder?:string, - /** 搜索框默认文字*/ - searchPlaceholder?:string, - /** 下拉菜单的样式*/ - dropdownStyle?:React.CSSProperties, - /** 下拉菜单和选择器同宽*/ - dropdownMatchSelectWidth?:boolean, - /** 输入框自动提示模式*/ - combobox?:boolean, - /** 选择框大小,可选 `large` `small`*/ - size?:'large' | 'small', - /** 在下拉中显示搜索框*/ - showSearch?:boolean, - /** 是否禁用*/ - disabled?:boolean, - /** 默认展开所有树节点*/ - treeDefaultExpandAll?:boolean, - /** 显示checkbox*/ - treeCheckable?:boolean, - /** 是否根据输入项进行筛选,返回值true*/ - filterTreeNode?:(treeNode:any) => boolean, - /** 输入项过滤对应的 treeNode 属性*/ - treeNodeFilterProp?:string, - /** 作为显示的prop设置*/ - treeNodeLabelProp?:string, - /** treeNodes数据,如果设置则不需要手动构造TreeNode节点(如果value在整个树范围内不唯一,需要设置`key`其值为整个树范围内的唯一id*/ - treeData?:Array, - - treeDataSimpleMode?:boolean, - /** 异步加载数据*/ - loadData?:(node:any) => void, - - showCheckedStrategy?:'SHOW_ALL' | 'SHOW_PARENT' | 'SHOW_CHILD' - -} -/** - * #TreeSelect - 树型选择控件。 - - ## 何时使用 - - 类似 Select 的选择控件,可选择的数据结构是一个树形结构时,可以使用 TreeSelect,例如公司层级、学科系统、分类目录等等。 - */ -export class TreeSelect extends React.Component { - static TreeNode:typeof TreeSelectTreeNode -} - - -type UploadFileStatus = 'error' | 'success' | 'done' | 'uploading' | 'removed' - -export interface HttpRequestHeader { - [key:string]:string; -} - -interface File { - uid:number, - size:number, - name:string, - lastModifiedDate?:Date, - url?:string, - status?:UploadFileStatus, - percent?:number, -} - -interface UploadChangeParam { - file:File, - fileList:Array, - event?:{ percent:number }, -} - -// Upload -interface UploadProps { - /** 可选参数, 上传的文件 */ - name?:string, - - defaultFileList?:Array, - - fileList?:Array, - /** 必选参数, 上传的地址 */ - action:string, - /** 可选参数, 上传所需参数 */ - data?:Object, - /** 可选参数, 设置上传的请求头部,IE10 以上有效*/ - headers?:HttpRequestHeader, - /** 可选参数, 是否展示 uploadList, 默认开启 */ - showUploadList?:boolean, - /** 可选参数, 是否支持多选文件,`ie10+` 支持。开启后按住 ctrl 可选择多个文件。*/ - multiple?:boolean, - /** 可选参数, 接受上传的文件类型, 详见 input accept Attribute */ - accept?:string, - /** 可选参数, 上传文件之前的钩子,参数为上传的文件,若返回 `false` 或者 Promise 则停止上传。**注意:该方法不支持老 IE**。*/ - beforeUpload?:(file:File) => boolean | PromiseLike, - /** 可选参数, 上传文件改变时的状态,详见 onChange */ - onChange?:(info:UploadChangeParam) => void, - /** 上传列表的内建样式,支持两种基本样式 `text` or `picture` */ - listType?:'text' | 'picture', - /** 自定义类名*/ - className?:string, - - onPreview?:(file:File) => void, - - onRemove?:(file:File) => void, - - supportServerRender?:boolean, - - style?:React.CSSProperties -} -/** - * #Upload - 文件选择上传和拖拽上传控件。 - - ## 何时使用 - - 上传是将信息(网页、文字、图片、视频等)通过网页或者上传工具发布到远程服务器上的过程。 - - - 当需要上传一个或一些文件时。 - - 当需要展现上传的进度时。 - - 当需要使用拖拽交互时。*/ -export class Upload extends React.Component { -} - -interface RateProps { - count?:number, - value?:number, - defaultValue?:number, - onChange?:(value:number) => void, - allowHalf?:boolean, - disabled?:boolean, - style?:React.CSSProperties -} -export class Rate extends React.Component { -} - -interface CardProps { - title?:React.ReactNode, - extra?:React.ReactNode, - bordered?:boolean, - bodyStyle?:React.CSSProperties, - style?:React.CSSProperties, - loading?:boolean -} -export class Card extends React.Component { -} - -interface LocaleProviderProps { - locale?:any -} -export class LocaleProvider extends React.Component { -} diff --git a/package.json b/package.json index ec024b4d65..39a4717666 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "antd", - "version": "1.9.1", + "version": "1.10.0", "title": "Ant Design", - "description": "一个 UI 设计语言", + "description": "An enterprise-class UI design language and React-based implementation", "homepage": "http://ant.design/", "keywords": [ "ant", @@ -43,7 +43,7 @@ "object.omit": "^2.0.0", "rc-animate": "~2.3.0", "rc-calendar": "~6.0.2", - "rc-cascader": "~0.9.11", + "rc-cascader": "~0.10.1", "rc-checkbox": "~1.4.0", "rc-collapse": "~1.6.4", "rc-dialog": "~6.2.1", @@ -89,12 +89,12 @@ "enquire.js": "^2.1.1", "es6-shim": "^0.35.0", "eslint": "^3.0.1", - "eslint-config-airbnb": "^9.0.1", + "eslint-config-airbnb": "^10.0.1", "eslint-plugin-babel": "^3.0.0", "eslint-plugin-import": "^1.6.1", "eslint-plugin-jsx-a11y": "^2.0.1", "eslint-plugin-markdown": "*", - "eslint-plugin-react": "^5.0.1", + "eslint-plugin-react": "^6.1.2", "eslint-tinker": "^0.3.1", "history": "^3.0.0", "intl": "^1.2.2", @@ -122,6 +122,7 @@ "react-stateless-wrapper": "^1.0.2", "react-sublime-video": "^0.2.0", "reqwest": "^2.0.5", + "typings": "^1.3.2", "values.js": "^1.0.3", "webpack-babel-jest": "^1.0.4" }, @@ -133,7 +134,7 @@ "site": "bisheng build -c ./site/bisheng.config.js", "pre-deploy": "mkdir -p _site && cp CNAME _site", "deploy": "npm run clean && npm run pre-deploy && bisheng gh-pages -c ./site/bisheng.config.js", - "lint": "npm run tslint && npm run srclint && npm run demolint && npm run lesshint", + "lint": "npm run tslint && tsc && npm run srclint && npm run demolint && npm run lesshint", "srclint": "RUN_ENV=SRC eslint test site scripts ./*.js --ext '.js,.jsx,.tsx'", "tslint": "antd-tools run ts-lint", "demolint": "RUN_ENV=DEMO eslint components/*/demo/*.md --ext '.md'", @@ -141,6 +142,7 @@ "eslint-fix": "eslint --fix components test site scripts ./*.js --ext '.js,.jsx' && eslint-tinker ./components/*/demo/*.md", "test": "npm run lint && npm run dist", "jest": "jest", + "postinstall": "typings install", "pre-publish": "node ./scripts/prepub", "prepublish": "antd-tools run guard", "pub": "antd-tools run update-self && antd-tools run pub", diff --git a/site/theme/static/demo.less b/site/theme/static/demo.less index 6f65b68045..cc379206a8 100644 --- a/site/theme/static/demo.less +++ b/site/theme/static/demo.less @@ -44,21 +44,29 @@ box-shadow: 0 0 4px rgba(45, 183, 245, 0.5); } -.code-box:hover .code-box-meta, -.code-box:target .code-box-meta { - background: #fbfbfb; -} +.code-box { + .code-box-title a, + .code-box-title a:hover { + color: #666; + font-size: 14px; + font-weight: 500; + } -.code-box:hover .code-box-title, -.code-box:target .code-box-title { - background: #fbfbfb; - box-shadow: 0 -1.2px 0 #e9e9e9; -} + a.edit-button { + position: absolute; + right: -16px; + top: 7px; + font-size: 12px; + transform: scale(0.9); + background: #fff; + padding-right: 6px; + opacity: 0; + transition: opacity .3s; + } -.code-box .code-box-title a, -.code-box .code-box-title a:hover { - color: #666; - font-size: 14px; + &:hover a.edit-button { + opacity: 1; + } } .code-box .code-box-demo { @@ -73,7 +81,7 @@ .code-box-meta.markdown { position: relative; - padding: 16px; + padding: 17px 16px 15px 20px; border-radius: 0 0 6px 6px; transition: background-color 0.4s ease; width: 100%; @@ -97,26 +105,13 @@ section.code-box-meta p { .code-box-title { position: absolute; top: -14px; - padding: 1px 1.1em; + padding: 1px 8px; + margin-left: -8px; color: #777; border-radius: 6px; + border-top-left-radius: 0; background: #fff; - transition: all 0.4s ease; -} - -.code-box-title:before { - font-family: anticon; - content: "\e658"; - font-size: 16px; - vertical-align: middle; - line-height: 22px; - position: relative; - margin-right: 8px; - top: -2px; - color: #ccc; - -webkit-transform: rotate(-45deg); - transform: rotate(-45deg); - display: inline-block; + transition: background-color 0.4s ease; } .code-box-meta > p { @@ -135,7 +130,7 @@ section.code-box-meta p { .code-box .collapse { position: absolute; right: 16px; - bottom: 16px; + bottom: 17px; cursor: pointer; width: 18px; height: 18px; @@ -143,9 +138,8 @@ section.code-box-meta p { line-height: 18px; opacity: 0.5; text-align: center; - -webkit-transform: rotate(90deg); transform: rotate(90deg); - transition: all 0.3s ease; + transition: all 0.3s; color: #999; background: #fff; user-select: none; @@ -153,7 +147,6 @@ section.code-box-meta p { } .code-box.expand .collapse { - -webkit-transform: rotate(-90deg); transform: rotate(-90deg); } diff --git a/site/theme/static/markdown.less b/site/theme/static/markdown.less index 482950c858..36318a518e 100644 --- a/site/theme/static/markdown.less +++ b/site/theme/static/markdown.less @@ -169,6 +169,26 @@ cursor: not-allowed; } +.markdown a.edit-button { + line-height: 12px; + display: inline-block; + margin-left: 10px; + height: 12px; + + i { + color: #999; + + &:hover { + color: #2db7f5; + } + } + + .anticon { + display: block; + font-size: 14px; + } +} + .markdown h1:hover .anchor, .markdown h2:hover .anchor, .markdown h3:hover .anchor, diff --git a/site/theme/static/preview-img.less b/site/theme/static/preview-img.less index 758f79fa05..027ee3ccf3 100644 --- a/site/theme/static/preview-img.less +++ b/site/theme/static/preview-img.less @@ -118,15 +118,31 @@ position: relative; text-align: center; } -} -.image-modal-single.slick-slider { - padding-bottom: 0; -} + .ant-carousel { + .slick-slider { + padding-bottom: 24px; + img { + display: inline; + max-width: 100%; + } + } + .slick-dots { + text-align: left; + bottom: -10px; + li { + margin: 0; + } + } + } -.ant-carousel .slick-slider img { - display: inline; - max-width: 100%; + .image-modal-single.slick-slider { + padding-bottom: 0; + } + + .image-modal-single .slick-dots { + display: none!important; + } } .transition-video-player { diff --git a/site/theme/static/template.html b/site/theme/static/template.html index 861d125114..b0b084ca9f 100644 --- a/site/theme/static/template.html +++ b/site/theme/static/template.html @@ -8,7 +8,7 @@ @@ -45,6 +45,12 @@ /* eslint-enable */ } + diff --git a/site/theme/template/BrowserDemo.jsx b/site/theme/template/BrowserDemo.jsx index 654ded4840..8225f489ed 100644 --- a/site/theme/template/BrowserDemo.jsx +++ b/site/theme/template/BrowserDemo.jsx @@ -5,9 +5,9 @@ export default function BrowserDemo(props) {
    -
    -
    -
    +
    +
    +
    diff --git a/site/theme/template/Content/Article.jsx b/site/theme/template/Content/Article.jsx index 70af998b4f..8b9a8524d2 100644 --- a/site/theme/template/Content/Article.jsx +++ b/site/theme/template/Content/Article.jsx @@ -2,6 +2,7 @@ import React, { Children, cloneElement } from 'react'; import DocumentTitle from 'react-document-title'; import { getChildren } from 'jsonml.js/lib/utils'; import { Timeline } from 'antd'; +import EditButton from './EditButton'; import * as utils from '../utils'; export default class Article extends React.Component { @@ -9,7 +10,7 @@ export default class Article extends React.Component { this.componentDidUpdate(); } componentDidUpdate() { - const links = Array.apply(null, document.querySelectorAll('.outside-link.internal')); + const links = [...document.querySelectorAll('.outside-link.internal')]; if (links.length === 0) { return; } @@ -54,7 +55,7 @@ export default class Article extends React.Component { const content = props.content; const { meta, description } = content; - const { title, subtitle, chinese, english } = meta; + const { title, subtitle, chinese, english, filename } = meta; return ( @@ -65,6 +66,7 @@ export default class Article extends React.Component { (!subtitle && !chinese) ? null : {subtitle || chinese} } + { !description ? null : diff --git a/site/theme/template/Content/ComponentDoc.jsx b/site/theme/template/Content/ComponentDoc.jsx index 4ec3722974..6a8948c0c8 100644 --- a/site/theme/template/Content/ComponentDoc.jsx +++ b/site/theme/template/Content/ComponentDoc.jsx @@ -4,6 +4,7 @@ import classNames from 'classnames'; import { Row, Col, Icon, Affix } from 'antd'; import { getChildren } from 'jsonml.js/lib/utils'; import Demo from './Demo'; +import EditButton from './EditButton'; export default class ComponentDoc extends React.Component { static contextTypes = { @@ -71,7 +72,7 @@ export default class ComponentDoc extends React.Component { ); }); - const { title, subtitle, chinese, english } = meta; + const { title, subtitle, chinese, english, filename } = meta; return (
    @@ -87,6 +88,7 @@ export default class ComponentDoc extends React.Component { (!subtitle && !chinese) ? null : {subtitle || chinese} } + { props.utils.toReactComponent( diff --git a/site/theme/template/Content/Demo.jsx b/site/theme/template/Content/Demo.jsx index 8a7c9a4bf8..4f73db5b30 100644 --- a/site/theme/template/Content/Demo.jsx +++ b/site/theme/template/Content/Demo.jsx @@ -1,6 +1,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import classNames from 'classnames'; +import EditButton from './EditButton'; export default class Demo extends React.Component { static contextTypes = { @@ -64,7 +65,7 @@ export default class Demo extends React.Component { preview(React, ReactDOM) } { - !!style ? + style ?