1 | import _extends from "@babel/runtime/helpers/extends";
|
2 | import "core-js/modules/es7.array.includes";
|
3 | import "core-js/modules/es6.string.includes";
|
4 | import "core-js/modules/es6.regexp.split";
|
5 | import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
6 | import React, { useCallback, useMemo, useState, useEffect, useRef } from 'react';
|
7 | import Layer from '@beisen-phoenix/unmodeled-layer';
|
8 | import Select from '@beisen-phoenix/select/';
|
9 | import SingleSelect from '@beisen-phoenix/single-select-list';
|
10 | import GroupSingleSelect from '@beisen-phoenix/group-single-select';
|
11 | import MultipleSelect from '@beisen-phoenix/multi-select-list';
|
12 | import FormControlPreview from '@beisen-phoenix/form-control-preview';
|
13 | import { getFilterdOptions, getDisplayLabel } from './utils';
|
14 | import './index.css';
|
15 | import utils from '@beisen-phoenix/common-utils';
|
16 | var classes = utils.BEMClass('fieldDropdown');
|
17 |
|
18 | var onChange = function onChange(data) {};
|
19 |
|
20 | var FieldDropdown = function FieldDropdown(props) {
|
21 | var _props$optionSearch = props.optionSearch,
|
22 | optionSearch = _props$optionSearch === void 0 ? false : _props$optionSearch,
|
23 | _props$showCheckAll = props.showCheckAll,
|
24 | showCheckAll = _props$showCheckAll === void 0 ? true : _props$showCheckAll,
|
25 | _props$hasError = props.hasError,
|
26 | hasError = _props$hasError === void 0 ? false : _props$hasError,
|
27 | _props$isPreview = props.isPreview,
|
28 | isPreview = _props$isPreview === void 0 ? false : _props$isPreview,
|
29 | _props$selectType = props.selectType,
|
30 | selectType = _props$selectType === void 0 ? 'single' : _props$selectType,
|
31 | _props$disabled = props.disabled,
|
32 | disabled = _props$disabled === void 0 ? false : _props$disabled,
|
33 | layerWidth = props.layerWidth,
|
34 | onBlur = props.onBlur,
|
35 | _props$selectIsActive = props.selectIsActive,
|
36 | selectIsActive = _props$selectIsActive === void 0 ? false : _props$selectIsActive,
|
37 | _props$autoFocus = props.autoFocus,
|
38 | autoFocus = _props$autoFocus === void 0 ? false : _props$autoFocus,
|
39 | _props$hostSubmit = props.hostSubmit,
|
40 | hostSubmit = _props$hostSubmit === void 0 ? false : _props$hostSubmit,
|
41 | caseSensitive = props.caseSensitive,
|
42 | optionSearchAutoFocus = props.optionSearchAutoFocus,
|
43 | _props$splitKey = props.splitKey,
|
44 | splitKey = _props$splitKey === void 0 ? ',' : _props$splitKey;
|
45 | var isSearch = disabled ? false : 'isSearch' in props ? props.isSearch : true;
|
46 |
|
47 | var _useState = useState(autoFocus),
|
48 | _useState2 = _slicedToArray(_useState, 2),
|
49 | visible = _useState2[0],
|
50 | setVisible = _useState2[1];
|
51 |
|
52 | var _useState3 = useState(autoFocus),
|
53 | _useState4 = _slicedToArray(_useState3, 2),
|
54 | selectFocus = _useState4[0],
|
55 | setSelectFocus = _useState4[1];
|
56 |
|
57 | var layerWrapperRef = useRef();
|
58 | var isWrapperInRef = useRef(false);
|
59 |
|
60 | var inputRef = useRef();
|
61 | var isBlurRef = useRef(false);
|
62 | var isSelectClickRef = useRef(false);
|
63 |
|
64 |
|
65 |
|
66 | var _useState5 = useState(props.value || ''),
|
67 | _useState6 = _slicedToArray(_useState5, 2),
|
68 | selectedValue = _useState6[0],
|
69 | setSelectedValue = _useState6[1];
|
70 |
|
71 |
|
72 | var _useState7 = useState(props.value || ''),
|
73 | _useState8 = _slicedToArray(_useState7, 2),
|
74 | selectedValueForMultiSelect = _useState8[0],
|
75 | setSelectedValueForMultiSelect = _useState8[1];
|
76 |
|
77 |
|
78 | var _useState9 = useState(),
|
79 | _useState10 = _slicedToArray(_useState9, 2),
|
80 | searchWord = _useState10[0],
|
81 | setSearchWord = _useState10[1];
|
82 |
|
83 | useEffect(function () {
|
84 | setSelectedValue(props.value || '');
|
85 | }, [props.value]);
|
86 | useEffect(function () {
|
87 | setSelectedValueForMultiSelect(props.value || '');
|
88 | }, [props.value]);
|
89 |
|
90 | var toggleLayer = useCallback(function (visible) {
|
91 | if (disabled) return;
|
92 |
|
93 | if (visible) setSearchWord('');
|
94 |
|
95 | visible && setSelectedValue(selectedValue);
|
96 |
|
97 | if (visible && selectType === 'multiple') {
|
98 |
|
99 | var selectLength = selectedValue && selectedValue.split(splitKey).length;
|
100 | var tmpLength = selectedValueForMultiSelect && selectedValueForMultiSelect.split(splitKey).length;
|
101 |
|
102 | if (tmpLength !== selectLength) {
|
103 | setSelectedValueForMultiSelect(selectedValue);
|
104 | }
|
105 | }
|
106 |
|
107 | if (isSelectClickRef.current) {
|
108 | setVisible(true);
|
109 | isSelectClickRef.current = false;
|
110 | } else {
|
111 | setVisible(visible);
|
112 | }
|
113 |
|
114 | if (visible) setSelectFocus(true);
|
115 | }, [selectedValue, selectedValueForMultiSelect, disabled]);
|
116 |
|
117 | var onDelete = useCallback(function (data) {
|
118 | if (data) {
|
119 | var val = data.map(function (item) {
|
120 | return item.value;
|
121 | }).join(splitKey);
|
122 | setSelectedValue(val);
|
123 | setSelectedValueForMultiSelect(val);
|
124 | props.onChange && props.onChange(val);
|
125 | } else {
|
126 |
|
127 | setSearchWord('');
|
128 |
|
129 | if (selectType !== 'multiple') {
|
130 | setSelectedValue('');
|
131 | setSelectedValueForMultiSelect('');
|
132 | props.onChange && props.onChange('');
|
133 | }
|
134 | }
|
135 |
|
136 | setVisible(false);
|
137 | }, [props.onChange]);
|
138 |
|
139 | var onSearch = useCallback(function (data) {
|
140 | setSearchWord(data);
|
141 | }, []);
|
142 |
|
143 | var onSelect = useCallback(function (data) {
|
144 | if (selectType !== 'multiple') {
|
145 | setSelectedValue(data.value);
|
146 | setVisible(false);
|
147 | props.onChange && props.onChange(data.value);
|
148 |
|
149 | if (layerWrapperRef.current) {
|
150 | layerWrapperRef.current.focus();
|
151 | }
|
152 | } else {
|
153 |
|
154 | var newData = data.map(function (item) {
|
155 | return item.value;
|
156 | });
|
157 |
|
158 | if (searchWord) {
|
159 |
|
160 | var selectedArr = selectedValue && selectedValue.split(splitKey) || [];
|
161 |
|
162 | var searchdValue = getFilterdOptions(selectType, props.options, searchWord, caseSensitive).map(function (item) {
|
163 | return item.value;
|
164 | });
|
165 |
|
166 | var mayLost = selectedArr.filter(function (v) {
|
167 | return searchdValue.indexOf(v) > -1;
|
168 | });
|
169 |
|
170 | var realLost = mayLost.filter(function (item) {
|
171 | return !newData.includes(item);
|
172 | });
|
173 |
|
174 | realLost.forEach(function (item) {
|
175 | var index = selectedArr.indexOf(item);
|
176 | if (index !== -1) selectedArr.splice(index, 1);
|
177 | });
|
178 |
|
179 | for (var ind in newData) {
|
180 | if (!selectedArr.includes(newData[ind])) {
|
181 | selectedArr.push(newData[ind]);
|
182 | }
|
183 | }
|
184 |
|
185 | setSelectedValueForMultiSelect(selectedArr.join(splitKey));
|
186 | } else {
|
187 | setSelectedValueForMultiSelect(newData.join(splitKey));
|
188 | }
|
189 |
|
190 | if (layerWrapperRef.current) {
|
191 | layerWrapperRef.current.focus();
|
192 | }
|
193 | }
|
194 |
|
195 | setSelectFocus(true);
|
196 | }, [selectType, selectedValue, searchWord]);
|
197 |
|
198 | var afterOnClick = function afterOnClick(values) {
|
199 | setSelectedValue(values);
|
200 | setSearchWord('');
|
201 | setVisible(false);
|
202 | };
|
203 |
|
204 |
|
205 | var footer = useMemo(function () {
|
206 | var values = selectedValueForMultiSelect;
|
207 | return selectType == 'multiple' ? [{
|
208 | text: '确定',
|
209 | onClick: function onClick() {
|
210 | if (hostSubmit) {
|
211 | props.onChange && props.onChange(values, function () {
|
212 | afterOnClick(values);
|
213 | });
|
214 | afterOnClick(values);
|
215 | } else {
|
216 | props.onChange && props.onChange(values);
|
217 | afterOnClick(values);
|
218 | }
|
219 |
|
220 | if (layerWrapperRef.current) {
|
221 | layerWrapperRef.current.focus();
|
222 | }
|
223 | }
|
224 | }] : null;
|
225 | }, [selectType, selectedValueForMultiSelect, selectedValue, props.onChange]);
|
226 |
|
227 | var getSelectList = function getSelectList() {
|
228 |
|
229 |
|
230 |
|
231 | var canSearch = isSearch ? false : optionSearch ? true : false;
|
232 | var options = searchWord ? getFilterdOptions(selectType, props.options, searchWord, caseSensitive) : props.options;
|
233 | var selectContent;
|
234 |
|
235 | if (selectType == 'group') {
|
236 | selectContent = React.createElement(GroupSingleSelect, {
|
237 | searchWord: searchWord,
|
238 | value: selectedValue,
|
239 | options: options,
|
240 | onChange: onSelect,
|
241 | caseSensitive: caseSensitive,
|
242 | autoFocus: optionSearchAutoFocus
|
243 | });
|
244 | }
|
245 |
|
246 | if (selectType == 'multiple') {
|
247 | var selectedData = selectedValueForMultiSelect ? options.filter(function (item) {
|
248 | return selectedValueForMultiSelect.split(splitKey).includes(item.value);
|
249 | }) : undefined;
|
250 | selectContent = React.createElement(MultipleSelect, {
|
251 | searchWord: searchWord,
|
252 | showCheckAll: showCheckAll,
|
253 | defaultSelectedItems: selectedData,
|
254 | isSearch: canSearch
|
255 | ,
|
256 | items: options,
|
257 | extraCls: classes({
|
258 | element: 'multiSelect'
|
259 | }),
|
260 | onChange: onSelect,
|
261 | caseSensitive: caseSensitive,
|
262 | autoFocus: optionSearchAutoFocus
|
263 | });
|
264 | }
|
265 |
|
266 | if (!selectContent) {
|
267 | selectContent = React.createElement(SingleSelect, {
|
268 | searchWord: searchWord,
|
269 | selectedValue: selectedValue,
|
270 | items: options,
|
271 | isSearch: canSearch,
|
272 | onChange: onSelect,
|
273 | caseSensitive: caseSensitive,
|
274 | autoFocus: optionSearchAutoFocus
|
275 | });
|
276 | }
|
277 |
|
278 | return selectContent;
|
279 | };
|
280 |
|
281 | var getPopupContainer = useCallback(function () {
|
282 |
|
283 |
|
284 |
|
285 |
|
286 |
|
287 | }, [props.getPopupContainer]);
|
288 | var handleWrapperBlur = useCallback(function () {
|
289 | if (!visible && !isWrapperInRef.current && !isBlurRef.current) {
|
290 | onBlur && onBlur();
|
291 | isBlurRef.current = true;
|
292 | setTimeout(function () {
|
293 | isBlurRef.current = false;
|
294 | }, 10);
|
295 | setSelectFocus(false);
|
296 | }
|
297 | }, [visible, onBlur]);
|
298 |
|
299 | var handleWrapperMouseEnterLeave = useCallback(function (flag) {
|
300 | return function (e) {
|
301 | isWrapperInRef.current = flag;
|
302 | };
|
303 | }, []);
|
304 | var getInputRef = useCallback(function (node) {
|
305 | inputRef.current = node;
|
306 | }, []);
|
307 |
|
308 |
|
309 |
|
310 |
|
311 |
|
312 |
|
313 |
|
314 |
|
315 |
|
316 |
|
317 |
|
318 |
|
319 |
|
320 |
|
321 |
|
322 | useEffect(function () {
|
323 | if (inputRef.current) {
|
324 | inputRef.current.onblur = function () {
|
325 | if (!visible && !isWrapperInRef.current && !isBlurRef.current) {
|
326 | onBlur && onBlur();
|
327 | setSelectFocus(false);
|
328 | isBlurRef.current = true;
|
329 | setTimeout(function () {
|
330 | isBlurRef.current = false;
|
331 | }, 10);
|
332 | }
|
333 | };
|
334 | }
|
335 | }, [onBlur, visible]);
|
336 | useEffect(function () {
|
337 | if (autoFocus && inputRef.current) {
|
338 | inputRef.current.focus();
|
339 | }
|
340 | }, []);
|
341 |
|
342 | var handleSelectClick = useCallback(function () {
|
343 | if (isSearch) {
|
344 | isSelectClickRef.current = true;
|
345 | }
|
346 | }, [isSearch]);
|
347 |
|
348 | if (isPreview) {
|
349 | return React.createElement(FormControlPreview, {
|
350 | multiple: selectType === 'multiple',
|
351 | value: getDisplayLabel(props.options, selectType, selectedValue, props.displayLabel, splitKey)
|
352 | });
|
353 | }
|
354 |
|
355 | return React.createElement(Layer, {
|
356 | blockContainer: true,
|
357 | trigger: ['click'],
|
358 | content: visible ? getSelectList() : null,
|
359 | visible: visible,
|
360 | zIndex: props.zIndex,
|
361 | onVisibleChange: toggleLayer,
|
362 | footer: props.options.length > 0 ? footer : null,
|
363 | width: layerWidth,
|
364 | getPopupContainer: props.getPopupContainer,
|
365 | destroyPopupOnHide: true,
|
366 | stretch: props.stretch
|
367 | }, React.createElement("div", {
|
368 | tabIndex: 2,
|
369 | className: "select_dropdown_wrapper",
|
370 | onMouseEnter: handleWrapperMouseEnterLeave(true),
|
371 | onMouseLeave: handleWrapperMouseEnterLeave(false),
|
372 | ref: layerWrapperRef,
|
373 | onBlur: handleWrapperBlur
|
374 | }, React.createElement(Select, _extends({}, props, {
|
375 | extraCls: classes({
|
376 | element: '',
|
377 | extra: props.extraCls
|
378 | }),
|
379 | isSearch: isSearch,
|
380 | error: hasError,
|
381 | inputRef: getInputRef,
|
382 | onClick: handleSelectClick,
|
383 | value: getDisplayLabel(props.options, selectType, selectedValue, props.displayLabel, splitKey),
|
384 | isMultiSelect: selectType == 'multiple',
|
385 | onDelete: onDelete,
|
386 | isActive: selectIsActive ? selectFocus : visible,
|
387 | onSearch: onSearch,
|
388 | onChange: onChange,
|
389 | exitSearch: !visible
|
390 | }))));
|
391 | };
|
392 |
|
393 | FieldDropdown.defaultProps = {
|
394 | options: []
|
395 | };
|
396 | export default FieldDropdown; |
\ | No newline at end of file |