funda-ui 4.7.163 → 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 +147 -277
- package/lib/cjs/Select/index.d.ts +6 -12
- package/lib/cjs/Select/index.js +147 -277
- package/lib/css/Select/index.css +32 -4
- package/lib/esm/Select/index.scss +41 -4
- package/lib/esm/Select/index.tsx +145 -112
- package/package.json +1 -1
package/lib/css/Select/index.css
CHANGED
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
--cus-sel-control-wrapper-bg: #fff;
|
|
10
10
|
--cus-sel-control-wrapper-border-color: #dee2e6;
|
|
11
11
|
--cus-sel-control-list-bg: #efefef;
|
|
12
|
+
--cus-sel-clear-fill: #a5a5a5;
|
|
13
|
+
--cus-sel-clear-hover-fill: #000;
|
|
12
14
|
--cus-sel-arrow-fill: #a5a5a5;
|
|
13
15
|
--cus-sel-searchbtn-fill: #a5a5a5;
|
|
14
16
|
--cus-sel-searchbtn-hover-fill: #333;
|
|
@@ -17,7 +19,8 @@
|
|
|
17
19
|
position: relative; /* Required */
|
|
18
20
|
/*------ Placeholder for input ------*/
|
|
19
21
|
/*------ Arrow ------*/
|
|
20
|
-
/*------
|
|
22
|
+
/*------ Clear Icon ------*/
|
|
23
|
+
/*------ Clear Trigger ------*/
|
|
21
24
|
/*------ Input ------*/
|
|
22
25
|
/*------ Arrow ------*/
|
|
23
26
|
/*------ Blinking cursor ------*/
|
|
@@ -33,7 +36,32 @@
|
|
|
33
36
|
.custom-select__wrapper .arrow svg .arrow-fill-g {
|
|
34
37
|
fill: var(--cus-sel-arrow-fill);
|
|
35
38
|
}
|
|
36
|
-
.custom-select__wrapper .
|
|
39
|
+
.custom-select__wrapper .custom-select-clear-icon {
|
|
40
|
+
position: absolute;
|
|
41
|
+
top: 50%;
|
|
42
|
+
transform: rotate(0deg) translateY(-50%);
|
|
43
|
+
transform-origin: top;
|
|
44
|
+
right: 1.5rem;
|
|
45
|
+
z-index: 2;
|
|
46
|
+
pointer-events: all;
|
|
47
|
+
}
|
|
48
|
+
.custom-select__wrapper .custom-select-clear-icon button {
|
|
49
|
+
border: none;
|
|
50
|
+
box-shadow: none;
|
|
51
|
+
margin: 0;
|
|
52
|
+
padding: 0;
|
|
53
|
+
background: none;
|
|
54
|
+
}
|
|
55
|
+
.custom-select__wrapper .custom-select-clear-icon.pos-offset {
|
|
56
|
+
right: 2.25rem;
|
|
57
|
+
}
|
|
58
|
+
.custom-select__wrapper .custom-select-clear-icon svg path {
|
|
59
|
+
fill: var(--cus-sel-clear-fill);
|
|
60
|
+
}
|
|
61
|
+
.custom-select__wrapper .custom-select-clear-icon:hover svg path {
|
|
62
|
+
fill: var(--cus-sel-clear-hover-fill);
|
|
63
|
+
}
|
|
64
|
+
.custom-select__wrapper .clear svg .clear-fill-g {
|
|
37
65
|
fill: var(--cus-sel-arrow-fill);
|
|
38
66
|
}
|
|
39
67
|
.custom-select__wrapper [data-select]:focus {
|
|
@@ -392,10 +420,10 @@
|
|
|
392
420
|
font-size: 0.75rem;
|
|
393
421
|
padding: 0.1rem 0.5rem;
|
|
394
422
|
}
|
|
395
|
-
.custom-select__options-wrapper .custom-select-multi__control-option-item--
|
|
423
|
+
.custom-select__options-wrapper .custom-select-multi__control-option-item--clear.hide {
|
|
396
424
|
display: none !important;
|
|
397
425
|
}
|
|
398
|
-
.custom-select__options-wrapper .custom-select-multi__control-option-item--
|
|
426
|
+
.custom-select__options-wrapper .custom-select-multi__control-option-item--clear .btn {
|
|
399
427
|
font-size: 0.75rem;
|
|
400
428
|
padding: 0.1rem 0.5rem;
|
|
401
429
|
}
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
--cus-sel-control-wrapper-bg: #fff;
|
|
12
12
|
--cus-sel-control-wrapper-border-color: #dee2e6;
|
|
13
13
|
--cus-sel-control-list-bg: #efefef;
|
|
14
|
+
--cus-sel-clear-fill: #a5a5a5;
|
|
15
|
+
--cus-sel-clear-hover-fill: #000;
|
|
14
16
|
--cus-sel-arrow-fill: #a5a5a5;
|
|
15
17
|
--cus-sel-searchbtn-fill: #a5a5a5;
|
|
16
18
|
--cus-sel-searchbtn-hover-fill: #333;
|
|
@@ -35,9 +37,44 @@
|
|
|
35
37
|
fill: var(--cus-sel-arrow-fill);
|
|
36
38
|
}
|
|
37
39
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
40
|
+
|
|
41
|
+
/*------ Clear Icon ------*/
|
|
42
|
+
.custom-select-clear-icon {
|
|
43
|
+
position: absolute;
|
|
44
|
+
top: 50%;
|
|
45
|
+
transform: rotate(0deg) translateY(-50%);
|
|
46
|
+
transform-origin: top;
|
|
47
|
+
right: 1.5rem;
|
|
48
|
+
z-index: 2;
|
|
49
|
+
pointer-events: all;
|
|
50
|
+
|
|
51
|
+
button {
|
|
52
|
+
border: none;
|
|
53
|
+
box-shadow: none;
|
|
54
|
+
margin: 0;
|
|
55
|
+
padding: 0;
|
|
56
|
+
background: none;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
&.pos-offset {
|
|
61
|
+
right: 2.25rem;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
svg path {
|
|
65
|
+
fill: var(--cus-sel-clear-fill);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
&:hover {
|
|
69
|
+
svg path {
|
|
70
|
+
fill: var(--cus-sel-clear-hover-fill);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/*------ Clear Trigger ------*/
|
|
76
|
+
.clear {
|
|
77
|
+
svg .clear-fill-g {
|
|
41
78
|
fill: var(--cus-sel-arrow-fill);
|
|
42
79
|
}
|
|
43
80
|
}
|
|
@@ -576,7 +613,7 @@
|
|
|
576
613
|
}
|
|
577
614
|
|
|
578
615
|
/*------ Extended buttons of Single selection ------*/
|
|
579
|
-
.custom-select-multi__control-option-item--
|
|
616
|
+
.custom-select-multi__control-option-item--clear {
|
|
580
617
|
|
|
581
618
|
&.hide {
|
|
582
619
|
display: none !important;
|
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;
|
|
@@ -323,9 +316,9 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
323
316
|
return _data.map((v: any) => v.toString()).includes(val.toString());
|
|
324
317
|
};
|
|
325
318
|
|
|
326
|
-
//
|
|
327
|
-
const
|
|
328
|
-
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';
|
|
329
322
|
|
|
330
323
|
|
|
331
324
|
const optionsFormatGroupOpt = (allData: any[]) => {
|
|
@@ -373,7 +366,7 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
373
366
|
if (MULTI_SEL_VALID) {
|
|
374
367
|
updateOptionCheckboxes('remove');
|
|
375
368
|
} else {
|
|
376
|
-
|
|
369
|
+
handleClearValue();
|
|
377
370
|
}
|
|
378
371
|
|
|
379
372
|
selectInputRef.current.blur();
|
|
@@ -558,32 +551,16 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
558
551
|
// STEP 3: ===========
|
|
559
552
|
// value & label must be initialized
|
|
560
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);
|
|
561
557
|
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
// If a manual action is used to trigger the request
|
|
565
|
-
if (typeof fetchTriggerForDefaultData !== 'undefined' && fetchTriggerForDefaultData !== null && typeof fetchTriggerForDefaultData?.values[0] !== 'undefined') {
|
|
566
|
-
filterRes = [{
|
|
567
|
-
value: fetchTriggerForDefaultData?.values[0],
|
|
568
|
-
label: fetchTriggerForDefaultData?.labels[0],
|
|
569
|
-
queryString: fetchTriggerForDefaultData?.queryStrings[0]
|
|
570
|
-
}];
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
} else {
|
|
574
|
-
|
|
575
|
-
// If the default value is label, match value
|
|
576
|
-
const filterResQueryValue = _ORGIN_DATA.filter((item: any) => item.value == defaultValue);
|
|
577
|
-
const filterResQueryLabel = _ORGIN_DATA.filter((item: any) => item.label == defaultValue);
|
|
578
|
-
|
|
579
|
-
filterRes = filterResQueryValue;
|
|
580
|
-
if (filterResQueryValue.length === 0) filterRes = filterResQueryLabel;
|
|
581
|
-
|
|
582
|
-
// if the default value is Object
|
|
583
|
-
if (isObject(inputDefault) && filterRes.length === 0) {
|
|
584
|
-
filterRes = [inputDefault];
|
|
585
|
-
}
|
|
558
|
+
filterRes = filterResQueryValue;
|
|
559
|
+
if (filterResQueryValue.length === 0) filterRes = filterResQueryLabel;
|
|
586
560
|
|
|
561
|
+
// if the default value is Object
|
|
562
|
+
if (isObject(inputDefault) && filterRes.length === 0) {
|
|
563
|
+
filterRes = [inputDefault];
|
|
587
564
|
}
|
|
588
565
|
|
|
589
566
|
|
|
@@ -618,29 +595,16 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
618
595
|
|
|
619
596
|
|
|
620
597
|
|
|
621
|
-
if (chkValueExist(defaultValue) &&
|
|
598
|
+
if (chkValueExist(defaultValue) && Array.isArray(defaultValue)) {
|
|
622
599
|
|
|
623
600
|
// initialize default values of Multiple selection
|
|
624
|
-
const _currentData:
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
let _tempValues = [..._currentData.values];
|
|
628
|
-
|
|
629
|
-
const _values: string[] = VALUE_BY_BRACKETS ? extractContentsOfBrackets(defaultValue) : defaultValue.split(',');
|
|
630
|
-
|
|
631
|
-
_values.forEach((_value: string, _index: number) => {
|
|
632
|
-
if (!multiSelControlOptionExist(_currentData.values, _value) && typeof _currentData.values[_index] !== 'undefined') {
|
|
633
|
-
_tempLabels.push(_currentData.labels[_index]);
|
|
634
|
-
_tempValues.push(_currentData.values[_index]);
|
|
635
|
-
}
|
|
636
|
-
});
|
|
637
|
-
|
|
638
|
-
_tempLabels = unique(_tempLabels.filter((v: any) => v !== ''));
|
|
639
|
-
_tempValues = unique(_tempValues.filter((v: any) => v !== ''));
|
|
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);
|
|
640
604
|
|
|
641
605
|
setControlArr({
|
|
642
|
-
labels:
|
|
643
|
-
values:
|
|
606
|
+
labels: _defaultLabels,
|
|
607
|
+
values: _defaultValues,
|
|
644
608
|
});
|
|
645
609
|
|
|
646
610
|
}
|
|
@@ -695,8 +659,6 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
695
659
|
|
|
696
660
|
|
|
697
661
|
// STEP 3: ===========
|
|
698
|
-
// value & label must be initialized
|
|
699
|
-
|
|
700
662
|
// If the default value is label, match value
|
|
701
663
|
let filterRes: any = [];
|
|
702
664
|
const filterResQueryValue = staticOptionsData.filter((item: any) => item.value == defaultValue);
|
|
@@ -743,29 +705,16 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
743
705
|
});
|
|
744
706
|
}
|
|
745
707
|
|
|
746
|
-
if (chkValueExist(defaultValue) &&
|
|
708
|
+
if (chkValueExist(defaultValue) && Array.isArray(defaultValue)) {
|
|
747
709
|
|
|
748
710
|
// initialize default values of Multiple selection
|
|
749
|
-
const _currentData:
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
const _values: string[] = VALUE_BY_BRACKETS ? extractContentsOfBrackets(defaultValue) : defaultValue.split(',');
|
|
755
|
-
|
|
756
|
-
_values.forEach((_value: string, _index: number) => {
|
|
757
|
-
if (!multiSelControlOptionExist(_currentData.values, _value) && typeof _currentData.values[_index] !== 'undefined') {
|
|
758
|
-
_tempLabels.push(_currentData.labels[_index]);
|
|
759
|
-
_tempValues.push(_currentData.values[_index]);
|
|
760
|
-
}
|
|
761
|
-
});
|
|
762
|
-
|
|
763
|
-
_tempLabels = unique(_tempLabels.filter((v: any) => v !== ''));
|
|
764
|
-
_tempValues = unique(_tempValues.filter((v: any) => v !== ''));
|
|
765
|
-
|
|
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
|
+
|
|
766
715
|
setControlArr({
|
|
767
|
-
labels:
|
|
768
|
-
values:
|
|
716
|
+
labels: _defaultLabels,
|
|
717
|
+
values: _defaultValues,
|
|
769
718
|
});
|
|
770
719
|
}
|
|
771
720
|
|
|
@@ -833,9 +782,9 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
833
782
|
const activedItem = el.querySelectorAll(`.list-group-item.${!MULTI_SEL_VALID ? 'active' : 'item-selected'}`)[0];
|
|
834
783
|
if (typeof activedItem !== 'undefined') {
|
|
835
784
|
|
|
836
|
-
const
|
|
837
|
-
const
|
|
838
|
-
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;
|
|
839
788
|
|
|
840
789
|
el.scrollTop = _latestScrollTop;
|
|
841
790
|
}
|
|
@@ -1180,7 +1129,7 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
1180
1129
|
|
|
1181
1130
|
|
|
1182
1131
|
if (MANUAL_REQ) {
|
|
1183
|
-
//
|
|
1132
|
+
// clear data
|
|
1184
1133
|
setOptionsData([]);
|
|
1185
1134
|
} else {
|
|
1186
1135
|
// restore data
|
|
@@ -1244,7 +1193,7 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
1244
1193
|
|
|
1245
1194
|
|
|
1246
1195
|
if (MANUAL_REQ) {
|
|
1247
|
-
//
|
|
1196
|
+
// clear data
|
|
1248
1197
|
setOptionsData([]);
|
|
1249
1198
|
} else {
|
|
1250
1199
|
// restore data
|
|
@@ -1724,7 +1673,7 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
1724
1673
|
|
|
1725
1674
|
}
|
|
1726
1675
|
|
|
1727
|
-
function
|
|
1676
|
+
function handleClearValue(event?: any) {
|
|
1728
1677
|
if (typeof event !== 'undefined') {
|
|
1729
1678
|
event.preventDefault();
|
|
1730
1679
|
event.stopPropagation(); /* REQUIRED */
|
|
@@ -1927,7 +1876,7 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
1927
1876
|
|
|
1928
1877
|
|
|
1929
1878
|
// Avoid selecting options that are disabled
|
|
1930
|
-
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)'));
|
|
1931
1880
|
const currentIndex = options.findIndex((e) => e === listRef.current.querySelector('.list-group-item.active'));
|
|
1932
1881
|
|
|
1933
1882
|
|
|
@@ -2064,7 +2013,6 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
2064
2013
|
|
|
2065
2014
|
useEffect(() => {
|
|
2066
2015
|
|
|
2067
|
-
|
|
2068
2016
|
// Call a function when the component has been rendered completely
|
|
2069
2017
|
//--------------
|
|
2070
2018
|
onLoad?.(selectInputRef.current, valueInputRef.current, finalRes(value));
|
|
@@ -2091,25 +2039,35 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
2091
2039
|
// Forced assignment does not depend on "fetch" or "firstRequestAutoExe"
|
|
2092
2040
|
// Don't use "value.value && value.label" directly, if it is empty, it will be treated as FALSE
|
|
2093
2041
|
if (chkValueExist(value)) {
|
|
2094
|
-
|
|
2042
|
+
// ++++++++++++++++++++
|
|
2043
|
+
// Single selection
|
|
2044
|
+
// ++++++++++++++++++++
|
|
2045
|
+
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
2095
2046
|
if (typeof value.value !== 'undefined' && value.value !== null) setControlValue(value.value as string);
|
|
2096
2047
|
if (typeof value.label !== 'undefined' && value.label !== null) setControlLabel(formatIndentVal(value.label, INDENT_LAST_PLACEHOLDER));
|
|
2097
2048
|
}
|
|
2098
2049
|
|
|
2099
|
-
|
|
2100
|
-
|
|
2050
|
+
// ++++++++++++++++++++
|
|
2051
|
+
// Multiple selection
|
|
2052
|
+
// ++++++++++++++++++++
|
|
2053
|
+
if (MULTI_SEL_VALID) {
|
|
2054
|
+
if (chkValueExist(value) && Array.isArray(value)) {
|
|
2101
2055
|
|
|
2102
|
-
|
|
2103
|
-
const _currentData:
|
|
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);
|
|
2104
2059
|
|
|
2105
2060
|
setControlArr({
|
|
2106
|
-
labels:
|
|
2107
|
-
values:
|
|
2061
|
+
labels: _defaultLabels,
|
|
2062
|
+
values: _defaultValues,
|
|
2108
2063
|
});
|
|
2109
2064
|
}
|
|
2110
2065
|
}
|
|
2111
2066
|
|
|
2112
2067
|
} else {
|
|
2068
|
+
// ++++++++++++++++++++
|
|
2069
|
+
// Single selection & Multiple selection
|
|
2070
|
+
// ++++++++++++++++++++
|
|
2113
2071
|
if (!FIRST_REQUEST_AUTO) {
|
|
2114
2072
|
setControlValue('');
|
|
2115
2073
|
setControlLabel('');
|
|
@@ -2157,6 +2115,50 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
2157
2115
|
}
|
|
2158
2116
|
}
|
|
2159
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
|
+
}
|
|
2159
|
+
}
|
|
2160
|
+
|
|
2161
|
+
|
|
2160
2162
|
}
|
|
2161
2163
|
|
|
2162
2164
|
}, []);
|
|
@@ -2200,6 +2202,42 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
2200
2202
|
>
|
|
2201
2203
|
|
|
2202
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
|
+
|
|
2203
2241
|
|
|
2204
2242
|
{!MULTI_SEL_VALID ? <>
|
|
2205
2243
|
|
|
@@ -2251,8 +2289,6 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
2251
2289
|
/>
|
|
2252
2290
|
|
|
2253
2291
|
</div>
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
2292
|
</> : null}
|
|
2257
2293
|
|
|
2258
2294
|
{/* ========== RESULT CONTAINER ========== */}
|
|
@@ -2297,7 +2333,6 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
2297
2333
|
*/}
|
|
2298
2334
|
{!MULTI_SEL_VALID ? <div className="custom-select-single__inputplaceholder-wrapper">
|
|
2299
2335
|
|
|
2300
|
-
|
|
2301
2336
|
{/* PLACEHOLDER */}
|
|
2302
2337
|
<div className="custom-select-single__inputplaceholder-inner" style={style}>
|
|
2303
2338
|
<input
|
|
@@ -2386,9 +2421,7 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
2386
2421
|
// ++++++++++++++++++++
|
|
2387
2422
|
*/}
|
|
2388
2423
|
{MULTI_SEL_VALID ? <div ref={rootMultiRef} className="custom-select-multi__inputplaceholder-wrapper">
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2424
|
+
|
|
2392
2425
|
{/* PLACEHOLDER */}
|
|
2393
2426
|
<div className="custom-select-multi__inputplaceholder-inner">
|
|
2394
2427
|
<div style={MULTI_SEL_ENTIRE_AREA_TRIGGER ? {pointerEvents: 'auto', cursor: 'pointer'} : undefined} onClick={(e: React.MouseEvent) => {
|
|
@@ -2700,26 +2733,26 @@ const Select = forwardRef((props: SelectProps, externalRef: any) => {
|
|
|
2700
2733
|
|
|
2701
2734
|
|
|
2702
2735
|
|
|
2703
|
-
{/*
|
|
2736
|
+
{/* CLEAR BUTTON (Only Single selection) */}
|
|
2704
2737
|
{!MULTI_SEL_VALID ? <>
|
|
2705
|
-
{
|
|
2738
|
+
{CLEAR_TRIGGER_VALID ? <>
|
|
2706
2739
|
<span
|
|
2707
2740
|
tabIndex={-1}
|
|
2708
|
-
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"
|
|
2709
2742
|
role="tab"
|
|
2710
2743
|
>
|
|
2711
2744
|
<span
|
|
2712
2745
|
tabIndex={-1}
|
|
2713
2746
|
className="btn btn-secondary"
|
|
2714
2747
|
dangerouslySetInnerHTML={{
|
|
2715
|
-
__html: `${
|
|
2748
|
+
__html: `${CLEAR_TRIGGER_LABEL}`
|
|
2716
2749
|
}}
|
|
2717
|
-
onClick={
|
|
2750
|
+
onClick={handleClearValue}
|
|
2718
2751
|
></span>
|
|
2719
2752
|
</span>
|
|
2720
2753
|
</> : null}
|
|
2721
2754
|
</> : null}
|
|
2722
|
-
{/* /
|
|
2755
|
+
{/* /CLEAR BUTTON (Only Single selection) */}
|
|
2723
2756
|
|
|
2724
2757
|
|
|
2725
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",
|