@xapp/chat-widget 1.96.4 → 1.97.1
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/components/ActionBar/ActionBar.d.ts +0 -0
- package/dist/components/ActionBar/index.d.ts +0 -0
- package/dist/index.css +1 -1
- package/dist/index.es.js +135 -20
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +135 -20
- package/dist/index.js.map +1 -1
- package/dist/utils/formPage.d.ts +0 -0
- package/dist/xapp-chat-widget.css +1 -1
- package/dist/xapp-chat-widget.js +4 -4
- package/dist/xapp-chat-widget.js.map +1 -1
- package/package.json +5 -5
package/dist/index.es.js
CHANGED
|
@@ -320,13 +320,14 @@ const color_1 = color;
|
|
|
320
320
|
/** Fallback when a crawl found no branding. Deliberately neutral. */
|
|
321
321
|
const DEFAULT_PRIMARY = "#1AA7DC";
|
|
322
322
|
function buildChatWidgetChannel(props) {
|
|
323
|
+
var _a;
|
|
323
324
|
const { appId, apiUrl, mcpUrl, formWidgetKey, phoneNumber } = props;
|
|
325
|
+
const businessName = (_a = props.businessName) === null || _a === void 0 ? void 0 : _a.trim();
|
|
324
326
|
// Only a colour whose contrast can actually be computed, so the background
|
|
325
327
|
// and the text on it are always a matched pair rather than one scraped
|
|
326
328
|
// value and one guess.
|
|
327
329
|
const primaryColor = (0, color_1.usableColorOr)(props.primaryColor, DEFAULT_PRIMARY);
|
|
328
|
-
return {
|
|
329
|
-
type: "chat-widget",
|
|
330
|
+
return Object.assign({ type: "chat-widget",
|
|
330
331
|
// MCP by default. The widget runs on a public page, so homeowner mode
|
|
331
332
|
// — which is unauthenticated and carries the appId in the url — is the
|
|
332
333
|
// only one that can work there; business_owner needs a token, and a
|
|
@@ -337,10 +338,7 @@ function buildChatWidgetChannel(props) {
|
|
|
337
338
|
mcp: {
|
|
338
339
|
mode: "homeowner"
|
|
339
340
|
}
|
|
340
|
-
},
|
|
341
|
-
theme: buildChatTheme(primaryColor, props.secondaryColor),
|
|
342
|
-
actionBar: buildActionBar({ apiUrl, formWidgetKey, phoneNumber })
|
|
343
|
-
};
|
|
341
|
+
}, theme: buildChatTheme(primaryColor, props.secondaryColor), actionBar: buildActionBar({ apiUrl, formWidgetKey, phoneNumber }) }, (businessName ? { botName: businessName } : {}));
|
|
344
342
|
}
|
|
345
343
|
/**
|
|
346
344
|
* The dock of buttons that replaces the plain chat bubble.
|
|
@@ -932,9 +930,39 @@ var MOBILE_MEDIA_QUERY = "(max-width: 640px), (max-height: 480px) and (pointer:
|
|
|
932
930
|
* Two concurrent bars would fight over it, and either one unmounting would clear it.
|
|
933
931
|
*/
|
|
934
932
|
var ACTION_BAR_HEIGHT_VAR = "--xapp-action-bar-height";
|
|
933
|
+
/**
|
|
934
|
+
* Whether pressing this button ends up in the form widget.
|
|
935
|
+
*
|
|
936
|
+
* `schedule` is the same form-widget infrastructure with a calendar icon, so it is the
|
|
937
|
+
* same button as far as this question goes. XappMedia/chat-widget#1626.
|
|
938
|
+
*/
|
|
939
|
+
function opensFormWidget(button) {
|
|
940
|
+
return lib.isActionBarFormButton(button) || lib.isActionBarScheduleButton(button);
|
|
941
|
+
}
|
|
942
|
+
/**
|
|
943
|
+
* Which of a bar's configured buttons would actually render.
|
|
944
|
+
*
|
|
945
|
+
* Exported because the decision is needed in two places: here, to render, and in
|
|
946
|
+
* `ChatWidget`, to know whether the bar has anything left to show and whether anything on
|
|
947
|
+
* the page can still open the form widget. Two copies of this predicate would drift.
|
|
948
|
+
*/
|
|
949
|
+
function visibleActionBarButtons(buttons, options) {
|
|
950
|
+
if (buttons === void 0) { buttons = []; }
|
|
951
|
+
if (options === void 0) { options = {}; }
|
|
952
|
+
var chatDisabled = options.chatDisabled, formDisabled = options.formDisabled;
|
|
953
|
+
return buttons.filter(function (button) {
|
|
954
|
+
if (chatDisabled && lib.isActionBarChatButton(button)) {
|
|
955
|
+
return false;
|
|
956
|
+
}
|
|
957
|
+
if (formDisabled && opensFormWidget(button)) {
|
|
958
|
+
return false;
|
|
959
|
+
}
|
|
960
|
+
return true;
|
|
961
|
+
});
|
|
962
|
+
}
|
|
935
963
|
var ActionBar = function (_a) {
|
|
936
964
|
var _b, _c;
|
|
937
|
-
var config = _a.config, visible = _a.visible, chatDisabled = _a.chatDisabled, _d = _a.hasUserInteracted, hasUserInteracted = _d === void 0 ? false : _d, onChatClick = _a.onChatClick, onChatMinimize = _a.onChatMinimize, onFormClick = _a.onFormClick, onCtaDismiss = _a.onCtaDismiss;
|
|
965
|
+
var config = _a.config, visible = _a.visible, chatDisabled = _a.chatDisabled, formDisabled = _a.formDisabled, _d = _a.hasUserInteracted, hasUserInteracted = _d === void 0 ? false : _d, onChatClick = _a.onChatClick, onChatMinimize = _a.onChatMinimize, onFormClick = _a.onFormClick, onCtaDismiss = _a.onCtaDismiss;
|
|
938
966
|
var _e = useState(false), isMobile = _e[0], setIsMobile = _e[1];
|
|
939
967
|
// An explicit override can only be a width; without one we ask the same question the
|
|
940
968
|
// stylesheets ask, so the two cannot disagree. A survey of production on 2026-08-19
|
|
@@ -1005,10 +1033,9 @@ var ActionBar = function (_a) {
|
|
|
1005
1033
|
document.documentElement.style.removeProperty(ACTION_BAR_HEIGHT_VAR);
|
|
1006
1034
|
};
|
|
1007
1035
|
}, [isMobile]);
|
|
1008
|
-
//
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
: config.buttons;
|
|
1036
|
+
// Drop the buttons this page has no use for - chat when chat is disabled, form/schedule
|
|
1037
|
+
// when the form already is the page.
|
|
1038
|
+
var filteredButtons = visibleActionBarButtons(config.buttons, { chatDisabled: chatDisabled, formDisabled: formDisabled });
|
|
1012
1039
|
// Build class names - ActionBar stays visible even when chat is open
|
|
1013
1040
|
var classNames = [
|
|
1014
1041
|
"xapp-action-bar",
|
|
@@ -1021,7 +1048,7 @@ var ActionBar = function (_a) {
|
|
|
1021
1048
|
// - Must have CTA config with a message
|
|
1022
1049
|
// - Chat must not be visible (user hasn't opened it)
|
|
1023
1050
|
// - Chat must not be disabled
|
|
1024
|
-
var hasChatButton =
|
|
1051
|
+
var hasChatButton = filteredButtons.some(lib.isActionBarChatButton);
|
|
1025
1052
|
var showCta = ((_c = config.cta) === null || _c === void 0 ? void 0 : _c.message) && !visible && !chatDisabled && hasChatButton;
|
|
1026
1053
|
var handleCtaClick = function () {
|
|
1027
1054
|
onChatClick();
|
|
@@ -1029,6 +1056,13 @@ var ActionBar = function (_a) {
|
|
|
1029
1056
|
var handleCtaDismiss = function () {
|
|
1030
1057
|
onCtaDismiss === null || onCtaDismiss === void 0 ? void 0 : onCtaDismiss();
|
|
1031
1058
|
};
|
|
1059
|
+
// A bar with nothing in it is a bare strip of chrome the visitor cannot use. The bar
|
|
1060
|
+
// renders on `actionBar.enabled` alone, so an App configured with only Form + Schedule
|
|
1061
|
+
// filters down to zero on a form page - render nothing rather than an empty shell.
|
|
1062
|
+
// This is after the hooks on purpose; bailing earlier would change the hook order.
|
|
1063
|
+
if (filteredButtons.length === 0) {
|
|
1064
|
+
return null;
|
|
1065
|
+
}
|
|
1032
1066
|
return (jsxs("div", { ref: barRef, className: classNames, role: "toolbar", "aria-label": "Chat actions", children: [showCta && (jsx("div", { className: "xapp-action-bar-cta-wrapper", children: jsx(ActionBarCta, { config: config.cta, isMobile: isMobile, onClick: handleCtaClick, onDismiss: handleCtaDismiss, hasUserInteracted: hasUserInteracted }) })), jsx("div", { className: "xapp-action-bar__buttons", children: filteredButtons.map(function (button) { return (jsx(ActionBarButton, { button: button, chatActive: visible, onChatClick: onChatClick, onChatMinimize: onChatMinimize, onFormClick: onFormClick, isMobile: isMobile }, button.id)); }) })] }));
|
|
1033
1067
|
};
|
|
1034
1068
|
|
|
@@ -12797,6 +12831,64 @@ function getSrcId(url) {
|
|
|
12797
12831
|
return res;
|
|
12798
12832
|
}
|
|
12799
12833
|
|
|
12834
|
+
/*! Copyright (c) 2026, XAPPmedia */
|
|
12835
|
+
/**
|
|
12836
|
+
* Body attribute a host page sets to declare "a form widget already *is* this page".
|
|
12837
|
+
*
|
|
12838
|
+
* The standalone contact/booking page (contact.xapp.ai, book.xapp.ai, sche.dule.pro)
|
|
12839
|
+
* renders a docked form-widget as its whole content and then injects the chat widget on
|
|
12840
|
+
* top of it. Without a signal, the injected widget cheerfully offers two more ways into
|
|
12841
|
+
* the same form - an ActionBar Contact/Book button and the form-widget's own side button.
|
|
12842
|
+
*
|
|
12843
|
+
* This is a declaration, not a detection: the page knows what it renders, the widget does
|
|
12844
|
+
* not. Sniffing the DOM for a docked form would be guesswork, and it would also fire on
|
|
12845
|
+
* pages that legitimately embed a form *and* want a separate one from the bar.
|
|
12846
|
+
*
|
|
12847
|
+
* The writer is `@xapp/form-widget`'s `useFormPageMarker` (used by `@xapp/contact-app`).
|
|
12848
|
+
* The two packages ship independently, so this string is the contract between them -
|
|
12849
|
+
* the same arrangement `[data-xapp-form-side-button]` already uses. Do not rename it on
|
|
12850
|
+
* one side only. XappMedia/chat-widget#1626.
|
|
12851
|
+
*/
|
|
12852
|
+
var FORM_PAGE_ATTRIBUTE = "data-xapp-form-page";
|
|
12853
|
+
/**
|
|
12854
|
+
* Whether a form widget is already the page, per the marker above.
|
|
12855
|
+
*/
|
|
12856
|
+
function isFormPage() {
|
|
12857
|
+
if (typeof document === "undefined" || !document.body) {
|
|
12858
|
+
return false;
|
|
12859
|
+
}
|
|
12860
|
+
return document.body.getAttribute(FORM_PAGE_ATTRIBUTE) === "true";
|
|
12861
|
+
}
|
|
12862
|
+
/**
|
|
12863
|
+
* Reactive form of {@link isFormPage}.
|
|
12864
|
+
*
|
|
12865
|
+
* The marker and the chat widget mount independently - the widget arrives from a
|
|
12866
|
+
* `<script>` tag, so it can win or lose the race against the page's own React tree.
|
|
12867
|
+
* Observing the attribute rather than reading it once means the filter settles correctly
|
|
12868
|
+
* whichever order they land in.
|
|
12869
|
+
*/
|
|
12870
|
+
function useIsFormPage() {
|
|
12871
|
+
var _a = useState(isFormPage), formPage = _a[0], setFormPage = _a[1];
|
|
12872
|
+
useEffect(function () {
|
|
12873
|
+
if (typeof document === "undefined" || !document.body) {
|
|
12874
|
+
return undefined;
|
|
12875
|
+
}
|
|
12876
|
+
// Re-read on mount: the marker may have appeared between the initial state and here.
|
|
12877
|
+
setFormPage(isFormPage());
|
|
12878
|
+
// jsdom has MutationObserver, but a customer's browser might not - an old browser
|
|
12879
|
+
// that reads the marker once is still better than one that throws on mount.
|
|
12880
|
+
if (typeof MutationObserver === "undefined") {
|
|
12881
|
+
return undefined;
|
|
12882
|
+
}
|
|
12883
|
+
var observer = new MutationObserver(function () {
|
|
12884
|
+
setFormPage(isFormPage());
|
|
12885
|
+
});
|
|
12886
|
+
observer.observe(document.body, { attributes: true, attributeFilter: [FORM_PAGE_ATTRIBUTE] });
|
|
12887
|
+
return function () { return observer.disconnect(); };
|
|
12888
|
+
}, []);
|
|
12889
|
+
return formPage;
|
|
12890
|
+
}
|
|
12891
|
+
|
|
12800
12892
|
function useChatServerVisitorId() {
|
|
12801
12893
|
var dispatch = useChatServerDispatch();
|
|
12802
12894
|
var clientVisitorId = useSelector(function (state) {
|
|
@@ -37041,6 +37133,21 @@ var ChatWidgetUI = function (props) {
|
|
|
37041
37133
|
log("Rendering - accountStatus: \"".concat(chatState.accountStatus, "\", connectionStatus: \"").concat(chatState.connection.connectionStatus, "\""));
|
|
37042
37134
|
var config = props.config, onConnectionStatusChange = props.onConnectionStatusChange;
|
|
37043
37135
|
var actionBarEnabled = ((_s = config === null || config === void 0 ? void 0 : config.actionBar) === null || _s === void 0 ? void 0 : _s.enabled) === true;
|
|
37136
|
+
// The host page declares this; the widget cannot work it out. On the standalone
|
|
37137
|
+
// contact/booking page the form already *is* the page, which makes every button that
|
|
37138
|
+
// only opens one redundant. XappMedia/chat-widget#1626.
|
|
37139
|
+
var isFormPage = useIsFormPage();
|
|
37140
|
+
var actionBarButtons = useMemo(function () {
|
|
37141
|
+
return actionBarEnabled && (config === null || config === void 0 ? void 0 : config.actionBar)
|
|
37142
|
+
? visibleActionBarButtons(config.actionBar.buttons, {
|
|
37143
|
+
chatDisabled: config.disabled,
|
|
37144
|
+
formDisabled: isFormPage,
|
|
37145
|
+
})
|
|
37146
|
+
: [];
|
|
37147
|
+
}, [actionBarEnabled, config === null || config === void 0 ? void 0 : config.actionBar, config === null || config === void 0 ? void 0 : config.disabled, isFormPage]);
|
|
37148
|
+
// A bar that filters down to nothing is a bare strip of chrome. Treat it as if the bar
|
|
37149
|
+
// were off, so the visitor still gets the plain chat button rather than an empty shell.
|
|
37150
|
+
var actionBarVisible = actionBarEnabled && actionBarButtons.length > 0;
|
|
37044
37151
|
// Disable greeting in preview mode
|
|
37045
37152
|
useGreeting(!isOffline && !props.preChatFormEnabled && visible && !previewMode);
|
|
37046
37153
|
var connectionStatus = chatState.connection.connectionStatus;
|
|
@@ -37050,23 +37157,31 @@ var ChatWidgetUI = function (props) {
|
|
|
37050
37157
|
}
|
|
37051
37158
|
}, [connectionStatus, onConnectionStatusChange]);
|
|
37052
37159
|
useExternalScript((_t = props.config) === null || _t === void 0 ? void 0 : _t.middlewareUrl);
|
|
37053
|
-
//
|
|
37160
|
+
// Only reach for form.xapp.ai when something on this page can still open the form.
|
|
37161
|
+
//
|
|
37162
|
+
// Loading it is not free: the script mounts a second form-widget instance whose wrapper
|
|
37163
|
+
// renders its own sticky "Contact Us" side button. On a page that already is the form
|
|
37164
|
+
// that button is a third way into the same thing, so not loading the script at all is
|
|
37165
|
+
// what actually removes it - hiding it in CSS only papers over the second instance.
|
|
37166
|
+
//
|
|
37167
|
+
// With no bar configured the side button IS the entry point, so that case still loads.
|
|
37168
|
+
var formWidgetNeeded = !isFormPage && (!actionBarEnabled || actionBarButtons.some(opensFormWidget));
|
|
37054
37169
|
useEffect(function () {
|
|
37055
|
-
if (config === null || config === void 0 ? void 0 : config.formWidgetKey) {
|
|
37170
|
+
if ((config === null || config === void 0 ? void 0 : config.formWidgetKey) && formWidgetNeeded) {
|
|
37056
37171
|
preloadFormWidgetScript(config.formWidgetKey);
|
|
37057
37172
|
}
|
|
37058
|
-
}, [config === null || config === void 0 ? void 0 : config.formWidgetKey]);
|
|
37173
|
+
}, [config === null || config === void 0 ? void 0 : config.formWidgetKey, formWidgetNeeded]);
|
|
37059
37174
|
// Set body attribute when actionBar is enabled (used by CSS to hide form-widget side button on mobile)
|
|
37060
37175
|
// Uses reference counting to handle multiple widget instances
|
|
37061
37176
|
useEffect(function () {
|
|
37062
|
-
if (
|
|
37177
|
+
if (actionBarVisible) {
|
|
37063
37178
|
// Increment reference count
|
|
37064
37179
|
var currentCount = parseInt(document.body.getAttribute("data-xapp-action-bar-count") || "0", 10);
|
|
37065
37180
|
document.body.setAttribute("data-xapp-action-bar-count", String(currentCount + 1));
|
|
37066
37181
|
document.body.setAttribute("data-xapp-action-bar-enabled", "true");
|
|
37067
37182
|
}
|
|
37068
37183
|
return function () {
|
|
37069
|
-
if (
|
|
37184
|
+
if (actionBarVisible) {
|
|
37070
37185
|
// Decrement reference count
|
|
37071
37186
|
var currentCount = parseInt(document.body.getAttribute("data-xapp-action-bar-count") || "0", 10);
|
|
37072
37187
|
var newCount = Math.max(0, currentCount - 1);
|
|
@@ -37079,7 +37194,7 @@ var ChatWidgetUI = function (props) {
|
|
|
37079
37194
|
}
|
|
37080
37195
|
}
|
|
37081
37196
|
};
|
|
37082
|
-
}, [
|
|
37197
|
+
}, [actionBarVisible]);
|
|
37083
37198
|
// This is a pseudo agent. It represent's the widget (shown in the header avatar for instance)
|
|
37084
37199
|
var widgetAgent = ((_u = chatState.agents["agent:robot"]) === null || _u === void 0 ? void 0 : _u.user) ||
|
|
37085
37200
|
(config === null || config === void 0 ? void 0 : config.agent) || {
|
|
@@ -37087,9 +37202,9 @@ var ChatWidgetUI = function (props) {
|
|
|
37087
37202
|
avatarPath: config.avatarUrl,
|
|
37088
37203
|
display_name: "Agent",
|
|
37089
37204
|
};
|
|
37090
|
-
return (jsxs(Fragment, { children: [jsxs("div", { className: "widget-container ".concat(modeClass, " ").concat(getVisibilityClass()).concat(
|
|
37205
|
+
return (jsxs(Fragment, { children: [jsxs("div", { className: "widget-container ".concat(modeClass, " ").concat(getVisibilityClass()).concat(actionBarVisible ? " widget-container--with-action-bar" : ""), children: [jsx(WidgetStylesheet, { theme: config === null || config === void 0 ? void 0 : config.theme }), jsx(ChatHeader, { accountStatus: chatState.accountStatus, refreshOnClick: handleRestartClick, minimizeOnClick: handleMinimizeClick, cancelOnClick: handleCancelClick, agent: widgetAgent, canRefresh: canRefresh, canMinimize: canMinimize, canCancel: canCancel, config: config === null || config === void 0 ? void 0 : config.header, menuConfig: config.menu, debugMode: (_x = (_w = (_v = props.config) === null || _v === void 0 ? void 0 : _v.connection) === null || _w === void 0 ? void 0 : _w.mcp) === null || _x === void 0 ? void 0 : _x.debugMode, onSubmit: handleOnSubmit }), jsx(MessageList, { visible: visible, queuePosition: chatState.queuePosition, isChatting: chatState.isChatting, isOffline: isOffline, messages: messages, agents: chatState.agents, agent: config === null || config === void 0 ? void 0 : config.agent, lastRatingRequestTimestamp: chatState.lastRatingRequestTimestamp, hasRating: chatState.hasRating, visitorId: chatState.visitorId, hasWsButton: !!chatState.wsButton, messageMiddleware: props.messageMiddleware, textTypingStatusEnabled: (_z = (_y = props.config) === null || _y === void 0 ? void 0 : _y.typingStatus) === null || _z === void 0 ? void 0 : _z.textTypingStatusEnabled, disableAutoScroll: props.disableAutoScroll, onSend: handleSendMessage, onWrite: handleWriteMessage, onOpenUrl: handleOpenUrl, minimizeOnClick: handleMinimizeClick }), jsx("div", { className: "xa-spinner-container ".concat(visible && connectionStatus === "pending" ? "visible" : ""), children: jsx("div", { className: "xa-spinner" }) }), connectionStatus === "offline" && jsx(ServerOffline, {}), chatState.wsButton && visible && (jsx(WsButton, { button: chatState.wsButton, onPress: handleWsButtonPress })), jsx(ChatFooter, { isAdmin: config === null || config === void 0 ? void 0 : config.isAdmin, isChatting: chatState.isChatting, placeholder: (_0 = config === null || config === void 0 ? void 0 : config.input) === null || _0 === void 0 ? void 0 : _0.placeholder, sendButtonIcon: (_2 = (_1 = config === null || config === void 0 ? void 0 : config.footer) === null || _1 === void 0 ? void 0 : _1.sendButton) === null || _2 === void 0 ? void 0 : _2.icon, sendButtonIconHover: (_4 = (_3 = config === null || config === void 0 ? void 0 : config.footer) === null || _3 === void 0 ? void 0 : _3.sendButton) === null || _4 === void 0 ? void 0 : _4.iconHover, sendButtonIconDisabled: (_6 = (_5 = config === null || config === void 0 ? void 0 : config.footer) === null || _5 === void 0 ? void 0 : _5.sendButton) === null || _6 === void 0 ? void 0 : _6.iconDisabled, visible: visible, hasWsButton: !!chatState.wsButton, menuConfig: (_7 = props.config) === null || _7 === void 0 ? void 0 : _7.menu, footerConfig: (_8 = props.config) === null || _8 === void 0 ? void 0 : _8.footer, inputConfig: (_9 = props.config) === null || _9 === void 0 ? void 0 : _9.input, disabled: previewMode, onChange: handleOnChange, onSubmit: handleOnSubmit, onFileUpload: handleFileUpload }), jsx("div", { className: "restartModal", ref: modalRef, onClick: handleRestartModalCloseClick, children: jsx(ModalContent, { onClose: handleRestartModalCloseClick, onReset: handleReset }) })] }), actionBarVisible && config.actionBar ? (jsxs(Fragment, { children: [jsx(ActionBar, { config: __assign(__assign({}, config.actionBar), {
|
|
37091
37206
|
// Use actionBar.cta if set, otherwise fall back to widget-level cta
|
|
37092
|
-
cta: (_10 = config.actionBar.cta) !== null && _10 !== void 0 ? _10 : config.cta }), visible: visible, chatDisabled: config.disabled, hasUserInteracted: (_11 = chatState.visuals) === null || _11 === void 0 ? void 0 : _11.hasInteracted, onChatClick: chatButtonOnClick, onChatMinimize: handleMinimizeClick, onFormClick: handleFormButtonClick, onCtaDismiss: handleCtaDismiss }), formModalOpen && activeFormConfig && (jsx(FormModal, { config: activeFormConfig, widgetEnv: config, onClose: handleFormModalClose }))] })) : (jsx(ChatButton, { addClass: visible ? "visible" : "", onClick: chatButtonOnClick, config: config === null || config === void 0 ? void 0 : config.cta, imageUrl: (_12 = config === null || config === void 0 ? void 0 : config.chatButton) === null || _12 === void 0 ? void 0 : _12.imageUrl, visible: visible, hasInteracted: (_13 = chatState.visuals) === null || _13 === void 0 ? void 0 : _13.hasInteracted, onCtaDismiss: handleCtaDismiss })), jsx(ErrorOverlay, { enableErrorOverlay: config === null || config === void 0 ? void 0 : config.enableErrorOverlay })] }));
|
|
37207
|
+
cta: (_10 = config.actionBar.cta) !== null && _10 !== void 0 ? _10 : config.cta }), visible: visible, chatDisabled: config.disabled, formDisabled: isFormPage, hasUserInteracted: (_11 = chatState.visuals) === null || _11 === void 0 ? void 0 : _11.hasInteracted, onChatClick: chatButtonOnClick, onChatMinimize: handleMinimizeClick, onFormClick: handleFormButtonClick, onCtaDismiss: handleCtaDismiss }), formModalOpen && activeFormConfig && (jsx(FormModal, { config: activeFormConfig, widgetEnv: config, onClose: handleFormModalClose }))] })) : (jsx(ChatButton, { addClass: visible ? "visible" : "", onClick: chatButtonOnClick, config: config === null || config === void 0 ? void 0 : config.cta, imageUrl: (_12 = config === null || config === void 0 ? void 0 : config.chatButton) === null || _12 === void 0 ? void 0 : _12.imageUrl, visible: visible, hasInteracted: (_13 = chatState.visuals) === null || _13 === void 0 ? void 0 : _13.hasInteracted, onCtaDismiss: handleCtaDismiss })), jsx(ErrorOverlay, { enableErrorOverlay: config === null || config === void 0 ? void 0 : config.enableErrorOverlay })] }));
|
|
37093
37208
|
};
|
|
37094
37209
|
/**
|
|
37095
37210
|
* Top-level wrapper that dispatches between preview mode and connected mode.
|