@aigentyc/chat-sdk 0.1.0
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/LICENSE +21 -0
- package/README.md +156 -0
- package/dist/JsonRenderResult-Ftw4AKwb.d.cts +18 -0
- package/dist/JsonRenderResult-Ftw4AKwb.d.ts +18 -0
- package/dist/JsonRenderResult-GQOYPLVH.cjs +15 -0
- package/dist/JsonRenderResult-GQOYPLVH.cjs.map +1 -0
- package/dist/JsonRenderResult-ZFJ6VWMS.js +6 -0
- package/dist/JsonRenderResult-ZFJ6VWMS.js.map +1 -0
- package/dist/SlotsContext-CBtt36al.d.ts +148 -0
- package/dist/SlotsContext-CHvISDJT.d.cts +148 -0
- package/dist/VisualizationRenderer-FNFYNN66.js +5 -0
- package/dist/VisualizationRenderer-FNFYNN66.js.map +1 -0
- package/dist/VisualizationRenderer-VKMZXRUX.cjs +20 -0
- package/dist/VisualizationRenderer-VKMZXRUX.cjs.map +1 -0
- package/dist/ai-elements.cjs +4608 -0
- package/dist/ai-elements.cjs.map +1 -0
- package/dist/ai-elements.d.cts +897 -0
- package/dist/ai-elements.d.ts +897 -0
- package/dist/ai-elements.js +4363 -0
- package/dist/ai-elements.js.map +1 -0
- package/dist/chunk-3MP2EGEJ.cjs +270 -0
- package/dist/chunk-3MP2EGEJ.cjs.map +1 -0
- package/dist/chunk-3RW7O444.js +26 -0
- package/dist/chunk-3RW7O444.js.map +1 -0
- package/dist/chunk-42ARGQXE.js +51 -0
- package/dist/chunk-42ARGQXE.js.map +1 -0
- package/dist/chunk-4FBVV64J.js +257 -0
- package/dist/chunk-4FBVV64J.js.map +1 -0
- package/dist/chunk-4QT25AXI.js +21 -0
- package/dist/chunk-4QT25AXI.js.map +1 -0
- package/dist/chunk-525KS5HM.cjs +30 -0
- package/dist/chunk-525KS5HM.cjs.map +1 -0
- package/dist/chunk-5F3O3ZJH.js +299 -0
- package/dist/chunk-5F3O3ZJH.js.map +1 -0
- package/dist/chunk-5QSXB6UL.cjs +259 -0
- package/dist/chunk-5QSXB6UL.cjs.map +1 -0
- package/dist/chunk-5T4FJ2SR.js +664 -0
- package/dist/chunk-5T4FJ2SR.js.map +1 -0
- package/dist/chunk-7BNYTOTE.cjs +67 -0
- package/dist/chunk-7BNYTOTE.cjs.map +1 -0
- package/dist/chunk-AWAJOSFP.cjs +96 -0
- package/dist/chunk-AWAJOSFP.cjs.map +1 -0
- package/dist/chunk-BKDV2H6Z.js +224 -0
- package/dist/chunk-BKDV2H6Z.js.map +1 -0
- package/dist/chunk-FQN6OBGN.cjs +171 -0
- package/dist/chunk-FQN6OBGN.cjs.map +1 -0
- package/dist/chunk-FYPJSHCL.js +190 -0
- package/dist/chunk-FYPJSHCL.js.map +1 -0
- package/dist/chunk-J2H6MLQF.cjs +680 -0
- package/dist/chunk-J2H6MLQF.cjs.map +1 -0
- package/dist/chunk-J2K7EJYP.cjs +198 -0
- package/dist/chunk-J2K7EJYP.cjs.map +1 -0
- package/dist/chunk-JI5KCSOI.cjs +23 -0
- package/dist/chunk-JI5KCSOI.cjs.map +1 -0
- package/dist/chunk-JOO6C3XT.cjs +44 -0
- package/dist/chunk-JOO6C3XT.cjs.map +1 -0
- package/dist/chunk-KBGPBUTI.cjs +78 -0
- package/dist/chunk-KBGPBUTI.cjs.map +1 -0
- package/dist/chunk-MT2AMINB.js +75 -0
- package/dist/chunk-MT2AMINB.js.map +1 -0
- package/dist/chunk-MZQKGNWF.js +4 -0
- package/dist/chunk-MZQKGNWF.js.map +1 -0
- package/dist/chunk-NG7OTWXQ.cjs +226 -0
- package/dist/chunk-NG7OTWXQ.cjs.map +1 -0
- package/dist/chunk-NPJKLYLV.js +68 -0
- package/dist/chunk-NPJKLYLV.js.map +1 -0
- package/dist/chunk-NW2ESHRV.js +685 -0
- package/dist/chunk-NW2ESHRV.js.map +1 -0
- package/dist/chunk-NWF735F5.js +1631 -0
- package/dist/chunk-NWF735F5.js.map +1 -0
- package/dist/chunk-NYQSM3EB.cjs +305 -0
- package/dist/chunk-NYQSM3EB.cjs.map +1 -0
- package/dist/chunk-OU7OROOE.cjs +1643 -0
- package/dist/chunk-OU7OROOE.cjs.map +1 -0
- package/dist/chunk-PS3U7T37.js +42 -0
- package/dist/chunk-PS3U7T37.js.map +1 -0
- package/dist/chunk-Q7T3VAJV.cjs +687 -0
- package/dist/chunk-Q7T3VAJV.cjs.map +1 -0
- package/dist/chunk-QYCEHFAB.js +265 -0
- package/dist/chunk-QYCEHFAB.js.map +1 -0
- package/dist/chunk-RPDJXB3U.js +676 -0
- package/dist/chunk-RPDJXB3U.js.map +1 -0
- package/dist/chunk-UKEL7FWS.js +64 -0
- package/dist/chunk-UKEL7FWS.js.map +1 -0
- package/dist/chunk-VS3NZ7FX.js +164 -0
- package/dist/chunk-VS3NZ7FX.js.map +1 -0
- package/dist/chunk-WZLWAVSS.cjs +73 -0
- package/dist/chunk-WZLWAVSS.cjs.map +1 -0
- package/dist/chunk-X5YEOOPK.cjs +758 -0
- package/dist/chunk-X5YEOOPK.cjs.map +1 -0
- package/dist/chunk-X7R334SB.cjs +5 -0
- package/dist/chunk-X7R334SB.cjs.map +1 -0
- package/dist/chunk-XXNDL5SJ.cjs +432 -0
- package/dist/chunk-XXNDL5SJ.cjs.map +1 -0
- package/dist/chunk-YQELMJW5.js +429 -0
- package/dist/chunk-YQELMJW5.js.map +1 -0
- package/dist/components.cjs +551 -0
- package/dist/components.cjs.map +1 -0
- package/dist/components.d.cts +181 -0
- package/dist/components.d.ts +181 -0
- package/dist/components.js +483 -0
- package/dist/components.js.map +1 -0
- package/dist/core.cjs +283 -0
- package/dist/core.cjs.map +1 -0
- package/dist/core.d.cts +455 -0
- package/dist/core.d.ts +455 -0
- package/dist/core.js +241 -0
- package/dist/core.js.map +1 -0
- package/dist/hooks.cjs +324 -0
- package/dist/hooks.cjs.map +1 -0
- package/dist/hooks.d.cts +163 -0
- package/dist/hooks.d.ts +163 -0
- package/dist/hooks.js +277 -0
- package/dist/hooks.js.map +1 -0
- package/dist/i18n.cjs +26 -0
- package/dist/i18n.cjs.map +1 -0
- package/dist/i18n.d.cts +50 -0
- package/dist/i18n.d.ts +50 -0
- package/dist/i18n.js +5 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.cjs +466 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +80 -0
- package/dist/index.d.ts +80 -0
- package/dist/index.js +438 -0
- package/dist/index.js.map +1 -0
- package/dist/interaction-tracker-D9P1Oq4j.d.cts +83 -0
- package/dist/interaction-tracker-D9P1Oq4j.d.ts +83 -0
- package/dist/json-render.cjs +23 -0
- package/dist/json-render.cjs.map +1 -0
- package/dist/json-render.d.cts +857 -0
- package/dist/json-render.d.ts +857 -0
- package/dist/json-render.js +6 -0
- package/dist/json-render.js.map +1 -0
- package/dist/live-chat-transport-4XLOIPOE.js +4 -0
- package/dist/live-chat-transport-4XLOIPOE.js.map +1 -0
- package/dist/live-chat-transport-ALVRGWX7.cjs +13 -0
- package/dist/live-chat-transport-ALVRGWX7.cjs.map +1 -0
- package/dist/select-B4l9yoyn.d.cts +99 -0
- package/dist/select-B4l9yoyn.d.ts +99 -0
- package/dist/styles.css +2 -0
- package/dist/theme.cjs +18 -0
- package/dist/theme.cjs.map +1 -0
- package/dist/theme.d.cts +55 -0
- package/dist/theme.d.ts +55 -0
- package/dist/theme.js +5 -0
- package/dist/theme.js.map +1 -0
- package/dist/tools.cjs +32 -0
- package/dist/tools.cjs.map +1 -0
- package/dist/tools.d.cts +117 -0
- package/dist/tools.d.ts +117 -0
- package/dist/tools.js +11 -0
- package/dist/tools.js.map +1 -0
- package/dist/types-DKJ_-nbG.d.cts +349 -0
- package/dist/types-DKJ_-nbG.d.ts +349 -0
- package/dist/ui.cjs +667 -0
- package/dist/ui.cjs.map +1 -0
- package/dist/ui.d.cts +95 -0
- package/dist/ui.d.ts +95 -0
- package/dist/ui.js +414 -0
- package/dist/ui.js.map +1 -0
- package/package.json +255 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { C as ChatProviderProps } from './types-DKJ_-nbG.js';
|
|
3
|
+
export { a as ChatConfig, b as ChatEventCallbacks, c as ChatMessage, d as ComponentAction, L as Language, e as LiveChatMessage, f as LiveChatState, Q as QuestionConfig, S as SlotMap, T as ThemeConfig, g as ToolRendererProps, h as ToolResult } from './types-DKJ_-nbG.js';
|
|
4
|
+
export { L as LiveChatReturn, U as UseAigentycChatOptions, a as UseAigentycChatReturn, u as useAigentycChat, b as useChatContext, c as useLiveChat, d as useSlot, e as useSlots } from './SlotsContext-CBtt36al.js';
|
|
5
|
+
export { useTheme } from './theme.js';
|
|
6
|
+
export { useI18n } from './i18n.js';
|
|
7
|
+
import 'react';
|
|
8
|
+
|
|
9
|
+
interface ChatProps extends ChatProviderProps {
|
|
10
|
+
/** Optional className forwarded to the ChatInterface root. */
|
|
11
|
+
className?: string;
|
|
12
|
+
}
|
|
13
|
+
declare function Chat({ className, children, ...providerProps }: ChatProps): react_jsx_runtime.JSX.Element;
|
|
14
|
+
|
|
15
|
+
/** Widget placement mode. */
|
|
16
|
+
type WidgetMode = "floating" | "inline" | "trigger";
|
|
17
|
+
interface ChatWidgetProps extends ChatProviderProps {
|
|
18
|
+
/** How the widget is rendered. Default "floating". */
|
|
19
|
+
mode?: WidgetMode;
|
|
20
|
+
/** Fixed position for the floating button. Default "bottom-right". */
|
|
21
|
+
position?: "bottom-right" | "bottom-left" | "top-right" | "top-left";
|
|
22
|
+
positionMobile?: "bottom-right" | "bottom-left" | "top-right" | "top-left";
|
|
23
|
+
/** Controlled open state. */
|
|
24
|
+
isOpen?: boolean;
|
|
25
|
+
/** Fired whenever the widget opens/closes. */
|
|
26
|
+
onOpenChange?: (open: boolean) => void;
|
|
27
|
+
/** Message to pre-fill and auto-submit on open. */
|
|
28
|
+
pendingMessage?: string | null;
|
|
29
|
+
/** Overlay z-index (defaults to 9999). */
|
|
30
|
+
zIndex?: number;
|
|
31
|
+
greetingText?: string;
|
|
32
|
+
greetingOffsetX?: string;
|
|
33
|
+
greetingOffsetY?: string;
|
|
34
|
+
greetingMaxWidth?: string;
|
|
35
|
+
buttonOffsetXMobile?: string;
|
|
36
|
+
buttonOffsetYMobile?: string;
|
|
37
|
+
buttonOffsetXDesktop?: string;
|
|
38
|
+
buttonOffsetYDesktop?: string;
|
|
39
|
+
buttonIconUrl?: string;
|
|
40
|
+
buttonImageUrl?: string;
|
|
41
|
+
buttonImageUrlMobile?: string;
|
|
42
|
+
buttonWidth?: string;
|
|
43
|
+
buttonHeight?: string;
|
|
44
|
+
buttonIconSize?: string;
|
|
45
|
+
buttonWidthMobile?: string;
|
|
46
|
+
buttonHeightMobile?: string;
|
|
47
|
+
buttonIconSizeMobile?: string;
|
|
48
|
+
buttonBgColor?: string;
|
|
49
|
+
buttonBorderRadius?: string;
|
|
50
|
+
hideGreeting?: boolean;
|
|
51
|
+
logoUrl?: string;
|
|
52
|
+
welcomeTitle?: string;
|
|
53
|
+
welcomeSubtitle?: string;
|
|
54
|
+
hideWelcomeHeader?: boolean;
|
|
55
|
+
footerText?: string;
|
|
56
|
+
hideHeader?: boolean;
|
|
57
|
+
showFirstMessage?: boolean;
|
|
58
|
+
questionsLayout?: "vertical" | "horizontal";
|
|
59
|
+
questionsLayoutMobile?: "vertical" | "horizontal";
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Top-level widget (Level 1 API). Composes ChatProvider internally and renders
|
|
63
|
+
* the correct shell based on `mode`.
|
|
64
|
+
*/
|
|
65
|
+
declare function ChatWidget(props: ChatWidgetProps): react_jsx_runtime.JSX.Element;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Top-level provider that composes all Aigentyc Chat sub-providers.
|
|
69
|
+
*
|
|
70
|
+
* Provider order (outermost to innermost):
|
|
71
|
+
* 1. I18nProvider
|
|
72
|
+
* 2. ThemeProvider (renders `<div data-aigentyc-chat>`)
|
|
73
|
+
* 3. SlotsProvider
|
|
74
|
+
* 4. ChatContextProvider
|
|
75
|
+
* 5. LiveChatProvider (conditional on `enableLiveChat`)
|
|
76
|
+
* 6. PreviewEmbedProvider
|
|
77
|
+
*/
|
|
78
|
+
declare function ChatProvider(props: ChatProviderProps): react_jsx_runtime.JSX.Element;
|
|
79
|
+
|
|
80
|
+
export { Chat, ChatProvider, ChatProviderProps, ChatWidget };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
export { useAigentycChat } from './chunk-4FBVV64J.js';
|
|
3
|
+
import './chunk-BKDV2H6Z.js';
|
|
4
|
+
import { ChatInterface, PreviewEmbedPanel, LiveChatPanel, MobileLiveChatDrawer, FloatingButton } from './chunk-NWF735F5.js';
|
|
5
|
+
import { LiveChatProvider, PreviewEmbedProvider, useIsMobile, usePreviewEmbed } from './chunk-5F3O3ZJH.js';
|
|
6
|
+
export { useLiveChat } from './chunk-5F3O3ZJH.js';
|
|
7
|
+
import { ThemeProvider } from './chunk-UKEL7FWS.js';
|
|
8
|
+
export { useTheme } from './chunk-UKEL7FWS.js';
|
|
9
|
+
import './chunk-VS3NZ7FX.js';
|
|
10
|
+
import './chunk-MZQKGNWF.js';
|
|
11
|
+
import { I18nProvider } from './chunk-QYCEHFAB.js';
|
|
12
|
+
export { useI18n } from './chunk-QYCEHFAB.js';
|
|
13
|
+
import './chunk-YQELMJW5.js';
|
|
14
|
+
import { SlotsProvider, ChatContextProvider, useSlots, renderSlot } from './chunk-FYPJSHCL.js';
|
|
15
|
+
export { useChatContext, useSlot, useSlots } from './chunk-FYPJSHCL.js';
|
|
16
|
+
import './chunk-PS3U7T37.js';
|
|
17
|
+
import './chunk-42ARGQXE.js';
|
|
18
|
+
import './chunk-4QT25AXI.js';
|
|
19
|
+
import './chunk-NPJKLYLV.js';
|
|
20
|
+
import { cn } from './chunk-3RW7O444.js';
|
|
21
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
22
|
+
import { useState, useEffect, useCallback, useMemo } from 'react';
|
|
23
|
+
|
|
24
|
+
var CALLBACK_KEYS = [
|
|
25
|
+
"onReady",
|
|
26
|
+
"onSessionStart",
|
|
27
|
+
"onSessionRestore",
|
|
28
|
+
"onMessageSent",
|
|
29
|
+
"onMessageReceived",
|
|
30
|
+
"onStreamStart",
|
|
31
|
+
"onStreamEnd",
|
|
32
|
+
"onToolCall",
|
|
33
|
+
"onToolResult",
|
|
34
|
+
"onToolAction",
|
|
35
|
+
"onLiveChatRequested",
|
|
36
|
+
"onLiveChatConnected",
|
|
37
|
+
"onLiveChatEnded",
|
|
38
|
+
"onError",
|
|
39
|
+
"onInteraction"
|
|
40
|
+
];
|
|
41
|
+
function pickCallbacks(props) {
|
|
42
|
+
const out = {};
|
|
43
|
+
for (const key of CALLBACK_KEYS) {
|
|
44
|
+
if (props[key] !== void 0) out[key] = props[key];
|
|
45
|
+
}
|
|
46
|
+
return out;
|
|
47
|
+
}
|
|
48
|
+
function ChatProvider(props) {
|
|
49
|
+
const {
|
|
50
|
+
children,
|
|
51
|
+
projectId,
|
|
52
|
+
apiEndpoint,
|
|
53
|
+
apiKey,
|
|
54
|
+
clientName,
|
|
55
|
+
language,
|
|
56
|
+
translations,
|
|
57
|
+
theme,
|
|
58
|
+
slots,
|
|
59
|
+
enableLiveChat = false,
|
|
60
|
+
chatServiceUrl,
|
|
61
|
+
persistMessages: _persistMessages,
|
|
62
|
+
maxMessages: _maxMessages,
|
|
63
|
+
questions: _questions,
|
|
64
|
+
...rest
|
|
65
|
+
} = props;
|
|
66
|
+
const callbacks = pickCallbacks(rest);
|
|
67
|
+
const config = { projectId, apiEndpoint, apiKey, clientName };
|
|
68
|
+
const langCode = language ?? "en";
|
|
69
|
+
const translationOverrides = translations?.[langCode];
|
|
70
|
+
const liveChatUrl = chatServiceUrl ?? apiEndpoint;
|
|
71
|
+
const inner = enableLiveChat && liveChatUrl && apiKey ? /* @__PURE__ */ jsx(
|
|
72
|
+
LiveChatProvider,
|
|
73
|
+
{
|
|
74
|
+
chatServiceUrl: liveChatUrl,
|
|
75
|
+
apiKey,
|
|
76
|
+
projectId: projectId || "default",
|
|
77
|
+
sessionId: "default",
|
|
78
|
+
children: /* @__PURE__ */ jsx(PreviewEmbedProvider, { children })
|
|
79
|
+
}
|
|
80
|
+
) : /* @__PURE__ */ jsx(PreviewEmbedProvider, { children });
|
|
81
|
+
return /* @__PURE__ */ jsx(I18nProvider, { language, translations: translationOverrides, children: /* @__PURE__ */ jsx(ThemeProvider, { theme, children: /* @__PURE__ */ jsx(SlotsProvider, { slots, children: /* @__PURE__ */ jsx(
|
|
82
|
+
ChatContextProvider,
|
|
83
|
+
{
|
|
84
|
+
config,
|
|
85
|
+
callbacks,
|
|
86
|
+
children: inner
|
|
87
|
+
}
|
|
88
|
+
) }) }) });
|
|
89
|
+
}
|
|
90
|
+
function Chat({ className, children, ...providerProps }) {
|
|
91
|
+
return /* @__PURE__ */ jsx(ChatProvider, { ...providerProps, children: /* @__PURE__ */ jsxs("div", { className, children: [
|
|
92
|
+
/* @__PURE__ */ jsx(ChatInterface, {}),
|
|
93
|
+
children
|
|
94
|
+
] }) });
|
|
95
|
+
}
|
|
96
|
+
function PreviewEventBridge() {
|
|
97
|
+
const previewEmbed = usePreviewEmbed();
|
|
98
|
+
useEffect(() => {
|
|
99
|
+
if (!previewEmbed || typeof window === "undefined") return;
|
|
100
|
+
const handler = (e) => {
|
|
101
|
+
const { url, title, description } = e.detail || {};
|
|
102
|
+
if (url) previewEmbed.openPreview({ url, title, description });
|
|
103
|
+
};
|
|
104
|
+
window.addEventListener("widget-preview-open", handler);
|
|
105
|
+
return () => window.removeEventListener("widget-preview-open", handler);
|
|
106
|
+
}, [previewEmbed]);
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
function MobilePreviewDrawer() {
|
|
110
|
+
const previewEmbed = usePreviewEmbed();
|
|
111
|
+
const isVisible = !!previewEmbed?.preview;
|
|
112
|
+
const preview = previewEmbed?.preview;
|
|
113
|
+
const closePreview = previewEmbed?.closePreview;
|
|
114
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
115
|
+
/* @__PURE__ */ jsx(
|
|
116
|
+
"div",
|
|
117
|
+
{
|
|
118
|
+
className: "absolute inset-0 z-40 bg-black/50",
|
|
119
|
+
style: {
|
|
120
|
+
opacity: isVisible ? 1 : 0,
|
|
121
|
+
pointerEvents: isVisible ? "auto" : "none",
|
|
122
|
+
transition: "opacity 200ms ease-out"
|
|
123
|
+
},
|
|
124
|
+
onClick: closePreview
|
|
125
|
+
}
|
|
126
|
+
),
|
|
127
|
+
/* @__PURE__ */ jsxs(
|
|
128
|
+
"div",
|
|
129
|
+
{
|
|
130
|
+
className: "absolute inset-x-0 bottom-0 z-50 rounded-t-2xl border-t shadow-2xl",
|
|
131
|
+
style: {
|
|
132
|
+
backgroundColor: "var(--ac-background)",
|
|
133
|
+
borderColor: "var(--ac-border)",
|
|
134
|
+
height: "calc(100dvh - 150px)",
|
|
135
|
+
transform: isVisible ? "translateY(0)" : "translateY(100%)",
|
|
136
|
+
transition: "transform 300ms cubic-bezier(0.32, 0.72, 0, 1)"
|
|
137
|
+
},
|
|
138
|
+
children: [
|
|
139
|
+
/* @__PURE__ */ jsx("div", { className: "flex justify-center pt-3 pb-1", children: /* @__PURE__ */ jsx("div", { className: "w-[100px] h-2 rounded-full bg-muted" }) }),
|
|
140
|
+
/* @__PURE__ */ jsxs("div", { className: "px-5 py-3 flex items-center justify-between", children: [
|
|
141
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
142
|
+
/* @__PURE__ */ jsx("h3", { className: "font-medium text-sm truncate", style: { color: "var(--ac-text)" }, children: preview?.title || "Preview" }),
|
|
143
|
+
preview?.description && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-0.5 truncate", children: preview.description })
|
|
144
|
+
] }),
|
|
145
|
+
/* @__PURE__ */ jsxs(
|
|
146
|
+
"button",
|
|
147
|
+
{
|
|
148
|
+
type: "button",
|
|
149
|
+
onClick: closePreview,
|
|
150
|
+
className: "shrink-0 w-8 h-8 rounded-full border flex items-center justify-center hover:bg-muted transition-colors ml-3",
|
|
151
|
+
children: [
|
|
152
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" }),
|
|
153
|
+
"\xD7"
|
|
154
|
+
]
|
|
155
|
+
}
|
|
156
|
+
)
|
|
157
|
+
] }),
|
|
158
|
+
/* @__PURE__ */ jsx("div", { className: "px-4 pb-4 flex-1", style: { height: "calc(100% - 80px)" }, children: preview && /* @__PURE__ */ jsx(
|
|
159
|
+
"iframe",
|
|
160
|
+
{
|
|
161
|
+
src: preview.url,
|
|
162
|
+
className: "w-full h-full rounded-xl border-none",
|
|
163
|
+
sandbox: "allow-scripts allow-same-origin allow-forms allow-popups allow-presentation",
|
|
164
|
+
title: preview.title || "Preview"
|
|
165
|
+
},
|
|
166
|
+
preview.url
|
|
167
|
+
) })
|
|
168
|
+
]
|
|
169
|
+
}
|
|
170
|
+
)
|
|
171
|
+
] });
|
|
172
|
+
}
|
|
173
|
+
function ChatWidgetInner({
|
|
174
|
+
mode = "floating",
|
|
175
|
+
position = "bottom-right",
|
|
176
|
+
positionMobile,
|
|
177
|
+
isOpen: controlledIsOpen,
|
|
178
|
+
onOpenChange,
|
|
179
|
+
pendingMessage: initialPendingMessage,
|
|
180
|
+
zIndex,
|
|
181
|
+
greetingText,
|
|
182
|
+
greetingOffsetX,
|
|
183
|
+
greetingOffsetY,
|
|
184
|
+
greetingMaxWidth,
|
|
185
|
+
buttonOffsetXMobile,
|
|
186
|
+
buttonOffsetYMobile,
|
|
187
|
+
buttonOffsetXDesktop,
|
|
188
|
+
buttonOffsetYDesktop,
|
|
189
|
+
buttonIconUrl,
|
|
190
|
+
buttonImageUrl,
|
|
191
|
+
buttonImageUrlMobile,
|
|
192
|
+
buttonWidth,
|
|
193
|
+
buttonHeight,
|
|
194
|
+
buttonIconSize,
|
|
195
|
+
buttonWidthMobile,
|
|
196
|
+
buttonHeightMobile,
|
|
197
|
+
buttonIconSizeMobile,
|
|
198
|
+
buttonBgColor,
|
|
199
|
+
buttonBorderRadius,
|
|
200
|
+
hideGreeting,
|
|
201
|
+
logoUrl,
|
|
202
|
+
welcomeTitle,
|
|
203
|
+
welcomeSubtitle,
|
|
204
|
+
hideWelcomeHeader,
|
|
205
|
+
footerText,
|
|
206
|
+
hideHeader,
|
|
207
|
+
showFirstMessage,
|
|
208
|
+
questionsLayout,
|
|
209
|
+
questionsLayoutMobile,
|
|
210
|
+
language
|
|
211
|
+
}) {
|
|
212
|
+
const [internalIsOpen, setInternalIsOpen] = useState(false);
|
|
213
|
+
const [pendingMessage, setPendingMessage] = useState(initialPendingMessage ?? null);
|
|
214
|
+
const isMobile = useIsMobile();
|
|
215
|
+
const slots = useSlots();
|
|
216
|
+
useEffect(() => {
|
|
217
|
+
if (controlledIsOpen === true) setInternalIsOpen(true);
|
|
218
|
+
}, [controlledIsOpen]);
|
|
219
|
+
const isOpen = internalIsOpen;
|
|
220
|
+
useEffect(() => {
|
|
221
|
+
if (mode === "inline" || typeof document === "undefined") return;
|
|
222
|
+
if (isOpen) {
|
|
223
|
+
const originalStyle = window.getComputedStyle(document.body).overflow;
|
|
224
|
+
document.body.style.overflow = "hidden";
|
|
225
|
+
return () => {
|
|
226
|
+
document.body.style.overflow = originalStyle;
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
}, [isOpen, mode]);
|
|
230
|
+
const handleOpen = useCallback(() => {
|
|
231
|
+
setInternalIsOpen(true);
|
|
232
|
+
onOpenChange?.(true);
|
|
233
|
+
}, [onOpenChange]);
|
|
234
|
+
const handleClose = useCallback(() => {
|
|
235
|
+
setInternalIsOpen(false);
|
|
236
|
+
onOpenChange?.(false);
|
|
237
|
+
}, [onOpenChange]);
|
|
238
|
+
const handleToggle = useCallback(() => {
|
|
239
|
+
if (isOpen) handleClose();
|
|
240
|
+
else handleOpen();
|
|
241
|
+
}, [isOpen, handleOpen, handleClose]);
|
|
242
|
+
const isRightSide = position === "bottom-right" || position === "top-right";
|
|
243
|
+
const dirRTL = language === "he";
|
|
244
|
+
const chatInterfaceProps = useMemo(
|
|
245
|
+
() => ({
|
|
246
|
+
isOpen,
|
|
247
|
+
onClose: handleClose,
|
|
248
|
+
logoUrl,
|
|
249
|
+
welcomeTitle,
|
|
250
|
+
welcomeSubtitle,
|
|
251
|
+
hideWelcomeHeader,
|
|
252
|
+
footerText,
|
|
253
|
+
hideHeader,
|
|
254
|
+
showFirstMessage,
|
|
255
|
+
questionsLayout,
|
|
256
|
+
questionsLayoutMobile,
|
|
257
|
+
pendingMessage,
|
|
258
|
+
onPendingMessageConsumed: () => setPendingMessage(null)
|
|
259
|
+
}),
|
|
260
|
+
[isOpen, handleClose, logoUrl, welcomeTitle, welcomeSubtitle, hideWelcomeHeader, footerText, hideHeader, showFirstMessage, questionsLayout, questionsLayoutMobile, pendingMessage]
|
|
261
|
+
);
|
|
262
|
+
if (mode === "inline") {
|
|
263
|
+
return /* @__PURE__ */ jsx("div", { className: "flex flex-col w-full h-full", dir: dirRTL ? "rtl" : "ltr", style: { backgroundColor: "var(--ac-background)" }, children: /* @__PURE__ */ jsx(ChatInterface, { ...chatInterfaceProps }) });
|
|
264
|
+
}
|
|
265
|
+
const panelZIndex = zIndex || 9999;
|
|
266
|
+
const floatingButtonProps = {
|
|
267
|
+
onClick: handleToggle,
|
|
268
|
+
position,
|
|
269
|
+
positionMobile,
|
|
270
|
+
isOpen,
|
|
271
|
+
greeting: greetingText,
|
|
272
|
+
greetingOffsetX,
|
|
273
|
+
greetingOffsetY,
|
|
274
|
+
greetingMaxWidth,
|
|
275
|
+
buttonOffsetXMobile,
|
|
276
|
+
buttonOffsetYMobile,
|
|
277
|
+
buttonOffsetXDesktop,
|
|
278
|
+
buttonOffsetYDesktop,
|
|
279
|
+
buttonIconUrl,
|
|
280
|
+
buttonImageUrl,
|
|
281
|
+
buttonImageUrlMobile,
|
|
282
|
+
buttonWidth,
|
|
283
|
+
buttonHeight,
|
|
284
|
+
buttonIconSize,
|
|
285
|
+
buttonWidthMobile,
|
|
286
|
+
buttonHeightMobile,
|
|
287
|
+
buttonIconSizeMobile,
|
|
288
|
+
buttonBgColor,
|
|
289
|
+
buttonBorderRadius,
|
|
290
|
+
zIndex: zIndex || 999999,
|
|
291
|
+
hideGreeting
|
|
292
|
+
};
|
|
293
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
294
|
+
/* @__PURE__ */ jsx(PreviewEventBridge, {}),
|
|
295
|
+
/* @__PURE__ */ jsx(
|
|
296
|
+
"div",
|
|
297
|
+
{
|
|
298
|
+
className: "fixed inset-0 bg-black/50 transition-opacity duration-300 ease-in-out",
|
|
299
|
+
style: {
|
|
300
|
+
zIndex: panelZIndex - 1,
|
|
301
|
+
opacity: isOpen ? 1 : 0,
|
|
302
|
+
pointerEvents: isOpen ? "auto" : "none"
|
|
303
|
+
},
|
|
304
|
+
onClick: handleClose
|
|
305
|
+
}
|
|
306
|
+
),
|
|
307
|
+
!isMobile && /* @__PURE__ */ jsx(PreviewEmbedPanel, { isOpen, isRightSide, zIndex: panelZIndex - 1 }),
|
|
308
|
+
!isMobile && /* @__PURE__ */ jsx(LiveChatPanel, { isWidgetOpen: isOpen, isRightSide, zIndex: panelZIndex - 1 }),
|
|
309
|
+
/* @__PURE__ */ jsxs(
|
|
310
|
+
"div",
|
|
311
|
+
{
|
|
312
|
+
className: cn(
|
|
313
|
+
"fixed flex flex-col p-0 shadow-2xl",
|
|
314
|
+
isMobile ? "inset-x-0 rounded-t-2xl border-t" : cn("inset-y-0 w-full max-w-[780px]", isRightSide ? "right-0 border-l" : "left-0 border-r")
|
|
315
|
+
),
|
|
316
|
+
dir: dirRTL ? "rtl" : "ltr",
|
|
317
|
+
style: {
|
|
318
|
+
backgroundColor: "var(--ac-background)",
|
|
319
|
+
borderColor: "var(--ac-border)",
|
|
320
|
+
...isMobile ? {
|
|
321
|
+
top: "70px",
|
|
322
|
+
bottom: 0,
|
|
323
|
+
height: "calc(100dvh - 70px)",
|
|
324
|
+
transform: isOpen ? "translateY(0)" : "translateY(100%)",
|
|
325
|
+
opacity: isOpen ? 1 : 0,
|
|
326
|
+
pointerEvents: isOpen ? "auto" : "none"
|
|
327
|
+
} : {
|
|
328
|
+
transform: isOpen ? "translateX(0)" : isRightSide ? "translateX(100%)" : "translateX(-100%)",
|
|
329
|
+
opacity: isOpen ? 1 : 0,
|
|
330
|
+
pointerEvents: isOpen ? "auto" : "none"
|
|
331
|
+
},
|
|
332
|
+
transition: "transform 300ms ease-in-out",
|
|
333
|
+
zIndex: panelZIndex
|
|
334
|
+
},
|
|
335
|
+
children: [
|
|
336
|
+
isMobile && /* @__PURE__ */ jsx(MobilePreviewDrawer, {}),
|
|
337
|
+
/* @__PURE__ */ jsx(MobileLiveChatDrawer, {}),
|
|
338
|
+
/* @__PURE__ */ jsx(ChatInterface, { ...chatInterfaceProps })
|
|
339
|
+
]
|
|
340
|
+
}
|
|
341
|
+
),
|
|
342
|
+
!isOpen && renderSlot(
|
|
343
|
+
"floatingButton",
|
|
344
|
+
floatingButtonProps,
|
|
345
|
+
FloatingButton,
|
|
346
|
+
slots
|
|
347
|
+
)
|
|
348
|
+
] });
|
|
349
|
+
}
|
|
350
|
+
function ChatWidget(props) {
|
|
351
|
+
const {
|
|
352
|
+
// Widget shell props consumed by inner component (also forwarded separately)
|
|
353
|
+
mode,
|
|
354
|
+
position,
|
|
355
|
+
positionMobile,
|
|
356
|
+
isOpen,
|
|
357
|
+
onOpenChange,
|
|
358
|
+
pendingMessage,
|
|
359
|
+
zIndex,
|
|
360
|
+
greetingText,
|
|
361
|
+
greetingOffsetX,
|
|
362
|
+
greetingOffsetY,
|
|
363
|
+
greetingMaxWidth,
|
|
364
|
+
buttonOffsetXMobile,
|
|
365
|
+
buttonOffsetYMobile,
|
|
366
|
+
buttonOffsetXDesktop,
|
|
367
|
+
buttonOffsetYDesktop,
|
|
368
|
+
buttonIconUrl,
|
|
369
|
+
buttonImageUrl,
|
|
370
|
+
buttonImageUrlMobile,
|
|
371
|
+
buttonWidth,
|
|
372
|
+
buttonHeight,
|
|
373
|
+
buttonIconSize,
|
|
374
|
+
buttonWidthMobile,
|
|
375
|
+
buttonHeightMobile,
|
|
376
|
+
buttonIconSizeMobile,
|
|
377
|
+
buttonBgColor,
|
|
378
|
+
buttonBorderRadius,
|
|
379
|
+
hideGreeting,
|
|
380
|
+
logoUrl,
|
|
381
|
+
welcomeTitle,
|
|
382
|
+
welcomeSubtitle,
|
|
383
|
+
hideWelcomeHeader,
|
|
384
|
+
footerText,
|
|
385
|
+
hideHeader,
|
|
386
|
+
showFirstMessage,
|
|
387
|
+
questionsLayout,
|
|
388
|
+
questionsLayoutMobile,
|
|
389
|
+
children: _children,
|
|
390
|
+
...providerProps
|
|
391
|
+
} = props;
|
|
392
|
+
return /* @__PURE__ */ jsx(ChatProvider, { ...providerProps, children: /* @__PURE__ */ jsx(
|
|
393
|
+
ChatWidgetInner,
|
|
394
|
+
{
|
|
395
|
+
mode,
|
|
396
|
+
position,
|
|
397
|
+
positionMobile,
|
|
398
|
+
isOpen,
|
|
399
|
+
onOpenChange,
|
|
400
|
+
pendingMessage,
|
|
401
|
+
zIndex,
|
|
402
|
+
greetingText,
|
|
403
|
+
greetingOffsetX,
|
|
404
|
+
greetingOffsetY,
|
|
405
|
+
greetingMaxWidth,
|
|
406
|
+
buttonOffsetXMobile,
|
|
407
|
+
buttonOffsetYMobile,
|
|
408
|
+
buttonOffsetXDesktop,
|
|
409
|
+
buttonOffsetYDesktop,
|
|
410
|
+
buttonIconUrl,
|
|
411
|
+
buttonImageUrl,
|
|
412
|
+
buttonImageUrlMobile,
|
|
413
|
+
buttonWidth,
|
|
414
|
+
buttonHeight,
|
|
415
|
+
buttonIconSize,
|
|
416
|
+
buttonWidthMobile,
|
|
417
|
+
buttonHeightMobile,
|
|
418
|
+
buttonIconSizeMobile,
|
|
419
|
+
buttonBgColor,
|
|
420
|
+
buttonBorderRadius,
|
|
421
|
+
hideGreeting,
|
|
422
|
+
logoUrl,
|
|
423
|
+
welcomeTitle,
|
|
424
|
+
welcomeSubtitle,
|
|
425
|
+
hideWelcomeHeader,
|
|
426
|
+
footerText,
|
|
427
|
+
hideHeader,
|
|
428
|
+
showFirstMessage,
|
|
429
|
+
questionsLayout,
|
|
430
|
+
questionsLayoutMobile,
|
|
431
|
+
language: providerProps.language
|
|
432
|
+
}
|
|
433
|
+
) });
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
export { Chat, ChatProvider, ChatWidget };
|
|
437
|
+
//# sourceMappingURL=index.js.map
|
|
438
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/providers/ChatProvider.tsx","../src/components/Chat.tsx","../src/components/ChatWidget.tsx"],"names":["jsx","jsxs"],"mappings":"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","file":"index.js","sourcesContent":["\"use client\";\n\nimport { I18nProvider } from \"./I18nProvider\";\nimport { ThemeProvider } from \"./ThemeProvider\";\nimport { SlotsProvider } from \"./SlotsContext\";\nimport { ChatContextProvider } from \"./ChatContext\";\nimport { LiveChatProvider } from \"./LiveChatProvider\";\nimport { PreviewEmbedProvider } from \"./PreviewEmbedProvider\";\nimport type { ChatProviderProps, ChatEventCallbacks } from \"../core/types\";\nimport type { TranslationMap } from \"./I18nProvider\";\n\nconst CALLBACK_KEYS: (keyof ChatEventCallbacks)[] = [\n \"onReady\",\n \"onSessionStart\",\n \"onSessionRestore\",\n \"onMessageSent\",\n \"onMessageReceived\",\n \"onStreamStart\",\n \"onStreamEnd\",\n \"onToolCall\",\n \"onToolResult\",\n \"onToolAction\",\n \"onLiveChatRequested\",\n \"onLiveChatConnected\",\n \"onLiveChatEnded\",\n \"onError\",\n \"onInteraction\",\n];\n\nfunction pickCallbacks(props: Record<string, unknown>): ChatEventCallbacks {\n const out: Record<string, unknown> = {};\n for (const key of CALLBACK_KEYS) {\n if (props[key] !== undefined) out[key] = props[key];\n }\n return out as ChatEventCallbacks;\n}\n\n/**\n * Top-level provider that composes all Aigentyc Chat sub-providers.\n *\n * Provider order (outermost to innermost):\n * 1. I18nProvider\n * 2. ThemeProvider (renders `<div data-aigentyc-chat>`)\n * 3. SlotsProvider\n * 4. ChatContextProvider\n * 5. LiveChatProvider (conditional on `enableLiveChat`)\n * 6. PreviewEmbedProvider\n */\nexport function ChatProvider(props: ChatProviderProps) {\n const {\n children,\n projectId,\n apiEndpoint,\n apiKey,\n clientName,\n language,\n translations,\n theme,\n slots,\n enableLiveChat = false,\n chatServiceUrl,\n persistMessages: _persistMessages,\n maxMessages: _maxMessages,\n questions: _questions,\n ...rest\n } = props;\n\n const callbacks = pickCallbacks(rest as Record<string, unknown>);\n const config = { projectId, apiEndpoint, apiKey, clientName };\n\n // Flatten translations from per-language map into single overrides.\n const langCode = language ?? \"en\";\n const translationOverrides = translations?.[langCode] as Partial<TranslationMap> | undefined;\n\n const liveChatUrl = chatServiceUrl ?? apiEndpoint;\n const inner = enableLiveChat && liveChatUrl && apiKey ? (\n <LiveChatProvider\n chatServiceUrl={liveChatUrl}\n apiKey={apiKey}\n projectId={projectId || \"default\"}\n sessionId=\"default\"\n >\n <PreviewEmbedProvider>{children}</PreviewEmbedProvider>\n </LiveChatProvider>\n ) : (\n <PreviewEmbedProvider>{children}</PreviewEmbedProvider>\n );\n\n return (\n <I18nProvider language={language} translations={translationOverrides}>\n <ThemeProvider theme={theme}>\n <SlotsProvider slots={slots as never}>\n <ChatContextProvider\n config={config}\n callbacks={callbacks}\n >\n {inner}\n </ChatContextProvider>\n </SlotsProvider>\n </ThemeProvider>\n </I18nProvider>\n );\n}\n","\"use client\";\n\n/**\n * Chat — Level 1 drop-in embed component.\n *\n * Wraps everything in `<ChatProvider>` internally and renders `<ChatInterface />`\n * inline (no floating button, no overlay). Use this when you want to embed a\n * chat directly inside a page layout.\n */\n\nimport type { ChatProviderProps } from \"../core/types\";\nimport { ChatProvider } from \"../providers/ChatProvider\";\nimport { ChatInterface } from \"./ChatInterface\";\n\nexport interface ChatProps extends ChatProviderProps {\n /** Optional className forwarded to the ChatInterface root. */\n className?: string;\n}\n\nexport function Chat({ className, children, ...providerProps }: ChatProps) {\n return (\n <ChatProvider {...(providerProps as unknown as React.ComponentProps<typeof ChatProvider>)}>\n <div className={className}>\n <ChatInterface />\n {children}\n </div>\n </ChatProvider>\n );\n}\n\nexport default Chat;\n","\"use client\";\n\n/**\n * Top-level widget (Level 1 API).\n *\n * Composes ChatProvider internally and renders FloatingButton, ChatInterface,\n * LiveChatPanel, and PreviewEmbedPanel based on widget mode.\n */\n\nimport { useState, useCallback, useEffect, useMemo } from \"react\";\nimport { ChatProvider } from \"../providers/ChatProvider\";\nimport type { ChatProviderProps } from \"../core/types\";\nimport { useIsMobile } from \"../hooks/use-mobile\";\nimport { cn } from \"../core/utils\";\nimport { ChatInterface } from \"./ChatInterface\";\nimport { FloatingButton } from \"./FloatingButton\";\nimport { LiveChatPanel, MobileLiveChatDrawer } from \"./LiveChatPanel\";\nimport { PreviewEmbedPanel } from \"./PreviewEmbedPanel\";\nimport { usePreviewEmbed } from \"../providers/PreviewEmbedProvider\";\nimport { useSlots, renderSlot } from \"../providers/SlotsContext\";\n\n/** Widget placement mode. */\nexport type WidgetMode = \"floating\" | \"inline\" | \"trigger\";\n\nexport interface ChatWidgetProps extends ChatProviderProps {\n\t/** How the widget is rendered. Default \"floating\". */\n\tmode?: WidgetMode;\n\t/** Fixed position for the floating button. Default \"bottom-right\". */\n\tposition?: \"bottom-right\" | \"bottom-left\" | \"top-right\" | \"top-left\";\n\tpositionMobile?: \"bottom-right\" | \"bottom-left\" | \"top-right\" | \"top-left\";\n\t/** Controlled open state. */\n\tisOpen?: boolean;\n\t/** Fired whenever the widget opens/closes. */\n\tonOpenChange?: (open: boolean) => void;\n\t/** Message to pre-fill and auto-submit on open. */\n\tpendingMessage?: string | null;\n\t/** Overlay z-index (defaults to 9999). */\n\tzIndex?: number;\n\n\t// Floating button customisation\n\tgreetingText?: string;\n\tgreetingOffsetX?: string;\n\tgreetingOffsetY?: string;\n\tgreetingMaxWidth?: string;\n\tbuttonOffsetXMobile?: string;\n\tbuttonOffsetYMobile?: string;\n\tbuttonOffsetXDesktop?: string;\n\tbuttonOffsetYDesktop?: string;\n\tbuttonIconUrl?: string;\n\tbuttonImageUrl?: string;\n\tbuttonImageUrlMobile?: string;\n\tbuttonWidth?: string;\n\tbuttonHeight?: string;\n\tbuttonIconSize?: string;\n\tbuttonWidthMobile?: string;\n\tbuttonHeightMobile?: string;\n\tbuttonIconSizeMobile?: string;\n\tbuttonBgColor?: string;\n\tbuttonBorderRadius?: string;\n\thideGreeting?: boolean;\n\n\t// Welcome-page customisation (passed through to ChatInterface)\n\tlogoUrl?: string;\n\twelcomeTitle?: string;\n\twelcomeSubtitle?: string;\n\thideWelcomeHeader?: boolean;\n\tfooterText?: string;\n\thideHeader?: boolean;\n\tshowFirstMessage?: boolean;\n\tquestionsLayout?: \"vertical\" | \"horizontal\";\n\tquestionsLayoutMobile?: \"vertical\" | \"horizontal\";\n}\n\n/** Bridges the \"widget-preview-open\" custom event to the PreviewEmbed context. */\nfunction PreviewEventBridge() {\n\tconst previewEmbed = usePreviewEmbed();\n\n\tuseEffect(() => {\n\t\tif (!previewEmbed || typeof window === \"undefined\") return;\n\t\tconst handler = (e: Event) => {\n\t\t\tconst { url, title, description } = (e as CustomEvent).detail || {};\n\t\t\tif (url) previewEmbed.openPreview({ url, title, description });\n\t\t};\n\t\twindow.addEventListener(\"widget-preview-open\", handler);\n\t\treturn () => window.removeEventListener(\"widget-preview-open\", handler);\n\t}, [previewEmbed]);\n\n\treturn null;\n}\n\n/** Mobile preview drawer — slides up from bottom of the widget. */\nfunction MobilePreviewDrawer() {\n\tconst previewEmbed = usePreviewEmbed();\n\tconst isVisible = !!previewEmbed?.preview;\n\tconst preview = previewEmbed?.preview;\n\tconst closePreview = previewEmbed?.closePreview;\n\n\treturn (\n\t\t<>\n\t\t\t<div\n\t\t\t\tclassName=\"absolute inset-0 z-40 bg-black/50\"\n\t\t\t\tstyle={{\n\t\t\t\t\topacity: isVisible ? 1 : 0,\n\t\t\t\t\tpointerEvents: isVisible ? \"auto\" : \"none\",\n\t\t\t\t\ttransition: \"opacity 200ms ease-out\",\n\t\t\t\t}}\n\t\t\t\tonClick={closePreview}\n\t\t\t/>\n\t\t\t<div\n\t\t\t\tclassName=\"absolute inset-x-0 bottom-0 z-50 rounded-t-2xl border-t shadow-2xl\"\n\t\t\t\tstyle={{\n\t\t\t\t\tbackgroundColor: \"var(--ac-background)\",\n\t\t\t\t\tborderColor: \"var(--ac-border)\",\n\t\t\t\t\theight: \"calc(100dvh - 150px)\",\n\t\t\t\t\ttransform: isVisible ? \"translateY(0)\" : \"translateY(100%)\",\n\t\t\t\t\ttransition: \"transform 300ms cubic-bezier(0.32, 0.72, 0, 1)\",\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<div className=\"flex justify-center pt-3 pb-1\">\n\t\t\t\t\t<div className=\"w-[100px] h-2 rounded-full bg-muted\" />\n\t\t\t\t</div>\n\t\t\t\t<div className=\"px-5 py-3 flex items-center justify-between\">\n\t\t\t\t\t<div className=\"min-w-0\">\n\t\t\t\t\t\t<h3 className=\"font-medium text-sm truncate\" style={{ color: \"var(--ac-text)\" }}>\n\t\t\t\t\t\t\t{preview?.title || \"Preview\"}\n\t\t\t\t\t\t</h3>\n\t\t\t\t\t\t{preview?.description && (\n\t\t\t\t\t\t\t<p className=\"text-xs text-muted-foreground mt-0.5 truncate\">{preview.description}</p>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={closePreview}\n\t\t\t\t\t\tclassName=\"shrink-0 w-8 h-8 rounded-full border flex items-center justify-center hover:bg-muted transition-colors ml-3\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<span className=\"sr-only\">Close</span>×\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"px-4 pb-4 flex-1\" style={{ height: \"calc(100% - 80px)\" }}>\n\t\t\t\t\t{preview && (\n\t\t\t\t\t\t<iframe\n\t\t\t\t\t\t\tkey={preview.url}\n\t\t\t\t\t\t\tsrc={preview.url}\n\t\t\t\t\t\t\tclassName=\"w-full h-full rounded-xl border-none\"\n\t\t\t\t\t\t\tsandbox=\"allow-scripts allow-same-origin allow-forms allow-popups allow-presentation\"\n\t\t\t\t\t\t\ttitle={preview.title || \"Preview\"}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</>\n\t);\n}\n\n/** Props for the inner widget shell — does not include ChatProvider config. */\ntype ChatWidgetInnerProps = Omit<\n\tChatWidgetProps,\n\tkeyof ChatProviderProps | \"children\"\n> & { language?: string };\n\n/** Inner component — rendered inside ChatProvider so it can read context. */\nfunction ChatWidgetInner({\n\tmode = \"floating\",\n\tposition = \"bottom-right\",\n\tpositionMobile,\n\tisOpen: controlledIsOpen,\n\tonOpenChange,\n\tpendingMessage: initialPendingMessage,\n\tzIndex,\n\tgreetingText,\n\tgreetingOffsetX,\n\tgreetingOffsetY,\n\tgreetingMaxWidth,\n\tbuttonOffsetXMobile,\n\tbuttonOffsetYMobile,\n\tbuttonOffsetXDesktop,\n\tbuttonOffsetYDesktop,\n\tbuttonIconUrl,\n\tbuttonImageUrl,\n\tbuttonImageUrlMobile,\n\tbuttonWidth,\n\tbuttonHeight,\n\tbuttonIconSize,\n\tbuttonWidthMobile,\n\tbuttonHeightMobile,\n\tbuttonIconSizeMobile,\n\tbuttonBgColor,\n\tbuttonBorderRadius,\n\thideGreeting,\n\tlogoUrl,\n\twelcomeTitle,\n\twelcomeSubtitle,\n\thideWelcomeHeader,\n\tfooterText,\n\thideHeader,\n\tshowFirstMessage,\n\tquestionsLayout,\n\tquestionsLayoutMobile,\n\tlanguage,\n}: ChatWidgetInnerProps) {\n\tconst [internalIsOpen, setInternalIsOpen] = useState(false);\n\tconst [pendingMessage, setPendingMessage] = useState<string | null>(initialPendingMessage ?? null);\n\tconst isMobile = useIsMobile();\n\tconst slots = useSlots();\n\n\tuseEffect(() => {\n\t\tif (controlledIsOpen === true) setInternalIsOpen(true);\n\t}, [controlledIsOpen]);\n\n\tconst isOpen = internalIsOpen;\n\n\t// Lock body scroll when open (except in inline mode)\n\tuseEffect(() => {\n\t\tif (mode === \"inline\" || typeof document === \"undefined\") return;\n\t\tif (isOpen) {\n\t\t\tconst originalStyle = window.getComputedStyle(document.body).overflow;\n\t\t\tdocument.body.style.overflow = \"hidden\";\n\t\t\treturn () => {\n\t\t\t\tdocument.body.style.overflow = originalStyle;\n\t\t\t};\n\t\t}\n\t}, [isOpen, mode]);\n\n\tconst handleOpen = useCallback(() => {\n\t\tsetInternalIsOpen(true);\n\t\tonOpenChange?.(true);\n\t}, [onOpenChange]);\n\n\tconst handleClose = useCallback(() => {\n\t\tsetInternalIsOpen(false);\n\t\tonOpenChange?.(false);\n\t}, [onOpenChange]);\n\n\tconst handleToggle = useCallback(() => {\n\t\tif (isOpen) handleClose();\n\t\telse handleOpen();\n\t}, [isOpen, handleOpen, handleClose]);\n\n\tconst isRightSide = position === \"bottom-right\" || position === \"top-right\";\n\tconst dirRTL = language === \"he\";\n\n\tconst chatInterfaceProps = useMemo(\n\t\t() => ({\n\t\t\tisOpen,\n\t\t\tonClose: handleClose,\n\t\t\tlogoUrl,\n\t\t\twelcomeTitle,\n\t\t\twelcomeSubtitle,\n\t\t\thideWelcomeHeader,\n\t\t\tfooterText,\n\t\t\thideHeader,\n\t\t\tshowFirstMessage,\n\t\t\tquestionsLayout,\n\t\t\tquestionsLayoutMobile,\n\t\t\tpendingMessage,\n\t\t\tonPendingMessageConsumed: () => setPendingMessage(null),\n\t\t}),\n\t\t[isOpen, handleClose, logoUrl, welcomeTitle, welcomeSubtitle, hideWelcomeHeader, footerText, hideHeader, showFirstMessage, questionsLayout, questionsLayoutMobile, pendingMessage],\n\t);\n\n\t// Inline mode\n\tif (mode === \"inline\") {\n\t\treturn (\n\t\t\t<div className=\"flex flex-col w-full h-full\" dir={dirRTL ? \"rtl\" : \"ltr\"} style={{ backgroundColor: \"var(--ac-background)\" }}>\n\t\t\t\t<ChatInterface {...chatInterfaceProps} />\n\t\t\t</div>\n\t\t);\n\t}\n\n\tconst panelZIndex = zIndex || 9999;\n\n\t// Floating button slot props\n\tconst floatingButtonProps = {\n\t\tonClick: handleToggle,\n\t\tposition,\n\t\tpositionMobile,\n\t\tisOpen,\n\t\tgreeting: greetingText,\n\t\tgreetingOffsetX,\n\t\tgreetingOffsetY,\n\t\tgreetingMaxWidth,\n\t\tbuttonOffsetXMobile,\n\t\tbuttonOffsetYMobile,\n\t\tbuttonOffsetXDesktop,\n\t\tbuttonOffsetYDesktop,\n\t\tbuttonIconUrl,\n\t\tbuttonImageUrl,\n\t\tbuttonImageUrlMobile,\n\t\tbuttonWidth,\n\t\tbuttonHeight,\n\t\tbuttonIconSize,\n\t\tbuttonWidthMobile,\n\t\tbuttonHeightMobile,\n\t\tbuttonIconSizeMobile,\n\t\tbuttonBgColor,\n\t\tbuttonBorderRadius,\n\t\tzIndex: zIndex || 999999,\n\t\thideGreeting,\n\t};\n\n\treturn (\n\t\t<>\n\t\t\t<PreviewEventBridge />\n\n\t\t\t{/* Overlay */}\n\t\t\t<div\n\t\t\t\tclassName=\"fixed inset-0 bg-black/50 transition-opacity duration-300 ease-in-out\"\n\t\t\t\tstyle={{\n\t\t\t\t\tzIndex: panelZIndex - 1,\n\t\t\t\t\topacity: isOpen ? 1 : 0,\n\t\t\t\t\tpointerEvents: isOpen ? \"auto\" : \"none\",\n\t\t\t\t}}\n\t\t\t\tonClick={handleClose}\n\t\t\t/>\n\n\t\t\t{!isMobile && <PreviewEmbedPanel isOpen={isOpen} isRightSide={isRightSide} zIndex={panelZIndex - 1} />}\n\t\t\t{!isMobile && <LiveChatPanel isWidgetOpen={isOpen} isRightSide={isRightSide} zIndex={panelZIndex - 1} />}\n\n\t\t\t{/* Main chat panel */}\n\t\t\t<div\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"fixed flex flex-col p-0 shadow-2xl\",\n\t\t\t\t\tisMobile\n\t\t\t\t\t\t? \"inset-x-0 rounded-t-2xl border-t\"\n\t\t\t\t\t\t: cn(\"inset-y-0 w-full max-w-[780px]\", isRightSide ? \"right-0 border-l\" : \"left-0 border-r\"),\n\t\t\t\t)}\n\t\t\t\tdir={dirRTL ? \"rtl\" : \"ltr\"}\n\t\t\t\tstyle={{\n\t\t\t\t\tbackgroundColor: \"var(--ac-background)\",\n\t\t\t\t\tborderColor: \"var(--ac-border)\",\n\t\t\t\t\t...(isMobile\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\ttop: \"70px\",\n\t\t\t\t\t\t\t\tbottom: 0,\n\t\t\t\t\t\t\t\theight: \"calc(100dvh - 70px)\",\n\t\t\t\t\t\t\t\ttransform: isOpen ? \"translateY(0)\" : \"translateY(100%)\",\n\t\t\t\t\t\t\t\topacity: isOpen ? 1 : 0,\n\t\t\t\t\t\t\t\tpointerEvents: isOpen ? \"auto\" : \"none\",\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\ttransform: isOpen ? \"translateX(0)\" : isRightSide ? \"translateX(100%)\" : \"translateX(-100%)\",\n\t\t\t\t\t\t\t\topacity: isOpen ? 1 : 0,\n\t\t\t\t\t\t\t\tpointerEvents: isOpen ? \"auto\" : \"none\",\n\t\t\t\t\t\t\t}),\n\t\t\t\t\ttransition: \"transform 300ms ease-in-out\",\n\t\t\t\t\tzIndex: panelZIndex,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{isMobile && <MobilePreviewDrawer />}\n\t\t\t\t<MobileLiveChatDrawer />\n\n\t\t\t\t<ChatInterface {...chatInterfaceProps} />\n\t\t\t</div>\n\n\t\t\t{/* Floating button — hidden when open */}\n\t\t\t{!isOpen &&\n\t\t\t\trenderSlot(\n\t\t\t\t\t\"floatingButton\",\n\t\t\t\t\tfloatingButtonProps as never,\n\t\t\t\t\tFloatingButton as never,\n\t\t\t\t\tslots,\n\t\t\t\t)}\n\t\t</>\n\t);\n}\n\n/**\n * Top-level widget (Level 1 API). Composes ChatProvider internally and renders\n * the correct shell based on `mode`.\n */\nexport function ChatWidget(props: ChatWidgetProps) {\n\t// Split ChatProviderProps from widget-shell props.\n\tconst {\n\t\t// Widget shell props consumed by inner component (also forwarded separately)\n\t\tmode,\n\t\tposition,\n\t\tpositionMobile,\n\t\tisOpen,\n\t\tonOpenChange,\n\t\tpendingMessage,\n\t\tzIndex,\n\t\tgreetingText,\n\t\tgreetingOffsetX,\n\t\tgreetingOffsetY,\n\t\tgreetingMaxWidth,\n\t\tbuttonOffsetXMobile,\n\t\tbuttonOffsetYMobile,\n\t\tbuttonOffsetXDesktop,\n\t\tbuttonOffsetYDesktop,\n\t\tbuttonIconUrl,\n\t\tbuttonImageUrl,\n\t\tbuttonImageUrlMobile,\n\t\tbuttonWidth,\n\t\tbuttonHeight,\n\t\tbuttonIconSize,\n\t\tbuttonWidthMobile,\n\t\tbuttonHeightMobile,\n\t\tbuttonIconSizeMobile,\n\t\tbuttonBgColor,\n\t\tbuttonBorderRadius,\n\t\thideGreeting,\n\t\tlogoUrl,\n\t\twelcomeTitle,\n\t\twelcomeSubtitle,\n\t\thideWelcomeHeader,\n\t\tfooterText,\n\t\thideHeader,\n\t\tshowFirstMessage,\n\t\tquestionsLayout,\n\t\tquestionsLayoutMobile,\n\t\tchildren: _children,\n\t\t...providerProps\n\t} = props;\n\n\treturn (\n\t\t<ChatProvider {...providerProps}>\n\t\t\t<ChatWidgetInner\n\t\t\t\tmode={mode}\n\t\t\t\tposition={position}\n\t\t\t\tpositionMobile={positionMobile}\n\t\t\t\tisOpen={isOpen}\n\t\t\t\tonOpenChange={onOpenChange}\n\t\t\t\tpendingMessage={pendingMessage}\n\t\t\t\tzIndex={zIndex}\n\t\t\t\tgreetingText={greetingText}\n\t\t\t\tgreetingOffsetX={greetingOffsetX}\n\t\t\t\tgreetingOffsetY={greetingOffsetY}\n\t\t\t\tgreetingMaxWidth={greetingMaxWidth}\n\t\t\t\tbuttonOffsetXMobile={buttonOffsetXMobile}\n\t\t\t\tbuttonOffsetYMobile={buttonOffsetYMobile}\n\t\t\t\tbuttonOffsetXDesktop={buttonOffsetXDesktop}\n\t\t\t\tbuttonOffsetYDesktop={buttonOffsetYDesktop}\n\t\t\t\tbuttonIconUrl={buttonIconUrl}\n\t\t\t\tbuttonImageUrl={buttonImageUrl}\n\t\t\t\tbuttonImageUrlMobile={buttonImageUrlMobile}\n\t\t\t\tbuttonWidth={buttonWidth}\n\t\t\t\tbuttonHeight={buttonHeight}\n\t\t\t\tbuttonIconSize={buttonIconSize}\n\t\t\t\tbuttonWidthMobile={buttonWidthMobile}\n\t\t\t\tbuttonHeightMobile={buttonHeightMobile}\n\t\t\t\tbuttonIconSizeMobile={buttonIconSizeMobile}\n\t\t\t\tbuttonBgColor={buttonBgColor}\n\t\t\t\tbuttonBorderRadius={buttonBorderRadius}\n\t\t\t\thideGreeting={hideGreeting}\n\t\t\t\tlogoUrl={logoUrl}\n\t\t\t\twelcomeTitle={welcomeTitle}\n\t\t\t\twelcomeSubtitle={welcomeSubtitle}\n\t\t\t\thideWelcomeHeader={hideWelcomeHeader}\n\t\t\t\tfooterText={footerText}\n\t\t\t\thideHeader={hideHeader}\n\t\t\t\tshowFirstMessage={showFirstMessage}\n\t\t\t\tquestionsLayout={questionsLayout}\n\t\t\t\tquestionsLayoutMobile={questionsLayoutMobile}\n\t\t\t\tlanguage={providerProps.language as string | undefined}\n\t\t\t/>\n\t\t</ChatProvider>\n\t);\n}\n"]}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supported interaction types for analytics.
|
|
3
|
+
*/
|
|
4
|
+
type InteractionType = "link_click" | "suggestion_click" | "source_click" | "copy" | "expand" | "collapse" | "button_click" | "landing_question_click" | "tool_ui_interaction" | "tool_action_click" | "tool_order_sample" | "tool_view_details" | "tool_back_to_list" | "tool_gallery_image_click" | "tool_contact_click" | "tool_pagination_next" | "tool_pagination_prev" | "feedback" | "flag" | "page_view";
|
|
5
|
+
/**
|
|
6
|
+
* Arbitrary metadata attached to a tracked interaction.
|
|
7
|
+
*/
|
|
8
|
+
interface InteractionMetadata {
|
|
9
|
+
/** URL that was interacted with */
|
|
10
|
+
url?: string;
|
|
11
|
+
/** Visible text of the element */
|
|
12
|
+
text?: string;
|
|
13
|
+
/** Position / index in a list */
|
|
14
|
+
position?: number;
|
|
15
|
+
/** DOM element type (e.g. `"a"`, `"button"`) */
|
|
16
|
+
elementType?: string;
|
|
17
|
+
/** Additional key-value pairs */
|
|
18
|
+
[key: string]: unknown;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Parameters for a single `trackInteraction` call.
|
|
22
|
+
*/
|
|
23
|
+
interface TrackInteractionParams {
|
|
24
|
+
/** Interaction type */
|
|
25
|
+
type: InteractionType;
|
|
26
|
+
/** Identifier for the interacted element */
|
|
27
|
+
target?: string;
|
|
28
|
+
/** Human-readable label */
|
|
29
|
+
label?: string;
|
|
30
|
+
/** Extra metadata */
|
|
31
|
+
metadata?: InteractionMetadata;
|
|
32
|
+
/** Associated message ID (for per-message analytics) */
|
|
33
|
+
messageId?: string;
|
|
34
|
+
/** Server event ID (for correlation) */
|
|
35
|
+
eventId?: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Options for the `useInteractionTracker` hook.
|
|
39
|
+
*/
|
|
40
|
+
interface UseInteractionTrackerOptions {
|
|
41
|
+
/** Base API endpoint */
|
|
42
|
+
apiEndpoint: string;
|
|
43
|
+
/** Aigentyc project ID */
|
|
44
|
+
projectId: string;
|
|
45
|
+
/** Bearer API key (optional — falls back to session cookies) */
|
|
46
|
+
apiKey?: string;
|
|
47
|
+
/** Current page URL for contextual tracking */
|
|
48
|
+
pageUrl?: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* React hook to track user interactions via the KB analytics API.
|
|
52
|
+
*
|
|
53
|
+
* Interactions are batched (up to `BATCH_SIZE`) and flushed after
|
|
54
|
+
* `BATCH_DELAY_MS` of inactivity.
|
|
55
|
+
*
|
|
56
|
+
* @param sessionId - Current chat session ID (tracking is skipped if `null`)
|
|
57
|
+
* @param options - API configuration
|
|
58
|
+
* @returns `{ trackInteraction, flushOnUnmount }`
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```tsx
|
|
62
|
+
* const { trackInteraction, flushOnUnmount } = useInteractionTracker(sessionId, {
|
|
63
|
+
* apiEndpoint: "https://api.example.com",
|
|
64
|
+
* projectId: "abc",
|
|
65
|
+
* });
|
|
66
|
+
*
|
|
67
|
+
* useEffect(() => () => flushOnUnmount(), [flushOnUnmount]);
|
|
68
|
+
*
|
|
69
|
+
* trackInteraction({ type: "link_click", target: "https://example.com" });
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
declare function useInteractionTracker(sessionId: string | null, options: UseInteractionTrackerOptions): {
|
|
73
|
+
trackInteraction: (params: TrackInteractionParams) => void;
|
|
74
|
+
flushOnUnmount: () => void;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Generate a unique session ID for analytics.
|
|
78
|
+
*
|
|
79
|
+
* Format: `kb-<timestamp>-<random>`
|
|
80
|
+
*/
|
|
81
|
+
declare function generateSessionId(): string;
|
|
82
|
+
|
|
83
|
+
export { type InteractionMetadata as I, type TrackInteractionParams as T, type UseInteractionTrackerOptions as U, type InteractionType as a, generateSessionId as g, useInteractionTracker as u };
|