├── .babelrc ├── .eslintrc ├── .gitignore ├── CHANGELOG.md ├── README.md ├── examples ├── App │ └── index.js ├── Default │ └── index.js ├── Entry │ └── index.js ├── Html │ └── index.js ├── Navigator │ └── index.js ├── Routers │ └── index.js ├── components │ ├── FormItemCascader │ │ ├── Demo01 │ │ │ ├── README.md │ │ │ ├── component.js │ │ │ ├── config.js │ │ │ └── index.js │ │ └── index.js │ ├── FormItemCheckboxGroup │ │ ├── Demo01 │ │ │ ├── README.md │ │ │ ├── component.js │ │ │ ├── config.js │ │ │ └── index.js │ │ └── index.js │ ├── FormItemInput │ │ ├── Demo01 │ │ │ ├── README.md │ │ │ ├── component.js │ │ │ ├── config.js │ │ │ └── index.js │ │ ├── README.md │ │ └── index.js │ ├── FormItemRadioGroup │ │ ├── Demo01 │ │ │ ├── README.md │ │ │ ├── component.js │ │ │ ├── config.js │ │ │ └── index.js │ │ └── index.js │ ├── FormItemSelect │ │ ├── Demo01 │ │ │ ├── README.md │ │ │ ├── component.js │ │ │ ├── config.js │ │ │ └── index.js │ │ └── index.js │ └── FuzzySearch │ │ ├── Demo01 │ │ ├── README.md │ │ ├── component.js │ │ ├── config.js │ │ └── index.js │ │ └── index.js ├── constants.js ├── fetch.js ├── index.html └── style.less ├── lib ├── FormItemCascader │ └── index.js ├── FormItemCheckboxGroup │ └── index.js ├── FormItemInput │ └── index.js ├── FormItemNoLabel │ └── index.js ├── FormItemRadioGroup │ └── index.js ├── FormItemSelect │ └── index.js ├── FuzzySearch │ └── index.js ├── config.js ├── index.js └── util.js ├── package.json ├── server ├── app.js ├── routes │ └── apis.js ├── views │ ├── 404.jade │ └── error.jade └── www ├── src ├── FormItemCascader │ └── index.js ├── FormItemCheckboxGroup │ └── index.js ├── FormItemInput │ └── index.js ├── FormItemNoLabel │ └── index.js ├── FormItemRadioGroup │ └── index.js ├── FormItemSelect │ └── index.js ├── FuzzySearch │ └── index.js ├── config.js ├── index.js └── util.js ├── webpack.config.js └── webpack.dev.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | ["import", { 4 | "libraryName": "antd", 5 | "libraryDirectory": "lib", 6 | "style": true 7 | }], 8 | ["import", { 9 | "libraryName": "react-router", 10 | "libraryDirectory": "lib" 11 | }] 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "commonjs": true, 5 | "es6": true 6 | }, 7 | "globals": { 8 | "__DEV__": true, 9 | "process": true, 10 | "__dirname": true 11 | 12 | }, 13 | "extends": [ 14 | "eslint:recommended", 15 | "plugin:react/recommended" 16 | ], 17 | "parser": "babel-eslint", 18 | "parserOptions": { 19 | "ecmaFeatures": { 20 | "experimentalObjectRestSpread": true, 21 | "jsx": true 22 | }, 23 | "sourceType": "module" 24 | }, 25 | "plugins": [ 26 | "react" 27 | ], 28 | "rules": { 29 | "comma-dangle": [ 30 | 2, 31 | "never" 32 | ], 33 | "indent": [ 34 | 2, 35 | 2, 36 | {"SwitchCase": 1} 37 | ], 38 | "linebreak-style": [ 39 | 2, 40 | "unix" 41 | ], 42 | "quotes": [ 43 | 2, 44 | "single" 45 | ], 46 | "semi": [ 47 | 2, 48 | "always" 49 | ], 50 | "no-class-assign": 0, 51 | "react/prop-types": 0, 52 | "react/no-danger": 0 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | dist 4 | 5 | # Mac 6 | .DS_Store 7 | 8 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | ## 版本信息 3 | 4 | ### 0.4.0 5 | 6 | `2017-03-15` 7 | 8 | - 修改**form config**中`formLayout`改为`layout` 9 | - 删除**form config**中`formItemLayoutWithOutLabel`属性 10 | - 修复有些组件不能单独传`layout`属性bug等 11 | - 优化示例代码 12 | 13 | ### 0.3.4 14 | 15 | `2017-03-13` 16 | 17 | - 优化演示示例,tab形式交互 18 | - 示例中显示表单配置项 19 | 20 | ### 0.3.2 21 | 22 | `2017-03-03` 23 | 24 | - 优化演示示例 25 | - 添加表单组件默认配置 26 | 27 | 28 | ### 0.3.1 29 | 30 | `2017-03-01` 31 | 32 | - 在`antd-easy`中支持导出 `antd` 原始模块 33 | - `utils` 模块重命名为 `util` 34 | - 优化示例代码导出 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # antd-easy 3 | 4 | > 基于ant-design封装的业务组件,涉及表单校验、错误提示等复杂交互。技术底层为React.js 5 | 6 | ## 作为第三方库使用 7 | 8 | ### 基于 `antd@2.7.*` 版本 9 | 10 | ### 安装 11 | 12 | ```shell 13 | npm i antd-easy --save 14 | ``` 15 | 16 | ### 通过 `import` 方式引入 17 | 18 | ```javascript 19 | import FormItemInput from 'antd-easy/lib/FormItemInput'; 20 | import FormItemSelect from 'antd-easy/lib/FormItemSelect'; 21 | ... 22 | ``` 23 | 24 | 或者 25 | 26 | ```javascript 27 | import { Input, Select, FormItemInput, FormItemSelect } from 'antd-easy'; 28 | ... 29 | ``` 30 | 31 | ## 本地查看demo演示 32 | 33 | ### 准备,clone 并安装依赖 34 | 35 | ``` 36 | git clone git@github.com:tt-ghost/antd-easy.git 37 | cd antd-easy 38 | npm i 39 | ``` 40 | 41 | ### 启动 42 | 43 | #### 启动服务端,用于返回示例文件源码,默认启动 *3100* 端口 44 | 45 | ```npm 46 | npm run server 47 | ``` 48 | 49 | #### 执行以下代码运行前端代码,成功后访问 [http://localhost:9100](http://localhost:9100) 50 | 51 | ```npm 52 | npm start 53 | ``` 54 | 55 | -------------------------------------------------------------------------------- /examples/App/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from 'react-router'; 3 | import Navigator from '../Navigator'; 4 | import { Layout } from 'antd-easy'; 5 | 6 | const { Header, Content, Footer, Sider } = Layout; 7 | 8 | class App extends React.Component { 9 | 10 | render(){ 11 | return 12 |
Antd-Easy
13 | 14 | 15 | 16 | 17 | 18 | 19 | {this.props.children} 20 | 21 | 22 | 23 | 24 |
; 25 | } 26 | } 27 | 28 | export default App; 29 | -------------------------------------------------------------------------------- /examples/Default/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const docs = [{ 4 | title: 'Ant Design 官网', 5 | url: 'https://ant.design/docs/react/introduce-cn' 6 | }, { 7 | title: 'React.js', 8 | url: 'http://reactjs.cn/react/docs/component-api.html' 9 | }]; 10 | 11 | class Default extends React.Component { 12 | 13 | render(){ 14 | return
15 |

Antd-Easy

16 |
17 | 欢迎使用 Antd-Easy 组件,本组件基于 ant design 进行再次封装,旨在更便捷的使用。 18 |
19 |

关于使用

20 |
21 |
Antd Design的原始组件可以同时使用,直接按 {'import { Input } from "antd-easy"'} 这种方式导入即可。 22 |
23 |
关于Ant Design 组件的详细API,请参考 {docs[0].title}
24 |
25 |

相关文档

26 |
27 | 32 |
33 |
; 34 | } 35 | } 36 | 37 | Default.contextTypes = { 38 | router: React.PropTypes.object.isRequired 39 | }; 40 | 41 | export default Default; 42 | -------------------------------------------------------------------------------- /examples/Entry/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import Routers from '../Routers'; 4 | import 'antd/dist/antd.less'; 5 | import '../style.less'; 6 | 7 | ReactDOM.render(, document.getElementById('antd-easy-container')); 8 | -------------------------------------------------------------------------------- /examples/Html/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactMarkdown from 'react-markdown'; 3 | import marked from 'marked'; 4 | import highlight from 'highlight.js'; 5 | import { Tabs } from 'antd-easy'; 6 | import fetch from '../fetch'; 7 | import { baseURL } from '../constants'; 8 | import 'highlight.js/styles/googlecode.css'; 9 | 10 | const TabPane = Tabs.TabPane; 11 | 12 | class Html extends React.Component { 13 | constructor(props) { 14 | super(props); 15 | 16 | marked.setOptions({ 17 | renderer: new marked.Renderer(), 18 | gfm: true, 19 | tables: true, 20 | breaks: true, 21 | pedantic: true, 22 | sanitize: true, 23 | smartLists: true, 24 | smartypants: true, 25 | highlight: function(code){ 26 | return highlight.highlightAuto(code).value; 27 | } 28 | }); 29 | this.state = { 30 | text: '', 31 | jsx: '', 32 | config: '' 33 | }; 34 | } 35 | 36 | componentDidMount() { 37 | const { mdpath } = this.props; 38 | 39 | // codepath && this.getFile(codepath, 'code'); 40 | mdpath && this.getFile(mdpath, 'markdown', 'text'); 41 | } 42 | 43 | getFile(filePath, type, stateField){ 44 | const language = this.props.language||'js'; 45 | 46 | return fetch(baseURL + `file?name=${filePath}`, {method: 'GET'}) 47 | .then(res => { 48 | return res.text(); 49 | }) 50 | .then(res => { 51 | const willChangeState = type === 'code' ? 52 | {[stateField]: '\n```'+language+'\n'+res+'```\n'} : {[stateField]: res}; 53 | this.setState(willChangeState); 54 | return res; 55 | }); 56 | } 57 | 58 | onTabChange(key) { 59 | const { codepath, configpath } = this.props; 60 | if(key === 'jsx' && codepath && !this.state.jsx){ 61 | this.getFile(codepath, 'code', 'jsx'); 62 | } 63 | if(key === 'config' && configpath && !this.state.config){ 64 | this.getFile(configpath, 'code', 'config'); 65 | } 66 | } 67 | 68 | render(){ 69 | const { jsx, text, config='暂无内容' } = this.state; 70 | const { configpath } = this.props; 71 | const _jsx = marked(jsx||''); 72 | const _config = marked(config||''); 73 | 74 | return
75 | {this.props.children} 76 | 77 | 78 | 79 | 80 | 81 |
82 | 83 | {configpath ? 84 |
85 | : null } 86 | 87 |
; 88 | } 89 | } 90 | 91 | export default Html; 92 | 93 | -------------------------------------------------------------------------------- /examples/Navigator/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Menu } from 'antd-easy'; 3 | 4 | const MenuItem = Menu.Item; 5 | 6 | class Navigator extends React.Component { 7 | constructor(props){ 8 | super(props); 9 | this.state = { 10 | current: 'FormItemInput' 11 | }; 12 | } 13 | componentWillReceiveProps(nextProps) { 14 | if(!this.getCurrentPath(nextProps)){ 15 | this.setState({current: ''}); 16 | } 17 | } 18 | 19 | componentDidMount() { 20 | this.setState({current: this.getCurrentPath(this.props)}); 21 | } 22 | 23 | getCurrentPath(props){ 24 | const pathname = props.location.pathname.split('/'); 25 | pathname.shift(); 26 | return pathname[0]; 27 | } 28 | 29 | onMenuClick(e){ 30 | this.context.router.push(`/${e.key}`); 31 | this.setState({current: e.key}); 32 | } 33 | 34 | render(){ 35 | return 36 | FormItemInput 输入框 37 | FormItemSelect 下拉框 38 | FuzzySearch 模糊搜索 39 | FormItemRadioGroup 单选 40 | FormItemCheckboxGroup 复选 41 | FormItemCascader 级联 42 | ; 43 | } 44 | } 45 | 46 | Navigator.contextTypes = { 47 | router: React.PropTypes.object.isRequired 48 | }; 49 | 50 | export default Navigator; 51 | -------------------------------------------------------------------------------- /examples/Routers/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Router, IndexRoute, Route, browserHistory } from 'react-router'; 3 | import App from '../App'; 4 | import Default from '../Default'; 5 | import FormItemInput from '../components/FormItemInput'; 6 | import FormItemSelect from '../components/FormItemSelect'; 7 | import FuzzySearch from '../components/FuzzySearch'; 8 | import FormItemRadioGroup from '../components/FormItemRadioGroup'; 9 | import FormItemCheckboxGroup from '../components/FormItemCheckboxGroup'; 10 | import FormItemCascader from '../components/FormItemCascader'; 11 | 12 | class Routers extends React.Component { 13 | render(){ 14 | return 15 | {require.ensure([], ()=>{callback(null, App);}, 'App');}} 17 | > 18 | {require.ensure([], ()=>{callback(null, Default);}, 'Default');}} 20 | /> 21 | {require.ensure([], ()=>{callback(null, FormItemInput);}, 'FormItemInput');}} 23 | /> 24 | {require.ensure([], ()=>{callback(null, FormItemSelect);}, 'FormItemSelect');}} 26 | /> 27 | {require.ensure([], ()=>{callback(null, FuzzySearch);}, 'FuzzySearch');}} 29 | /> 30 | {require.ensure([], ()=>{callback(null, FormItemRadioGroup);}, 'FormItemRadioGroup');}} 32 | /> 33 | {require.ensure([], ()=>{callback(null, FormItemCheckboxGroup);}, 'FormItemCheckboxGroup');}} 35 | /> 36 | {require.ensure([], ()=>{callback(null, FormItemCascader);}, 'FormItemCascader');}} 38 | /> 39 | 40 | 41 | ; 42 | } 43 | } 44 | 45 | export default Routers; 46 | -------------------------------------------------------------------------------- /examples/components/FormItemCascader/Demo01/README.md: -------------------------------------------------------------------------------- 1 | 2 | ### FormItemCascader 级联 3 | -------------------------------------------------------------------------------- /examples/components/FormItemCascader/Demo01/component.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Form, Button, FormItemCascader, FormItemNoLabel } from 'antd-easy'; 3 | import config from './config'; 4 | 5 | const createForm = Form.create; 6 | 7 | class FormItemCascaderDemo extends React.Component { 8 | constructor(props) { 9 | super(props); 10 | this.state = { 11 | loading: false 12 | }; 13 | } 14 | 15 | getChildContext() { 16 | return { form: this.props.form }; 17 | } 18 | 19 | onSubmit(){ 20 | this.props.form.validateFieldsAndScroll({ force: true }, (errors, values) => { 21 | if (errors) {return values;} 22 | /*eslint-disable no-console */ 23 | console.log(values); 24 | this.setState({loading: true, values}); 25 | setTimeout(() => {this.setState({loading: false});}, 2000); 26 | }); 27 | } 28 | 29 | render(){ 30 | const options = [ 31 | {label: '北京', value: 'beijing', children: [ 32 | { label: '朝阳区', value: 'chaoyang'}, 33 | { label: '海淀区', value: 'haidian', children: [ 34 | {label: '西二旗', value: 'xierqi'}, 35 | {label: '中关村', value: 'zhognguancun'}, 36 | {label: '西单', value: 'xidan'} 37 | ]}, 38 | { label: '西城区', value: 'xicheng'}, 39 | { label: '昌平区', value: 'changping'} 40 | ]}, 41 | {label: '安徽', value: 'anhui'}, 42 | {label: '上海', value: 'shanghai'} 43 | ]; 44 | 45 | this.props.form.config = config; 46 | 47 | return
48 | 49 | 50 | 51 | 55 | 56 | ; 57 | } 58 | } 59 | 60 | FormItemCascaderDemo.childContextTypes = { 61 | form: React.PropTypes.object.isRequired 62 | }; 63 | 64 | export default createForm()(FormItemCascaderDemo); 65 | 66 | -------------------------------------------------------------------------------- /examples/components/FormItemCascader/Demo01/config.js: -------------------------------------------------------------------------------- 1 | 2 | const layout = { 3 | labelCol: { span: 4 }, 4 | wrapperCol: { span: 16 } 5 | }; 6 | 7 | export default { 8 | layout, 9 | local: { 10 | type: 'Cascader', 11 | formItemAttr: { 12 | label: '地区', 13 | required: true 14 | }, 15 | fieldAttr: { 16 | placeholder: '请选择地区', 17 | allowClear: false, 18 | showSearch: true, 19 | size: 'large', 20 | style: {width: '100%'}, 21 | notFoundContent: '没有找到' 22 | }, 23 | error: { 24 | message: '请选择正确的地区' 25 | } 26 | } 27 | }; -------------------------------------------------------------------------------- /examples/components/FormItemCascader/Demo01/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Component from './component'; 3 | import Html from '../../../Html'; 4 | 5 | const basePath = 'FormItemCascader/Demo01/'; 6 | 7 | class Container extends React.Component { 8 | 9 | render(){ 10 | return 14 | 15 | ; 16 | } 17 | } 18 | 19 | export default Container; 20 | 21 | -------------------------------------------------------------------------------- /examples/components/FormItemCascader/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Demo01 from './Demo01'; 3 | 4 | class FormItemCascaderDemo extends React.Component { 5 | 6 | render(){ 7 | return
8 | 9 |
; 10 | } 11 | } 12 | 13 | export default FormItemCascaderDemo; 14 | 15 | -------------------------------------------------------------------------------- /examples/components/FormItemCheckboxGroup/Demo01/README.md: -------------------------------------------------------------------------------- 1 | 2 | ### FormItemCheckboxGroup 复选 3 | -------------------------------------------------------------------------------- /examples/components/FormItemCheckboxGroup/Demo01/component.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Form, Button, FormItemCheckboxGroup, FormItemNoLabel, FormItemInput } from 'antd-easy'; 3 | import config from './config'; 4 | 5 | const createForm = Form.create; 6 | 7 | class FormItemCheckboxGroupDemo extends React.Component { 8 | constructor(props) { 9 | super(props); 10 | this.state = { 11 | loading: false 12 | }; 13 | } 14 | 15 | getChildContext() { 16 | return { form: this.props.form }; 17 | } 18 | 19 | getFormData(values){ 20 | const { color, sendEmail, remark } = values; 21 | return { 22 | color, 23 | sendEmail: sendEmail && sendEmail.length?true:false, 24 | remark 25 | }; 26 | } 27 | 28 | onSubmit(){ 29 | this.props.form.validateFieldsAndScroll({ force: true }, (errors, values) => { 30 | if (errors) {return values;} 31 | const formData = this.getFormData(values); 32 | /*eslint-disable no-console */ 33 | console.log(formData); 34 | this.setState({loading: true, formData}); 35 | setTimeout(() => {this.setState({loading: false});}, 2000); 36 | }); 37 | } 38 | 39 | render(){ 40 | const options = [ 41 | {label: '红色', value: 'red'}, 42 | {label: '绿色', value: 'green'}, 43 | {label: '蓝色', value: 'blue', disabled: true} 44 | ]; 45 | const sendEmailOptions = [ 46 | {label: '是否发送邮件', value: true} 47 | ]; 48 | const needRemarkOptions = [ 49 | {label: '是否添加备注', value: true} 50 | ]; 51 | const { getFieldValue } = this.props.form; 52 | const needRemark = getFieldValue('needRemark'); 53 | 54 | this.props.form.config = config; 55 | 56 | return
57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | {needRemark && needRemark.length ? 67 | 68 | 69 | 70 | :null} 71 | 72 | 73 | 77 | 78 | ; 79 | } 80 | } 81 | 82 | FormItemCheckboxGroupDemo.childContextTypes = { 83 | form: React.PropTypes.object.isRequired 84 | }; 85 | 86 | export default createForm()(FormItemCheckboxGroupDemo); 87 | 88 | -------------------------------------------------------------------------------- /examples/components/FormItemCheckboxGroup/Demo01/config.js: -------------------------------------------------------------------------------- 1 | 2 | const layout = { 3 | labelCol: { span: 4 }, 4 | wrapperCol: { span: 16 } 5 | }; 6 | 7 | export default { 8 | layout, 9 | color: { 10 | type: 'CheckboxGroup', 11 | formItemAttr: { 12 | label: '颜色', 13 | required: true 14 | }, 15 | fieldAttr: { 16 | 17 | }, 18 | error: { 19 | message: '请选择颜色' 20 | } 21 | }, 22 | sendEmail: { 23 | type: 'Checkbox', 24 | formItemAttr: { 25 | // label: '颜色', 26 | required: false 27 | }, 28 | fieldAttr: { 29 | }, 30 | error: { 31 | message: '请选择颜色' 32 | } 33 | }, 34 | needRemark: { 35 | type: 'Checkbox', 36 | formItemAttr: { 37 | // label: '颜色', 38 | required: false 39 | }, 40 | fieldAttr: { 41 | }, 42 | error: { 43 | message: '请选择' 44 | } 45 | }, 46 | remark:{ 47 | type: 'Input', 48 | formItemAttr: { 49 | // label: '备注', 50 | required: true 51 | }, 52 | fieldAttr: { 53 | placeholder: '请填写备注', 54 | type: 'textarea' 55 | }, 56 | error: { 57 | message: '请输入正确的备注' 58 | } 59 | } 60 | }; -------------------------------------------------------------------------------- /examples/components/FormItemCheckboxGroup/Demo01/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Component from './component'; 3 | import Html from '../../../Html'; 4 | 5 | const basePath = 'FormItemCheckboxGroup/Demo01/'; 6 | 7 | class Container extends React.Component { 8 | 9 | render(){ 10 | return 14 | 15 | ; 16 | } 17 | } 18 | 19 | export default Container; 20 | 21 | -------------------------------------------------------------------------------- /examples/components/FormItemCheckboxGroup/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Demo01 from './Demo01'; 3 | 4 | class FormItemCheckboxGroupDemo extends React.Component { 5 | 6 | render(){ 7 | return
8 | 9 |
; 10 | } 11 | } 12 | 13 | export default FormItemCheckboxGroupDemo; 14 | 15 | -------------------------------------------------------------------------------- /examples/components/FormItemInput/Demo01/README.md: -------------------------------------------------------------------------------- 1 | 2 | ### FormItemInput 输入框 3 | 4 | 5 | -------------------------------------------------------------------------------- /examples/components/FormItemInput/Demo01/component.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Button, Form, FormItemInput, FormItemNoLabel } from 'antd-easy'; 3 | import config from './config'; 4 | 5 | const createForm = Form.create; 6 | 7 | class FormItemInputDemo extends React.Component { 8 | constructor(props) { 9 | super(props); 10 | this.state = { 11 | loading: false 12 | }; 13 | } 14 | 15 | getChildContext() { 16 | return { form: this.props.form }; 17 | } 18 | 19 | onSubmit(){ 20 | this.props.form.validateFieldsAndScroll({ force: true }, (errors, values) => { 21 | if (errors) {return values;} 22 | this.setState({loading: true}); 23 | setTimeout(() => {this.setState({loading: false});}, 2000); 24 | }); 25 | } 26 | 27 | render(){ 28 | 29 | this.props.form.config = config; 30 | return
31 | 32 | 33 | 34 | 35 | ; 36 | } 37 | } 38 | 39 | FormItemInputDemo.childContextTypes = { 40 | form: React.PropTypes.object.isRequired 41 | }; 42 | 43 | export default createForm()(FormItemInputDemo); 44 | 45 | -------------------------------------------------------------------------------- /examples/components/FormItemInput/Demo01/config.js: -------------------------------------------------------------------------------- 1 | 2 | const layout = { 3 | labelCol: { span: 4 }, 4 | wrapperCol: { span: 16 } 5 | }; 6 | 7 | export default { 8 | layout, 9 | name: { 10 | type: 'Input', 11 | formItemAttr: { 12 | label: '姓名', 13 | required: true 14 | }, 15 | fieldAttr: { 16 | placeholder: '请填写姓名', 17 | type: 'text' 18 | }, 19 | error: { 20 | message: '请输入正确的姓名' 21 | } 22 | } 23 | }; -------------------------------------------------------------------------------- /examples/components/FormItemInput/Demo01/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Component from './component'; 3 | import Html from '../../../Html'; 4 | 5 | const basePath = 'FormItemInput/Demo01/'; 6 | 7 | class Container extends React.Component { 8 | 9 | render(){ 10 | return 14 | 15 | ; 16 | } 17 | } 18 | 19 | export default Container; 20 | 21 | -------------------------------------------------------------------------------- /examples/components/FormItemInput/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## FormItemInput 输入框 3 | 4 | 表单中基本文本输入框 5 | 6 | ## 何时使用 7 | 8 | 需要用户输入简单文本的表单内容时 9 | 10 | ## 代码演示 11 | -------------------------------------------------------------------------------- /examples/components/FormItemInput/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Demo01 from './Demo01'; 3 | 4 | class FormItemInputDemo extends React.Component { 5 | 6 | render(){ 7 | return
8 | 9 |
; 10 | } 11 | } 12 | 13 | export default FormItemInputDemo; 14 | 15 | -------------------------------------------------------------------------------- /examples/components/FormItemRadioGroup/Demo01/README.md: -------------------------------------------------------------------------------- 1 | 2 | ### FormItemRadio 单选 -------------------------------------------------------------------------------- /examples/components/FormItemRadioGroup/Demo01/component.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Form, Button, FormItemRadioGroup, FormItemNoLabel } from 'antd-easy'; 3 | import config from './config'; 4 | 5 | const createForm = Form.create; 6 | 7 | class FormItemRadioGroupDemo extends React.Component { 8 | constructor(props) { 9 | super(props); 10 | this.state = { 11 | loading: false 12 | }; 13 | } 14 | 15 | getChildContext() { 16 | return { form: this.props.form }; 17 | } 18 | 19 | onSubmit(){ 20 | this.props.form.validateFieldsAndScroll({ force: true }, (errors, values) => { 21 | if (errors) {return values;} 22 | this.setState({loading: true}); 23 | setTimeout(() => {this.setState({loading: false});}, 2000); 24 | }); 25 | } 26 | 27 | render(){ 28 | 29 | this.props.form.config = config; 30 | const options = [ 31 | {label: '男', value: 'male'}, 32 | {label: '女', value: 'female'}, 33 | {label: '保密', value: 'secret'} 34 | ]; 35 | return
36 | 37 | 38 | 39 | 40 | ; 41 | } 42 | } 43 | 44 | FormItemRadioGroupDemo.childContextTypes = { 45 | form: React.PropTypes.object.isRequired 46 | }; 47 | 48 | export default createForm()(FormItemRadioGroupDemo); 49 | 50 | -------------------------------------------------------------------------------- /examples/components/FormItemRadioGroup/Demo01/config.js: -------------------------------------------------------------------------------- 1 | 2 | const layout = { 3 | labelCol: { span: 4 }, 4 | wrapperCol: { span: 16 } 5 | }; 6 | 7 | export default { 8 | layout, 9 | sex: { 10 | type: 'RadioGroup', 11 | formItemAttr: { 12 | label: '性别', 13 | required: true 14 | }, 15 | fieldAttr: { 16 | }, 17 | error: { 18 | message: '请选择性别' 19 | } 20 | } 21 | }; -------------------------------------------------------------------------------- /examples/components/FormItemRadioGroup/Demo01/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Component from './component'; 3 | import Html from '../../../Html'; 4 | 5 | const basePath = 'FormItemRadioGroup/Demo01/'; 6 | 7 | class Container extends React.Component { 8 | 9 | render(){ 10 | return 14 | 15 | ; 16 | } 17 | } 18 | 19 | export default Container; 20 | 21 | -------------------------------------------------------------------------------- /examples/components/FormItemRadioGroup/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Demo01 from './Demo01'; 3 | 4 | class FormItemRadioGroupDemo extends React.Component { 5 | 6 | render(){ 7 | return
8 | 9 |
; 10 | } 11 | } 12 | 13 | export default FormItemRadioGroupDemo; 14 | 15 | -------------------------------------------------------------------------------- /examples/components/FormItemSelect/Demo01/README.md: -------------------------------------------------------------------------------- 1 | 2 | ### FormItemSelect 下拉框 3 | 4 | -------------------------------------------------------------------------------- /examples/components/FormItemSelect/Demo01/component.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Form, Button, FormItemSelect, FormItemNoLabel } from 'antd-easy'; 3 | import config from './config'; 4 | 5 | const createForm = Form.create; 6 | 7 | class FormItemSelectDemo extends React.Component { 8 | constructor(props) { 9 | super(props); 10 | this.state = { 11 | loading: false 12 | }; 13 | } 14 | 15 | getChildContext() { 16 | return { form: this.props.form }; 17 | } 18 | 19 | onSubmit(){ 20 | this.props.form.validateFieldsAndScroll({ force: true }, (errors, values) => { 21 | if (errors) {return values;} 22 | this.setState({loading: true}); 23 | setTimeout(() => {this.setState({loading: false});}, 2000); 24 | }); 25 | } 26 | 27 | render(){ 28 | 29 | this.props.form.config = config; 30 | const options = [{label: '北京', value: 'beijing'}, {label: '上海', value: 'shanghai'}]; 31 | 32 | return
33 | 34 | 35 | 36 | 37 | ; 38 | } 39 | } 40 | 41 | FormItemSelectDemo.childContextTypes = { 42 | form: React.PropTypes.object.isRequired 43 | }; 44 | 45 | export default createForm()(FormItemSelectDemo); 46 | 47 | -------------------------------------------------------------------------------- /examples/components/FormItemSelect/Demo01/config.js: -------------------------------------------------------------------------------- 1 | 2 | const layout = { 3 | labelCol: { span: 4 }, 4 | wrapperCol: { span: 16 } 5 | }; 6 | 7 | export default { 8 | layout, 9 | location: { 10 | type: 'Select', 11 | formItemAttr: { 12 | label: '地区', 13 | required: true 14 | }, 15 | fieldAttr: { 16 | placeholder: '请选择地区' 17 | }, 18 | keyField: 'value', 19 | valueField: 'label', 20 | error: { 21 | message: '请选择地区' 22 | } 23 | } 24 | }; -------------------------------------------------------------------------------- /examples/components/FormItemSelect/Demo01/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Component from './component'; 3 | import Html from '../../../Html'; 4 | 5 | const basePath = 'FormItemSelect/Demo01/'; 6 | 7 | class Container extends React.Component { 8 | 9 | render(){ 10 | return 14 | 15 | ; 16 | } 17 | } 18 | 19 | export default Container; 20 | 21 | -------------------------------------------------------------------------------- /examples/components/FormItemSelect/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Demo01 from './Demo01'; 3 | 4 | class FormItemSelectDemo extends React.Component { 5 | 6 | render(){ 7 | return
8 | 9 |
; 10 | } 11 | } 12 | 13 | export default FormItemSelectDemo; 14 | 15 | -------------------------------------------------------------------------------- /examples/components/FuzzySearch/Demo01/README.md: -------------------------------------------------------------------------------- 1 | 2 | ### FuzzySearch 模糊搜索 3 | 4 | -------------------------------------------------------------------------------- /examples/components/FuzzySearch/Demo01/component.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Form, Button, FuzzySearch, FormItemNoLabel } from 'antd-easy'; 3 | import config from './config'; 4 | 5 | const createForm = Form.create; 6 | 7 | class FuzzySearchDemo extends React.Component { 8 | constructor(props) { 9 | super(props); 10 | this.state = { 11 | loading: false 12 | }; 13 | } 14 | 15 | getChildContext() { 16 | return { form: this.props.form }; 17 | } 18 | 19 | onSubmit(){ 20 | this.props.form.validateFieldsAndScroll({ force: true }, (errors, values) => { 21 | if (errors) {return values;} 22 | this.setState({loading: true}); 23 | setTimeout(() => {this.setState({loading: false});}, 2000); 24 | }); 25 | } 26 | 27 | render(){ 28 | 29 | this.props.form.config = config; 30 | 31 | return
32 | { 33 | return `${item.en}(${item.name} ${item.location}人 今年 ${item.age} 岁)`; 34 | }}/> 35 | 36 | 37 | 38 | ; 39 | } 40 | } 41 | 42 | FuzzySearchDemo.childContextTypes = { 43 | form: React.PropTypes.object.isRequired 44 | }; 45 | 46 | export default createForm()(FuzzySearchDemo); 47 | 48 | -------------------------------------------------------------------------------- /examples/components/FuzzySearch/Demo01/config.js: -------------------------------------------------------------------------------- 1 | 2 | import { util } from 'antd-easy'; 3 | import { URL } from '../../../constants'; 4 | import Fetch from '../../../fetch'; 5 | 6 | const layout = { 7 | labelCol: { span: 4 }, 8 | wrapperCol: { span: 16 } 9 | }; 10 | 11 | export default { 12 | layout, 13 | user: { 14 | type: 'FuzzySearch', 15 | formItemAttr: { 16 | label: '用户', 17 | required: true 18 | }, 19 | fieldAttr: { 20 | showSearch: true, 21 | placeholder: '请输入用户邮箱前缀', 22 | notFoundContent: '', 23 | defaultActiveFirstOption: false, 24 | showArrow: false, 25 | filterOption: util.filterOptionByChildren, 26 | size: 'large', 27 | style: {width: '100%'} 28 | }, 29 | keyField: 'name', 30 | fuzzySearch: (keyword, callback) => { 31 | Fetch(URL.search_user + '?keyword=' + keyword) 32 | .then(res => res.json()) 33 | .then(res => { 34 | callback(res); 35 | }); 36 | }, 37 | accurateSearch: (value, callback) => { 38 | Fetch(URL.search_user_by_prefix.replace('{prefix}', value)) 39 | .then(res => res.json()) 40 | .then(res => { 41 | callback(res); 42 | }); 43 | }, 44 | // layout: {}, 45 | error: { 46 | message: '请输入用户' 47 | } 48 | } 49 | }; -------------------------------------------------------------------------------- /examples/components/FuzzySearch/Demo01/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Component from './component'; 3 | import Html from '../../../Html'; 4 | 5 | const basePath = 'FuzzySearch/Demo01/'; 6 | 7 | class Container extends React.Component { 8 | 9 | render(){ 10 | return 14 | 15 | ; 16 | } 17 | } 18 | 19 | export default Container; 20 | 21 | -------------------------------------------------------------------------------- /examples/components/FuzzySearch/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Demo01 from './Demo01'; 3 | 4 | class FuzzySearchDemo extends React.Component { 5 | 6 | render(){ 7 | return
8 | 9 |
; 10 | } 11 | } 12 | 13 | export default FuzzySearchDemo; 14 | 15 | -------------------------------------------------------------------------------- /examples/constants.js: -------------------------------------------------------------------------------- 1 | 2 | export const baseURL = 'http://localhost:3100/api/'; 3 | 4 | export const URL = { 5 | search_user: baseURL + 'users', 6 | search_user_by_prefix: baseURL + 'users/{prefix}' 7 | }; 8 | -------------------------------------------------------------------------------- /examples/fetch.js: -------------------------------------------------------------------------------- 1 | import fetch from 'isomorphic-fetch'; 2 | 3 | module.exports = function (url, option) { 4 | return fetch(url, option) 5 | .then((res) => { 6 | if (res.status >= 300) { 7 | if(res.status === 401){ 8 | res.json().then((res) => { 9 | return res; 10 | }); 11 | } 12 | if(res.status === 403){ 13 | res.json().then((res) => { 14 | return res; 15 | }); 16 | } 17 | if(res.status === 400){ 18 | // return res; 19 | res.json().then((res) => { 20 | return res; 21 | }); 22 | } 23 | throw new Error(res); 24 | } 25 | return res; 26 | }); 27 | }; 28 | 29 | -------------------------------------------------------------------------------- /examples/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Antd-Easy 6 | 7 | 8 |
9 | 10 | 11 | -------------------------------------------------------------------------------- /examples/style.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Antd-Easy exapmles style 3 | * ttghost@126.com 4 | */ 5 | 6 | /* base style */ 7 | .mt10{margin-top:10px;} 8 | .mt20{margin-top:20px;} 9 | .mr10{margin-right:10px;} 10 | .mr20{margin-right:20px;} 11 | .mb10{margin-bottom:10px;} 12 | .mb20{margin-bottom:20px;} 13 | .ml10{margin-left:10px;} 14 | .ml20{margin-left:20px;} 15 | 16 | .pt10{padding-top:10px;} 17 | .pt20{padding-top:20px;} 18 | .pr10{padding-right:10px;} 19 | .pr20{padding-right:20px;} 20 | .pb10{padding-bottom:10px;} 21 | .pb20{padding-bottom:20px;} 22 | .pl10{padding-left:10px;} 23 | .pl20{padding-left:20px;} 24 | 25 | .f12{font-size:12px;} 26 | .f13{font-size:13px;} 27 | .f14{font-size:14px;} 28 | .f15{font-size:15px;} 29 | .f16{font-size:16px;} 30 | .f18{font-size:18px;} 31 | .f20{font-size:20px;} 32 | .f24{font-size:24px;} 33 | .f28{font-size:28px;} 34 | .f32{font-size:32px;} 35 | .f36{font-size:36px;} 36 | 37 | .text-left{text-align:left;} 38 | .text-center{text-align:center;} 39 | .text-right{text-align:right;} 40 | 41 | .float-left{float:left;} 42 | .float-right{float:right;} 43 | .clearfix{ 44 | &:after{ 45 | display:block; 46 | content:''; 47 | height:0; 48 | line-height: 0; 49 | visibility: hidden; 50 | clear:both; 51 | } 52 | } 53 | 54 | 55 | /* common style */ 56 | .antd-easy-h1, .antd-easy-h2{ 57 | margin-top:22px; 58 | margin-bottom:16px; 59 | } 60 | .antd-easy-h3, .antd-easy-h4{ 61 | margin-top:16px; 62 | margin-bottom:10px; 63 | } 64 | .antd-easy-h5, .antd-easy-h6{ 65 | margin-top:12px; 66 | margin-bottom:6px; 67 | } 68 | .antd-easy-h1{font-size: 24px;} 69 | .antd-easy-h2{font-size: 22px;} 70 | .antd-easy-h3{font-size: 20px;} 71 | .antd-easy-h4{font-size: 18px;} 72 | .antd-easy-h5{font-size: 16px;} 73 | .antd-easy-h6{font-size: 14px;} 74 | 75 | .antd-easy-content{ 76 | margin-bottom:16px; 77 | } 78 | 79 | .bg-white{background-color:#fff;} 80 | 81 | 82 | 83 | /* pages style */ 84 | 85 | body{ 86 | font-size:14px; 87 | } 88 | pre{ 89 | white-space: pre-wrap; 90 | } 91 | 92 | .antd-easy-header{ 93 | color:#fff; 94 | font-size:18px; 95 | a{ 96 | color:#fff; 97 | } 98 | } 99 | 100 | /* HTML component */ 101 | .antd-easy-code-container{ 102 | font-size:12px; 103 | } 104 | 105 | /* default page */ 106 | 107 | .demo-item-container{ 108 | border:1px solid #eee; 109 | padding:30px 16px; 110 | border-radius:5px; 111 | transition:.5s ease all; 112 | margin-bottom:30px; 113 | &:hover{ 114 | box-shadow: 2px 3px 10px rgba(0,0,0,.1); 115 | } 116 | } 117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /lib/FormItemCascader/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _style3 = require('antd/lib/cascader/style'); 8 | 9 | var _cascader = require('antd/lib/cascader'); 10 | 11 | var _cascader2 = _interopRequireDefault(_cascader); 12 | 13 | var _style4 = require('antd/lib/form/style'); 14 | 15 | var _form = require('antd/lib/form'); 16 | 17 | var _form2 = _interopRequireDefault(_form); 18 | 19 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; 20 | 21 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 22 | 23 | var _react = require('react'); 24 | 25 | var _react2 = _interopRequireDefault(_react); 26 | 27 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 28 | 29 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 30 | 31 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 32 | 33 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 34 | 35 | var FormItem = _form2.default.Item; 36 | 37 | var FormItemCascader = function (_React$Component) { 38 | _inherits(FormItemCascader, _React$Component); 39 | 40 | function FormItemCascader() { 41 | _classCallCheck(this, FormItemCascader); 42 | 43 | return _possibleConstructorReturn(this, (FormItemCascader.__proto__ || Object.getPrototypeOf(FormItemCascader)).apply(this, arguments)); 44 | } 45 | 46 | _createClass(FormItemCascader, [{ 47 | key: 'render', 48 | value: function render() { 49 | var form = this.context.form; 50 | var _props = this.props, 51 | field = _props.field, 52 | options = _props.options, 53 | onChange = _props.onChange; 54 | var layout = form.config.layout; 55 | var _form$config$field = form.config[field], 56 | formItemAttr = _form$config$field.formItemAttr, 57 | fieldAttr = _form$config$field.fieldAttr, 58 | error = _form$config$field.error; 59 | var getFieldDecorator = form.getFieldDecorator; 60 | 61 | var fieldProps = getFieldDecorator(field, { 62 | rules: [{ required: formItemAttr.required, message: error.message }] 63 | }); 64 | 65 | var fieldOptions = form.config[field].options; 66 | var _options = options ? options : fieldOptions; 67 | 68 | var fieldLayout = form.config[field].layout; 69 | var _layout = fieldLayout || layout; 70 | 71 | return _react2.default.createElement( 72 | FormItem, 73 | _extends({}, _layout, formItemAttr), 74 | fieldProps(_react2.default.createElement(_cascader2.default, _extends({}, fieldAttr, { options: _options, onChange: onChange }))) 75 | ); 76 | } 77 | }]); 78 | 79 | return FormItemCascader; 80 | }(_react2.default.Component); 81 | 82 | FormItemCascader.contextTypes = { 83 | form: _react2.default.PropTypes.object.isRequired 84 | }; 85 | 86 | exports.default = FormItemCascader; -------------------------------------------------------------------------------- /lib/FormItemCheckboxGroup/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _style3 = require('antd/lib/checkbox/style'); 8 | 9 | var _checkbox = require('antd/lib/checkbox'); 10 | 11 | var _checkbox2 = _interopRequireDefault(_checkbox); 12 | 13 | var _style4 = require('antd/lib/form/style'); 14 | 15 | var _form = require('antd/lib/form'); 16 | 17 | var _form2 = _interopRequireDefault(_form); 18 | 19 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; 20 | 21 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 22 | 23 | var _react = require('react'); 24 | 25 | var _react2 = _interopRequireDefault(_react); 26 | 27 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 28 | 29 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 30 | 31 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 32 | 33 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 34 | 35 | var FormItem = _form2.default.Item; 36 | var CheckboxGroup = _checkbox2.default.Group; 37 | 38 | var FormItemCheckboxGroup = function (_React$Component) { 39 | _inherits(FormItemCheckboxGroup, _React$Component); 40 | 41 | function FormItemCheckboxGroup(props) { 42 | _classCallCheck(this, FormItemCheckboxGroup); 43 | 44 | return _possibleConstructorReturn(this, (FormItemCheckboxGroup.__proto__ || Object.getPrototypeOf(FormItemCheckboxGroup)).call(this, props)); 45 | } 46 | 47 | _createClass(FormItemCheckboxGroup, [{ 48 | key: 'render', 49 | value: function render() { 50 | var form = this.context.form; 51 | var _props = this.props, 52 | field = _props.field, 53 | onChange = _props.onChange; 54 | var layout = form.config.layout; 55 | var _form$config$field = form.config[field], 56 | formItemAttr = _form$config$field.formItemAttr, 57 | fieldAttr = _form$config$field.fieldAttr, 58 | error = _form$config$field.error; 59 | var getFieldDecorator = form.getFieldDecorator; 60 | 61 | var fieldProps = getFieldDecorator(field, { 62 | rules: [{ required: formItemAttr.required, message: error.message }] 63 | }); 64 | 65 | // 相关options 必须为对象组成的数组,如 [{label: '北京', value: 'beijing'}]; 66 | var propsOptions = this.props.options; 67 | var configOptions = form.config[field].options; 68 | var options = Array.isArray(propsOptions) ? propsOptions : configOptions || []; 69 | 70 | var fieldLayout = form.config[field].layout; 71 | var _layout = fieldLayout || layout; 72 | 73 | return _react2.default.createElement( 74 | FormItem, 75 | _extends({}, _layout, formItemAttr), 76 | fieldProps(_react2.default.createElement(CheckboxGroup, _extends({}, fieldAttr, { options: options, onChange: onChange }))) 77 | ); 78 | } 79 | }]); 80 | 81 | return FormItemCheckboxGroup; 82 | }(_react2.default.Component); 83 | 84 | FormItemCheckboxGroup.contextTypes = { 85 | form: _react2.default.PropTypes.object.isRequired 86 | }; 87 | 88 | exports.default = FormItemCheckboxGroup; -------------------------------------------------------------------------------- /lib/FormItemInput/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _style3 = require('antd/lib/input/style'); 8 | 9 | var _input = require('antd/lib/input'); 10 | 11 | var _input2 = _interopRequireDefault(_input); 12 | 13 | var _style4 = require('antd/lib/form/style'); 14 | 15 | var _form = require('antd/lib/form'); 16 | 17 | var _form2 = _interopRequireDefault(_form); 18 | 19 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; 20 | 21 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 22 | 23 | var _react = require('react'); 24 | 25 | var _react2 = _interopRequireDefault(_react); 26 | 27 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 28 | 29 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 30 | 31 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 32 | 33 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 34 | 35 | var FormItem = _form2.default.Item; 36 | 37 | var FormItemInput = function (_React$Component) { 38 | _inherits(FormItemInput, _React$Component); 39 | 40 | function FormItemInput(props) { 41 | _classCallCheck(this, FormItemInput); 42 | 43 | return _possibleConstructorReturn(this, (FormItemInput.__proto__ || Object.getPrototypeOf(FormItemInput)).call(this, props)); 44 | } 45 | 46 | _createClass(FormItemInput, [{ 47 | key: 'render', 48 | value: function render() { 49 | var form = this.context.form; 50 | var _props = this.props, 51 | field = _props.field, 52 | onChange = _props.onChange; 53 | var layout = form.config.layout; 54 | var _form$config$field = form.config[field], 55 | formItemAttr = _form$config$field.formItemAttr, 56 | fieldAttr = _form$config$field.fieldAttr, 57 | error = _form$config$field.error; 58 | var getFieldDecorator = form.getFieldDecorator; 59 | 60 | var fieldProps = getFieldDecorator(field, { 61 | rules: [{ required: formItemAttr.required, message: error.message }] 62 | }); 63 | 64 | var fieldLayout = form.config[field].layout; 65 | var _layout = fieldLayout || layout; 66 | 67 | return _react2.default.createElement( 68 | FormItem, 69 | _extends({}, _layout, formItemAttr), 70 | fieldProps(_react2.default.createElement(_input2.default, _extends({}, fieldAttr, { onChange: onChange }))) 71 | ); 72 | } 73 | }]); 74 | 75 | return FormItemInput; 76 | }(_react2.default.Component); 77 | 78 | FormItemInput.contextTypes = { 79 | form: _react2.default.PropTypes.object.isRequired 80 | }; 81 | 82 | exports.default = FormItemInput; -------------------------------------------------------------------------------- /lib/FormItemNoLabel/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _style2 = require('antd/lib/form/style'); 8 | 9 | var _form = require('antd/lib/form'); 10 | 11 | var _form2 = _interopRequireDefault(_form); 12 | 13 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; 14 | 15 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 16 | 17 | var _react = require('react'); 18 | 19 | var _react2 = _interopRequireDefault(_react); 20 | 21 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 22 | 23 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 24 | 25 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 26 | 27 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 28 | 29 | var FormItem = _form2.default.Item; 30 | 31 | var FormItemNoLabel = function (_React$Component) { 32 | _inherits(FormItemNoLabel, _React$Component); 33 | 34 | function FormItemNoLabel(props) { 35 | _classCallCheck(this, FormItemNoLabel); 36 | 37 | return _possibleConstructorReturn(this, (FormItemNoLabel.__proto__ || Object.getPrototypeOf(FormItemNoLabel)).call(this, props)); 38 | } 39 | 40 | _createClass(FormItemNoLabel, [{ 41 | key: 'render', 42 | value: function render() { 43 | var form = this.context.form; 44 | var layout = form.config.layout; 45 | 46 | 47 | return _react2.default.createElement( 48 | FormItem, 49 | _extends({ label: ' ', colon: false }, layout), 50 | this.props.children 51 | ); 52 | } 53 | }]); 54 | 55 | return FormItemNoLabel; 56 | }(_react2.default.Component); 57 | 58 | FormItemNoLabel.contextTypes = { 59 | form: _react2.default.PropTypes.object.isRequired 60 | }; 61 | 62 | exports.default = FormItemNoLabel; -------------------------------------------------------------------------------- /lib/FormItemRadioGroup/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _style3 = require('antd/lib/radio/style'); 8 | 9 | var _radio = require('antd/lib/radio'); 10 | 11 | var _radio2 = _interopRequireDefault(_radio); 12 | 13 | var _style4 = require('antd/lib/form/style'); 14 | 15 | var _form = require('antd/lib/form'); 16 | 17 | var _form2 = _interopRequireDefault(_form); 18 | 19 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; 20 | 21 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 22 | 23 | var _react = require('react'); 24 | 25 | var _react2 = _interopRequireDefault(_react); 26 | 27 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 28 | 29 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 30 | 31 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 32 | 33 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 34 | 35 | var FormItem = _form2.default.Item; 36 | var RadioGroup = _radio2.default.Group; 37 | 38 | var FormItemRadioGroup = function (_React$Component) { 39 | _inherits(FormItemRadioGroup, _React$Component); 40 | 41 | function FormItemRadioGroup(props) { 42 | _classCallCheck(this, FormItemRadioGroup); 43 | 44 | return _possibleConstructorReturn(this, (FormItemRadioGroup.__proto__ || Object.getPrototypeOf(FormItemRadioGroup)).call(this, props)); 45 | } 46 | 47 | _createClass(FormItemRadioGroup, [{ 48 | key: 'render', 49 | value: function render() { 50 | var form = this.context.form; 51 | var _props = this.props, 52 | field = _props.field, 53 | onChange = _props.onChange; 54 | var layout = form.config.layout; 55 | var _form$config$field = form.config[field], 56 | formItemAttr = _form$config$field.formItemAttr, 57 | fieldAttr = _form$config$field.fieldAttr, 58 | error = _form$config$field.error; 59 | var getFieldDecorator = form.getFieldDecorator; 60 | 61 | var fieldProps = getFieldDecorator(field, { 62 | rules: [{ required: formItemAttr.required, message: error.message }] 63 | }); 64 | 65 | var fieldLayout = form.config[field].layout; 66 | var _layout = fieldLayout || layout; 67 | // 相关options 必须为对象组成的数组,如 [{label: '北京', value: 'beijing'}]; 68 | var propsOptions = this.props.options; 69 | var configOptions = form.config[field].options; 70 | var options = Array.isArray(propsOptions) ? propsOptions : configOptions || []; 71 | 72 | return _react2.default.createElement( 73 | FormItem, 74 | _extends({}, _layout, formItemAttr), 75 | fieldProps(_react2.default.createElement( 76 | RadioGroup, 77 | _extends({}, fieldAttr, { onChange: onChange }), 78 | options.map(function (option, k) { 79 | return _react2.default.createElement( 80 | _radio2.default, 81 | { key: k, value: option.value }, 82 | option.label 83 | ); 84 | }) 85 | )) 86 | ); 87 | } 88 | }]); 89 | 90 | return FormItemRadioGroup; 91 | }(_react2.default.Component); 92 | 93 | FormItemRadioGroup.contextTypes = { 94 | form: _react2.default.PropTypes.object.isRequired 95 | }; 96 | 97 | exports.default = FormItemRadioGroup; -------------------------------------------------------------------------------- /lib/FormItemSelect/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _style3 = require('antd/lib/select/style'); 8 | 9 | var _select = require('antd/lib/select'); 10 | 11 | var _select2 = _interopRequireDefault(_select); 12 | 13 | var _style4 = require('antd/lib/form/style'); 14 | 15 | var _form = require('antd/lib/form'); 16 | 17 | var _form2 = _interopRequireDefault(_form); 18 | 19 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; 20 | 21 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 22 | 23 | var _react = require('react'); 24 | 25 | var _react2 = _interopRequireDefault(_react); 26 | 27 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 28 | 29 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 30 | 31 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 32 | 33 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 34 | 35 | var FormItem = _form2.default.Item; 36 | var Option = _select2.default.Option; 37 | 38 | var FormItemSelect = function (_React$Component) { 39 | _inherits(FormItemSelect, _React$Component); 40 | 41 | function FormItemSelect(props) { 42 | _classCallCheck(this, FormItemSelect); 43 | 44 | return _possibleConstructorReturn(this, (FormItemSelect.__proto__ || Object.getPrototypeOf(FormItemSelect)).call(this, props)); 45 | } 46 | 47 | _createClass(FormItemSelect, [{ 48 | key: 'render', 49 | value: function render() { 50 | var form = this.context.form; 51 | var _props = this.props, 52 | field = _props.field, 53 | onChange = _props.onChange, 54 | render = _props.render; 55 | var layout = form.config.layout; 56 | var _form$config$field = form.config[field], 57 | _form$config$field$fo = _form$config$field.formItemAttr, 58 | formItemAttr = _form$config$field$fo === undefined ? {} : _form$config$field$fo, 59 | _form$config$field$fi = _form$config$field.fieldAttr, 60 | fieldAttr = _form$config$field$fi === undefined ? {} : _form$config$field$fi, 61 | _form$config$field$er = _form$config$field.error, 62 | error = _form$config$field$er === undefined ? {} : _form$config$field$er, 63 | keyField = _form$config$field.keyField, 64 | valueField = _form$config$field.valueField; 65 | var getFieldDecorator = form.getFieldDecorator; 66 | 67 | var fieldProps = getFieldDecorator(field, { 68 | rules: [{ required: formItemAttr.required, message: error.message }] 69 | }); 70 | 71 | var fieldLayout = form.config[field].layout; 72 | var _layout = fieldLayout || layout; 73 | // 相关options 必须为对象组成的数组,如 [{label: '北京', value: 'beijing'}]; 74 | var propsOptions = this.props.options; 75 | var configOptions = form.config[field].options || []; 76 | var options = Array.isArray(propsOptions) ? propsOptions : configOptions; 77 | 78 | return _react2.default.createElement( 79 | FormItem, 80 | _extends({}, _layout, formItemAttr), 81 | fieldProps(_react2.default.createElement( 82 | _select2.default, 83 | _extends({}, fieldAttr, { onChange: onChange }), 84 | options.map(function (item, k) { 85 | var value = item[keyField] !== undefined ? item[keyField] + '' : item; 86 | var text = item[valueField] !== undefined ? item[valueField] : item; 87 | var option = typeof render === 'function' ? render(item, k) : text; 88 | 89 | return _react2.default.createElement( 90 | Option, 91 | { key: k, value: value }, 92 | option 93 | ); 94 | }) 95 | )) 96 | ); 97 | } 98 | }]); 99 | 100 | return FormItemSelect; 101 | }(_react2.default.Component); 102 | 103 | FormItemSelect.contextTypes = { 104 | form: _react2.default.PropTypes.object.isRequired 105 | }; 106 | 107 | exports.default = FormItemSelect; -------------------------------------------------------------------------------- /lib/FuzzySearch/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _style3 = require('antd/lib/select/style'); 8 | 9 | var _select = require('antd/lib/select'); 10 | 11 | var _select2 = _interopRequireDefault(_select); 12 | 13 | var _style4 = require('antd/lib/form/style'); 14 | 15 | var _form = require('antd/lib/form'); 16 | 17 | var _form2 = _interopRequireDefault(_form); 18 | 19 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; 20 | 21 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 22 | 23 | var _react = require('react'); 24 | 25 | var _react2 = _interopRequireDefault(_react); 26 | 27 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 28 | 29 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 30 | 31 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 32 | 33 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 34 | 35 | var FormItem = _form2.default.Item; 36 | var Option = _select2.default.Option; 37 | var timer = void 0; 38 | 39 | var FuzzySearch = function (_React$Component) { 40 | _inherits(FuzzySearch, _React$Component); 41 | 42 | function FuzzySearch(props) { 43 | _classCallCheck(this, FuzzySearch); 44 | 45 | var _this = _possibleConstructorReturn(this, (FuzzySearch.__proto__ || Object.getPrototypeOf(FuzzySearch)).call(this, props)); 46 | 47 | _this.state = { 48 | options: [] 49 | }; 50 | return _this; 51 | } 52 | 53 | _createClass(FuzzySearch, [{ 54 | key: 'componentWillReceiveProps', 55 | value: function componentWillReceiveProps() { 56 | var field = this.props.field; 57 | var getFieldValue = this.context.form.getFieldValue; 58 | 59 | var value = getFieldValue(field); 60 | 61 | this.onChange(value); 62 | } 63 | }, { 64 | key: 'onFuzzySearch', 65 | value: function onFuzzySearch(keyword) { 66 | var _this2 = this; 67 | 68 | var form = this.context.form; 69 | var field = this.props.field; 70 | var fuzzySearch = form.config[field].fuzzySearch; 71 | 72 | 73 | if (typeof fuzzySearch === 'function') { 74 | fuzzySearch(keyword, function (res) { 75 | _this2.setState({ options: res }); 76 | }); 77 | } 78 | } 79 | }, { 80 | key: 'onSearch', 81 | value: function onSearch(keyword) { 82 | var _this3 = this; 83 | 84 | if (keyword) { 85 | if (timer) { 86 | clearTimeout(timer); 87 | timer = null; 88 | } 89 | timer = setTimeout(function () { 90 | _this3.onFuzzySearch(keyword.toLowerCase()); 91 | }, 100); 92 | } 93 | } 94 | }, { 95 | key: 'onChange', 96 | value: function onChange(value) { 97 | var _this4 = this; 98 | 99 | if (value) { 100 | var form = this.context.form; 101 | var field = this.props.field; 102 | var accurateSearch = form.config[field].accurateSearch; 103 | 104 | 105 | accurateSearch(value, function (res) { 106 | _this4.setState({ options: [res] }); 107 | }); 108 | } 109 | } 110 | }, { 111 | key: 'render', 112 | value: function render() { 113 | var form = this.context.form; 114 | var _props = this.props, 115 | field = _props.field, 116 | render = _props.render; 117 | var layout = form.config.layout; 118 | var _form$config$field = form.config[field], 119 | formItemAttr = _form$config$field.formItemAttr, 120 | fieldAttr = _form$config$field.fieldAttr, 121 | error = _form$config$field.error, 122 | keyField = _form$config$field.keyField, 123 | valueField = _form$config$field.valueField; 124 | var getFieldDecorator = form.getFieldDecorator; 125 | 126 | var fieldProps = getFieldDecorator(field, { 127 | rules: [{ required: formItemAttr.required, message: error.message }] 128 | }); 129 | var fieldLayout = form.config[field].layout; 130 | var _layout = fieldLayout || layout; 131 | var _state$options = this.state.options, 132 | options = _state$options === undefined ? [] : _state$options; 133 | 134 | 135 | return _react2.default.createElement( 136 | FormItem, 137 | _extends({}, _layout, formItemAttr), 138 | fieldProps(_react2.default.createElement( 139 | _select2.default, 140 | _extends({}, fieldAttr, { onSearch: this.onSearch.bind(this), onChange: this.onChange.bind(this) }), 141 | options.map(function (item, k) { 142 | var value = item[keyField] !== undefined ? item[keyField] + '' : item; 143 | var text = item[valueField] !== undefined ? item[valueField] : item; 144 | var option = typeof render === 'function' ? render(item, k) : text; 145 | 146 | return _react2.default.createElement( 147 | Option, 148 | { key: k, value: value }, 149 | option 150 | ); 151 | }) 152 | )) 153 | ); 154 | } 155 | }]); 156 | 157 | return FuzzySearch; 158 | }(_react2.default.Component); 159 | 160 | FuzzySearch.contextTypes = { 161 | form: _react2.default.PropTypes.object.isRequired 162 | }; 163 | 164 | exports.default = FuzzySearch; -------------------------------------------------------------------------------- /lib/config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.FuzzySearch = exports.RadioGroup = exports.CheckboxGroup = exports.Cascader = exports.Select = exports.Input = undefined; 7 | 8 | var _util = require('./util'); 9 | 10 | var _util2 = _interopRequireDefault(_util); 11 | 12 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 13 | 14 | var Input = exports.Input = { 15 | type: 'Input', 16 | formItemAttr: { 17 | label: ' ', 18 | required: false 19 | }, 20 | fieldAttr: { 21 | placeholder: '请填写', 22 | type: 'text' 23 | }, 24 | error: { 25 | message: '请输入' 26 | } 27 | }; 28 | 29 | var Select = exports.Select = { 30 | type: 'Select', 31 | formItemAttr: { 32 | label: ' ', 33 | required: false 34 | }, 35 | fieldAttr: { 36 | placeholder: '请选择' 37 | }, 38 | keyField: 'value', 39 | valueField: 'label', 40 | error: { 41 | message: '请选择' 42 | } 43 | }; 44 | 45 | var Cascader = exports.Cascader = { 46 | type: 'Cascader', 47 | formItemAttr: { 48 | label: ' ', 49 | required: false 50 | }, 51 | fieldAttr: { 52 | placeholder: '请选择', 53 | allowClear: false, 54 | showSearch: true, 55 | size: 'large', 56 | style: { width: '100%' }, 57 | notFoundContent: '没有找到' 58 | }, 59 | error: { 60 | message: '请选择' 61 | } 62 | }; 63 | 64 | var CheckboxGroup = exports.CheckboxGroup = { 65 | type: 'CheckboxGroup', 66 | formItemAttr: { 67 | label: ' ', 68 | required: false 69 | }, 70 | fieldAttr: {}, 71 | error: { 72 | message: '请选择' 73 | } 74 | }; 75 | 76 | var RadioGroup = exports.RadioGroup = { 77 | type: 'RadioGroup', 78 | formItemAttr: { 79 | label: ' ', 80 | required: false 81 | }, 82 | fieldAttr: {}, 83 | error: { 84 | message: '请选择' 85 | } 86 | }; 87 | 88 | var FuzzySearch = exports.FuzzySearch = { 89 | type: 'FuzzySearch', 90 | formItemAttr: { 91 | label: ' ', 92 | required: false 93 | }, 94 | fieldAttr: { 95 | showSearch: true, 96 | placeholder: '请输入关键字', 97 | notFoundContent: '', 98 | defaultActiveFirstOption: false, 99 | showArrow: false, 100 | filterOption: _util2.default.filterOptionByChildren, 101 | size: 'large', 102 | style: { width: '100%' } 103 | }, 104 | keyField: 'name', 105 | fuzzySearch: function fuzzySearch(keyword, callback) { 106 | _util2.default.fetch('/').then(function (res) { 107 | return res.json(); 108 | }).then(function (res) { 109 | callback(res); 110 | }); 111 | }, 112 | accurateSearch: function accurateSearch(value, callback) { 113 | _util2.default.fetch('/').then(function (res) { 114 | return res.json(); 115 | }).then(function (res) { 116 | callback(res); 117 | }); 118 | }, 119 | // formItemLayout: {}, 120 | error: { 121 | message: '请输入用户' 122 | } 123 | }; -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.version = exports.Upload = exports.Mention = exports.Tooltip = exports.Timeline = exports.TimePicker = exports.Tag = exports.Tabs = exports.TreeSelect = exports.Tree = exports.Transfer = exports.Table = exports.Switch = exports.Steps = exports.Spin = exports.Slider = exports.Select = exports.Row = exports.Rate = exports.Radio = exports.Progress = exports.Popover = exports.Popconfirm = exports.Pagination = exports.notification = exports.Modal = exports.Menu = exports.message = exports.LocaleProvider = exports.Layout = exports.InputNumber = exports.Input = exports.Icon = exports.Form = exports.Dropdown = exports.DatePicker = exports.Col = exports.Checkbox = exports.Cascader = exports.Carousel = exports.Collapse = exports.Card = exports.Calendar = exports.Button = exports.Breadcrumb = exports.Badge = exports.BackTop = exports.Alert = exports.AutoComplete = exports.Anchor = exports.Affix = exports.FuzzySearch = exports.FormItemSelect = exports.FormItemNoLabel = exports.FormItemCascader = exports.FormItemRadioGroup = exports.FormItemCheckboxGroup = exports.FormItemInput = exports.util = undefined; 7 | 8 | var _FormItemInput = require('./FormItemInput'); 9 | 10 | var _FormItemInput2 = _interopRequireDefault(_FormItemInput); 11 | 12 | var _FormItemCheckboxGroup = require('./FormItemCheckboxGroup'); 13 | 14 | var _FormItemCheckboxGroup2 = _interopRequireDefault(_FormItemCheckboxGroup); 15 | 16 | var _FormItemRadioGroup = require('./FormItemRadioGroup'); 17 | 18 | var _FormItemRadioGroup2 = _interopRequireDefault(_FormItemRadioGroup); 19 | 20 | var _FormItemCascader = require('./FormItemCascader'); 21 | 22 | var _FormItemCascader2 = _interopRequireDefault(_FormItemCascader); 23 | 24 | var _FormItemNoLabel = require('./FormItemNoLabel'); 25 | 26 | var _FormItemNoLabel2 = _interopRequireDefault(_FormItemNoLabel); 27 | 28 | var _FormItemSelect = require('./FormItemSelect'); 29 | 30 | var _FormItemSelect2 = _interopRequireDefault(_FormItemSelect); 31 | 32 | var _FuzzySearch = require('./FuzzySearch'); 33 | 34 | var _FuzzySearch2 = _interopRequireDefault(_FuzzySearch); 35 | 36 | var _util = require('./util'); 37 | 38 | var util = _interopRequireWildcard(_util); 39 | 40 | var _affix = require('antd/lib/affix'); 41 | 42 | var _affix2 = _interopRequireDefault(_affix); 43 | 44 | var _anchor = require('antd/lib/anchor'); 45 | 46 | var _anchor2 = _interopRequireDefault(_anchor); 47 | 48 | var _autoComplete = require('antd/lib/auto-complete'); 49 | 50 | var _autoComplete2 = _interopRequireDefault(_autoComplete); 51 | 52 | var _alert = require('antd/lib/alert'); 53 | 54 | var _alert2 = _interopRequireDefault(_alert); 55 | 56 | var _backTop = require('antd/lib/back-top'); 57 | 58 | var _backTop2 = _interopRequireDefault(_backTop); 59 | 60 | var _badge = require('antd/lib/badge'); 61 | 62 | var _badge2 = _interopRequireDefault(_badge); 63 | 64 | var _breadcrumb = require('antd/lib/breadcrumb'); 65 | 66 | var _breadcrumb2 = _interopRequireDefault(_breadcrumb); 67 | 68 | var _button = require('antd/lib/button'); 69 | 70 | var _button2 = _interopRequireDefault(_button); 71 | 72 | var _calendar = require('antd/lib/calendar'); 73 | 74 | var _calendar2 = _interopRequireDefault(_calendar); 75 | 76 | var _card = require('antd/lib/card'); 77 | 78 | var _card2 = _interopRequireDefault(_card); 79 | 80 | var _collapse = require('antd/lib/collapse'); 81 | 82 | var _collapse2 = _interopRequireDefault(_collapse); 83 | 84 | var _carousel = require('antd/lib/carousel'); 85 | 86 | var _carousel2 = _interopRequireDefault(_carousel); 87 | 88 | var _cascader = require('antd/lib/cascader'); 89 | 90 | var _cascader2 = _interopRequireDefault(_cascader); 91 | 92 | var _checkbox = require('antd/lib/checkbox'); 93 | 94 | var _checkbox2 = _interopRequireDefault(_checkbox); 95 | 96 | var _col = require('antd/lib/col'); 97 | 98 | var _col2 = _interopRequireDefault(_col); 99 | 100 | var _datePicker = require('antd/lib/date-picker'); 101 | 102 | var _datePicker2 = _interopRequireDefault(_datePicker); 103 | 104 | var _dropdown = require('antd/lib/dropdown'); 105 | 106 | var _dropdown2 = _interopRequireDefault(_dropdown); 107 | 108 | var _form = require('antd/lib/form'); 109 | 110 | var _form2 = _interopRequireDefault(_form); 111 | 112 | var _icon = require('antd/lib/icon'); 113 | 114 | var _icon2 = _interopRequireDefault(_icon); 115 | 116 | var _input = require('antd/lib/input'); 117 | 118 | var _input2 = _interopRequireDefault(_input); 119 | 120 | var _inputNumber = require('antd/lib/input-number'); 121 | 122 | var _inputNumber2 = _interopRequireDefault(_inputNumber); 123 | 124 | var _layout = require('antd/lib/layout'); 125 | 126 | var _layout2 = _interopRequireDefault(_layout); 127 | 128 | var _localeProvider = require('antd/lib/locale-provider'); 129 | 130 | var _localeProvider2 = _interopRequireDefault(_localeProvider); 131 | 132 | var _message = require('antd/lib/message'); 133 | 134 | var _message2 = _interopRequireDefault(_message); 135 | 136 | var _menu = require('antd/lib/menu'); 137 | 138 | var _menu2 = _interopRequireDefault(_menu); 139 | 140 | var _modal = require('antd/lib/modal'); 141 | 142 | var _modal2 = _interopRequireDefault(_modal); 143 | 144 | var _notification = require('antd/lib/notification'); 145 | 146 | var _notification2 = _interopRequireDefault(_notification); 147 | 148 | var _pagination = require('antd/lib/pagination'); 149 | 150 | var _pagination2 = _interopRequireDefault(_pagination); 151 | 152 | var _popconfirm = require('antd/lib/popconfirm'); 153 | 154 | var _popconfirm2 = _interopRequireDefault(_popconfirm); 155 | 156 | var _popover = require('antd/lib/popover'); 157 | 158 | var _popover2 = _interopRequireDefault(_popover); 159 | 160 | var _progress = require('antd/lib/progress'); 161 | 162 | var _progress2 = _interopRequireDefault(_progress); 163 | 164 | var _radio = require('antd/lib/radio'); 165 | 166 | var _radio2 = _interopRequireDefault(_radio); 167 | 168 | var _rate = require('antd/lib/rate'); 169 | 170 | var _rate2 = _interopRequireDefault(_rate); 171 | 172 | var _row = require('antd/lib/row'); 173 | 174 | var _row2 = _interopRequireDefault(_row); 175 | 176 | var _select = require('antd/lib/select'); 177 | 178 | var _select2 = _interopRequireDefault(_select); 179 | 180 | var _slider = require('antd/lib/slider'); 181 | 182 | var _slider2 = _interopRequireDefault(_slider); 183 | 184 | var _spin = require('antd/lib/spin'); 185 | 186 | var _spin2 = _interopRequireDefault(_spin); 187 | 188 | var _steps = require('antd/lib/steps'); 189 | 190 | var _steps2 = _interopRequireDefault(_steps); 191 | 192 | var _switch = require('antd/lib/switch'); 193 | 194 | var _switch2 = _interopRequireDefault(_switch); 195 | 196 | var _table = require('antd/lib/table'); 197 | 198 | var _table2 = _interopRequireDefault(_table); 199 | 200 | var _transfer = require('antd/lib/transfer'); 201 | 202 | var _transfer2 = _interopRequireDefault(_transfer); 203 | 204 | var _tree = require('antd/lib/tree'); 205 | 206 | var _tree2 = _interopRequireDefault(_tree); 207 | 208 | var _treeSelect = require('antd/lib/tree-select'); 209 | 210 | var _treeSelect2 = _interopRequireDefault(_treeSelect); 211 | 212 | var _tabs = require('antd/lib/tabs'); 213 | 214 | var _tabs2 = _interopRequireDefault(_tabs); 215 | 216 | var _tag = require('antd/lib/tag'); 217 | 218 | var _tag2 = _interopRequireDefault(_tag); 219 | 220 | var _timePicker = require('antd/lib/time-picker'); 221 | 222 | var _timePicker2 = _interopRequireDefault(_timePicker); 223 | 224 | var _timeline = require('antd/lib/timeline'); 225 | 226 | var _timeline2 = _interopRequireDefault(_timeline); 227 | 228 | var _tooltip = require('antd/lib/tooltip'); 229 | 230 | var _tooltip2 = _interopRequireDefault(_tooltip); 231 | 232 | var _mention = require('antd/lib/mention'); 233 | 234 | var _mention2 = _interopRequireDefault(_mention); 235 | 236 | var _upload = require('antd/lib/upload'); 237 | 238 | var _upload2 = _interopRequireDefault(_upload); 239 | 240 | var _version = require('antd/lib/version/'); 241 | 242 | var _version2 = _interopRequireDefault(_version); 243 | 244 | function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } 245 | 246 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 247 | 248 | exports.util = util; 249 | exports.FormItemInput = _FormItemInput2.default; 250 | exports.FormItemCheckboxGroup = _FormItemCheckboxGroup2.default; 251 | exports.FormItemRadioGroup = _FormItemRadioGroup2.default; 252 | exports.FormItemCascader = _FormItemCascader2.default; 253 | exports.FormItemNoLabel = _FormItemNoLabel2.default; 254 | exports.FormItemSelect = _FormItemSelect2.default; 255 | exports.FuzzySearch = _FuzzySearch2.default; 256 | exports.Affix = _affix2.default; 257 | exports.Anchor = _anchor2.default; 258 | exports.AutoComplete = _autoComplete2.default; 259 | exports.Alert = _alert2.default; 260 | exports.BackTop = _backTop2.default; 261 | exports.Badge = _badge2.default; 262 | exports.Breadcrumb = _breadcrumb2.default; 263 | exports.Button = _button2.default; 264 | exports.Calendar = _calendar2.default; 265 | exports.Card = _card2.default; 266 | exports.Collapse = _collapse2.default; 267 | exports.Carousel = _carousel2.default; 268 | exports.Cascader = _cascader2.default; 269 | exports.Checkbox = _checkbox2.default; 270 | exports.Col = _col2.default; 271 | exports.DatePicker = _datePicker2.default; 272 | exports.Dropdown = _dropdown2.default; 273 | exports.Form = _form2.default; 274 | exports.Icon = _icon2.default; 275 | exports.Input = _input2.default; 276 | exports.InputNumber = _inputNumber2.default; 277 | exports.Layout = _layout2.default; 278 | exports.LocaleProvider = _localeProvider2.default; 279 | exports.message = _message2.default; 280 | exports.Menu = _menu2.default; 281 | exports.Modal = _modal2.default; 282 | exports.notification = _notification2.default; 283 | exports.Pagination = _pagination2.default; 284 | exports.Popconfirm = _popconfirm2.default; 285 | exports.Popover = _popover2.default; 286 | exports.Progress = _progress2.default; 287 | exports.Radio = _radio2.default; 288 | exports.Rate = _rate2.default; 289 | exports.Row = _row2.default; 290 | exports.Select = _select2.default; 291 | exports.Slider = _slider2.default; 292 | exports.Spin = _spin2.default; 293 | exports.Steps = _steps2.default; 294 | exports.Switch = _switch2.default; 295 | exports.Table = _table2.default; 296 | exports.Transfer = _transfer2.default; 297 | exports.Tree = _tree2.default; 298 | exports.TreeSelect = _treeSelect2.default; 299 | exports.Tabs = _tabs2.default; 300 | exports.Tag = _tag2.default; 301 | exports.TimePicker = _timePicker2.default; 302 | exports.Timeline = _timeline2.default; 303 | exports.Tooltip = _tooltip2.default; 304 | exports.Mention = _mention2.default; 305 | exports.Upload = _upload2.default; 306 | exports.version = _version2.default; -------------------------------------------------------------------------------- /lib/util.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.filterOptionByChildren = filterOptionByChildren; 7 | exports.fetch = fetch; 8 | 9 | /* 10 | * 下拉框忽略大小写 11 | */ 12 | function filterOptionByChildren(inputValue, option) { 13 | return option.props.children.toLowerCase().indexOf(inputValue.toLowerCase()) > -1; 14 | } 15 | 16 | function fetch(url, option) { 17 | var defaultHeaders = { 18 | 'Accept': 'application/json', 19 | 'Content-Type': 'application/json' 20 | }; 21 | var originHeaders = Object.assign({}, option.headers); 22 | option.headers = Object.assign({}, defaultHeaders, originHeaders); 23 | return require('isomorphic-fetch')(url, option); 24 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "antd-easy", 3 | "version": "0.4.0", 4 | "description": "基于ant-design封装的业务组件,涉及表单校验、错误提示等复杂交互。技术底层为React.js", 5 | "main": "./lib/index.js", 6 | "scripts": { 7 | "start": "npm run dev", 8 | "dev": "webpack-dev-server --config webpack.dev.js --hot --inline", 9 | "publish": "babel src --out-dir lib --presets=es2015,react", 10 | "server": "node ./server/www" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git@github.com:tt-ghost/antd-easy.git" 15 | }, 16 | "keywords": [ 17 | "antd", 18 | "antd-easy", 19 | "react" 20 | ], 21 | "author": "ttghost@126.com", 22 | "license": "ISC", 23 | "dependencies": { 24 | "antd": "^2.7.0" 25 | }, 26 | "devDependencies": { 27 | "babel-cli": "^6.23.0", 28 | "babel-core": "~6.21.0", 29 | "babel-eslint": "^7.1.1", 30 | "babel-loader": "~6.2.10", 31 | "babel-plugin-import": "^1.1.0", 32 | "babel-preset-es2015": "~6.22.0", 33 | "babel-preset-react": "~6.22.0", 34 | "babel-preset-stage-0": "^6.22.0", 35 | "css-loader": "~0.26.1", 36 | "eslint": "^3.15.0", 37 | "eslint-loader": "^1.6.1", 38 | "eslint-plugin-react": "^6.9.0", 39 | "highlight.js": "^9.9.0", 40 | "history": "^4.5.1", 41 | "html-webpack-plugin": "^2.28.0", 42 | "isomorphic-fetch": "^2.2.1", 43 | "jade": "^1.11.0", 44 | "less": "~2.7.2", 45 | "less-loader": "~2.2.3", 46 | "marked": "^0.3.6", 47 | "react": "~15.4.2", 48 | "react-codemirror": "^0.3.0", 49 | "react-dom": "~15.4.2", 50 | "react-markdown": "^2.4.4", 51 | "react-router": "^3.0.2", 52 | "style-loader": "~0.13.1", 53 | "webpack": "~2.2.0", 54 | "webpack-dev-server": "~2.2.0" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /server/app.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var path = require('path'); 3 | var apis = require('./routes/apis'); 4 | var app = express(); 5 | 6 | // view engine setup 7 | app.set('views', path.join(__dirname, 'views')); 8 | app.set('view engine', 'jade'); 9 | 10 | 11 | // 允许跨域 12 | app.all('*', function(req, res, next) { 13 | res.header('Access-Control-Allow-Origin', '*'); 14 | next(); 15 | }); 16 | 17 | // 终端打log 18 | app.all('*', function(req, res, next){ 19 | console.log('URL: ' + req.path); 20 | next(); 21 | }); 22 | 23 | app.use('/api', apis); 24 | 25 | // catch 404 and forward to error handler 26 | // app.use(function(req, res, next) { 27 | // var err = new Error('Not Found'); 28 | // err.status = 404; 29 | // next(err); 30 | // }); 31 | 32 | // error handlers 33 | 34 | // development error handler 35 | // will print stacktrace 36 | if (app.get('env') === 'development') { 37 | app.use(function(err, req, res, next) { 38 | res.status(err.status || 500); 39 | res.render('error', { 40 | message: err.message, 41 | error: err 42 | }); 43 | }); 44 | } 45 | 46 | // production error handler 47 | // no stacktraces leaked to user 48 | app.use(function(err, req, res, next) { 49 | res.status(err.status || 500); 50 | res.render('error', { 51 | message: err.message, 52 | error: {} 53 | }); 54 | }); 55 | 56 | 57 | module.exports = app; 58 | -------------------------------------------------------------------------------- /server/routes/apis.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | var fs = require('fs'); 4 | var path = require('path'); 5 | var sourceDir = path.join(__dirname, '../../examples/components/'); 6 | var locations = ['北京市', '上海市', '南京市', '广州市', '合肥市', '南昌市', '杭州市', '合肥市', '南昌市', '杭州市']; 7 | var names = ['Tom', 'Jack', 'Lili', 'Jean', 'Lucy', 'Nancy', 'Kim', 'Aaron', 'Abbott', 'Miya']; 8 | 9 | /* GET home page. */ 10 | router.get('/file', function(req, res, next) { 11 | // res.send(req.path) 12 | var filename = req.path.split('/api/file/')[1]; 13 | console.log(req.query.name) 14 | var targetFile = sourceDir + req.query.name; 15 | console.log(targetFile) 16 | readTargetFile(targetFile, function(text){ 17 | res.send(text); 18 | }); 19 | // res.send('index'); 20 | }); 21 | 22 | router.get('/users', function(req, res, next) { 23 | 24 | var kw = req.query.keyword; 25 | var users = '0123456789'.split('').map(function(item, k){ 26 | return { 27 | id: k, 28 | name: kw + k, 29 | en: names[k], 30 | age: (Math.random()*100).toFixed(0), 31 | location: locations[k] 32 | }; 33 | }) 34 | res.send(users); 35 | }); 36 | 37 | router.get('/users/:user', function(req, res, next) { 38 | var userName = req.params.user; 39 | var user = { 40 | id: 1, 41 | name: userName, 42 | en: names[1], 43 | age: (Math.random()*100).toFixed(0), 44 | location: locations[1] 45 | }; 46 | res.send(user); 47 | }); 48 | 49 | 50 | function readTargetFile(targetFile, callback){ 51 | fs.exists(targetFile, function(exists) { 52 | if(exists){ 53 | var file = fs.readFileSync(targetFile, 'utf8', function(err, data){ 54 | if(err) throw new Error(err); 55 | }); 56 | callback(file) 57 | } else { 58 | callback('Not Found!') 59 | } 60 | }); 61 | 62 | } 63 | 64 | module.exports = router; 65 | -------------------------------------------------------------------------------- /server/views/404.jade: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tt-ghost/antd-easy/b0dd0a8d1a54676b35932fd429272176db5038dc/server/views/404.jade -------------------------------------------------------------------------------- /server/views/error.jade: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tt-ghost/antd-easy/b0dd0a8d1a54676b35932fd429272176db5038dc/server/views/error.jade -------------------------------------------------------------------------------- /server/www: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Module dependencies. 5 | */ 6 | 7 | var app = require('./app'); 8 | var debug = require('debug')('tmp:server'); 9 | var http = require('http'); 10 | 11 | /** 12 | * Get port from environment and store in Express. 13 | */ 14 | 15 | var port = normalizePort(process.env.PORT || '3100'); 16 | app.set('port', port); 17 | 18 | /** 19 | * Create HTTP server. 20 | */ 21 | 22 | var server = http.createServer(app); 23 | 24 | /** 25 | * Listen on provided port, on all network interfaces. 26 | */ 27 | 28 | server.listen(port); 29 | server.on('error', onError); 30 | server.on('listening', onListening); 31 | 32 | /** 33 | * Normalize a port into a number, string, or false. 34 | */ 35 | 36 | function normalizePort(val) { 37 | var port = parseInt(val, 10); 38 | 39 | if (isNaN(port)) { 40 | // named pipe 41 | return val; 42 | } 43 | 44 | if (port >= 0) { 45 | // port number 46 | return port; 47 | } 48 | 49 | return false; 50 | } 51 | 52 | /** 53 | * Event listener for HTTP server "error" event. 54 | */ 55 | 56 | function onError(error) { 57 | if (error.syscall !== 'listen') { 58 | throw error; 59 | } 60 | 61 | var bind = typeof port === 'string' 62 | ? 'Pipe ' + port 63 | : 'Port ' + port; 64 | 65 | // handle specific listen errors with friendly messages 66 | switch (error.code) { 67 | case 'EACCES': 68 | console.error(bind + ' requires elevated privileges'); 69 | process.exit(1); 70 | break; 71 | case 'EADDRINUSE': 72 | console.error(bind + ' is already in use'); 73 | process.exit(1); 74 | break; 75 | default: 76 | throw error; 77 | } 78 | } 79 | 80 | /** 81 | * Event listener for HTTP server "listening" event. 82 | */ 83 | 84 | function onListening() { 85 | // var addr = server.address(); 86 | // var bind = typeof addr === 'string' 87 | // ? 'pipe ' + addr 88 | // : 'port ' + addr.port; 89 | // debug('Listening on ' + bind); 90 | } 91 | -------------------------------------------------------------------------------- /src/FormItemCascader/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Form, Cascader } from 'antd'; 3 | 4 | const FormItem = Form.Item; 5 | 6 | class FormItemCascader extends React.Component { 7 | 8 | render(){ 9 | const { form } = this.context; 10 | const { field, options, onChange } = this.props; 11 | const { layout } = form.config; 12 | const { formItemAttr, fieldAttr, error } = form.config[field]; 13 | const { getFieldDecorator } = form; 14 | const fieldProps = getFieldDecorator(field, { 15 | rules: [{required: formItemAttr.required, message: error.message}] 16 | }); 17 | 18 | const fieldOptions = form.config[field].options; 19 | const _options = options ? options : fieldOptions; 20 | 21 | const fieldLayout = form.config[field].layout; 22 | const _layout = fieldLayout || layout; 23 | 24 | return 25 | {fieldProps()} 26 | ; 27 | } 28 | } 29 | 30 | FormItemCascader.contextTypes = { 31 | form: React.PropTypes.object.isRequired 32 | }; 33 | 34 | export default FormItemCascader; 35 | -------------------------------------------------------------------------------- /src/FormItemCheckboxGroup/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Form, Checkbox } from 'antd'; 3 | 4 | const FormItem = Form.Item; 5 | const CheckboxGroup = Checkbox.Group; 6 | 7 | class FormItemCheckboxGroup extends React.Component { 8 | constructor(props) { 9 | super(props); 10 | } 11 | render(){ 12 | 13 | const { form } = this.context; 14 | const { field, onChange } = this.props; 15 | const { layout } = form.config; 16 | const { formItemAttr, fieldAttr, error } = form.config[field]; 17 | const { getFieldDecorator } = form; 18 | const fieldProps = getFieldDecorator(field, { 19 | rules: [{required: formItemAttr.required, message: error.message}] 20 | }); 21 | 22 | // 相关options 必须为对象组成的数组,如 [{label: '北京', value: 'beijing'}]; 23 | const propsOptions = this.props.options; 24 | const configOptions = form.config[field].options; 25 | const options = Array.isArray(propsOptions) ? propsOptions : (configOptions||[]); 26 | 27 | const fieldLayout = form.config[field].layout; 28 | const _layout = fieldLayout || layout; 29 | 30 | return 31 | {fieldProps()} 32 | ; 33 | } 34 | } 35 | 36 | FormItemCheckboxGroup.contextTypes = { 37 | form: React.PropTypes.object.isRequired 38 | }; 39 | 40 | export default FormItemCheckboxGroup; 41 | -------------------------------------------------------------------------------- /src/FormItemInput/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Form, Input } from 'antd'; 3 | 4 | const FormItem = Form.Item; 5 | 6 | class FormItemInput extends React.Component { 7 | constructor(props) { 8 | super(props); 9 | } 10 | render(){ 11 | 12 | const { form } = this.context; 13 | const { field, onChange } = this.props; 14 | const { layout } = form.config; 15 | const { formItemAttr, fieldAttr, error } = form.config[field]; 16 | const { getFieldDecorator } = form; 17 | const fieldProps = getFieldDecorator(field, { 18 | rules: [{required: formItemAttr.required, message: error.message}] 19 | }); 20 | 21 | const fieldLayout = form.config[field].layout; 22 | const _layout = fieldLayout || layout; 23 | 24 | return 25 | {fieldProps()} 26 | ; 27 | } 28 | } 29 | 30 | FormItemInput.contextTypes = { 31 | form: React.PropTypes.object.isRequired 32 | }; 33 | 34 | export default FormItemInput; 35 | -------------------------------------------------------------------------------- /src/FormItemNoLabel/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Form } from 'antd'; 3 | 4 | const FormItem = Form.Item; 5 | 6 | class FormItemNoLabel extends React.Component { 7 | constructor(props) { 8 | super(props); 9 | } 10 | 11 | render(){ 12 | 13 | const { form } = this.context; 14 | const { layout } = form.config; 15 | 16 | return 17 | {this.props.children} 18 | ; 19 | } 20 | } 21 | 22 | FormItemNoLabel.contextTypes = { 23 | form: React.PropTypes.object.isRequired 24 | }; 25 | 26 | export default FormItemNoLabel; 27 | 28 | -------------------------------------------------------------------------------- /src/FormItemRadioGroup/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Form, Radio } from 'antd'; 3 | 4 | const FormItem = Form.Item; 5 | const RadioGroup = Radio.Group; 6 | 7 | class FormItemRadioGroup extends React.Component { 8 | constructor(props) { 9 | super(props); 10 | } 11 | render(){ 12 | 13 | const { form } = this.context; 14 | const { field, onChange } = this.props; 15 | const { layout } = form.config; 16 | const { formItemAttr, fieldAttr, error } = form.config[field]; 17 | const { getFieldDecorator } = form; 18 | const fieldProps = getFieldDecorator(field, { 19 | rules: [{required: formItemAttr.required, message: error.message}] 20 | }); 21 | 22 | const fieldLayout = form.config[field].layout; 23 | const _layout = fieldLayout || layout; 24 | // 相关options 必须为对象组成的数组,如 [{label: '北京', value: 'beijing'}]; 25 | const propsOptions = this.props.options; 26 | const configOptions = form.config[field].options; 27 | const options = Array.isArray(propsOptions) ? propsOptions : (configOptions||[]); 28 | 29 | return 30 | {fieldProps( 31 | {options.map((option, k) => { 32 | return {option.label}; 33 | })} 34 | )} 35 | ; 36 | } 37 | } 38 | 39 | FormItemRadioGroup.contextTypes = { 40 | form: React.PropTypes.object.isRequired 41 | }; 42 | 43 | export default FormItemRadioGroup; 44 | -------------------------------------------------------------------------------- /src/FormItemSelect/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Form, Select } from 'antd'; 3 | 4 | const FormItem = Form.Item; 5 | const Option = Select.Option; 6 | 7 | class FormItemSelect extends React.Component { 8 | constructor(props) { 9 | super(props); 10 | } 11 | render(){ 12 | 13 | const { form } = this.context; 14 | const { field, onChange, render } = this.props; 15 | const { layout } = form.config; 16 | const { formItemAttr={}, fieldAttr={}, error={}, keyField, valueField } = form.config[field]; 17 | const { getFieldDecorator } = form; 18 | const fieldProps = getFieldDecorator(field, { 19 | rules: [{required: formItemAttr.required, message: error.message}] 20 | }); 21 | 22 | const fieldLayout = form.config[field].layout; 23 | const _layout = fieldLayout || layout; 24 | // 相关options 必须为对象组成的数组,如 [{label: '北京', value: 'beijing'}]; 25 | const propsOptions = this.props.options; 26 | const configOptions = form.config[field].options||[]; 27 | const options = Array.isArray(propsOptions) ? propsOptions : configOptions; 28 | 29 | return 30 | {fieldProps()} 39 | ; 40 | } 41 | } 42 | 43 | FormItemSelect.contextTypes = { 44 | form: React.PropTypes.object.isRequired 45 | }; 46 | 47 | export default FormItemSelect; 48 | -------------------------------------------------------------------------------- /src/FuzzySearch/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Form, Select } from 'antd'; 3 | 4 | const FormItem = Form.Item; 5 | const Option = Select.Option; 6 | let timer; 7 | 8 | class FuzzySearch extends React.Component { 9 | constructor(props) { 10 | super(props); 11 | this.state = { 12 | options: [] 13 | }; 14 | } 15 | 16 | componentWillReceiveProps() { 17 | const { field } = this.props; 18 | const { getFieldValue } = this.context.form; 19 | const value = getFieldValue(field); 20 | 21 | this.onChange(value); 22 | } 23 | 24 | onFuzzySearch(keyword){ 25 | const { form } = this.context; 26 | const { field } = this.props; 27 | const { fuzzySearch } = form.config[field]; 28 | 29 | if(typeof fuzzySearch === 'function'){ 30 | fuzzySearch(keyword, res => { 31 | this.setState({options: res}); 32 | }); 33 | } 34 | } 35 | 36 | onSearch(keyword){ 37 | if(keyword){ 38 | if (timer) { 39 | clearTimeout(timer); 40 | timer = null; 41 | } 42 | timer = setTimeout(() => { 43 | this.onFuzzySearch(keyword.toLowerCase()); 44 | }, 100); 45 | } 46 | } 47 | 48 | onChange(value){ 49 | 50 | if(value){ 51 | const { form } = this.context; 52 | const { field } = this.props; 53 | const { accurateSearch } = form.config[field]; 54 | 55 | accurateSearch(value, res => { 56 | this.setState({options: [res]}); 57 | }); 58 | } 59 | } 60 | 61 | render(){ 62 | 63 | const { form } = this.context; 64 | const { field, render } = this.props; 65 | const { layout } = form.config; 66 | const { formItemAttr, fieldAttr, error, keyField, valueField } = form.config[field]; 67 | const { getFieldDecorator } = form; 68 | const fieldProps = getFieldDecorator(field, { 69 | rules: [{required: formItemAttr.required, message: error.message}] 70 | }); 71 | const fieldLayout = form.config[field].layout; 72 | const _layout = fieldLayout || layout; 73 | const { options = [] } = this.state; 74 | 75 | return 76 | {fieldProps()} 85 | ; 86 | } 87 | } 88 | 89 | FuzzySearch.contextTypes = { 90 | form: React.PropTypes.object.isRequired 91 | }; 92 | 93 | export default FuzzySearch; 94 | -------------------------------------------------------------------------------- /src/config.js: -------------------------------------------------------------------------------- 1 | import util from './util'; 2 | 3 | export const Input = { 4 | type: 'Input', 5 | formItemAttr: { 6 | label: ' ', 7 | required: false 8 | }, 9 | fieldAttr: { 10 | placeholder: '请填写', 11 | type: 'text' 12 | }, 13 | error: { 14 | message: '请输入' 15 | } 16 | }; 17 | 18 | export const Select = { 19 | type: 'Select', 20 | formItemAttr: { 21 | label: ' ', 22 | required: false 23 | }, 24 | fieldAttr: { 25 | placeholder: '请选择' 26 | }, 27 | keyField: 'value', 28 | valueField: 'label', 29 | error: { 30 | message: '请选择' 31 | } 32 | }; 33 | 34 | export const Cascader = { 35 | type: 'Cascader', 36 | formItemAttr: { 37 | label: ' ', 38 | required: false 39 | }, 40 | fieldAttr: { 41 | placeholder: '请选择', 42 | allowClear: false, 43 | showSearch: true, 44 | size: 'large', 45 | style: {width: '100%'}, 46 | notFoundContent: '没有找到' 47 | }, 48 | error: { 49 | message: '请选择' 50 | } 51 | }; 52 | 53 | export const CheckboxGroup = { 54 | type: 'CheckboxGroup', 55 | formItemAttr: { 56 | label: ' ', 57 | required: false 58 | }, 59 | fieldAttr: { 60 | 61 | }, 62 | error: { 63 | message: '请选择' 64 | } 65 | }; 66 | 67 | export const RadioGroup = { 68 | type: 'RadioGroup', 69 | formItemAttr: { 70 | label: ' ', 71 | required: false 72 | }, 73 | fieldAttr: { 74 | }, 75 | error: { 76 | message: '请选择' 77 | } 78 | }; 79 | 80 | export const FuzzySearch = { 81 | type: 'FuzzySearch', 82 | formItemAttr: { 83 | label: ' ', 84 | required: false 85 | }, 86 | fieldAttr: { 87 | showSearch: true, 88 | placeholder: '请输入关键字', 89 | notFoundContent: '', 90 | defaultActiveFirstOption: false, 91 | showArrow: false, 92 | filterOption: util.filterOptionByChildren, 93 | size: 'large', 94 | style: {width: '100%'} 95 | }, 96 | keyField: 'name', 97 | fuzzySearch: (keyword, callback) => { 98 | util.fetch('/') 99 | .then(res => res.json()) 100 | .then(res => { 101 | callback(res); 102 | }); 103 | }, 104 | accurateSearch: (value, callback) => { 105 | util.fetch('/') 106 | .then(res => res.json()) 107 | .then(res => { 108 | callback(res); 109 | }); 110 | }, 111 | // formItemLayout: {}, 112 | error: { 113 | message: '请输入用户' 114 | } 115 | }; 116 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import FormItemInput from './FormItemInput'; 2 | import FormItemCheckboxGroup from './FormItemCheckboxGroup'; 3 | import FormItemRadioGroup from './FormItemRadioGroup'; 4 | import FormItemCascader from './FormItemCascader'; 5 | import FormItemNoLabel from './FormItemNoLabel'; 6 | import FormItemSelect from './FormItemSelect'; 7 | import FuzzySearch from './FuzzySearch'; 8 | import * as util from './util'; 9 | 10 | import Affix from 'antd/lib/affix'; 11 | import Anchor from 'antd/lib/anchor'; 12 | import AutoComplete from 'antd/lib/auto-complete'; 13 | import Alert from 'antd/lib/alert'; 14 | import BackTop from 'antd/lib/back-top'; 15 | import Badge from 'antd/lib/badge'; 16 | import Breadcrumb from 'antd/lib/breadcrumb'; 17 | import Button from 'antd/lib/button'; 18 | import Calendar from 'antd/lib/calendar'; 19 | import Card from 'antd/lib/card'; 20 | import Collapse from 'antd/lib/collapse'; 21 | import Carousel from 'antd/lib/carousel'; 22 | import Cascader from 'antd/lib/cascader'; 23 | import Checkbox from 'antd/lib/checkbox'; 24 | import Col from 'antd/lib/col'; 25 | import DatePicker from 'antd/lib/date-picker'; 26 | import Dropdown from 'antd/lib/dropdown'; 27 | import Form from 'antd/lib/form'; 28 | import Icon from 'antd/lib/icon'; 29 | import Input from 'antd/lib/input'; 30 | import InputNumber from 'antd/lib/input-number'; 31 | import Layout from 'antd/lib/layout'; 32 | import LocaleProvider from 'antd/lib/locale-provider'; 33 | import message from 'antd/lib/message'; 34 | import Menu from 'antd/lib/menu'; 35 | import Modal from 'antd/lib/modal'; 36 | import notification from 'antd/lib/notification'; 37 | import Pagination from 'antd/lib/pagination'; 38 | import Popconfirm from 'antd/lib/popconfirm'; 39 | import Popover from 'antd/lib/popover'; 40 | import Progress from 'antd/lib/progress'; 41 | import Radio from 'antd/lib/radio'; 42 | import Rate from 'antd/lib/rate'; 43 | import Row from 'antd/lib/row'; 44 | import Select from 'antd/lib/select'; 45 | import Slider from 'antd/lib/slider'; 46 | import Spin from 'antd/lib/spin'; 47 | import Steps from 'antd/lib/steps'; 48 | import Switch from 'antd/lib/switch'; 49 | import Table from 'antd/lib/table'; 50 | import Transfer from 'antd/lib/transfer'; 51 | import Tree from 'antd/lib/tree'; 52 | import TreeSelect from 'antd/lib/tree-select'; 53 | import Tabs from 'antd/lib/tabs'; 54 | import Tag from 'antd/lib/tag'; 55 | import TimePicker from 'antd/lib/time-picker'; 56 | import Timeline from 'antd/lib/timeline'; 57 | import Tooltip from 'antd/lib/tooltip'; 58 | import Mention from 'antd/lib/mention'; 59 | import Upload from 'antd/lib/upload'; 60 | import version from 'antd/lib/version/'; 61 | 62 | export { 63 | util, 64 | FormItemInput, 65 | FormItemCheckboxGroup, 66 | FormItemRadioGroup, 67 | FormItemCascader, 68 | FormItemNoLabel, 69 | FormItemSelect, 70 | FuzzySearch, 71 | 72 | Affix, 73 | Anchor, 74 | AutoComplete, 75 | Alert, 76 | BackTop, 77 | Badge, 78 | Breadcrumb, 79 | Button, 80 | Calendar, 81 | Card, 82 | Collapse, 83 | Carousel, 84 | Cascader, 85 | Checkbox, 86 | Col, 87 | DatePicker, 88 | Dropdown, 89 | Form, 90 | Icon, 91 | Input, 92 | InputNumber, 93 | Layout, 94 | LocaleProvider, 95 | message, 96 | Menu, 97 | Modal, 98 | notification, 99 | Pagination, 100 | Popconfirm, 101 | Popover, 102 | Progress, 103 | Radio, 104 | Rate, 105 | Row, 106 | Select, 107 | Slider, 108 | Spin, 109 | Steps, 110 | Switch, 111 | Table, 112 | Transfer, 113 | Tree, 114 | TreeSelect, 115 | Tabs, 116 | Tag, 117 | TimePicker, 118 | Timeline, 119 | Tooltip, 120 | Mention, 121 | Upload, 122 | version 123 | }; 124 | -------------------------------------------------------------------------------- /src/util.js: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * 下拉框忽略大小写 4 | */ 5 | export function filterOptionByChildren(inputValue, option){ 6 | return option.props.children.toLowerCase().indexOf(inputValue.toLowerCase()) > -1; 7 | } 8 | 9 | export function fetch(url, option) { 10 | const defaultHeaders = { 11 | 'Accept': 'application/json', 12 | 'Content-Type': 'application/json' 13 | }; 14 | const originHeaders = Object.assign({}, option.headers); 15 | option.headers = Object.assign({}, defaultHeaders, originHeaders); 16 | return require('isomorphic-fetch')(url, option); 17 | } 18 | 19 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | entry: './src/index.js', 3 | output: { 4 | filename: 'bundle.js', 5 | path: './dist' 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /webpack.dev.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var webpack = require('webpack'); 3 | var HtmlWebpackPlugin = require('html-webpack-plugin'); 4 | 5 | module.exports = { 6 | devtool: 'cheap-module-eval-source-map', 7 | entry: { 8 | index: './examples/Entry/index.js', 9 | dev: 'webpack-dev-server/client?http://localhost:9100' 10 | }, 11 | output: { 12 | path: path.join(__dirname, 'dist'), 13 | filename: '[name].js', 14 | chunkFilename: 'dist/[name].[chunkhash:6].js' 15 | }, 16 | resolve: { 17 | alias: { 18 | 'antd-easy': path.join(__dirname, './lib') 19 | } 20 | }, 21 | module: { 22 | rules: [ 23 | { 24 | test: /\.js[x]?$/, 25 | exclude: /node_modules/, 26 | include: [path.resolve(__dirname, 'src'), path.resolve(__dirname, 'examples')], 27 | loader: 'babel-loader', 28 | options: { 29 | presets: ['es2015', 'react'] 30 | } 31 | }, 32 | { 33 | test: /\.js[x]?$/, 34 | exclude: /node_modules/, 35 | include: [path.resolve(__dirname, 'src'), path.resolve(__dirname, 'examples')], 36 | loader: 'eslint-loader', 37 | query: { 38 | configFile: './.eslintrc' 39 | } 40 | }, 41 | { 42 | test: /\.less$/, 43 | use: [ 44 | 'style-loader', 45 | { loader: 'css-loader', options: { importLoaders: 1 } }, 46 | 'less-loader' 47 | ] 48 | }, 49 | { 50 | test: /\.css$/, 51 | use: [ 52 | 'style-loader','css-loader' 53 | ] 54 | } 55 | ] 56 | }, 57 | plugins: [ 58 | // new webpack.optimize.UglifyJsPlugin({ 59 | // compress: { 60 | // warnings: false 61 | // } 62 | // }), 63 | new webpack.HotModuleReplacementPlugin(), 64 | new HtmlWebpackPlugin({ 65 | template: './examples/index.html' 66 | }) 67 | ], 68 | devServer: { 69 | // contentBase: path.join(__dirname, 'examples'), 70 | compress: true, // 开启gzip 71 | host: '0.0.0.0', 72 | port: 9100, 73 | // hot: true, 74 | clientLogLevel: 'warning', 75 | watchContentBase: true, 76 | quiet: false, 77 | staticOptions: { 78 | redirect: false 79 | }, 80 | proxy: { 81 | '/api': { 82 | target: 'http://localhost:3100/api', 83 | bypass: function (req, res, proxyOptions) { 84 | if(req.headers.accept.indexOf('html') !== -1){ 85 | // console.log('skiping proxy for browser request.'); 86 | return '/'; 87 | } 88 | } 89 | } 90 | } 91 | } 92 | }; 93 | --------------------------------------------------------------------------------