├── .yo-rc.json
├── coverage
├── lcov-report
│ ├── sort-arrow-sprite.png
│ ├── prettify.css
│ ├── src
│ │ ├── index.js.html
│ │ ├── i18n.js.html
│ │ ├── SuperComponent.js.html
│ │ ├── index.html
│ │ ├── util.js.html
│ │ ├── Search.jsx.html
│ │ └── CascadeSubmenu.jsx.html
│ ├── index.html
│ ├── sorter.js
│ ├── base.css
│ └── prettify.js
└── lcov.info
├── tests
├── index.js
├── options.js
└── CascadeSelect.spec.jsx
├── src
├── index.js
├── i18n.js
├── SuperComponent.js
├── util.js
├── Search.jsx
├── CascadeSubmenu.jsx
├── CascadeSelect.less
└── CascadeSelect.jsx
├── .gitignore
├── .npmignore
├── demo
├── index.js
├── CascadeSelectDemo.less
└── CascadeSelectDemo.jsx
├── .eslintrc.json
├── .travis.yml
├── index.html
├── package.json
├── HISTORY.md
└── README.md
/.yo-rc.json:
--------------------------------------------------------------------------------
1 | {
2 | "generator-uxcore": {}
3 | }
--------------------------------------------------------------------------------
/coverage/lcov-report/sort-arrow-sprite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WisestCoder/uxcore-cascade-select/master/coverage/lcov-report/sort-arrow-sprite.png
--------------------------------------------------------------------------------
/tests/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * only require other specs here
3 | */
4 |
5 | const req = require.context('.', false, /\.spec\.js(x)?$/);
6 | req.keys().forEach(req);
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * CascadeSelect Component for uxcore
3 | * @author changming
4 | *
5 | * Copyright 2015-2017, Uxcore Team, Alinw.
6 | * All rights reserved.
7 | */
8 |
9 | module.exports = require('./CascadeSelect');
10 |
--------------------------------------------------------------------------------
/src/i18n.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'zh-cn': {
3 | placeholder: '请选择',
4 | confirm: '确定',
5 | alreadyChoosed: '已选择',
6 | },
7 | 'en-us': {
8 | placeholder: 'Please select',
9 | confirm: 'OK',
10 | alreadyChoosed: 'Choosed',
11 | },
12 | };
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | *.log
3 | .idea/
4 | .ipr
5 | .iws
6 | *~
7 | ~*
8 | *.diff
9 | *.patch
10 | *.bak
11 | .DS_Store
12 | Thumbs.db
13 | .project
14 | .*proj
15 | .svn/
16 | *.swp
17 | *.swo
18 | *.pyc
19 | *.pyo
20 | .build
21 | node_modules
22 | _site
23 | sea-modules
24 | spm_modules
25 | .cache
26 | .happypack
27 | dist
28 | build
29 | assets/**/*.css
30 | .vscode
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | bower_components/
2 | *.cfg
3 | node_modules/
4 | nohup.out
5 | *.iml
6 | .idea/
7 | .ipr
8 | .iws
9 | *~
10 | ~*
11 | *.diff
12 | *.log
13 | *.patch
14 | *.bak
15 | .DS_Store
16 | Thumbs.db
17 | .project
18 | .*proj
19 | .svn/
20 | *.swp
21 | out/
22 | .build
23 | .happypack
24 | node_modules
25 | _site
26 | sea-modules
27 | spm_modules
28 | .cache
29 | dist
--------------------------------------------------------------------------------
/demo/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * CascadeSelect Component Demo for uxcore
3 | * @author changming
4 | *
5 | * Copyright 2015-2017, Uxcore Team, Alinw.
6 | * All rights reserved.
7 | */
8 |
9 | const ReactDOM = require('react-dom');
10 | const React = require('react');
11 | const Demo = require('./CascadeSelectDemo');
12 | ReactDOM.render(
| 1 47 | 2 48 | 3 49 | 4 50 | 5 51 | 6 52 | 7 53 | 8 54 | 9 55 | 10 56 | 11 57 | 12 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 1× 68 | | 'use strict';
69 |
70 | /**
71 | * CascadeSelect Component for uxcore
72 | * @author changming
73 | *
74 | * Copyright 2015-2017, Uxcore Team, Alinw.
75 | * All rights reserved.
76 | */
77 |
78 | module.exports = require('./CascadeSelect');
79 | |
| 1 47 | 2 48 | 3 49 | 4 50 | 5 51 | 6 52 | 7 53 | 8 54 | 9 55 | 10 56 | 11 57 | 12 58 | 13 59 | 14 60 | 15 | 61 | 62 | 1× 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | | 'use strict';
75 |
76 | module.exports = {
77 | 'zh-cn': {
78 | placeholder: '请选择',
79 | confirm: '确定',
80 | alreadyChoosed: '已选择'
81 | },
82 | 'en-us': {
83 | placeholder: 'Please select',
84 | confirm: 'OK',
85 | alreadyChoosed: 'Choosed'
86 | }
87 | };
88 | |
| File | 50 |51 | | Statements | 52 |53 | | Branches | 54 |55 | | Functions | 56 |57 | | Lines | 58 |59 | |
|---|---|---|---|---|---|---|---|---|---|
| src/ | 63 |87.7% | 65 |499/569 | 66 |74.79% | 67 |264/353 | 68 |80.73% | 69 |88/109 | 70 |88.55% | 71 |441/498 | 72 |
| 1 47 | 2 48 | 3 49 | 4 50 | 5 51 | 6 52 | 7 53 | 8 54 | 9 55 | 10 56 | 11 57 | 12 58 | 13 59 | 14 60 | 15 61 | 16 62 | 17 63 | 18 64 | 19 65 | 20 66 | 21 67 | 22 68 | 23 69 | 24 70 | 25 71 | 26 72 | 27 73 | 28 74 | 29 75 | 30 76 | 31 77 | 32 78 | 33 79 | 34 80 | 35 81 | 36 82 | 37 83 | 38 84 | 39 85 | 40 86 | 41 87 | 42 88 | 43 | 89 | 90 | 1× 91 | 92 | 93 | 94 | 5× 95 | 96 | 33× 97 | 98 | 33× 99 | 100 | 1× 101 | 102 | 1× 103 | 104 | 1× 105 | 1× 106 | 107 | 1× 108 | 33× 109 | 110 | 33× 111 | 112 | 113 | 1× 114 | 787× 115 | 116 | 787× 117 | 800× 118 | 119 | 120 | 121 | 1× 122 | 123 | 124 | 1× 125 | 126 | 127 | 128 | 1× 129 | 1× 130 | | 'use strict';
131 |
132 | Object.defineProperty(exports, "__esModule", {
133 | value: true
134 | });
135 |
136 | function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); Iif (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; }
137 |
138 | function _classCallCheck(instance, Constructor) { Iif (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
139 |
140 | function _possibleConstructorReturn(self, call) { Iif (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
141 |
142 | function _inherits(subClass, superClass) { Iif (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); Eif (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : _defaults(subClass, superClass); }
143 |
144 | var React = require('react');
145 |
146 | var SuperComponent = function (_React$Component) {
147 | _inherits(SuperComponent, _React$Component);
148 |
149 | function SuperComponent() {
150 | _classCallCheck(this, SuperComponent);
151 |
152 | return _possibleConstructorReturn(this, _React$Component.apply(this, arguments));
153 | }
154 |
155 | SuperComponent.prototype.prefixCls = function prefixCls(name) {
156 | var prefixCls = this.props.prefixCls;
157 |
158 | return name.split(/\s/).map(function (i) {
159 | return prefixCls + '-' + i;
160 | }).join(' ');
161 | };
162 |
163 | return SuperComponent;
164 | }(React.Component);
165 |
166 | SuperComponent.propTypes = {
167 | prefixCls: React.PropTypes.string
168 | };
169 |
170 | exports['default'] = SuperComponent;
171 | module.exports = exports['default'];
172 | |
| File | 50 |51 | | Statements | 52 |53 | | Branches | 54 |55 | | Functions | 56 |57 | | Lines | 58 |59 | |
|---|---|---|---|---|---|---|---|---|---|
| CascadeSelect.jsx | 63 |86.92% | 65 |279/321 | 66 |76.5% | 67 |153/200 | 68 |82.76% | 69 |48/58 | 70 |87.58% | 71 |261/298 | 72 ||
| CascadeSubmenu.jsx | 76 |96.09% | 78 |123/128 | 79 |78.75% | 80 |63/80 | 81 |88% | 82 |22/25 | 83 |99% | 84 |99/100 | 85 ||
| Search.jsx | 89 |50% | 91 |12/24 | 92 |30.77% | 93 |4/13 | 94 |22.22% | 95 |2/9 | 96 |47.83% | 97 |11/23 | 98 ||
| SuperComponent.js | 102 |88.89% | 104 |32/36 | 105 |54.17% | 106 |13/24 | 107 |100% | 108 |8/8 | 109 |100% | 110 |19/19 | 111 ||
| i18n.js | 115 |100% | 117 |1/1 | 118 |100% | 119 |0/0 | 120 |100% | 121 |0/0 | 122 |100% | 123 |1/1 | 124 ||
| index.js | 128 |100% | 130 |1/1 | 131 |100% | 132 |0/0 | 133 |100% | 134 |0/0 | 135 |100% | 136 |1/1 | 137 ||
| util.js | 141 |87.93% | 143 |51/58 | 144 |86.11% | 145 |31/36 | 146 |88.89% | 147 |8/9 | 148 |87.5% | 149 |49/56 | 150 |
| 1 47 | 2 48 | 3 49 | 4 50 | 5 51 | 6 52 | 7 53 | 8 54 | 9 55 | 10 56 | 11 57 | 12 58 | 13 59 | 14 60 | 15 61 | 16 62 | 17 63 | 18 64 | 19 65 | 20 66 | 21 67 | 22 68 | 23 69 | 24 70 | 25 71 | 26 72 | 27 73 | 28 74 | 29 75 | 30 76 | 31 77 | 32 78 | 33 79 | 34 80 | 35 81 | 36 82 | 37 83 | 38 84 | 39 85 | 40 86 | 41 87 | 42 88 | 43 89 | 44 90 | 45 91 | 46 92 | 47 93 | 48 94 | 49 95 | 50 96 | 51 97 | 52 98 | 53 99 | 54 100 | 55 101 | 56 102 | 57 103 | 58 104 | 59 105 | 60 106 | 61 107 | 62 108 | 63 109 | 64 110 | 65 111 | 66 112 | 67 113 | 68 114 | 69 115 | 70 116 | 71 117 | 72 118 | 73 119 | 74 120 | 75 121 | 76 122 | 77 123 | 78 124 | 79 125 | 80 126 | 81 127 | 82 128 | 83 129 | 84 130 | 85 131 | 86 132 | 87 133 | 88 134 | 89 135 | 90 136 | 91 137 | 92 138 | 93 139 | 94 140 | 95 141 | 96 142 | 97 | 143 | 144 | 1× 145 | 146 | 147 | 1× 148 | 1× 149 | 150 | 1× 151 | 1× 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 1× 161 | 33× 162 | 163 | 164 | 33× 165 | 166 | 167 | 33× 168 | 33× 169 | 33× 170 | 171 | 33× 172 | 43× 173 | 43× 174 | 33× 175 | 176 | 177 | 178 | 179 | 180 | 181 | 1× 182 | 4× 183 | 184 | 185 | 1× 186 | 4× 187 | 4× 188 | 4× 189 | 1× 190 | 16× 191 | 192 | 16× 193 | 29× 194 | 18× 195 | 3× 196 | 3× 197 | 198 | 18× 199 | 12× 200 | 201 | 202 | 203 | 4× 204 | 4× 205 | 3× 206 | 3× 207 | 8× 208 | 8× 209 | 210 | 211 | 3× 212 | 213 | 214 | 1× 215 | 36× 216 | 36× 217 | 218 | 36× 219 | 15× 220 | 221 | 21× 222 | 9× 223 | 12× 224 | 9× 225 | 226 | 227 | 228 | 12× 229 | 230 | 231 | 1× 232 | 233 | 234 | 235 | 236 | 237 | 1× 238 | | 'use strict';
239 |
240 | Object.defineProperty(exports, "__esModule", {
241 | value: true
242 | });
243 | var _arguments = arguments;
244 | var supportNativeFind = !!Array.prototype.find;
245 |
246 | var find = function () {
247 | Iif (supportNativeFind) {
248 | return function (ary) {
249 | for (var _len = arguments.length, params = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
250 | params[_key - 1] = arguments[_key];
251 | }
252 |
253 | return ary.find.apply(ary, params);
254 | };
255 | }
256 | return function (ary, predicate) {
257 | Iif (undefined === null) {
258 | throw new TypeError('find called on null or undefined');
259 | }
260 | Iif (typeof predicate !== 'function') {
261 | throw new TypeError('predicate must be a function');
262 | }
263 | var length = ary.length >>> 0;
264 | var ctx = _arguments[2];
265 | var value = void 0;
266 |
267 | for (var i = 0; i < length; i++) {
268 | value = ary[i];
269 | if (predicate.call(ctx, value, i, ary)) {
270 | return value;
271 | }
272 | }
273 | return undefined;
274 | };
275 | }();
276 |
277 | var deepCopy = function deepCopy(o) {
278 | return JSON.parse(JSON.stringify(o));
279 | };
280 |
281 | var getArrayLeafItemContains = function getArrayLeafItemContains(options, keyArr) {
282 | var position = void 0;
283 | var isFound = false;
284 | var selectedOptions = [];
285 | function recursion(opts) {
286 | var pos = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '0';
287 |
288 | opts.forEach(function (opt, index) {
289 | if (isFound) return;
290 | if (keyArr[0] + '_' === opt.value + '_') {
291 | position = pos + '-' + index;
292 | isFound = true;
293 | }
294 | if (opt.children) {
295 | recursion(opt.children, pos + '-' + index);
296 | }
297 | });
298 | }
299 | recursion(options);
300 | if (!position) return [];
301 | var parents = options;
302 | position.split('-').slice(1).forEach(function (pos) {
303 | selectedOptions.push(parents[pos]);
304 | parents = parents[pos].children;
305 | });
306 |
307 | return selectedOptions;
308 | };
309 |
310 | var getOptions = function getOptions(options) {
311 | var value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
312 | var level = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
313 |
314 | if (level === 0 && options) {
315 | return options;
316 | }
317 | if (value.length) {
318 | for (var i = 0, l = options.length; i < l; i++) {
319 | if (options[i].value + '_' === value[0] + '_') {
320 | return getOptions(options[i].children, value.slice(1), level - 1);
321 | }
322 | }
323 | }
324 | return [];
325 | };
326 |
327 | exports['default'] = {
328 | find: find,
329 | getArrayLeafItemContains: getArrayLeafItemContains,
330 | deepCopy: deepCopy,
331 | getOptions: getOptions
332 | };
333 | module.exports = exports['default'];
334 | |
| 1 47 | 2 48 | 3 49 | 4 50 | 5 51 | 6 52 | 7 53 | 8 54 | 9 55 | 10 56 | 11 57 | 12 58 | 13 59 | 14 60 | 15 61 | 16 62 | 17 63 | 18 64 | 19 65 | 20 66 | 21 67 | 22 68 | 23 69 | 24 70 | 25 71 | 26 72 | 27 73 | 28 74 | 29 75 | 30 76 | 31 77 | 32 78 | 33 79 | 34 80 | 35 81 | 36 82 | 37 83 | 38 84 | 39 85 | 40 86 | 41 87 | 42 88 | 43 89 | 44 90 | 45 91 | 46 92 | 47 93 | 48 94 | 49 95 | 50 96 | 51 97 | 52 98 | 53 99 | 54 100 | 55 101 | 56 102 | 57 103 | 58 104 | 59 105 | 60 106 | 61 107 | 62 108 | 63 109 | 64 110 | 65 111 | 66 112 | 67 113 | 68 114 | 69 115 | 70 116 | 71 117 | 72 118 | 73 119 | 74 120 | 75 121 | 76 122 | 77 123 | 78 124 | 79 125 | 80 126 | 81 127 | 82 128 | 83 129 | 84 130 | 85 131 | 86 132 | 87 133 | 88 134 | 89 135 | 90 136 | 91 137 | 92 138 | 93 139 | 94 140 | 95 | 141 | 142 | 1× 143 | 144 | 145 | 146 | 1× 147 | 148 | 1× 149 | 150 | 1× 151 | 152 | 1× 153 | 4× 154 | 155 | 156 | 157 | 158 | 159 | 160 | 4× 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 1× 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 1× 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 1× 233 | 1× 234 | | 'use strict';
235 |
236 | Object.defineProperty(exports, "__esModule", {
237 | value: true
238 | });
239 |
240 | var _react = require('react');
241 |
242 | var _react2 = _interopRequireDefault(_react);
243 |
244 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
245 |
246 | var Search = function Search(_ref) {
247 | var text = _ref.text,
248 | disabled = _ref.disabled,
249 | placeholder = _ref.placeholder,
250 | searchOption = _ref.searchOption,
251 | value = _ref.value,
252 | onValueChange = _ref.onValueChange,
253 | onSearchResultChange = _ref.onSearchResultChange;
254 | return _react2['default'].createElement('input', {
255 | type: 'text',
256 | placeholder: placeholder,
257 | style: { width: '100%', border: 'none', background: 'transparent' },
258 | disabled: disabled,
259 | value: value !== null ? value : text,
260 | onChange: function onChange(e) {
261 | var keywords = e.target.value;
262 | // 修复IE11下bug
263 | if (value === null && text === '' && keywords === '') {
264 | onValueChange(null);
265 | } else {
266 | onValueChange(keywords);
267 | }
268 | if (searchOption) {
269 | searchOption.doSearch(keywords, function (searchResult) {
270 | onSearchResultChange(searchResult);
271 | });
272 | }
273 | }
274 | });
275 | };
276 |
277 | Search.propTypes = {
278 | value: _react.PropTypes.string,
279 | text: _react.PropTypes.string,
280 | disabled: _react.PropTypes.bool,
281 | placeholder: _react.PropTypes.string,
282 | searchOption: _react.PropTypes.object,
283 | onSearchResultChange: _react.PropTypes.func,
284 | onValueChange: _react.PropTypes.func
285 | };
286 |
287 | Search.renderResult = function (result, onSelect) {
288 | return _react2['default'].createElement(
289 | 'div',
290 | {
291 | className: '',
292 | style: {
293 | background: '#fff',
294 | border: '1px solid #d9d9d9',
295 | boxShadow: '0 1px 4px 0 rgba(31,56,88,.15)',
296 | borderRadius: '3px',
297 | minWidth: '200px'
298 | }
299 | },
300 | _react2['default'].createElement(
301 | 'ul',
302 | { className: 'kuma-select2-dropdown-menu' },
303 | result.map(function (item) {
304 | return _react2['default'].createElement(
305 | 'li',
306 | {
307 | key: item.value,
308 | className: 'kuma-select2-dropdown-menu-item',
309 | onClick: function onClick() {
310 | return onSelect(item);
311 | },
312 | onMouseEnter: function onMouseEnter(e) {
313 | e.target.className += ' kuma-select2-dropdown-menu-item-active';
314 | },
315 | onMouseLeave: function onMouseLeave(e) {
316 | e.target.className = e.target.className.replace(' kuma-select2-dropdown-menu-item-active', '');
317 | }
318 | },
319 | item.label
320 | );
321 | })
322 | )
323 | );
324 | };
325 |
326 | exports['default'] = Search;
327 | module.exports = exports['default'];
328 | |