@tp3/chat-widget 0.1.10 → 0.1.11
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/dist/ChatWidget.js +4 -34
- package/dist/ChatWidget.mjs +4 -34
- package/package.json +1 -1
- package/src/ChatWidget.tsx +8 -44
package/dist/ChatWidget.js
CHANGED
|
@@ -64,45 +64,18 @@ function ChatWidget({
|
|
|
64
64
|
const wsRef = (0, import_react.useRef)(null);
|
|
65
65
|
const messagesEnd = (0, import_react.useRef)(null);
|
|
66
66
|
const inputRef = (0, import_react.useRef)(null);
|
|
67
|
-
const chatWindowRef = (0, import_react.useRef)(null);
|
|
68
67
|
const typewriterQueue = (0, import_react.useRef)([]);
|
|
69
68
|
const typewriterTimer = (0, import_react.useRef)(null);
|
|
70
69
|
(0, import_react.useEffect)(() => {
|
|
71
70
|
if (open && !closing) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
document.
|
|
75
|
-
document.body.style.width = "100%";
|
|
76
|
-
} else if (!open) {
|
|
77
|
-
const top = Math.abs(parseInt(document.body.style.top || "0", 10));
|
|
78
|
-
document.body.style.position = "";
|
|
79
|
-
document.body.style.top = "";
|
|
80
|
-
document.body.style.width = "";
|
|
81
|
-
window.scrollTo(0, top);
|
|
71
|
+
document.documentElement.style.overflow = "hidden";
|
|
72
|
+
} else {
|
|
73
|
+
document.documentElement.style.overflow = "";
|
|
82
74
|
}
|
|
83
75
|
return () => {
|
|
84
|
-
|
|
85
|
-
document.body.style.position = "";
|
|
86
|
-
document.body.style.top = "";
|
|
87
|
-
document.body.style.width = "";
|
|
88
|
-
if (open) window.scrollTo(0, top);
|
|
76
|
+
document.documentElement.style.overflow = "";
|
|
89
77
|
};
|
|
90
78
|
}, [open, closing]);
|
|
91
|
-
(0, import_react.useEffect)(() => {
|
|
92
|
-
const el = chatWindowRef.current;
|
|
93
|
-
if (!el || !open) return;
|
|
94
|
-
function blockIfOutsideMessages(e) {
|
|
95
|
-
const target = e.target;
|
|
96
|
-
if (target.closest("[data-chat-messages]")) return;
|
|
97
|
-
e.preventDefault();
|
|
98
|
-
}
|
|
99
|
-
el.addEventListener("wheel", blockIfOutsideMessages, { passive: false });
|
|
100
|
-
el.addEventListener("touchmove", blockIfOutsideMessages, { passive: false });
|
|
101
|
-
return () => {
|
|
102
|
-
el.removeEventListener("wheel", blockIfOutsideMessages);
|
|
103
|
-
el.removeEventListener("touchmove", blockIfOutsideMessages);
|
|
104
|
-
};
|
|
105
|
-
}, [open]);
|
|
106
79
|
(0, import_react.useEffect)(() => {
|
|
107
80
|
if (messages.length > 1) {
|
|
108
81
|
messagesEnd.current?.scrollIntoView({ behavior: "smooth" });
|
|
@@ -298,7 +271,6 @@ function ChatWidget({
|
|
|
298
271
|
open && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
299
272
|
"div",
|
|
300
273
|
{
|
|
301
|
-
ref: chatWindowRef,
|
|
302
274
|
className: closing ? "chat-window-out" : "chat-window",
|
|
303
275
|
style: {
|
|
304
276
|
position: "fixed",
|
|
@@ -309,7 +281,6 @@ function ChatWidget({
|
|
|
309
281
|
maxWidth: "calc(100vw - 48px)",
|
|
310
282
|
height: chatHeight,
|
|
311
283
|
maxHeight: "calc(100dvh - 48px)",
|
|
312
|
-
overscrollBehavior: "contain",
|
|
313
284
|
background: "var(--chat-primary-fg, #fff)",
|
|
314
285
|
display: "flex",
|
|
315
286
|
flexDirection: "column",
|
|
@@ -374,7 +345,6 @@ function ChatWidget({
|
|
|
374
345
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
375
346
|
"div",
|
|
376
347
|
{
|
|
377
|
-
"data-chat-messages": true,
|
|
378
348
|
style: {
|
|
379
349
|
flex: 1,
|
|
380
350
|
overflowY: "auto",
|
package/dist/ChatWidget.mjs
CHANGED
|
@@ -40,45 +40,18 @@ function ChatWidget({
|
|
|
40
40
|
const wsRef = useRef(null);
|
|
41
41
|
const messagesEnd = useRef(null);
|
|
42
42
|
const inputRef = useRef(null);
|
|
43
|
-
const chatWindowRef = useRef(null);
|
|
44
43
|
const typewriterQueue = useRef([]);
|
|
45
44
|
const typewriterTimer = useRef(null);
|
|
46
45
|
useEffect(() => {
|
|
47
46
|
if (open && !closing) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
document.
|
|
51
|
-
document.body.style.width = "100%";
|
|
52
|
-
} else if (!open) {
|
|
53
|
-
const top = Math.abs(parseInt(document.body.style.top || "0", 10));
|
|
54
|
-
document.body.style.position = "";
|
|
55
|
-
document.body.style.top = "";
|
|
56
|
-
document.body.style.width = "";
|
|
57
|
-
window.scrollTo(0, top);
|
|
47
|
+
document.documentElement.style.overflow = "hidden";
|
|
48
|
+
} else {
|
|
49
|
+
document.documentElement.style.overflow = "";
|
|
58
50
|
}
|
|
59
51
|
return () => {
|
|
60
|
-
|
|
61
|
-
document.body.style.position = "";
|
|
62
|
-
document.body.style.top = "";
|
|
63
|
-
document.body.style.width = "";
|
|
64
|
-
if (open) window.scrollTo(0, top);
|
|
52
|
+
document.documentElement.style.overflow = "";
|
|
65
53
|
};
|
|
66
54
|
}, [open, closing]);
|
|
67
|
-
useEffect(() => {
|
|
68
|
-
const el = chatWindowRef.current;
|
|
69
|
-
if (!el || !open) return;
|
|
70
|
-
function blockIfOutsideMessages(e) {
|
|
71
|
-
const target = e.target;
|
|
72
|
-
if (target.closest("[data-chat-messages]")) return;
|
|
73
|
-
e.preventDefault();
|
|
74
|
-
}
|
|
75
|
-
el.addEventListener("wheel", blockIfOutsideMessages, { passive: false });
|
|
76
|
-
el.addEventListener("touchmove", blockIfOutsideMessages, { passive: false });
|
|
77
|
-
return () => {
|
|
78
|
-
el.removeEventListener("wheel", blockIfOutsideMessages);
|
|
79
|
-
el.removeEventListener("touchmove", blockIfOutsideMessages);
|
|
80
|
-
};
|
|
81
|
-
}, [open]);
|
|
82
55
|
useEffect(() => {
|
|
83
56
|
if (messages.length > 1) {
|
|
84
57
|
messagesEnd.current?.scrollIntoView({ behavior: "smooth" });
|
|
@@ -274,7 +247,6 @@ function ChatWidget({
|
|
|
274
247
|
open && /* @__PURE__ */ jsxs(
|
|
275
248
|
"div",
|
|
276
249
|
{
|
|
277
|
-
ref: chatWindowRef,
|
|
278
250
|
className: closing ? "chat-window-out" : "chat-window",
|
|
279
251
|
style: {
|
|
280
252
|
position: "fixed",
|
|
@@ -285,7 +257,6 @@ function ChatWidget({
|
|
|
285
257
|
maxWidth: "calc(100vw - 48px)",
|
|
286
258
|
height: chatHeight,
|
|
287
259
|
maxHeight: "calc(100dvh - 48px)",
|
|
288
|
-
overscrollBehavior: "contain",
|
|
289
260
|
background: "var(--chat-primary-fg, #fff)",
|
|
290
261
|
display: "flex",
|
|
291
262
|
flexDirection: "column",
|
|
@@ -350,7 +321,6 @@ function ChatWidget({
|
|
|
350
321
|
/* @__PURE__ */ jsxs(
|
|
351
322
|
"div",
|
|
352
323
|
{
|
|
353
|
-
"data-chat-messages": true,
|
|
354
324
|
style: {
|
|
355
325
|
flex: 1,
|
|
356
326
|
overflowY: "auto",
|
package/package.json
CHANGED
package/src/ChatWidget.tsx
CHANGED
|
@@ -64,57 +64,24 @@ export default function ChatWidget({
|
|
|
64
64
|
const wsRef = useRef<WebSocket | null>(null);
|
|
65
65
|
const messagesEnd = useRef<HTMLDivElement>(null);
|
|
66
66
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
67
|
-
const chatWindowRef = useRef<HTMLDivElement>(null);
|
|
68
67
|
const typewriterQueue = useRef<string[]>([]);
|
|
69
68
|
const typewriterTimer = useRef<ReturnType<typeof setInterval> | null>(null);
|
|
70
69
|
|
|
71
|
-
// Lock
|
|
72
|
-
//
|
|
73
|
-
//
|
|
70
|
+
// Lock scroll on the page behind the chat.
|
|
71
|
+
// Using overflow:hidden on <html> is the standard approach used by
|
|
72
|
+
// modal/chat libraries — it blocks wheel and touch scroll on desktop
|
|
73
|
+
// and mobile without interfering with the keyboard or viewport.
|
|
74
74
|
useEffect(() => {
|
|
75
75
|
if (open && !closing) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
document.
|
|
79
|
-
document.body.style.width = "100%";
|
|
80
|
-
} else if (!open) {
|
|
81
|
-
const top = Math.abs(parseInt(document.body.style.top || "0", 10));
|
|
82
|
-
document.body.style.position = "";
|
|
83
|
-
document.body.style.top = "";
|
|
84
|
-
document.body.style.width = "";
|
|
85
|
-
window.scrollTo(0, top);
|
|
76
|
+
document.documentElement.style.overflow = "hidden";
|
|
77
|
+
} else {
|
|
78
|
+
document.documentElement.style.overflow = "";
|
|
86
79
|
}
|
|
87
80
|
return () => {
|
|
88
|
-
|
|
89
|
-
document.body.style.position = "";
|
|
90
|
-
document.body.style.top = "";
|
|
91
|
-
document.body.style.width = "";
|
|
92
|
-
if (open) window.scrollTo(0, top);
|
|
81
|
+
document.documentElement.style.overflow = "";
|
|
93
82
|
};
|
|
94
83
|
}, [open, closing]);
|
|
95
84
|
|
|
96
|
-
// Prevent events on the chat window from scrolling the page behind.
|
|
97
|
-
// Only blocks events targeting the window itself, not the scrollable messages area.
|
|
98
|
-
useEffect(() => {
|
|
99
|
-
const el = chatWindowRef.current;
|
|
100
|
-
if (!el || !open) return;
|
|
101
|
-
|
|
102
|
-
function blockIfOutsideMessages(e: WheelEvent | TouchEvent) {
|
|
103
|
-
const target = e.target as HTMLElement;
|
|
104
|
-
// Allow scroll inside the messages container
|
|
105
|
-
if (target.closest('[data-chat-messages]')) return;
|
|
106
|
-
e.preventDefault();
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
el.addEventListener("wheel", blockIfOutsideMessages, { passive: false });
|
|
110
|
-
el.addEventListener("touchmove", blockIfOutsideMessages, { passive: false });
|
|
111
|
-
|
|
112
|
-
return () => {
|
|
113
|
-
el.removeEventListener("wheel", blockIfOutsideMessages);
|
|
114
|
-
el.removeEventListener("touchmove", blockIfOutsideMessages);
|
|
115
|
-
};
|
|
116
|
-
}, [open]);
|
|
117
|
-
|
|
118
85
|
useEffect(() => {
|
|
119
86
|
// Don't scroll on first render — wait for the open animation
|
|
120
87
|
if (messages.length > 1) {
|
|
@@ -330,7 +297,6 @@ export default function ChatWidget({
|
|
|
330
297
|
|
|
331
298
|
{open && (
|
|
332
299
|
<div
|
|
333
|
-
ref={chatWindowRef}
|
|
334
300
|
className={closing ? "chat-window-out" : "chat-window"}
|
|
335
301
|
style={{
|
|
336
302
|
position: "fixed",
|
|
@@ -341,7 +307,6 @@ export default function ChatWidget({
|
|
|
341
307
|
maxWidth: "calc(100vw - 48px)",
|
|
342
308
|
height: chatHeight,
|
|
343
309
|
maxHeight: "calc(100dvh - 48px)",
|
|
344
|
-
overscrollBehavior: "contain",
|
|
345
310
|
background: "var(--chat-primary-fg, #fff)",
|
|
346
311
|
display: "flex",
|
|
347
312
|
flexDirection: "column",
|
|
@@ -401,7 +366,6 @@ export default function ChatWidget({
|
|
|
401
366
|
|
|
402
367
|
{/* Messages */}
|
|
403
368
|
<div
|
|
404
|
-
data-chat-messages
|
|
405
369
|
style={{
|
|
406
370
|
flex: 1,
|
|
407
371
|
overflowY: "auto",
|