funda-ui 4.7.161 → 4.7.171
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Select/index.css +32 -4
- package/Select/index.d.ts +6 -12
- package/Select/index.js +199 -308
- package/lib/cjs/Select/index.d.ts +6 -12
- package/lib/cjs/Select/index.js +199 -308
- package/lib/css/Select/index.css +32 -4
- package/lib/esm/Select/index.scss +41 -4
- package/lib/esm/Select/index.tsx +192 -142
- package/package.json +1 -1
package/lib/esm/Select/index.tsx
CHANGED
|
@@ -52,14 +52,8 @@ import { clsWrite, combinedCls } from 'funda-utils/dist/cjs/cls';
|
|
|
52
52
|
|
|
53
53
|
|
|
54
54
|
|
|
55
|
-
|
|
56
55
|
export type SelectOptionChangeFnType = (arg1: any, arg2: any, arg3: any) => void;
|
|
57
56
|
|
|
58
|
-
export interface MultiSelectDataConfig {
|
|
59
|
-
values: string[] | number[];
|
|
60
|
-
labels: string[] | number[];
|
|
61
|
-
queryStrings: string[] | number[];
|
|
62
|
-
}
|
|
63
57
|
|
|
64
58
|
export interface MultiSelectControlValConfig {
|
|
65
59
|
values: string[];
|
|
@@ -83,7 +77,6 @@ export interface MultiSelectConfig {
|
|
|
83
77
|
selectAll: boolean;
|
|
84
78
|
selectAllLabel?: string;
|
|
85
79
|
deselectAllLabel?: string;
|
|
86
|
-
data: MultiSelectDataConfig | null;
|
|
87
80
|
}
|
|
88
81
|
|
|
89
82
|
export interface multiSelectSelectedItemOnlyStatusConfig {
|
|
@@ -94,9 +87,9 @@ export interface multiSelectSelectedItemOnlyStatusConfig {
|
|
|
94
87
|
|
|
95
88
|
|
|
96
89
|
|
|
97
|
-
export interface
|
|
90
|
+
export interface ClearTriggerConfig {
|
|
98
91
|
valid: boolean;
|
|
99
|
-
|
|
92
|
+
clearValueLabel?: string;
|
|
100
93
|
}
|
|
101
94
|
|
|
102
95
|
|
|
@@ -108,13 +101,14 @@ export type SelectProps = {
|
|
|
108
101
|
controlExClassName?: string;
|
|
109
102
|
optionsExClassName?: string;
|
|
110
103
|
exceededSidePosOffset?: number;
|
|
104
|
+
clearIcon?: boolean;
|
|
111
105
|
multiSelect?: MultiSelectConfig;
|
|
112
106
|
multiSelectEntireAreaTrigger?: boolean;
|
|
113
107
|
multiSelectSelectedItemOnlyStatus?: multiSelectSelectedItemOnlyStatusConfig;
|
|
114
108
|
renderSelectedValue?: (selectedData: MultiSelectControlValConfig, removeFunc: (e: React.MouseEvent) => void) => React.ReactNode;
|
|
115
|
-
|
|
116
|
-
defaultValue?: string | OptionConfig;
|
|
117
|
-
value?: string | OptionConfig;
|
|
109
|
+
clearTrigger?: ClearTriggerConfig;
|
|
110
|
+
defaultValue?: string | OptionConfig | OptionConfig[];
|
|
111
|
+
value?: string | OptionConfig | OptionConfig[];
|
|
118
112
|
label?: React.ReactNode | string;
|
|
119
113
|
name?: string;
|
|
120
114
|
disabled?: any;
|
|
@@ -131,7 +125,6 @@ export type SelectProps = {
|
|
|
131
125
|
controlArrow?: React.ReactNode;
|
|
132
126
|
firstRequestAutoExec?: boolean;
|
|
133
127
|
fetchTrigger?: boolean;
|
|
134
|
-
fetchTriggerForDefaultData?: MultiSelectDataConfig | null;
|
|
135
128
|
/** Set the depth value of the control to control the display of the pop-up layer appear above.
|
|
136
129
|
* Please set it when multiple controls are used at the same time. */
|
|
137
130
|
depth?: number;
|
|
@@ -172,6 +165,7 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
172
165
|
controlExClassName,
|
|
173
166
|
optionsExClassName,
|
|
174
167
|
exceededSidePosOffset,
|
|
168
|
+
clearIcon,
|
|
175
169
|
multiSelect,
|
|
176
170
|
multiSelectEntireAreaTrigger,
|
|
177
171
|
multiSelectSelectedItemOnlyStatus,
|
|
@@ -189,7 +183,7 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
189
183
|
autoCapitalize,
|
|
190
184
|
spellCheck,
|
|
191
185
|
options,
|
|
192
|
-
|
|
186
|
+
clearTrigger,
|
|
193
187
|
loader,
|
|
194
188
|
lockBodyScroll,
|
|
195
189
|
hierarchical,
|
|
@@ -202,7 +196,6 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
202
196
|
tabIndex,
|
|
203
197
|
firstRequestAutoExec,
|
|
204
198
|
fetchTrigger,
|
|
205
|
-
fetchTriggerForDefaultData,
|
|
206
199
|
fetchNoneInfo = 'No match yet',
|
|
207
200
|
fetchUpdate,
|
|
208
201
|
fetchFuncAsync,
|
|
@@ -227,7 +220,7 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
227
220
|
const MANUAL_REQ = typeof fetchTrigger !== 'undefined' && fetchTrigger === true ? true : false; // Manual requests
|
|
228
221
|
const LIVE_SEARCH_DISABLED = !MANUAL_REQ && typeof window !== 'undefined' && typeof (window as any)['funda-ui__Select-disable-livesearch'] !== 'undefined' ? true : false; // Globally disable real-time search functionality (only valid for non-dynamic requests)
|
|
229
222
|
|
|
230
|
-
|
|
223
|
+
const CLEAR_ICON = typeof clearIcon === 'undefined' ? true : clearIcon;
|
|
231
224
|
const FIRST_REQUEST_AUTO = typeof firstRequestAutoExec === 'undefined' ? true : firstRequestAutoExec;
|
|
232
225
|
const INPUT_READONLY = LIVE_SEARCH_DISABLED ? true : (typeof readOnly === 'undefined' ? null : readOnly);
|
|
233
226
|
const VALUE_BY_BRACKETS = typeof extractValueByBrackets === 'undefined' ? true : extractValueByBrackets;
|
|
@@ -303,6 +296,11 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
303
296
|
values: []
|
|
304
297
|
});
|
|
305
298
|
|
|
299
|
+
function chkValueExist(v: any) {
|
|
300
|
+
return typeof v !== 'undefined' && v !== '';
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
|
|
306
304
|
const listContainerHeightLimit = (num: number) => {
|
|
307
305
|
let res = num;
|
|
308
306
|
if (res > LIST_CONTAINER_MAX_HEIGHT) res = LIST_CONTAINER_MAX_HEIGHT;
|
|
@@ -318,9 +316,9 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
318
316
|
return _data.map((v: any) => v.toString()).includes(val.toString());
|
|
319
317
|
};
|
|
320
318
|
|
|
321
|
-
//
|
|
322
|
-
const
|
|
323
|
-
const
|
|
319
|
+
// clear trigger
|
|
320
|
+
const CLEAR_TRIGGER_VALID = typeof clearTrigger === 'undefined' ? false : (clearTrigger ? clearTrigger.valid : false);
|
|
321
|
+
const CLEAR_TRIGGER_LABEL = clearTrigger ? clearTrigger.clearValueLabel : 'Clear';
|
|
324
322
|
|
|
325
323
|
|
|
326
324
|
const optionsFormatGroupOpt = (allData: any[]) => {
|
|
@@ -368,7 +366,7 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
368
366
|
if (MULTI_SEL_VALID) {
|
|
369
367
|
updateOptionCheckboxes('remove');
|
|
370
368
|
} else {
|
|
371
|
-
|
|
369
|
+
handleClearValue();
|
|
372
370
|
}
|
|
373
371
|
|
|
374
372
|
selectInputRef.current.blur();
|
|
@@ -515,7 +513,6 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
515
513
|
// Determine whether the default value is user query input or default input
|
|
516
514
|
const defaultValue = init ? valueToInputDefault : '';
|
|
517
515
|
|
|
518
|
-
|
|
519
516
|
if (typeof fetchFuncAsync === 'object') {
|
|
520
517
|
|
|
521
518
|
|
|
@@ -554,42 +551,24 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
554
551
|
// STEP 3: ===========
|
|
555
552
|
// value & label must be initialized
|
|
556
553
|
let filterRes: any = [];
|
|
554
|
+
// If the default value is label, match value
|
|
555
|
+
const filterResQueryValue = _ORGIN_DATA.filter((item: any) => item.value == defaultValue);
|
|
556
|
+
const filterResQueryLabel = _ORGIN_DATA.filter((item: any) => item.label == defaultValue);
|
|
557
557
|
|
|
558
|
+
filterRes = filterResQueryValue;
|
|
559
|
+
if (filterResQueryValue.length === 0) filterRes = filterResQueryLabel;
|
|
558
560
|
|
|
559
|
-
if
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
if (typeof fetchTriggerForDefaultData !== 'undefined' && fetchTriggerForDefaultData !== null && typeof fetchTriggerForDefaultData?.values[0] !== 'undefined') {
|
|
563
|
-
filterRes = [{
|
|
564
|
-
value: fetchTriggerForDefaultData?.values[0],
|
|
565
|
-
label: fetchTriggerForDefaultData?.labels[0],
|
|
566
|
-
queryString: fetchTriggerForDefaultData?.queryStrings[0]
|
|
567
|
-
}];
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
} else {
|
|
571
|
-
|
|
572
|
-
// If the default value is label, match value
|
|
573
|
-
const filterResQueryValue = _ORGIN_DATA.filter((item: any) => item.value == defaultValue);
|
|
574
|
-
const filterResQueryLabel = _ORGIN_DATA.filter((item: any) => item.label == defaultValue);
|
|
575
|
-
|
|
576
|
-
filterRes = filterResQueryValue;
|
|
577
|
-
if (filterResQueryValue.length === 0) filterRes = filterResQueryLabel;
|
|
578
|
-
|
|
579
|
-
// if the default value is Object
|
|
580
|
-
if (isObject(inputDefault) && filterRes.length === 0) {
|
|
581
|
-
filterRes = [inputDefault];
|
|
582
|
-
}
|
|
583
|
-
|
|
561
|
+
// if the default value is Object
|
|
562
|
+
if (isObject(inputDefault) && filterRes.length === 0) {
|
|
563
|
+
filterRes = [inputDefault];
|
|
584
564
|
}
|
|
585
565
|
|
|
586
|
-
|
|
587
566
|
|
|
588
567
|
// STEP 4: ===========
|
|
589
568
|
// ++++++++++++++++++++
|
|
590
569
|
// Single selection
|
|
591
570
|
// ++++++++++++++++++++
|
|
592
|
-
if (
|
|
571
|
+
if (!chkValueExist(defaultValue)) { // Do not use `init`, otherwise the query will revert to the default value if there is no value
|
|
593
572
|
setControlValue('');
|
|
594
573
|
setControlLabel('');
|
|
595
574
|
} else {
|
|
@@ -607,7 +586,7 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
607
586
|
if (MULTI_SEL_VALID) {
|
|
608
587
|
|
|
609
588
|
|
|
610
|
-
if ((
|
|
589
|
+
if (!chkValueExist(defaultValue) && init) {
|
|
611
590
|
setControlArr({
|
|
612
591
|
labels: [],
|
|
613
592
|
values: []
|
|
@@ -616,43 +595,18 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
616
595
|
|
|
617
596
|
|
|
618
597
|
|
|
619
|
-
if (
|
|
598
|
+
if (chkValueExist(defaultValue) && Array.isArray(defaultValue)) {
|
|
620
599
|
|
|
621
600
|
// initialize default values of Multiple selection
|
|
622
|
-
const _currentData:
|
|
601
|
+
const _currentData: OptionConfig[] = defaultValue;
|
|
602
|
+
const _defaultValues = _currentData.map((v: OptionConfig) => v.value as string);
|
|
603
|
+
const _defaultLabels = _currentData.map((v: OptionConfig) => v.label as string);
|
|
623
604
|
|
|
624
605
|
setControlArr({
|
|
625
|
-
labels:
|
|
626
|
-
values:
|
|
606
|
+
labels: _defaultLabels,
|
|
607
|
+
values: _defaultValues,
|
|
627
608
|
});
|
|
628
609
|
|
|
629
|
-
//
|
|
630
|
-
const _values: string[] = VALUE_BY_BRACKETS ? extractContentsOfBrackets(defaultValue) : defaultValue.split(',');
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
_values.forEach((_value: string, _index: number) => {
|
|
634
|
-
|
|
635
|
-
if (!multiSelControlOptionExist(_currentData.values, _value) && typeof _currentData.values[_index] !== 'undefined') {
|
|
636
|
-
|
|
637
|
-
let filterRes: any = [];
|
|
638
|
-
filterRes = [{
|
|
639
|
-
value: _currentData.values[_index],
|
|
640
|
-
label: _currentData.labels[_index],
|
|
641
|
-
queryString: _currentData.queryStrings[_index]
|
|
642
|
-
}];
|
|
643
|
-
|
|
644
|
-
setControlArr((prevState: any) => {
|
|
645
|
-
return {
|
|
646
|
-
labels: unique([...prevState.labels, typeof filterRes[0] !== 'undefined' ? filterRes[0].label : ''].filter((v: any) => v !== '')),
|
|
647
|
-
values: unique([...prevState.values, typeof filterRes[0] !== 'undefined' ? filterRes[0].value : ''].filter((v: any) => v !== ''))
|
|
648
|
-
}
|
|
649
|
-
});
|
|
650
|
-
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
});
|
|
654
|
-
|
|
655
|
-
|
|
656
610
|
}
|
|
657
611
|
|
|
658
612
|
// Appropriate multi-item container height
|
|
@@ -705,8 +659,6 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
705
659
|
|
|
706
660
|
|
|
707
661
|
// STEP 3: ===========
|
|
708
|
-
// value & label must be initialized
|
|
709
|
-
|
|
710
662
|
// If the default value is label, match value
|
|
711
663
|
let filterRes: any = [];
|
|
712
664
|
const filterResQueryValue = staticOptionsData.filter((item: any) => item.value == defaultValue);
|
|
@@ -727,7 +679,7 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
727
679
|
// ++++++++++++++++++++
|
|
728
680
|
// Single selection
|
|
729
681
|
// ++++++++++++++++++++
|
|
730
|
-
if (
|
|
682
|
+
if (!chkValueExist(defaultValue)) { // Do not use `init`, otherwise the query will revert to the default value if there is no value
|
|
731
683
|
setControlValue('');
|
|
732
684
|
setControlLabel('');
|
|
733
685
|
} else {
|
|
@@ -746,46 +698,23 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
746
698
|
if (MULTI_SEL_VALID) {
|
|
747
699
|
|
|
748
700
|
|
|
749
|
-
if ((
|
|
701
|
+
if (!chkValueExist(defaultValue) && init) {
|
|
750
702
|
setControlArr({
|
|
751
703
|
labels: [],
|
|
752
704
|
values: []
|
|
753
705
|
});
|
|
754
706
|
}
|
|
755
707
|
|
|
756
|
-
if (
|
|
708
|
+
if (chkValueExist(defaultValue) && Array.isArray(defaultValue)) {
|
|
757
709
|
|
|
758
710
|
// initialize default values of Multiple selection
|
|
759
|
-
const _currentData:
|
|
760
|
-
|
|
711
|
+
const _currentData: OptionConfig[] = defaultValue;
|
|
712
|
+
const _defaultValues = _currentData.map((v: OptionConfig) => v.value as string);
|
|
713
|
+
const _defaultLabels = _currentData.map((v: OptionConfig) => v.label as string);
|
|
714
|
+
|
|
761
715
|
setControlArr({
|
|
762
|
-
labels:
|
|
763
|
-
values:
|
|
764
|
-
});
|
|
765
|
-
|
|
766
|
-
//
|
|
767
|
-
const _values: string[] = typeof defaultValue !== 'undefined' ? (VALUE_BY_BRACKETS ? extractContentsOfBrackets(defaultValue) : defaultValue.split(',')) : [];
|
|
768
|
-
_values.forEach((_value: string, _index: number) => {
|
|
769
|
-
|
|
770
|
-
if (!multiSelControlOptionExist(_currentData.values, _value) && typeof _currentData.values[_index] !== 'undefined') {
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
let filterRes: any = [];
|
|
774
|
-
filterRes = [{
|
|
775
|
-
value: _currentData.values[_index],
|
|
776
|
-
label: _currentData.labels[_index],
|
|
777
|
-
queryString: _currentData.queryStrings[_index]
|
|
778
|
-
}];
|
|
779
|
-
|
|
780
|
-
setControlArr((prevState: any) => {
|
|
781
|
-
return {
|
|
782
|
-
labels: unique([...prevState.labels, typeof filterRes[0] !== 'undefined' ? filterRes[0].label : ''].filter((v: any) => v !== '')),
|
|
783
|
-
values: unique([...prevState.values, typeof filterRes[0] !== 'undefined' ? filterRes[0].value : ''].filter((v: any) => v !== ''))
|
|
784
|
-
}
|
|
785
|
-
});
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
}
|
|
716
|
+
labels: _defaultLabels,
|
|
717
|
+
values: _defaultValues,
|
|
789
718
|
});
|
|
790
719
|
}
|
|
791
720
|
|
|
@@ -853,9 +782,9 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
853
782
|
const activedItem = el.querySelectorAll(`.list-group-item.${!MULTI_SEL_VALID ? 'active' : 'item-selected'}`)[0];
|
|
854
783
|
if (typeof activedItem !== 'undefined') {
|
|
855
784
|
|
|
856
|
-
const
|
|
857
|
-
const
|
|
858
|
-
const _latestScrollTop = activedItem.offsetTop -
|
|
785
|
+
const clearItem = el.querySelector(`.list-group-item.${!MULTI_SEL_VALID ? 'custom-select-multi__control-option-item--clear' : 'custom-select-multi__control-option-item--select-all'}`);
|
|
786
|
+
const clearItemHeight = clearItem === null ? 0 : clearItem.clientHeight;
|
|
787
|
+
const _latestScrollTop = activedItem.offsetTop - clearItemHeight;
|
|
859
788
|
|
|
860
789
|
el.scrollTop = _latestScrollTop;
|
|
861
790
|
}
|
|
@@ -1200,7 +1129,7 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
1200
1129
|
|
|
1201
1130
|
|
|
1202
1131
|
if (MANUAL_REQ) {
|
|
1203
|
-
//
|
|
1132
|
+
// clear data
|
|
1204
1133
|
setOptionsData([]);
|
|
1205
1134
|
} else {
|
|
1206
1135
|
// restore data
|
|
@@ -1264,7 +1193,7 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
1264
1193
|
|
|
1265
1194
|
|
|
1266
1195
|
if (MANUAL_REQ) {
|
|
1267
|
-
//
|
|
1196
|
+
// clear data
|
|
1268
1197
|
setOptionsData([]);
|
|
1269
1198
|
} else {
|
|
1270
1199
|
// restore data
|
|
@@ -1744,7 +1673,7 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
1744
1673
|
|
|
1745
1674
|
}
|
|
1746
1675
|
|
|
1747
|
-
function
|
|
1676
|
+
function handleClearValue(event?: any) {
|
|
1748
1677
|
if (typeof event !== 'undefined') {
|
|
1749
1678
|
event.preventDefault();
|
|
1750
1679
|
event.stopPropagation(); /* REQUIRED */
|
|
@@ -1848,10 +1777,6 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
1848
1777
|
|
|
1849
1778
|
async function handleFirstFetch(inputVal: any = null) {
|
|
1850
1779
|
|
|
1851
|
-
// If manual requests are enabled, do not send them for the first time
|
|
1852
|
-
if (MANUAL_REQ) return [];
|
|
1853
|
-
|
|
1854
|
-
//
|
|
1855
1780
|
const _oparams: any[] = fetchFuncMethodParams || [];
|
|
1856
1781
|
const _params: any[] = _oparams.map((item: any) => item !== '$QUERY_STRING' ? item : (MANUAL_REQ ? QUERY_STRING_PLACEHOLDER : ''));
|
|
1857
1782
|
const res = await fetchData((_params).join(','), finalRes(inputVal), inputVal);
|
|
@@ -1951,7 +1876,7 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
1951
1876
|
|
|
1952
1877
|
|
|
1953
1878
|
// Avoid selecting options that are disabled
|
|
1954
|
-
const options = [].slice.call(listRef.current.querySelectorAll('.list-group-item:not(.hide):not(.custom-select-multi__control-option-item--select-all):not(.custom-select-multi__control-option-item--
|
|
1879
|
+
const options = [].slice.call(listRef.current.querySelectorAll('.list-group-item:not(.hide):not(.custom-select-multi__control-option-item--select-all):not(.custom-select-multi__control-option-item--clear)'));
|
|
1955
1880
|
const currentIndex = options.findIndex((e) => e === listRef.current.querySelector('.list-group-item.active'));
|
|
1956
1881
|
|
|
1957
1882
|
|
|
@@ -2088,7 +2013,6 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
2088
2013
|
|
|
2089
2014
|
useEffect(() => {
|
|
2090
2015
|
|
|
2091
|
-
|
|
2092
2016
|
// Call a function when the component has been rendered completely
|
|
2093
2017
|
//--------------
|
|
2094
2018
|
onLoad?.(selectInputRef.current, valueInputRef.current, finalRes(value));
|
|
@@ -2103,16 +2027,61 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
2103
2027
|
//--------------
|
|
2104
2028
|
if (FIRST_REQUEST_AUTO) {
|
|
2105
2029
|
handleFirstFetch(value);
|
|
2030
|
+
} else {
|
|
2031
|
+
if (MULTI_SEL_VALID) {
|
|
2032
|
+
// Appropriate multi-item container height
|
|
2033
|
+
setTimeout(() => {
|
|
2034
|
+
adjustMultiControlContainerHeight();
|
|
2035
|
+
}, 0);
|
|
2036
|
+
}
|
|
2106
2037
|
}
|
|
2107
2038
|
|
|
2108
2039
|
// Forced assignment does not depend on "fetch" or "firstRequestAutoExe"
|
|
2109
2040
|
// Don't use "value.value && value.label" directly, if it is empty, it will be treated as FALSE
|
|
2110
|
-
if (
|
|
2111
|
-
|
|
2112
|
-
|
|
2041
|
+
if (chkValueExist(value)) {
|
|
2042
|
+
// ++++++++++++++++++++
|
|
2043
|
+
// Single selection
|
|
2044
|
+
// ++++++++++++++++++++
|
|
2045
|
+
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
2046
|
+
if (typeof value.value !== 'undefined' && value.value !== null) setControlValue(value.value as string);
|
|
2047
|
+
if (typeof value.label !== 'undefined' && value.label !== null) setControlLabel(formatIndentVal(value.label, INDENT_LAST_PLACEHOLDER));
|
|
2048
|
+
}
|
|
2049
|
+
|
|
2050
|
+
// ++++++++++++++++++++
|
|
2051
|
+
// Multiple selection
|
|
2052
|
+
// ++++++++++++++++++++
|
|
2053
|
+
if (MULTI_SEL_VALID) {
|
|
2054
|
+
if (chkValueExist(value) && Array.isArray(value)) {
|
|
2055
|
+
|
|
2056
|
+
const _currentData: OptionConfig[] = value;
|
|
2057
|
+
const _defaultValues = _currentData.map((v: OptionConfig) => v.value as string);
|
|
2058
|
+
const _defaultLabels = _currentData.map((v: OptionConfig) => v.label as string);
|
|
2059
|
+
|
|
2060
|
+
setControlArr({
|
|
2061
|
+
labels: _defaultLabels,
|
|
2062
|
+
values: _defaultValues,
|
|
2063
|
+
});
|
|
2064
|
+
}
|
|
2065
|
+
}
|
|
2066
|
+
|
|
2067
|
+
} else {
|
|
2068
|
+
// ++++++++++++++++++++
|
|
2069
|
+
// Single selection & Multiple selection
|
|
2070
|
+
// ++++++++++++++++++++
|
|
2071
|
+
if (!FIRST_REQUEST_AUTO) {
|
|
2072
|
+
setControlValue('');
|
|
2073
|
+
setControlLabel('');
|
|
2074
|
+
setControlArr({
|
|
2075
|
+
labels: [],
|
|
2076
|
+
values: []
|
|
2077
|
+
});
|
|
2078
|
+
}
|
|
2113
2079
|
}
|
|
2114
2080
|
|
|
2115
2081
|
|
|
2082
|
+
|
|
2083
|
+
|
|
2084
|
+
|
|
2116
2085
|
//
|
|
2117
2086
|
//--------------
|
|
2118
2087
|
return () => {
|
|
@@ -2137,14 +2106,64 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
2137
2106
|
//--------------
|
|
2138
2107
|
if (FIRST_REQUEST_AUTO) {
|
|
2139
2108
|
handleFirstFetch(defaultValue);
|
|
2109
|
+
} else {
|
|
2110
|
+
if (MULTI_SEL_VALID) {
|
|
2111
|
+
// Appropriate multi-item container height
|
|
2112
|
+
setTimeout(() => {
|
|
2113
|
+
adjustMultiControlContainerHeight();
|
|
2114
|
+
}, 0);
|
|
2115
|
+
}
|
|
2116
|
+
}
|
|
2117
|
+
|
|
2118
|
+
|
|
2119
|
+
// Forced assignment does not depend on "fetch" or "firstRequestAutoExe"
|
|
2120
|
+
// Don't use "value.value && value.label" directly, if it is empty, it will be treated as FALSE
|
|
2121
|
+
if (chkValueExist(defaultValue)) {
|
|
2122
|
+
// ++++++++++++++++++++
|
|
2123
|
+
// Single selection
|
|
2124
|
+
// ++++++++++++++++++++
|
|
2125
|
+
if (typeof defaultValue === 'object' && !Array.isArray(defaultValue)) {
|
|
2126
|
+
if (typeof defaultValue.value !== 'undefined' && defaultValue.value !== null) setControlValue(defaultValue.value as string);
|
|
2127
|
+
if (typeof defaultValue.label !== 'undefined' && defaultValue.label !== null) setControlLabel(formatIndentVal(defaultValue.label, INDENT_LAST_PLACEHOLDER));
|
|
2128
|
+
}
|
|
2129
|
+
|
|
2130
|
+
// ++++++++++++++++++++
|
|
2131
|
+
// Multiple selection
|
|
2132
|
+
// ++++++++++++++++++++
|
|
2133
|
+
if (MULTI_SEL_VALID) {
|
|
2134
|
+
if (chkValueExist(defaultValue) && Array.isArray(defaultValue)) {
|
|
2135
|
+
|
|
2136
|
+
const _currentData: OptionConfig[] = defaultValue;
|
|
2137
|
+
const _defaultValues = _currentData.map((v: OptionConfig) => v.value as string);
|
|
2138
|
+
const _defaultLabels = _currentData.map((v: OptionConfig) => v.label as string);
|
|
2139
|
+
|
|
2140
|
+
setControlArr({
|
|
2141
|
+
labels: _defaultLabels,
|
|
2142
|
+
values: _defaultValues,
|
|
2143
|
+
});
|
|
2144
|
+
}
|
|
2145
|
+
}
|
|
2146
|
+
|
|
2147
|
+
} else {
|
|
2148
|
+
// ++++++++++++++++++++
|
|
2149
|
+
// Single selection & Multiple selection
|
|
2150
|
+
// ++++++++++++++++++++
|
|
2151
|
+
if (!FIRST_REQUEST_AUTO) {
|
|
2152
|
+
setControlValue('');
|
|
2153
|
+
setControlLabel('');
|
|
2154
|
+
setControlArr({
|
|
2155
|
+
labels: [],
|
|
2156
|
+
values: []
|
|
2157
|
+
});
|
|
2158
|
+
}
|
|
2140
2159
|
}
|
|
2141
2160
|
|
|
2161
|
+
|
|
2142
2162
|
}
|
|
2143
2163
|
|
|
2144
2164
|
}, []);
|
|
2145
2165
|
|
|
2146
2166
|
|
|
2147
|
-
|
|
2148
2167
|
// Fixed an out-of-focus issue
|
|
2149
2168
|
//--------------
|
|
2150
2169
|
// !!! TIPS:
|
|
@@ -2183,6 +2202,42 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
2183
2202
|
>
|
|
2184
2203
|
|
|
2185
2204
|
|
|
2205
|
+
{/* CLEAR ICON */}
|
|
2206
|
+
{CLEAR_ICON && (
|
|
2207
|
+
(!MULTI_SEL_VALID && controlValue) || // Single selection Control
|
|
2208
|
+
(MULTI_SEL_VALID && controlArr.values.length > 0 ) // Multiple selection Control
|
|
2209
|
+
) ? (
|
|
2210
|
+
<span className={`custom-select-clear-icon ${MANUAL_REQ ? 'pos-offset' : ''}`}>
|
|
2211
|
+
<button
|
|
2212
|
+
tabIndex={-1}
|
|
2213
|
+
type="button"
|
|
2214
|
+
onClick={(e: React.MouseEvent) => {
|
|
2215
|
+
e.preventDefault();
|
|
2216
|
+
e.stopPropagation();
|
|
2217
|
+
|
|
2218
|
+
if (MULTI_SEL_VALID) {
|
|
2219
|
+
updateOptionCheckboxes('remove');
|
|
2220
|
+
|
|
2221
|
+
onChange?.(
|
|
2222
|
+
selectInputRef.current,
|
|
2223
|
+
valueInputRef.current,
|
|
2224
|
+
multipleSelectionCallback([], [])
|
|
2225
|
+
);
|
|
2226
|
+
|
|
2227
|
+
} else {
|
|
2228
|
+
handleClearValue();
|
|
2229
|
+
}
|
|
2230
|
+
|
|
2231
|
+
}}
|
|
2232
|
+
>
|
|
2233
|
+
<svg width="12px" height="12px" viewBox="0 0 1024 1024">
|
|
2234
|
+
<path fill="#000" d="M195.2 195.2a64 64 0 0 1 90.496 0L512 421.504 738.304 195.2a64 64 0 0 1 90.496 90.496L602.496 512 828.8 738.304a64 64 0 0 1-90.496 90.496L512 602.496 285.696 828.8a64 64 0 0 1-90.496-90.496L421.504 512 195.2 285.696a64 64 0 0 1 0-90.496z" />
|
|
2235
|
+
</svg>
|
|
2236
|
+
</button>
|
|
2237
|
+
</span>
|
|
2238
|
+
) : null}
|
|
2239
|
+
{/* CLEAR ICON */}
|
|
2240
|
+
|
|
2186
2241
|
|
|
2187
2242
|
{!MULTI_SEL_VALID ? <>
|
|
2188
2243
|
|
|
@@ -2234,8 +2289,6 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
2234
2289
|
/>
|
|
2235
2290
|
|
|
2236
2291
|
</div>
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
2292
|
</> : null}
|
|
2240
2293
|
|
|
2241
2294
|
{/* ========== RESULT CONTAINER ========== */}
|
|
@@ -2280,7 +2333,6 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
2280
2333
|
*/}
|
|
2281
2334
|
{!MULTI_SEL_VALID ? <div className="custom-select-single__inputplaceholder-wrapper">
|
|
2282
2335
|
|
|
2283
|
-
|
|
2284
2336
|
{/* PLACEHOLDER */}
|
|
2285
2337
|
<div className="custom-select-single__inputplaceholder-inner" style={style}>
|
|
2286
2338
|
<input
|
|
@@ -2369,9 +2421,7 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
2369
2421
|
// ++++++++++++++++++++
|
|
2370
2422
|
*/}
|
|
2371
2423
|
{MULTI_SEL_VALID ? <div ref={rootMultiRef} className="custom-select-multi__inputplaceholder-wrapper">
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2424
|
+
|
|
2375
2425
|
{/* PLACEHOLDER */}
|
|
2376
2426
|
<div className="custom-select-multi__inputplaceholder-inner">
|
|
2377
2427
|
<div style={MULTI_SEL_ENTIRE_AREA_TRIGGER ? {pointerEvents: 'auto', cursor: 'pointer'} : undefined} onClick={(e: React.MouseEvent) => {
|
|
@@ -2683,26 +2733,26 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
2683
2733
|
|
|
2684
2734
|
|
|
2685
2735
|
|
|
2686
|
-
{/*
|
|
2736
|
+
{/* CLEAR BUTTON (Only Single selection) */}
|
|
2687
2737
|
{!MULTI_SEL_VALID ? <>
|
|
2688
|
-
{
|
|
2738
|
+
{CLEAR_TRIGGER_VALID ? <>
|
|
2689
2739
|
<span
|
|
2690
2740
|
tabIndex={-1}
|
|
2691
|
-
className="list-group-item list-group-item-action border-start-0 border-end-0 text-secondary bg-light custom-select-multi__control-option-item--
|
|
2741
|
+
className="list-group-item list-group-item-action border-start-0 border-end-0 text-secondary bg-light custom-select-multi__control-option-item--clear position-sticky top-0 z-3"
|
|
2692
2742
|
role="tab"
|
|
2693
2743
|
>
|
|
2694
2744
|
<span
|
|
2695
2745
|
tabIndex={-1}
|
|
2696
2746
|
className="btn btn-secondary"
|
|
2697
2747
|
dangerouslySetInnerHTML={{
|
|
2698
|
-
__html: `${
|
|
2748
|
+
__html: `${CLEAR_TRIGGER_LABEL}`
|
|
2699
2749
|
}}
|
|
2700
|
-
onClick={
|
|
2750
|
+
onClick={handleClearValue}
|
|
2701
2751
|
></span>
|
|
2702
2752
|
</span>
|
|
2703
2753
|
</> : null}
|
|
2704
2754
|
</> : null}
|
|
2705
|
-
{/* /
|
|
2755
|
+
{/* /CLEAR BUTTON (Only Single selection) */}
|
|
2706
2756
|
|
|
2707
2757
|
|
|
2708
2758
|
{/* NO MATCH & LOADER */}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"author": "UIUX Lab",
|
|
3
3
|
"email": "uiuxlab@gmail.com",
|
|
4
4
|
"name": "funda-ui",
|
|
5
|
-
"version": "4.7.
|
|
5
|
+
"version": "4.7.171",
|
|
6
6
|
"description": "React components using pure Bootstrap 5+ which does not contain any external style and script libraries.",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|