funda-ui 4.6.151 → 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.
- package/Chatbox/index.css +88 -14
- package/Chatbox/index.d.ts +5 -0
- package/Chatbox/index.js +457 -281
- package/Utils/format-string.d.ts +64 -0
- package/Utils/format-string.js +157 -0
- package/lib/cjs/Chatbox/index.d.ts +5 -0
- package/lib/cjs/Chatbox/index.js +457 -281
- package/lib/cjs/Utils/format-string.d.ts +64 -0
- package/lib/cjs/Utils/format-string.js +157 -0
- package/lib/css/Chatbox/index.css +88 -14
- package/lib/esm/Chatbox/PureLoader.tsx +4 -2
- package/lib/esm/Chatbox/TypingEffect.tsx +12 -41
- package/lib/esm/Chatbox/index.scss +118 -28
- package/lib/esm/Chatbox/index.tsx +148 -36
- package/lib/esm/Chatbox/utils/func.ts +52 -1
- package/lib/esm/Textarea/index.tsx +0 -2
- package/lib/esm/Utils/libs/format-string.ts +106 -0
- package/package.json +1 -1
|
@@ -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
|
+
});
|
|
@@ -1,24 +1,19 @@
|
|
|
1
1
|
/*=================== Chatbox (Loading) =================*/
|
|
2
2
|
.custom-chatbox-loader-container {
|
|
3
|
+
--custom-chatbox-loader-color: #b9caf7;
|
|
4
|
+
--custom-chatbox-loader-color2: #0d6efd;
|
|
3
5
|
width: 130px;
|
|
4
6
|
text-align: start;
|
|
5
7
|
}
|
|
6
8
|
.custom-chatbox-loader-container .custom-chatbox-loader {
|
|
7
9
|
height: 4px;
|
|
8
10
|
width: 100%;
|
|
9
|
-
--c: no-repeat linear-gradient(var(--
|
|
10
|
-
background: var(--c), var(--c),
|
|
11
|
+
--c: no-repeat linear-gradient(var(--custom-chatbox-loader-color2) 0 0);
|
|
12
|
+
background: var(--c), var(--c), var(--custom-chatbox-loader-color);
|
|
11
13
|
background-size: 60% 100%;
|
|
12
|
-
animation:
|
|
14
|
+
animation: loader-move 3s infinite;
|
|
13
15
|
}
|
|
14
|
-
|
|
15
|
-
.dark-mode .custom-chatbox-loader-container .custom-chatbox-loader,
|
|
16
|
-
[data-bs-theme=dark] .custom-chatbox-loader-container .custom-chatbox-loader {
|
|
17
|
-
--c: no-repeat linear-gradient(var(--bs-primary) 0 0);
|
|
18
|
-
background: var(--c), var(--c), #8692b5;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
@keyframes cssAnim--loadermove {
|
|
16
|
+
@keyframes loader-move {
|
|
22
17
|
0% {
|
|
23
18
|
background-position: -150% 0, -150% 0;
|
|
24
19
|
}
|
|
@@ -29,6 +24,29 @@
|
|
|
29
24
|
background-position: 250% 0, 250% 0;
|
|
30
25
|
}
|
|
31
26
|
}
|
|
27
|
+
|
|
28
|
+
.custom-chatbox-mini-loader {
|
|
29
|
+
--custom-chatbox-miniloader-color: rgba(0,0,0,.5);
|
|
30
|
+
width: 15px;
|
|
31
|
+
height: 15px;
|
|
32
|
+
margin: 0.5rem;
|
|
33
|
+
margin-bottom: 0;
|
|
34
|
+
border: 3px dotted var(--custom-chatbox-miniloader-color);
|
|
35
|
+
border-radius: 50%;
|
|
36
|
+
display: inline-block;
|
|
37
|
+
position: relative;
|
|
38
|
+
box-sizing: border-box;
|
|
39
|
+
animation: mini-loader-spin 1s linear infinite;
|
|
40
|
+
}
|
|
41
|
+
@keyframes mini-loader-spin {
|
|
42
|
+
0% {
|
|
43
|
+
transform: rotate(0deg);
|
|
44
|
+
}
|
|
45
|
+
100% {
|
|
46
|
+
transform: rotate(360deg);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
32
50
|
/*=================== Chatbox (Core) =================*/
|
|
33
51
|
.custom-chatbox-circle {
|
|
34
52
|
--custom-chatbox-circle-color: #5A5EB9;
|
|
@@ -115,6 +133,8 @@
|
|
|
115
133
|
--custom-chatbox-toolkit-btn-radius: 20px;
|
|
116
134
|
--custom-chatbox-questions-bg: #f5f5f5;
|
|
117
135
|
--custom-chatbox-questions-hover-bg: #e9e9e9;
|
|
136
|
+
--custom-chatbox-content-html-elem-border-color: #ddd;
|
|
137
|
+
--custom-chatbox-content-html-elem-bg: rgba(0,0,0,.05);
|
|
118
138
|
min-width: var(--custom-chatbox-w);
|
|
119
139
|
max-width: var(--custom-chatbox-w);
|
|
120
140
|
margin: auto;
|
|
@@ -142,6 +162,8 @@
|
|
|
142
162
|
padding: 0;
|
|
143
163
|
font-size: 0.75rem;
|
|
144
164
|
margin-bottom: 0.5rem;
|
|
165
|
+
background: var(--custom-chatbox-msg-bg);
|
|
166
|
+
padding: 0.5rem;
|
|
145
167
|
}
|
|
146
168
|
.custom-chatbox-container summary {
|
|
147
169
|
cursor: pointer;
|
|
@@ -171,11 +193,12 @@
|
|
|
171
193
|
font-size: 0.75rem;
|
|
172
194
|
}
|
|
173
195
|
.custom-chatbox-container .messages {
|
|
174
|
-
height: calc(100% -
|
|
196
|
+
height: calc(100% - 110px);
|
|
175
197
|
overflow-y: auto;
|
|
176
198
|
margin-bottom: 10px;
|
|
177
199
|
font-size: 13px;
|
|
178
200
|
margin-right: 0;
|
|
201
|
+
/* copy button */
|
|
179
202
|
}
|
|
180
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 {
|
|
181
204
|
display: inline;
|
|
@@ -186,10 +209,11 @@
|
|
|
186
209
|
.custom-chatbox-container .messages::-webkit-scrollbar-thumb {
|
|
187
210
|
background: rgba(0, 0, 0, 0.2);
|
|
188
211
|
}
|
|
189
|
-
.custom-chatbox-container .messages > div {
|
|
212
|
+
.custom-chatbox-container .messages > div:not(.newchat-btn) {
|
|
190
213
|
margin: 5px 0;
|
|
191
214
|
padding: 3px 5px;
|
|
192
215
|
border-radius: 0.35rem;
|
|
216
|
+
position: relative;
|
|
193
217
|
}
|
|
194
218
|
.custom-chatbox-container .messages p {
|
|
195
219
|
margin: 3px 0;
|
|
@@ -216,6 +240,33 @@
|
|
|
216
240
|
margin-top: 0.3rem;
|
|
217
241
|
display: inline-block;
|
|
218
242
|
text-align: start;
|
|
243
|
+
/* Custom HTML Styles */
|
|
244
|
+
}
|
|
245
|
+
.custom-chatbox-container .messages .qa-content .table-container {
|
|
246
|
+
overflow-x: auto;
|
|
247
|
+
margin-bottom: 0.5rem;
|
|
248
|
+
}
|
|
249
|
+
.custom-chatbox-container .messages .qa-content .table-container::-webkit-scrollbar {
|
|
250
|
+
height: 10px;
|
|
251
|
+
}
|
|
252
|
+
.custom-chatbox-container .messages .qa-content .table-container::-webkit-scrollbar-thumb {
|
|
253
|
+
background: rgba(0, 0, 0, 0.2);
|
|
254
|
+
}
|
|
255
|
+
.custom-chatbox-container .messages .qa-content .table-container table {
|
|
256
|
+
width: 100%;
|
|
257
|
+
border-collapse: collapse;
|
|
258
|
+
border-radius: 0.35rem;
|
|
259
|
+
}
|
|
260
|
+
.custom-chatbox-container .messages .qa-content .table-container table thead {
|
|
261
|
+
background: var(--custom-chatbox-content-html-elem-bg);
|
|
262
|
+
}
|
|
263
|
+
.custom-chatbox-container .messages .qa-content .table-container table thead tr {
|
|
264
|
+
white-space: nowrap;
|
|
265
|
+
}
|
|
266
|
+
.custom-chatbox-container .messages .qa-content .table-container table th, .custom-chatbox-container .messages .qa-content .table-container table td {
|
|
267
|
+
padding: 0.25rem;
|
|
268
|
+
text-align: left;
|
|
269
|
+
border: 1px solid var(--custom-chatbox-content-html-elem-border-color);
|
|
219
270
|
}
|
|
220
271
|
.custom-chatbox-container .messages .request {
|
|
221
272
|
text-align: end;
|
|
@@ -232,6 +283,23 @@
|
|
|
232
283
|
}
|
|
233
284
|
.custom-chatbox-container .messages .reply .qa-content {
|
|
234
285
|
width: var(--custom-chatbox-content-w);
|
|
286
|
+
background: transparent;
|
|
287
|
+
padding-top: 0;
|
|
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;
|
|
235
303
|
}
|
|
236
304
|
.custom-chatbox-container .msg-dotted-loader-container {
|
|
237
305
|
font-weight: normal;
|
|
@@ -373,6 +441,11 @@
|
|
|
373
441
|
}
|
|
374
442
|
.custom-chatbox-container .newchat-btn {
|
|
375
443
|
text-align: center;
|
|
444
|
+
position: absolute;
|
|
445
|
+
bottom: 95px;
|
|
446
|
+
left: 50%;
|
|
447
|
+
transform: translateX(-50%);
|
|
448
|
+
z-index: 1;
|
|
376
449
|
}
|
|
377
450
|
.custom-chatbox-container .newchat-btn > button {
|
|
378
451
|
padding: 3px 6px;
|
|
@@ -462,6 +535,7 @@
|
|
|
462
535
|
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
|
|
463
536
|
margin-bottom: 10px;
|
|
464
537
|
max-height: 300px;
|
|
538
|
+
min-width: 120px;
|
|
465
539
|
overflow-y: auto;
|
|
466
540
|
animation: dropupAnimation 0.2s ease;
|
|
467
541
|
position: absolute;
|
|
@@ -489,7 +563,7 @@
|
|
|
489
563
|
.custom-chatbox-container .toolkit-select-wrapper .toolkit-select-option.cancel {
|
|
490
564
|
color: var(--custom-chatbox-gray-color);
|
|
491
565
|
}
|
|
492
|
-
.custom-chatbox-container .toolkit-select-wrapper .toolkit-select-option:hover {
|
|
566
|
+
.custom-chatbox-container .toolkit-select-wrapper .toolkit-select-option.selected:not(.cancel), .custom-chatbox-container .toolkit-select-wrapper .toolkit-select-option:hover {
|
|
493
567
|
background-color: var(--custom-chatbox-toolkit-opt-active-color);
|
|
494
568
|
}
|
|
495
569
|
.custom-chatbox-container .default-questions-title {
|
|
@@ -2,6 +2,7 @@ import React from "react";
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
type PureLoaderProps = {
|
|
5
|
+
prefix?: string;
|
|
5
6
|
txt?: React.ReactNode;
|
|
6
7
|
center?: boolean;
|
|
7
8
|
customClassName?: string;
|
|
@@ -12,6 +13,7 @@ type PureLoaderProps = {
|
|
|
12
13
|
const PureLoader = (props: PureLoaderProps) => {
|
|
13
14
|
|
|
14
15
|
const {
|
|
16
|
+
prefix = 'custom-',
|
|
15
17
|
txt,
|
|
16
18
|
center,
|
|
17
19
|
customClassName
|
|
@@ -21,11 +23,11 @@ const PureLoader = (props: PureLoaderProps) => {
|
|
|
21
23
|
return (
|
|
22
24
|
<>
|
|
23
25
|
|
|
24
|
-
<div className={
|
|
26
|
+
<div className={`${prefix}chatbox-loader-container ${customClassName || ''}`}>
|
|
25
27
|
<div className="row g-0 align-items-center">
|
|
26
28
|
<div className={center ? 'text-center' : ''}><small>{txt || txt === '' ? txt : 'Loading...'}</small></div>
|
|
27
29
|
<div>
|
|
28
|
-
<div className="
|
|
30
|
+
<div className="${prefix}chatbox-loader"></div>
|
|
29
31
|
</div>
|
|
30
32
|
</div>
|
|
31
33
|
</div>
|
|
@@ -1,57 +1,28 @@
|
|
|
1
1
|
import React, { useEffect, useState } from 'react';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// extract
|
|
4
|
+
import { extractHtmlTags } from './utils/func';
|
|
5
|
+
import type { HtmlTagPlaceholder } from './utils/func';
|
|
6
|
+
|
|
7
|
+
export interface TypingEffectProps {
|
|
4
8
|
content: string; // The content to display
|
|
5
9
|
speed: number; // Speed of typing in milliseconds
|
|
6
10
|
onComplete?: () => void; // Callback when typing is complete
|
|
7
11
|
onUpdate?: () => void; // Callback when typing
|
|
8
12
|
}
|
|
9
13
|
|
|
10
|
-
|
|
11
|
-
original: string;
|
|
12
|
-
placeholder: string;
|
|
13
|
-
type: 'img' | 'svg';
|
|
14
|
-
}
|
|
14
|
+
|
|
15
15
|
const TypingEffect: React.FC<TypingEffectProps> = ({ content, speed, onComplete, onUpdate }) => {
|
|
16
16
|
const [displayedContent, setDisplayedContent] = useState<string>('');
|
|
17
17
|
const [index, setIndex] = useState<number>(0);
|
|
18
|
-
const [
|
|
18
|
+
const [htmlTagPlaceholder, setHtmlTagPlaceholders] = useState<HtmlTagPlaceholder[]>([]);
|
|
19
19
|
const [processedContent, setProcessedContent] = useState<string>('');
|
|
20
20
|
|
|
21
21
|
// Extract and replace image tags
|
|
22
22
|
useEffect(() => {
|
|
23
|
-
const
|
|
24
|
-
const placeholders: ImagePlaceholder[] = [];
|
|
25
|
-
let processedHtml = html;
|
|
26
|
-
|
|
27
|
-
// <img>
|
|
28
|
-
processedHtml = processedHtml.replace(/<img[^>]*>/g, (match) => {
|
|
29
|
-
const placeholder = `[IMG_${placeholders.length}]`;
|
|
30
|
-
placeholders.push({
|
|
31
|
-
original: match,
|
|
32
|
-
placeholder,
|
|
33
|
-
type: 'img'
|
|
34
|
-
});
|
|
35
|
-
return placeholder;
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
// <svg>
|
|
39
|
-
processedHtml = processedHtml.replace(/<svg[^>]*>[\s\S]*?<\/svg>/g, (match) => {
|
|
40
|
-
const placeholder = `[SVG_${placeholders.length}]`;
|
|
41
|
-
placeholders.push({
|
|
42
|
-
original: match,
|
|
43
|
-
placeholder,
|
|
44
|
-
type: 'svg'
|
|
45
|
-
});
|
|
46
|
-
return placeholder;
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
return { processedHtml, placeholders };
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
const { processedHtml, placeholders } = extractImages(content);
|
|
23
|
+
const { processedHtml, placeholders } = extractHtmlTags(content);
|
|
53
24
|
setProcessedContent(processedHtml);
|
|
54
|
-
|
|
25
|
+
setHtmlTagPlaceholders(placeholders);
|
|
55
26
|
}, [content]);
|
|
56
27
|
|
|
57
28
|
// Handle typing effects
|
|
@@ -61,7 +32,7 @@ const TypingEffect: React.FC<TypingEffectProps> = ({ content, speed, onComplete,
|
|
|
61
32
|
let newContent = processedContent.substring(0, index + 1);
|
|
62
33
|
|
|
63
34
|
// Replace the completed placeholder
|
|
64
|
-
|
|
35
|
+
htmlTagPlaceholder.forEach(({ original, placeholder }) => {
|
|
65
36
|
if (newContent.includes(placeholder)) {
|
|
66
37
|
newContent = newContent.replace(placeholder, original);
|
|
67
38
|
}
|
|
@@ -77,9 +48,9 @@ const TypingEffect: React.FC<TypingEffectProps> = ({ content, speed, onComplete,
|
|
|
77
48
|
}, speed);
|
|
78
49
|
|
|
79
50
|
return () => clearInterval(timer);
|
|
80
|
-
}, [processedContent, index, speed, onComplete, onUpdate,
|
|
51
|
+
}, [processedContent, index, speed, onComplete, onUpdate, htmlTagPlaceholder]);
|
|
81
52
|
|
|
82
|
-
return <
|
|
53
|
+
return <div dangerouslySetInnerHTML={{ __html: displayedContent }} />;
|
|
83
54
|
};
|
|
84
55
|
|
|
85
56
|
export default TypingEffect;
|