funda-ui 4.7.150 → 4.7.155

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.
@@ -110,7 +110,9 @@ __webpack_require__.r(__webpack_exports__);
110
110
  var RootPortal = function RootPortal(props) {
111
111
  var containerClassName = props.containerClassName,
112
112
  show = props.show,
113
- children = props.children;
113
+ children = props.children,
114
+ _props$usePortal = props.usePortal,
115
+ usePortal = _props$usePortal === void 0 ? true : _props$usePortal;
114
116
  var containerRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)();
115
117
 
116
118
  // Move HTML templates to tag end body </body>
@@ -121,15 +123,20 @@ var RootPortal = function RootPortal(props) {
121
123
  // Use `containerRef.current` to ensure the correctness of the nextjs framework. It may report an error document as undefined
122
124
 
123
125
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(function () {
124
- containerRef.current = document.createElement('div');
125
- containerRef.current.className = "root-portal-container ".concat(containerClassName || '');
126
- document.body.appendChild(containerRef.current);
126
+ if (usePortal) {
127
+ containerRef.current = document.createElement('div');
128
+ containerRef.current.className = "root-portal-container ".concat(containerClassName || '');
129
+ document.body.appendChild(containerRef.current);
130
+ }
127
131
  return function () {
128
- if (containerRef.current) {
132
+ if (usePortal && containerRef.current) {
129
133
  containerRef.current.remove();
130
134
  }
131
135
  };
132
- }, []);
136
+ }, [usePortal]);
137
+ if (!usePortal) {
138
+ return show ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, children) : null;
139
+ }
133
140
  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, containerRef.current && show && /*#__PURE__*/(0,react_dom__WEBPACK_IMPORTED_MODULE_1__.createPortal)(children, containerRef.current));
134
141
  };
135
142
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (RootPortal);
@@ -171,7 +171,9 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
171
171
  var RootPortal = function RootPortal(props) {
172
172
  var containerClassName = props.containerClassName,
173
173
  show = props.show,
174
- children = props.children;
174
+ children = props.children,
175
+ _props$usePortal = props.usePortal,
176
+ usePortal = _props$usePortal === void 0 ? true : _props$usePortal;
175
177
  var containerRef = (0, react__WEBPACK_IMPORTED_MODULE_0__.useRef)();
176
178
 
177
179
  // Move HTML templates to tag end body </body>
@@ -182,15 +184,20 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
182
184
  // Use `containerRef.current` to ensure the correctness of the nextjs framework. It may report an error document as undefined
183
185
 
184
186
  (0, react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(function () {
185
- containerRef.current = document.createElement('div');
186
- containerRef.current.className = "root-portal-container ".concat(containerClassName || '');
187
- document.body.appendChild(containerRef.current);
187
+ if (usePortal) {
188
+ containerRef.current = document.createElement('div');
189
+ containerRef.current.className = "root-portal-container ".concat(containerClassName || '');
190
+ document.body.appendChild(containerRef.current);
191
+ }
188
192
  return function () {
189
- if (containerRef.current) {
193
+ if (usePortal && containerRef.current) {
190
194
  containerRef.current.remove();
191
195
  }
192
196
  };
193
- }, []);
197
+ }, [usePortal]);
198
+ if (!usePortal) {
199
+ return show ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(react__WEBPACK_IMPORTED_MODULE_0___default().Fragment, null, children) : null;
200
+ }
194
201
  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(react__WEBPACK_IMPORTED_MODULE_0___default().Fragment, null, containerRef.current && show && /*#__PURE__*/(0, react_dom__WEBPACK_IMPORTED_MODULE_1__.createPortal)(children, containerRef.current));
195
202
  };
196
203
  /* harmony default export */
@@ -171,7 +171,9 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
171
171
  var RootPortal = function RootPortal(props) {
172
172
  var containerClassName = props.containerClassName,
173
173
  show = props.show,
174
- children = props.children;
174
+ children = props.children,
175
+ _props$usePortal = props.usePortal,
176
+ usePortal = _props$usePortal === void 0 ? true : _props$usePortal;
175
177
  var containerRef = (0, react__WEBPACK_IMPORTED_MODULE_0__.useRef)();
176
178
 
177
179
  // Move HTML templates to tag end body </body>
@@ -182,15 +184,20 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
182
184
  // Use `containerRef.current` to ensure the correctness of the nextjs framework. It may report an error document as undefined
183
185
 
184
186
  (0, react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(function () {
185
- containerRef.current = document.createElement('div');
186
- containerRef.current.className = "root-portal-container ".concat(containerClassName || '');
187
- document.body.appendChild(containerRef.current);
187
+ if (usePortal) {
188
+ containerRef.current = document.createElement('div');
189
+ containerRef.current.className = "root-portal-container ".concat(containerClassName || '');
190
+ document.body.appendChild(containerRef.current);
191
+ }
188
192
  return function () {
189
- if (containerRef.current) {
193
+ if (usePortal && containerRef.current) {
190
194
  containerRef.current.remove();
191
195
  }
192
196
  };
193
- }, []);
197
+ }, [usePortal]);
198
+ if (!usePortal) {
199
+ return show ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(react__WEBPACK_IMPORTED_MODULE_0___default().Fragment, null, children) : null;
200
+ }
194
201
  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(react__WEBPACK_IMPORTED_MODULE_0___default().Fragment, null, containerRef.current && show && /*#__PURE__*/(0, react_dom__WEBPACK_IMPORTED_MODULE_1__.createPortal)(children, containerRef.current));
195
202
  };
196
203
  /* harmony default export */
@@ -171,7 +171,9 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
171
171
  var RootPortal = function RootPortal(props) {
172
172
  var containerClassName = props.containerClassName,
173
173
  show = props.show,
174
- children = props.children;
174
+ children = props.children,
175
+ _props$usePortal = props.usePortal,
176
+ usePortal = _props$usePortal === void 0 ? true : _props$usePortal;
175
177
  var containerRef = (0, react__WEBPACK_IMPORTED_MODULE_0__.useRef)();
176
178
 
177
179
  // Move HTML templates to tag end body </body>
@@ -182,15 +184,20 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
182
184
  // Use `containerRef.current` to ensure the correctness of the nextjs framework. It may report an error document as undefined
183
185
 
184
186
  (0, react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(function () {
185
- containerRef.current = document.createElement('div');
186
- containerRef.current.className = "root-portal-container ".concat(containerClassName || '');
187
- document.body.appendChild(containerRef.current);
187
+ if (usePortal) {
188
+ containerRef.current = document.createElement('div');
189
+ containerRef.current.className = "root-portal-container ".concat(containerClassName || '');
190
+ document.body.appendChild(containerRef.current);
191
+ }
188
192
  return function () {
189
- if (containerRef.current) {
193
+ if (usePortal && containerRef.current) {
190
194
  containerRef.current.remove();
191
195
  }
192
196
  };
193
- }, []);
197
+ }, [usePortal]);
198
+ if (!usePortal) {
199
+ return show ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(react__WEBPACK_IMPORTED_MODULE_0___default().Fragment, null, children) : null;
200
+ }
194
201
  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement(react__WEBPACK_IMPORTED_MODULE_0___default().Fragment, null, containerRef.current && show && /*#__PURE__*/(0, react_dom__WEBPACK_IMPORTED_MODULE_1__.createPortal)(children, containerRef.current));
195
202
  };
196
203
  /* harmony default export */
@@ -154,6 +154,7 @@
154
154
  right: 0;
155
155
  z-index: 1031;
156
156
  height: var(--custom-chatbox-h);
157
+ /* disable popup */
157
158
  /* message list */
158
159
  /* dot loading */
159
160
  /* control area */
@@ -164,6 +165,12 @@
164
165
  /* default questions */
165
166
  /* Tooltip */
166
167
  }
168
+ .custom-chatbox-container.popup-none {
169
+ position: relative;
170
+ bottom: auto;
171
+ right: auto;
172
+ box-shadow: none;
173
+ }
167
174
  .custom-chatbox-container details {
168
175
  font-style: italic;
169
176
  margin: 0;
@@ -375,6 +382,7 @@
375
382
  border: 1px solid var(--custom-chatbox-gray-color);
376
383
  border-radius: 0.35rem;
377
384
  transition: all 0.3s ease;
385
+ background: var(--custom-chatbox-input-bg);
378
386
  }
379
387
  .custom-chatbox-container .msgcontrol img, .custom-chatbox-container .msgcontrol svg, .custom-chatbox-container .msgcontrol video, .custom-chatbox-container .msgcontrol canvas, .custom-chatbox-container .msgcontrol audio, .custom-chatbox-container .msgcontrol iframe, .custom-chatbox-container .msgcontrol embed, .custom-chatbox-container .msgcontrol object {
380
388
  display: inline;
@@ -189,6 +189,14 @@
189
189
  z-index: 1031;
190
190
  height: var(--custom-chatbox-h);
191
191
 
192
+ /* disable popup */
193
+ &.popup-none {
194
+ position: relative;
195
+ bottom: auto;
196
+ right: auto;
197
+ box-shadow: none;
198
+ }
199
+
192
200
  details {
193
201
  font-style: italic;
194
202
  margin: 0;
@@ -449,6 +457,7 @@
449
457
  border: 1px solid var(--custom-chatbox-gray-color);
450
458
  border-radius: 0.35rem;
451
459
  transition: all 0.3s ease;
460
+ background: var(--custom-chatbox-input-bg);
452
461
 
453
462
  img, svg, video, canvas, audio, iframe, embed, object {
454
463
  display: inline;
@@ -12,8 +12,6 @@ import useClickOutside from 'funda-utils/dist/cjs/useClickOutside';
12
12
  import { htmlEncode } from 'funda-utils/dist/cjs/sanitize';
13
13
 
14
14
 
15
-
16
-
17
15
  // loader
18
16
  import PureLoader from './PureLoader';
19
17
  import TypingEffect from "./TypingEffect";
@@ -46,16 +44,24 @@ export type QuestionData = {
46
44
  list: Array<string>;
47
45
  };
48
46
 
47
+ export type SelectedOption = {
48
+ [key: string]: string | number;
49
+ curIndex: number;
50
+ curValue: string;
51
+ };
49
52
 
50
53
  export interface FloatingButton {
51
54
  label: string; // HTML string
52
55
  value: string;
53
56
  onClick: string;
57
+ active?: boolean; // Specify if the button should be active by default
54
58
  isSelect?: boolean; // Mark whether it is a drop-down selection button
55
59
  dynamicOptions?: boolean; // Mark whether to use dynamic options
60
+ defaultSelected?: number; // Specify default selected option index
56
61
  [key: string]: any; // Allows dynamic `onSelect__<number>` attributes, such as `onSelect__1`, `onSelect__2`, ...
57
62
  }
58
63
 
64
+
59
65
  export interface FloatingButtonSelectOption {
60
66
  label: string;
61
67
  value: string;
@@ -122,6 +128,7 @@ export type ChatboxProps = {
122
128
  defaultQuestions?: QuestionData;
123
129
  showCopyBtn?: boolean; // Whether to show copy button for each reply
124
130
  autoCopyReply?: boolean; // Whether to automatically copy reply to clipboard
131
+ usePopUp?: boolean;
125
132
  customRequest?: CustomRequestFunction;
126
133
  renderParser?: (input: string) => Promise<string>;
127
134
  requestBodyFormatter?: (body: any, contextData: Record<string, any>, conversationHistory: MessageDetail[]) => Promise<Record<string, any>>;
@@ -178,6 +185,11 @@ const Chatbox = (props: ChatboxProps) => {
178
185
  const [enableStreamMode, setEnableStreamMode] = useState<boolean>(true);
179
186
  const animatedMessagesRef = useRef<Set<number>>(new Set()); // Add a ref to keep track of messages that have already been animated
180
187
 
188
+ // Keep track of whether the default values have been initialized
189
+ const [initializedDefaults, setInitializedDefaults] = useState<Record<string, boolean>>({});
190
+
191
+
192
+
181
193
  //
182
194
  const timer = useRef<any>(null);
183
195
 
@@ -307,6 +319,7 @@ const Chatbox = (props: ChatboxProps) => {
307
319
  toolkitButtons,
308
320
  newChatButton,
309
321
  maxHistoryLength,
322
+ usePopUp,
310
323
  customRequest,
311
324
  onQuestionClick,
312
325
  onCopyCallback,
@@ -387,6 +400,7 @@ const Chatbox = (props: ChatboxProps) => {
387
400
  maxHistoryLength,
388
401
  toolkitButtons,
389
402
  newChatButton,
403
+ usePopUp,
390
404
  customRequest,
391
405
  onQuestionClick,
392
406
  onCopyCallback,
@@ -508,6 +522,19 @@ const Chatbox = (props: ChatboxProps) => {
508
522
  return newState;
509
523
  });
510
524
  };
525
+
526
+ // The onClick action specifically used to perform the default options
527
+ const executeDefaultOptionAction = async (actionStr: string, buttonId: string) => {
528
+ try {
529
+ const actionFn = new Function('method', 'isActive', 'button', actionStr);
530
+ // To perform the action, pass false as the "isActive" parameter, as this is the default option
531
+ await actionFn(exposedMethods(), false, document.getElementById(buttonId));
532
+ } catch (error) {
533
+ console.error('Error executing default option action:', error);
534
+ }
535
+ };
536
+
537
+
511
538
  const executeButtonAction = async (actionStr: string, buttonId: string, buttonElement: HTMLButtonElement) => {
512
539
  try {
513
540
  const actionFn = new Function('method', 'isActive', 'button', actionStr);
@@ -547,7 +574,11 @@ const Chatbox = (props: ChatboxProps) => {
547
574
 
548
575
 
549
576
  // options
550
- const [selectedOpt, setSelectedOpt] = useState<Record<string, string | number>>({});
577
+ const [selectedOpt, setSelectedOpt] = useState<SelectedOption>({
578
+ curIndex: -1,
579
+ curValue: ''
580
+ });
581
+
551
582
  // Store dynamic options
552
583
  const [dynamicOptions, setDynamicOptions] = useState<Record<string, FloatingButtonSelectOption[]>>({});
553
584
 
@@ -575,7 +606,7 @@ const Chatbox = (props: ChatboxProps) => {
575
606
  return options;
576
607
  };
577
608
 
578
- const handleExecuteButtonSelect = (buttonId: string, option: FloatingButtonSelectOption, index: number, value: string) => {
609
+ const handleExecuteButtonSelect = (buttonId: string, option: FloatingButtonSelectOption, index: number, value: string, isDefaultSelection: boolean = false) => {
579
610
 
580
611
  if (option.value === "cancel") {
581
612
  setSelectedOpt(prev => {
@@ -597,11 +628,15 @@ const Chatbox = (props: ChatboxProps) => {
597
628
  }));
598
629
  }
599
630
 
631
+
632
+ // The button action is performed and the drop-down menu is closed only when it is not the default selection
633
+ if (!isDefaultSelection) {
634
+ executeButtonAction(option.onClick, buttonId, document.getElementById(buttonId) as HTMLButtonElement);
635
+
636
+ // Close the drop-down
637
+ closeDropdowns();
638
+ }
600
639
 
601
- executeButtonAction(option.onClick, buttonId, document.getElementById(buttonId) as HTMLButtonElement);
602
-
603
- // Close the drop-down
604
- closeDropdowns();
605
640
  };
606
641
 
607
642
  // click outside
@@ -1054,10 +1089,11 @@ const Chatbox = (props: ChatboxProps) => {
1054
1089
  customMethodsRef.current,
1055
1090
  conversationHistory.current
1056
1091
  );
1057
-
1058
1092
  const { content, isStream } = customResponse;
1059
1093
  let contentRes: any = content;
1060
1094
 
1095
+
1096
+
1061
1097
  // Update stream mode
1062
1098
  setEnableStreamMode(isStream);
1063
1099
 
@@ -1164,6 +1200,7 @@ const Chatbox = (props: ChatboxProps) => {
1164
1200
  // hide loader
1165
1201
  setLoaderDisplay(false);
1166
1202
 
1203
+
1167
1204
  let result: any = jsonResponse;
1168
1205
  if (extractPath) {
1169
1206
  for (const path of extractPath) {
@@ -1176,6 +1213,7 @@ const Chatbox = (props: ChatboxProps) => {
1176
1213
  // Replace with a valid label
1177
1214
  content = fixHtmlTags(content, args().withReasoning, args().reasoningSwitchLabel);
1178
1215
 
1216
+
1179
1217
  return {
1180
1218
  reply: formatLatestDisplayContent(content),
1181
1219
  useStreamRender: false
@@ -1244,10 +1282,57 @@ const Chatbox = (props: ChatboxProps) => {
1244
1282
  (window as any).chatboxCopyToClipboard = chatboxCopyToClipboard;
1245
1283
  }, []);
1246
1284
 
1285
+
1286
+
1287
+ // Initialize the default value of toolkit buttons
1288
+ useEffect(() => {
1289
+ if (args().toolkitButtons) {
1290
+ args().toolkitButtons.forEach((btn: FloatingButton, index: number) => {
1291
+ const _id = `${args().prefix || 'custom-'}chatbox-btn-tools-${chatId}${index}`;
1292
+
1293
+ if (btn.isSelect) {
1294
+
1295
+ if (!initializedDefaults[_id] && typeof btn.defaultSelected === 'number') {
1296
+ const options = getButtonOptions(btn, _id);
1297
+
1298
+ // If there is a default selected item, initialize the selected state
1299
+ if (btn.defaultSelected >= 0 && btn.defaultSelected < options.length) {
1300
+ const defaultOption = options[btn.defaultSelected];
1301
+ if (defaultOption) {
1302
+ // Update the selected status
1303
+ // console.log('--> defaultOption: ', defaultOption);
1304
+
1305
+ // Pass the "isDefaultSelection" parameter as true
1306
+ handleExecuteButtonSelect(_id, defaultOption, btn.defaultSelected, defaultOption.value, true);
1307
+
1308
+ // Perform the onClick action alone
1309
+ executeDefaultOptionAction(defaultOption.onClick, _id);
1310
+
1311
+
1312
+ // Mark this button with the default value initialized
1313
+ setInitializedDefaults(prev => ({
1314
+ ...prev,
1315
+ [_id]: true
1316
+ }));
1317
+
1318
+ }
1319
+ }
1320
+ }
1321
+ } else if (btn.active) {
1322
+ // For non-select buttons, if defaultActive is true, execute the onClick action
1323
+ executeButtonAction(btn.onClick, _id, document.getElementById(_id) as HTMLButtonElement);
1324
+ }
1325
+
1326
+
1327
+ })
1328
+ }
1329
+ }, [chatId, args().toolkitButtons]); // It is only executed when the component is first rendered and when toolkitButtons changes
1330
+
1331
+
1247
1332
  return (
1248
1333
  <>
1249
1334
 
1250
- <RootPortal show={true} containerClassName="Chatbox">
1335
+ <RootPortal show={true} usePortal={args().usePopUp} containerClassName="Chatbox">
1251
1336
 
1252
1337
  {/**------------- BUBBLE -------------*/}
1253
1338
  {args().bubble ? <>
@@ -1270,7 +1355,7 @@ const Chatbox = (props: ChatboxProps) => {
1270
1355
  {/**------------- CLOSE BUTTON------------- */}
1271
1356
 
1272
1357
 
1273
- <div style={{ display: show ? 'block' : 'none' }} className={`${args().prefix || 'custom-'}chatbox-container`} ref={rootRef}>
1358
+ <div style={{ display: show ? 'block' : 'none' }} className={`${args().prefix || 'custom-'}chatbox-container ${typeof args().usePopUp !== 'undefined' && args().usePopUp === false ? 'popup-none' : ''}`} ref={rootRef}>
1274
1359
 
1275
1360
  {/**------------- NO DATA -------------*/}
1276
1361
  {msgList.length === 0 ? <>
@@ -1310,7 +1395,8 @@ const Chatbox = (props: ChatboxProps) => {
1310
1395
 
1311
1396
 
1312
1397
  {/**------------- MESSAGES LIST -------------*/}
1313
- <div className="messages" ref={msgContainerRef}>
1398
+ {/** Prevent excessive height overflow */}
1399
+ <div className={`messages ${msgList.length === 0 ? 'd-none' : ''}`} ref={msgContainerRef}>
1314
1400
 
1315
1401
  {msgList.map((msg, index) => {
1316
1402
 
@@ -1570,12 +1656,13 @@ const Chatbox = (props: ChatboxProps) => {
1570
1656
 
1571
1657
  if (btn.isSelect) {
1572
1658
  const options = getButtonOptions(btn, _id);
1573
-
1659
+
1574
1660
  return (
1575
1661
  <div key={index} className="toolkit-select-wrapper">
1576
1662
  <button
1577
1663
  id={_id}
1578
- className={`toolkit-select-btn ${btn.value || ''} ${isActive ? 'active' : ''} ${selectedOpt.curValue !== 'cancel' && typeof selectedOpt.curValue !== 'undefined' && selectedOpt.curValue !== '' ? 'opt-active' : ''}`}
1664
+ data-value={btn.value || ''}
1665
+ className={`toolkit-select-btn ${isActive ? 'active' : ''} ${selectedOpt.curValue !== 'cancel' && typeof selectedOpt.curValue !== 'undefined' && selectedOpt.curValue !== '' ? 'opt-active' : ''}`}
1579
1666
  onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
1580
1667
  e.preventDefault();
1581
1668
  setActiveButtons(prev => ({
@@ -1610,7 +1697,8 @@ const Chatbox = (props: ChatboxProps) => {
1610
1697
  {options.map((option: FloatingButtonSelectOption, optIndex: number) => (
1611
1698
  <div
1612
1699
  key={optIndex}
1613
- className={`toolkit-select-option ${option.value || ''} ${selectedOpt.curIndex === optIndex ? 'selected' : ''}`}
1700
+ data-value={option.value || ''}
1701
+ className={`toolkit-select-option ${selectedOpt.curIndex === optIndex ? 'selected' : ''}`}
1614
1702
  onClick={() => handleExecuteButtonSelect(_id, option, optIndex, option.value)}
1615
1703
  >
1616
1704
  <span dangerouslySetInnerHTML={{ __html: option.label }}></span>
@@ -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(
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.150",
5
+ "version": "4.7.155",
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",