├── .babelrc ├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── dist ├── index.js └── uform.css ├── docs ├── 0-1.css ├── 0-2.css ├── antd.14c8a50.js ├── app.14c8a50.js ├── css │ └── app.14c8a50.css ├── highlight.14c8a50.js └── index.html ├── examples ├── .babelrc ├── package.json ├── public │ └── index.html ├── src │ ├── components │ │ ├── ApiBlock.js │ │ ├── CodeBlock.jsx │ │ └── PageAnchor.js │ ├── css │ │ ├── hightlight.scss │ │ └── main.scss │ ├── index.js │ └── views │ │ ├── App.jsx │ │ ├── ModalForm.js │ │ └── NormalForm.js └── tools │ ├── pathConfig.js │ ├── webpack.com.config.js │ ├── webpack.dev.config.js │ └── webpack.prod.config.js ├── imgs ├── 弹窗表单.png └── 通用表单.png ├── lib ├── components │ ├── Field.jsx │ ├── FormComponent.jsx │ ├── ModalForm.jsx │ ├── NormalForm.jsx │ └── UForm.jsx ├── css │ └── main.css ├── index.js └── util │ └── index.js ├── package.json └── scripts ├── build.js └── pathEnv.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [["@babel/preset-env", { "loose": true }], "@babel/preset-react"], 3 | "plugins": [ 4 | [ 5 | "import", 6 | { 7 | "libraryName": "antd", 8 | "style": "css" // or 'css' 9 | } 10 | ], 11 | "@babel/plugin-transform-runtime", 12 | "@babel/plugin-proposal-class-properties", 13 | "@babel/plugin-syntax-dynamic-import" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | package-lock.json 3 | examples/node_modules 4 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | package-lock.json 3 | examples 4 | docs 5 | 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 笪笪的前端小站 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # uform 2 | 3 | 基于 antd 表单实现的自定义表单,简单实用,支持常用表单及弹窗表单,支持`Input`、`InputNumber`、`Textarea`、`Select`、`Radio`、`Checkbox`、`Password`、`Switch`、`Rate`、`custom(自定义ReactNode)`。 4 | 5 | **documentation:[https://dadaiwei.github.io/uform](https://dadaiwei.github.io/uform)** 6 |
7 | **npm:[https://www.npmjs.com/package/uform](https://www.npmjs.com/package/uform)** 8 | 9 | ## 基本介绍 10 | 11 | 基于 antd 组件库定制的简单易用 Form,支持通用表单及弹框表单两种形式,支持 Input、InputNumber、Textarea、Select、Radio、Checkbox、Password、Switch、Rate、custom(自定义 ReactNode)。 12 | 13 | ## 使用指南 14 | 15 | 1.安装 UForm 依赖包 16 | 17 | ``` 18 | npm install uform --save-dev 19 | ``` 20 | 21 | 2.引入依赖包 22 | 23 | ``` 24 | import UForm from "uform"; 25 | import "uform/dist/uform.css"; 26 | ``` 27 | 28 | 3.使用 UForm 组件 29 | 30 | ``` 31 | 38 | ``` 39 | 40 | ## 代码演示 41 | 42 | ### 通用表单 43 | 44 | ![通用表单](./imgs/通用表单.png) 45 | 46 | 代码 47 | 48 | ``` 49 | import React, { useState } from "react"; 50 | import UForm from "uform"; 51 | import "uform/dist/uform.css"; 52 | 53 | function NormalForm() { 54 | const [data, setData] = useState({ 55 | name: "", 56 | size: 1, 57 | city: 0, 58 | area: "郊区", 59 | password: "", 60 | choosen: true, 61 | confirm: true, 62 | rate: 3, 63 | describe: "" 64 | }); 65 | const fields = [ 66 | { 67 | name: "name", 68 | label: "名称", 69 | type: "input", 70 | placeholder: "请输入名称", 71 | rules: [ 72 | { 73 | required: true, 74 | message: "请输入名称" 75 | } 76 | ] 77 | }, 78 | { 79 | name: "size", 80 | label: "大小", 81 | type: "inputNumber", 82 | placeholder: "请输入大小", 83 | rules: [ 84 | { 85 | required: true, 86 | message: "请输入名称" 87 | } 88 | ] 89 | }, 90 | { 91 | name: "city", 92 | label: "城市", 93 | type: "select", 94 | fieldData: [ 95 | { 96 | name: "北京", 97 | value: 0 98 | }, 99 | { 100 | name: "上海", 101 | value: 1 102 | }, 103 | { 104 | name: "杭州", 105 | value: 2 106 | }, 107 | { 108 | name: "深圳", 109 | value: 3 110 | } 111 | ], 112 | rules: [ 113 | { 114 | required: true, 115 | message: "请输入名称" 116 | } 117 | ] 118 | }, 119 | { 120 | name: "area", 121 | label: "地区", 122 | type: "radio", 123 | fieldData: ["城区", "郊区"] 124 | }, 125 | { 126 | name: "confirm", 127 | label: "确认选择", 128 | type: "checkbox", 129 | rules: [ 130 | { 131 | required: true, 132 | message: "请确认选择" 133 | } 134 | ] 135 | }, 136 | { 137 | name: "custom", 138 | label: "自定义项", 139 | type: "custom", 140 | node: ( 141 |
142 |

自定义表单项

143 |
144 | ) 145 | }, 146 | { 147 | name: "password", 148 | label: "密码", 149 | type: "password", 150 | rules: [ 151 | { 152 | required: true, 153 | message: "请输入密码" 154 | } 155 | ] 156 | }, 157 | { 158 | name: "choosen", 159 | label: "是否选择", 160 | type: "switch", 161 | checkedChildren: "开", 162 | unCheckedChildren: "关", 163 | rules: [ 164 | { 165 | required: true, 166 | message: "请输入密码" 167 | } 168 | ] 169 | }, 170 | { 171 | name: "rate", 172 | label: "评分", 173 | type: "rate" 174 | }, 175 | { 176 | name: "describe", 177 | label: "描述", 178 | type: "textarea", 179 | placeholder: "请输入描述" 180 | } 181 | ]; 182 | const onChange = (result) => { 183 | setData({ 184 | ...data, 185 | ...result 186 | }); 187 | }; 188 | const onSubmit = (values) => { 189 | console.log(values); 190 | }; 191 | const onCancel = () => { 192 | console.log("cancel"); 193 | }; 194 | return ( 195 |
196 |
197 | 204 |
205 |
206 | ); 207 | } 208 | ``` 209 | 210 | ### 弹窗表单 211 | 212 | ![弹窗表单](./imgs/弹窗表单.png) 213 | 214 | 代码 215 | 216 | ``` 217 | import React, { useState } from "react"; 218 | import { Button } from "antd"; 219 | import UForm from "uform"; 220 | import "uform/dist/uform.css"; 221 | 222 | function ModalForm() { 223 | const { visible, setVisible } = useState(false); 224 | const [data, setData] = useState({ 225 | name: "", 226 | size: 1, 227 | city: 0, 228 | area: "郊区", 229 | password: "", 230 | choosen: true, 231 | confirm: true, 232 | rate: 3, 233 | describe: "" 234 | }); 235 | const fields = [ 236 | { 237 | name: "name", 238 | label: "名称", 239 | type: "input", 240 | placeholder: "请输入名称", 241 | rules: [ 242 | { 243 | required: true, 244 | message: "请输入名称" 245 | } 246 | ] 247 | }, 248 | { 249 | name: "size", 250 | label: "大小", 251 | type: "inputNumber", 252 | placeholder: "请输入大小", 253 | rules: [ 254 | { 255 | required: true, 256 | message: "请输入名称" 257 | } 258 | ] 259 | }, 260 | { 261 | name: "city", 262 | label: "城市", 263 | type: "select", 264 | fieldData: [ 265 | { 266 | name: "北京", 267 | value: 0 268 | }, 269 | { 270 | name: "上海", 271 | value: 1 272 | }, 273 | { 274 | name: "杭州", 275 | value: 2 276 | }, 277 | { 278 | name: "深圳", 279 | value: 3 280 | } 281 | ], 282 | rules: [ 283 | { 284 | required: true, 285 | message: "请输入名称" 286 | } 287 | ] 288 | }, 289 | { 290 | name: "area", 291 | label: "地区", 292 | type: "radio", 293 | fieldData: ["城区", "郊区"] 294 | }, 295 | { 296 | name: "confirm", 297 | label: "确认选择", 298 | type: "checkbox", 299 | rules: [ 300 | { 301 | required: true, 302 | message: "请确认选择" 303 | } 304 | ] 305 | }, 306 | { 307 | name: "custom", 308 | label: "自定义项", 309 | type: "custom", 310 | node: ( 311 |
312 |

自定义表单项

313 |
314 | ) 315 | }, 316 | { 317 | name: "password", 318 | label: "密码", 319 | type: "password", 320 | rules: [ 321 | { 322 | required: true, 323 | message: "请输入密码" 324 | } 325 | ] 326 | }, 327 | { 328 | name: "choosen", 329 | label: "是否选择", 330 | type: "switch", 331 | checkedChildren: "开", 332 | unCheckedChildren: "关", 333 | rules: [ 334 | { 335 | required: true, 336 | message: "请输入密码" 337 | } 338 | ] 339 | }, 340 | { 341 | name: "rate", 342 | label: "评分", 343 | type: "rate" 344 | }, 345 | { 346 | name: "describe", 347 | label: "描述", 348 | type: "textarea", 349 | placeholder: "请输入描述" 350 | } 351 | ]; 352 | const onChange = (result) => { 353 | setData({ 354 | ...data, 355 | ...result 356 | }); 357 | }; 358 | const onSubmit = (values) => { 359 | console.log(values); 360 | }; 361 | const onCancel = () => { 362 | setVisible(false); 363 | }; 364 | return ( 365 |
366 | 373 |
374 | 384 |
385 |
386 | ); 387 | } 388 | ``` 389 | 390 | ## API 391 | 392 | ### 公共 API 393 | 394 | | 属性 | 说明 | 必填属性 | 类型 | 可选值 | 默认值 | 395 | | :--------- | :----------------------- | :------- | :--------------- | :-------------------------------- | :--------- | 396 | | type | 使用通用表单或者弹框表单 | false | string | norma \| modal | normal | 397 | | layout | 表单布局 | false | string | horizontal \| vertical \| inline | horizontal | 398 | | labelCol | 表单 label 占宽 | false | number | 1-24 之间整数 | 4 | 399 | | wrapperCol | 表单内容项占宽 | false | number | 1-24 之间整数,通常为 24-labelCol | 16 | 400 | | loading | 确定按钮 loading | false | boolean | true \| false | false | 401 | | data | 表单数据 | true | any[ ] | - | [ ] | 402 | | fields | 表单每一项特征描述 | true | any[ ] | - | [ ] | 403 | | onSubmit | 表单提交回调 | true | Function(values) | - | 无 | 404 | | onChange | 表单每一项修改回调 | false | Function(value) | - | 无 | 405 | | onCancel | 表单取消回调 | false | Function( ) | - | 无 | 406 | 407 | ### fields props 408 | 409 | | 属性 | 说明 | 必填属性 | 类型 | 可选值 | 默认值 | 410 | | :--------- | :---------------------------------------------- | :------- | :--------- | :------------------------------------------------------------------------------------------------------------------ | :----- | 411 | | name | 表单数据 name,与 data 中 key 值一致 | true | string | - | 无 | 412 | | type | 表单项类型 | true | string | input \| inputNumber \| textarea \| select \| radio \| checkbox \| password \| switch \| rate \| custom(自定义项) | 无 | 413 | | label | 表单项 label | true | string | - | 无 | 414 | | rules | 表单项限制规则,与 antd Form 限制规则一致 | false | object [ ] | - | 无 | 415 | | fieldData | 适用于 type 为 select/radio 的选择项 | true | object [ ] | - | 无 | 416 | | placehoder | 适用于 type 为 input/textarea/select 的提示信息 | false | string | - | 无 | 417 | | node | 适用于 type 为 custom 的自定义 ReactNode | true | ReactNode | - | 无 | 418 | 419 | > **特别说明**:type 类型为 **select/radio**时, **fieldsData** 是必填属性, type 类型为 **custome** 时, **node** 是必填属性。 420 | 421 | ### 通用表单特有 API 422 | 423 | | 属性 | 说明 | 必填属性 | 类型 | 可选值 | 默认值 | 424 | | :--------------- | :--------------- | :------- | :------ | :------------ | :----- | 425 | | showCancelButton | 是否展示取消按钮 | false | boolean | true \| false | true | 426 | 427 | ### 弹框表单特有 API 428 | 429 | | 属性 | 说明 | 必填属性 | 类型 | 可选值 | 默认值 | 430 | | :------ | :----------- | :------- | :------------------ | :------------ | :----- | 431 | | visible | 弹框是否可见 | true | boolean | true \| false | true | 432 | | title | 弹框标题 | true | string \| ReactNode | - | 无 | 433 | | width | 弹框宽度 | false | number | - | 600 | 434 | 435 | ## License 436 | 437 | [MIT](https://opensource.org/licenses/MIT) 438 | 439 | Copyright (c) 2019 笪笪的前端小站 440 | -------------------------------------------------------------------------------- /docs/antd.14c8a50.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[0],{12:function(e,t,n){"use strict";var o=n(1),r=n(4),i=n.n(r),a=n(103),c=n(626);function l(){return(l=Object.assign||function(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:{},t=e.scriptUrl,n=e.extraCommonProps,r=void 0===n?{}:n;if("undefined"!=typeof document&&"undefined"!=typeof window&&"function"==typeof document.createElement&&"string"==typeof t&&t.length&&!s.has(t)){var i=document.createElement("script");i.setAttribute("src",t),i.setAttribute("data-namespace",t),s.add(t),document.body.appendChild(i)}var a=function(e){var t=e.type,n=e.children,i=u(e,["type","children"]),a=null;return e.type&&(a=o.createElement("use",{xlinkHref:"#".concat(t)})),n&&(a=n),o.createElement(j,l({},i,r),a)};return a.displayName="Iconfont",a},P.getTwoToneColor=function(){return c.a.getTwoToneColors().primaryColor},P.setTwoToneColor=b;var j=t.a=P},14:function(e,t,n){"use strict";var o=n(102);t.a=function(e,t,n){Object(o.a)(e,"[antd: ".concat(t,"] ").concat(n))}},23:function(e,t,n){"use strict";var o=n(1),r=n(0),i=n(35).a;function a(e){return(a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function c(){return(c=Object.assign||function(e){for(var t=1;t1&&void 0!==arguments[1]?arguments[1]:1,n=i++,o=t;return a[n]=r()(function t(){(o-=1)<=0?(e(),delete a[n]):a[n]=r()(t)}),n}c.cancel=function(e){void 0!==e&&(r.a.cancel(a[e]),delete a[e])},c.ids=a},622:function(e,t,n){},627:function(e,t,n){"use strict";var o=n(1),r=n(8),i=n(20),a=n(105),c=n(0),l=n(4),u=n.n(l),s=n(13),f=n.n(s),p=n(10),y=n(17),d=n(278),h=n.n(d),m=n(281),b=n(9),v=n(14),g=n(12),O=n(24);function w(e){return(w="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function C(){return(C=Object.assign||function(e){for(var t=1;t=0?"slide-down":"slide-up"}},{key:"render",value:function(){return o.createElement(b.a,null,this.renderDropDown)}}])&&S(n.prototype,r),i&&S(n,i),t}();k.defaultProps={mouseEnterDelay:.15,mouseLeaveDelay:.1,placement:"bottomLeft"};var E=n(81);function _(e){return(_="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function N(){return(N=Object.assign||function(e){for(var t=1;t0&&(b=n.getOptions().map(function(e){return o.createElement($,{prefixCls:d,key:e.value.toString(),disabled:"disabled"in e?e.disabled:a.disabled,value:e.value,checked:-1!==c.value.indexOf(e.value),onChange:e.onChange,className:"".concat(h,"-item")},e.label)}));var v=u()(h,s);return o.createElement("div",J({className:v,style:f},m),b)},n.state={value:e.value||e.defaultValue||[],registeredValues:[]},n}var n,r,a;return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&ne(e,t)}(t,o["Component"]),n=t,a=[{key:"getDerivedStateFromProps",value:function(e){return"value"in e?{value:e.value||[]}:null}}],(r=[{key:"getChildContext",value:function(){return{checkboxGroup:{toggleOption:this.toggleOption,value:this.state.value,disabled:this.props.disabled,name:this.props.name,registerValue:this.registerValue,cancelValue:this.cancelValue}}}},{key:"shouldComponentUpdate",value:function(e,t){return!f()(this.props,e)||!f()(this.state,t)}},{key:"getOptions",value:function(){return this.props.options.map(function(e){return"string"==typeof e?{label:e,value:e}:e})}},{key:"render",value:function(){return o.createElement(b.a,null,this.renderGroup)}}])&&Z(n.prototype,r),a&&Z(n,a),t}();re.defaultProps={options:[]},re.propTypes={defaultValue:c.array,value:c.array,options:c.array.isRequired,onChange:c.func},re.childContextTypes={checkboxGroup:c.any},Object(p.polyfill)(re);var ie=re;$.Group=ie;var ae=$;function ce(e){return(ce="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function le(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function ue(){return(ue=Object.assign||function(e){for(var t=1;t0&&(d=l.map(function(e){return"string"==typeof e?o.createElement(he,{key:e,prefixCls:f,disabled:n.props.disabled,value:e,checked:n.state.value===e},e):o.createElement(he,{key:"radio-group-value-options-".concat(e.value),prefixCls:f,disabled:e.disabled||n.props.disabled,value:e.value,checked:n.state.value===e.value},e.label)})),o.createElement("div",{className:y,style:r.style,onMouseEnter:r.onMouseEnter,onMouseLeave:r.onMouseLeave,id:r.id},d)},"value"in e)a=e.value;else if("defaultValue"in e)a=e.defaultValue;else{var c=we(e.children);a=c&&c.value}return n.state={value:a},n}var n,r,i;return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&Oe(e,t)}(t,o["Component"]),n=t,i=[{key:"getDerivedStateFromProps",value:function(e){if("value"in e)return{value:e.value};var t=we(e.children);return t?{value:t.value}:null}}],(r=[{key:"getChildContext",value:function(){return{radioGroup:{onChange:this.onRadioChange,value:this.state.value,disabled:this.props.disabled,name:this.props.name}}}},{key:"shouldComponentUpdate",value:function(e,t){return!f()(this.props,e)||!f()(this.state,t)}},{key:"render",value:function(){return o.createElement(b.a,null,this.renderGroup)}}])&&be(n.prototype,r),i&&be(n,i),t}();Ce.defaultProps={buttonStyle:"outline"},Ce.childContextTypes={radioGroup:c.any},Object(p.polyfill)(Ce);var Se=Ce;function Pe(e){return(Pe="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function je(){return(je=Object.assign||function(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"children",n=[];return function e(o){o.forEach(function(o){if(o[t]){var r=Me({},o);delete r[t],n.push(r),o[t].length>0&&e(o[t])}else n.push(o)})}(e),n}function Ke(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"children";return e.map(function(e,o){var r={};return e[n]&&(r[n]=Ke(e[n],t,n)),Me({},t(e,o),r)})}function Fe(e,t){return e.reduce(function(e,n){if(t(n)&&e.push(n),n.children){var o=Fe(n.children,t);e.push.apply(e,Re(o))}return e},[])}function Le(e){var t=[];return o.Children.forEach(e,function(e){if(o.isValidElement(e)){var n=Me({},e.props);e.key&&(n.key=e.key),e.type&&e.type.__ANT_TABLE_COLUMN_GROUP&&(n.children=Le(n.children)),t.push(n)}}),t}function Ve(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return(e||[]).forEach(function(e){var n=e.value,o=e.children;t[n.toString()]=n,Ve(o,t)}),t}function ze(e){return(ze="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function Be(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Ue(e,t){for(var n=0;n=0?delete o[e.key]:o[e.key]=e.keyPath,n.setState({keyPathOfSelectedItem:o})}},n.renderFilterIcon=function(){var e,t=n.props,r=t.column,i=t.locale,a=t.prefixCls,c=t.selectedKeys,l=c&&c.length>0,s=r.filterIcon;"function"==typeof s&&(s=s(l));var f=u()((Be(e={},"".concat(a,"-selected"),l),Be(e,"".concat(a,"-open"),n.getDropdownVisible()),e));return s?o.cloneElement(s,{title:i.filterTitle,className:u()("".concat(a,"-icon"),f,s.props.className),onClick:qe}):o.createElement(g.a,{title:i.filterTitle,type:"filter",theme:"filled",className:f,onClick:qe})};var c="filterDropdownVisible"in e.column&&e.column.filterDropdownVisible;return n.state={selectedKeys:e.selectedKeys,valueKeys:Ve(e.column.filters),keyPathOfSelectedItem:{},visible:c,prevProps:e},n}var n,i,a;return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&We(e,t)}(t,o["Component"]),n=t,a=[{key:"getDerivedStateFromProps",value:function(e,t){var n=e.column,o=t.prevProps,r={prevProps:e};return"selectedKeys"in e&&!f()(o.selectedKeys,e.selectedKeys)&&(r.selectedKeys=e.selectedKeys),f()((o.column||{}).filters,(e.column||{}).filters)||(r.valueKeys=Ve(e.column.filters)),"filterDropdownVisible"in n&&(r.visible=n.filterDropdownVisible),r}}],(i=[{key:"componentDidMount",value:function(){var e=this.props.column;this.setNeverShown(e)}},{key:"componentDidUpdate",value:function(){var e=this.props.column;this.setNeverShown(e)}},{key:"getDropdownVisible",value:function(){return!this.neverShown&&this.state.visible}},{key:"setVisible",value:function(e){var t=this.props.column;"filterDropdownVisible"in t||this.setState({visible:e}),t.onFilterDropdownVisibleChange&&t.onFilterDropdownVisibleChange(e)}},{key:"hasSubMenu",value:function(){var e=this.props.column.filters;return(void 0===e?[]:e).some(function(e){return!!(e.children&&e.children.length>0)})}},{key:"confirmFilter",value:function(){var e=this.props,t=e.column,n=e.selectedKeys,o=e.confirmFilter,r=this.state,i=r.selectedKeys,a=r.valueKeys,c=t.filterDropdown;f()(i,n)||o(t,c?i:i.map(function(e){return a[e]}).filter(function(e){return void 0!==e}))}},{key:"renderMenus",value:function(e){var t=this;return e.map(function(e){if(e.children&&e.children.length>0){var n=t.state.keyPathOfSelectedItem,r=Object.keys(n).some(function(t){return n[t].indexOf(e.value)>=0})?"".concat(t.props.dropdownPrefixCls,"-submenu-contain-selected"):"";return o.createElement(y.d,{title:e.text,className:r,key:e.value.toString()},t.renderMenus(e.children))}return t.renderMenuItem(e)})}},{key:"renderMenuItem",value:function(e){var t=this.props.column,n=this.state.selectedKeys,r=!("filterMultiple"in t)||t.filterMultiple,i=(n||[]).map(function(e){return e.toString()}),a=r?o.createElement(ae,{checked:i.indexOf(e.value.toString())>=0}):o.createElement(Ie,{checked:i.indexOf(e.value.toString())>=0});return o.createElement(y.b,{key:e.value},a,o.createElement("span",null,e.text))}},{key:"render",value:function(){var e=this,t=this.state.selectedKeys,n=this.props,r=n.column,i=n.locale,a=n.prefixCls,c=n.dropdownPrefixCls,l=n.getPopupContainer,s=!("filterMultiple"in r)||r.filterMultiple,f=u()(Be({},"".concat(c,"-menu-without-submenu"),!this.hasSubMenu())),p=r.filterDropdown;p instanceof Function&&(p=p({prefixCls:"".concat(c,"-custom"),setSelectedKeys:function(t){return e.setSelectedKeys({selectedKeys:t})},selectedKeys:t,confirm:this.handleConfirm,clearFilters:this.handleClearFilters,filters:r.filters}));var d=p?o.createElement(De,{className:"".concat(a,"-dropdown")},p):o.createElement(De,{className:"".concat(a,"-dropdown")},o.createElement(y.e,{multiple:s,onClick:this.handleMenuItemClick,prefixCls:"".concat(c,"-menu"),className:f,onSelect:this.setSelectedKeys,onDeselect:this.setSelectedKeys,selectedKeys:t&&t.map(function(e){return e.toString()}),getPopupContainer:l},this.renderMenus(r.filters)),o.createElement("div",{className:"".concat(a,"-dropdown-btns")},o.createElement("a",{className:"".concat(a,"-dropdown-link confirm"),onClick:this.handleConfirm},i.filterConfirm),o.createElement("a",{className:"".concat(a,"-dropdown-link clear"),onClick:this.handleClearFilters},i.filterReset)));return o.createElement(F,{trigger:["click"],placement:"bottomRight",overlay:d,visible:this.getDropdownVisible(),onVisibleChange:this.onVisibleChange,getPopupContainer:l,forceRender:!0},this.renderFilterIcon())}}])&&Ue(n.prototype,i),a&&Ue(n,a),t}();Xe.defaultProps={handleFilter:function(){},column:{}},Object(p.polyfill)(Xe);var $e=Xe;function Ye(){return(Ye=Object.assign||function(e){for(var t=1;t=0:t.getState().selectedRowKeys.indexOf(o)>=0||n.indexOf(o)>=0}},{key:"subscribe",value:function(){var e=this,t=this.props.store;this.unsubscribe=t.subscribe(function(){var t=e.getCheckState(e.props);e.setState({checked:t})})}},{key:"render",value:function(){var e=this.props,t=e.type,n=e.rowIndex,r=ot(e,["type","rowIndex"]),i=this.state.checked;return"radio"===t?o.createElement(Ie,Qe({checked:i,value:n},r)):o.createElement(ae,Qe({checked:i},r))}}])&&Ze(n.prototype,r),i&&Ze(n,i),t}(),it=n(33),at=n.n(it),ct=at()({inlineCollapsed:!1});function lt(e){return(lt="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function ut(){return(ut=Object.assign||function(e){for(var t=1;t=0||r.indexOf("Bottom")>=0?a.top="".concat(i.height-t.offset[1],"px"):(r.indexOf("Top")>=0||r.indexOf("bottom")>=0)&&(a.top="".concat(-t.offset[1],"px")),r.indexOf("left")>=0||r.indexOf("Right")>=0?a.left="".concat(i.width-t.offset[0],"px"):(r.indexOf("right")>=0||r.indexOf("Left")>=0)&&(a.left="".concat(-t.offset[0],"px")),e.style.transformOrigin="".concat(a.left," ").concat(a.top)}},n.renderTooltip=function(e){var t=e.getPopupContainer,r=e.getPrefixCls,i=xt(n),a=i.props,c=i.state,l=a.prefixCls,s=a.title,f=a.overlay,p=a.openClassName,y=a.getPopupContainer,d=a.getTooltipContainer,h=a.children,m=r("tooltip",l),b=c.visible;"visible"in a||!n.isNoTitle()||(b=!1);var v,g,O,w=function(e){var t=e.type;if((t.__ANT_BUTTON||t.__ANT_SWITCH||t.__ANT_CHECKBOX||"button"===e.type)&&e.props.disabled){var n=_t(e.props.style,["position","left","right","top","bottom","float","display","zIndex"]),r=n.picked,i=n.omitted,a=Et({display:"inline-block"},r,{cursor:"not-allowed",width:e.props.block?"100%":null}),c=Et({},i,{pointerEvents:"none"}),l=o.cloneElement(e,{style:c,className:null});return o.createElement("span",{style:a,className:e.props.className},l)}return e}(o.isValidElement(h)?h:o.createElement("span",null,h)),C=w.props,S=u()(C.className,(v={},g=p||"".concat(m,"-open"),O=!0,g in v?Object.defineProperty(v,g,{value:O,enumerable:!0,configurable:!0,writable:!0}):v[g]=O,v));return o.createElement(mt.a,Et({},n.props,{prefixCls:m,getTooltipContainer:y||d||t,ref:n.saveTooltip,builtinPlacements:n.getPlacements(),overlay:f||s||"",visible:b,onVisibleChange:n.onVisibleChange,onPopupAlign:n.onPopupAlign}),b?o.cloneElement(w,{className:S}):w)},n.state={visible:!!e.visible||!!e.defaultVisible},n}var n,r,i;return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&kt(e,t)}(t,o["Component"]),n=t,i=[{key:"getDerivedStateFromProps",value:function(e){return"visible"in e?{visible:e.visible}:null}}],(r=[{key:"getPopupDomNode",value:function(){return this.tooltip.getPopupDomNode()}},{key:"getPlacements",value:function(){var e=this.props,t=e.builtinPlacements,n=e.arrowPointAtCenter,o=e.autoAdjustOverflow;return t||function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.arrowWidth,n=void 0===t?5:t,o=e.horizontalArrowShift,r=void 0===o?16:o,i=e.verticalArrowShift,a=void 0===i?12:i,c=e.autoAdjustOverflow,l=void 0===c||c,u={left:{points:["cr","cl"],offset:[-4,0]},right:{points:["cl","cr"],offset:[4,0]},top:{points:["bc","tc"],offset:[0,-4]},bottom:{points:["tc","bc"],offset:[0,4]},topLeft:{points:["bl","tc"],offset:[-(r+n),-4]},leftTop:{points:["tr","cl"],offset:[-4,-(a+n)]},topRight:{points:["br","tc"],offset:[r+n,-4]},rightTop:{points:["tl","cr"],offset:[4,-(a+n)]},bottomRight:{points:["tr","bc"],offset:[r+n,4]},rightBottom:{points:["bl","cr"],offset:[4,a+n]},bottomLeft:{points:["tl","bc"],offset:[-(r+n),4]},leftBottom:{points:["br","cl"],offset:[-4,a+n]}};return Object.keys(u).forEach(function(t){u[t]=e.arrowPointAtCenter?vt({},u[t],{overflow:Ct(l),targetOffset:wt}):vt({},bt.a[t],{overflow:Ct(l)}),u[t].ignoreShake=!0}),u}({arrowPointAtCenter:n,verticalArrowShift:8,autoAdjustOverflow:o})}},{key:"isNoTitle",value:function(){var e=this.props,t=e.title,n=e.overlay;return!t&&!n}},{key:"render",value:function(){return o.createElement(b.a,null,this.renderTooltip)}}])&&Pt(n.prototype,r),i&&Pt(n,i),t}();Nt.defaultProps={placement:"top",transitionName:"zoom-big-fast",mouseEnterDelay:.1,mouseLeaveDelay:.1,arrowPointAtCenter:!1,autoAdjustOverflow:!0},Object(p.polyfill)(Nt);var Tt=Nt;function It(e){return(It="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function Dt(e){return function(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);t0,t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e));return o.createElement(Ut.Provider,{value:{siderHook:this.getSiderHook()}},o.createElement(s,Rt({className:p},f),c))}}]),t}(),qt=Ht({suffixCls:"layout",tagName:"section"})(Wt),Xt=Ht({suffixCls:"layout-header",tagName:"header"})(Gt),$t=Ht({suffixCls:"layout-footer",tagName:"footer"})(Gt),Yt=Ht({suffixCls:"layout-content",tagName:"main"})(Gt);qt.Header=Xt,qt.Footer=$t,qt.Content=Yt;var Jt=function(e){return!isNaN(parseFloat(e))&&isFinite(e)};function Qt(e){return(Qt="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function Zt(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function en(){return(en=Object.assign||function(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:"";return sn+=1,"".concat(e).concat(sn)}),dn=function(e){function t(e){var n,r,a;return tn(this,t),(n=rn(this,an(t).call(this,e))).responsiveHandler=function(e){n.setState({below:e.matches});var t=n.props.onBreakpoint;t&&t(e.matches),n.state.collapsed!==e.matches&&n.setCollapsed(e.matches,"responsive")},n.setCollapsed=function(e,t){"collapsed"in n.props||n.setState({collapsed:e});var o=n.props.onCollapse;o&&o(e,t)},n.toggle=function(){var e=!n.state.collapsed;n.setCollapsed(e,"clickTrigger")},n.belowShowChange=function(){n.setState(function(e){return{belowShow:!e.belowShow}})},n.renderSider=function(e){var t,r=e.getPrefixCls,a=n.props,c=a.prefixCls,l=a.className,s=a.theme,f=a.collapsible,p=a.reverseArrow,y=a.trigger,d=a.style,h=a.width,m=a.collapsedWidth,b=un(a,["prefixCls","className","theme","collapsible","reverseArrow","trigger","style","width","collapsedWidth"]),v=r("layout-sider",c),O=Object(i.a)(b,["collapsed","defaultCollapsed","onCollapse","breakpoint","onBreakpoint","siderHook"]),w=n.state.collapsed?m:h,C=Jt(w)?"".concat(w,"px"):String(w),S=0===parseFloat(String(m||0))?o.createElement("span",{onClick:n.toggle,className:"".concat(v,"-zero-width-trigger ").concat(v,"-zero-width-trigger-").concat(p?"right":"left")},o.createElement(g.a,{type:"bars"})):null,P={expanded:p?o.createElement(g.a,{type:"right"}):o.createElement(g.a,{type:"left"}),collapsed:p?o.createElement(g.a,{type:"left"}):o.createElement(g.a,{type:"right"})}[n.state.collapsed?"collapsed":"expanded"],j=null!==y?S||o.createElement("div",{className:"".concat(v,"-trigger"),onClick:n.toggle,style:{width:C}},y||P):null,x=en({},d,{flex:"0 0 ".concat(C),maxWidth:C,minWidth:C,width:C}),k=u()(l,v,"".concat(v,"-").concat(s),(Zt(t={},"".concat(v,"-collapsed"),!!n.state.collapsed),Zt(t,"".concat(v,"-has-trigger"),f&&null!==y&&!S),Zt(t,"".concat(v,"-below"),!!n.state.below),Zt(t,"".concat(v,"-zero-width"),0===parseFloat(C)),t));return o.createElement("aside",en({className:k},O,{style:x}),o.createElement("div",{className:"".concat(v,"-children")},n.props.children),f||n.state.below&&S?j:null)},n.uniqueId=yn("ant-sider-"),"undefined"!=typeof window&&(r=window.matchMedia),r&&e.breakpoint&&e.breakpoint in fn&&(n.mql=r("(max-width: ".concat(fn[e.breakpoint],")"))),a="collapsed"in e?e.collapsed:e.defaultCollapsed,n.state={collapsed:a,below:!1},n}return cn(t,o["Component"]),on(t,[{key:"componentDidMount",value:function(){this.mql&&(this.mql.addListener(this.responsiveHandler),this.responsiveHandler(this.mql)),this.props.siderHook&&this.props.siderHook.addSider(this.uniqueId)}},{key:"componentWillUnmount",value:function(){this.mql&&this.mql.removeListener(this.responsiveHandler),this.props.siderHook&&this.props.siderHook.removeSider(this.uniqueId)}},{key:"render",value:function(){var e=this.state.collapsed,t=this.props.collapsedWidth;return o.createElement(pn.Provider,{value:{siderCollapsed:e,collapsedWidth:t}},o.createElement(b.a,null,this.renderSider))}}],[{key:"getDerivedStateFromProps",value:function(e){return"collapsed"in e?{collapsed:e.collapsed}:null}}]),t}();dn.defaultProps={collapsible:!1,defaultCollapsed:!1,reverseArrow:!1,width:200,collapsedWidth:80,style:{},theme:"dark"},Object(p.polyfill)(dn);function hn(e){return(hn="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function mn(){return(mn=Object.assign||function(e){for(var t=1;t=0;(t||i)&&n.restoreModeVerticalFromInline()},n.handleClick=function(e){n.handleOpenChange([]);var t=n.props.onClick;t&&t(e)},n.handleOpenChange=function(e){n.setOpenKeys(e);var t=n.props.onOpenChange;t&&t(e)},n.renderMenu=function(e){var t,r,a,c=e.getPopupContainer,l=e.getPrefixCls,s=n.state.mounted,f=n.props,p=f.prefixCls,d=f.className,h=f.theme,m=f.collapsedWidth,b=Object(i.a)(n.props,["collapsedWidth","siderCollapsed"]),v=n.getRealMenuMode(),g=n.getMenuOpenAnimation(v),O=l("menu",p),w=u()(d,"".concat(O,"-").concat(h),(t={},r="".concat(O,"-inline-collapsed"),a=n.getInlineCollapsed(),r in t?Object.defineProperty(t,r,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[r]=a,t)),C={openKeys:n.state.openKeys,onOpenChange:n.handleOpenChange,className:w,mode:v};return"inline"!==v?(C.onClick=n.handleClick,C.openTransitionName=s?g:""):C.openAnimation=s?g:{},!n.getInlineCollapsed()||0!==m&&"0"!==m&&"0px"!==m?o.createElement(y.e,Nn({getPopupContainer:c},b,C,{prefixCls:O,onTransitionEnd:n.handleTransitionEnd,onMouseEnter:n.handleMouseEnter})):null},Object(v.a)(!("onOpen"in e||"onClose"in e),"Menu","`onOpen` and `onClose` are removed, please use `onOpenChange` instead, see: https://u.ant.design/menu-on-open-change."),Object(v.a)(!("inlineCollapsed"in e&&"inline"!==e.mode),"Menu","`inlineCollapsed` should only be used when `mode` is inline."),Object(v.a)(!(void 0!==e.siderCollapsed&&"inlineCollapsed"in e),"Menu","`inlineCollapsed` not control Menu under Sider. Should set `collapsed` on Sider instead."),"openKeys"in e?r=e.openKeys:"defaultOpenKeys"in e&&(r=e.defaultOpenKeys),n.state={openKeys:r||[],switchingModeFromInline:!1,inlineOpenKeys:[],prevProps:e,mounted:!1},n}return An(t,o["Component"]),Dn(t,[{key:"componentDidMount",value:function(){var e=this;this.mountRafId=Object(En.a)(function(){e.setState({mounted:!0})},10)}},{key:"componentWillUnmount",value:function(){En.a.cancel(this.mountRafId)}},{key:"setOpenKeys",value:function(e){"openKeys"in this.props||this.setState({openKeys:e})}},{key:"getRealMenuMode",value:function(){var e=this.getInlineCollapsed();if(this.state.switchingModeFromInline&&e)return"inline";var t=this.props.mode;return e?"vertical":t}},{key:"getInlineCollapsed",value:function(){var e=this.props.inlineCollapsed;return void 0!==this.props.siderCollapsed?this.props.siderCollapsed:e}},{key:"getMenuOpenAnimation",value:function(e){var t=this.props,n=t.openAnimation,o=t.openTransitionName,r=n||o;return void 0===n&&void 0===o&&(r="horizontal"===e?"slide-up":"inline"===e?kn:this.state.switchingModeFromInline?"":"zoom-big"),r}},{key:"restoreModeVerticalFromInline",value:function(){this.state.switchingModeFromInline&&this.setState({switchingModeFromInline:!1})}},{key:"render",value:function(){return o.createElement(ct.Provider,{value:{inlineCollapsed:this.getInlineCollapsed()||!1,antdMenuTheme:this.props.theme}},o.createElement(b.a,null,this.renderMenu))}}],[{key:"getDerivedStateFromProps",value:function(e,t){var n=t.prevProps,o={prevProps:e};return"inline"===n.mode&&"inline"!==e.mode&&(o.switchingModeFromInline=!0),"openKeys"in e?o.openKeys=e.openKeys:((e.inlineCollapsed&&!n.inlineCollapsed||e.siderCollapsed&&!n.siderCollapsed)&&(o.switchingModeFromInline=!0,o.inlineOpenKeys=t.openKeys,o.openKeys=[]),(!e.inlineCollapsed&&n.inlineCollapsed||!e.siderCollapsed&&n.siderCollapsed)&&(o.openKeys=t.inlineOpenKeys,o.inlineOpenKeys=[])),o}}]),t}();Fn.defaultProps={className:"",theme:"light",focusable:!1},Object(p.polyfill)(Fn);var Ln=function(e){function t(){return Tn(this,t),Rn(this,Mn(t).apply(this,arguments))}return An(t,o["Component"]),Dn(t,[{key:"render",value:function(){var e=this;return o.createElement(pn.Consumer,null,function(t){return o.createElement(Fn,Nn({},e.props,t))})}}]),t}();function Vn(e){return(Vn="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function zn(e,t){for(var n=0;n=0}))}function qn(e){var t=e.store,n=e.data;if(!n.length)return!1;var o=Wn(Gn({},e,{data:n,type:"some",byDefaultChecked:!1}))&&!Wn(Gn({},e,{data:n,type:"every",byDefaultChecked:!1})),r=Wn(Gn({},e,{data:n,type:"some",byDefaultChecked:!0}))&&!Wn(Gn({},e,{data:n,type:"every",byDefaultChecked:!0}));return t.getState().selectionDirty?o:o||r}function Xn(e){var t=e.store,n=e.data;return!!n.length&&(t.getState().selectionDirty?Wn(Gn({},e,{data:n,type:"every",byDefaultChecked:!1})):Wn(Gn({},e,{data:n,type:"every",byDefaultChecked:!1}))||Wn(Gn({},e,{data:n,type:"every",byDefaultChecked:!0})))}Ln.Divider=y.a,Ln.Item=Cn,Ln.SubMenu=ht,Ln.ItemGroup=y.c;var $n=function(e){function t(e){var n;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),(n=Bn(this,Un(t).call(this,e))).state={checked:!1,indeterminate:!1},n.handleSelectAllChange=function(e){var t=e.target.checked;n.props.onSelect(t?"all":"removeAll",0,null)},n.defaultSelections=e.hideDefaultSelections?[]:[{key:"all",text:e.locale.selectAll,onSelect:function(){}},{key:"invert",text:e.locale.selectInvert,onSelect:function(){}}],n}var n,r,i;return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&Hn(e,t)}(t,o["Component"]),n=t,i=[{key:"getDerivedStateFromProps",value:function(e,t){var n=Xn(e),o=qn(e),r={};return o!==t.indeterminate&&(r.indeterminate=o),n!==t.checked&&(r.checked=n),r}}],(r=[{key:"componentDidMount",value:function(){this.subscribe()}},{key:"componentWillUnmount",value:function(){this.unsubscribe&&this.unsubscribe()}},{key:"setCheckState",value:function(e){var t=Xn(e),n=qn(e);this.setState(function(e){var o={};return n!==e.indeterminate&&(o.indeterminate=n),t!==e.checked&&(o.checked=t),o})}},{key:"subscribe",value:function(){var e=this,t=this.props.store;this.unsubscribe=t.subscribe(function(){e.setCheckState(e.props)})}},{key:"renderMenus",value:function(e){var t=this;return e.map(function(e,n){return o.createElement(Ln.Item,{key:e.key||n},o.createElement("div",{onClick:function(){t.props.onSelect(e.key,n,e.onSelect)}},e.text))})}},{key:"render",value:function(){var e,t,n,r=this.props,i=r.disabled,a=r.prefixCls,c=r.selections,l=r.getPopupContainer,s=this.state,f=s.checked,p=s.indeterminate,y="".concat(a,"-selection"),d=null;if(c){var h=Array.isArray(c)?this.defaultSelections.concat(c):this.defaultSelections,m=o.createElement(Ln,{className:"".concat(y,"-menu"),selectedKeys:[]},this.renderMenus(h));d=h.length>0?o.createElement(F,{overlay:m,getPopupContainer:l},o.createElement("div",{className:"".concat(y,"-down")},o.createElement(g.a,{type:"down"}))):null}return o.createElement("div",{className:y},o.createElement(ae,{className:u()((e={},t="".concat(y,"-select-all-custom"),n=d,t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e)),checked:f,indeterminate:p,disabled:i,onChange:this.handleSelectAllChange}),d)}}])&&zn(n.prototype,r),i&&zn(n,i),t}();Object(p.polyfill)($n);var Yn=$n;function Jn(e){return(Jn="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function Qn(e,t){return!t||"object"!==Jn(t)&&"function"!=typeof t?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):t}function Zn(e){return(Zn=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function eo(e,t){return(eo=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}var to=function(e){function t(){return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),Qn(this,Zn(t).apply(this,arguments))}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&eo(e,t)}(t,o["Component"]),t}();function no(e){return(no="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function oo(e,t){return!t||"object"!==no(t)&&"function"!=typeof t?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):t}function ro(e){return(ro=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function io(e,t){return(io=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}var ao=function(e){function t(){return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),oo(this,ro(t).apply(this,arguments))}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&io(e,t)}(t,o["Component"]),t}();function co(e){return(co="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function lo(){return(lo=Object.assign||function(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:"tr";return function(t){function n(e){var t;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,n),(t=so(this,fo(n).call(this,e))).store=e.store;var o=t.store.getState().selectedRowKeys;return t.state={selected:o.indexOf(e.rowKey)>=0},t}var r,a,c;return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&po(e,t)}(n,o["Component"]),r=n,(a=[{key:"componentDidMount",value:function(){this.subscribe()}},{key:"componentWillUnmount",value:function(){this.unsubscribe&&this.unsubscribe()}},{key:"subscribe",value:function(){var e=this,t=this.props,n=t.store,o=t.rowKey;this.unsubscribe=n.subscribe(function(){var t=e.store.getState().selectedRowKeys.indexOf(o)>=0;t!==e.state.selected&&e.setState({selected:t})})}},{key:"render",value:function(){var t,n,r,a=Object(i.a)(this.props,["prefixCls","rowKey","store"]),c=u()(this.props.className,(t={},n="".concat(this.props.prefixCls,"-row-selected"),r=this.state.selected,n in t?Object.defineProperty(t,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):t[n]=r,t));return o.createElement(e,lo({},a,{className:c}),this.props.children)}}])&&uo(r.prototype,a),c&&uo(r,c),n}()}ao.__ANT_TABLE_COLUMN_GROUP=!0;var ho=n(279),mo=n(72),bo=n(80);function vo(e){return(vo="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function go(){return(go=Object.assign||function(e){for(var t=1;t0&&(c.filters=l),"object"===mr(o.pagination)&&"current"in o.pagination&&(c.pagination=vr({},r,{current:n.state.pagination.current})),n.setState(c,function(){n.store.setState({selectionDirty:!1});var e=n.props.onChange;e&&e.apply(null,n.prepareParamsArguments(vr({},n.state,{selectionDirty:!1,filters:i,pagination:r})))})},n.handleSelect=function(e,t,o){var r=o.target.checked,i=o.nativeEvent,a=n.store.getState().selectionDirty?[]:n.getDefaultSelection(),c=n.store.getState().selectedRowKeys.concat(a),l=n.getRecordKey(e,t),u=n.state.pivot,s=n.getFlatCurrentPageData(),f=t;if(n.props.expandedRowRender&&(f=s.findIndex(function(e){return n.getRecordKey(e,t)===l})),i.shiftKey&&void 0!==u&&f!==u){for(var p=[],y=Math.sign(u-f),d=Math.abs(u-f),h=0,m=function(){var e=f+h*y;h+=1;var t=s[e],o=n.getRecordKey(t,e);n.getCheckboxPropsByItem(t,e).disabled||(c.includes(o)?r||(c=c.filter(function(e){return o!==e}),p.push(o)):r&&(c.push(o),p.push(o)))};h<=d;)m();n.setState({pivot:f}),n.store.setState({selectionDirty:!0}),n.setSelectedRowKeys(c,{selectWay:"onSelectMultiple",record:e,checked:r,changeRowKeys:p,nativeEvent:i})}else r?c.push(n.getRecordKey(e,f)):c=c.filter(function(e){return l!==e}),n.setState({pivot:f}),n.store.setState({selectionDirty:!0}),n.setSelectedRowKeys(c,{selectWay:"onSelect",record:e,checked:r,changeRowKeys:void 0,nativeEvent:i})},n.handleRadioSelect=function(e,t,o){var r=o.target.checked,i=o.nativeEvent,a=[n.getRecordKey(e,t)];n.store.setState({selectionDirty:!0}),n.setSelectedRowKeys(a,{selectWay:"onSelect",record:e,checked:r,changeRowKeys:void 0,nativeEvent:i})},n.handleSelectRow=function(e,t,o){var r,i=n.getFlatCurrentPageData(),a=n.store.getState().selectionDirty?[]:n.getDefaultSelection(),c=n.store.getState().selectedRowKeys.concat(a),l=i.filter(function(e,t){return!n.getCheckboxPropsByItem(e,t).disabled}).map(function(e,t){return n.getRecordKey(e,t)}),u=[],s="onSelectAll";switch(e){case"all":l.forEach(function(e){c.indexOf(e)<0&&(c.push(e),u.push(e))}),s="onSelectAll",r=!0;break;case"removeAll":l.forEach(function(e){c.indexOf(e)>=0&&(c.splice(c.indexOf(e),1),u.push(e))}),s="onSelectAll",r=!1;break;case"invert":l.forEach(function(e){c.indexOf(e)<0?c.push(e):c.splice(c.indexOf(e),1),u.push(e),s="onSelectInvert"})}n.store.setState({selectionDirty:!0});var f=n.props.rowSelection,p=2;if(f&&f.hideDefaultSelections&&(p=0),t>=p&&"function"==typeof o)return o(l);n.setSelectedRowKeys(c,{selectWay:s,checked:r,changeRowKeys:u})},n.handlePageChange=function(e){var t=n.props,o=vr({},n.state.pagination);o.current=e||(o.current||1);for(var r=arguments.length,i=new Array(r>1?r-1:0),a=1;a0){var t=this.getSortStateFromColumns(this.columns);t.sortColumn===this.state.sortColumn&&t.sortOrder===this.state.sortOrder||this.setState(t)}if(this.getFilteredValueColumns(this.columns).length>0){var n=this.getFiltersFromColumns(this.columns),o=vr({},this.state.filters);Object.keys(n).forEach(function(e){o[e]=n[e]}),this.isFiltersChanged(o)&&this.setState({filters:o})}this.createComponents(e.components,this.props.components)}},{key:"getDefaultSelection",value:function(){var e=this;return xr(this.props).getCheckboxProps?this.getFlatData().filter(function(t,n){return e.getCheckboxPropsByItem(t,n).defaultChecked}).map(function(t,n){return e.getRecordKey(t,n)}):[]}},{key:"getDefaultPagination",value:function(e){var t,n,o="object"===mr(e.pagination)?e.pagination:{};return"current"in o?t=o.current:"defaultCurrent"in o&&(t=o.defaultCurrent),"pageSize"in o?n=o.pageSize:"defaultPageSize"in o&&(n=o.defaultPageSize),this.hasPagination(e)?vr({},Er,o,{current:t||1,pageSize:n||10}):{}}},{key:"getSortOrderColumns",value:function(e){return Fe(e||this.columns||[],function(e){return"sortOrder"in e})}},{key:"getFilteredValueColumns",value:function(e){return Fe(e||this.columns||[],function(e){return void 0!==e.filteredValue})}},{key:"getFiltersFromColumns",value:function(e){var t={};return this.getFilteredValueColumns(e).forEach(function(e){var n=kr(e);t[n]=e.filteredValue}),t}},{key:"getDefaultSortOrder",value:function(e){var t=this.getSortStateFromColumns(e),n=Fe(e||[],function(e){return null!=e.defaultSortOrder})[0];return n&&!t.sortColumn?{sortColumn:n,sortOrder:n.defaultSortOrder}:t}},{key:"getSortStateFromColumns",value:function(e){var t=this.getSortOrderColumns(e).filter(function(e){return e.sortOrder})[0];return t?{sortColumn:t,sortOrder:t.sortOrder}:{sortColumn:null,sortOrder:null}}},{key:"getMaxCurrent",value:function(e){var t=this.state.pagination,n=t.current,o=t.pageSize;return(n-1)*o>=e?Math.floor((e-1)/o)+1:n}},{key:"getSorterFn",value:function(e){var t=e||this.state,n=t.sortOrder,o=t.sortColumn;if(n&&o&&"function"==typeof o.sorter)return function(e,t){var r=o.sorter(e,t,n);return 0!==r?"descend"===n?-r:r:0}}},{key:"getCurrentPageData",value:function(){var e,t,n=this.getLocalData(),o=this.state;return this.hasPagination()?(t=o.pagination.pageSize,e=this.getMaxCurrent(o.pagination.total||n.length)):(t=Number.MAX_VALUE,e=1),(n.length>t||t===Number.MAX_VALUE)&&(n=n.filter(function(n,o){return o>=(e-1)*t&&o1&&void 0!==arguments[1])||arguments[1],o=e||this.state,r=this.props.dataSource,i=r||[];i=i.slice(0);var a=this.getSorterFn(o);return a&&(i=this.recursiveSort(i,a)),n&&o.filters&&Object.keys(o.filters).forEach(function(e){var n=t.findColumn(e);if(n){var r=o.filters[e]||[];if(0!==r.length){var a=n.onFilter;i=a?i.filter(function(e){return r.some(function(t){return a(t,e)})}):i}}}),i}},{key:"setSelectedRowKeys",value:function(e,t){var n=this,o=t.selectWay,r=t.record,i=t.checked,a=t.changeRowKeys,c=t.nativeEvent,l=xr(this.props);!l||"selectedRowKeys"in l||this.store.setState({selectedRowKeys:e});var u=this.getFlatData();if(l.onChange||l[o]){var s=u.filter(function(t,o){return e.indexOf(n.getRecordKey(t,o))>=0});if(l.onChange&&l.onChange(e,s),"onSelect"===o&&l.onSelect)l.onSelect(r,i,s,c);else if("onSelectMultiple"===o&&l.onSelectMultiple){var f=u.filter(function(e,t){return a.indexOf(n.getRecordKey(e,t))>=0});l.onSelectMultiple(i,s,f)}else if("onSelectAll"===o&&l.onSelectAll){var p=u.filter(function(e,t){return a.indexOf(n.getRecordKey(e,t))>=0});l.onSelectAll(i,s,p)}else"onSelectInvert"===o&&l.onSelectInvert&&l.onSelectInvert(e)}}},{key:"toggleSortOrder",value:function(e){if(e.sorter){var t,n,o,r=vr({},this.state.pagination),i=e.sortDirections||this.props.sortDirections,a=this.state,c=a.sortOrder,l=a.sortColumn;if(o=e,((n=l)&&o&&n.key&&n.key===o.key||n===o||f()(n,o,function(e,t){if("function"==typeof e&&"function"==typeof t)return e===t||e.toString()===t.toString()}))&&void 0!==c){var u=i.indexOf(c)+1;t=u===i.length?void 0:i[u]}else t=i[0];this.props.pagination&&(r.current=1,r.onChange(r.current));var s={pagination:r,sortOrder:t,sortColumn:t?e:null};0===this.getSortOrderColumns().length&&this.setState(s);var p=this.props.onChange;p&&p.apply(null,this.prepareParamsArguments(vr({},this.state,s)))}}},{key:"hasPagination",value:function(e){return!1!==(e||this.props).pagination}},{key:"isFiltersChanged",value:function(e){var t=this,n=!1;return Object.keys(e).length!==Object.keys(this.state.filters).length?n=!0:Object.keys(e).forEach(function(o){e[o]!==t.state.filters[o]&&(n=!0)}),n}},{key:"isSortColumn",value:function(e){var t=this.state.sortColumn;return!(!e||!t)&&kr(t)===kr(e)}},{key:"prepareParamsArguments",value:function(e){var t=vr({},e.pagination);delete t.onChange,delete t.onShowSizeChange;var n=e.filters,o={};return e.sortColumn&&e.sortOrder&&(o.column=e.sortColumn,o.order=e.sortOrder,o.field=e.sortColumn.dataIndex,o.columnKey=kr(e.sortColumn)),[t,n,o,{currentDataSource:this.getLocalData(e)}]}},{key:"findColumn",value:function(e){var t;return Ke(this.columns,function(n){kr(n)===e&&(t=n)}),t}},{key:"createComponents",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1?arguments[1]:void 0,n=e&&e.body&&e.body.row,o=t&&t.body&&t.body.row;this.row&&n===o||(this.row=yo(n)),this.components=vr({},e,{body:vr({},e.body,{row:this.row})})}},{key:"recursiveSort",value:function(e,t){var n=this,o=this.props.childrenColumnName,r=void 0===o?"children":o;return e.sort(t).map(function(e){return e[r]?vr({},e,br({},r,n.recursiveSort(e[r],t))):e})}},{key:"renderPagination",value:function(e,t){if(!this.hasPagination())return null;var n="default",r=this.state.pagination;r.size?n=r.size:"middle"!==this.props.size&&"small"!==this.props.size||(n="small");var i=r.position||"bottom",a=r.total||this.getLocalData().length;return a>0&&(i===t||"both"===i)?o.createElement(Ho,vr({key:"pagination-".concat(t)},r,{className:u()(r.className,"".concat(e,"-pagination")),onChange:this.handlePageChange,total:a,size:n,current:this.getMaxCurrent(a),onShowSizeChange:this.handleShowSizeChange})):null}},{key:"renderRowSelection",value:function(e){var t=this,n=e.prefixCls,r=e.locale,i=e.getPopupContainer,c=this.props.rowSelection,l=this.columns.concat();if(c){var s=this.getFlatCurrentPageData().filter(function(e,n){return!c.getCheckboxProps||!t.getCheckboxPropsByItem(e,n).disabled}),f=u()("".concat(n,"-selection-column"),br({},"".concat(n,"-selection-column-custom"),c.selections)),p=br({key:"selection-column",render:this.renderSelectionBox(c.type),className:f,fixed:c.fixed,width:c.columnWidth,title:c.columnTitle},a.a,{className:"".concat(n,"-selection-col")});if("radio"!==c.type){var y=s.every(function(e,n){return t.getCheckboxPropsByItem(e,n).disabled});p.title=p.title||o.createElement(Yn,{store:this.store,locale:r,data:s,getCheckboxPropsByItem:this.getCheckboxPropsByItem,getRecordKey:this.getRecordKey,disabled:y,prefixCls:n,onSelect:this.handleSelectRow,selections:c.selections,hideDefaultSelections:c.hideDefaultSelections,getPopupContainer:this.generatePopupContainerFunc(i)})}"fixed"in c?p.fixed=c.fixed:l.some(function(e){return"left"===e.fixed||!0===e.fixed})&&(p.fixed="left"),l[0]&&"selection-column"===l[0].key?l[0]=p:l.unshift(p)}return l}},{key:"renderColumnsDropdown",value:function(e){var t=this,n=e.prefixCls,r=e.dropdownPrefixCls,i=e.columns,a=e.locale,c=e.getPopupContainer,l=this.state,s=l.sortOrder,f=l.filters;return Ke(i,function(e,i){var l,p,y,d=kr(e,i),h=e.onHeaderCell,m=t.isSortColumn(e);if(e.filters&&e.filters.length>0||e.filterDropdown){var b=d in f?f[d]:[];p=o.createElement($e,{locale:a,column:e,selectedKeys:b,confirmFilter:t.handleFilter,prefixCls:"".concat(n,"-filter"),dropdownPrefixCls:r||"ant-dropdown",getPopupContainer:t.generatePopupContainerFunc(c),key:"filter-dropdown"})}if(e.sorter){var v=e.sortDirections||t.props.sortDirections,O=m&&"ascend"===s,w=m&&"descend"===s,C=-1!==v.indexOf("ascend")&&o.createElement(g.a,{className:"".concat(n,"-column-sorter-up ").concat(O?"on":"off"),type:"caret-up",theme:"filled"}),S=-1!==v.indexOf("descend")&&o.createElement(g.a,{className:"".concat(n,"-column-sorter-down ").concat(w?"on":"off"),type:"caret-down",theme:"filled"});y=o.createElement("div",{title:a.sortTitle,className:u()("".concat(n,"-column-sorter-inner"),C&&S&&"".concat(n,"-column-sorter-inner-full")),key:"sorter"},C,S),h=function(n){var o={};e.onHeaderCell&&(o=vr({},e.onHeaderCell(n)));var r=o.onClick;return o.onClick=function(){t.toggleSortOrder(e),r&&r.apply(void 0,arguments)},o}}return vr({},e,{className:u()(e.className,(l={},br(l,"".concat(n,"-column-has-actions"),y||p),br(l,"".concat(n,"-column-has-filters"),p),br(l,"".concat(n,"-column-has-sorters"),y),br(l,"".concat(n,"-column-sort"),m&&s),l)),title:[o.createElement("span",{key:"title",className:"".concat(n,"-header-column")},o.createElement("div",{className:y?"".concat(n,"-column-sorters"):void 0},o.createElement("span",{className:"".concat(n,"-column-title")},t.renderColumnTitle(e.title)),o.createElement("span",{className:"".concat(n,"-column-sorter")},y))),p],onHeaderCell:h})})}},{key:"renderColumnTitle",value:function(e){var t=this.state,n=t.filters,o=t.sortOrder;return e instanceof Function?e({filters:n,sortOrder:o}):e}},{key:"render",value:function(){return o.createElement(b.a,null,this.renderComponent)}}])&&gr(n.prototype,c),l&&gr(n,l),t}();Nr.Column=to,Nr.ColumnGroup=ao,Nr.propTypes={dataSource:c.array,columns:c.array,prefixCls:c.string,useFixedHeader:c.bool,rowSelection:c.object,className:c.string,size:c.string,loading:c.oneOfType([c.bool,c.object]),bordered:c.bool,onChange:c.func,locale:c.object,dropdownPrefixCls:c.string,sortDirections:c.array,getPopupContainer:c.func},Nr.defaultProps={dataSource:[],useFixedHeader:!1,className:"",size:"default",loading:!1,bordered:!1,indentSize:20,locale:{},rowKey:"key",showHeader:!0,sortDirections:["ascend","descend"],childrenColumnName:"children"};t.a=Nr},628:function(e,t,n){"use strict";var o=n(1),r=n(8),i=n(0),a=n(4),c=n.n(a),l=n(22),u=n(10),s=n(20),f=n(9),p=n(19),y=n.n(p);function d(e){return function(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);te.top-n)return n+t.top}function x(e,t,n){if(void 0!==n&&t.bottom=0;c--)(r=e[c])&&(a=(i<3?r(a):i>3?r(t,n,a):r(t,n))||a);return i>3&&a&&Object.defineProperty(t,n,a),a};!function(e){e[e.None=0]="None",e[e.Prepare=1]="Prepare"}(K||(K={}));var L=function(e){function t(){var e;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),(e=D(this,R(t).apply(this,arguments))).state={status:K.None,lastAffix:!1,prevTarget:null},e.getOffsetTop=function(){var t=e.props,n=t.offset,o=t.offsetBottom,r=e.props.offsetTop;return void 0===r&&(r=n,Object(S.a)(void 0===n,"Affix","`offset` is deprecated. Please use `offsetTop` instead.")),void 0===o&&void 0===r&&(r=0),r},e.getOffsetBottom=function(){return e.props.offsetBottom},e.savePlaceholderNode=function(t){e.placeholderNode=t},e.saveFixedNode=function(t){e.fixedNode=t},e.measure=function(){var t=e.state,n=t.status,o=t.lastAffix,r=e.props,i=r.target,a=r.onChange;if(n===K.Prepare&&e.fixedNode&&e.placeholderNode&&i){var c=e.getOffsetTop(),l=e.getOffsetBottom(),u=i();if(u){var s={status:K.None},f=P(u),p=P(e.placeholderNode),y=j(p,f,c),d=x(p,f,l);void 0!==y?(s.affixStyle={position:"fixed",top:y,width:p.width,height:p.height},s.placeholderStyle={width:p.width,height:p.height}):void 0!==d&&(s.affixStyle={position:"fixed",bottom:d,width:p.width,height:p.height},s.placeholderStyle={width:p.width,height:p.height}),s.lastAffix=!!s.affixStyle,a&&o!==s.lastAffix&&a(s.lastAffix),e.setState(s)}}},e.prepareMeasure=function(){e.setState({status:K.Prepare,affixStyle:void 0,placeholderStyle:void 0})},e.renderAffix=function(t){var n,r,i,a=t.getPrefixCls,l=e.state,u=l.affixStyle,f=l.placeholderStyle,p=e.props,y=p.prefixCls,d=p.children,h=c()((n={},r=a("affix",y),i=u,r in n?Object.defineProperty(n,r,{value:i,enumerable:!0,configurable:!0,writable:!0}):n[r]=i,n)),m=Object(s.a)(e.props,["prefixCls","offsetTop","offsetBottom","target","onChange"]);return o.createElement(C,{onResize:function(){e.updatePosition()}},o.createElement("div",T({},m,{ref:e.savePlaceholderNode}),u&&o.createElement("div",{style:f,"aria-hidden":"true"}),o.createElement("div",{className:h,ref:e.saveFixedNode,style:u},o.createElement(C,{onResize:function(){e.updatePosition()}},d))))},e}var n,r,i;return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&M(e,t)}(t,o["Component"]),n=t,(r=[{key:"componentDidMount",value:function(){var e=this,t=this.props.target;t&&(this.timeout=setTimeout(function(){_(t(),e),e.updatePosition()}))}},{key:"componentDidUpdate",value:function(e){var t=this.state.prevTarget,n=this.props.target,o=null;n&&(o=n()||null),t!==o&&(N(this),o&&(_(o,this),this.updatePosition()),this.setState({prevTarget:o})),e.offsetTop===this.props.offsetTop&&e.offsetBottom===this.props.offsetBottom||this.updatePosition(),this.measure()}},{key:"componentWillUnmount",value:function(){clearTimeout(this.timeout),N(this),this.updatePosition.cancel()}},{key:"updatePosition",value:function(){this.prepareMeasure()}},{key:"lazyUpdatePosition",value:function(){var e=this.props.target,t=this.state.affixStyle;if(e&&t){var n=this.getOffsetTop(),o=this.getOffsetBottom(),r=e();if(r){var i=P(r),a=P(this.placeholderNode),c=j(a,i,n),l=x(a,i,o);if(void 0!==c&&t.top===c||void 0!==l&&t.bottom===l)return}}this.prepareMeasure()}},{key:"render",value:function(){return o.createElement(f.a,null,this.renderAffix)}}])&&I(n.prototype,r),i&&I(n,i),t}();L.defaultProps={target:function(){return"undefined"!=typeof window?window:null}},F([h()],L.prototype,"updatePosition",null),F([h()],L.prototype,"lazyUpdatePosition",null),Object(u.polyfill)(L);var V=L;function z(e,t){if("undefined"==typeof window)return 0;var n=t?"scrollTop":"scrollLeft",o=e===window,r=o?e[t?"pageYOffset":"pageXOffset"]:e[n];return o&&"number"!=typeof r&&(r=document.documentElement[n]),r}function B(e){return(B="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function U(){return(U=Object.assign||function(e){for(var t=1;t1&&void 0!==arguments[1]?arguments[1]:{},n=t.getContainer,o=void 0===n?function(){return window}:n,r=t.callback,i=t.duration,a=void 0===i?450:i,c=o(),l=z(c,!0),u=Date.now();y()(function t(){var n,o,i,s=Date.now()-u,f=(n=s>a?a:s,i=e-(o=l),(n/=a/2)<1?i/2*n*n*n+o:i/2*((n-=2)*n*n+2)+o);c===window?window.scrollTo(window.pageXOffset,f):c.scrollTop=f,s0&&void 0!==arguments[0]?arguments[0]:0,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:5,n=this.props.getCurrentAnchor;if("function"==typeof n)return n();var o="";if("undefined"==typeof document)return o;var r=[],i=this.props.getContainer,a=i();if(this.links.forEach(function(n){var o=$.exec(n.toString());if(o){var i=document.getElementById(o[1]);if(i){var c=X(i,a);ce.top?t:e});return c.link}return""}},{key:"render",value:function(){return o.createElement(f.a,null,this.renderAnchor)}}])&&H(n.prototype,i),a&&H(n,a),t}();function J(e){return(J="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function Q(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Z(e,t){for(var n=0;n=0)){var r=e.props.insertExtraNode;e.extraNode=document.createElement("div");var i=v(e).extraNode;i.className="ant-click-animating-node";var a,c=e.getAttributeName();t.setAttribute(c,"true"),o=o||document.createElement("style"),!n||"#ffffff"===n||"rgb(255, 255, 255)"===n||(a=(n||"").match(/rgba?\((\d*), (\d*), (\d*)(, [\.\d]*)?\)/))&&a[1]&&a[2]&&a[3]&&a[1]===a[2]&&a[2]===a[3]||/rgba\(\d*, \d*, \d*, 0\)/.test(n)||"transparent"===n||(e.csp&&e.csp.nonce&&(o.nonce=e.csp.nonce),i.style.borderColor=n,o.innerHTML="\n [ant-click-animating-without-extra-node='true']::after, .ant-click-animating-node {\n --antd-wave-shadow-color: ".concat(n,";\n }"),document.body.contains(o)||document.body.appendChild(o)),r&&t.appendChild(i),y.a.addStartEventListener(t,e.onTransitionStart),y.a.addEndEventListener(t,e.onTransitionEnd)}},e.onTransitionStart=function(t){if(!e.destroy){var n=Object(p.findDOMNode)(v(e));t&&t.target===n&&(e.animationStart||e.resetEffect(n))}},e.onTransitionEnd=function(t){t&&"fadeEffect"===t.animationName&&e.resetEffect(t.target)},e.bindAnimationEvent=function(t){if(t&&t.getAttribute&&!t.getAttribute("disabled")&&!(t.className.indexOf("disabled")>=0)){var n=function(n){if("INPUT"!==n.target.tagName&&!O(n.target)){e.resetEffect(t);var o=getComputedStyle(t).getPropertyValue("border-top-color")||getComputedStyle(t).getPropertyValue("border-color")||getComputedStyle(t).getPropertyValue("background-color");e.clickWaveTimeoutId=window.setTimeout(function(){return e.onClick(t,o)},0),d.a.cancel(e.animationStartId),e.animationStart=!0,e.animationStartId=Object(d.a)(function(){e.animationStart=!1},10)}};return t.addEventListener("click",n,!0),{cancel:function(){t.removeEventListener("click",n,!0)}}}},e.renderWave=function(t){var n=t.csp,o=e.props.children;return e.csp=n,o},e}var n,i,a;return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&g(e,t)}(t,r["Component"]),n=t,(i=[{key:"componentDidMount",value:function(){var e=Object(p.findDOMNode)(this);e&&1===e.nodeType&&(this.instance=this.bindAnimationEvent(e))}},{key:"componentWillUnmount",value:function(){this.instance&&this.instance.cancel(),this.clickWaveTimeoutId&&clearTimeout(this.clickWaveTimeoutId),this.destroy=!0}},{key:"getAttributeName",value:function(){return this.props.insertExtraNode?"ant-click-animating":"ant-click-animating-without-extra-node"}},{key:"resetEffect",value:function(e){if(e&&e!==this.extraNode&&e instanceof Element){var t=this.props.insertExtraNode,n=this.getAttributeName();e.setAttribute(n,"false"),o&&(o.innerHTML=""),t&&this.extraNode&&e.contains(this.extraNode)&&e.removeChild(this.extraNode),y.a.removeStartEventListener(e,this.onTransitionStart),y.a.removeEndEventListener(e,this.onTransitionEnd)}}},{key:"render",value:function(){return r.createElement(f.a,null,this.renderWave)}}])&&m(n.prototype,i),a&&m(n,a),t}(),C=n(24);function S(){return(S=Object.assign||function(e){for(var t=1;tUForm
-------------------------------------------------------------------------------- /examples/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env", "@babel/preset-react"], 3 | "plugins": ["@babel/plugin-transform-runtime"] 4 | } 5 | -------------------------------------------------------------------------------- /examples/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "examples", 3 | "version": "0.2.1", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server --config ./tools/webpack.dev.config.js", 8 | "build": "webpack --config ./tools/webpack.prod.config.js" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "@babel/core": "^7.5.5", 14 | "@babel/plugin-transform-runtime": "^7.5.5", 15 | "@babel/polyfill": "^7.4.4", 16 | "@babel/preset-env": "^7.5.5", 17 | "@babel/preset-react": "^7.0.0", 18 | "@babel/runtime": "^7.5.5", 19 | "babel-loader": "^8.0.6", 20 | "compression-webpack-plugin": "^3.0.0", 21 | "css-loader": "^3.2.0", 22 | "css-split-webpack-plugin": "^0.2.6", 23 | "file-loader": "^4.2.0", 24 | "html-webpack-plugin": "^3.2.0", 25 | "mini-css-extract-plugin": "^0.8.0", 26 | "optimize-css-assets-webpack-plugin": "^5.0.3", 27 | "react": "^16.9.0", 28 | "react-dom": "^16.9.0", 29 | "react-highlight.js": "^1.0.7", 30 | "sass-loader": "^7.3.1", 31 | "uform": "^0.1.5", 32 | "url-loader": "^2.1.0", 33 | "webpack-bundle-analyzer": "^3.4.1", 34 | "webpack-merge": "^4.2.1" 35 | }, 36 | "dependencies": { 37 | "antd": "^3.22.2" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /examples/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | UForm 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /examples/src/components/ApiBlock.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Table } from "antd"; 3 | 4 | function ApiTable(props) { 5 | const data = props.data || []; 6 | const columns = props.columns || []; 7 | return
; 8 | } 9 | 10 | export default ApiTable; 11 | -------------------------------------------------------------------------------- /examples/src/components/CodeBlock.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import { Icon } from "antd"; 3 | import Hightlight from "react-highlight.js"; 4 | 5 | function CodeBlock(props) { 6 | const { children, code } = props; 7 | const [collapse, setCollapse] = useState(true); 8 | return ( 9 |
10 |
{children}
11 |
12 |
setCollapse(!collapse)}> 13 | {collapse ? ( 14 |
15 | 16 | 展开代码 17 |
18 | ) : ( 19 |
20 | 21 | 收起代码 22 |
23 | )} 24 |
25 |
26 |
27 | 28 | {code} 29 | 30 |
31 |
32 | ); 33 | } 34 | 35 | export default CodeBlock; 36 | -------------------------------------------------------------------------------- /examples/src/components/PageAnchor.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Anchor } from "antd"; 3 | 4 | const { Link } = Anchor; 5 | 6 | function PageAnchor(props) { 7 | const links = props.links || []; 8 | const renderChildLinks = (items) => 9 | items.map((item) => ); 10 | return ( 11 |
12 | 13 | {links.map((item) => { 14 | if (!item.children) return ; 15 | return ( 16 | 17 | {renderChildLinks(item.children)} 18 | 19 | ); 20 | })} 21 | 22 |
23 | ); 24 | } 25 | 26 | export default PageAnchor; 27 | -------------------------------------------------------------------------------- /examples/src/css/hightlight.scss: -------------------------------------------------------------------------------- 1 | .hljs { 2 | display: block; 3 | overflow-x: auto; 4 | padding: .5em; 5 | background: #232323; 6 | color: #e6e1dc 7 | } 8 | 9 | .hljs-comment, 10 | .hljs-quote { 11 | color: #bc9458; 12 | font-style: italic 13 | } 14 | 15 | .hljs-keyword, 16 | .hljs-selector-tag { 17 | color: #c26230 18 | } 19 | 20 | .hljs-string, 21 | .hljs-number, 22 | .hljs-regexp, 23 | .hljs-variable, 24 | .hljs-template-variable { 25 | color: #a5c261 26 | } 27 | 28 | .hljs-subst { 29 | color: #519f50 30 | } 31 | 32 | .hljs-tag, 33 | .hljs-name { 34 | color: #e8bf6a 35 | } 36 | 37 | .hljs-type { 38 | color: #da4939 39 | } 40 | 41 | .hljs-symbol, 42 | .hljs-bullet, 43 | .hljs-built_in, 44 | .hljs-builtin-name, 45 | .hljs-attr, 46 | .hljs-link { 47 | color: #6d9cbe 48 | } 49 | 50 | .hljs-params { 51 | color: #d0d0ff 52 | } 53 | 54 | .hljs-attribute { 55 | color: #cda869 56 | } 57 | 58 | .hljs-meta { 59 | color: #9b859d 60 | } 61 | 62 | .hljs-title, 63 | .hljs-section { 64 | color: #ffc66d 65 | } 66 | 67 | .hljs-addition { 68 | background-color: #144212; 69 | color: #e6e1dc; 70 | display: inline-block; 71 | width: 100% 72 | } 73 | 74 | .hljs-deletion { 75 | background-color: #600; 76 | color: #e6e1dc; 77 | display: inline-block; 78 | width: 100% 79 | } 80 | 81 | .hljs-selector-class { 82 | color: #9b703f 83 | } 84 | 85 | .hljs-selector-id { 86 | color: #8b98ab 87 | } 88 | 89 | .hljs-emphasis { 90 | font-style: italic 91 | } 92 | 93 | .hljs-strong { 94 | font-weight: bold 95 | } 96 | 97 | .hljs-link { 98 | text-decoration: underline 99 | } -------------------------------------------------------------------------------- /examples/src/css/main.scss: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; 3 | font-size: 16px; 4 | background-color: #ffffff; 5 | color: #000; 6 | } 7 | 8 | div, 9 | h1, 10 | h2, 11 | h3, 12 | h4, 13 | h5 { 14 | box-sizing: border-box; 15 | } 16 | 17 | h1, 18 | h2, 19 | h3, 20 | h4, 21 | h5 { 22 | font-weight: bold; 23 | } 24 | 25 | h2 { 26 | margin: 30px 0 10px; 27 | } 28 | 29 | #root { 30 | width: 70%; 31 | padding: 0 15px 20px 0; 32 | margin: 0 0 40px 140px; 33 | 34 | .page-anchor { 35 | position: fixed; 36 | right: 100px; 37 | top: 100px; 38 | } 39 | 40 | .demo-container { 41 | .page-header { 42 | padding-bottom: 9px; 43 | margin: 40px 0 20px; 44 | border-bottom: 1px solid #eee; 45 | 46 | a { 47 | cursor: pointer; 48 | font-size: 20px; 49 | color: #337ab7; 50 | text-decoration: none; 51 | 52 | &:hover { 53 | text-decoration: underline; 54 | } 55 | } 56 | } 57 | } 58 | 59 | .description { 60 | margin-bottom: 20px; 61 | font-size: 20px; 62 | font-weight: normal; 63 | line-height: 1.8; 64 | } 65 | 66 | .use-block { 67 | .step { 68 | font-size: 16px; 69 | margin-bottom: 10px; 70 | } 71 | 72 | .step-code { 73 | .javascript { 74 | padding-left: 20px; 75 | } 76 | } 77 | } 78 | 79 | 80 | .demo-box-container { 81 | width: 100%; 82 | margin: 20px 0 20px; 83 | 84 | .demo-box { 85 | width: 100%; 86 | 87 | h3 { 88 | margin-bottom: 10px; 89 | } 90 | } 91 | 92 | .modal-form-demo-box { 93 | .code-box { 94 | padding-top: 20px; 95 | } 96 | 97 | .code-html { 98 | padding: 0; 99 | height: 80px; 100 | } 101 | } 102 | 103 | .code-html { 104 | padding: 40px 0 10px; 105 | 106 | .button-container { 107 | display: flex; 108 | justify-content: center; 109 | padding: 20px 100px 0; 110 | } 111 | } 112 | 113 | .code-box { 114 | width: 100%; 115 | border-radius: 2px; 116 | border: 1px solid #ccc; 117 | 118 | .code-collapse-box { 119 | margin-top: 5px; 120 | height: 40px; 121 | line-height: 40px; 122 | text-align: center; 123 | border-top: 1px solid #dddddd; 124 | 125 | .code-collapse { 126 | cursor: pointer; 127 | 128 | &:hover { 129 | color: #1890ff; 130 | } 131 | } 132 | } 133 | 134 | .code-block { 135 | overflow: auto; 136 | transition: height 0.2s; 137 | 138 | .code { 139 | .javascript { 140 | padding: 0 50px 20px; 141 | } 142 | } 143 | } 144 | } 145 | } 146 | 147 | .api-container { 148 | h3:nth-child(n+2) { 149 | margin: 15px 0 10px; 150 | } 151 | 152 | .api-explain { 153 | margin: 20px 0 10px; 154 | 155 | .bold { 156 | font-weight: bold; 157 | color: #c41d7f; 158 | } 159 | } 160 | 161 | .api-block { 162 | .ant-table { 163 | font-size: 16px; 164 | 165 | .api-table-attribute { 166 | font-weight: bold; 167 | } 168 | 169 | .api-table-type { 170 | color: #c41d7f; 171 | } 172 | 173 | .api-table-required { 174 | color: #0aa679; 175 | } 176 | 177 | .api-table-values { 178 | color: #1890ff; 179 | } 180 | } 181 | } 182 | } 183 | 184 | } -------------------------------------------------------------------------------- /examples/src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import App from "./views/App"; 4 | 5 | ReactDOM.render(, document.getElementById("root")); 6 | -------------------------------------------------------------------------------- /examples/src/views/App.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import Hightlight from "react-highlight.js"; 3 | import CodeBlock from "../components/CodeBlock"; 4 | import ApiBlock from "../components/ApiBlock"; 5 | import PageAnchor from "../components/PageAnchor"; 6 | import NormalForm, { NormalFormCode } from "./NormalForm"; 7 | import ModalForm, { ModalFormCode } from "./ModalForm"; 8 | import "antd/dist/antd.css"; 9 | import "../css/main.scss"; 10 | import "../css/hightlight.scss"; 11 | 12 | class App extends Component { 13 | constructor(props) { 14 | super(props); 15 | this.componentStep = ``; 22 | this.apiColumns = [ 23 | { 24 | title: "属性", 25 | dataIndex: "attribute", 26 | key: "atttibute", 27 | width: 220, 28 | render: (text) =>
{text}
29 | }, 30 | { 31 | title: "说明", 32 | dataIndex: "explain", 33 | key: "explain", 34 | width: 220 35 | }, 36 | { 37 | title: "必填属性", 38 | dataIndex: "required", 39 | key: "required", 40 | width: 130, 41 | render: (text) => ( 42 |
47 | {text} 48 |
49 | ) 50 | }, 51 | { 52 | title: "类型", 53 | dataIndex: "type", 54 | key: "type", 55 | width: 200, 56 | render: (text) =>
{text}
57 | }, 58 | { 59 | title: "可选值", 60 | dataIndex: "values", 61 | key: "values", 62 | render: (text) =>
{text}
63 | }, 64 | { 65 | title: "默认值", 66 | dataIndex: "defaultValue", 67 | key: "defaultValue", 68 | width: 150 69 | } 70 | ]; 71 | this.commonApi = [ 72 | { 73 | key: "1", 74 | attribute: "type", 75 | explain: "使用通用表单或者弹框表单", 76 | required: "false", 77 | type: "string", 78 | values: "norma | modal", 79 | defaultValue: "normal" 80 | }, 81 | { 82 | key: "2", 83 | attribute: "layout", 84 | required: "false", 85 | explain: "表单布局", 86 | type: "string", 87 | values: "horizontal | vertical | inline", 88 | defaultValue: "horizontal" 89 | }, 90 | { 91 | key: "3", 92 | attribute: "labelCol", 93 | explain: "表单label占宽", 94 | required: "false", 95 | type: "number", 96 | values: "1-24之间整数", 97 | defaultValue: "4" 98 | }, 99 | { 100 | key: "4", 101 | attribute: "wrapperCol", 102 | explain: "表单内容项占宽", 103 | required: "false", 104 | type: "number", 105 | values: "1-24之间整数,通常为24-labelCol", 106 | defaultValue: "16" 107 | }, 108 | { 109 | key: "6", 110 | attribute: "loading", 111 | explain: "确定按钮 loading", 112 | required: "false", 113 | type: "boolean", 114 | values: "true | false", 115 | defaultValue: "false" 116 | }, 117 | { 118 | key: "5", 119 | attribute: "data", 120 | explain: "表单数据", 121 | required: "true", 122 | type: "any[ ]", 123 | values: "-", 124 | defaultValue: "[ ]" 125 | }, 126 | { 127 | key: "7", 128 | attribute: "fields", 129 | explain: "表单每一项特征描述", 130 | required: "true", 131 | type: "any[ ]", 132 | values: "-", 133 | defaultValue: "[ ]" 134 | }, 135 | { 136 | key: "8", 137 | attribute: "onSubmit", 138 | explain: "表单提交回调", 139 | required: "true", 140 | type: "Function(values)", 141 | values: "-", 142 | defaultValue: "无" 143 | }, 144 | { 145 | key: "9", 146 | attribute: "onChange", 147 | explain: "表单每一项修改回调", 148 | required: "false", 149 | type: "Function(value)", 150 | values: "-", 151 | defaultValue: "无" 152 | }, 153 | { 154 | key: "10", 155 | attribute: "onCancel", 156 | explain: "表单取消回调", 157 | required: "false", 158 | type: "Function( )", 159 | values: "-", 160 | defaultValue: "无" 161 | } 162 | ]; 163 | this.normalFormApi = [ 164 | { 165 | key: "1", 166 | attribute: "showCancelButton", 167 | explain: "是否展示取消按钮", 168 | required: "false", 169 | type: "boolean", 170 | values: "true | false", 171 | defaultValue: "true" 172 | } 173 | ]; 174 | this.modelFormApi = [ 175 | { 176 | key: "1", 177 | attribute: "visible", 178 | explain: "弹框是否可见", 179 | required: "true", 180 | type: "boolean", 181 | values: "true | false", 182 | defaultValue: "true" 183 | }, 184 | { 185 | key: "2", 186 | attribute: "title", 187 | explain: "弹框标题", 188 | required: "true", 189 | type: "string | ReactNode", 190 | values: "-", 191 | defaultValue: "无" 192 | }, 193 | { 194 | key: "3", 195 | attribute: "width", 196 | required: "false", 197 | explain: "弹框宽度", 198 | type: "number", 199 | values: "-", 200 | defaultValue: "600" 201 | } 202 | ]; 203 | this.fieldsApi = [ 204 | { 205 | key: "1", 206 | attribute: "name", 207 | explain: "表单数据name,与data中key值一致", 208 | required: "true", 209 | type: "string", 210 | values: "-", 211 | defaultValue: "无" 212 | }, 213 | { 214 | key: "2", 215 | attribute: "type", 216 | explain: "表单项类型", 217 | required: "true", 218 | type: "string", 219 | values: 220 | "input | inputNumber | textarea | select | radio | checkbox | password | switch | rate | custom(自定义项)", 221 | defaultValue: "无" 222 | }, 223 | { 224 | key: "3", 225 | attribute: "label", 226 | explain: "表单项label", 227 | required: "true", 228 | type: "string", 229 | values: "-", 230 | defaultValue: "无" 231 | }, 232 | { 233 | key: "4", 234 | attribute: "rules", 235 | explain: "表单项限制规则,与antd Form限制规则一致", 236 | required: "false", 237 | type: "object [ ]", 238 | values: "-", 239 | defaultValue: "无" 240 | }, 241 | { 242 | key: "5", 243 | attribute: "fieldData", 244 | explain: "适用于type为select/radio的选择项", 245 | required: "true", 246 | type: "object [ ]", 247 | values: "-", 248 | defaultValue: "无" 249 | }, 250 | { 251 | key: "6", 252 | attribute: "placehoder", 253 | explain: "适用于type为input/textarea/select的提示信息", 254 | required: "false", 255 | type: "string", 256 | values: "-", 257 | defaultValue: "无" 258 | }, 259 | { 260 | key: "7", 261 | attribute: "node", 262 | explain: "适用于type为custom的自定义ReactNode", 263 | required: "true", 264 | type: "ReactNode", 265 | values: "-", 266 | defaultValue: "无" 267 | } 268 | ]; 269 | this.links = [ 270 | { 271 | href: "#base-introduction", 272 | title: "基本介绍" 273 | }, 274 | { 275 | href: "#use-guide", 276 | title: "使用指南" 277 | }, 278 | { 279 | href: "#code-demonstration", 280 | title: "代码演示", 281 | children: [ 282 | { 283 | href: "#normal-form", 284 | title: "通用表单" 285 | }, 286 | { 287 | href: "#modal-form", 288 | title: "弹框表单" 289 | } 290 | ] 291 | }, 292 | { 293 | href: "#api", 294 | title: "API", 295 | children: [ 296 | { 297 | href: "#common-api", 298 | title: "公共API" 299 | }, 300 | { 301 | href: "#fields-api", 302 | title: "fields props" 303 | }, 304 | { 305 | href: "#normal-form-api", 306 | title: "通用表单特有API" 307 | }, 308 | { 309 | href: "#modal-form-api", 310 | title: "通用表单特有API" 311 | } 312 | ] 313 | } 314 | ]; 315 | } 316 | render() { 317 | return ( 318 |
319 | 320 |

321 | UForm   322 | 323 | View in Github 324 | 325 |

326 |
327 |

基本介绍

328 |
329 | 基于antd组件库定制的简单易用Form,支持通用表单及弹框表单两种形式,支持Input、InputNumber、Textarea、Select、Radio、Checkbox、Password、Switch、Rate、custom(自定义ReactNode)。 330 |
331 |
332 |
333 |

使用指南

334 |
335 |
1.安装UForm依赖包
336 |
337 | npm install uform --save-dev 338 |
339 |
2.引入依赖包
340 |
341 | 342 |
import UForm from "uform";
343 |
import "uform/dist/uform.css";
344 |
345 |
346 |
3.使用UForm组件
347 |
348 | {this.componentStep.trim()} 349 |
350 |
351 |
352 | 353 |
354 |

代码演示

355 |
356 |
357 |

通用表单

358 | 359 | 360 | 361 |
362 |
363 |
364 |
365 | 366 | 367 | 368 | 369 |
370 |
371 |
372 |
373 |

API

374 |

公共API

375 |
376 | 377 |
378 |

fields props

379 |
380 | 381 |
382 |
383 | 特别说明: 384 | type类型为 select/radio 时, 385 | fieldsData 是必填属性, type类型为 386 | custome 时, node 387 | 是必填属性。 388 |
389 |

通用表单特有API

390 |
391 | 392 |
393 | 394 |
395 | 396 |
397 |
398 |
399 | ); 400 | } 401 | } 402 | 403 | export default App; 404 | -------------------------------------------------------------------------------- /examples/src/views/ModalForm.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import { Button } from "antd"; 3 | import UForm from "uform"; 4 | import "uform/dist/uform.css"; 5 | 6 | function ModalForm() { 7 | const [visible, setVisible] = useState(false); 8 | const [data, setData] = useState({ 9 | name: "", 10 | size: 1, 11 | city: 0, 12 | area: "郊区", 13 | password: "", 14 | choosen: true, 15 | confirm: true, 16 | rate: 3, 17 | describe: "" 18 | }); 19 | const fields = [ 20 | { 21 | name: "name", 22 | label: "名称", 23 | type: "input", 24 | placeholder: "请输入名称", 25 | rules: [ 26 | { 27 | required: true, 28 | message: "请输入名称" 29 | } 30 | ] 31 | }, 32 | { 33 | name: "size", 34 | label: "大小", 35 | type: "inputNumber", 36 | placeholder: "请输入大小", 37 | rules: [ 38 | { 39 | required: true, 40 | message: "请输入名称" 41 | } 42 | ] 43 | }, 44 | { 45 | name: "city", 46 | label: "城市", 47 | type: "select", 48 | fieldData: [ 49 | { 50 | name: "北京", 51 | value: 0 52 | }, 53 | { 54 | name: "上海", 55 | value: 1 56 | }, 57 | { 58 | name: "杭州", 59 | value: 2 60 | }, 61 | { 62 | name: "深圳", 63 | value: 3 64 | } 65 | ], 66 | rules: [ 67 | { 68 | required: true, 69 | message: "请输入名称" 70 | } 71 | ] 72 | }, 73 | { 74 | name: "area", 75 | label: "地区", 76 | type: "radio", 77 | fieldData: ["城区", "郊区"] 78 | }, 79 | { 80 | name: "confirm", 81 | label: "确认选择", 82 | type: "checkbox", 83 | rules: [ 84 | { 85 | required: true, 86 | message: "请确认选择" 87 | } 88 | ] 89 | }, 90 | { 91 | name: "custom", 92 | label: "自定义项", 93 | type: "custom", 94 | node: ( 95 |
96 |

自定义表单项

97 |
98 | ) 99 | }, 100 | { 101 | name: "password", 102 | label: "密码", 103 | type: "password", 104 | rules: [ 105 | { 106 | required: true, 107 | message: "请输入密码" 108 | } 109 | ] 110 | }, 111 | { 112 | name: "choosen", 113 | label: "是否选择", 114 | type: "switch", 115 | checkedChildren: "开", 116 | unCheckedChildren: "关", 117 | rules: [ 118 | { 119 | required: true, 120 | message: "请输入密码" 121 | } 122 | ] 123 | }, 124 | { 125 | name: "rate", 126 | label: "评分", 127 | type: "rate" 128 | }, 129 | { 130 | name: "describe", 131 | label: "描述", 132 | type: "textarea", 133 | placeholder: "请输入描述" 134 | } 135 | ]; 136 | const onChange = (result) => { 137 | setData({ 138 | ...data, 139 | ...result 140 | }); 141 | }; 142 | const onSubmit = (values) => { 143 | console.log(values); 144 | }; 145 | const onCancel = () => { 146 | setVisible(false); 147 | }; 148 | return ( 149 |
150 |
151 | 158 |
159 | 169 |
170 | ); 171 | } 172 | 173 | const ModalFormCode = ` 174 | import React, { useState } from "react"; 175 | import { Button } from "antd"; 176 | import UForm from "uform"; 177 | import "uform/dist/uform.css"; 178 | 179 | function ModalForm() { 180 | const { visible, setVisible } = useState(false); 181 | const [data, setData] = useState({ 182 | name: "", 183 | size: 1, 184 | city: 0, 185 | area: "郊区", 186 | password: "", 187 | choosen: true, 188 | confirm: true, 189 | rate: 3, 190 | describe: "" 191 | }); 192 | const fields = [ 193 | { 194 | name: "name", 195 | label: "名称", 196 | type: "input", 197 | placeholder: "请输入名称", 198 | rules: [ 199 | { 200 | required: true, 201 | message: "请输入名称" 202 | } 203 | ] 204 | }, 205 | { 206 | name: "size", 207 | label: "大小", 208 | type: "inputNumber", 209 | placeholder: "请输入大小", 210 | rules: [ 211 | { 212 | required: true, 213 | message: "请输入名称" 214 | } 215 | ] 216 | }, 217 | { 218 | name: "city", 219 | label: "城市", 220 | type: "select", 221 | fieldData: [ 222 | { 223 | name: "北京", 224 | value: 0 225 | }, 226 | { 227 | name: "上海", 228 | value: 1 229 | }, 230 | { 231 | name: "杭州", 232 | value: 2 233 | }, 234 | { 235 | name: "深圳", 236 | value: 3 237 | } 238 | ], 239 | rules: [ 240 | { 241 | required: true, 242 | message: "请输入名称" 243 | } 244 | ] 245 | }, 246 | { 247 | name: "area", 248 | label: "地区", 249 | type: "radio", 250 | fieldData: ["城区", "郊区"] 251 | }, 252 | { 253 | name: "confirm", 254 | label: "确认选择", 255 | type: "checkbox", 256 | rules: [ 257 | { 258 | required: true, 259 | message: "请确认选择" 260 | } 261 | ] 262 | }, 263 | { 264 | name: "custom", 265 | label: "自定义项", 266 | type: "custom", 267 | node: ( 268 |
269 |

自定义表单项

270 |
271 | ) 272 | }, 273 | { 274 | name: "password", 275 | label: "密码", 276 | type: "password", 277 | rules: [ 278 | { 279 | required: true, 280 | message: "请输入密码" 281 | } 282 | ] 283 | }, 284 | { 285 | name: "choosen", 286 | label: "是否选择", 287 | type: "switch", 288 | checkedChildren: "开", 289 | unCheckedChildren: "关", 290 | rules: [ 291 | { 292 | required: true, 293 | message: "请输入密码" 294 | } 295 | ] 296 | }, 297 | { 298 | name: "rate", 299 | label: "评分", 300 | type: "rate" 301 | }, 302 | { 303 | name: "describe", 304 | label: "描述", 305 | type: "textarea", 306 | placeholder: "请输入描述" 307 | } 308 | ]; 309 | const onChange = (result) => { 310 | setData({ 311 | ...data, 312 | ...result 313 | }); 314 | }; 315 | const onSubmit = (values) => { 316 | console.log(values); 317 | }; 318 | const onCancel = () => { 319 | setVisible(false); 320 | }; 321 | return ( 322 |
323 | 330 |
331 | 341 |
342 |
343 | ); 344 | } 345 | `; 346 | 347 | export { ModalFormCode }; 348 | 349 | export default ModalForm; 350 | -------------------------------------------------------------------------------- /examples/src/views/NormalForm.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import UForm from "uform"; 3 | import "uform/dist/uform.css"; 4 | 5 | function NormalForm() { 6 | const [data, setData] = useState({ 7 | name: "", 8 | size: 1, 9 | city: 0, 10 | area: "郊区", 11 | password: "", 12 | choosen: true, 13 | confirm: true, 14 | rate: 3, 15 | describe: "" 16 | }); 17 | const fields = [ 18 | { 19 | name: "name", 20 | label: "名称", 21 | type: "input", 22 | placeholder: "请输入名称", 23 | rules: [ 24 | { 25 | required: true, 26 | message: "请输入名称" 27 | } 28 | ] 29 | }, 30 | { 31 | name: "size", 32 | label: "大小", 33 | type: "inputNumber", 34 | placeholder: "请输入大小", 35 | rules: [ 36 | { 37 | required: true, 38 | message: "请输入名称" 39 | } 40 | ] 41 | }, 42 | { 43 | name: "city", 44 | label: "城市", 45 | type: "select", 46 | fieldData: [ 47 | { 48 | name: "北京", 49 | value: 0 50 | }, 51 | { 52 | name: "上海", 53 | value: 1 54 | }, 55 | { 56 | name: "杭州", 57 | value: 2 58 | }, 59 | { 60 | name: "深圳", 61 | value: 3 62 | } 63 | ], 64 | rules: [ 65 | { 66 | required: true, 67 | message: "请输入名称" 68 | } 69 | ] 70 | }, 71 | { 72 | name: "area", 73 | label: "地区", 74 | type: "radio", 75 | fieldData: ["城区", "郊区"] 76 | }, 77 | { 78 | name: "confirm", 79 | label: "确认选择", 80 | type: "checkbox", 81 | rules: [ 82 | { 83 | required: true, 84 | message: "请确认选择" 85 | } 86 | ] 87 | }, 88 | { 89 | name: "custom", 90 | label: "自定义项", 91 | type: "custom", 92 | node: ( 93 |
94 |

自定义表单项

95 |
96 | ) 97 | }, 98 | { 99 | name: "password", 100 | label: "密码", 101 | type: "password", 102 | rules: [ 103 | { 104 | required: true, 105 | message: "请输入密码" 106 | } 107 | ] 108 | }, 109 | { 110 | name: "choosen", 111 | label: "是否选择", 112 | type: "switch", 113 | checkedChildren: "开", 114 | unCheckedChildren: "关", 115 | rules: [ 116 | { 117 | required: true, 118 | message: "请输入密码" 119 | } 120 | ] 121 | }, 122 | { 123 | name: "rate", 124 | label: "评分", 125 | type: "rate" 126 | }, 127 | { 128 | name: "describe", 129 | label: "描述", 130 | type: "textarea", 131 | placeholder: "请输入描述" 132 | } 133 | ]; 134 | const onChange = (result) => { 135 | setData({ 136 | ...data, 137 | ...result 138 | }); 139 | }; 140 | const onSubmit = (values) => { 141 | console.log(values); 142 | }; 143 | const onCancel = () => { 144 | console.log("cancel"); 145 | }; 146 | return ( 147 |
148 | 155 |
156 | ); 157 | } 158 | 159 | const NormalFormCode = ` 160 | import React, { useState } from "react"; 161 | import UForm from "uform"; 162 | import "uform/dist/uform.css"; 163 | 164 | function NormalForm() { 165 | const [data, setData] = useState({ 166 | name: "", 167 | size: 1, 168 | city: 0, 169 | area: "郊区", 170 | password: "", 171 | choosen: true, 172 | confirm: true, 173 | rate: 3, 174 | describe: "" 175 | }); 176 | const fields = [ 177 | { 178 | name: "name", 179 | label: "名称", 180 | type: "input", 181 | placeholder: "请输入名称", 182 | rules: [ 183 | { 184 | required: true, 185 | message: "请输入名称" 186 | } 187 | ] 188 | }, 189 | { 190 | name: "size", 191 | label: "大小", 192 | type: "inputNumber", 193 | placeholder: "请输入大小", 194 | rules: [ 195 | { 196 | required: true, 197 | message: "请输入名称" 198 | } 199 | ] 200 | }, 201 | { 202 | name: "city", 203 | label: "城市", 204 | type: "select", 205 | fieldData: [ 206 | { 207 | name: "北京", 208 | value: 0 209 | }, 210 | { 211 | name: "上海", 212 | value: 1 213 | }, 214 | { 215 | name: "杭州", 216 | value: 2 217 | }, 218 | { 219 | name: "深圳", 220 | value: 3 221 | } 222 | ], 223 | rules: [ 224 | { 225 | required: true, 226 | message: "请输入名称" 227 | } 228 | ] 229 | }, 230 | { 231 | name: "area", 232 | label: "地区", 233 | type: "radio", 234 | fieldData: ["城区", "郊区"] 235 | }, 236 | { 237 | name: "confirm", 238 | label: "确认选择", 239 | type: "checkbox", 240 | rules: [ 241 | { 242 | required: true, 243 | message: "请确认选择" 244 | } 245 | ] 246 | }, 247 | { 248 | name: "custom", 249 | label: "自定义项", 250 | type: "custom", 251 | node: ( 252 |
253 |

自定义表单项

254 |
255 | ) 256 | }, 257 | { 258 | name: "password", 259 | label: "密码", 260 | type: "password", 261 | rules: [ 262 | { 263 | required: true, 264 | message: "请输入密码" 265 | } 266 | ] 267 | }, 268 | { 269 | name: "choosen", 270 | label: "是否选择", 271 | type: "switch", 272 | checkedChildren: "开", 273 | unCheckedChildren: "关", 274 | rules: [ 275 | { 276 | required: true, 277 | message: "请输入密码" 278 | } 279 | ] 280 | }, 281 | { 282 | name: "rate", 283 | label: "评分", 284 | type: "rate" 285 | }, 286 | { 287 | name: "describe", 288 | label: "描述", 289 | type: "textarea", 290 | placeholder: "请输入描述" 291 | } 292 | ]; 293 | const onChange = (result) => { 294 | setData({ 295 | ...data, 296 | ...result 297 | }); 298 | }; 299 | const onSubmit = (values) => { 300 | console.log(values); 301 | }; 302 | const onCancel = () => { 303 | console.log("cancel"); 304 | }; 305 | return ( 306 |
307 |
308 | 315 |
316 |
317 | ); 318 | }`; 319 | 320 | export { NormalFormCode }; 321 | 322 | export default NormalForm; 323 | -------------------------------------------------------------------------------- /examples/tools/pathConfig.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const fs = require("fs"); 3 | 4 | const appDirectory = fs.realpathSync(process.cwd()); // 获取当前根目录 5 | const resolvePath = (relativePath) => path.resolve(appDirectory, relativePath); 6 | 7 | module.exports = { 8 | appHtml: resolvePath("public/index.html"), // 模板html 9 | appBuild: resolvePath("../docs"), // 打包目录 10 | appIndexJs: resolvePath("src/index.js") // 入口js文件 11 | }; 12 | -------------------------------------------------------------------------------- /examples/tools/webpack.com.config.js: -------------------------------------------------------------------------------- 1 | const { CleanWebpackPlugin } = require("clean-webpack-plugin"); 2 | const HtmlWebpackPlugin = require("html-webpack-plugin"); 3 | const MiniCssExtractPlugin = require("mini-css-extract-plugin"); 4 | const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin"); 5 | const CSSSplitWebpackPlugin = require("css-split-webpack-plugin").default; 6 | const { appIndexJs, appBuild, appHtml } = require("./pathConfig"); 7 | 8 | module.exports = { 9 | entry: { 10 | app: appIndexJs 11 | }, 12 | output: { 13 | filename: "[name].[hash:7].js", 14 | path: appBuild 15 | }, 16 | module: { 17 | rules: [ 18 | { 19 | test: /\.js[x]?$/, // jsx、js处理 20 | exclude: /node_modules/, 21 | use: ["babel-loader"] 22 | }, 23 | { 24 | test: /\.(sa|sc|c)ss$/, // scss、css处理 25 | use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"] 26 | }, 27 | { 28 | test: /\.(png|jpg|jpeg|gif|svg)/, // 图片处理 29 | use: [ 30 | { 31 | loader: "url-loader", 32 | options: { 33 | name: "[name]_[hash].[ext]", 34 | outputPath: "images/", 35 | limit: 204800 // 小于200kb采用base64转码 36 | } 37 | } 38 | ] 39 | }, 40 | { 41 | test: /\.(eot|woff2?|ttf)/, // 字体处理 42 | use: [ 43 | { 44 | loader: "url-loader", 45 | options: { 46 | name: "[name]-[hash:5].min.[ext]", 47 | limit: 5000, // 5kb限制 48 | outputPath: "fonts/" 49 | } 50 | } 51 | ] 52 | } 53 | ] 54 | }, 55 | resolve: { 56 | extensions: [".jsx", ".js"] 57 | }, 58 | optimization: { 59 | splitChunks: { 60 | // 提取公共代码 61 | chunks: "all", // async(动态加载模块),initital(入口模块),all(全部模块入口和动态的) 62 | minSize: 3000, // 抽取出来的文件压缩前最小大小 63 | maxSize: 0, // 抽取出来的文件压缩前的最大大小 64 | minChunks: 1, // 被引用次数,默认为1 65 | cacheGroups: { 66 | // 缓存组 67 | antd: { 68 | // 将node_modules模块被不同的chunk引入超过1次的抽取为common 69 | test: /[\\/]node_modules[\\/]((antd).*)[\\/]/, 70 | name: "antd", 71 | chunks: "all" 72 | }, 73 | highlight: { 74 | test: /[\\/]node_modules[\\/]((highlight).*)[\\/]/, 75 | name: "highlight", 76 | chunks: "all" 77 | }, 78 | vendor: { 79 | test: /[\\/]node_modules[\\/](?!(antd|hightlight).*)[\\/]/, 80 | name: "vendor", 81 | chunks: "all" 82 | }, 83 | default: { 84 | reuseExistingChunk: true, // 避免被重复打包分割 85 | filename: "common.js", // 其他公共函数打包成common.js 86 | priority: -20 87 | } 88 | } 89 | } 90 | }, 91 | plugins: [ 92 | new CleanWebpackPlugin(), 93 | new MiniCssExtractPlugin({ 94 | filename: "css/[name].[hash:7].css", 95 | chunkFilename: "[id].css" 96 | }), 97 | new OptimizeCSSAssetsPlugin({ 98 | assetNameRegExp: /\.css$/g, 99 | cssProcessor: require("cssnano"), // //引入cssnano配置压缩选项 100 | cssProcessorPluginOptions: { 101 | preset: [ 102 | "default", 103 | { 104 | discardComments: { 105 | // 移除注释 106 | removeAll: true 107 | }, 108 | normalizeUnicode: false 109 | } 110 | ] 111 | }, 112 | canPrint: true 113 | }), 114 | new CSSSplitWebpackPlugin({ 115 | size: 4000, // 超过4kb进行拆分 116 | filename: "[name]-[part].[ext]" 117 | }), 118 | new HtmlWebpackPlugin({ 119 | filename: "index.html", // 模板文件名 120 | template: appHtml, // 模板文件源 121 | minify: { 122 | collapseWhitespace: true, // 压缩空格 123 | minifyCSS: true, // 压缩css 124 | minifyJS: true, // 压缩js 125 | removeComments: true, // 移除注释 126 | caseSensitive: true, // 去除大小写 127 | removeScriptTypeAttributes: true, // 移除script的type属性 128 | removeStyleLinkTypeAttributes: true // 移除link的type属性 129 | } 130 | }) 131 | ] 132 | }; 133 | -------------------------------------------------------------------------------- /examples/tools/webpack.dev.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const merge = require("webpack-merge"); 3 | const baseConfig = require("./webpack.com.config"); 4 | 5 | module.exports = merge(baseConfig, { 6 | mode: "development", 7 | devServer: { 8 | contentBase: path.join(__dirname, "../dist"), 9 | host: "localhost", 10 | port: 3000, 11 | open: true, // 自动打开浏览器 12 | compress: true, // 启用gzip压缩 13 | inline: true // 启用内联模式 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /examples/tools/webpack.prod.config.js: -------------------------------------------------------------------------------- 1 | const merge = require("webpack-merge"); 2 | const baseConfig = require("./webpack.com.config"); 3 | 4 | module.exports = merge(baseConfig, { 5 | mode: "production" 6 | }); 7 | -------------------------------------------------------------------------------- /imgs/弹窗表单.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadaiwei/uform/739f79724bedd13f8cc934712c570783c8e514ef/imgs/弹窗表单.png -------------------------------------------------------------------------------- /imgs/通用表单.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadaiwei/uform/739f79724bedd13f8cc934712c570783c8e514ef/imgs/通用表单.png -------------------------------------------------------------------------------- /lib/components/Field.jsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import PropTypes from "prop-types"; 3 | import get from "lodash/get"; 4 | import { Form, Input, InputNumber, Select, Radio, Checkbox, Switch, Rate } from "antd"; 5 | import { getFieldLabelValue } from "../util/index"; 6 | 7 | class Field extends React.Component { 8 | static propTypes = { 9 | data: PropTypes.object.isRequired, 10 | fieldProps: PropTypes.object.isRequired, 11 | getFieldDecorator: PropTypes.func.isRequired, 12 | onChange: PropTypes.func.isRequired 13 | }; 14 | 15 | // Input 16 | renderInput = (name, restFieldProps) => { 17 | return ( 18 | this.onChange({ [name]: e.target.value })} /> 19 | ); 20 | }; 21 | 22 | // InputNumber 23 | renderInputNumber = (name, restFieldProps) => { 24 | return ( 25 | this.onChange({ [name]: value })} /> 26 | ); 27 | }; 28 | 29 | // Textarea 30 | renderTextArea = (name, restFieldProps) => { 31 | return ( 32 | this.onChange({ [name]: e.target.value })} 35 | /> 36 | ); 37 | }; 38 | 39 | // Select 40 | renderSelect = (name, restFieldProps) => { 41 | const { fieldData, ...restSelectProps } = restFieldProps; 42 | const { fieldLabel, fieldValue } = getFieldLabelValue(fieldData); 43 | return ( 44 | 59 | ); 60 | }; 61 | 62 | // Radio 63 | renderRadio = (name, restFieldProps) => { 64 | const { fieldData, ...restRadioProps } = restFieldProps; 65 | const { fieldLabel, fieldValue } = getFieldLabelValue(fieldData); 66 | return ( 67 | this.onChange({ [name]: e.target.value })}> 68 | {(fieldData || []).map((item) => { 69 | const label = get(item, fieldLabel, item); 70 | const value = get(item, fieldValue, item); 71 | return ( 72 | 73 | {label} 74 | 75 | ); 76 | })} 77 | 78 | ); 79 | }; 80 | 81 | // Checkbox 82 | renderCheckbox = (name, restFieldProps) => { 83 | return ( 84 | this.onChange({ [name]: e.target.checked })} /> 85 | ); 86 | }; 87 | 88 | // Password 89 | renderPassword = (name, restFieldProps) => { 90 | return ( 91 | this.onChange({ [name]: e.target.value })} 94 | /> 95 | ); 96 | }; 97 | 98 | // Switch 99 | renderSwitch = (name, restFieldProps) => { 100 | return ( 101 | this.onChange({ [name]: checked })}> 104 | ); 105 | }; 106 | 107 | // Rate 108 | renderRate = (name, restFieldProps) => { 109 | return ( 110 | this.onChange({ [name]: number })}> 111 | ); 112 | }; 113 | 114 | // 自定义表单项 115 | renderCustom = (restFieldProps) => { 116 | const { node } = restFieldProps; 117 | return {node}; 118 | }; 119 | 120 | // 渲染表单项 121 | renderField = (fieldProps) => { 122 | const { name, type, ...restFieldProps } = fieldProps; 123 | switch (type) { 124 | case "input": 125 | return this.renderInput(name, restFieldProps); 126 | case "inputNumber": 127 | return this.renderInputNumber(name, restFieldProps); 128 | case "textarea": 129 | return this.renderTextArea(name, restFieldProps); 130 | case "select": 131 | return this.renderSelect(name, restFieldProps); 132 | case "radio": 133 | return this.renderRadio(name, restFieldProps); 134 | case "checkbox": 135 | return this.renderCheckbox(name, restFieldProps); 136 | case "password": 137 | return this.renderPassword(name, restFieldProps); 138 | case "switch": 139 | return this.renderSwitch(name, restFieldProps); 140 | case "rate": 141 | return this.renderRate(name, restFieldProps); 142 | case "custom": 143 | return this.renderCustom(restFieldProps); 144 | default: 145 | return null; 146 | } 147 | }; 148 | 149 | // 表单项变化 150 | onChange = (value) => { 151 | const { onChange, form } = this.props; 152 | onChange && onChange({ ...value, form }); 153 | }; 154 | 155 | // handleFieldValue 156 | handleDecoratorProps = (type, value, decoratorProps) => { 157 | switch (type) { 158 | case "switch": 159 | case "checkbox": 160 | decoratorProps.valuePropName = value ? "checked" : ""; 161 | break; 162 | default: 163 | break; 164 | } 165 | }; 166 | 167 | render() { 168 | const { data, fieldProps, getFieldDecorator } = this.props; 169 | const { label, name, type, rules, ...restFieldProps } = fieldProps; 170 | const decoratorProps = { 171 | rules: rules || [] 172 | }; 173 | const value = get(data, name, undefined); 174 | decoratorProps.initialValue = value; 175 | this.handleDecoratorProps(type, value, decoratorProps); 176 | return ( 177 | 178 | {getFieldDecorator(name, decoratorProps)( 179 | this.renderField({ 180 | name, 181 | type, 182 | ...restFieldProps 183 | }) 184 | )} 185 | 186 | ); 187 | } 188 | } 189 | 190 | export default Field; 191 | -------------------------------------------------------------------------------- /lib/components/FormComponent.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import PropTypes from "prop-types"; 3 | import { Form } from "antd"; 4 | import Field from "./Field"; 5 | import get from "lodash/get"; 6 | 7 | class FormComponent extends Component { 8 | static propTypes = { 9 | layout: PropTypes.string, 10 | formItemLayout: PropTypes.object, 11 | data: PropTypes.object.isRequired, 12 | fields: PropTypes.array.isRequired, 13 | onChange: PropTypes.func 14 | }; 15 | 16 | componentWillReceiveProps(nextProps) { 17 | // 打开弹窗时,重置表单 18 | if (nextProps.visible && nextProps.visible !== this.props.visible) { 19 | this.props.form.resetFields(); 20 | } 21 | if (nextProps.data !== this.props.data) { 22 | const fields = this.props.fields; 23 | fields.forEach((field) => { 24 | const fieldName = field.name; 25 | const nextFieldValue = get(nextProps.data, fieldName, ""); 26 | const preFieldValue = get(this.props.data, fieldName, ""); 27 | if (nextFieldValue !== preFieldValue) { 28 | this.props.form.setFieldsValue({ 29 | [fieldName]: nextFieldValue 30 | }); 31 | } 32 | }); 33 | } 34 | } 35 | 36 | render() { 37 | const { layout, formItemLayout, data, fields, form, onChange, children } = this.props; 38 | const { getFieldDecorator } = form; 39 | return ( 40 |
41 | {fields.map((item, index) => { 42 | return ( 43 | 50 | ); 51 | })} 52 | {children} 53 | 54 | ); 55 | } 56 | } 57 | 58 | export default Form.create({})(FormComponent); 59 | -------------------------------------------------------------------------------- /lib/components/ModalForm.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import PropTypes from "prop-types"; 3 | import { Modal } from "antd"; 4 | import FormComponent from "./FormComponent"; 5 | 6 | class ModalForm extends Component { 7 | constructor(props) { 8 | super(props); 9 | this.formRef = React.createRef(); 10 | } 11 | 12 | static propTypes = { 13 | title: PropTypes.oneOfType([PropTypes.string, PropTypes.instanceOf(React.ReactNode)]) 14 | .isRequired, 15 | visible: PropTypes.bool.isRequired, 16 | loading: PropTypes.bool, 17 | width: PropTypes.number, 18 | data: PropTypes.object.isRequired, 19 | fields: PropTypes.array.isRequired, 20 | onChange: PropTypes.func, 21 | onCancel: PropTypes.func.isRequired, 22 | onSubmit: PropTypes.func.isRequired 23 | }; 24 | 25 | static defaultProps = { 26 | width: 600, 27 | visible: false, 28 | loading: false 29 | }; 30 | 31 | // 关闭弹窗 32 | leaveModal = () => { 33 | const { onCancel } = this.props; 34 | onCancel && onCancel(); 35 | }; 36 | 37 | // 确认操作 38 | confirmAction = () => { 39 | this.formRef.current.validateFields({ force: true }, (err, values) => { 40 | if (!err) { 41 | const { onSubmit } = this.props; 42 | onSubmit && onSubmit(); 43 | } 44 | }); 45 | }; 46 | 47 | render() { 48 | const { title, width, visible, loading, ...restProps } = this.props; 49 | return ( 50 | 61 | 62 | 63 | ); 64 | } 65 | } 66 | 67 | export default ModalForm; 68 | -------------------------------------------------------------------------------- /lib/components/NormalForm.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import PropTypes from "prop-types"; 3 | import { Form, Button } from "antd"; 4 | import FormComponent from "./FormComponent"; 5 | 6 | class NormalForm extends Component { 7 | constructor(props) { 8 | super(props); 9 | this.formRef = React.createRef(); 10 | } 11 | 12 | static propTypes = { 13 | layout: PropTypes.string, 14 | formItemLayout: PropTypes.object, 15 | tailFormItemLayout: PropTypes.object, 16 | showCancelButton: PropTypes.bool, 17 | loading: PropTypes.bool, 18 | data: PropTypes.object.isRequired, 19 | fields: PropTypes.array.isRequired, 20 | onChange: PropTypes.func, 21 | onSubmit: PropTypes.func.isRequired, 22 | onCancel: PropTypes.func 23 | }; 24 | 25 | // 表单提交 26 | handleSubmit = () => { 27 | this.formRef.current.validateFields({ force: true }, (err, values) => { 28 | if (!err) { 29 | const { onSubmit } = this.props; 30 | onSubmit && onSubmit(values); 31 | } 32 | }); 33 | }; 34 | 35 | // 取消表单提交 36 | cancelSubmit = () => { 37 | const { onCancel } = this.props; 38 | onCancel && onCancel(); 39 | }; 40 | 41 | render() { 42 | const { tailFormItemLayout, showCancelButton, loading, ...restProps } = this.props; 43 | return ( 44 | 45 | 46 | 49 | {showCancelButton && ( 50 | 53 | )} 54 | 55 | 56 | ); 57 | } 58 | } 59 | 60 | export default NormalForm; 61 | -------------------------------------------------------------------------------- /lib/components/UForm.jsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import PropTypes from "prop-types"; 3 | import NormalForm from "./NormalForm"; 4 | import ModalForm from "./ModalForm"; 5 | import "../css/main.css"; 6 | 7 | class UForm extends React.Component { 8 | static propTypes = { 9 | type: PropTypes.string, // 表单类型,type-normal/modal 10 | layout: PropTypes.string, // 表单布局,horizontal/vertical/inline 11 | visible: PropTypes.bool, // modal form是否可见 12 | title: PropTypes.string, // modal标题 13 | loading: PropTypes.bool, // 确定按钮loading 14 | labelCol: PropTypes.number, // formItem label部分占宽 15 | wrapperCol: PropTypes.number, // formItem内容部分占宽 16 | data: PropTypes.object.isRequired, // data 17 | fields: PropTypes.array.isRequired, // fields 18 | showCancelButton: PropTypes.bool, // 展示取消按钮 19 | onChange: PropTypes.func, // 修改表单回调 20 | onSubmit: PropTypes.func.isRequired, // 提交回调 21 | onCancel: PropTypes.func // 取消回调 22 | }; 23 | 24 | static defaultProps = { 25 | type: "normal", 26 | layout: "horizontal", 27 | visible: false, 28 | labelCol: 4, 29 | wrapperCol: 16, 30 | data: {}, 31 | fields: [], 32 | showCancelButton: true 33 | }; 34 | 35 | // 渲染表单,区分弹窗表单和正常表单 36 | renderForm = (type) => { 37 | const { layout, labelCol, wrapperCol } = this.props; 38 | let formItemLayout = { 39 | labelCol: { 40 | xs: { span: 24 }, 41 | sm: { span: labelCol } 42 | }, 43 | wrapperCol: { 44 | xs: { span: 24 }, 45 | sm: { span: wrapperCol } 46 | } 47 | }; 48 | let tailFormItemLayout = { 49 | wrapperCol: { 50 | xs: { span: 24 }, 51 | sm: { span: wrapperCol, offset: labelCol } 52 | } 53 | }; 54 | if (layout !== "horizontal") { 55 | formItemLayout = null; 56 | tailFormItemLayout = null; 57 | } 58 | switch (type) { 59 | case "normal": 60 | return ( 61 | 66 | ); 67 | case "modal": 68 | return ; 69 | default: 70 | return ; 71 | } 72 | }; 73 | 74 | render() { 75 | const { type } = this.props; 76 | return {this.renderForm(type)}; 77 | } 78 | } 79 | 80 | export default UForm; 81 | -------------------------------------------------------------------------------- /lib/css/main.css: -------------------------------------------------------------------------------- 1 | /* form按钮 */ 2 | .normal-form-button { 3 | margin-left: 20px; 4 | } 5 | 6 | /* form弹窗 */ 7 | .form-modal .ant-modal-body { 8 | max-height: 70vh; 9 | overflow: auto; 10 | } -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | import UForm from "./components/UForm"; 2 | 3 | export default UForm; 4 | -------------------------------------------------------------------------------- /lib/util/index.js: -------------------------------------------------------------------------------- 1 | const getFieldLabelValue = (fieldData) => { 2 | try { 3 | if (!fieldData) { 4 | return; 5 | } 6 | const item = fieldData[0]; 7 | if (typeof item === "object") { 8 | const keys = Object.keys(item); 9 | const fieldLabel = keys[0]; 10 | const fieldValue = keys[1]; 11 | return { 12 | fieldLabel, 13 | fieldValue 14 | }; 15 | } 16 | return { 17 | fieldLabel: item, 18 | fieldValue: item 19 | }; 20 | } catch (err) { 21 | throw err; 22 | } 23 | }; 24 | 25 | export { getFieldLabelValue }; 26 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "uform", 3 | "version": "0.1.9", 4 | "description": "A form component for antd", 5 | "main": "./dist/index.js", 6 | "scripts": { 7 | "build": "webpack --config ./scripts/build.js" 8 | }, 9 | "keywords": [ 10 | "React", 11 | "antd", 12 | "form" 13 | ], 14 | "author": "dadaiwei", 15 | "license": "ISC", 16 | "devDependencies": { 17 | "@babel/core": "^7.5.5", 18 | "@babel/plugin-proposal-class-properties": "^7.5.5", 19 | "@babel/plugin-syntax-dynamic-import": "^7.2.0", 20 | "@babel/plugin-transform-runtime": "^7.5.5", 21 | "@babel/polyfill": "^7.4.4", 22 | "@babel/preset-env": "^7.5.5", 23 | "@babel/preset-react": "^7.0.0", 24 | "@babel/runtime": "^7.5.5", 25 | "antd": "^3.22.2", 26 | "babel-loader": "^8.0.6", 27 | "babel-plugin-import": "^1.12.1", 28 | "clean-webpack-plugin": "^3.0.0", 29 | "css-loader": "^3.2.0", 30 | "css-split-webpack-plugin": "^0.2.6", 31 | "i": "^0.3.6", 32 | "less": "^3.10.3", 33 | "less-loader": "^5.0.0", 34 | "lodash": "^4.17.15", 35 | "mini-css-extract-plugin": "^0.8.0", 36 | "npm": "^6.11.2", 37 | "optimize-css-assets-webpack-plugin": "^5.0.3", 38 | "prop-types": "^15.7.2", 39 | "react": "^16.8.6", 40 | "react-dom": "^16.8.6", 41 | "sass-loader": "^7.1.0", 42 | "uglifyjs-webpack-plugin": "^2.1.3", 43 | "webpack": "^4.38.0", 44 | "webpack-bundle-analyzer": "^3.4.1", 45 | "webpack-cli": "^3.3.6" 46 | }, 47 | "dependencies": {} 48 | } 49 | -------------------------------------------------------------------------------- /scripts/build.js: -------------------------------------------------------------------------------- 1 | const { CleanWebpackPlugin } = require("clean-webpack-plugin"); 2 | const WebpackBundleAnylyzer = require("webpack-bundle-analyzer").BundleAnalyzerPlugin; 3 | const MiniCssExtractPlugin = require("mini-css-extract-plugin"); 4 | const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin"); 5 | const pathEnv = require("./pathEnv"); 6 | 7 | module.exports = { 8 | mode: "production", 9 | entry: pathEnv.entry, 10 | output: pathEnv.output, 11 | module: { 12 | rules: [ 13 | { 14 | test: /\.(js|jsx)/, 15 | exclude: /node_modules/, 16 | use: ["babel-loader"] 17 | }, 18 | { 19 | test: /\.[le|c]ss/, 20 | use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"] 21 | } 22 | ] 23 | }, 24 | resolve: { 25 | extensions: [".jsx", ".js"] 26 | }, 27 | plugins: [ 28 | new CleanWebpackPlugin(), 29 | new MiniCssExtractPlugin({ 30 | filename: "uform.css", 31 | chunkFilename: "[id].css" 32 | }), 33 | new OptimizeCSSAssetsPlugin({ 34 | assetNameRegExp: /\.css$/g, 35 | cssProcessor: require("cssnano"), // //引入cssnano配置压缩选项 36 | cssProcessorPluginOptions: { 37 | preset: [ 38 | "default", 39 | { 40 | discardComments: { 41 | // 移除注释 42 | removeAll: true 43 | }, 44 | normalizeUnicode: false 45 | } 46 | ] 47 | }, 48 | canPrint: true 49 | }) 50 | ] 51 | }; 52 | -------------------------------------------------------------------------------- /scripts/pathEnv.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | 3 | const pathEnv = { 4 | entry: "./lib/index", 5 | output: { 6 | filename: "index.js", 7 | path: path.resolve(__dirname, "../dist"), 8 | library: "UForm", 9 | libraryTarget: "umd" 10 | } 11 | }; 12 | 13 | module.exports = pathEnv; 14 | --------------------------------------------------------------------------------