funda-ui 4.7.152 → 4.7.161

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.
Files changed (45) hide show
  1. package/CascadingSelect/index.js +13 -6
  2. package/CascadingSelectE2E/index.js +13 -6
  3. package/Chatbox/index.css +8 -0
  4. package/Chatbox/index.d.ts +1 -0
  5. package/Chatbox/index.js +18 -8
  6. package/Date/index.js +13 -6
  7. package/DropdownMenu/index.js +13 -6
  8. package/EventCalendar/index.js +42 -35
  9. package/EventCalendarTimeline/index.js +55 -41
  10. package/LiveSearch/index.css +33 -0
  11. package/LiveSearch/index.d.ts +1 -0
  12. package/LiveSearch/index.js +186 -91
  13. package/ModalDialog/index.js +13 -6
  14. package/RootPortal/index.d.ts +2 -1
  15. package/RootPortal/index.js +13 -6
  16. package/Select/index.js +81 -72
  17. package/Toast/index.js +13 -6
  18. package/Tooltip/index.js +13 -6
  19. package/lib/cjs/CascadingSelect/index.js +13 -6
  20. package/lib/cjs/CascadingSelectE2E/index.js +13 -6
  21. package/lib/cjs/Chatbox/index.d.ts +1 -0
  22. package/lib/cjs/Chatbox/index.js +18 -8
  23. package/lib/cjs/Date/index.js +13 -6
  24. package/lib/cjs/DropdownMenu/index.js +13 -6
  25. package/lib/cjs/EventCalendar/index.js +42 -35
  26. package/lib/cjs/EventCalendarTimeline/index.js +55 -41
  27. package/lib/cjs/LiveSearch/index.d.ts +1 -0
  28. package/lib/cjs/LiveSearch/index.js +186 -91
  29. package/lib/cjs/ModalDialog/index.js +13 -6
  30. package/lib/cjs/RootPortal/index.d.ts +2 -1
  31. package/lib/cjs/RootPortal/index.js +13 -6
  32. package/lib/cjs/Select/index.js +81 -72
  33. package/lib/cjs/Toast/index.js +13 -6
  34. package/lib/cjs/Tooltip/index.js +13 -6
  35. package/lib/css/Chatbox/index.css +8 -0
  36. package/lib/css/LiveSearch/index.css +33 -0
  37. package/lib/esm/Chatbox/index.scss +9 -0
  38. package/lib/esm/Chatbox/index.tsx +7 -4
  39. package/lib/esm/LiveSearch/index.scss +47 -0
  40. package/lib/esm/LiveSearch/index.tsx +120 -64
  41. package/lib/esm/RootPortal/index.tsx +14 -8
  42. package/lib/esm/SearchBar/index.tsx +1 -0
  43. package/lib/esm/Select/index.tsx +65 -64
  44. package/lib/esm/Textarea/index.tsx +1 -0
  45. package/package.json +1 -1
@@ -1,8 +1,12 @@
1
+
2
+
3
+
1
4
  /* ======================================================
2
5
  <!-- Live Search -->
3
6
  /* ====================================================== */
4
7
 
5
8
  .livesearch__wrapper {
9
+ position: relative;
6
10
 
7
11
  /*------ Search button ------*/
8
12
  .livesearch__wrapper-searchbtn {
@@ -14,6 +18,46 @@
14
18
  pointer-events: auto;
15
19
  }
16
20
 
21
+
22
+
23
+
24
+ /*------ Loader ------*/
25
+ .livesearch-loader {
26
+ position: absolute;
27
+ right: 0;
28
+ top: 50%;
29
+ margin-top: -6px;
30
+ pointer-events: none;
31
+ pointer-events: none;
32
+ z-index: 5;
33
+ width: 12px;
34
+ height: 12px;
35
+ text-align: center;
36
+ transform-origin: center;
37
+ transform: translate(-5px, 0) rotate(0);
38
+ animation: 1s linear infinite livesearch__spinner;
39
+
40
+ &.pos-offset {
41
+ right: 2rem;
42
+ }
43
+
44
+ svg {
45
+ vertical-align: top;
46
+
47
+ path {
48
+ fill: var(--cus-sel-loader-color);
49
+ }
50
+ }
51
+ }
52
+
53
+ @keyframes livesearch__spinner {
54
+ to {
55
+ transform: translate(-5px, 0) rotate(-360deg);
56
+ }
57
+ }
58
+
59
+
60
+
17
61
  }
18
62
 
19
63
 
@@ -35,9 +79,12 @@
35
79
  display: block !important;
36
80
  }
37
81
 
82
+
83
+ /*------ Options ------*/
38
84
  .livesearch__options-contentlist {
39
85
  overflow: hidden;
40
86
  overflow-y: auto;
87
+ background-color: var(--bs-list-group-bg);
41
88
 
42
89
  &.noscroll {
43
90
  overflow-y: hidden;
@@ -17,6 +17,7 @@ import {
17
17
  import { clsWrite, combinedCls } from 'funda-utils/dist/cjs/cls';
18
18
 
19
19
 
20
+
20
21
  export interface OptionConfig {
21
22
  disabled?: boolean;
22
23
  label: any;
@@ -39,6 +40,7 @@ export type LiveSearchProps = {
39
40
  appearance?: string;
40
41
  isSearchInput?: boolean;
41
42
  allowSpacingRetrive?: boolean;
43
+ loader?: React.ReactNode;
42
44
  value?: string;
43
45
  label?: React.ReactNode | string;
44
46
  name?: string;
@@ -100,6 +102,7 @@ const LiveSearch = forwardRef((props: LiveSearchProps, externalRef: any) => {
100
102
  appearance,
101
103
  isSearchInput,
102
104
  allowSpacingRetrive,
105
+ loader,
103
106
  readOnly,
104
107
  disabled,
105
108
  required,
@@ -128,7 +131,7 @@ const LiveSearch = forwardRef((props: LiveSearchProps, externalRef: any) => {
128
131
  tabIndex,
129
132
  data,
130
133
  autoShowOptions,
131
- fetchNoneInfo,
134
+ fetchNoneInfo = 'No match yet',
132
135
  fetchUpdate,
133
136
  fetchFuncAsync,
134
137
  fetchFuncMethod,
@@ -148,7 +151,9 @@ const LiveSearch = forwardRef((props: LiveSearchProps, externalRef: any) => {
148
151
  const DEPTH = depth || 1055; // the default value same as bootstrap
149
152
  const POS_OFFSET = 0;
150
153
  const EXCEEDED_SIDE_POS_OFFSET = Number(exceededSidePosOffset) || 15;
151
- const EMPTY_FOR_FETCH = typeof autoShowOptions === 'undefined' || autoShowOptions === false ? false : true;
154
+ const AUTO_SHOW_OPTIONS = typeof autoShowOptions !== 'undefined' && autoShowOptions === true ? true : false;
155
+ const MANUAL_REQ = typeof fetchTrigger !== 'undefined' && fetchTrigger === true ? true : false; // Manual requests
156
+
152
157
  const NO_MATCH_POPUP = typeof noMatchPopup === 'undefined' ? true : noMatchPopup;
153
158
  const WIN_WIDTH = typeof winWidth === 'function' ? winWidth() : winWidth ? winWidth : 'auto';
154
159
  const uniqueID = useComId();
@@ -158,11 +163,13 @@ const LiveSearch = forwardRef((props: LiveSearchProps, externalRef: any) => {
158
163
  const listRef = useRef<any>(null);
159
164
  const listContentRef = useRef<any>(null);
160
165
  const optionsRes = options ? (isJSON(options) ? JSON.parse(options as string) : options) : [];
166
+
161
167
 
162
168
  // return a array of options
163
169
  let staticOptionsData: OptionConfig[] = optionsRes;
164
170
 
165
171
  //
172
+ const [controlTempValue, setControlTempValue] = useState<string | null>(null); // Storage for temporary input
166
173
  const [firstFetch, setFirstFetch] = useState<boolean>(false);
167
174
  const [dataInit, setOrginalDataInit] = useState<any[]>(staticOptionsData);
168
175
  const [orginalData, setOrginalData] = useState<any[]>([]);
@@ -170,7 +177,13 @@ const LiveSearch = forwardRef((props: LiveSearchProps, externalRef: any) => {
170
177
  const [isOpen, setIsOpen] = useState<boolean>(false);
171
178
  const [hasErr, setHasErr] = useState<boolean>(false);
172
179
  const [componentFirstLoad, setComponentFirstLoad] = useState<boolean>(false);
180
+ const [reqProgress, setReqProgress] = useState<boolean>(false);
181
+
173
182
 
183
+ // Mark whether it is out of focus
184
+ // Fixed the issue that caused the pop-up window to still display due to
185
+ // the delayed close in handleBlur and the timing of the call to popwinPosInit
186
+ const isBlurringRef = useRef<boolean>(false);
174
187
 
175
188
  //performance
176
189
  const handleChangeFetchSafe = useDebounce((e: any) => {
@@ -183,9 +196,11 @@ const LiveSearch = forwardRef((props: LiveSearchProps, externalRef: any) => {
183
196
  popupRef,
184
197
  () => ({
185
198
  close: () => {
186
- setIsOpen(false);
187
199
  cancel();
188
- }
200
+ },
201
+ open: () => {
202
+ activate();
203
+ },
189
204
  }),
190
205
  [popupRef],
191
206
  );
@@ -200,6 +215,7 @@ const LiveSearch = forwardRef((props: LiveSearchProps, externalRef: any) => {
200
215
  getLatestVal: () => {
201
216
  return changedVal || '';
202
217
  },
218
+
203
219
  clear: (cb?: any) => {
204
220
  setChangedVal('');
205
221
  cb?.();
@@ -230,7 +246,6 @@ const LiveSearch = forwardRef((props: LiveSearchProps, externalRef: any) => {
230
246
  },
231
247
  handle: (event: any) => {
232
248
  // cancel
233
- setIsOpen(false);
234
249
  cancel();
235
250
  }
236
251
  }, [isOpen, rootRef, listRef]);
@@ -248,10 +263,14 @@ const LiveSearch = forwardRef((props: LiveSearchProps, externalRef: any) => {
248
263
  });
249
264
 
250
265
 
251
-
252
266
  function popwinPosInit(showAct: boolean = true) {
253
267
  if (listContentRef.current === null || inputRef.current === null) return;
254
268
 
269
+ // If it is out of focus, do not perform position initialization
270
+ if (isBlurringRef.current && !MANUAL_REQ) return;
271
+
272
+
273
+ //
255
274
  const contentHeightOffset = 80;
256
275
  let contentMaxHeight = 0;
257
276
 
@@ -447,9 +466,7 @@ const LiveSearch = forwardRef((props: LiveSearchProps, externalRef: any) => {
447
466
  });
448
467
  }
449
468
 
450
-
451
469
  if (query) {
452
-
453
470
  const _oparams: any[] = fetchFuncMethodParams || [];
454
471
  const _params: any[] = _oparams.map((item: any) => item !== '$QUERY_STRING' ? item : val);
455
472
  const response: any = await fetchData((_params).join(','));
@@ -470,9 +487,12 @@ const LiveSearch = forwardRef((props: LiveSearchProps, externalRef: any) => {
470
487
 
471
488
  setChangedVal(val);
472
489
 
490
+ // update temporary value
491
+ setControlTempValue(val);
492
+
473
493
  //
474
- if (!fetchTrigger) {
475
- matchData(val, fetchUpdate, EMPTY_FOR_FETCH).then((response: any) => {
494
+ if (!MANUAL_REQ) {
495
+ matchData(val, fetchUpdate, AUTO_SHOW_OPTIONS).then((response: any) => {
476
496
 
477
497
  setOrginalData(response);
478
498
 
@@ -508,13 +528,26 @@ const LiveSearch = forwardRef((props: LiveSearchProps, externalRef: any) => {
508
528
  }
509
529
 
510
530
  function cancel() {
531
+ // hide list
532
+ setIsOpen(false);
533
+
534
+
535
+ //
511
536
  setOrginalData([]);
512
537
  popwinPosHide();
538
+
539
+ // update temporary value
540
+ setControlTempValue(null);
541
+
513
542
  }
514
543
 
515
544
 
516
545
  async function fetchData(params: any) {
517
546
 
547
+ // update request process
548
+ setReqProgress(true);
549
+
550
+ //
518
551
  if (typeof fetchFuncAsync === 'object') {
519
552
 
520
553
  const response: any = await fetchFuncAsync[`${fetchFuncMethod}`](...params.split(','));
@@ -549,9 +582,15 @@ const LiveSearch = forwardRef((props: LiveSearchProps, externalRef: any) => {
549
582
  }, 500);
550
583
  }
551
584
 
585
+ // update request process
586
+ setReqProgress(false);
552
587
 
553
588
  return _ORGIN_DATA;
554
589
  } else {
590
+
591
+ // update request process
592
+ setReqProgress(false);
593
+
555
594
  return [];
556
595
  }
557
596
 
@@ -572,13 +611,14 @@ const LiveSearch = forwardRef((props: LiveSearchProps, externalRef: any) => {
572
611
 
573
612
  } else {
574
613
  const _curData = typeof el.target !== 'undefined' ? el.target.dataset.itemdata : el.dataset.itemdata;
614
+ if (typeof _curData === 'undefined') return;
575
615
 
576
616
  const _data = JSON.parse(_curData);
577
617
 
578
618
  let res: any = [];
579
619
 
580
- if (!EMPTY_FOR_FETCH) {
581
- res = await matchData(inputRef.current.value, false, EMPTY_FOR_FETCH);
620
+ if (!AUTO_SHOW_OPTIONS) {
621
+ res = await matchData(inputRef.current.value, false, AUTO_SHOW_OPTIONS);
582
622
  } else {
583
623
  res = dataInit;
584
624
  }
@@ -589,16 +629,15 @@ const LiveSearch = forwardRef((props: LiveSearchProps, externalRef: any) => {
589
629
 
590
630
 
591
631
  // cancel
592
- setIsOpen(false);
593
632
  cancel();
594
633
  }
595
634
 
596
635
  async function handleFetch() {
597
- if (fetchTrigger) {
598
- const res: any = await matchData(changedVal, fetchUpdate, EMPTY_FOR_FETCH);
636
+ if (MANUAL_REQ) {
637
+
638
+ const res: any = await matchData(changedVal, true, true);
599
639
  setOrginalData(res);
600
640
 
601
-
602
641
  //
603
642
  setIsOpen(res.length === 0 ? true : false);
604
643
 
@@ -610,53 +649,62 @@ const LiveSearch = forwardRef((props: LiveSearchProps, externalRef: any) => {
610
649
  }
611
650
  }
612
651
 
613
- function handleClick() {
652
+ function activate() {
653
+ if (AUTO_SHOW_OPTIONS) {
654
+ setOrginalData(dataInit);
655
+ setIsOpen(true);
656
+ }
614
657
 
615
- if (!isOpen) {
616
- if (EMPTY_FOR_FETCH) {
617
- setOrginalData(dataInit);
618
- setIsOpen(true);
619
- }
658
+ // window position
659
+ setTimeout(() => {
660
+ popwinPosInit();
661
+ }, 0);
662
+ }
620
663
 
621
- // window position
622
- setTimeout(() => {
623
- popwinPosInit();
624
- }, 0);
664
+ function handleShowList() {
665
+
666
+ // Reset the out-of-focus marker
667
+ isBlurringRef.current = false;
668
+
669
+ if (!isOpen) {
670
+ activate();
625
671
  } else {
626
672
  // cancel
627
- setIsOpen(false);
628
673
  cancel();
629
674
  }
630
675
 
631
676
 
632
-
677
+ // Every time the input changes or the search button is clicked, a data request will be triggered
678
+ if (
679
+ (!AUTO_SHOW_OPTIONS && (controlTempValue === '' || controlTempValue === null)) ||
680
+ MANUAL_REQ
681
+ ) {
682
+ setTimeout(() => {
683
+ popwinPosHide();
684
+ }, 0);
685
+ }
686
+
687
+
633
688
  onClick?.(inputRef.current, listRef.current)
634
689
  }
635
690
 
636
691
 
637
692
  function handleBlur(e: any) {
638
693
 
639
- setIsOpen(false);
640
- if (!fetchTrigger) {
641
- setTimeout(() => {
642
-
643
- //
644
- onBlur?.(inputRef.current, listRef.current);
645
-
646
- //
647
- cancel();
694
+ // Set the out-of-focus marker
695
+ isBlurringRef.current = true;
648
696
 
649
- }, 300);
650
- }
697
+ setTimeout(() => {
698
+ // cancel
699
+ cancel(); // The delay is to avoid losing focus and not being able to click on the option
651
700
 
652
- }
701
+ //
702
+ onBlur?.(inputRef.current, listRef.current);
703
+ }, 300);
653
704
 
654
- function handleMouseLeaveTrigger() {
655
- setIsOpen(false);
656
705
  }
657
706
 
658
707
 
659
-
660
708
  function optionFocus(type: string) {
661
709
 
662
710
  return new Promise(function (resolve) {
@@ -773,15 +821,17 @@ const LiveSearch = forwardRef((props: LiveSearchProps, externalRef: any) => {
773
821
 
774
822
  // data init
775
823
  //--------------
776
- const _oparams: any[] = fetchFuncMethodParams || [];
777
- const _params: any[] = _oparams.map((item: any) => item !== '$QUERY_STRING' ? item : (fetchTrigger && !fetchUpdate) ? '' : (fetchUpdate ? QUERY_STRING_PLACEHOLDER : (fetchTrigger ? QUERY_STRING_PLACEHOLDER : '')));
778
- if (!firstFetch) {
779
- fetchData((_params).join(','));
780
- setFirstFetch(true); // avoid triggering two data requests if the input value has not changed
824
+ // If automatic request enabled, do not send them for the first time
825
+ if (AUTO_SHOW_OPTIONS) {
826
+ const _oparams: any[] = fetchFuncMethodParams || [];
827
+ const _params: any[] = _oparams.map((item: any) => item !== '$QUERY_STRING' ? item : (MANUAL_REQ && !fetchUpdate) ? '' : (fetchUpdate ? QUERY_STRING_PLACEHOLDER : (MANUAL_REQ ? QUERY_STRING_PLACEHOLDER : '')));
828
+ if (!firstFetch) {
829
+ fetchData((_params).join(','));
830
+ setFirstFetch(true); // avoid triggering two data requests if the input value has not changed
831
+ }
781
832
  }
782
833
 
783
834
 
784
-
785
835
  }, [value, data]);
786
836
 
787
837
 
@@ -799,7 +849,6 @@ const LiveSearch = forwardRef((props: LiveSearchProps, externalRef: any) => {
799
849
  'active': isOpen
800
850
  }
801
851
  )}
802
- onMouseLeave={handleMouseLeaveTrigger}
803
852
  onKeyDown={handleKeyPressed}
804
853
  >
805
854
 
@@ -839,8 +888,8 @@ const LiveSearch = forwardRef((props: LiveSearchProps, externalRef: any) => {
839
888
  }}
840
889
  onBlur={handleBlur}
841
890
  onSubmit={handleFetch}
842
- onClick={handleClick}
843
- icon={hideIcon ? '' : (!fetchTrigger ? '' : icon)}
891
+ onClick={handleShowList}
892
+ icon={hideIcon ? '' : (!MANUAL_REQ ? '' : icon)}
844
893
  btnId={btnId}
845
894
  autoComplete={typeof autoComplete === 'undefined' ? 'off' : autoComplete}
846
895
  autoCapitalize={typeof autoCapitalize === 'undefined' ? 'off' : autoCapitalize}
@@ -878,12 +927,12 @@ const LiveSearch = forwardRef((props: LiveSearchProps, externalRef: any) => {
878
927
  'd-none': (orginalData && orginalData.length === 0) && !NO_MATCH_POPUP
879
928
  }
880
929
  )}
881
- style={{ backgroundColor: 'var(--bs-list-group-bg)' }}
882
930
  ref={listContentRef}
883
931
  >
884
932
  <div className="livesearch__options-contentlist-inner">
885
933
 
886
934
 
935
+
887
936
  {/* NO MATCH */}
888
937
  {orginalData && orginalData.length === 0 ? <>
889
938
  <button
@@ -891,7 +940,7 @@ const LiveSearch = forwardRef((props: LiveSearchProps, externalRef: any) => {
891
940
  type="button"
892
941
  className="list-group-item list-group-item-action border-top-0 border-bottom-0 no-match livesearch__control-option-item--nomatch"
893
942
  disabled
894
- >{fetchNoneInfo || 'No match yet'}</button>
943
+ >{fetchNoneInfo}</button>
895
944
  </> : null}
896
945
  {/* /NO MATCH */}
897
946
 
@@ -940,17 +989,24 @@ const LiveSearch = forwardRef((props: LiveSearchProps, externalRef: any) => {
940
989
  </> : null}
941
990
 
942
991
 
992
+ {/* LOADER */}
993
+ {reqProgress ? <><div className={`livesearch-loader ${!hideIcon ? 'pos-offset' : ''}`}>{loader || <svg height="12px" width="12px" viewBox="0 0 512 512"><g><path fill="inherit" d="M256,0c-23.357,0-42.297,18.932-42.297,42.288c0,23.358,18.94,42.288,42.297,42.288c23.357,0,42.279-18.93,42.279-42.288C298.279,18.932,279.357,0,256,0z" /><path fill="inherit" d="M256,427.424c-23.357,0-42.297,18.931-42.297,42.288C213.703,493.07,232.643,512,256,512c23.357,0,42.279-18.93,42.279-42.288C298.279,446.355,279.357,427.424,256,427.424z" /><path fill="inherit" d="M74.974,74.983c-16.52,16.511-16.52,43.286,0,59.806c16.52,16.52,43.287,16.52,59.806,0c16.52-16.511,16.52-43.286,0-59.806C118.261,58.463,91.494,58.463,74.974,74.983z" /><path fill="inherit" d="M377.203,377.211c-16.503,16.52-16.503,43.296,0,59.815c16.519,16.52,43.304,16.52,59.806,0c16.52-16.51,16.52-43.295,0-59.815C420.489,360.692,393.722,360.7,377.203,377.211z" /><path fill="inherit" d="M84.567,256c0.018-23.348-18.922-42.279-42.279-42.279c-23.357-0.009-42.297,18.932-42.279,42.288c-0.018,23.348,18.904,42.279,42.279,42.279C65.645,298.288,84.567,279.358,84.567,256z" /><path fill="inherit" d="M469.712,213.712c-23.357,0-42.279,18.941-42.297,42.288c0,23.358,18.94,42.288,42.297,42.297c23.357,0,42.297-18.94,42.279-42.297C512.009,232.652,493.069,213.712,469.712,213.712z" /><path fill="inherit" d="M74.991,377.22c-16.519,16.511-16.519,43.296,0,59.806c16.503,16.52,43.27,16.52,59.789,0c16.52-16.519,16.52-43.295,0-59.815C118.278,360.692,91.511,360.692,74.991,377.22z" /><path fill="inherit" d="M437.026,134.798c16.52-16.52,16.52-43.304,0-59.824c-16.519-16.511-43.304-16.52-59.823,0c-16.52,16.52-16.503,43.295,0,59.815C393.722,151.309,420.507,151.309,437.026,134.798z" /></g></svg>}</div></> : null}
994
+ {/* /LOADER */}
995
+
996
+
943
997
  {hideIcon ? null : <>
944
- {!fetchTrigger ? <>
945
- <span className="livesearch__wrapper-searchbtn">
946
- <button tabIndex={-1} type="button" className="btn border-end-0 rounded-pill" style={{ pointerEvents: 'none' }}>
947
- <svg width="1em" height="1em" fill="#a5a5a5" viewBox="0 0 16 16">
948
- <path d="M12.027 9.92L16 13.95 14 16l-4.075-3.976A6.465 6.465 0 0 1 6.5 13C2.91 13 0 10.083 0 6.5 0 2.91 2.917 0 6.5 0 10.09 0 13 2.917 13 6.5a6.463 6.463 0 0 1-.973 3.42zM1.997 6.452c0 2.48 2.014 4.5 4.5 4.5 2.48 0 4.5-2.015 4.5-4.5 0-2.48-2.015-4.5-4.5-4.5-2.48 0-4.5 2.014-4.5 4.5z" fillRule="evenodd" />
949
- </svg>
950
- </button>
951
-
952
- </span>
953
- </> : null}
998
+ <span className="livesearch__wrapper-searchbtn">
999
+ <button tabIndex={-1} type="button" className="btn border-end-0 rounded-pill" style={MANUAL_REQ ? undefined :{pointerEvents: 'none'}} onClick={(e: React.MouseEvent) => {
1000
+ e.preventDefault();
1001
+ e.stopPropagation();
1002
+ handleFetch();
1003
+ }}>
1004
+ <svg width="1em" height="1em" fill="#a5a5a5" viewBox="0 0 16 16">
1005
+ <path d="M12.027 9.92L16 13.95 14 16l-4.075-3.976A6.465 6.465 0 0 1 6.5 13C2.91 13 0 10.083 0 6.5 0 2.91 2.917 0 6.5 0 10.09 0 13 2.917 13 6.5a6.463 6.463 0 0 1-.973 3.42zM1.997 6.452c0 2.48 2.014 4.5 4.5 4.5 2.48 0 4.5-2.015 4.5-4.5 0-2.48-2.015-4.5-4.5-4.5-2.48 0-4.5 2.014-4.5 4.5z" fillRule="evenodd" />
1006
+ </svg>
1007
+ </button>
1008
+
1009
+ </span>
954
1010
  </>}
955
1011
 
956
1012
 
@@ -6,13 +6,15 @@ export type RootPortalProps = {
6
6
  containerClassName?: string;
7
7
  children?: React.ReactNode;
8
8
  show?: boolean;
9
+ usePortal?: boolean;
9
10
  };
10
11
 
11
12
  const RootPortal = (props: RootPortalProps) => {
12
13
  const {
13
14
  containerClassName,
14
15
  show,
15
- children
16
+ children,
17
+ usePortal = true
16
18
  } = props;
17
19
 
18
20
  const containerRef = useRef<HTMLElement>();
@@ -25,19 +27,23 @@ const RootPortal = (props: RootPortalProps) => {
25
27
  // Use `containerRef.current` to ensure the correctness of the nextjs framework. It may report an error document as undefined
26
28
 
27
29
  useEffect(() => {
28
-
29
- containerRef.current = document.createElement('div');
30
- containerRef.current.className = `root-portal-container ${containerClassName || ''}`;
31
- document.body.appendChild(containerRef.current);
32
-
30
+ if (usePortal) {
31
+ containerRef.current = document.createElement('div');
32
+ containerRef.current.className = `root-portal-container ${containerClassName || ''}`;
33
+ document.body.appendChild(containerRef.current);
34
+ }
33
35
 
34
36
  return () => {
35
- if (containerRef.current) {
37
+ if (usePortal && containerRef.current) {
36
38
  containerRef.current.remove();
37
39
  }
38
40
  };
39
- }, []);
41
+ }, [usePortal]);
40
42
 
43
+ if (!usePortal) {
44
+ return show ? <>{children}</> : null;
45
+ }
46
+
41
47
  return (
42
48
  <>
43
49
  {containerRef.current && show && createPortal(
@@ -4,6 +4,7 @@ import useComId from 'funda-utils/dist/cjs/useComId';
4
4
  import { clsWrite, combinedCls } from 'funda-utils/dist/cjs/cls';
5
5
 
6
6
 
7
+
7
8
  export type SearchBarProps = {
8
9
  wrapperClassName?: string;
9
10
  controlClassName?: string;