")))),this.state.shown&&3===t&&f.a.createElement("div",{className:"original-code"},f.a.createElement("pre",null,f.a.createElement("code",null,f.a.createElement("span",null,"//返回值是一个数组,分别是省份行政区域文本"),f.a.createElement("br",null),f.a.createElement("span",null,"<"),"AreaSelect type='text' level={3} defaultArea={['广东省', '深圳市', '南山区', '粤海街道']} onChange={this.handleSelectedChange}/",f.a.createElement("span",null,">")))),this.state.shown&&0===t&&f.a.createElement("div",{className:"original-code"},f.a.createElement("pre",null,f.a.createElement("code",null,f.a.createElement("span",null,"//返回值是一个数组,分别是省份行政区域代码"),f.a.createElement("br",null),f.a.createElement("span",null,"<"),"AreaSelect type='all' level={0} defaultArea={['440000']} onChange={this.handleSelectedChange}/",f.a.createElement("span",null,">")))),f.a.createElement("div",{className:"show-code",onClick:this.toggle},this.state.shown?"Hide Code":"Show Code"))},n}(a.Component);var Z=function(e){function n(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,n);var t=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,e.call(this));return t.handleSelectedChange=function(e){t.setState({selected:e})},t.toggle=function(){t.setState({shown:!t.state.shown})},t.state={selected:[],shown:!1},t}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(n,e),n.prototype.render=function(){return f.a.createElement("div",{className:"code-area"},f.a.createElement("div",{className:"area-left"},f.a.createElement(q,{data:u.pca,onChange:this.handleSelectedChange})),f.a.createElement("div",{className:"area-right"},f.a.createElement("pre",null,f.a.createElement("code",null,"["+this.state.selected+"]"))),this.state.shown&&f.a.createElement("div",{className:"original-code"},f.a.createElement("pre",null,f.a.createElement("code",null,f.a.createElement("span",null,"//返回值是一个数组,分别是省市的行政区域代码"),f.a.createElement("br",null),f.a.createElement("span",null,"<"),"AreaCascader onChange={this.handleSelectedChange}/",f.a.createElement("span",null,">")))),f.a.createElement("div",{className:"show-code",onClick:this.toggle},this.state.shown?"Hide Code":"Show Code"))},n}(a.Component);var G=function(e){function n(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,n);var t=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,e.call(this));return t.handleSelectedChange=function(e){t.setState({selected:e})},t.toggle=function(){t.setState({shown:!t.state.shown})},t.state={selected:[],shown:!1},t}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(n,e),n.prototype.render=function(){return f.a.createElement("div",{className:"code-area"},f.a.createElement("div",{className:"area-left"},f.a.createElement(q,{data:u.pca,type:"all",onChange:this.handleSelectedChange})),f.a.createElement("div",{className:"area-right"},f.a.createElement("pre",null,f.a.createElement("code",null,""+JSON.stringify(this.state.selected)))),this.state.shown&&f.a.createElement("div",{className:"original-code"},f.a.createElement("pre",null,f.a.createElement("code",null,f.a.createElement("span",null,"//返回值是一个数组,数组项是包含省市的行政区域代码和文本的对象"),f.a.createElement("br",null),f.a.createElement("span",null,"<"),"AreaCascader type='all' onChange={this.handleSelectedChange}/",f.a.createElement("span",null,">")))),f.a.createElement("div",{className:"show-code",onClick:this.toggle},this.state.shown?"Hide Code":"Show Code"))},n}(a.Component);var K=function(e){function n(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,n);var t=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,e.call(this));return t.handleSelectedChange=function(e){t.setState({selected:e})},t.toggle=function(){t.setState({shown:!t.state.shown})},t.state={selected:[],shown:!1},t}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(n,e),n.prototype.render=function(){return f.a.createElement("div",{className:"code-area"},f.a.createElement("div",{className:"area-left"},f.a.createElement(q,{data:u.pcaa,type:"text",level:1,defaultArea:["440000","440300","440305"],onChange:this.handleSelectedChange})),f.a.createElement("div",{className:"area-right"},f.a.createElement("pre",null,f.a.createElement("code",null,"["+this.state.selected+"]"))),this.state.shown&&f.a.createElement("div",{className:"original-code"},f.a.createElement("pre",null,f.a.createElement("code",null,f.a.createElement("span",null,"//绑定默认值defaultArea=['440000','440300','440305'], 代码对应的区域文本是['广东省', '深圳市', '南山区']"),f.a.createElement("br",null),f.a.createElement("span",null,"<"),"AreaCascader type='text' level={1} defaultArea={defaultArea} onChange={this.handleSelectedChange}/",f.a.createElement("span",null,">")))),f.a.createElement("div",{className:"show-code",onClick:this.toggle},this.state.shown?"Hide Code":"Show Code"))},n}(a.Component);var Q=function(e){function n(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,n);var t=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,e.call(this));return t.handleSelectedChange=function(e){t.setState({selected:e})},t.toggle=function(){t.setState({shown:!t.state.shown})},t.state={selected:[],shown:!1},t}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(n,e),n.prototype.render=function(){return f.a.createElement("div",{className:"code-area"},f.a.createElement("div",{className:"area-left"},f.a.createElement(q,{data:u.pcaa,type:"text",level:1,onChange:this.handleSelectedChange})),f.a.createElement("div",{className:"area-right"},f.a.createElement("pre",null,f.a.createElement("code",null,"["+this.state.selected+"]"))),this.state.shown&&f.a.createElement("div",{className:"original-code"},f.a.createElement("pre",null,f.a.createElement("code",null,f.a.createElement("span",null,"//代码对应的区域文本是['广东省', '深圳市', '南山区']"),f.a.createElement("br",null),f.a.createElement("span",null,"<"),"AreaCascader type='text' level={1} onChange={this.handleSelectedChange}/",f.a.createElement("span",null,">")))),f.a.createElement("div",{className:"show-code",onClick:this.toggle},this.state.shown?"Hide Code":"Show Code"))},n}(a.Component);var X=function(e){function t(){return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,e.call(this))}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),t.prototype.render=function(){return f.a.createElement("div",{className:"app-main"},f.a.createElement("h3",null,"基本使用"),f.a.createElement("h4",null,"1. 作为选择器"),f.a.createElement("h5",null,"默认形式"),f.a.createElement(B,null),f.a.createElement("h5",null,"改变大小"),f.a.createElement(F,null),f.a.createElement("h5",null,"返回区域文本"),f.a.createElement(U,null),f.a.createElement("h5",null,"返回区域代码和文本"),f.a.createElement(J,null),f.a.createElement("h5",null,"设置 placeholders"),f.a.createElement(B,{placeholders:["选择省","选择市"]}),f.a.createElement("p",{className:"desc"},f.a.createElement("code",null,"placeholders")," 是一个数组, 数组项顺序分别对应省/市/区."),f.a.createElement("h5",null,"设置默认值及省市区联动"),f.a.createElement($,{level:2}),f.a.createElement("p",{className:"desc"},f.a.createElement("code",null,"selected")," 是一个数组, 数组项顺序分别对应省/市/区, 且类型(区域代码/区域文本)必须统一. 以第一个元素类型为基准. 类型不统一将报错."),f.a.createElement("h5",null,"只选省份"),f.a.createElement($,{level:0,type:"all"}),f.a.createElement("h4",null,"2. 作为级联器(只支持2/3级联动)"),f.a.createElement("h5",null,"默认形式"),f.a.createElement(Z,null),f.a.createElement("h5",null,"返回区域文本和代码"),f.a.createElement(G,null),f.a.createElement("p",{className:"desc"},f.a.createElement("code",null,"type")," 表示返回值, 支持:['text', 'code', 'all'], 默认值是 code"),f.a.createElement("h5",null,"设置默认值"),f.a.createElement(K,null),f.a.createElement("h5",null,"省市区联动"),f.a.createElement(Q,null))},t}(a.Component);var Y=function(e){function t(){return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,e.call(this))}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),t.prototype.render=function(){return f.a.createElement("footer",null,f.a.createElement("p",null,"Vue 版本:",f.a.createElement("a",{target:"_blank",href:"https://github.com/dwqs/vue-area-linkage"},"Vue Area Linkage")),f.a.createElement("p",null,"最新数据来源:",f.a.createElement("a",{href:"https://github.com/dwqs/area-data",target:"_blank"},"省/市/区数据")),f.a.createElement("p",null,"官方数据:",f.a.createElement("a",{href:"http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2016/index.html",target:"_blank"},"国家统计局-城乡划分")))},t}(a.Component);var ee=function(t){function n(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,n);var e=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,t.call(this));return e.onChange=function(e){},e.state={selected:[]},e}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(n,t),n.prototype.render=function(){return f.a.createElement("div",{className:"app-wrap"},f.a.createElement(l,null),f.a.createElement(i,null),f.a.createElement(X,null),f.a.createElement(Y,null))},n.prototype.componentDidMount=function(){},n}(a.Component);window.onload=function(){r.a.render(f.a.createElement(ee,null),document.getElementById("app"))}}},[9]);
--------------------------------------------------------------------------------
/demo/gh.a09051bf.js.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dwqs/react-area-linkage/3b34efeabe5d5cf1df591ea87af360e7fc2896e7/demo/gh.a09051bf.js.gz
--------------------------------------------------------------------------------
/demo/gh.d33fa769.css:
--------------------------------------------------------------------------------
1 | a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{margin:0;padding:0;border:0;font-size:100%;outline:0;vertical-align:baseline;background:transparent}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body,html{height:100%;width:100%;font-family:-apple-system,BlinkMacSystemFont,PingFang SC,Helvetica Neue,STHeiti,Microsoft Yahei,Tahoma,Simsun,sans-serif}body{margin:0;padding:0;box-sizing:border-box;font-size:14px;line-height:1;background:none;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;overflow-x:hidden;-webkit-overflow-scrolling:touch;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;tap-highlight-color:transparent;-webkit-tap-highlight-color:transparent}nav ul,ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:after,blockquote:before,q:after,q:before{content:""}table{border-collapse:collapse;border-spacing:0}a{text-decoration:none;margin:0;padding:0;border:0;font-size:100%;vertical-align:baseline;background:transparent;-webkit-appearance:none;-webkit-tap-highlight-color:transparent}:focus{outline:none}ins{text-decoration:none}ins,mark{background-color:#ff9;color:#000}mark{font-style:italic;font-weight:700}del{text-decoration:line-through}abbr[title],dfn[title]{border-bottom:1px dotted #000;cursor:help}hr{display:block;height:1px;border:0;border-top:1px solid #ccc;margin:1em 0;padding:0}input,input[type=password],input[type=text],select,textarea{outline:none;-webkit-appearance:none}input,select{vertical-align:middle}*{box-sizing:border-box;font-family:-apple-system,BlinkMacSystemFont,PingFang SC,Helvetica Neue,STHeiti,Microsoft Yahei,Tahoma,Simsun,sans-serif;color:inherit}.app-wrap{width:960px;height:200px;margin:0 auto}header{text-align:center;margin-top:100px}h2{font-size:27px;font-weight:400}header p{margin-top:20px;margin-bottom:20px;font-size:16px}header>a{position:fixed;right:0;top:0}header p a{color:#008efd;text-decoration:none;padding-left:5px}footer{margin-top:30px;text-align:center;color:#999}footer a{text-decoration:none;color:#999}footer p{margin-top:15px;cursor:pointer}footer p:hover,footer p:hover a{color:#008efd}.start{margin-top:40px}.start h3{text-align:center;font-size:25px;color:#6289ad}.start h4{font-size:18px;color:#6289ad}.start pre{margin-top:15px;background:#f8f8f8;padding:15px 10px;color:#000;font-size:16px;font-weight:400}.start .install{margin-top:20px}.start .install p{margin-top:20px;margin-bottom:20px}.app-main,.start .register{margin-top:20px}.app-main h3{text-align:center;font-size:25px;color:#6289ad}.app-main h4{margin-top:25px;font-size:18px;color:#6289ad}.app-main h5{margin-top:20px;font-size:16px;color:#6289ad}.app-main .desc{margin-top:15px}.app-main .desc code{background:#f8f8f8;color:#333;padding:5px}.app-main .code-area{position:relative;width:100%;height:auto;border:1px solid #dce7f4;border-radius:4px;margin-top:20px;padding:0}.app-main .code-area>div{margin-top:40px;display:inline-block;vertical-align:middle}.app-main .code-area .area-left{width:75%;margin-left:10px}.app-main .code-area .area-right{width:21%;margin-left:10px}.app-main .code-area .area-right pre{background:#f8f8f8;padding:15px 10px;color:#6289ad;line-height:20px}.app-main .code-area .original-code{width:90%;margin:25px 45px -10px}.app-main .code-area .original-code pre{background:#f8f8f8;padding:15px 10px}.app-main .code-area .show-code{width:100%;cursor:pointer;text-align:center;border-top:1px solid #dce7f4;padding-top:3px;padding-bottom:3px;color:#6289ad;font-weight:500;font-size:18px}.app-main .code-area .show-code:hover{background-color:#dce7f4;color:#fff}.area-zoom-in-top-enter,.area-zoom-in-top-exit-active{opacity:0;transform:scaleY(0)}.area-zoom-in-top-enter-active,.area-zoom-in-top-exit{opacity:1;transform:scaleY(1);transition:all .3s cubic-bezier(.645,.045,.355,1);transform-origin:center top}.area-select-wrap .area-select{margin-left:10px}.area-select-wrap .area-select-empty{padding:4px 0;margin:0;text-align:center;color:#999;font-size:14px}.area-select{position:relative;display:inline-block;vertical-align:top;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;height:32px;cursor:pointer;background:#fff;border-radius:4px;border:1px solid #e1e2e6}.area-select *{box-sizing:border-box}.area-select:hover{border-color:#a1a4ad}.area-select.small{width:126px}.area-select.medium{width:160px}.area-select.large{width:194px}.area-select.is-disabled{background:#eceff5;cursor:not-allowed}.area-select.is-disabled:hover{border-color:#e1e2e6}.area-select.is-disabled .area-selected-trigger{cursor:not-allowed}.area-select .area-selected-trigger{position:relative;display:block;font-size:14px;cursor:pointer;margin:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;height:100%;line-height:100%;padding:8px 20px 7px 12px}.area-select .area-select-icon{position:absolute;top:50%;margin-top:-2px;right:6px;content:"";width:0;height:0;border:6px solid transparent;border-top-color:#a1a4ad;transition:all .3s linear;transform-origin:center}.area-select .area-select-icon.active{margin-top:-8px;transform:rotate(180deg)}.area-selectable-list-wrap{position:absolute;width:100%;max-height:275px;z-index:15000;border:1px solid #a1a4ad;border-radius:2px;background-color:#fff;box-shadow:0 2px 4px rgba(0,0,0,.12),0 0 6px rgba(0,0,0,.04);box-sizing:border-box;margin:5px 0;overflow-x:hidden;overflow-x:auto}.area-selectable-list{position:relative;margin:0;padding:6px 0;width:100%;font-size:14px;color:#565656;list-style:none}.area-selectable-list .area-select-option{position:relative;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:pointer;padding:0 15px 0 10px;height:32px;line-height:32px}.area-selectable-list .area-select-option.hover{background-color:#e4e8f1}.area-selectable-list .area-select-option.selected{background-color:#e4e8f1;color:#ff6200;font-weight:700}.cascader-menu-list-wrap{position:absolute;white-space:nowrap;z-index:15000;border:1px solid #a1a4ad;border-radius:2px;background-color:#fff;box-shadow:0 2px 4px rgba(0,0,0,.12),0 0 6px rgba(0,0,0,.04);box-sizing:border-box;margin:5px 0;overflow:hidden;font-size:0}.cascader-menu-list{position:relative;margin:0;font-size:14px;color:#565656;padding:6px 0;list-style:none;display:inline-block;height:204px;overflow-x:hidden;overflow-y:auto;min-width:160px;vertical-align:top;background-color:#fff;border-right:1px solid #e4e7ed}.cascader-menu-list:last-child{border-right:none}.cascader-menu-list .cascader-menu-option{position:relative;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:pointer;padding:0 15px 0 10px;height:32px;line-height:32px}.cascader-menu-list .cascader-menu-option.hover,.cascader-menu-list .cascader-menu-option:hover{background-color:#e4e8f1}.cascader-menu-list .cascader-menu-option.selected{background-color:#e4e8f1;color:#ff6200;font-weight:700}.cascader-menu-list .cascader-menu-option.cascader-menu-extensible:after{position:absolute;top:50%;margin-top:-4px;right:5px;content:"";width:0;height:0;border:4px solid transparent;border-left-color:#a1a4ad}.area-selectable-list-wrap::-webkit-scrollbar,.cascader-menu-list::-webkit-scrollbar{width:8px;background:transparent}.area-selectable-list-wrap::-webkit-scrollbar-button:vertical:decremen,.area-selectable-list-wrap::-webkit-scrollbar-button:vertical:end:decrement,.area-selectable-list-wrap::-webkit-scrollbar-button:vertical:increment,.area-selectable-list-wrap::-webkit-scrollbar-button:vertical:start:increment,.cascader-menu-list::-webkit-scrollbar-button:vertical:decremen,.cascader-menu-list::-webkit-scrollbar-button:vertical:end:decrement,.cascader-menu-list::-webkit-scrollbar-button:vertical:increment,.cascader-menu-list::-webkit-scrollbar-button:vertical:start:increment{display:none}.area-selectable-list-wrap::-webkit-scrollbar-thumb:vertical,.cascader-menu-list::-webkit-scrollbar-thumb:vertical{background-color:#b8b8b8;border-radius:4px}.area-selectable-list-wrap::-webkit-scrollbar-thumb:vertical:hover,.cascader-menu-list::-webkit-scrollbar-thumb:vertical:hover{background-color:#777}
--------------------------------------------------------------------------------
/demo/vendor.54999dc1.js.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dwqs/react-area-linkage/3b34efeabe5d5cf1df591ea87af360e7fc2896e7/demo/vendor.54999dc1.js.gz
--------------------------------------------------------------------------------
/dist/index.css:
--------------------------------------------------------------------------------
1 | .area-zoom-in-top-enter,.area-zoom-in-top-exit-active{opacity:0;transform:scaleY(0)}.area-zoom-in-top-enter-active,.area-zoom-in-top-exit{opacity:1;transform:scaleY(1);transition:all .3s cubic-bezier(.645,.045,.355,1);transform-origin:center top}.area-select-wrap .area-select{margin-left:10px}.area-select-wrap .area-select-empty{padding:4px 0;margin:0;text-align:center;color:#999;font-size:14px}.area-select{position:relative;display:inline-block;vertical-align:top;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;height:32px;cursor:pointer;background:#fff;border-radius:4px;border:1px solid #e1e2e6}.area-select *{box-sizing:border-box}.area-select:hover{border-color:#a1a4ad}.area-select.small{width:126px}.area-select.medium{width:160px}.area-select.large{width:194px}.area-select.is-disabled{background:#eceff5;cursor:not-allowed}.area-select.is-disabled:hover{border-color:#e1e2e6}.area-select.is-disabled .area-selected-trigger{cursor:not-allowed}.area-select .area-selected-trigger{position:relative;display:block;font-size:14px;cursor:pointer;margin:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;height:100%;line-height:100%;padding:8px 20px 7px 12px}.area-select .area-select-icon{position:absolute;top:50%;margin-top:-2px;right:6px;content:"";width:0;height:0;border:6px solid transparent;border-top-color:#a1a4ad;transition:all .3s linear;transform-origin:center}.area-select .area-select-icon.active{margin-top:-8px;transform:rotate(180deg)}.area-selectable-list-wrap{position:absolute;width:100%;max-height:275px;z-index:15000;border:1px solid #a1a4ad;border-radius:2px;background-color:#fff;box-shadow:0 2px 4px rgba(0,0,0,.12),0 0 6px rgba(0,0,0,.04);box-sizing:border-box;margin:5px 0;overflow-x:hidden;overflow-x:auto}.area-selectable-list{position:relative;margin:0;padding:6px 0;width:100%;font-size:14px;color:#565656;list-style:none}.area-selectable-list .area-select-option{position:relative;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:pointer;padding:0 15px 0 10px;height:32px;line-height:32px}.area-selectable-list .area-select-option.hover{background-color:#e4e8f1}.area-selectable-list .area-select-option.selected{background-color:#e4e8f1;color:#ff6200;font-weight:700}.cascader-menu-list-wrap{position:absolute;white-space:nowrap;z-index:15000;border:1px solid #a1a4ad;border-radius:2px;background-color:#fff;box-shadow:0 2px 4px rgba(0,0,0,.12),0 0 6px rgba(0,0,0,.04);box-sizing:border-box;margin:5px 0;overflow:hidden;font-size:0}.cascader-menu-list{position:relative;margin:0;font-size:14px;color:#565656;padding:6px 0;list-style:none;display:inline-block;height:204px;overflow-x:hidden;overflow-y:auto;min-width:160px;vertical-align:top;background-color:#fff;border-right:1px solid #e4e7ed}.cascader-menu-list:last-child{border-right:none}.cascader-menu-list .cascader-menu-option{position:relative;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:pointer;padding:0 15px 0 10px;height:32px;line-height:32px}.cascader-menu-list .cascader-menu-option.hover,.cascader-menu-list .cascader-menu-option:hover{background-color:#e4e8f1}.cascader-menu-list .cascader-menu-option.selected{background-color:#e4e8f1;color:#ff6200;font-weight:700}.cascader-menu-list .cascader-menu-option.cascader-menu-extensible:after{position:absolute;top:50%;margin-top:-4px;right:5px;content:"";width:0;height:0;border:4px solid transparent;border-left-color:#a1a4ad}.area-selectable-list-wrap::-webkit-scrollbar,.cascader-menu-list::-webkit-scrollbar{width:8px;background:transparent}.area-selectable-list-wrap::-webkit-scrollbar-button:vertical:decremen,.area-selectable-list-wrap::-webkit-scrollbar-button:vertical:end:decrement,.area-selectable-list-wrap::-webkit-scrollbar-button:vertical:increment,.area-selectable-list-wrap::-webkit-scrollbar-button:vertical:start:increment,.cascader-menu-list::-webkit-scrollbar-button:vertical:decremen,.cascader-menu-list::-webkit-scrollbar-button:vertical:end:decrement,.cascader-menu-list::-webkit-scrollbar-button:vertical:increment,.cascader-menu-list::-webkit-scrollbar-button:vertical:start:increment{display:none}.area-selectable-list-wrap::-webkit-scrollbar-thumb:vertical,.cascader-menu-list::-webkit-scrollbar-thumb:vertical{background-color:#b8b8b8;border-radius:4px}.area-selectable-list-wrap::-webkit-scrollbar-thumb:vertical:hover,.cascader-menu-list::-webkit-scrollbar-thumb:vertical:hover{background-color:#777}
--------------------------------------------------------------------------------
/gh/components/footer/index.js:
--------------------------------------------------------------------------------
1 | import React, {Component, Children} from 'react';
2 |
3 | export default class Footer extends Component {
4 | constructor (){
5 | super ();
6 | }
7 |
8 | render () {
9 | return (
10 |
15 | );
16 | }
17 | }
--------------------------------------------------------------------------------
/gh/components/header/index.js:
--------------------------------------------------------------------------------
1 | import React, {Component, Children} from 'react';
2 |
3 | export default class Header extends Component {
4 | constructor (){
5 | super ();
6 | }
7 |
8 | render () {
9 | return (
10 |
21 | );
22 | }
23 | }
--------------------------------------------------------------------------------
/gh/components/main/area-text-code.js:
--------------------------------------------------------------------------------
1 | import React, {Component, Children} from 'react';
2 | import { pca } from 'area-data';
3 |
4 | import { AreaSelect } from '../../../src/index';
5 |
6 | export default class AreaText extends Component {
7 | constructor (){
8 | super ();
9 | this.state = {
10 | selected: [],
11 | shown: false
12 | };
13 | }
14 |
15 | handleSelectedChange = (val) => {
16 | this.setState({
17 | selected: val
18 | });
19 | }
20 |
21 | toggle = () => {
22 | this.setState({
23 | shown: !this.state.shown
24 | });
25 | }
26 |
27 | render () {
28 | return (
29 |
30 |
33 |
34 |
{`${JSON.stringify(this.state.selected)}`}
35 |
36 | {
37 | this.state.shown &&
38 |
39 |
//返回值是一个数组,数组项是包含省市的行政区域代码和文本的对象
<AreaSelect type='all' onChange={this.handleSelectedChange}/>
40 |
41 | }
42 |
43 | {this.state.shown ? 'Hide Code' : 'Show Code'}
44 |
45 |
46 | );
47 | }
48 | }
--------------------------------------------------------------------------------
/gh/components/main/area-text.js:
--------------------------------------------------------------------------------
1 | import React, {Component, Children} from 'react';
2 | import { pca } from 'area-data';
3 |
4 | import { AreaSelect } from '../../../src/index';
5 |
6 | export default class AreaText extends Component {
7 | constructor (){
8 | super ();
9 | this.state = {
10 | selected: [],
11 | shown: false
12 | };
13 | }
14 |
15 | handleSelectedChange = (val) => {
16 | this.setState({
17 | selected: val
18 | });
19 | }
20 |
21 | toggle = () => {
22 | this.setState({
23 | shown: !this.state.shown
24 | });
25 | }
26 |
27 | render () {
28 | return (
29 |
30 |
33 |
34 |
{`[${this.state.selected}]`}
35 |
36 | {
37 | this.state.shown &&
38 |
39 |
//type:['text','all','code'], 默认值是 code. 返回值是一个数组,分别是省市的行政区域文本
<AreaSelect type='text' onChange={this.handleSelectedChange}/>
40 |
41 | }
42 |
43 | {this.state.shown ? 'Hide Code' : 'Show Code'}
44 |
45 |
46 | );
47 | }
48 | }
--------------------------------------------------------------------------------
/gh/components/main/basic.js:
--------------------------------------------------------------------------------
1 | import React, {Component, Children} from 'react';
2 | import { pca } from 'area-data';
3 |
4 | import { AreaSelect } from '../../../src/index';
5 |
6 | export default class Basic extends Component {
7 | constructor (){
8 | super ();
9 | this.state = {
10 | selected: [],
11 | shown: false
12 | };
13 | }
14 |
15 | handleSelectedChange = (val) => {
16 | this.setState({
17 | selected: val
18 | });
19 | }
20 |
21 | toggle = () => {
22 | this.setState({
23 | shown: !this.state.shown
24 | });
25 | }
26 |
27 | render () {
28 | const { placeholders } = this.props;
29 | return (
30 |
31 |
34 |
35 |
{`[${this.state.selected}]`}
36 |
37 | {
38 | this.state.shown && !placeholders &&
39 |
40 |
//返回值是一个数组,分别是省市的行政区域代码
<AreaSelect onChange={this.handleSelectedChange}/>
41 |
42 | }
43 | {
44 | this.state.shown && placeholders &&
45 |
46 |
//设置 placeholders,其值应该和关联层次对应
<AreaSelect placeholders={['选择省', '选择市']} onChange={this.handleSelectedChange}/>
47 |
48 | }
49 |
50 | {this.state.shown ? 'Hide Code' : 'Show Code'}
51 |
52 |
53 | );
54 | }
55 | }
--------------------------------------------------------------------------------
/gh/components/main/cas-basic.js:
--------------------------------------------------------------------------------
1 | import React, {Component, Children} from 'react';
2 | import { pca } from 'area-data';
3 |
4 | import { AreaCascader } from '../../../src/index';
5 |
6 | export default class CasBasic extends Component {
7 | constructor (){
8 | super ();
9 | this.state = {
10 | selected: [],
11 | shown: false
12 | };
13 | }
14 |
15 | handleSelectedChange = (val) => {
16 | this.setState({
17 | selected: val
18 | });
19 | }
20 |
21 | toggle = () => {
22 | this.setState({
23 | shown: !this.state.shown
24 | });
25 | }
26 |
27 | render () {
28 |
29 | return (
30 |
31 |
34 |
35 |
{`[${this.state.selected}]`}
36 |
37 | {
38 | this.state.shown &&
39 |
40 |
//返回值是一个数组,分别是省市的行政区域代码
<AreaCascader onChange={this.handleSelectedChange}/>
41 |
42 | }
43 |
44 | {this.state.shown ? 'Hide Code' : 'Show Code'}
45 |
46 |
47 | );
48 | }
49 | }
--------------------------------------------------------------------------------
/gh/components/main/cas-def-value.js:
--------------------------------------------------------------------------------
1 | import React, {Component, Children} from 'react';
2 | import { pcaa } from 'area-data';
3 |
4 | import { AreaCascader } from '../../../src/index';
5 |
6 | export default class DefaultVal extends Component {
7 | constructor (){
8 | super ();
9 | this.state = {
10 | selected: [],
11 | shown: false
12 | };
13 | }
14 |
15 | handleSelectedChange = (val) => {
16 | this.setState({
17 | selected: val
18 | });
19 | }
20 |
21 | toggle = () => {
22 | this.setState({
23 | shown: !this.state.shown
24 | });
25 | }
26 |
27 | render () {
28 | let def = ['440000','440300','440305'];
29 | // if(level === 0) {
30 | // def = ['440000'];
31 | // } else if (level === 2) {
32 | // def = ['440000','440300','440305'];
33 | // } else {
34 | // def = ['广东省', '深圳市', '南山区', '粤海街道'];
35 | // }
36 |
37 | return (
38 |
39 |
42 |
43 |
{`[${this.state.selected}]`}
44 |
45 | {
46 | this.state.shown &&
47 |
48 |
//绑定默认值defaultArea=['440000','440300','440305'], 代码对应的区域文本是['广东省', '深圳市', '南山区']
<AreaCascader type='text' level={1} defaultArea={defaultArea} onChange={this.handleSelectedChange}/>
49 |
50 | }
51 |
52 | {this.state.shown ? 'Hide Code' : 'Show Code'}
53 |
54 |
55 | );
56 | }
57 | }
--------------------------------------------------------------------------------
/gh/components/main/cas-linkage.js:
--------------------------------------------------------------------------------
1 | import React, {Component, Children} from 'react';
2 | import { pcaa } from 'area-data';
3 |
4 | import { AreaCascader } from '../../../src/index';
5 |
6 | export default class DefaultVal extends Component {
7 | constructor (){
8 | super ();
9 | this.state = {
10 | selected: [],
11 | shown: false
12 | };
13 | }
14 |
15 | handleSelectedChange = (val) => {
16 | this.setState({
17 | selected: val
18 | });
19 | }
20 |
21 | toggle = () => {
22 | this.setState({
23 | shown: !this.state.shown
24 | });
25 | }
26 |
27 | render () {
28 |
29 | return (
30 |
31 |
34 |
35 |
{`[${this.state.selected}]`}
36 |
37 | {
38 | this.state.shown &&
39 |
40 |
//代码对应的区域文本是['广东省', '深圳市', '南山区']
<AreaCascader type='text' level={1} onChange={this.handleSelectedChange}/>
41 |
42 | }
43 |
44 | {this.state.shown ? 'Hide Code' : 'Show Code'}
45 |
46 |
47 | );
48 | }
49 | }
--------------------------------------------------------------------------------
/gh/components/main/cas-text-code.js:
--------------------------------------------------------------------------------
1 | import React, {Component, Children} from 'react';
2 | import { pca } from 'area-data';
3 |
4 | import { AreaCascader } from '../../../src/index';
5 |
6 | export default class CasAreaText extends Component {
7 | constructor (){
8 | super ();
9 | this.state = {
10 | selected: [],
11 | shown: false
12 | };
13 | }
14 |
15 | handleSelectedChange = (val) => {
16 | this.setState({
17 | selected: val
18 | });
19 | }
20 |
21 | toggle = () => {
22 | this.setState({
23 | shown: !this.state.shown
24 | });
25 | }
26 |
27 | render () {
28 | return (
29 |
30 |
33 |
34 |
{`${JSON.stringify(this.state.selected)}`}
35 |
36 | {
37 | this.state.shown &&
38 |
39 |
//返回值是一个数组,数组项是包含省市的行政区域代码和文本的对象
<AreaCascader type='all' onChange={this.handleSelectedChange}/>
40 |
41 | }
42 |
43 | {this.state.shown ? 'Hide Code' : 'Show Code'}
44 |
45 |
46 | );
47 | }
48 | }
--------------------------------------------------------------------------------
/gh/components/main/default-value.js:
--------------------------------------------------------------------------------
1 | import React, {Component, Children} from 'react';
2 | import { pca, pcaa } from 'area-data';
3 |
4 | import { AreaSelect } from '../../../src/index';
5 |
6 | export default class DefaultVal extends Component {
7 | constructor (){
8 | super ();
9 | this.state = {
10 | selected: [],
11 | shown: false
12 | };
13 | }
14 |
15 | handleSelectedChange = (val) => {
16 | this.setState({
17 | selected: val
18 | });
19 | }
20 |
21 | toggle = () => {
22 | this.setState({
23 | shown: !this.state.shown
24 | });
25 | }
26 |
27 | render () {
28 | const { level, type } = this.props;
29 | let def = [];
30 | let d = {};
31 | if(level === 0) {
32 | def = ['440000'];
33 | d = pca;
34 | } else if (level === 2) {
35 | def = ['440000','440300','440305'];
36 | d = pcaa;
37 | }
38 |
39 | return (
40 |
41 |
44 |
45 | {
46 | level > 0 &&
47 |
{`[${this.state.selected}]`}
48 | }
49 | {
50 | level === 0 &&
51 |
{`${JSON.stringify(this.state.selected)}`}
52 | }
53 |
54 | {
55 | this.state.shown && level === 2 &&
56 |
57 |
//绑定默认值defaultArea=['440000','440300','440305'],代码对应的区域文本是['广东省', '深圳市', '南山区']
<AreaSelect level={2} defaultArea={['440000','440300','440305']} onChange={this.handleSelectedChange}/>
58 |
59 | }
60 | {
61 | this.state.shown && level === 3 &&
62 |
63 |
//返回值是一个数组,分别是省份行政区域文本
<AreaSelect type='text' level={3} defaultArea={['广东省', '深圳市', '南山区', '粤海街道']} onChange={this.handleSelectedChange}/>
64 |
65 | }
66 | {
67 | this.state.shown && level === 0 &&
68 |
69 |
//返回值是一个数组,分别是省份行政区域代码
<AreaSelect type='all' level={0} defaultArea={['440000']} onChange={this.handleSelectedChange}/>
70 |
71 | }
72 |
73 | {this.state.shown ? 'Hide Code' : 'Show Code'}
74 |
75 |
76 | );
77 | }
78 | }
--------------------------------------------------------------------------------
/gh/components/main/index.js:
--------------------------------------------------------------------------------
1 | import './index.less';
2 |
3 | import React, {Component, Children} from 'react';
4 |
5 | import Basic from './basic';
6 | import Size from './size';
7 | import AreaText from './area-text';
8 | import AreaTextCode from './area-text-code';
9 | import DefaultVal from './default-value';
10 |
11 | import CasBasic from './cas-basic';
12 | import CasAreaTextCode from './cas-text-code';
13 | import CasAreaDef from './cas-def-value';
14 | import CasLink from './cas-linkage';
15 |
16 | export default class Main extends Component {
17 | constructor (){
18 | super ();
19 | }
20 |
21 | render () {
22 | return (
23 |
24 |
基本使用
25 |
1. 作为选择器
26 |
默认形式
27 |
28 |
改变大小
29 |
30 |
返回区域文本
31 |
32 |
返回区域代码和文本
33 |
34 |
设置 placeholders
35 |
36 |
37 | placeholders
是一个数组, 数组项顺序分别对应省/市/区.
38 |
39 |
设置默认值及省市区联动
40 |
41 |
42 | selected
是一个数组, 数组项顺序分别对应省/市/区, 且类型(区域代码/区域文本)必须统一. 以第一个元素类型为基准. 类型不统一将报错.
43 |
44 |
只选省份
45 |
46 |
2. 作为级联器(只支持2/3级联动)
47 |
默认形式
48 |
49 |
返回区域文本和代码
50 |
51 |
52 | type
表示返回值, 支持:['text', 'code', 'all'], 默认值是 code
53 |
54 |
设置默认值
55 |
56 |
省市区联动
57 |
58 |
59 | );
60 | }
61 | }
--------------------------------------------------------------------------------
/gh/components/main/index.less:
--------------------------------------------------------------------------------
1 | .app-main{
2 | margin-top: 20px;
3 | h3{
4 | text-align: center;
5 | font-size: 25px;
6 | color: #6289ad
7 | }
8 | h4{
9 | margin-top: 25px;
10 | font-size: 18px;
11 | color: #6289ad
12 | }
13 | h5{
14 | margin-top: 20px;
15 | font-size: 16px;
16 | color: #6289ad
17 | }
18 | .desc{
19 | margin-top: 15px;
20 | code{
21 | background: #f8f8f8;
22 | color: #333;
23 | padding: 5px;
24 | }
25 | }
26 | .code-area{
27 | position: relative;
28 | width: 100%;
29 | height: auto;
30 | border: 1px solid #dce7f4;
31 | border-radius: 4px;
32 | margin-top: 20px;
33 | padding: 0;
34 | &>div{
35 | margin-top: 40px;
36 | display: inline-block;
37 | vertical-align: middle
38 | }
39 | .area-left{
40 | width: 75%;
41 | margin-left: 10px;
42 | }
43 | .area-right{
44 | width: 21%;
45 | margin-left: 10px;
46 | pre{
47 | background: #f8f8f8;
48 | padding: 15px 10px;
49 | color: #6289ad;
50 | line-height: 20px
51 | }
52 | }
53 | .original-code{
54 | width: 90%;
55 | margin: 25px 45px -10px;
56 | pre{
57 | background: #f8f8f8;
58 | padding: 15px 10px;
59 | }
60 | }
61 | .show-code{
62 | width: 100%;
63 | cursor: pointer;
64 | text-align: center;
65 | border-top: 1px solid #dce7f4;
66 | padding-top: 3px;
67 | padding-bottom: 3px;
68 | color: #6289ad;
69 | font-weight: 500;
70 | font-size: 18px;
71 | &:hover{
72 | background-color: #dce7f4;
73 | color: #fff;
74 | }
75 | }
76 | }
77 | }
--------------------------------------------------------------------------------
/gh/components/main/size.js:
--------------------------------------------------------------------------------
1 | import React, {Component, Children} from 'react';
2 |
3 | import { pca } from 'area-data';
4 |
5 | import { AreaSelect } from '../../../src/index';
6 |
7 | export default class Size extends Component {
8 | constructor (){
9 | super ();
10 | this.state = {
11 | selected: [],
12 | shown: false
13 | };
14 | }
15 |
16 | handleSelectedChange = (val) => {
17 | this.setState({
18 | selected: val
19 | });
20 | }
21 |
22 | toggle = () => {
23 | this.setState({
24 | shown: !this.state.shown
25 | });
26 | }
27 |
28 | render () {
29 | return (
30 |
31 |
34 |
35 |
{`[${this.state.selected}]`}
36 |
37 | {
38 | this.state.shown &&
39 |
40 |
//size:['small','default','large'], 默认值是 default
<AreaSelect size='large' onChange={this.handleSelectedChange}/>
41 |
42 | }
43 |
44 | {this.state.shown ? 'Hide Code' : 'Show Code'}
45 |
46 |
47 | );
48 | }
49 | }
--------------------------------------------------------------------------------
/gh/components/start/index.js:
--------------------------------------------------------------------------------
1 | import './index.less';
2 | import React, {Component, Children} from 'react';
3 |
4 | export default class Start extends Component {
5 | constructor (){
6 | super ();
7 | }
8 |
9 | render () {
10 | return (
11 |
12 |
快速开始
13 |
14 |
安装
15 |
npm i --save react-area-linkage
16 |
或者
17 |
yarn add react-area-linkage
18 |
19 |
20 |
使用
21 |
import React from 'react';
import ReactDOM from 'react-dom';
import 'react-area-linkage/dist/index.css';
import { AreaSelect, AreaCascader } from 'react-area-linkage';
<AreaSelect/>
<AreaCascader/>
22 |
23 |
24 |
25 | );
26 | }
27 | }
--------------------------------------------------------------------------------
/gh/components/start/index.less:
--------------------------------------------------------------------------------
1 | .start{
2 | margin-top: 40px;
3 | h3{
4 | text-align: center;
5 | font-size: 25px;
6 | color: #6289ad
7 | }
8 | h4{
9 | font-size: 18px;
10 | color: #6289ad
11 | }
12 | pre{
13 | margin-top: 15px;
14 | background: #f8f8f8;
15 | padding: 15px 10px;
16 | color: #000;
17 | font-size: 16px;
18 | font-weight: 400
19 | }
20 | .install{
21 | margin-top: 20px;
22 | p{
23 | margin-top: 20px;
24 | margin-bottom: 20px;
25 | }
26 | }
27 | .register{
28 | margin-top: 20px
29 | }
30 | }
--------------------------------------------------------------------------------
/gh/general/app/index.js:
--------------------------------------------------------------------------------
1 | import './index.less';
2 |
3 | import React, {Component, Children} from 'react';
4 |
5 | import Header from '@components/header/index';
6 | import Start from '@components/start/index';
7 | import Main from '@components/main/index';
8 | import Footer from '@components/footer/index';
9 |
10 | import AreaSelect from '../../../components/area-select/index';
11 | import AreaCascader from '../../../components/area-cascader/index';
12 |
13 | export default class App extends Component {
14 | constructor (){
15 | super ();
16 | this.state = {
17 | selected: [] //['广东省', '深圳市', '南山区'] //['440000','440300','440305']
18 | };
19 | }
20 |
21 | onChange = (val) => {
22 | console.log('aaaaaa', val);
23 | }
24 |
25 | render () {
26 | return (
27 |
28 | {
29 | //
1
30 | //
1
31 | //
1
32 | //
1
33 | //
1
34 | //
35 | //
36 | }
37 |
38 |
39 |
40 |
41 |
42 | );
43 | }
44 |
45 | componentDidMount () {
46 | // setTimeout(() => {
47 | // this.setState({
48 | // selected: ['440000','440300','440305']
49 | // });
50 | // }, 2000);
51 | }
52 | }
--------------------------------------------------------------------------------
/gh/general/app/index.less:
--------------------------------------------------------------------------------
1 | .app-wrap{
2 | width: 960px;
3 | height: 200px;
4 | margin: 0 auto;
5 | }
6 |
7 | // header 部分
8 | header{
9 | text-align: center;
10 | margin-top: 100px;
11 | }
12 | h2{
13 | font-size: 27px;
14 | font-weight: 400
15 | }
16 | header p{
17 | margin-top: 20px;
18 | margin-bottom: 20px;
19 | font-size: 16px
20 | }
21 |
22 | header>a{
23 | position: fixed;
24 | right: 0;
25 | top: 0
26 | }
27 |
28 | header p a{
29 | color: #008efd;
30 | text-decoration: none;
31 | padding-left: 5px
32 | }
33 |
34 | // footer 部分
35 | footer{
36 | margin-top: 30px;
37 | text-align: center;
38 | color: #999;
39 | a {
40 | text-decoration: none;
41 | color: #999;
42 | }
43 | }
44 | footer p{
45 | margin-top: 15px;
46 | cursor: pointer;
47 | }
48 | footer p:hover{
49 | color: #008efd;
50 | a {
51 | color: #008efd
52 | }
53 | }
--------------------------------------------------------------------------------
/gh/page/index.js:
--------------------------------------------------------------------------------
1 | import './reset.less';
2 |
3 | import React, {Component, Children} from 'react';
4 | import ReactDOM from 'react-dom';
5 | import { AppContainer } from 'react-hot-loader';
6 |
7 | import App from '../general/app/index';
8 |
9 | const env = process.env.NODE_ENV || 'development';
10 |
11 | if(env === 'development'){
12 | window.onload = function () {
13 | const render = Component => {
14 | ReactDOM.render(
15 |
16 |
17 | ,
18 | document.getElementById('app')
19 | );
20 | };
21 |
22 | render(App);
23 |
24 | // HMR
25 | if (module.hot) {
26 | module.hot.accept('../general/app/index', () => { render(App); });
27 | }
28 | };
29 | } else {
30 | window.onload = function () {
31 | ReactDOM.render(
32 | ,
33 | document.getElementById('app')
34 | );
35 | };
36 | }
37 |
--------------------------------------------------------------------------------
/gh/page/reset.less:
--------------------------------------------------------------------------------
1 | html, body, div, span, applet, object, iframe,
2 | h1, h2, h3, h4, h5, h6, p, blockquote, pre,
3 | a, abbr, acronym, address, big, cite, code,
4 | del, dfn, em, img, ins, kbd, q, s, samp,
5 | small, strike, strong, sub, sup, tt, var,
6 | b, u, i, center,
7 | dl, dt, dd, ol, ul, li,
8 | fieldset, form, label, legend,
9 | table, caption, tbody, tfoot, thead, tr, th, td,
10 | article, aside, canvas, details, embed,
11 | figure, figcaption, footer, header, hgroup,
12 | menu, nav, output, ruby, section, summary,
13 | time, mark, audio, video {
14 | margin: 0;
15 | padding: 0;
16 | border: 0;
17 | font-size: 100%;
18 | outline:0;
19 | vertical-align:baseline;
20 | background:transparent;
21 | }
22 | /* HTML5 display-role reset for older browsers */
23 | article, aside, details, figcaption, figure,
24 | footer, header, hgroup, menu, nav, section {
25 | display: block;
26 | }
27 |
28 | html,body {
29 | height: 100%;
30 | width: 100%;
31 | /* # https://github.com/AlloyTeam/Mars/blob/master/solutions/font-family.md */
32 | font-family: -apple-system, BlinkMacSystemFont, "PingFang SC","Helvetica Neue",STHeiti,"Microsoft Yahei",Tahoma,Simsun,sans-serif;
33 | }
34 |
35 | body {
36 | margin:0;
37 | padding:0;
38 | box-sizing: border-box;
39 | font-size: 14px;
40 | line-height: 1;
41 | background: none;
42 | -moz-user-select:none;
43 | -webkit-user-select:none;
44 | -ms-user-select:none;
45 | user-select:none;
46 | overflow-x:hidden;
47 | -webkit-overflow-scrolling:touch;
48 | -webkit-font-smoothing: antialiased;
49 | -moz-osx-font-smoothing: grayscale;
50 | tap-highlight-color: transparent;
51 | -webkit-tap-highlight-color: transparent;
52 | }
53 |
54 | ol, ul, nav ul {
55 | list-style: none;
56 | }
57 |
58 | blockquote, q {
59 | quotes: none;
60 | }
61 |
62 | blockquote:before, blockquote:after,
63 | q:before, q:after {
64 | content: '';
65 | }
66 |
67 | table {
68 | border-collapse:collapse;
69 | border-spacing:0;
70 | }
71 |
72 | a{
73 | text-decoration:none;
74 | margin: 0;
75 | padding: 0;
76 | border: 0;
77 | font-size:100%;
78 | vertical-align:baseline;
79 | background:transparent;
80 | -webkit-appearance: none;
81 | -webkit-tap-highlight-color: transparent;
82 | }
83 |
84 | :focus {
85 | outline: none;
86 | }
87 |
88 | ins {
89 | background-color:#ff9;
90 | color:#000;
91 | text-decoration:none;
92 | }
93 |
94 | mark {
95 | background-color:#ff9;
96 | color:#000;
97 | font-style:italic;
98 | font-weight:bold;
99 | }
100 |
101 | del {
102 | text-decoration: line-through;
103 | }
104 |
105 | abbr[title], dfn[title] {
106 | border-bottom:1px dotted #000;
107 | cursor:help;
108 | }
109 |
110 | hr {
111 | display:block;
112 | height:1px;
113 | border:0;
114 | border-top:1px solid #cccccc;
115 | margin:1em 0;
116 | padding:0;
117 | }
118 |
119 | input[type="text"], input[type="password"], textarea, input, select {
120 | outline: none;
121 | -webkit-appearance: none;
122 | }
123 |
124 | input, select {
125 | vertical-align:middle;
126 | }
127 |
128 | * {
129 | box-sizing: border-box;
130 | /* # https://github.com/AlloyTeam/Mars/blob/master/solutions/font-family.md */
131 | font-family: -apple-system, BlinkMacSystemFont, "PingFang SC","Helvetica Neue",STHeiti,"Microsoft Yahei",Tahoma,Simsun,sans-serif;
132 | /*font: 0.12rem/1 "Microsoft YaHei", Tahoma, Arial, Helvetica, \\5b8b\4f53, "Helvetica Neue", "PingFang SC", "Heiti SC", "Hiragino Sans GB", "\5FAE\8F6F\96C5\9ED1", sans-serif;*/
133 | color: inherit;
134 | }
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 | React Area Linkage-中国省市区联动选择器
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-area-linkage",
3 | "version": "3.0.0",
4 | "description": "React area linkage",
5 | "author": "dwqs",
6 | "license": "MIT",
7 | "main": "dist/index.js",
8 | "private": false,
9 | "repository": {
10 | "type": "git",
11 | "url": "https://github.com/dwqs/react-area-linkage.git"
12 | },
13 | "bugs": {
14 | "url": "https://github.com/dwqs/react-area-linkage/issues"
15 | },
16 | "keywords": [
17 | "react",
18 | "react 16",
19 | "area",
20 | "picker",
21 | "react picker",
22 | "react linkage"
23 | ],
24 | "scripts": {
25 | "prepush": "npm run ilint -q",
26 | "dev": "npx cross-env NODE_ENV=development node ./build/dev-server.js",
27 | "build:components": "NODE_ENV=production npx webpack --config ./webpack.components.config.js --progress --hide-modules",
28 | "build": "npx cross-env NODE_ENV=production npx webpack --config ./build/webpack.prod.config.js --progress --hide-modules",
29 | "ilint": "npx eslint src/**/*.js",
30 | "fix": "npx eslint --fix src/**/*.js",
31 | "postbuild": "mv ./demo/index.html ./",
32 | "prepublishOnly": "rm -rf dist && npm run build:components && npx webpack --config ./webpack.build.config.js --progress --hide-modules"
33 | },
34 | "dependencies": {
35 | "array-tree-filter": "^2.1.0",
36 | "classnames": "^2.2.5",
37 | "lodash.find": "^4.6.0",
38 | "prop-types": "^15.6.0"
39 | },
40 | "peerDependencies": {
41 | "react": ">= 15.0.0",
42 | "react-dom": ">=15.0.0",
43 | "area-data": ">=5.0.6"
44 | },
45 | "devDependencies": {
46 | "area-data": "^5.0.6",
47 | "autoprefixer": "^7.1.5",
48 | "babel-core": "^6.26.0",
49 | "babel-eslint": "^8.0.1",
50 | "babel-loader": "^7.1.2",
51 | "babel-plugin-transform-class-properties": "^6.24.1",
52 | "babel-plugin-transform-decorators-legacy": "^1.3.4",
53 | "babel-plugin-transform-react-remove-prop-types": "^0.4.9",
54 | "babel-preset-env": "^1.6.0",
55 | "babel-preset-react": "^6.24.1",
56 | "babel-preset-stage-2": "^6.24.1",
57 | "clean-webpack-plugin": "^0.1.17",
58 | "compression-webpack-plugin": "^1.0.1",
59 | "copy-webpack-plugin": "^4.1.1",
60 | "cross-env": "^5.0.5",
61 | "css-loader": "^0.28.7",
62 | "cssnano": "^3.10.0",
63 | "eslint": "^4.8.0",
64 | "eslint-plugin-import": "^2.7.0",
65 | "eslint-plugin-react": "^7.4.0",
66 | "extract-text-webpack-plugin": "^3.0.1",
67 | "gulp-util": "^3.0.8",
68 | "happypack": "^4.0.0",
69 | "html-webpack-plugin": "^2.30.1",
70 | "husky": "^0.14.3",
71 | "less": "^2.7.2",
72 | "less-loader": "^4.0.5",
73 | "open-browser-webpack-plugin": "^0.0.5",
74 | "optimize-css-assets-webpack-plugin": "^3.2.0",
75 | "ora": "^1.3.0",
76 | "postcss-loader": "^2.0.6",
77 | "react": "^16.0.0",
78 | "react-dom": "^16.0.0",
79 | "react-hot-loader": "^3.0.0-beta.7",
80 | "style-loader": "^0.19.0",
81 | "webpack": "^3.6.0",
82 | "webpack-dev-server": "^2.9.1",
83 | "webpack-md5-hash": "^0.0.5",
84 | "webpack-parallel-uglify-plugin": "^1.0.0"
85 | },
86 | "engines": {
87 | "node": ">= 6.0.0",
88 | "npm": ">= 5.2.0"
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by pomy on 20/07/2017.
3 | */
4 |
5 | //fix: https://github.com/akveo/ng2-admin/issues/604
6 | //使用 happypack 之后 需单独提供 postcss 配置文件
7 | module.exports = {
8 | plugins: [
9 | require('autoprefixer')({ browsers: ['last 5 versions','Android >= 4.0', 'iOS >= 7'] })
10 | ]
11 | };
12 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import './index.less';
2 |
3 | import AreaSelect from '../components/area-select/index';
4 | import AreaCascader from '../components/area-cascader/index';
5 |
6 | export {
7 | AreaSelect,
8 | AreaCascader
9 | };
10 |
11 | const ReactAreaLinkage = {
12 | AreaSelect,
13 | AreaCascader
14 | };
15 |
16 | export default ReactAreaLinkage;
--------------------------------------------------------------------------------
/src/index.less:
--------------------------------------------------------------------------------
1 | .area-zoom-in-top-enter,
2 | .area-zoom-in-top-exit-active {
3 | opacity: 0;
4 | transform: scaleY(0);
5 | }
6 |
7 | .area-zoom-in-top-enter-active,
8 | .area-zoom-in-top-exit {
9 | opacity: 1;
10 | transform: scaleY(1);
11 | transition: all 300ms cubic-bezier(.645,.045,.355,1);
12 | transform-origin: center top;
13 | }
14 |
15 | .area-select-wrap .area-select{
16 | margin-left: 10px;
17 | }
18 |
19 | .area-select-wrap .area-select-empty{
20 | padding: 4px 0;
21 | margin: 0;
22 | text-align: center;
23 | color: #999;
24 | font-size: 14px;
25 | }
26 |
27 | // commoon
28 | .area-select {
29 | position: relative;
30 | display: inline-block;
31 | vertical-align: top;
32 | user-select: none;
33 | height: 32px;
34 | cursor: pointer;
35 | background: #FFFFFF;
36 | border-radius: 4px;
37 | border: 1px solid #e1e2e6;
38 | * {
39 | box-sizing: border-box;
40 | }
41 | &:hover {
42 | border-color: #a1a4ad;
43 | }
44 | &.small {
45 | width: 126px;
46 | }
47 | &.medium {
48 | width: 160px;
49 | }
50 | &.large {
51 | width: 194px;
52 | }
53 | &.is-disabled {
54 | background: #eceff5;
55 | cursor: not-allowed;
56 | &:hover {
57 | border-color: #e1e2e6;
58 | }
59 | .area-selected-trigger {
60 | cursor: not-allowed;
61 | }
62 | }
63 | .area-selected-trigger {
64 | position: relative;
65 | display: block;
66 | font-size: 14px;
67 | cursor: pointer;
68 | margin: 0;
69 | overflow: hidden;
70 | white-space: nowrap;
71 | text-overflow: ellipsis;
72 | height: 100%;
73 | line-height: 100%;
74 | padding: 8px 20px 7px 12px;
75 | }
76 | .area-select-icon {
77 | position: absolute;
78 | top: 50%;
79 | margin-top: -2px;
80 | right: 6px;
81 | content: '';
82 | width: 0;
83 | height: 0;
84 | border: 6px solid transparent;
85 | border-top-color: #a1a4ad;
86 | transition: all .3s linear;
87 | transform-origin: center;
88 | &.active {
89 | margin-top: -8px;
90 | transform: rotate(180deg)
91 | }
92 | }
93 | }
94 |
95 | // select start
96 | .area-selectable-list-wrap {
97 | position: absolute;
98 | width: 100%;
99 | max-height: 275px;
100 | z-index: 15000;
101 | border: 1px solid #a1a4ad;
102 | border-radius: 2px;
103 | background-color: #FFFFFF;
104 | box-shadow: 0 2px 4px rgba(0,0,0,.12), 0 0 6px rgba(0,0,0,.04);
105 | box-sizing: border-box;
106 | margin: 5px 0;
107 | overflow-x: hidden;
108 | overflow-x: auto;
109 | }
110 |
111 | .area-selectable-list {
112 | position: relative;
113 | margin: 0;
114 | padding: 6px 0;
115 | width: 100%;
116 | font-size: 14px;
117 | color: #565656;
118 | list-style: none;
119 | .area-select-option {
120 | position: relative;
121 | white-space: nowrap;
122 | overflow: hidden;
123 | text-overflow: ellipsis;
124 | cursor: pointer;
125 | padding: 0px 15px 0px 10px;
126 | height: 32px;
127 | line-height: 32px;
128 | &.hover {
129 | background-color: #e4e8f1;
130 | }
131 | &.selected {
132 | background-color: #e4e8f1;
133 | color: #FF6200;
134 | font-weight: 700;
135 | }
136 | }
137 | }
138 |
139 | // select end
140 |
141 | // cascader start
142 | .cascader-menu-list-wrap {
143 | position: absolute;
144 | // max-height: 275px;
145 | white-space: nowrap;
146 | z-index: 15000;
147 | border: 1px solid #a1a4ad;
148 | border-radius: 2px;
149 | background-color: #FFFFFF;
150 | box-shadow: 0 2px 4px rgba(0,0,0,.12), 0 0 6px rgba(0,0,0,.04);
151 | box-sizing: border-box;
152 | margin: 5px 0;
153 | overflow: hidden;
154 | font-size: 0;
155 | }
156 |
157 | .cascader-menu-list {
158 | position: relative;
159 | margin: 0;
160 | font-size: 14px;
161 | color: #565656;
162 | padding: 6px 0;
163 | list-style: none;
164 | display: inline-block;
165 | height: 204px;
166 | overflow-x: hidden;
167 | overflow-y: auto;
168 | min-width: 160px;
169 | vertical-align: top;
170 | background-color: #fff;
171 | border-right: 1px solid #e4e7ed;
172 |
173 | &:last-child {
174 | border-right: none;
175 | }
176 | .cascader-menu-option {
177 | position: relative;
178 | white-space: nowrap;
179 | overflow: hidden;
180 | text-overflow: ellipsis;
181 | cursor: pointer;
182 | padding: 0px 15px 0px 10px;
183 | height: 32px;
184 | line-height: 32px;
185 | &.hover {
186 | background-color: #e4e8f1;
187 | }
188 | &:hover {
189 | background-color: #e4e8f1;
190 | }
191 | &.selected {
192 | background-color: #e4e8f1;
193 | color: #FF6200;
194 | font-weight: 700;
195 | }
196 | &.cascader-menu-extensible {
197 | &:after {
198 | position: absolute;
199 | top: 50%;
200 | margin-top: -4px;
201 | right: 5px;
202 | content: "";
203 | width: 0;
204 | height: 0;
205 | border: 4px solid transparent;
206 | border-left-color: #a1a4ad;
207 | }
208 | }
209 | }
210 | }
211 | // cascader end
212 |
213 | // custom scrollbar
214 | .cascader-menu-list, .area-selectable-list-wrap {
215 | &::-webkit-scrollbar {
216 | width: 8px;
217 | background: transparent;
218 | }
219 |
220 | &::-webkit-scrollbar-button:vertical:increment,
221 | &::-webkit-scrollbar-button:vertical:decremen,
222 | &::-webkit-scrollbar-button:vertical:start:increment,
223 | &::-webkit-scrollbar-button:vertical:end:decrement {
224 | display: none;
225 | }
226 |
227 | &::-webkit-scrollbar-thumb:vertical {
228 | background-color: #b8b8b8;
229 | border-radius: 4px;
230 | &:hover {
231 | background-color:#777;
232 | }
233 | }
234 | }
235 |
--------------------------------------------------------------------------------
/src/utils.js:
--------------------------------------------------------------------------------
1 | function contains (root, target) {
2 | // root 节点是否包含 target 节点
3 | const isElement = Object.prototype.toString.call(root).includes('Element') && Object.prototype.toString.call(target).includes('Element');
4 | if (!isElement) {
5 | return false;
6 | }
7 | let node = target;
8 | while (node) {
9 | if (node === root) {
10 | return true;
11 | }
12 | node = node.parentNode;
13 | }
14 | return false;
15 | }
16 |
17 | function assert (condition, msg = '') {
18 | if (!condition) {
19 | console.error(`[react-area-linkage]: ${msg}`);
20 | }
21 | }
22 |
23 | function isArray (param) {
24 | return Object.prototype.toString.call(param) === '[object Array]';
25 | }
26 |
27 | function scrollIntoView (container, target) {
28 | if (!target) {
29 | container.scrollTop = 0;
30 | return;
31 | }
32 |
33 | // refrence: https://github.com/ElemeFE/element/blob/dev/src/utils/scroll-into-view.js
34 | const top = target.offsetTop;
35 | const bottom = target.offsetTop + target.offsetHeight;
36 | const viewRectTop = container.scrollTop;
37 | const viewRectBottom = viewRectTop + container.clientHeight;
38 |
39 | if (top < viewRectTop) {
40 | container.scrollTop = top;
41 | } else if (bottom > viewRectBottom) {
42 | container.scrollTop = bottom - container.clientHeight;
43 | }
44 | }
45 |
46 | function setPanelPosition (panelHeight, wrapRect) {
47 | const wrapHeight = wrapRect.height;
48 | const wrapTop = wrapRect.top;
49 |
50 | const docHeight = document.documentElement.clientHeight;
51 | const panelDefTop = wrapTop + wrapHeight;
52 |
53 | const diff = docHeight - panelDefTop;
54 | if (diff < panelHeight) {
55 | if (wrapTop > panelHeight) {
56 | return -(panelHeight + 10);
57 | } else {
58 | return diff - panelHeight;
59 | }
60 | } else {
61 | return wrapHeight;
62 | }
63 | }
64 |
65 | export {
66 | contains,
67 | assert,
68 | isArray,
69 | scrollIntoView,
70 | setPanelPosition
71 | };
72 |
--------------------------------------------------------------------------------
/tpl.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | React Area Linkage-中国省市区联动选择器
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/webpack.build.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const webpack = require('webpack');
3 | const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin');
4 | const os = require('os');
5 | const ExtractTextPlugin = require('extract-text-webpack-plugin');
6 | const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin');
7 |
8 | module.exports = {
9 | entry: {
10 | index: path.resolve(__dirname, './src/index')
11 | },
12 |
13 | output: {
14 | path: path.join(__dirname, './dist'),
15 | filename: '[name].js',
16 | library: 'ReactAreaLinkage',
17 | libraryTarget: 'umd'
18 | },
19 |
20 | module: {
21 | rules: [
22 | {
23 | test: /\.jsx?$/,
24 | exclude: /node_modules/,
25 | loader: 'babel-loader'
26 | },
27 | {
28 | test: /\.less$/,
29 | use: ExtractTextPlugin.extract({
30 | fallback: 'style-loader',
31 | use: ['css-loader', 'postcss-loader', 'less-loader']
32 | })
33 | },
34 | {
35 | test: /\.css$/,
36 | use: ExtractTextPlugin.extract({
37 | fallback: 'style-loader',
38 | use: ['css-loader']
39 | })
40 | }
41 | ]
42 | },
43 |
44 | // fix: https://stackoverflow.com/questions/38053561/only-a-reactowner-can-have-refs-you-might-be-adding-a-ref-to-a-component-that-w
45 | externals: [{
46 | 'react': {
47 | root: 'React',
48 | commonjs2: 'react',
49 | commonjs: 'react',
50 | amd: 'react'
51 | }
52 | }, {
53 | 'react-dom': {
54 | root: 'ReactDOM',
55 | commonjs2: 'react-dom',
56 | commonjs: 'react-dom',
57 | amd: 'react-dom'
58 | }
59 | }],
60 |
61 | resolve: {
62 | extensions: ['.js', '.jsx'],
63 | modules: [path.join(__dirname, './node_modules')],
64 | alias: {
65 | '@src': path.resolve(__dirname, './src')
66 | }
67 | },
68 |
69 | plugins: [
70 | new ExtractTextPlugin({
71 | filename: '[name].css'
72 | }),
73 |
74 | new OptimizeCSSPlugin({
75 | cssProcessorOptions: {
76 | safe: true
77 | },
78 | cssProcessor: require('cssnano'),
79 | assetNameRegExp: /\.less|\.css$/g
80 | }),
81 |
82 | // new ParallelUglifyPlugin({
83 | // workerCount: os.cpus().length,
84 | // cacheDir: '.cache/',
85 | // sourceMap: false,
86 | // compress: {
87 | // warnings: false,
88 | // drop_debugger: true,
89 | // drop_console: true
90 | // },
91 | // mangle: true
92 | // }),
93 | new webpack.optimize.ModuleConcatenationPlugin()
94 | ]
95 | };
96 |
--------------------------------------------------------------------------------
/webpack.components.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const webpack = require('webpack');
3 |
4 | const Components = require('./components.json');
5 |
6 | module.exports = {
7 | entry: Components,
8 | output: {
9 | path: path.join(__dirname, './dist/lib'),
10 | filename: '[name].js',
11 | libraryTarget: 'commonjs2'
12 | },
13 | module: {
14 | rules: [
15 | {
16 | test: /\.js$/,
17 | exclude: /node_modules/,
18 | loader: 'babel-loader'
19 | }
20 | ]
21 | },
22 |
23 | externals: [{
24 | 'react': {
25 | root: 'React',
26 | commonjs2: 'react',
27 | commonjs: 'react',
28 | amd: 'react'
29 | }
30 | }, {
31 | 'react-dom': {
32 | root: 'ReactDOM',
33 | commonjs2: 'react-dom',
34 | commonjs: 'react-dom',
35 | amd: 'react-dom'
36 | }
37 | }],
38 |
39 | resolve: {
40 | extensions: ['.js', '.jsx'],
41 | modules: [path.join(__dirname, './node_modules')],
42 | alias: {
43 | '@src': path.resolve(__dirname, './src')
44 | }
45 | },
46 |
47 | plugins: [
48 | new webpack.optimize.ModuleConcatenationPlugin()
49 | ]
50 | };
51 |
--------------------------------------------------------------------------------