andy-widget-react 3.0.0-next.1 → 3.0.0-next.10

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 CHANGED
@@ -8,7 +8,7 @@ The official React Widget for Andy. Its canonical source is
8
8
  Pin an exact reviewed release. 3.0 prereleases are on the npm `next` tag:
9
9
 
10
10
  ```bash
11
- bun add andy-widget-react@3.0.0-next.1
11
+ bun add andy-widget-react@3.0.0-next.10
12
12
  ```
13
13
 
14
14
  React and React DOM 18 or 19 are peer dependencies. `andy-widget-core` (the `<andy-chat>` element) comes with
@@ -42,12 +42,11 @@ and the host page is unaffected.
42
42
  | --- | --- | --- |
43
43
  | `agentId` | `string` | The Sales Agent ID, shown to anonymous Visitors |
44
44
  | `support` | `SupportOptions` | Support Mode for signed-in Requesters (see [Authenticated Support](#authenticated-support)) |
45
- | `lang` | `'en' \| 'es'` | The Widget's language, over the page's `<html lang>` and the Agent's `defaultLang` |
45
+ | `lang` | `'en' \| 'es'` | The Widget's language, over the page's `<html lang>`, the browser's language and the Agent's `defaultLang` |
46
46
  | `initialOpen` | `boolean` | Start with the panel open; defaults to `false` |
47
47
  | `orientation` | `'left' \| 'right'` | The Launcher's side |
48
+ | `nudge` | `{ id: string, message: string, draft?: string, delayMs?: number } \| null` | A bubble above the closed Launcher, in Sales and Support Mode (see [Nudge](#nudge)) |
48
49
  | `name` | `string` | Override the Agent's name |
49
- | `headline` | `string` | Override the status line |
50
- | `description` | `string` | Override the intro description |
51
50
  | `welcomeMessage` | `string` | Override the Greeting |
52
51
  | `predefinedQuestions` | `{ order: number, question: string }[]` | Override the Starters |
53
52
  | `theme` | `'light' \| 'dark' \| 'auto'` | Override the theme |
@@ -60,10 +59,28 @@ and the host page is unaffected.
60
59
  | `embedId` | `string` | Deprecated alias of `agentId`; logs one notice |
61
60
  | `mode` | `'support'` | Deprecated: `support` without `agentId`; logs one notice |
62
61
  | `tooltip` | `string` | Deprecated and ignored: the 3.x Launcher has no tooltip |
62
+ | `headline` | `string` | Deprecated and ignored: the panel shows only the name and the Greeting, with no status line |
63
+ | `description` | `string` | Deprecated and ignored: the panel shows no intro description |
63
64
 
64
- The overrides replace the Agent's own values in every language, in Sales Mode only; an empty or invalid
65
+ The overrides replace the Agent's own values in the Widget's language, in Sales Mode only; an empty or invalid
65
66
  value leaves the Agent's. The server configuration controls **Powered by Andy**; no prop suppresses it.
66
67
 
68
+ ## Nudge
69
+
70
+ `nudge` asks the user something from a bubble above the closed Launcher, for example feedback on a new page:
71
+
72
+ ```tsx
73
+ <AndyChat
74
+ support={support}
75
+ nudge={{ id: 'visualizaciones-feedback-1', message: '¿Hay algo que mejorarías de esta visualización?', draft: 'Mejoraría ' }}
76
+ />
77
+ ```
78
+
79
+ - It shows `delayMs` after the Launcher appears (default 1,500 ms), only while the panel is closed, on the Launcher's side.
80
+ - Clicking it opens the panel with `draft` in an empty composer; nothing is sent until the user sends it.
81
+ - It shows on every page that passes it. Once its × is clicked, or the bubble opens the panel, it stays hidden for the rest of the browser session (`sessionStorage`, per `id`). A new session (a new tab or a reopened browser) shows it again, and so does a new `id`.
82
+ - `null`, or a different `id`, updates it in place without remounting the Widget. The same `id` with new text only changes the text.
83
+
67
84
  ## Authenticated Support
68
85
 
69
86
  Support requires a configured host installation and a server-provisioned Support Agent.
package/dist/index.cjs CHANGED
@@ -10,8 +10,6 @@ var andyWidgetCore = require('andy-widget-core');
10
10
  /** The 2.x props that override the Agent's copy and look, as the element's `overrides`. */
11
11
  const OVERRIDES = [
12
12
  'name',
13
- 'headline',
14
- 'description',
15
13
  'welcomeMessage',
16
14
  'predefinedQuestions',
17
15
  'theme',
@@ -36,13 +34,13 @@ const notice = (prop, message) => {
36
34
  * identity. It shows Sales (`agentId`) to a Visitor and Support to a Requester with a valid pass, and starts a
37
35
  * fresh panel on every identity change; this component only hands the element its props. The 2.x props keep
38
36
  * working: `embedId` and `mode="support"` as deprecated aliases, the copy and look overrides over the Agent's
39
- * config, and `previewMode`.
37
+ * config, and `previewMode`. `nudge` shows a bubble above the closed Launcher in either mode.
40
38
  */
41
39
  const AndyChat = props => {
42
40
  // `mode="support"` never showed Sales, so it keeps the Widget Support-only.
43
41
  const sales = props.mode === 'support' ? undefined : props;
44
42
  const agentId = sales?.agentId ?? sales?.embedId;
45
- const { support, orientation, initialOpen = false } = props;
43
+ const { support, orientation, initialOpen = false, nudge = null } = props;
46
44
  const lang = props.lang ?? support?.lang;
47
45
  const supportAlias = !sales;
48
46
  const embedAlias = sales?.embedId !== undefined;
@@ -85,6 +83,12 @@ const AndyChat = props => {
85
83
  ? { ...support, ...(lang ? { lang } : {}), ...(orientation ? { position: orientation } : {}), getRequesterPass: () => pass.current?.() }
86
84
  : null;
87
85
  }, [element, agentId, support, lang, orientation, overridesKey, preview]);
86
+ // By value, so a nudge written inline is not a new one each render.
87
+ const nudgeKey = JSON.stringify(nudge);
88
+ react.useEffect(() => {
89
+ if (element)
90
+ element.nudge = nudge;
91
+ }, [element, nudgeKey]);
88
92
  return jsxRuntime.jsx("div", { ref: host, className: 'andy-widget-host' });
89
93
  };
90
94
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/AndyChat.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react'\nimport { defineAndyChat, type AndyChatElement, type WidgetOverrides } from 'andy-widget-core'\nimport type { AndyChatProps, SalesAndyChatProps } from './types'\n\n/** The 2.x props that override the Agent's copy and look, as the element's `overrides`. */\nconst OVERRIDES = [\n\t'name',\n\t'headline',\n\t'description',\n\t'welcomeMessage',\n\t'predefinedQuestions',\n\t'theme',\n\t'orientation',\n\t'brandColor',\n\t'useBrandColor',\n\t'bubbleStyle',\n\t'bubbleLabel',\n\t'logoUrl'\n] as const satisfies ReadonlyArray<keyof WidgetOverrides & keyof SalesAndyChatProps>\n\nconst overridesOf = (props: SalesAndyChatProps): WidgetOverrides =>\n\tObject.fromEntries(OVERRIDES.filter(key => props[key] !== undefined).map(key => [key, props[key]]))\n\n/** Each deprecated prop logs one notice per page. */\nconst noticed = new Set<string>()\nconst notice = (prop: string, message: string) => {\n\tif (noticed.has(prop)) return\n\tnoticed.add(prop)\n\tconsole.warn(`AndyChat: ${message}`)\n}\n\n/**\n * The Andy Widget for React: one `<andy-chat>` element (`andy-widget-core`), whose Widget Mode comes from\n * identity. It shows Sales (`agentId`) to a Visitor and Support to a Requester with a valid pass, and starts a\n * fresh panel on every identity change; this component only hands the element its props. The 2.x props keep\n * working: `embedId` and `mode=\"support\"` as deprecated aliases, the copy and look overrides over the Agent's\n * config, and `previewMode`.\n */\nconst AndyChat: React.FC<AndyChatProps> = props => {\n\t// `mode=\"support\"` never showed Sales, so it keeps the Widget Support-only.\n\tconst sales = props.mode === 'support' ? undefined : props\n\tconst agentId = sales?.agentId ?? sales?.embedId\n\tconst { support, orientation, initialOpen = false } = props\n\tconst lang = props.lang ?? support?.lang\n\tconst supportAlias = !sales\n\tconst embedAlias = sales?.embedId !== undefined\n\tuseEffect(() => {\n\t\tif (supportAlias) notice('mode', '`mode=\"support\"` is deprecated. Pass `support` without `agentId`.')\n\t\tif (embedAlias) notice('embedId', '`embedId` is deprecated. Use `agentId`.')\n\t}, [supportAlias, embedAlias])\n\n\tconst host = useRef<HTMLDivElement>(null)\n\tconst [element, setElement] = useState<AndyChatElement | null>(null)\n\tconst pass = useRef(support?.getRequesterPass)\n\tpass.current = support?.getRequesterPass\n\tuseEffect(() => {\n\t\tdefineAndyChat()\n\t\tconst created = document.createElement('andy-chat')\n\t\tcreated.open = initialOpen\n\t\thost.current?.append(created)\n\t\tsetElement(created)\n\t\t// Removing the element ends its identity: pass, chat, requests and drafts go with it.\n\t\treturn () => created.remove()\n\t}, [])\n\tuseEffect(() => {\n\t\tif (lang) element?.setAttribute('lang', lang)\n\t\telse element?.removeAttribute('lang')\n\t}, [element, lang])\n\tconst overrides = sales ? overridesOf(sales) : {}\n\tconst overridesKey = JSON.stringify(overrides)\n\tconst preview = sales?.previewMode === true\n\tuseEffect(() => {\n\t\tif (!element) return\n\t\telement.overrides = overrides\n\t\telement.preview = preview\n\t\telement.agentId = agentId\n\t\t// The element compares installation, contextKey and API, so a new callback each render is not a new identity.\n\t\telement.support = support\n\t\t\t? { ...support, ...(lang ? { lang } : {}), ...(orientation ? { position: orientation } : {}), getRequesterPass: () => pass.current?.() }\n\t\t\t: null\n\t}, [element, agentId, support, lang, orientation, overridesKey, preview])\n\treturn <div ref={host} className='andy-widget-host' />\n}\n\nexport default AndyChat\n"],"names":["useEffect","useRef","useState","defineAndyChat","_jsx"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/AndyChat.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react'\nimport { defineAndyChat, type AndyChatElement, type WidgetOverrides } from 'andy-widget-core'\nimport type { AndyChatProps, SalesAndyChatProps } from './types'\n\n/** The 2.x props that override the Agent's copy and look, as the element's `overrides`. */\nconst OVERRIDES = [\n\t'name',\n\t'welcomeMessage',\n\t'predefinedQuestions',\n\t'theme',\n\t'orientation',\n\t'brandColor',\n\t'useBrandColor',\n\t'bubbleStyle',\n\t'bubbleLabel',\n\t'logoUrl'\n] as const satisfies ReadonlyArray<keyof WidgetOverrides & keyof SalesAndyChatProps>\n\nconst overridesOf = (props: SalesAndyChatProps): WidgetOverrides =>\n\tObject.fromEntries(OVERRIDES.filter(key => props[key] !== undefined).map(key => [key, props[key]]))\n\n/** Each deprecated prop logs one notice per page. */\nconst noticed = new Set<string>()\nconst notice = (prop: string, message: string) => {\n\tif (noticed.has(prop)) return\n\tnoticed.add(prop)\n\tconsole.warn(`AndyChat: ${message}`)\n}\n\n/**\n * The Andy Widget for React: one `<andy-chat>` element (`andy-widget-core`), whose Widget Mode comes from\n * identity. It shows Sales (`agentId`) to a Visitor and Support to a Requester with a valid pass, and starts a\n * fresh panel on every identity change; this component only hands the element its props. The 2.x props keep\n * working: `embedId` and `mode=\"support\"` as deprecated aliases, the copy and look overrides over the Agent's\n * config, and `previewMode`. `nudge` shows a bubble above the closed Launcher in either mode.\n */\nconst AndyChat: React.FC<AndyChatProps> = props => {\n\t// `mode=\"support\"` never showed Sales, so it keeps the Widget Support-only.\n\tconst sales = props.mode === 'support' ? undefined : props\n\tconst agentId = sales?.agentId ?? sales?.embedId\n\tconst { support, orientation, initialOpen = false, nudge = null } = props\n\tconst lang = props.lang ?? support?.lang\n\tconst supportAlias = !sales\n\tconst embedAlias = sales?.embedId !== undefined\n\tuseEffect(() => {\n\t\tif (supportAlias) notice('mode', '`mode=\"support\"` is deprecated. Pass `support` without `agentId`.')\n\t\tif (embedAlias) notice('embedId', '`embedId` is deprecated. Use `agentId`.')\n\t}, [supportAlias, embedAlias])\n\n\tconst host = useRef<HTMLDivElement>(null)\n\tconst [element, setElement] = useState<AndyChatElement | null>(null)\n\tconst pass = useRef(support?.getRequesterPass)\n\tpass.current = support?.getRequesterPass\n\tuseEffect(() => {\n\t\tdefineAndyChat()\n\t\tconst created = document.createElement('andy-chat')\n\t\tcreated.open = initialOpen\n\t\thost.current?.append(created)\n\t\tsetElement(created)\n\t\t// Removing the element ends its identity: pass, chat, requests and drafts go with it.\n\t\treturn () => created.remove()\n\t}, [])\n\tuseEffect(() => {\n\t\tif (lang) element?.setAttribute('lang', lang)\n\t\telse element?.removeAttribute('lang')\n\t}, [element, lang])\n\tconst overrides = sales ? overridesOf(sales) : {}\n\tconst overridesKey = JSON.stringify(overrides)\n\tconst preview = sales?.previewMode === true\n\tuseEffect(() => {\n\t\tif (!element) return\n\t\telement.overrides = overrides\n\t\telement.preview = preview\n\t\telement.agentId = agentId\n\t\t// The element compares installation, contextKey and API, so a new callback each render is not a new identity.\n\t\telement.support = support\n\t\t\t? { ...support, ...(lang ? { lang } : {}), ...(orientation ? { position: orientation } : {}), getRequesterPass: () => pass.current?.() }\n\t\t\t: null\n\t}, [element, agentId, support, lang, orientation, overridesKey, preview])\n\t// By value, so a nudge written inline is not a new one each render.\n\tconst nudgeKey = JSON.stringify(nudge)\n\tuseEffect(() => {\n\t\tif (element) element.nudge = nudge\n\t}, [element, nudgeKey])\n\treturn <div ref={host} className='andy-widget-host' />\n}\n\nexport default AndyChat\n"],"names":["useEffect","useRef","useState","defineAndyChat","_jsx"],"mappings":"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"}
package/dist/index.esm.js CHANGED
@@ -7,8 +7,6 @@ export { getApiBaseUrl, setApiBaseUrl } from 'andy-widget-core';
7
7
  /** The 2.x props that override the Agent's copy and look, as the element's `overrides`. */
8
8
  const OVERRIDES = [
9
9
  'name',
10
- 'headline',
11
- 'description',
12
10
  'welcomeMessage',
13
11
  'predefinedQuestions',
14
12
  'theme',
@@ -33,13 +31,13 @@ const notice = (prop, message) => {
33
31
  * identity. It shows Sales (`agentId`) to a Visitor and Support to a Requester with a valid pass, and starts a
34
32
  * fresh panel on every identity change; this component only hands the element its props. The 2.x props keep
35
33
  * working: `embedId` and `mode="support"` as deprecated aliases, the copy and look overrides over the Agent's
36
- * config, and `previewMode`.
34
+ * config, and `previewMode`. `nudge` shows a bubble above the closed Launcher in either mode.
37
35
  */
38
36
  const AndyChat = props => {
39
37
  // `mode="support"` never showed Sales, so it keeps the Widget Support-only.
40
38
  const sales = props.mode === 'support' ? undefined : props;
41
39
  const agentId = sales?.agentId ?? sales?.embedId;
42
- const { support, orientation, initialOpen = false } = props;
40
+ const { support, orientation, initialOpen = false, nudge = null } = props;
43
41
  const lang = props.lang ?? support?.lang;
44
42
  const supportAlias = !sales;
45
43
  const embedAlias = sales?.embedId !== undefined;
@@ -82,6 +80,12 @@ const AndyChat = props => {
82
80
  ? { ...support, ...(lang ? { lang } : {}), ...(orientation ? { position: orientation } : {}), getRequesterPass: () => pass.current?.() }
83
81
  : null;
84
82
  }, [element, agentId, support, lang, orientation, overridesKey, preview]);
83
+ // By value, so a nudge written inline is not a new one each render.
84
+ const nudgeKey = JSON.stringify(nudge);
85
+ useEffect(() => {
86
+ if (element)
87
+ element.nudge = nudge;
88
+ }, [element, nudgeKey]);
85
89
  return jsx("div", { ref: host, className: 'andy-widget-host' });
86
90
  };
87
91
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/AndyChat.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react'\nimport { defineAndyChat, type AndyChatElement, type WidgetOverrides } from 'andy-widget-core'\nimport type { AndyChatProps, SalesAndyChatProps } from './types'\n\n/** The 2.x props that override the Agent's copy and look, as the element's `overrides`. */\nconst OVERRIDES = [\n\t'name',\n\t'headline',\n\t'description',\n\t'welcomeMessage',\n\t'predefinedQuestions',\n\t'theme',\n\t'orientation',\n\t'brandColor',\n\t'useBrandColor',\n\t'bubbleStyle',\n\t'bubbleLabel',\n\t'logoUrl'\n] as const satisfies ReadonlyArray<keyof WidgetOverrides & keyof SalesAndyChatProps>\n\nconst overridesOf = (props: SalesAndyChatProps): WidgetOverrides =>\n\tObject.fromEntries(OVERRIDES.filter(key => props[key] !== undefined).map(key => [key, props[key]]))\n\n/** Each deprecated prop logs one notice per page. */\nconst noticed = new Set<string>()\nconst notice = (prop: string, message: string) => {\n\tif (noticed.has(prop)) return\n\tnoticed.add(prop)\n\tconsole.warn(`AndyChat: ${message}`)\n}\n\n/**\n * The Andy Widget for React: one `<andy-chat>` element (`andy-widget-core`), whose Widget Mode comes from\n * identity. It shows Sales (`agentId`) to a Visitor and Support to a Requester with a valid pass, and starts a\n * fresh panel on every identity change; this component only hands the element its props. The 2.x props keep\n * working: `embedId` and `mode=\"support\"` as deprecated aliases, the copy and look overrides over the Agent's\n * config, and `previewMode`.\n */\nconst AndyChat: React.FC<AndyChatProps> = props => {\n\t// `mode=\"support\"` never showed Sales, so it keeps the Widget Support-only.\n\tconst sales = props.mode === 'support' ? undefined : props\n\tconst agentId = sales?.agentId ?? sales?.embedId\n\tconst { support, orientation, initialOpen = false } = props\n\tconst lang = props.lang ?? support?.lang\n\tconst supportAlias = !sales\n\tconst embedAlias = sales?.embedId !== undefined\n\tuseEffect(() => {\n\t\tif (supportAlias) notice('mode', '`mode=\"support\"` is deprecated. Pass `support` without `agentId`.')\n\t\tif (embedAlias) notice('embedId', '`embedId` is deprecated. Use `agentId`.')\n\t}, [supportAlias, embedAlias])\n\n\tconst host = useRef<HTMLDivElement>(null)\n\tconst [element, setElement] = useState<AndyChatElement | null>(null)\n\tconst pass = useRef(support?.getRequesterPass)\n\tpass.current = support?.getRequesterPass\n\tuseEffect(() => {\n\t\tdefineAndyChat()\n\t\tconst created = document.createElement('andy-chat')\n\t\tcreated.open = initialOpen\n\t\thost.current?.append(created)\n\t\tsetElement(created)\n\t\t// Removing the element ends its identity: pass, chat, requests and drafts go with it.\n\t\treturn () => created.remove()\n\t}, [])\n\tuseEffect(() => {\n\t\tif (lang) element?.setAttribute('lang', lang)\n\t\telse element?.removeAttribute('lang')\n\t}, [element, lang])\n\tconst overrides = sales ? overridesOf(sales) : {}\n\tconst overridesKey = JSON.stringify(overrides)\n\tconst preview = sales?.previewMode === true\n\tuseEffect(() => {\n\t\tif (!element) return\n\t\telement.overrides = overrides\n\t\telement.preview = preview\n\t\telement.agentId = agentId\n\t\t// The element compares installation, contextKey and API, so a new callback each render is not a new identity.\n\t\telement.support = support\n\t\t\t? { ...support, ...(lang ? { lang } : {}), ...(orientation ? { position: orientation } : {}), getRequesterPass: () => pass.current?.() }\n\t\t\t: null\n\t}, [element, agentId, support, lang, orientation, overridesKey, preview])\n\treturn <div ref={host} className='andy-widget-host' />\n}\n\nexport default AndyChat\n"],"names":["_jsx"],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.js","sources":["../src/AndyChat.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react'\nimport { defineAndyChat, type AndyChatElement, type WidgetOverrides } from 'andy-widget-core'\nimport type { AndyChatProps, SalesAndyChatProps } from './types'\n\n/** The 2.x props that override the Agent's copy and look, as the element's `overrides`. */\nconst OVERRIDES = [\n\t'name',\n\t'welcomeMessage',\n\t'predefinedQuestions',\n\t'theme',\n\t'orientation',\n\t'brandColor',\n\t'useBrandColor',\n\t'bubbleStyle',\n\t'bubbleLabel',\n\t'logoUrl'\n] as const satisfies ReadonlyArray<keyof WidgetOverrides & keyof SalesAndyChatProps>\n\nconst overridesOf = (props: SalesAndyChatProps): WidgetOverrides =>\n\tObject.fromEntries(OVERRIDES.filter(key => props[key] !== undefined).map(key => [key, props[key]]))\n\n/** Each deprecated prop logs one notice per page. */\nconst noticed = new Set<string>()\nconst notice = (prop: string, message: string) => {\n\tif (noticed.has(prop)) return\n\tnoticed.add(prop)\n\tconsole.warn(`AndyChat: ${message}`)\n}\n\n/**\n * The Andy Widget for React: one `<andy-chat>` element (`andy-widget-core`), whose Widget Mode comes from\n * identity. It shows Sales (`agentId`) to a Visitor and Support to a Requester with a valid pass, and starts a\n * fresh panel on every identity change; this component only hands the element its props. The 2.x props keep\n * working: `embedId` and `mode=\"support\"` as deprecated aliases, the copy and look overrides over the Agent's\n * config, and `previewMode`. `nudge` shows a bubble above the closed Launcher in either mode.\n */\nconst AndyChat: React.FC<AndyChatProps> = props => {\n\t// `mode=\"support\"` never showed Sales, so it keeps the Widget Support-only.\n\tconst sales = props.mode === 'support' ? undefined : props\n\tconst agentId = sales?.agentId ?? sales?.embedId\n\tconst { support, orientation, initialOpen = false, nudge = null } = props\n\tconst lang = props.lang ?? support?.lang\n\tconst supportAlias = !sales\n\tconst embedAlias = sales?.embedId !== undefined\n\tuseEffect(() => {\n\t\tif (supportAlias) notice('mode', '`mode=\"support\"` is deprecated. Pass `support` without `agentId`.')\n\t\tif (embedAlias) notice('embedId', '`embedId` is deprecated. Use `agentId`.')\n\t}, [supportAlias, embedAlias])\n\n\tconst host = useRef<HTMLDivElement>(null)\n\tconst [element, setElement] = useState<AndyChatElement | null>(null)\n\tconst pass = useRef(support?.getRequesterPass)\n\tpass.current = support?.getRequesterPass\n\tuseEffect(() => {\n\t\tdefineAndyChat()\n\t\tconst created = document.createElement('andy-chat')\n\t\tcreated.open = initialOpen\n\t\thost.current?.append(created)\n\t\tsetElement(created)\n\t\t// Removing the element ends its identity: pass, chat, requests and drafts go with it.\n\t\treturn () => created.remove()\n\t}, [])\n\tuseEffect(() => {\n\t\tif (lang) element?.setAttribute('lang', lang)\n\t\telse element?.removeAttribute('lang')\n\t}, [element, lang])\n\tconst overrides = sales ? overridesOf(sales) : {}\n\tconst overridesKey = JSON.stringify(overrides)\n\tconst preview = sales?.previewMode === true\n\tuseEffect(() => {\n\t\tif (!element) return\n\t\telement.overrides = overrides\n\t\telement.preview = preview\n\t\telement.agentId = agentId\n\t\t// The element compares installation, contextKey and API, so a new callback each render is not a new identity.\n\t\telement.support = support\n\t\t\t? { ...support, ...(lang ? { lang } : {}), ...(orientation ? { position: orientation } : {}), getRequesterPass: () => pass.current?.() }\n\t\t\t: null\n\t}, [element, agentId, support, lang, orientation, overridesKey, preview])\n\t// By value, so a nudge written inline is not a new one each render.\n\tconst nudgeKey = JSON.stringify(nudge)\n\tuseEffect(() => {\n\t\tif (element) element.nudge = nudge\n\t}, [element, nudgeKey])\n\treturn <div ref={host} className='andy-widget-host' />\n}\n\nexport default AndyChat\n"],"names":["_jsx"],"mappings":"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"}
@@ -5,7 +5,7 @@ import type { AndyChatProps } from './types';
5
5
  * identity. It shows Sales (`agentId`) to a Visitor and Support to a Requester with a valid pass, and starts a
6
6
  * fresh panel on every identity change; this component only hands the element its props. The 2.x props keep
7
7
  * working: `embedId` and `mode="support"` as deprecated aliases, the copy and look overrides over the Agent's
8
- * config, and `previewMode`.
8
+ * config, and `previewMode`. `nudge` shows a bubble above the closed Launcher in either mode.
9
9
  */
10
10
  declare const AndyChat: React.FC<AndyChatProps>;
11
11
  export default AndyChat;
@@ -2,4 +2,5 @@ export { default as AndyChat } from './AndyChat';
2
2
  export { default as Andy } from './AndyChat';
3
3
  export { default } from './AndyChat';
4
4
  export type { AndyChatProps, SalesAndyChatProps, SupportAndyChatProps, PredefinedQuestion } from './types';
5
+ export type { WidgetNudge } from 'andy-widget-core';
5
6
  export { getApiBaseUrl, setApiBaseUrl } from 'andy-widget-core';
@@ -1,4 +1,4 @@
1
- import type { SupportOptions } from 'andy-widget-core';
1
+ import type { SupportOptions, WidgetNudge } from 'andy-widget-core';
2
2
  /** A Starter as 2.x served them: the question and its place in the list. */
3
3
  export interface PredefinedQuestion {
4
4
  order: number;
@@ -25,14 +25,15 @@ export interface SalesAndyChatProps {
25
25
  tooltip?: string;
26
26
  /** The Agent's name, over the configured one. */
27
27
  name?: string;
28
- /** The status line under the name. */
28
+ /** @deprecated Ignored: the 3.x Widget shows only the name and the Greeting, with no status line. */
29
29
  headline?: string;
30
+ /** @deprecated Ignored: the 3.x Widget shows only the name and the Greeting, with no intro description. */
30
31
  description?: string;
31
32
  /** The Greeting. */
32
33
  welcomeMessage?: string;
33
34
  /** The pill Launcher's label. */
34
35
  bubbleLabel?: string;
35
- /** The Widget's language, over the host page's `<html lang>` and the Agent's `defaultLang`. */
36
+ /** The Widget's language, over the host page's `<html lang>`, the browser's language and the Agent's `defaultLang`. */
36
37
  lang?: 'en' | 'es';
37
38
  /** The Starters. */
38
39
  predefinedQuestions?: PredefinedQuestion[];
@@ -50,6 +51,8 @@ export interface SalesAndyChatProps {
50
51
  previewMode?: boolean;
51
52
  /** Starts with the panel open. */
52
53
  initialOpen?: boolean;
54
+ /** A bubble above the closed Launcher, shown once per `id` in this browser; clicking it opens the panel with `draft` prefilled. */
55
+ nudge?: WidgetNudge | null;
53
56
  }
54
57
  /** The 2.x Support-only props. */
55
58
  export interface SupportAndyChatProps {
@@ -59,6 +62,8 @@ export interface SupportAndyChatProps {
59
62
  lang?: 'es' | 'en';
60
63
  orientation?: 'left' | 'right';
61
64
  initialOpen?: boolean;
65
+ /** A bubble above the closed Launcher, shown once per `id` in this browser; clicking it opens the panel with `draft` prefilled. */
66
+ nudge?: WidgetNudge | null;
62
67
  /** @deprecated The 3.x Launcher has no tooltip; its accessible name says what it opens. */
63
68
  tooltip?: string;
64
69
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "andy-widget-react",
3
- "version": "3.0.0-next.1",
3
+ "version": "3.0.0-next.10",
4
4
  "description": "The Andy Widget for React: a typed wrapper over <andy-chat>",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -60,6 +60,6 @@
60
60
  "react-dom": "^18.0.0 || ^19.0.0"
61
61
  },
62
62
  "dependencies": {
63
- "andy-widget-core": "3.0.0-next.1"
63
+ "andy-widget-core": "3.0.0-next.10"
64
64
  }
65
65
  }