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.
@@ -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 CleanTriggerConfig {
90
+ export interface ClearTriggerConfig {
98
91
  valid: boolean;
99
- cleanValueLabel?: string;
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
- cleanTrigger?: CleanTriggerConfig;
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
- cleanTrigger,
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
- // clean trigger
322
- const CLEAN_TRIGGER_VALID = typeof cleanTrigger === 'undefined' ? false : (cleanTrigger ? cleanTrigger.valid : false);
323
- const CLEAN_TRIGGER_LABEL = cleanTrigger ? cleanTrigger.cleanValueLabel : 'Clean';
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
- handleCleanValue();
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 (MANUAL_REQ) {
560
-
561
- // If a manual action is used to trigger the request
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 (typeof defaultValue === 'undefined' || defaultValue === '') { // Do not use `init`, otherwise the query will revert to the default value if there is no value
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 ((typeof defaultValue === 'undefined' || defaultValue === '') && init) {
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 (typeof defaultValue !== 'undefined' && defaultValue !== '' && multiSelect?.data !== null) {
598
+ if (chkValueExist(defaultValue) && Array.isArray(defaultValue)) {
620
599
 
621
600
  // initialize default values of Multiple selection
622
- const _currentData: any = multiSelect?.data;
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: _currentData.labels,
626
- values: _currentData.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 (typeof defaultValue === 'undefined' || defaultValue === '') { // Do not use `init`, otherwise the query will revert to the default value if there is no value
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 ((typeof defaultValue === 'undefined' || defaultValue === '') && init) {
701
+ if (!chkValueExist(defaultValue) && init) {
750
702
  setControlArr({
751
703
  labels: [],
752
704
  values: []
753
705
  });
754
706
  }
755
707
 
756
- if (typeof defaultValue !== 'undefined' && defaultValue !== '' && multiSelect?.data !== null) {
708
+ if (chkValueExist(defaultValue) && Array.isArray(defaultValue)) {
757
709
 
758
710
  // initialize default values of Multiple selection
759
- const _currentData: any = multiSelect?.data;
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: _currentData.labels,
763
- values: _currentData.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 cleanItem = el.querySelector(`.list-group-item.${!MULTI_SEL_VALID ? 'custom-select-multi__control-option-item--clean' : 'custom-select-multi__control-option-item--select-all'}`);
857
- const cleanItemHeight = cleanItem === null ? 0 : cleanItem.clientHeight;
858
- const _latestScrollTop = activedItem.offsetTop - cleanItemHeight;
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
- // clean data
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
- // clean data
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 handleCleanValue(event?: any) {
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--clean)'));
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 ( value && typeof value === 'object' ) {
2111
- if (typeof value.value !== 'undefined' && value.value !== null) setControlValue(value.value as string);
2112
- if (typeof value.label !== 'undefined' && value.label !== null) setControlLabel(formatIndentVal(value.label, INDENT_LAST_PLACEHOLDER));
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
- {/* CLEAN BUTTON (Only Single selection) */}
2736
+ {/* CLEAR BUTTON (Only Single selection) */}
2687
2737
  {!MULTI_SEL_VALID ? <>
2688
- {CLEAN_TRIGGER_VALID ? <>
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--clean position-sticky top-0 z-3"
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: `${CLEAN_TRIGGER_LABEL}`
2748
+ __html: `${CLEAR_TRIGGER_LABEL}`
2699
2749
  }}
2700
- onClick={handleCleanValue}
2750
+ onClick={handleClearValue}
2701
2751
  ></span>
2702
2752
  </span>
2703
2753
  </> : null}
2704
2754
  </> : null}
2705
- {/* /CLEAN BUTTON (Only Single selection) */}
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.161",
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",