UNPKG

38 kBJavaScriptView Raw
1'use strict';
2
3exports.__esModule = true;
4
5var _objectWithoutProperties2 = require('babel-runtime/helpers/objectWithoutProperties');
6
7var _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2);
8
9var _typeof2 = require('babel-runtime/helpers/typeof');
10
11var _typeof3 = _interopRequireDefault(_typeof2);
12
13var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
14
15var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
16
17var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
18
19var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
20
21var _inherits2 = require('babel-runtime/helpers/inherits');
22
23var _inherits3 = _interopRequireDefault(_inherits2);
24
25var _extends2 = require('babel-runtime/helpers/extends');
26
27var _extends3 = _interopRequireDefault(_extends2);
28
29var _class, _temp;
30
31var _react = require('react');
32
33var _react2 = _interopRequireDefault(_react);
34
35var _reactLifecyclesCompat = require('react-lifecycles-compat');
36
37var _propTypes = require('prop-types');
38
39var _propTypes2 = _interopRequireDefault(_propTypes);
40
41var _classnames = require('classnames');
42
43var _classnames2 = _interopRequireDefault(_classnames);
44
45var _select = require('../select');
46
47var _select2 = _interopRequireDefault(_select);
48
49var _tree = require('../tree');
50
51var _tree2 = _interopRequireDefault(_tree);
52
53var _util = require('../tree/view/util');
54
55var _util2 = require('../util');
56
57var _zhCn = require('../locale/zh-cn');
58
59var _zhCn2 = _interopRequireDefault(_zhCn);
60
61var _util3 = require('../select/util');
62
63function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
64
65var noop = function noop() {};
66var TreeNode = _tree2.default.Node;
67var bindCtx = _util2.func.bindCtx;
68
69
70var flatDataSource = function flatDataSource(props) {
71 var _k2n = {};
72 var _p2n = {};
73 var _v2n = {};
74
75 if ('dataSource' in props) {
76 var loop = function loop(data) {
77 var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '0';
78 return data.map(function (item, index) {
79 var value = item.value,
80 children = item.children;
81
82 var pos = prefix + '-' + index;
83 var key = item.key || pos;
84
85 var newItem = (0, _extends3.default)({}, item, { key: key, pos: pos });
86 if (children && children.length) {
87 newItem.children = loop(children, pos);
88 }
89
90 _k2n[key] = _p2n[pos] = _v2n[value] = newItem;
91 return newItem;
92 });
93 };
94
95 loop(props.dataSource);
96 } else if ('children' in props) {
97 var _loop = function _loop(children) {
98 var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '0';
99 return _react.Children.map(children, function (node, index) {
100 if (!_react2.default.isValidElement(node)) {
101 return;
102 }
103
104 var _node$props = node.props,
105 value = _node$props.value,
106 children = _node$props.children;
107
108 var pos = prefix + '-' + index;
109 var key = node.key || pos;
110 var newItem = (0, _extends3.default)({}, node.props, { key: key, pos: pos });
111 if (children && _react.Children.count(children)) {
112 newItem.children = _loop(children, pos);
113 }
114
115 _k2n[key] = _p2n[pos] = _v2n[value] = newItem;
116 return newItem;
117 });
118 };
119 _loop(props.children);
120 }
121
122 return { _k2n: _k2n, _p2n: _p2n, _v2n: _v2n };
123};
124
125var isSearched = function isSearched(label, searchedValue) {
126 var labelString = '';
127
128 searchedValue = String(searchedValue);
129
130 var loop = function loop(arg) {
131 if ((0, _react.isValidElement)(arg) && arg.props.children) {
132 _react.Children.forEach(arg.props.children, loop);
133 } else {
134 labelString += arg;
135 }
136 };
137 loop(label);
138
139 if (labelString.length >= searchedValue.length && labelString.toLowerCase().indexOf(searchedValue.toLowerCase()) > -1) {
140 return true;
141 }
142
143 return false;
144};
145
146var getSearchKeys = function getSearchKeys(searchedValue, _k2n, _p2n) {
147 var searchedKeys = [];
148 var retainedKeys = [];
149 Object.keys(_k2n).forEach(function (k) {
150 var _k2n$k = _k2n[k],
151 label = _k2n$k.label,
152 pos = _k2n$k.pos;
153
154
155 if (isSearched(label, searchedValue)) {
156 searchedKeys.push(k);
157 var posArr = pos.split('-');
158 posArr.forEach(function (n, i) {
159 if (i > 0) {
160 var p = posArr.slice(0, i + 1).join('-');
161 var kk = _p2n[p].key;
162 if (retainedKeys.indexOf(kk) === -1) {
163 retainedKeys.push(kk);
164 }
165 }
166 });
167 }
168 });
169
170 return { searchedKeys: searchedKeys, retainedKeys: retainedKeys };
171};
172
173/**
174 * TreeSelect
175 */
176var TreeSelect = (_temp = _class = function (_Component) {
177 (0, _inherits3.default)(TreeSelect, _Component);
178
179 function TreeSelect(props, context) {
180 (0, _classCallCheck3.default)(this, TreeSelect);
181
182 var _this = (0, _possibleConstructorReturn3.default)(this, _Component.call(this, props, context));
183
184 var defaultVisible = props.defaultVisible,
185 visible = props.visible,
186 defaultValue = props.defaultValue,
187 value = props.value;
188
189
190 _this.state = (0, _extends3.default)({
191 visible: typeof visible === 'undefined' ? defaultVisible : visible,
192 value: (0, _util.normalizeToArray)(typeof value === 'undefined' ? defaultValue : value),
193 searchedValue: '',
194 expandedKeys: [],
195 searchedKeys: [],
196 retainedKeys: [],
197 autoExpandParent: false,
198 // map of value => item, includes value not exist in dataSource
199 mapValueDS: {}
200 }, flatDataSource(props));
201
202 // init value/mapValueDS when defaultValue is not undefined
203 if (_this.state.value !== undefined) {
204 _this.state.mapValueDS = (0, _util3.getValueDataSource)(_this.state.value, _this.state.mapValueDS).mapValueDS;
205 _this.state.value = _this.state.value.map(function (v) {
206 return (0, _util3.valueToSelectKey)(v);
207 });
208 }
209
210 bindCtx(_this, ['handleSelect', 'handleCheck', 'handleSearch', 'handleSearchClear', 'handleVisibleChange', 'handleChange', 'handleRemove', 'handleExpand', 'handleKeyDown', 'saveTreeRef', 'saveSelectRef', 'renderMaxTagPlaceholder']);
211 return _this;
212 }
213
214 TreeSelect.getDerivedStateFromProps = function getDerivedStateFromProps(props, state) {
215 var st = {};
216
217 if ('value' in props) {
218 var valueArray = (0, _util.normalizeToArray)(props.value);
219 // convert value to string[]
220 st.value = valueArray.map(function (v) {
221 return (0, _util3.valueToSelectKey)(v);
222 });
223 // re-calculate map
224 st.mapValueDS = (0, _util3.getValueDataSource)(props.value, state.mapValueDS).mapValueDS;
225 }
226 if ('visible' in props) {
227 st.visible = props.visible;
228 }
229
230 var _flatDataSource = flatDataSource(props),
231 _k2n = _flatDataSource._k2n,
232 _p2n = _flatDataSource._p2n,
233 _v2n = _flatDataSource._v2n;
234
235 if (props.showSearch && state.searchedValue) {
236 var _getSearchKeys = getSearchKeys(state.searchedValue, _k2n, _p2n),
237 searchedKeys = _getSearchKeys.searchedKeys,
238 retainedKeys = _getSearchKeys.retainedKeys;
239
240 st.searchedKeys = searchedKeys;
241 st.retainedKeys = retainedKeys;
242 }
243
244 return (0, _extends3.default)({}, st, {
245 _k2n: _k2n,
246 _p2n: _p2n,
247 _v2n: _v2n
248 });
249 };
250
251 TreeSelect.prototype.getKeysByValue = function getKeysByValue(value) {
252 var _this2 = this;
253
254 return value.reduce(function (ret, v) {
255 var k = _this2.state._v2n[v] && _this2.state._v2n[v].key;
256 if (k) {
257 ret.push(k);
258 }
259 return ret;
260 }, []);
261 };
262
263 TreeSelect.prototype.getValueByKeys = function getValueByKeys(keys) {
264 var _this3 = this;
265
266 return keys.map(function (k) {
267 return _this3.state._k2n[k].value;
268 });
269 };
270
271 TreeSelect.prototype.getValueForSelect = function getValueForSelect(value) {
272 var treeCheckedStrategy = this.props.treeCheckedStrategy;
273
274 var nonExistentValueKeys = this.getNonExistentValueKeys();
275
276 var keys = this.getKeysByValue(value);
277 keys = (0, _util.getAllCheckedKeys)(keys, this.state._k2n, this.state._p2n);
278
279 switch (treeCheckedStrategy) {
280 case 'parent':
281 keys = (0, _util.filterChildKey)(keys, this.state._k2n, this.state._p2n);
282 break;
283 case 'child':
284 keys = (0, _util.filterParentKey)(keys, this.state._k2n, this.state._p2n);
285 break;
286 default:
287 break;
288 }
289
290 var values = this.getValueByKeys(keys);
291
292 return [].concat(values, nonExistentValueKeys);
293 };
294
295 TreeSelect.prototype.getData = function getData(value, forSelect) {
296 var _this4 = this;
297
298 var preserveNonExistentValue = this.props.preserveNonExistentValue;
299 var mapValueDS = this.state.mapValueDS;
300
301
302 var ret = value.reduce(function (ret, v) {
303 var k = _this4.state._v2n[v] && _this4.state._v2n[v].key;
304 if (k) {
305 var _state$_k2n$k = _this4.state._k2n[k],
306 label = _state$_k2n$k.label,
307 pos = _state$_k2n$k.pos,
308 disabled = _state$_k2n$k.disabled,
309 checkboxDisabled = _state$_k2n$k.checkboxDisabled;
310
311 var d = {
312 value: v,
313 label: label,
314 pos: pos
315 };
316 if (forSelect) {
317 d.disabled = disabled || checkboxDisabled;
318 } else {
319 d.key = k;
320 }
321 ret.push(d);
322 } else if (preserveNonExistentValue) {
323 // 需要保留 dataSource 中不存在的 value
324 var item = mapValueDS[v];
325 if (item) {
326 ret.push(item);
327 }
328 }
329 return ret;
330 }, []);
331
332 return ret;
333 };
334
335 TreeSelect.prototype.getNonExistentValues = function getNonExistentValues() {
336 var _this5 = this;
337
338 var preserveNonExistentValue = this.props.preserveNonExistentValue;
339 var value = this.state.value;
340
341
342 if (!preserveNonExistentValue) {
343 return [];
344 }
345 var nonExistentValues = value.filter(function (v) {
346 return !_this5.state._v2n[v];
347 });
348 return nonExistentValues;
349 };
350
351 TreeSelect.prototype.getNonExistentValueKeys = function getNonExistentValueKeys() {
352 var nonExistentValues = this.getNonExistentValues();
353 return nonExistentValues.map(function (v) {
354 if ((typeof v === 'undefined' ? 'undefined' : (0, _typeof3.default)(v)) === 'object' && v.hasOwnProperty('value')) {
355 return v.value;
356 }
357 return v;
358 });
359 };
360
361 TreeSelect.prototype.saveTreeRef = function saveTreeRef(ref) {
362 this.tree = ref;
363 };
364
365 TreeSelect.prototype.saveSelectRef = function saveSelectRef(ref) {
366 this.select = ref;
367 };
368
369 TreeSelect.prototype.handleVisibleChange = function handleVisibleChange(visible, type) {
370 if (!('visible' in this.props)) {
371 this.setState({
372 visible: visible
373 });
374 }
375
376 if (['fromTree', 'keyboard'].indexOf(type) !== -1 && !visible) {
377 this.select.focusInput();
378 }
379
380 this.props.onVisibleChange(visible, type);
381 };
382
383 TreeSelect.prototype.handleSelect = function handleSelect(selectedKeys, extra) {
384 var _props = this.props,
385 multiple = _props.multiple,
386 onChange = _props.onChange;
387 var selected = extra.selected;
388
389
390 if (multiple || selected) {
391 var value = this.getValueByKeys(selectedKeys);
392 var nonExistentValues = this.getNonExistentValues();
393 value = [].concat(nonExistentValues, value);
394
395 if (!('value' in this.props)) {
396 this.setState({
397 value: value
398 });
399 }
400 if (!multiple) {
401 this.handleVisibleChange(false, 'fromTree');
402 }
403
404 var data = this.getData(value);
405 multiple ? onChange(value, data) : onChange(value[0], data[0]);
406
407 // clear search value manually
408 this.select.handleSearchClear('select');
409 } else {
410 this.handleVisibleChange(false, 'fromTree');
411 }
412 };
413
414 TreeSelect.prototype.handleCheck = function handleCheck(checkedKeys) {
415 var onChange = this.props.onChange;
416
417
418 var value = this.getValueByKeys(checkedKeys);
419 var nonExistentValues = this.getNonExistentValues();
420 value = [].concat(nonExistentValues, value);
421
422 if (!('value' in this.props)) {
423 this.setState({
424 value: value
425 });
426 }
427
428 onChange(value, this.getData(value));
429
430 // clear search value manually
431 this.select.handleSearchClear('select');
432 };
433
434 TreeSelect.prototype.handleRemove = function handleRemove(removedItem) {
435 var _this6 = this;
436
437 var removedValue = removedItem.value;
438 var _props2 = this.props,
439 treeCheckable = _props2.treeCheckable,
440 treeCheckStrictly = _props2.treeCheckStrictly,
441 treeCheckedStrategy = _props2.treeCheckedStrategy,
442 onChange = _props2.onChange;
443
444
445 var value = void 0;
446 if (
447 // there's linkage relationship among nodes
448 treeCheckable && !treeCheckStrictly && ['parent', 'all'].indexOf(treeCheckedStrategy) !== -1 &&
449 // value exits in datasource
450 this.state._v2n[removedValue]) {
451 var removedPos = this.state._v2n[removedValue].pos;
452 value = this.state.value.filter(function (v) {
453 var p = _this6.state._v2n[v].pos;
454 return !(0, _util.isDescendantOrSelf)(removedPos, p);
455 });
456
457 var nums = removedPos.split('-');
458 for (var i = nums.length; i > 2; i--) {
459 var parentPos = nums.slice(0, i - 1).join('-');
460 var parentValue = this.state._p2n[parentPos].value;
461 var parentIndex = value.indexOf(parentValue);
462 if (parentIndex > -1) {
463 value.splice(parentIndex, 1);
464 } else {
465 break;
466 }
467 }
468 } else {
469 value = this.state.value.filter(function (v) {
470 return v !== removedValue;
471 });
472 }
473
474 if (!('value' in this.props)) {
475 this.setState({
476 value: value
477 });
478 }
479
480 var data = this.getData(value);
481 onChange(value, data);
482 };
483
484 TreeSelect.prototype.handleSearch = function handleSearch(searchedValue) {
485 var _state = this.state,
486 _k2n = _state._k2n,
487 _p2n = _state._p2n;
488
489 var _getSearchKeys2 = getSearchKeys(searchedValue, _k2n, _p2n),
490 searchedKeys = _getSearchKeys2.searchedKeys,
491 retainedKeys = _getSearchKeys2.retainedKeys;
492
493 this.setState({
494 searchedValue: searchedValue,
495 expandedKeys: searchedKeys,
496 searchedKeys: searchedKeys,
497 retainedKeys: retainedKeys,
498 autoExpandParent: true
499 });
500
501 this.props.onSearch(searchedValue);
502 };
503
504 TreeSelect.prototype.handleSearchClear = function handleSearchClear(triggerType) {
505 this.setState({
506 searchedValue: '',
507 expandedKeys: []
508 });
509 this.props.onSearchClear(triggerType);
510 };
511
512 TreeSelect.prototype.handleExpand = function handleExpand(expandedKeys) {
513 this.setState({
514 expandedKeys: expandedKeys,
515 autoExpandParent: false
516 });
517 };
518
519 TreeSelect.prototype.handleKeyDown = function handleKeyDown(e) {
520 var onKeyDown = this.props.onKeyDown;
521 var visible = this.state.visible;
522
523
524 if (onKeyDown) {
525 onKeyDown(e);
526 }
527
528 if (!visible) {
529 return;
530 }
531
532 switch (e.keyCode) {
533 case _util2.KEYCODE.UP:
534 case _util2.KEYCODE.DOWN:
535 this.tree.setFocusKey();
536 e.preventDefault();
537 break;
538 default:
539 break;
540 }
541 };
542
543 TreeSelect.prototype.handleChange = function handleChange(value, triggerType) {
544 if (this.props.hasClear && triggerType === 'clear') {
545 if (!('value' in this.props)) {
546 this.setState({
547 value: []
548 });
549 }
550
551 this.props.onChange(null, null);
552 }
553 };
554
555 TreeSelect.prototype.searchNodes = function searchNodes(children) {
556 var _state2 = this.state,
557 searchedKeys = _state2.searchedKeys,
558 retainedKeys = _state2.retainedKeys;
559
560
561 var loop = function loop(children) {
562 var retainedNodes = [];
563 _react.Children.forEach(children, function (child) {
564 if (searchedKeys.indexOf(child.key) > -1) {
565 retainedNodes.push(child);
566 } else if (retainedKeys.indexOf(child.key) > -1) {
567 var retainedNode = child.props.children ? (0, _react.cloneElement)(child, {}, loop(child.props.children)) : child;
568 retainedNodes.push(retainedNode);
569 } else {
570 var hideNode = (0, _react.cloneElement)(child, {
571 style: { display: 'none' }
572 });
573 retainedNodes.push(hideNode);
574 }
575 });
576 return retainedNodes;
577 };
578
579 return loop(children);
580 };
581
582 TreeSelect.prototype.createNodesByData = function createNodesByData(data, searching) {
583 var _this7 = this;
584
585 var _state3 = this.state,
586 searchedKeys = _state3.searchedKeys,
587 retainedKeys = _state3.retainedKeys;
588
589
590 var loop = function loop(data, isParentMatched) {
591 var prefix = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '0';
592
593 var retainedNodes = [];
594
595 data.forEach(function (item, index) {
596 var children = item.children,
597 others = (0, _objectWithoutProperties3.default)(item, ['children']);
598
599 var pos = prefix + '-' + index;
600 var key = _this7.state._p2n[pos].key;
601 var addNode = function addNode(isParentMatched, hide) {
602 if (hide) {
603 others.style = { display: 'none' };
604 }
605
606 retainedNodes.push(_react2.default.createElement(
607 TreeNode,
608 (0, _extends3.default)({}, others, { key: key }),
609 children && children.length ? loop(children, isParentMatched, pos) : null
610 ));
611 };
612
613 if (searching) {
614 if (searchedKeys.indexOf(key) > -1 || isParentMatched) {
615 addNode(true);
616 } else if (retainedKeys.indexOf(key) > -1) {
617 addNode(false);
618 } else {
619 addNode(false, true);
620 }
621 } else {
622 addNode();
623 }
624 });
625
626 return retainedNodes;
627 };
628
629 return loop(data, false);
630 };
631
632 /*eslint-disable max-statements*/
633
634
635 TreeSelect.prototype.renderPopupContent = function renderPopupContent() {
636 var prefix = this.props.prefix;
637 var treeSelectPrefix = prefix + 'tree-select-';
638
639 if (!this.state.visible) {
640 return _react2.default.createElement('div', { className: treeSelectPrefix + 'dropdown' });
641 }
642
643 var _props3 = this.props,
644 multiple = _props3.multiple,
645 treeCheckable = _props3.treeCheckable,
646 treeCheckStrictly = _props3.treeCheckStrictly,
647 treeCheckedStrategy = _props3.treeCheckedStrategy,
648 treeDefaultExpandAll = _props3.treeDefaultExpandAll,
649 treeDefaultExpandedKeys = _props3.treeDefaultExpandedKeys,
650 treeLoadData = _props3.treeLoadData,
651 _props3$treeProps = _props3.treeProps,
652 customTreeProps = _props3$treeProps === undefined ? {} : _props3$treeProps,
653 showSearch = _props3.showSearch,
654 dataSource = _props3.dataSource,
655 children = _props3.children,
656 readOnly = _props3.readOnly,
657 notFoundContent = _props3.notFoundContent,
658 useVirtual = _props3.useVirtual;
659 var _state4 = this.state,
660 value = _state4.value,
661 searchedValue = _state4.searchedValue,
662 expandedKeys = _state4.expandedKeys,
663 autoExpandParent = _state4.autoExpandParent,
664 searchedKeys = _state4.searchedKeys;
665
666
667 var treeProps = {
668 multiple: multiple,
669 ref: this.saveTreeRef,
670 loadData: treeLoadData,
671 defaultExpandAll: treeDefaultExpandAll,
672 defaultExpandedKeys: treeDefaultExpandedKeys,
673 useVirtual: useVirtual
674 };
675
676 // 使用虚拟滚动 设置默认高度
677 if (useVirtual) {
678 customTreeProps.style = (0, _extends3.default)({
679 maxHeight: '260px',
680 overflow: 'auto',
681 boxSizing: 'border-box'
682 }, customTreeProps.style);
683 }
684
685 var keys = this.getKeysByValue(value);
686 if (treeCheckable) {
687 treeProps.checkable = treeCheckable;
688 treeProps.checkStrictly = treeCheckStrictly;
689 treeProps.checkedStrategy = treeCheckStrictly ? 'all' : treeCheckedStrategy;
690 treeProps.checkedKeys = keys;
691 if (!readOnly) {
692 treeProps.onCheck = this.handleCheck;
693 }
694 } else {
695 treeProps.selectedKeys = keys;
696 if (!readOnly) {
697 treeProps.onSelect = this.handleSelect;
698 }
699 }
700
701 var notFound = false;
702 var newChildren = void 0;
703 if (showSearch && searchedValue) {
704 treeProps.expandedKeys = expandedKeys;
705 treeProps.autoExpandParent = autoExpandParent;
706 treeProps.onExpand = this.handleExpand;
707 treeProps.filterTreeNode = function (node) {
708 return searchedKeys.indexOf(node.props.eventKey) > -1;
709 };
710
711 if (searchedKeys.length) {
712 newChildren = dataSource ? this.createNodesByData(dataSource, true) : this.searchNodes(children);
713 } else {
714 notFound = true;
715 }
716 } else {
717 // eslint-disable-next-line
718 if (dataSource) {
719 if (dataSource.length) {
720 newChildren = this.createNodesByData(dataSource);
721 } else {
722 notFound = true;
723 }
724 } else {
725 // eslint-disable-next-line
726 if (_react.Children.count(children)) {
727 newChildren = children;
728 } else {
729 notFound = true;
730 }
731 }
732 }
733 var contentClass = treeSelectPrefix + 'dropdown-content';
734
735 return _react2.default.createElement(
736 'div',
737 { className: treeSelectPrefix + 'dropdown' },
738 notFound ? _react2.default.createElement(
739 'div',
740 { className: treeSelectPrefix + 'not-found contentClass' },
741 notFoundContent
742 ) : _react2.default.createElement(
743 _tree2.default,
744 (0, _extends3.default)({}, treeProps, customTreeProps, { className: contentClass }),
745 newChildren
746 )
747 );
748 };
749
750 TreeSelect.prototype.renderPreview = function renderPreview(data, others) {
751 var _props4 = this.props,
752 prefix = _props4.prefix,
753 className = _props4.className,
754 renderPreview = _props4.renderPreview;
755
756
757 var previewCls = (0, _classnames2.default)(className, prefix + 'form-preview');
758 var items = data && !Array.isArray(data) ? [data] : data;
759
760 if (typeof renderPreview === 'function') {
761 return _react2.default.createElement(
762 'div',
763 (0, _extends3.default)({}, others, { className: previewCls }),
764 renderPreview(items, this.props)
765 );
766 }
767
768 return _react2.default.createElement(
769 'p',
770 (0, _extends3.default)({}, others, { className: previewCls }),
771 items && items.map(function (_ref) {
772 var label = _ref.label;
773 return label;
774 }).join(', ')
775 );
776 };
777
778 /**
779 * TreeSelect 无法直接使用 Select 的 maxTagPlaceholder 逻辑
780 * Select 的 totalValue 是所有 leaf 节点,TreeSelect 的 totalValue 受 treeCheckedStrategy 和 treeCheckStrictly 影响
781 *
782 * treeCheckStrictly = true: totalValue 为所有节点
783 *
784 * treeCheckStrictly = false: 根据 treeCheckedStrategy 判断
785 * treeCheckedStrategy = 'all': totalValue 为所有节点
786 * treeCheckedStrategy = 'parent': totalValue 无意义,不返回
787 * treeCheckedStrategy = 'child': totalValue 为所有 leaf 节点
788 */
789
790
791 TreeSelect.prototype.renderMaxTagPlaceholder = function renderMaxTagPlaceholder(value, totalValue) {
792 // 这里的 totalValue 为所有 leaf 节点
793 var _props5 = this.props,
794 treeCheckStrictly = _props5.treeCheckStrictly,
795 maxTagPlaceholder = _props5.maxTagPlaceholder,
796 treeCheckedStrategy = _props5.treeCheckedStrategy,
797 locale = _props5.locale;
798 var _v2n = this.state._v2n;
799
800
801 var treeSelectTotalValue = totalValue; // all the leaf nodes
802
803 // calculate total value
804 if (treeCheckStrictly) {
805 // all the nodes
806 treeSelectTotalValue = _util2.obj.values(_v2n);
807 } else if (treeCheckedStrategy === 'all') {
808 // all
809 treeSelectTotalValue = _util2.obj.values(_v2n);
810 } else if (treeCheckedStrategy === 'parent') {
811 // totalValue is pointless when treeCheckedStrategy = 'parent'
812 treeSelectTotalValue = undefined;
813 }
814
815 // custom render function
816 if (maxTagPlaceholder) {
817 return maxTagPlaceholder(value, treeSelectTotalValue);
818 }
819
820 // default render function
821 if (treeCheckedStrategy === 'parent') {
822 // don't show totalValue when treeCheckedStrategy = 'parent'
823 return '' + _util2.str.template(locale.shortMaxTagPlaceholder, {
824 selected: value.length
825 });
826 }
827 return '' + _util2.str.template(locale.maxTagPlaceholder, {
828 selected: value.length,
829 total: treeSelectTotalValue.length
830 });
831 };
832
833 /*eslint-enable*/
834
835
836 TreeSelect.prototype.render = function render() {
837 var _props6 = this.props,
838 prefix = _props6.prefix,
839 size = _props6.size,
840 placeholder = _props6.placeholder,
841 disabled = _props6.disabled,
842 hasArrow = _props6.hasArrow,
843 hasBorder = _props6.hasBorder,
844 hasClear = _props6.hasClear,
845 label = _props6.label,
846 readOnly = _props6.readOnly,
847 autoWidth = _props6.autoWidth,
848 popupStyle = _props6.popupStyle,
849 popupClassName = _props6.popupClassName,
850 showSearch = _props6.showSearch,
851 multiple = _props6.multiple,
852 treeCheckable = _props6.treeCheckable,
853 treeCheckStrictly = _props6.treeCheckStrictly,
854 className = _props6.className,
855 popupContainer = _props6.popupContainer,
856 popupProps = _props6.popupProps,
857 followTrigger = _props6.followTrigger,
858 isPreview = _props6.isPreview,
859 dataSource = _props6.dataSource,
860 tagInline = _props6.tagInline;
861
862 var others = _util2.obj.pickOthers(Object.keys(TreeSelect.propTypes), this.props);
863 var _state5 = this.state,
864 value = _state5.value,
865 visible = _state5.visible;
866
867 // if (non-leaf 节点可选 & 父子节点选中状态需要联动),需要额外计算父子节点间的联动关系
868
869 var valueForSelect = treeCheckable && !treeCheckStrictly ? this.getValueForSelect(value) : value;
870
871 var data = this.getData(valueForSelect, true);
872 if (!multiple && !treeCheckable) {
873 data = data[0];
874 }
875
876 if (isPreview) {
877 return this.renderPreview(data, others);
878 }
879
880 return _react2.default.createElement(_select2.default, (0, _extends3.default)({
881 prefix: prefix,
882 className: className,
883 size: size,
884 hasBorder: hasBorder,
885 hasArrow: hasArrow,
886 hasClear: hasClear,
887 placeholder: placeholder,
888 disabled: disabled,
889 autoWidth: autoWidth,
890 label: label,
891 readOnly: readOnly,
892 ref: this.saveSelectRef,
893 dataSource: dataSource,
894 value: data,
895 onChange: this.handleChange,
896 visible: visible,
897 onVisibleChange: this.handleVisibleChange,
898 showSearch: showSearch,
899 onSearch: this.handleSearch,
900 onSearchClear: this.handleSearchClear,
901 popupContainer: popupContainer,
902 popupStyle: popupStyle,
903 popupClassName: popupClassName,
904 popupProps: popupProps,
905 followTrigger: followTrigger,
906 tagInline: tagInline,
907 maxTagPlaceholder: this.renderMaxTagPlaceholder
908 }, others, {
909 onRemove: this.handleRemove,
910 onKeyDown: this.handleKeyDown,
911 popupContent: this.renderPopupContent(),
912 mode: treeCheckable || multiple ? 'multiple' : 'single'
913 }));
914 };
915
916 return TreeSelect;
917}(_react.Component), _class.propTypes = {
918 prefix: _propTypes2.default.string,
919 pure: _propTypes2.default.bool,
920 locale: _propTypes2.default.object,
921 className: _propTypes2.default.string,
922 /**
923 * 树节点
924 */
925 children: _propTypes2.default.node,
926 /**
927 * 选择框大小
928 */
929 size: _propTypes2.default.oneOf(['small', 'medium', 'large']),
930 /**
931 * 选择框占位符
932 */
933 placeholder: _propTypes2.default.string,
934 /**
935 * 是否禁用
936 */
937 disabled: _propTypes2.default.bool,
938 /**
939 * 是否有下拉箭头
940 */
941 hasArrow: _propTypes2.default.bool,
942 /**
943 * 是否有边框
944 */
945 hasBorder: _propTypes2.default.bool,
946 /**
947 * 是否有清空按钮
948 */
949 hasClear: _propTypes2.default.bool,
950 /**
951 * 自定义内联 label
952 */
953 label: _propTypes2.default.node,
954 /**
955 * 是否只读,只读模式下可以展开弹层但不能选择
956 */
957 readOnly: _propTypes2.default.bool,
958 /**
959 * 下拉框是否与选择器对齐
960 */
961 autoWidth: _propTypes2.default.bool,
962 /**
963 * 数据源,该属性优先级高于 children
964 */
965 dataSource: _propTypes2.default.arrayOf(_propTypes2.default.object),
966 /**
967 * value/defaultValue 在 dataSource 中不存在时,是否展示
968 * @version 1.25
969 */
970 preserveNonExistentValue: _propTypes2.default.bool,
971 /**
972 * (受控)当前值
973 */
974 value: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.object, _propTypes2.default.arrayOf(_propTypes2.default.any)]),
975 /**
976 * (非受控)默认值
977 */
978 defaultValue: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.object, _propTypes2.default.arrayOf(_propTypes2.default.any)]),
979 /**
980 * 选中值改变时触发的回调函数
981 * @param {String|Array} value 选中的值,单选时返回单个值,多选时返回数组
982 * @param {Object|Array} data 选中的数据,包括 value, label, pos, key属性,单选时返回单个值,多选时返回数组,父子节点选中关联时,同时选中,只返回父节点
983 */
984 onChange: _propTypes2.default.func,
985 /**
986 * 是否一行显示,仅在 multiple 和 treeCheckable 为 true 时生效
987 * @version 1.25
988 */
989 tagInline: _propTypes2.default.bool,
990 /**
991 * 隐藏多余 tag 时显示的内容,在 tagInline 生效时起作用
992 * @param {Object[]} selectedValues 当前已选中的元素
993 * @param {Object[]} totalValues 总待选元素
994 * @returns {reactNode}
995 * @version 1.25
996 */
997 maxTagPlaceholder: _propTypes2.default.func,
998 /**
999 * 是否显示搜索框
1000 */
1001 showSearch: _propTypes2.default.bool,
1002 /**
1003 * 在搜索框中输入时触发的回调函数
1004 * @param {String} keyword 输入的关键字
1005 */
1006 onSearch: _propTypes2.default.func,
1007 onSearchClear: _propTypes2.default.func,
1008 /**
1009 * 无数据时显示内容
1010 */
1011 notFoundContent: _propTypes2.default.node,
1012 /**
1013 * 是否支持多选
1014 */
1015 multiple: _propTypes2.default.bool,
1016 /**
1017 * 下拉框中的树是否支持勾选节点的复选框
1018 */
1019 treeCheckable: _propTypes2.default.bool,
1020 /**
1021 * 下拉框中的树勾选节点复选框是否完全受控(父子节点选中状态不再关联)
1022 */
1023 treeCheckStrictly: _propTypes2.default.bool,
1024 /**
1025 * 定义选中时回填的方式
1026 * @enumdesc 返回所有选中的节点, 父子节点都选中时只返回父节点, 父子节点都选中时只返回子节点
1027 */
1028 treeCheckedStrategy: _propTypes2.default.oneOf(['all', 'parent', 'child']),
1029 /**
1030 * 下拉框中的树是否默认展开所有节点
1031 */
1032 treeDefaultExpandAll: _propTypes2.default.bool,
1033 /**
1034 * 下拉框中的树默认展开节点key的数组
1035 */
1036 treeDefaultExpandedKeys: _propTypes2.default.arrayOf(_propTypes2.default.string),
1037 /**
1038 * 下拉框中的树异步加载数据的函数,使用请参考[Tree的异步加载数据Demo](https://fusion.design/pc/component/basic/tree#%E5%BC%82%E6%AD%A5%E5%8A%A0%E8%BD%BD%E6%95%B0%E6%8D%AE)
1039 * @param {ReactElement} node 被点击展开的节点
1040 */
1041 treeLoadData: _propTypes2.default.func,
1042 /**
1043 * 透传到 Tree 的属性对象
1044 */
1045 treeProps: _propTypes2.default.object,
1046 /**
1047 * 初始下拉框是否显示
1048 */
1049 defaultVisible: _propTypes2.default.bool,
1050 /**
1051 * 当前下拉框是否显示
1052 */
1053 visible: _propTypes2.default.bool,
1054 /**
1055 * 下拉框显示或关闭时触发事件的回调函数
1056 * @param {Boolean} visible 是否显示
1057 * @param {String} type 触发显示关闭的操作类型
1058 */
1059 onVisibleChange: _propTypes2.default.func,
1060 /**
1061 * 下拉框自定义样式对象
1062 */
1063 popupStyle: _propTypes2.default.object,
1064 /**
1065 * 下拉框样式自定义类名
1066 */
1067 popupClassName: _propTypes2.default.string,
1068 /**
1069 * 下拉框挂载的容器节点
1070 */
1071 popupContainer: _propTypes2.default.any,
1072 /**
1073 * 透传到 Popup 的属性对象
1074 */
1075 popupProps: _propTypes2.default.object,
1076 /**
1077 * 是否跟随滚动
1078 */
1079 followTrigger: _propTypes2.default.bool,
1080 /**
1081 * 是否为预览态
1082 */
1083 isPreview: _propTypes2.default.bool,
1084 /**
1085 * 预览态模式下渲染的内容
1086 * @param {Array<data>} value 选择值 { label: , value:}
1087 */
1088 renderPreview: _propTypes2.default.func,
1089 /**
1090 * 是否开启虚拟滚动
1091 */
1092 useVirtual: _propTypes2.default.bool,
1093 /**
1094 * 是否是不可变数据
1095 * @version 1.23
1096 */
1097 immutable: _propTypes2.default.bool
1098}, _class.defaultProps = {
1099 prefix: 'next-',
1100 pure: false,
1101 locale: _zhCn2.default.TreeSelect,
1102 size: 'medium',
1103 disabled: false,
1104 hasArrow: true,
1105 hasBorder: true,
1106 hasClear: false,
1107 autoWidth: true,
1108 defaultValue: null,
1109 onChange: noop,
1110 tagInline: false,
1111 showSearch: false,
1112 onSearch: noop,
1113 onSearchClear: noop,
1114 notFoundContent: 'Not Found',
1115 multiple: false,
1116 treeCheckable: false,
1117 treeCheckStrictly: false,
1118 treeCheckedStrategy: 'parent',
1119 treeDefaultExpandAll: false,
1120 treeDefaultExpandedKeys: [],
1121 treeProps: {},
1122 defaultVisible: false,
1123 onVisibleChange: noop,
1124 useVirtual: false,
1125 /**
1126 * TODO
1127 * 目前 select/cascade select 是默认支持的,在 2.x 版本中 tree-select 也将默认支持
1128 */
1129 preserveNonExistentValue: false
1130}, _temp);
1131TreeSelect.displayName = 'TreeSelect';
1132
1133
1134TreeSelect.Node = TreeNode;
1135
1136exports.default = (0, _reactLifecyclesCompat.polyfill)(TreeSelect);
1137module.exports = exports['default'];
\No newline at end of file