From 2f771b0482a43d6d7ef71f760b4cd11bb6c70226 Mon Sep 17 00:00:00 2001 From: Benjy Cui Date: Sun, 27 Sep 2015 16:30:35 +0800 Subject: [PATCH] feat: button should be a component --- components/button/button-group.jsx | 22 ++++ components/button/button.jsx | 55 ++++++++++ components/button/demo/basic.md | 42 ++++---- components/button/demo/button-group.md | 142 ++++++++++++++----------- components/button/demo/icon.md | 75 +++++++------ components/button/demo/loading.md | 23 ++-- components/button/demo/menu.md | 19 ---- components/button/demo/shape.md | 42 ++++++++ components/button/demo/size.md | 23 ++-- components/button/demo/status.md | 36 ++++--- components/button/index.jsx | 7 ++ components/button/index.md | 31 ++---- index.js | 2 + style/components/button.less | 5 + 14 files changed, 339 insertions(+), 185 deletions(-) create mode 100644 components/button/button-group.jsx create mode 100644 components/button/button.jsx delete mode 100644 components/button/demo/menu.md create mode 100644 components/button/demo/shape.md create mode 100644 components/button/index.jsx diff --git a/components/button/button-group.jsx b/components/button/button-group.jsx new file mode 100644 index 0000000000..7de6bea230 --- /dev/null +++ b/components/button/button-group.jsx @@ -0,0 +1,22 @@ +import React from 'react'; + +const prefix = 'ant-btn-group-'; + +export default class ButtonGroup extends React.Component { + render() { + const {size, className, ...others} = this.props; + + let classSet = ['ant-btn-group']; + if (size) { + classSet.push(prefix + size); + } + if (className) { + classSet.push(className); + } + + return
; + } +} +ButtonGroup.propTypes = { + size: React.PropTypes.string, +}; diff --git a/components/button/button.jsx b/components/button/button.jsx new file mode 100644 index 0000000000..7cef8ece7a --- /dev/null +++ b/components/button/button.jsx @@ -0,0 +1,55 @@ +import React from 'react'; + +const rxTwoCNChar = /^[\u4e00-\u9fa5]{2,2}$/; +const isTwoCNChar = rxTwoCNChar.test.bind(rxTwoCNChar); +function isString(str) { + return typeof str === 'string'; +} + +const prefix = 'ant-btn-'; +function updateClassWithProp(classSet, prop) { + if (prop) { + classSet.push(prefix + prop); + } +} + +// Insert one space between two chinese characters automatically. +function insertSpace(child) { + if (isString(child) && isTwoCNChar(child)) { + return child.split('').join(' '); + } + + if (isString(child.type) && isTwoCNChar(child.props.children)) { + return React.cloneElement(child, {}, + child.props.children.split('').join(' ')); + } + + return child; +} + +export default class Button extends React.Component { + render() { + const props = this.props; + const {type, shape, size, onClick, className, children, ...others} = props; + + let classSet = ['ant-btn']; + updateClassWithProp(classSet, type); + updateClassWithProp(classSet, shape); + updateClassWithProp(classSet, size); + if ('loading' in props && props.loading !== false) { + classSet.push(prefix + 'loading'); + } + if (className) { + classSet.push(className); + } + + const kids = React.Children.map(children, insertSpace); + + return ; + } +} +Button.defaultProps = { + onClick() {}, +}; diff --git a/components/button/demo/basic.md b/components/button/demo/basic.md index 8e52a86d46..fc80271492 100644 --- a/components/button/demo/basic.md +++ b/components/button/demo/basic.md @@ -1,29 +1,27 @@ -# 标准按钮 +# 按钮类型 -- order: 1 +- order: 0 -为 ` -Link - - - -
- - - - - +React.render(
+ + + +
, +document.getElementById('components-button-demo-basic')) ```` + + diff --git a/components/button/demo/button-group.md b/components/button/demo/button-group.md index 69daa96796..c3ca68dc31 100644 --- a/components/button/demo/button-group.md +++ b/components/button/demo/button-group.md @@ -1,78 +1,86 @@ # 按钮组合 -- order: 6 +- order: 5 -将一系列的 `.ant-btn` 放入 `.ant-btn-group` 的容器中。 +可以将多个 `Button` 放入 `ButtonGroup` 的容器中。 -按钮组合尺寸 - -只要给 `.ant-btn-group` 加上 `.ant-btn-group-*` 类,即可设置不同的尺寸,目前支持大中小三种尺寸。 +通过设置 `size` 为 `lg` `sm` 分别把按钮组合设为大、小尺寸。若不设置 `size`,则尺寸为中。 --- -````html +````jsx +var Button = antd.Button; +var ButtonGroup = antd.ButtonGroup; +var Icon = antd.Icon; + +React.render(

基本组合

-
- - -
-
- - - -
-
- - - - -
+ + + + + + + + + + + + + + + +

带图标按钮组合

-
- - -
-
- - -
+ + + + + + + + +

多个组合

-
- - - - - -
+ + + + + + + +

尺寸

-
- - - -
-
- - - -
-
- - - + + + + + + + + + + + + + + +
+, document.getElementById('components-button-demo-button-group')); ```` diff --git a/components/button/demo/icon.md b/components/button/demo/icon.md index 8574a67c93..2ef66d0ac7 100644 --- a/components/button/demo/icon.md +++ b/components/button/demo/icon.md @@ -1,45 +1,58 @@ # 图标按钮 -- order: 4 +- order: 6 -图标一般放在文字前面,也可以单独存在。 +`Button` 内可以嵌套图标,图标可以放在文字前、后,也可以单独存在。 --- -````html - - + + - - + + - - + + -

+
- - - + + + +
, +document.getElementById('components-button-demo-icon')); ```` + + diff --git a/components/button/demo/loading.md b/components/button/demo/loading.md index 9f5a314be0..e2ce2c3fdb 100644 --- a/components/button/demo/loading.md +++ b/components/button/demo/loading.md @@ -1,12 +1,14 @@ # 加载中 -- order: 7 +- order: 4 -加载按钮。最后一个按钮演示点击后进入加载状态。 +添加 `loading` 属性即可让按钮处于加载状态,最后一个按钮演示点击后进入加载状态。 --- ````jsx +var Button = antd.Button; + var App = React.createClass({ getInitialState() { return { @@ -19,21 +21,20 @@ var App = React.createClass({ }); }, render() { - var loadingClass = this.state.loading ? 'ant-btn-loading' : ''; return
- - + - + +
- +
; } }); diff --git a/components/button/demo/menu.md b/components/button/demo/menu.md deleted file mode 100644 index 0beac97615..0000000000 --- a/components/button/demo/menu.md +++ /dev/null @@ -1,19 +0,0 @@ -# 菜单按钮 - -- order: 5 - -**注**: 下拉按钮的 icon 大小统一成 **10px**。 - -> 更多交互,详见 [Dropdown 下拉菜单](http://ant.design/components/dropdown/)。 - ---- - -````html - - -```` diff --git a/components/button/demo/shape.md b/components/button/demo/shape.md new file mode 100644 index 0000000000..bdda312a9a --- /dev/null +++ b/components/button/demo/shape.md @@ -0,0 +1,42 @@ +# 按钮形状 + +- order: 1 + +通过设置 `shape` 为 `circle` `circle-outline`,可以把按钮形状设为圆形,并且 `circle-outline` 在 hover 时会有动画效果。 + +--- + +````jsx +var Button = antd.Button; +var Icon = antd.Icon; + +React.render(
+ + + +
+ + + +
+, document.getElementById('components-button-demo-shape')); +```` + + diff --git a/components/button/demo/size.md b/components/button/demo/size.md index 8315e9f139..402538c977 100644 --- a/components/button/demo/size.md +++ b/components/button/demo/size.md @@ -2,14 +2,25 @@ - order: 2 -提供 大 中 小 三种尺寸。 +按钮有大、中、小三种尺寸。 -使用 `.ant-btn-lg` `.ant-btn-sm` 即可获得大 小尺寸,默认尺寸为中。 +通过设置 `size` 为 `lg` `sm` 分别把按钮设为大、小尺寸。若不设置 `size`,则尺寸为中。 --- -````html - - - +````jsx +var Button = antd.Button; + +React.render(
+ + + +
+, document.getElementById('components-button-demo-size')); ```` + + diff --git a/components/button/demo/status.md b/components/button/demo/status.md index 3566f26a9f..7a9f2a1e56 100644 --- a/components/button/demo/status.md +++ b/components/button/demo/status.md @@ -2,19 +2,31 @@ - order: 3 -通过背景色透明度的变化来体现不同的操作状态,移入或点击元素可以查看状态。 - -失效状态:为 ` - -

- - -

- - +````jsx +var Button = antd.Button; + +React.render(
+

使用 `disabled` 属性

+ + +
+ + +
+

使用 `.disabled` class

+ + +
+, document.getElementById('components-button-demo-status')); ```` + + diff --git a/components/button/index.jsx b/components/button/index.jsx new file mode 100644 index 0000000000..1ebc65968c --- /dev/null +++ b/components/button/index.jsx @@ -0,0 +1,7 @@ +import Button from './button'; +import ButtonGroup from './button-group'; + +export { + Button, + ButtonGroup, +}; diff --git a/components/button/index.md b/components/button/index.md index b0e8c49149..0540041440 100644 --- a/components/button/index.md +++ b/components/button/index.md @@ -15,27 +15,16 @@ ## 如何使用 -- 按钮的基础样式为 `ant-btn`。 +- 通过设置 Button 的属性来产生不同的按钮样式,推荐顺序为:`type` -> `shape` -> `size` -> `loading` -> `disabled` -- 通过类组装的形式来产生不同的按钮样式,推荐遵循如下顺序: -``` - .ant-btn - ↓ - .ant-btn-primary | .ant-btn-ghost - ↓ - .ant-btn-circle | .ant-btn-circle-outline - ↓ - .ant-btn-lg | .ant-btn-sm - ``` +- 按钮的属性说明如下: -- 按钮的样式参数说明如下: +属性 | 说明 | 类型 | 默认值 +-----|-----|-----|------ +type | 设置按钮类型,可选值为 `primary` `ghost` 或者不设 | Enum | undefined +shape | 设置按钮形状,可选值为 `circle` `circle-outline` 或者不设 | Enum | undefined +size | 设置按钮大小,可选值为 `sm` `lg` 或者不设 | Enum | undefined +loading | 设置按钮载入状态,存在为 `true`,不存在为 `false`,或直接设置值,如:`loading="true"` | Bool | false +onClick | `click` 事件的 handler | Function | `function() {}` -| 类名 | 说明 | -| ------------- | ------------- | -| `.ant-btn` | 按钮基础样式。 | -| `.ant-btn-primary` `.ant-btn-ghost` | 使用这些列出的类可以快速创建一个带有预定义样式的按钮。 | -| `.ant-btn-circle` `.ant-btn-circle-outline` | 用于创建圆形按钮,`.ant-btn-circle-outline` 为描边按钮。 | -| `.ant-btn-lg` `.ant-btn-sm` | 定义按钮大小尺寸,目前提供三种尺寸:大中小,默认为中。 | -| `.ant-btn-group` | 按钮组合,通过按钮组容器把一组按钮放在同一行里。 | - -> 当按钮只有两个汉字时,需要在两字中加空格。 +- `` 最终会被渲染为 ``,并且除了上表中的属性,其它属性都会直接传到 `` diff --git a/index.js b/index.js index 3fc96e5c7e..4e4c2e3b79 100644 --- a/index.js +++ b/index.js @@ -44,6 +44,8 @@ const antd = { Badge: require('./components/badge'), Menu: require('./components/menu'), Timeline: require('./components/timeline'), + Button: require('./components/button').Button, + ButtonGroup: require('./components/button').ButtonGroup, Icon: require('./components/iconfont') }; diff --git a/style/components/button.less b/style/components/button.less index d24047de0f..303de6f952 100644 --- a/style/components/button.less +++ b/style/components/button.less @@ -81,4 +81,9 @@ &-group { .btn-group(@btn-prefix-cls); } + + // To ensure that a space will be placed between character and `Icon`. + > .@{iconfont-css-prefix} + span, > span + .@{iconfont-css-prefix} { + margin-left: 0.5em; + } }