andy-widget-react 2.0.6 → 2.1.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/README.md +2 -0
- package/dist/index.cjs +67 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +67 -18
- package/dist/index.esm.js.map +1 -1
- package/dist/types/types/index.d.ts +4 -0
- package/package.json +2 -2
- package/src/AndyChat.tsx +31 -23
- package/src/types/index.ts +4 -0
package/README.md
CHANGED
|
@@ -46,6 +46,8 @@ Widget as a short, language-aware retry message.
|
|
|
46
46
|
| `description` | `string` | Override the configured description |
|
|
47
47
|
| `welcomeMessage` | `string` | Override the configured first message |
|
|
48
48
|
| `bubbleLabel` | `string` | Override the configured pill label |
|
|
49
|
+
| `lang` | `'en' \| 'es'` | Language for the Widget's own chrome (placeholder, starter-question title, error and handoff text). Overrides the Agent's `defaultLang`, so a Spanish Agent on an English page still renders English chrome |
|
|
50
|
+
| `predefinedQuestions` | `{ order: number, question: string }[]` | Override the configured starter questions |
|
|
49
51
|
| `theme` | `'light' \| 'dark' \| 'auto'` | Override the configured theme |
|
|
50
52
|
| `orientation` | `'left' \| 'right'` | Override the configured position |
|
|
51
53
|
| `brandColor` | `string` | Override the configured six-digit hex color |
|
package/dist/index.cjs
CHANGED
|
@@ -3437,6 +3437,48 @@ const SVG_ICONS = {
|
|
|
3437
3437
|
<path d="M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z" />
|
|
3438
3438
|
</svg>`};
|
|
3439
3439
|
|
|
3440
|
+
// Localized UI Strings
|
|
3441
|
+
// Chrome the widget renders itself, as opposed to copy the Agent supplies.
|
|
3442
|
+
// Keyed by language so React and Vanilla render identical text for a visitor.
|
|
3443
|
+
const UI_STRINGS = {
|
|
3444
|
+
en: {
|
|
3445
|
+
openChat: 'Open chat',
|
|
3446
|
+
closeChat: 'Close chat',
|
|
3447
|
+
goBack: 'Go back',
|
|
3448
|
+
messageInput: 'Message input',
|
|
3449
|
+
sendMessage: 'Send message',
|
|
3450
|
+
welcomeMessage: 'Welcome message',
|
|
3451
|
+
closeWelcomeMessage: 'Close welcome message',
|
|
3452
|
+
inputPlaceholder: 'Type your message...',
|
|
3453
|
+
predefinedQuestionsTitle: 'What would you like to know?',
|
|
3454
|
+
sendFailure: 'Sorry, I could not answer. Please try again.',
|
|
3455
|
+
handoffWaiting: 'A team member will reply soon.',
|
|
3456
|
+
teamName: 'Team'
|
|
3457
|
+
},
|
|
3458
|
+
es: {
|
|
3459
|
+
openChat: 'Abrir chat',
|
|
3460
|
+
closeChat: 'Cerrar chat',
|
|
3461
|
+
goBack: 'Volver',
|
|
3462
|
+
messageInput: 'Entrada de mensaje',
|
|
3463
|
+
sendMessage: 'Enviar mensaje',
|
|
3464
|
+
welcomeMessage: 'Mensaje de bienvenida',
|
|
3465
|
+
closeWelcomeMessage: 'Cerrar mensaje de bienvenida',
|
|
3466
|
+
inputPlaceholder: 'Escribe tu mensaje...',
|
|
3467
|
+
predefinedQuestionsTitle: '¿Qué te gustaría saber?',
|
|
3468
|
+
sendFailure: 'Lo siento, no pude responder. Inténtalo de nuevo.',
|
|
3469
|
+
handoffWaiting: 'Un miembro del equipo te responderá pronto.',
|
|
3470
|
+
teamName: 'Equipo'
|
|
3471
|
+
}
|
|
3472
|
+
};
|
|
3473
|
+
|
|
3474
|
+
/**
|
|
3475
|
+
* Get the widget's own UI strings for a language.
|
|
3476
|
+
* Unknown languages fall back to English rather than rendering blanks.
|
|
3477
|
+
* @param {string} [lang] - Language code ('en' or 'es')
|
|
3478
|
+
* @returns {typeof UI_STRINGS.en} The localized string set
|
|
3479
|
+
*/
|
|
3480
|
+
const getUiStrings = lang => UI_STRINGS[lang] || UI_STRINGS.en;
|
|
3481
|
+
|
|
3440
3482
|
/**
|
|
3441
3483
|
* Keyboard detection utility for handling mobile virtual keyboards
|
|
3442
3484
|
* Provides cross-browser support for detecting keyboard open/close events
|
|
@@ -3855,8 +3897,13 @@ const createBrowserHandoff = (chatbotId, bootstrap, onProjection) => {
|
|
|
3855
3897
|
}
|
|
3856
3898
|
};
|
|
3857
3899
|
|
|
3858
|
-
const AndyChat = ({ embedId, tooltip, name, headline, description, welcomeMessage, bubbleLabel, theme, orientation, brandColor, bubbleStyle, useBrandColor, logoUrl, previewMode = false, initialOpen = false }) => {
|
|
3900
|
+
const AndyChat = ({ embedId, tooltip, name, headline, description, welcomeMessage, bubbleLabel, lang, predefinedQuestions, theme, orientation, brandColor, bubbleStyle, useBrandColor, logoUrl, previewMode = false, initialOpen = false }) => {
|
|
3859
3901
|
const [config, setConfig] = react.useState(null);
|
|
3902
|
+
// The visitor's language wins over the Agent's own default: a Spanish Agent
|
|
3903
|
+
// embedded on an English page must still render English chrome.
|
|
3904
|
+
const uiLang = lang || config?.defaultLang || 'en';
|
|
3905
|
+
const strings = getUiStrings(uiLang);
|
|
3906
|
+
const activeQuestions = predefinedQuestions?.length ? predefinedQuestions : config?.predefinedQuestions;
|
|
3860
3907
|
const [isOpen, setIsOpen] = react.useState(initialOpen);
|
|
3861
3908
|
const [messages, setMessages] = react.useState([]);
|
|
3862
3909
|
const [isLoading, setIsLoading] = react.useState(false);
|
|
@@ -3886,8 +3933,11 @@ const AndyChat = ({ embedId, tooltip, name, headline, description, welcomeMessag
|
|
|
3886
3933
|
setSessionId(projection.identity.sessionId);
|
|
3887
3934
|
pendingHandoffIdsRef.current = projection.pendingProjectionIds || [];
|
|
3888
3935
|
const projectedMessages = projection.messages.map(message => ({ id: message.id, content: message.content, sender: message.role === 'user' ? 'user' : 'bot', timestamp: new Date(message.createdAt).toISOString(), isHuman: message.sentByHuman }));
|
|
3936
|
+
// An empty agent projection does not mean the client-only greeting is gone.
|
|
3937
|
+
if (projection.control === 'agent' && projectedMessages.length === 0)
|
|
3938
|
+
return;
|
|
3889
3939
|
setMessages(projection.control === 'requested' || projection.control === 'human'
|
|
3890
|
-
? [...projectedMessages, { id: 'handoff-waiting', content:
|
|
3940
|
+
? [...projectedMessages, { id: 'handoff-waiting', content: strings.handoffWaiting, sender: 'bot', timestamp: new Date().toISOString(), isWaiting: true }]
|
|
3891
3941
|
: projectedMessages);
|
|
3892
3942
|
});
|
|
3893
3943
|
handoffRef.current = handoff;
|
|
@@ -4076,12 +4126,12 @@ const AndyChat = ({ embedId, tooltip, name, headline, description, welcomeMessag
|
|
|
4076
4126
|
bubbleStyle: bubbleStyle || 'icon',
|
|
4077
4127
|
bubbleLabel: bubbleLabel || null,
|
|
4078
4128
|
useBrandColor: useBrandColor !== undefined ? useBrandColor : true,
|
|
4079
|
-
defaultLang:
|
|
4129
|
+
defaultLang: uiLang,
|
|
4080
4130
|
showBranding: true,
|
|
4081
4131
|
showWelcomePopup: { enabled: false, seconds: 3, message: '' },
|
|
4082
4132
|
collectUserInfo: { enabled: false, message: '' },
|
|
4083
4133
|
welcomeMessage: welcomeMessage || 'Hi there! How can I help you today?',
|
|
4084
|
-
predefinedQuestions: [],
|
|
4134
|
+
predefinedQuestions: predefinedQuestions || [],
|
|
4085
4135
|
faqs: []
|
|
4086
4136
|
};
|
|
4087
4137
|
setConfig(previewConfig);
|
|
@@ -4234,7 +4284,7 @@ const AndyChat = ({ embedId, tooltip, name, headline, description, welcomeMessag
|
|
|
4234
4284
|
setIsLoading(true);
|
|
4235
4285
|
const response = await sendMessageForWidget(embedId, sessionId, messageText);
|
|
4236
4286
|
if (response.status === 'waiting') {
|
|
4237
|
-
setMessages(prev => prev.some(message => message.isWaiting) ? prev : [...prev, { id: 'handoff-waiting', content:
|
|
4287
|
+
setMessages(prev => prev.some(message => message.isWaiting) ? prev : [...prev, { id: 'handoff-waiting', content: strings.handoffWaiting, sender: 'bot', timestamp: new Date().toISOString(), isWaiting: true }]);
|
|
4238
4288
|
return;
|
|
4239
4289
|
}
|
|
4240
4290
|
const botMessage = {
|
|
@@ -4261,9 +4311,7 @@ const AndyChat = ({ embedId, tooltip, name, headline, description, welcomeMessag
|
|
|
4261
4311
|
console.error('AndyChat: Message request failed.');
|
|
4262
4312
|
const errorMessage = {
|
|
4263
4313
|
id: timestamp + 3,
|
|
4264
|
-
content:
|
|
4265
|
-
? 'Lo siento, no pude responder. Inténtalo de nuevo.'
|
|
4266
|
-
: 'Sorry, I could not answer. Please try again.',
|
|
4314
|
+
content: strings.sendFailure,
|
|
4267
4315
|
sender: 'bot',
|
|
4268
4316
|
timestamp: new Date().toISOString(),
|
|
4269
4317
|
isError: true
|
|
@@ -4370,7 +4418,7 @@ const AndyChat = ({ embedId, tooltip, name, headline, description, welcomeMessag
|
|
|
4370
4418
|
bubble = document.createElement('button');
|
|
4371
4419
|
bubble.type = 'button';
|
|
4372
4420
|
bubble.className = 'andy-chat-bubble';
|
|
4373
|
-
bubble.setAttribute('aria-label',
|
|
4421
|
+
bubble.setAttribute('aria-label', strings.openChat);
|
|
4374
4422
|
const tooltipHTML = tooltip
|
|
4375
4423
|
? `<span class="andy-chat-bubble__tooltip" role="tooltip">${tooltip}</span>`
|
|
4376
4424
|
: '';
|
|
@@ -4379,9 +4427,10 @@ const AndyChat = ({ embedId, tooltip, name, headline, description, welcomeMessag
|
|
|
4379
4427
|
bubble.addEventListener('click', () => setIsOpen(prev => !prev));
|
|
4380
4428
|
}
|
|
4381
4429
|
const isPillStyle = config?.bubbleStyle === 'pill';
|
|
4382
|
-
const displayLabel = bubbleLabel || config?.bubbleLabel || (isPillStyle ? getDefaultBubbleLabel(
|
|
4430
|
+
const displayLabel = bubbleLabel || config?.bubbleLabel || (isPillStyle ? getDefaultBubbleLabel(uiLang) : null);
|
|
4383
4431
|
const bubbleLogoUrl = config?.logoUrl || CHAT_BUBBLE_DEFAULT_ICON_URL;
|
|
4384
4432
|
if (bubble) {
|
|
4433
|
+
bubble.setAttribute('aria-label', isOpen ? strings.closeChat : strings.openChat);
|
|
4385
4434
|
bubble.className = 'andy-chat-bubble';
|
|
4386
4435
|
if (isPillStyle) {
|
|
4387
4436
|
bubble.classList.add('andy-chat-bubble--pill');
|
|
@@ -4424,7 +4473,7 @@ const AndyChat = ({ embedId, tooltip, name, headline, description, welcomeMessag
|
|
|
4424
4473
|
}
|
|
4425
4474
|
}
|
|
4426
4475
|
}, [shadowReady, config, isOpen, tooltip, bubbleLabel]);
|
|
4427
|
-
return (jsxRuntime.jsx("div", { ref: containerRef, id: 'andy-chatbot-container', children: portalRef.current && shadowReady && config && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [ReactDOM.createPortal(jsxRuntime.jsxs("div", { className: `andy-chat-window ${isOpen ? 'andy-chat-window--open' : ''}`, children: [jsxRuntime.jsxs("header", { className: 'andy-header', children: [jsxRuntime.jsx("button", { type: 'button', className: 'andy-header__back', id: 'andy-back-button', "aria-label":
|
|
4476
|
+
return (jsxRuntime.jsx("div", { ref: containerRef, id: 'andy-chatbot-container', children: portalRef.current && shadowReady && config && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [ReactDOM.createPortal(jsxRuntime.jsxs("div", { className: `andy-chat-window ${isOpen ? 'andy-chat-window--open' : ''}`, children: [jsxRuntime.jsxs("header", { className: 'andy-header', children: [jsxRuntime.jsx("button", { type: 'button', className: 'andy-header__back', id: 'andy-back-button', "aria-label": strings.goBack, onClick: () => setIsOpen(false), children: jsxRuntime.jsx("svg", { className: 'andy-header__back-icon', width: '20', height: '20', viewBox: '0 0 24 24', fill: 'none', children: jsxRuntime.jsx("path", { d: 'M15 18l-6-6 6-6', stroke: 'currentColor', strokeWidth: '2', strokeLinecap: 'round', strokeLinejoin: 'round' }) }) }), jsxRuntime.jsxs("div", { className: 'andy-header__bot-info', children: [jsxRuntime.jsx("div", { className: 'andy-header__avatar', children: config?.logoUrl ? (jsxRuntime.jsx("img", { src: config.logoUrl, alt: 'Bot Avatar', className: 'andy-header__avatar-image' })) : (jsxRuntime.jsx("img", { src: CHAT_BUBBLE_DEFAULT_ICON_URL, alt: 'Bot Avatar', className: 'andy-header__avatar-icon andy-header__avatar-icon--default' })) }), jsxRuntime.jsxs("div", { className: 'andy-header__text', children: [jsxRuntime.jsx("h1", { className: 'andy-header__name', children: config?.name || 'Andy bot' }), config?.headline && (jsxRuntime.jsx("p", { className: 'andy-header__subtitle', title: config.headline, children: config.headline }))] })] }), jsxRuntime.jsx("button", { type: 'button', className: 'andy-header__close', id: 'andy-close-button', "aria-label": strings.closeChat, onClick: () => setIsOpen(false), children: jsxRuntime.jsx("svg", { className: 'andy-header__close-icon', width: '20', height: '20', viewBox: '0 0 24 24', fill: 'none', children: jsxRuntime.jsx("path", { d: 'M18 6L6 18M6 6l12 12', stroke: 'currentColor', strokeWidth: '2', strokeLinecap: 'round', strokeLinejoin: 'round' }) }) })] }), jsxRuntime.jsxs("div", { className: 'andy-chat-window__messages', id: 'andy-messages', ref: messagesContainerRef, children: [config?.description && (jsxRuntime.jsx("div", { className: 'andy-chat-subtitle', children: jsxRuntime.jsx("p", { className: 'andy-chat-subtitle__text', children: config.description }) })), messages.map(message => {
|
|
4428
4477
|
if (message.isForm) {
|
|
4429
4478
|
return (jsxRuntime.jsxs("div", { className: 'andy-message-container andy-message-container--form', children: [jsxRuntime.jsx("div", { className: 'andy-avatar', children: jsxRuntime.jsx("svg", { className: 'andy-avatar__icon', width: '24', height: '24', viewBox: '0 0 24 24', fill: 'none', xmlns: 'http://www.w3.org/2000/svg', children: jsxRuntime.jsx("path", { d: 'M20 2H4C2.9 2 2 2.9 2 4V22L6 18H20C21.1 18 22 17.1 22 16V4C22 2.9 21.1 2 20 2Z', fill: 'currentColor' }) }) }), jsxRuntime.jsx("div", { className: 'andy-message andy-message--bot andy-message--form', children: jsxRuntime.jsx("div", { className: 'andy-user-info-form', children: jsxRuntime.jsxs("div", { className: 'andy-user-info-form__content', children: [jsxRuntime.jsx("h3", { className: 'andy-user-info-form__title', children: config?.collectUserInfo?.message ||
|
|
4430
4479
|
'Please provide your information to continue:' }), jsxRuntime.jsxs("form", { className: 'andy-user-info-form__form', id: 'andy-user-info-form', children: [jsxRuntime.jsxs("div", { className: 'andy-form-group', children: [jsxRuntime.jsx("label", { htmlFor: 'andy-user-name', className: 'andy-form-group__label', children: "Name" }), jsxRuntime.jsx("input", { type: 'text', id: 'andy-user-name', className: 'andy-form-group__input', placeholder: 'Your Name', required: true })] }), jsxRuntime.jsxs("div", { className: 'andy-form-group', children: [jsxRuntime.jsx("label", { htmlFor: 'andy-user-email', className: 'andy-form-group__label', children: "Email" }), jsxRuntime.jsx("input", { type: 'email', id: 'andy-user-email', className: 'andy-form-group__input', placeholder: 'Your Email', required: true })] }), jsxRuntime.jsx("button", { type: 'submit', className: 'andy-button andy-button--primary andy-user-info-form__submit', children: "Submit" })] })] }) }) })] }, message.id));
|
|
@@ -4432,15 +4481,15 @@ const AndyChat = ({ embedId, tooltip, name, headline, description, welcomeMessag
|
|
|
4432
4481
|
if (message.isLoading) {
|
|
4433
4482
|
return (jsxRuntime.jsx("div", { className: 'andy-message-container andy-message-container--bot andy-message-container--loading', children: jsxRuntime.jsx("div", { className: 'andy-message andy-message--bot', children: jsxRuntime.jsxs("div", { className: 'andy-typing-indicator', children: [jsxRuntime.jsx("div", { className: 'andy-typing-indicator__dot' }), jsxRuntime.jsx("div", { className: 'andy-typing-indicator__dot' }), jsxRuntime.jsx("div", { className: 'andy-typing-indicator__dot' })] }) }) }, message.id));
|
|
4434
4483
|
}
|
|
4435
|
-
return (jsxRuntime.jsxs("div", { className: `andy-message-container andy-message-container--${message.sender} ${message.isWaiting ? 'andy-message-container--waiting' : ''}`, children: [message.sender === 'bot' && (jsxRuntime.jsxs("div", { className: `andy-message andy-message--bot ${message.isHuman ? 'andy-message--operator' : ''} ${message.isWaiting ? 'andy-message--waiting' : ''} ${message.isError ? 'andy-message--error' : ''}`, children: [jsxRuntime.jsxs("div", { className: 'andy-bot-header', children: [jsxRuntime.jsx("div", { className: 'andy-bot-header__icon', children: config?.logoUrl ? (jsxRuntime.jsx("img", { src: config.logoUrl, alt: 'Bot Avatar', className: 'andy-bot-header__icon-image' })) : (jsxRuntime.jsx("img", { src: CHAT_BUBBLE_DEFAULT_ICON_URL, alt: 'Bot Avatar', className: 'andy-bot-header__icon-image andy-bot-header__icon-image--default' })) }), jsxRuntime.jsx("span", { className: 'andy-bot-header__name', children: message.isHuman ?
|
|
4436
|
-
}), isLoading && (jsxRuntime.jsx("div", { className: 'andy-message-container andy-message-container--bot andy-message-container--typing', children: jsxRuntime.jsx("div", { className: 'andy-message andy-message--bot andy-message--typing', children: jsxRuntime.jsxs("div", { className: 'andy-typing-indicator', children: [jsxRuntime.jsx("div", { className: 'andy-typing-indicator__dot' }), jsxRuntime.jsx("div", { className: 'andy-typing-indicator__dot' }), jsxRuntime.jsx("div", { className: 'andy-typing-indicator__dot' })] }) }) }))] }), jsxRuntime.jsxs("div", { className: 'andy-chat-window__bottom', children: [
|
|
4437
|
-
|
|
4438
|
-
showPredefinedQuestions && (jsxRuntime.jsxs("div", { className: 'andy-predefined-questions', id: 'andy-predefined-questions', children: [jsxRuntime.jsx("div", { className: 'andy-predefined-questions__header', children: jsxRuntime.jsx("p", { className: 'andy-predefined-questions__title', children:
|
|
4484
|
+
return (jsxRuntime.jsxs("div", { className: `andy-message-container andy-message-container--${message.sender} ${message.isWaiting ? 'andy-message-container--waiting' : ''}`, children: [message.sender === 'bot' && (jsxRuntime.jsxs("div", { className: `andy-message andy-message--bot ${message.isHuman ? 'andy-message--operator' : ''} ${message.isWaiting ? 'andy-message--waiting' : ''} ${message.isError ? 'andy-message--error' : ''}`, children: [jsxRuntime.jsxs("div", { className: 'andy-bot-header', children: [jsxRuntime.jsx("div", { className: 'andy-bot-header__icon', children: config?.logoUrl ? (jsxRuntime.jsx("img", { src: config.logoUrl, alt: 'Bot Avatar', className: 'andy-bot-header__icon-image' })) : (jsxRuntime.jsx("img", { src: CHAT_BUBBLE_DEFAULT_ICON_URL, alt: 'Bot Avatar', className: 'andy-bot-header__icon-image andy-bot-header__icon-image--default' })) }), jsxRuntime.jsx("span", { className: 'andy-bot-header__name', children: message.isHuman ? strings.teamName : config?.name || 'Andy bot' })] }), jsxRuntime.jsx("div", { className: 'andy-message__content', children: jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: parseMarkdown(message.content) } }) })] })), message.sender === 'user' && (jsxRuntime.jsx("div", { className: 'andy-message andy-message--user', children: jsxRuntime.jsx("div", { className: 'andy-message__content', children: jsxRuntime.jsx("p", { children: message.content }) }) }))] }, message.id));
|
|
4485
|
+
}), isLoading && (jsxRuntime.jsx("div", { className: 'andy-message-container andy-message-container--bot andy-message-container--typing', children: jsxRuntime.jsx("div", { className: 'andy-message andy-message--bot andy-message--typing', children: jsxRuntime.jsxs("div", { className: 'andy-typing-indicator', children: [jsxRuntime.jsx("div", { className: 'andy-typing-indicator__dot' }), jsxRuntime.jsx("div", { className: 'andy-typing-indicator__dot' }), jsxRuntime.jsx("div", { className: 'andy-typing-indicator__dot' })] }) }) }))] }), jsxRuntime.jsxs("div", { className: 'andy-chat-window__bottom', children: [activeQuestions &&
|
|
4486
|
+
activeQuestions.length > 0 &&
|
|
4487
|
+
showPredefinedQuestions && (jsxRuntime.jsxs("div", { className: 'andy-predefined-questions', id: 'andy-predefined-questions', children: [jsxRuntime.jsx("div", { className: 'andy-predefined-questions__header', children: jsxRuntime.jsx("p", { className: 'andy-predefined-questions__title', children: strings.predefinedQuestionsTitle }) }), jsxRuntime.jsx("div", { className: 'andy-predefined-questions__list', children: activeQuestions.map((q, index) => (jsxRuntime.jsxs("button", { type: 'button', className: 'andy-predefined-question', "data-question": q.question, disabled: isCollectingUserInfo || isLoading || !config, children: [jsxRuntime.jsx("span", { className: 'andy-predefined-question__icon', children: "\uD83D\uDCAC" }), jsxRuntime.jsx("span", { className: 'andy-predefined-question__text', children: q.question })] }, index))) })] })), jsxRuntime.jsx("div", { className: 'andy-chat-window__input', children: jsxRuntime.jsx("div", { className: 'andy-input-container', children: jsxRuntime.jsxs("div", { className: 'andy-input', children: [jsxRuntime.jsx("input", { type: 'text', className: 'andy-input__field', id: 'andy-message-input', placeholder: config ? strings.inputPlaceholder : '...', "aria-label": strings.messageInput, onKeyDown: e => {
|
|
4439
4488
|
if (e.key === 'Enter' && e.target.value.trim()) {
|
|
4440
4489
|
handleSendMessage(e.target.value);
|
|
4441
4490
|
e.target.value = '';
|
|
4442
4491
|
}
|
|
4443
|
-
}, disabled: isCollectingUserInfo || !config }), jsxRuntime.jsx("button", { type: 'button', className: 'andy-input__button', id: 'andy-send-button', "aria-label":
|
|
4492
|
+
}, disabled: isCollectingUserInfo || !config }), jsxRuntime.jsx("button", { type: 'button', className: 'andy-input__button', id: 'andy-send-button', "aria-label": strings.sendMessage, onClick: () => {
|
|
4444
4493
|
const input = shadowRef.current?.getElementById('andy-message-input');
|
|
4445
4494
|
if (input && input.value.trim()) {
|
|
4446
4495
|
handleSendMessage(input.value);
|
|
@@ -4448,9 +4497,9 @@ const AndyChat = ({ embedId, tooltip, name, headline, description, welcomeMessag
|
|
|
4448
4497
|
}
|
|
4449
4498
|
}, disabled: isCollectingUserInfo || !config, children: jsxRuntime.jsx("svg", { className: 'andy-input__button-icon', width: '18', height: '18', viewBox: '0 0 24 24', fill: 'currentColor', xmlns: 'http://www.w3.org/2000/svg', children: jsxRuntime.jsx("path", { d: 'M2.01 21L23 12 2.01 3 2 10l15 2-15 2z' }) }) })] }) }) }), config?.showBranding !== false && (jsxRuntime.jsx("footer", { className: 'andy-chat-window__footer', children: jsxRuntime.jsx("a", { href: getFooterUrl(), target: '_blank', rel: 'noopener noreferrer', className: 'andy-chat-window__footer-link', children: jsxRuntime.jsx("span", { className: 'andy-chat-window__footer-text', children: FOOTER_TEXT }) }) }))] })] }), portalRef.current), showWelcomePopup &&
|
|
4450
4499
|
!isOpen &&
|
|
4451
|
-
ReactDOM.createPortal(jsxRuntime.jsxs("div", { className: `andy-welcome-popup ${config?.orientation === 'left' ? 'andychat-popup-left' : ''}`, style: { display: 'block' }, role: 'dialog', "aria-label":
|
|
4500
|
+
ReactDOM.createPortal(jsxRuntime.jsxs("div", { className: `andy-welcome-popup ${config?.orientation === 'left' ? 'andychat-popup-left' : ''}`, style: { display: 'block' }, role: 'dialog', "aria-label": strings.welcomeMessage, children: [jsxRuntime.jsxs("div", { className: 'andy-welcome-popup__content', children: [jsxRuntime.jsx("div", { className: 'andy-welcome-popup__message', children: config?.showWelcomePopup?.message ||
|
|
4452
4501
|
config?.welcomeMessage ||
|
|
4453
|
-
'Welcome! How can I help you today?' }), jsxRuntime.jsx("button", { type: 'button', className: 'andy-welcome-popup__close', "aria-label":
|
|
4502
|
+
'Welcome! How can I help you today?' }), jsxRuntime.jsx("button", { type: 'button', className: 'andy-welcome-popup__close', "aria-label": strings.closeWelcomeMessage, onClick: () => setShowWelcomePopup(false), children: jsxRuntime.jsx("svg", { className: 'andy-welcome-popup__close-icon', width: '20', height: '20', viewBox: '0 0 24 24', fill: 'none', xmlns: 'http://www.w3.org/2000/svg', children: jsxRuntime.jsx("path", { d: 'M18 6L6 18M6 6l12 12', stroke: 'currentColor', strokeWidth: '2', strokeLinecap: 'round', strokeLinejoin: 'round' }) }) })] }), jsxRuntime.jsx("div", { className: 'andy-welcome-popup__arrow' })] }), portalRef.current)] })) }));
|
|
4454
4503
|
};
|
|
4455
4504
|
|
|
4456
4505
|
const { SESSION_STORAGE_KEY, FORM_DISPLAY_DELAY_MS, PERSIST_SESSION } = CONFIG;
|