funda-ui 4.6.222 → 4.6.333

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.
@@ -0,0 +1,64 @@
1
+ /**
2
+ * String formatting utility functions
3
+ */
4
+ /**
5
+ * Remove all special characters except space from a string
6
+ * @param {string} input - The input string to process
7
+ * @returns {string} The processed string
8
+ */
9
+ declare function rmSpec(input: string): string;
10
+ /**
11
+ * Allow only numbers and letters in a string
12
+ * @param {string} input - The input string to process
13
+ * @returns {string} The processed string
14
+ */
15
+ declare function onlyNumAndLetter(input: string): string;
16
+ /**
17
+ * Remove all spaces including those in the middle
18
+ * @param {string} input - The input string to process
19
+ * @returns {string} The processed string
20
+ */
21
+ declare function rmAllSpace(input: string): string;
22
+ /**
23
+ * Remove whitespace from both sides of a string
24
+ * @param {string} input - The input string to process
25
+ * @returns {string} The processed string
26
+ */
27
+ declare function trimAll(input: string): string;
28
+ /**
29
+ * Replace multiple spaces with a single space
30
+ * @param {string} input - The input string to process
31
+ * @returns {string} The processed string
32
+ */
33
+ declare function multiSpacesToSingle(input: string): string;
34
+ /**
35
+ * Convert HTML text to plain text
36
+ * @param {string} input - The input string to process
37
+ * @returns {string} The processed string
38
+ */
39
+ declare function htmlToPlain(input: string): string;
40
+ /**
41
+ * Strip HTML tags and their content
42
+ * @param {string} input - The input string to process
43
+ * @returns {string} The processed string
44
+ */
45
+ declare function stripTagsAndContent(input: string): string;
46
+ /**
47
+ * Remove first and last slash from a URL
48
+ * @param {string} input - The input URL to process
49
+ * @returns {string} The processed URL
50
+ */
51
+ declare function removeFirstLastSlash(input: string): string;
52
+ /**
53
+ * Remove trailing slash from a URL
54
+ * @param {string} input - The input URL to process
55
+ * @returns {string} The processed URL
56
+ */
57
+ declare function removeTrailingSlash(input: string): string;
58
+ /**
59
+ * Remove first slash from a URL
60
+ * @param {string} input - The input URL to process
61
+ * @returns {string} The processed URL
62
+ */
63
+ declare function removeFirstSlash(input: string): string;
64
+ export { rmSpec, onlyNumAndLetter, rmAllSpace, trimAll, multiSpacesToSingle, htmlToPlain, stripTagsAndContent, removeFirstLastSlash, removeTrailingSlash, removeFirstSlash };
@@ -0,0 +1,157 @@
1
+ (function webpackUniversalModuleDefinition(root, factory) {
2
+ if(typeof exports === 'object' && typeof module === 'object')
3
+ module.exports = factory();
4
+ else if(typeof define === 'function' && define.amd)
5
+ define([], factory);
6
+ else if(typeof exports === 'object')
7
+ exports["RPB"] = factory();
8
+ else
9
+ root["RPB"] = factory();
10
+ })(this, () => {
11
+ return /******/ (() => { // webpackBootstrap
12
+ /******/ "use strict";
13
+ /******/ // The require scope
14
+ /******/ var __webpack_require__ = {};
15
+ /******/
16
+ /************************************************************************/
17
+ /******/ /* webpack/runtime/define property getters */
18
+ /******/ (() => {
19
+ /******/ // define getter functions for harmony exports
20
+ /******/ __webpack_require__.d = (exports, definition) => {
21
+ /******/ for(var key in definition) {
22
+ /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
23
+ /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
24
+ /******/ }
25
+ /******/ }
26
+ /******/ };
27
+ /******/ })();
28
+ /******/
29
+ /******/ /* webpack/runtime/hasOwnProperty shorthand */
30
+ /******/ (() => {
31
+ /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
32
+ /******/ })();
33
+ /******/
34
+ /******/ /* webpack/runtime/make namespace object */
35
+ /******/ (() => {
36
+ /******/ // define __esModule on exports
37
+ /******/ __webpack_require__.r = (exports) => {
38
+ /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
39
+ /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
40
+ /******/ }
41
+ /******/ Object.defineProperty(exports, '__esModule', { value: true });
42
+ /******/ };
43
+ /******/ })();
44
+ /******/
45
+ /************************************************************************/
46
+ var __webpack_exports__ = {};
47
+ __webpack_require__.r(__webpack_exports__);
48
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
49
+ /* harmony export */ "htmlToPlain": () => (/* binding */ htmlToPlain),
50
+ /* harmony export */ "multiSpacesToSingle": () => (/* binding */ multiSpacesToSingle),
51
+ /* harmony export */ "onlyNumAndLetter": () => (/* binding */ onlyNumAndLetter),
52
+ /* harmony export */ "removeFirstLastSlash": () => (/* binding */ removeFirstLastSlash),
53
+ /* harmony export */ "removeFirstSlash": () => (/* binding */ removeFirstSlash),
54
+ /* harmony export */ "removeTrailingSlash": () => (/* binding */ removeTrailingSlash),
55
+ /* harmony export */ "rmAllSpace": () => (/* binding */ rmAllSpace),
56
+ /* harmony export */ "rmSpec": () => (/* binding */ rmSpec),
57
+ /* harmony export */ "stripTagsAndContent": () => (/* binding */ stripTagsAndContent),
58
+ /* harmony export */ "trimAll": () => (/* binding */ trimAll)
59
+ /* harmony export */ });
60
+ /**
61
+ * String formatting utility functions
62
+ */
63
+
64
+ /**
65
+ * Remove all special characters except space from a string
66
+ * @param {string} input - The input string to process
67
+ * @returns {string} The processed string
68
+ */
69
+ function rmSpec(input) {
70
+ return input.replace(/[^a-zA-Z0-9 \u4E00-\u9FFF]/g, "");
71
+ }
72
+
73
+ /**
74
+ * Allow only numbers and letters in a string
75
+ * @param {string} input - The input string to process
76
+ * @returns {string} The processed string
77
+ */
78
+ function onlyNumAndLetter(input) {
79
+ return input.replace(/[^a-zA-Z0-9 ]/g, "");
80
+ }
81
+
82
+ /**
83
+ * Remove all spaces including those in the middle
84
+ * @param {string} input - The input string to process
85
+ * @returns {string} The processed string
86
+ */
87
+ function rmAllSpace(input) {
88
+ return input.replace(/\s/g, "");
89
+ }
90
+
91
+ /**
92
+ * Remove whitespace from both sides of a string
93
+ * @param {string} input - The input string to process
94
+ * @returns {string} The processed string
95
+ */
96
+ function trimAll(input) {
97
+ return input.replace(/(^\s+)|(\s+$)/g, "");
98
+ }
99
+
100
+ /**
101
+ * Replace multiple spaces with a single space
102
+ * @param {string} input - The input string to process
103
+ * @returns {string} The processed string
104
+ */
105
+ function multiSpacesToSingle(input) {
106
+ return input.replace(/\s+(\W)/g, ' ');
107
+ }
108
+
109
+ /**
110
+ * Convert HTML text to plain text
111
+ * @param {string} input - The input string to process
112
+ * @returns {string} The processed string
113
+ */
114
+ function htmlToPlain(input) {
115
+ return input.replace(/(<([^>]+)>)/ig, '');
116
+ }
117
+
118
+ /**
119
+ * Strip HTML tags and their content
120
+ * @param {string} input - The input string to process
121
+ * @returns {string} The processed string
122
+ */
123
+ function stripTagsAndContent(input) {
124
+ return input.replace(/<\/?[^>]+(>|$)(.*?)<\/?[^>]+(>|$)/ig, '');
125
+ }
126
+
127
+ /**
128
+ * Remove first and last slash from a URL
129
+ * @param {string} input - The input URL to process
130
+ * @returns {string} The processed URL
131
+ */
132
+ function removeFirstLastSlash(input) {
133
+ return input.replace(/^\/|\/$/g, '');
134
+ }
135
+
136
+ /**
137
+ * Remove trailing slash from a URL
138
+ * @param {string} input - The input URL to process
139
+ * @returns {string} The processed URL
140
+ */
141
+ function removeTrailingSlash(input) {
142
+ return input.replace(/\/+$/, '');
143
+ }
144
+
145
+ /**
146
+ * Remove first slash from a URL
147
+ * @param {string} input - The input URL to process
148
+ * @returns {string} The processed URL
149
+ */
150
+ function removeFirstSlash(input) {
151
+ return input.replace(/\//, '');
152
+ }
153
+
154
+ /******/ return __webpack_exports__;
155
+ /******/ })()
156
+ ;
157
+ });
@@ -198,6 +198,7 @@
198
198
  margin-bottom: 10px;
199
199
  font-size: 13px;
200
200
  margin-right: 0;
201
+ /* copy button */
201
202
  }
202
203
  .custom-chatbox-container .messages img, .custom-chatbox-container .messages svg, .custom-chatbox-container .messages video, .custom-chatbox-container .messages canvas, .custom-chatbox-container .messages audio, .custom-chatbox-container .messages iframe, .custom-chatbox-container .messages embed, .custom-chatbox-container .messages object {
203
204
  display: inline;
@@ -208,10 +209,11 @@
208
209
  .custom-chatbox-container .messages::-webkit-scrollbar-thumb {
209
210
  background: rgba(0, 0, 0, 0.2);
210
211
  }
211
- .custom-chatbox-container .messages > div {
212
+ .custom-chatbox-container .messages > div:not(.newchat-btn) {
212
213
  margin: 5px 0;
213
214
  padding: 3px 5px;
214
215
  border-radius: 0.35rem;
216
+ position: relative;
215
217
  }
216
218
  .custom-chatbox-container .messages p {
217
219
  margin: 3px 0;
@@ -284,6 +286,21 @@
284
286
  background: transparent;
285
287
  padding-top: 0;
286
288
  }
289
+ .custom-chatbox-container .messages .copy-btn {
290
+ position: absolute;
291
+ left: calc(var(--custom-chatbox-content-w) - 0.7rem);
292
+ bottom: 0.5rem;
293
+ z-index: 1;
294
+ background: transparent;
295
+ border: none;
296
+ padding: 4px;
297
+ cursor: pointer;
298
+ opacity: 0.6;
299
+ transition: opacity 0.2s;
300
+ }
301
+ .custom-chatbox-container .messages .copy-btn:hover {
302
+ opacity: 1;
303
+ }
287
304
  .custom-chatbox-container .msg-dotted-loader-container {
288
305
  font-weight: normal;
289
306
  transform: translateY(-5px);
@@ -167,6 +167,8 @@
167
167
  --custom-chatbox-content-html-elem-border-color: #ddd;
168
168
  --custom-chatbox-content-html-elem-bg: rgba(0,0,0,.05);
169
169
 
170
+
171
+
170
172
  min-width: var(--custom-chatbox-w);
171
173
  max-width: var(--custom-chatbox-w);
172
174
  margin: auto;
@@ -243,10 +245,11 @@
243
245
  }
244
246
 
245
247
 
246
- > div {
248
+ > div:not(.newchat-btn) {
247
249
  margin: 5px 0;
248
250
  padding: 3px 5px;
249
251
  border-radius: 0.35rem;
252
+ position: relative;
250
253
  }
251
254
 
252
255
  p {
@@ -298,6 +301,7 @@
298
301
  border-radius: 0.35rem;
299
302
 
300
303
 
304
+
301
305
  thead {
302
306
  background: var(--custom-chatbox-content-html-elem-bg);
303
307
 
@@ -313,6 +317,7 @@
313
317
  }
314
318
  }
315
319
  }
320
+
316
321
 
317
322
  }
318
323
 
@@ -345,6 +350,26 @@
345
350
 
346
351
  }
347
352
  }
353
+
354
+
355
+ /* copy button */
356
+ .copy-btn {
357
+ position: absolute;
358
+ left: calc(var(--custom-chatbox-content-w) - .7rem);
359
+ bottom: 0.5rem;
360
+ z-index: 1;
361
+ background: transparent;
362
+ border: none;
363
+ padding: 4px;
364
+ cursor: pointer;
365
+ opacity: 0.6;
366
+ transition: opacity 0.2s;
367
+
368
+ &:hover {
369
+ opacity: 1;
370
+ }
371
+ }
372
+
348
373
  }
349
374
 
350
375
  /* dot loading */
@@ -523,7 +548,7 @@
523
548
  left: 50%;
524
549
  transform: translateX(-50%);
525
550
  z-index: 1;
526
-
551
+
527
552
  > button {
528
553
  padding: 3px 6px;
529
554
  background-color: var(--custom-chatbox-newchat-btn-color);
@@ -683,8 +708,6 @@
683
708
  }
684
709
 
685
710
 
686
-
687
-
688
711
  /* default questions */
689
712
  .default-questions-title {
690
713
  margin-bottom: .5rem;
@@ -712,8 +735,6 @@
712
735
  }
713
736
 
714
737
  }
715
-
716
-
717
738
 
718
739
 
719
740
  }
@@ -12,6 +12,7 @@ import useClickOutside from 'funda-utils/dist/cjs/useClickOutside';
12
12
  import { htmlEncode } from 'funda-utils/dist/cjs/sanitize';
13
13
 
14
14
 
15
+
15
16
  // loader
16
17
  import PureLoader from './PureLoader';
17
18
  import TypingEffect from "./TypingEffect";
@@ -114,10 +115,14 @@ export type ChatboxProps = {
114
115
  newChatButton?: FloatingButton;
115
116
  customMethods?: CustomMethod[]; // [{"name": "method1", "func": "() => { console.log('test'); }"}, ...]
116
117
  defaultQuestions?: QuestionData;
118
+ showCopyBtn?: boolean; // Whether to show copy button for each reply
119
+ autoCopyReply?: boolean; // Whether to automatically copy reply to clipboard
117
120
  customRequest?: CustomRequestFunction;
118
121
  renderParser?: (input: string) => Promise<string>;
119
122
  requestBodyFormatter?: (body: any, contextData: Record<string, any>, conversationHistory: MessageDetail[]) => Promise<Record<string, any>>;
123
+ copiedContentFormatter?: (string: string) => string;
120
124
  nameFormatter?: (input: string) => string;
125
+ onCopyCallback?: (res: Record<string, any>) => void;
121
126
  onQuestionClick?: (text: string, methods: Record<string, Function>) => void;
122
127
  onInputChange?: (controlRef: React.RefObject<any>, val: string) => any;
123
128
  onInputCallback?: (input: string) => Promise<string>;
@@ -296,9 +301,13 @@ const Chatbox = (props: ChatboxProps) => {
296
301
  maxHistoryLength,
297
302
  customRequest,
298
303
  onQuestionClick,
304
+ onCopyCallback,
299
305
  renderParser,
300
306
  requestBodyFormatter,
307
+ copiedContentFormatter,
301
308
  nameFormatter,
309
+ showCopyBtn,
310
+ autoCopyReply,
302
311
  onInputChange,
303
312
  onInputCallback,
304
313
  onChunk,
@@ -370,9 +379,13 @@ const Chatbox = (props: ChatboxProps) => {
370
379
  newChatButton,
371
380
  customRequest,
372
381
  onQuestionClick,
382
+ onCopyCallback,
373
383
  renderParser,
374
384
  requestBodyFormatter,
385
+ copiedContentFormatter,
375
386
  nameFormatter,
387
+ showCopyBtn,
388
+ autoCopyReply,
376
389
  onInputChange,
377
390
  onInputCallback,
378
391
  onChunk,
@@ -393,6 +406,57 @@ const Chatbox = (props: ChatboxProps) => {
393
406
 
394
407
  }
395
408
 
409
+ //================================================================
410
+ // Clipboard
411
+ //================================================================
412
+ const chatboxCopyToClipboard = async (text: string) => {
413
+
414
+ let _content: string = text;
415
+ if (typeof args().copiedContentFormatter === 'function') {
416
+ _content = args().copiedContentFormatter(text);
417
+ }
418
+
419
+ try {
420
+ // Try using the modern Clipboard API first
421
+ if (navigator.clipboard && window.isSecureContext) {
422
+ await navigator.clipboard.writeText(_content);
423
+ args().onCopyCallback?.({
424
+ success: true,
425
+ message: 'Text copied to clipboard',
426
+ });
427
+ return true;
428
+ }
429
+
430
+ // Fallback for older browsers
431
+ const textArea = document.createElement('textarea');
432
+ textArea.value = _content;
433
+ textArea.style.position = 'fixed';
434
+ textArea.style.left = '-999999px';
435
+ textArea.style.top = '-999999px';
436
+ document.body.appendChild(textArea);
437
+ textArea.focus();
438
+ textArea.select();
439
+
440
+ try {
441
+ document.execCommand('copy');
442
+ textArea.remove();
443
+ args().onCopyCallback?.({
444
+ success: true,
445
+ message: 'Text copied to clipboard',
446
+ });
447
+ return true;
448
+ } catch (err) {
449
+ textArea.remove();
450
+ return false;
451
+ }
452
+ } catch (err) {
453
+ args().onCopyCallback?.({
454
+ success: false,
455
+ message: `Failed to copy text: ${err}`,
456
+ });
457
+ return false;
458
+ }
459
+ };
396
460
 
397
461
 
398
462
  //================================================================
@@ -820,6 +884,11 @@ const Chatbox = (props: ChatboxProps) => {
820
884
  // Update the message list state
821
885
  setMsgList((prevMessages) => [...prevMessages, newMessage]);
822
886
 
887
+ // Auto copy reply if enabled
888
+ if (args().autoCopyReply && sender === args().answerNameRes) {
889
+ chatboxCopyToClipboard(content);
890
+ }
891
+
823
892
  };
824
893
 
825
894
  const sendMessage = async () => {
@@ -1155,7 +1224,10 @@ const Chatbox = (props: ChatboxProps) => {
1155
1224
  }
1156
1225
  }, [props.defaultMessages]);
1157
1226
 
1158
-
1227
+ useEffect(() => {
1228
+ // Bind chatboxCopyToClipboard to window so it can be called in HTML code
1229
+ (window as any).chatboxCopyToClipboard = chatboxCopyToClipboard;
1230
+ }, []);
1159
1231
 
1160
1232
  return (
1161
1233
  <>
@@ -1220,39 +1292,42 @@ const Chatbox = (props: ChatboxProps) => {
1220
1292
 
1221
1293
  </> : null}
1222
1294
  {/**------------- /NO DATA -------------*/}
1223
-
1224
-
1295
+
1225
1296
 
1226
1297
  {/**------------- MESSAGES LIST -------------*/}
1227
1298
  <div className="messages" ref={msgContainerRef}>
1228
1299
 
1229
1300
  {msgList.map((msg, index) => {
1230
1301
 
1302
+ const copyTargetId = `${args().prefix || 'custom-'}chatbox-content--${chatId}${index}`;
1231
1303
  const isAnimProgress = tempAnimText !== '' && msg.sender !== args().questionNameRes && index === msgList.length - 1 && loading;
1232
1304
  const hasAnimated = animatedMessagesRef.current.has(index);
1233
1305
 
1234
1306
  // Mark the message as animated;
1235
1307
  animatedMessagesRef.current.add(index);
1236
1308
 
1309
+ const timeShow = `<span class="qa-timestamp">${msg.timestamp}</span>${args().showCopyBtn && msg.tag?.indexOf('[reply]') >= 0 ?(`<button class="copy-btn" onclick="window.chatboxCopyToClipboard(document.querySelector('#${copyTargetId} .qa-content-inner').innerHTML)"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M8 4v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V7.242a2 2 0 0 0-.602-1.43L16.083 2.57A2 2 0 0 0 14.685 2H10a2 2 0 0 0-2 2z"/><path d="M16 18v2a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h2"/></svg></button>`) : ''}`;
1310
+
1237
1311
  return <div key={index} className={msg.tag?.indexOf('[reply]') < 0 ? 'request' : 'reply'} style={{ display: isAnimProgress ? 'none' : '' }}>
1238
1312
  <div className="qa-name" dangerouslySetInnerHTML={{ __html: `${msg.sender}` }}></div>
1239
1313
 
1314
+
1240
1315
  {msg.sender === args().questionNameRes ? <>
1241
- <div className="qa-content" dangerouslySetInnerHTML={{ __html: `${msg.content} <span class="qa-timestamp">${msg.timestamp}</span>` }}></div>
1316
+ <div className="qa-content" id={copyTargetId} dangerouslySetInnerHTML={{ __html: `<div class="qa-content-inner">${msg.content}</div> ${timeShow}` }}></div>
1242
1317
  </> : <>
1243
1318
 
1244
1319
  {enableStreamMode ? <>
1245
- <div className="qa-content" dangerouslySetInnerHTML={{ __html: `${msg.content} <span class="qa-timestamp">${msg.timestamp}</span>` }}></div>
1320
+ <div className="qa-content" id={copyTargetId} dangerouslySetInnerHTML={{ __html: `<div class="qa-content-inner">${msg.content}</div> ${timeShow}` }}></div>
1246
1321
  </> : <>
1247
- <div className="qa-content">
1322
+ <div className="qa-content" id={copyTargetId}>
1248
1323
  {hasAnimated ? (
1249
- <div dangerouslySetInnerHTML={{ __html: `${msg.content} <span class="qa-timestamp">${msg.timestamp}</span>` }}></div>
1324
+ <div dangerouslySetInnerHTML={{ __html: `<div class="qa-content-inner">${msg.content}</div> ${timeShow}` }}></div>
1250
1325
  ) : (
1251
1326
  <TypingEffect
1252
1327
  onUpdate={() => {
1253
1328
  scrollToBottom();
1254
1329
  }}
1255
- content={`${msg.content} <span class="qa-timestamp">${msg.timestamp}</span>`}
1330
+ content={`<div class="qa-content-inner">${msg.content}</div> ${timeShow}`}
1256
1331
  speed={10}
1257
1332
  />
1258
1333
  )}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * String formatting utility functions
3
+ */
4
+
5
+ /**
6
+ * Remove all special characters except space from a string
7
+ * @param {string} input - The input string to process
8
+ * @returns {string} The processed string
9
+ */
10
+ function rmSpec(input: string): string {
11
+ return input.replace(/[^a-zA-Z0-9 \u4E00-\u9FFF]/g, "");
12
+ }
13
+
14
+ /**
15
+ * Allow only numbers and letters in a string
16
+ * @param {string} input - The input string to process
17
+ * @returns {string} The processed string
18
+ */
19
+ function onlyNumAndLetter(input: string): string {
20
+ return input.replace(/[^a-zA-Z0-9 ]/g, "");
21
+ }
22
+
23
+ /**
24
+ * Remove all spaces including those in the middle
25
+ * @param {string} input - The input string to process
26
+ * @returns {string} The processed string
27
+ */
28
+ function rmAllSpace(input: string): string {
29
+ return input.replace(/\s/g, "");
30
+ }
31
+
32
+ /**
33
+ * Remove whitespace from both sides of a string
34
+ * @param {string} input - The input string to process
35
+ * @returns {string} The processed string
36
+ */
37
+ function trimAll(input: string): string {
38
+ return input.replace(/(^\s+)|(\s+$)/g, "");
39
+ }
40
+
41
+ /**
42
+ * Replace multiple spaces with a single space
43
+ * @param {string} input - The input string to process
44
+ * @returns {string} The processed string
45
+ */
46
+ function multiSpacesToSingle(input: string): string {
47
+ return input.replace(/\s+(\W)/g, ' ');
48
+ }
49
+
50
+ /**
51
+ * Convert HTML text to plain text
52
+ * @param {string} input - The input string to process
53
+ * @returns {string} The processed string
54
+ */
55
+ function htmlToPlain(input: string): string {
56
+ return input.replace(/(<([^>]+)>)/ig, '');
57
+ }
58
+
59
+ /**
60
+ * Strip HTML tags and their content
61
+ * @param {string} input - The input string to process
62
+ * @returns {string} The processed string
63
+ */
64
+ function stripTagsAndContent(input: string): string {
65
+ return input.replace(/<\/?[^>]+(>|$)(.*?)<\/?[^>]+(>|$)/ig, '');
66
+ }
67
+
68
+ /**
69
+ * Remove first and last slash from a URL
70
+ * @param {string} input - The input URL to process
71
+ * @returns {string} The processed URL
72
+ */
73
+ function removeFirstLastSlash(input: string): string {
74
+ return input.replace(/^\/|\/$/g, '');
75
+ }
76
+
77
+ /**
78
+ * Remove trailing slash from a URL
79
+ * @param {string} input - The input URL to process
80
+ * @returns {string} The processed URL
81
+ */
82
+ function removeTrailingSlash(input: string): string {
83
+ return input.replace(/\/+$/, '');
84
+ }
85
+
86
+ /**
87
+ * Remove first slash from a URL
88
+ * @param {string} input - The input URL to process
89
+ * @returns {string} The processed URL
90
+ */
91
+ function removeFirstSlash(input: string): string {
92
+ return input.replace(/\//, '');
93
+ }
94
+
95
+ export {
96
+ rmSpec,
97
+ onlyNumAndLetter,
98
+ rmAllSpace,
99
+ trimAll,
100
+ multiSpacesToSingle,
101
+ htmlToPlain,
102
+ stripTagsAndContent,
103
+ removeFirstLastSlash,
104
+ removeTrailingSlash,
105
+ removeFirstSlash
106
+ };
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.6.222",
5
+ "version": "4.6.333",
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",