@salesforce/agentforce-conversation-client 1.25.0 → 1.25.2

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/index.d.ts CHANGED
@@ -4,100 +4,45 @@
4
4
  * For full license text, see the LICENSE.txt file
5
5
  */
6
6
  import { LightningOutApplication } from "@lightning-out/application";
7
- /**
8
- * The ACC wrapper component name used by Lightning Out
9
- */
10
7
  export declare const AGENTFORCE_CLIENT_ELEMENT_TAG = "runtime_copilot-acc-sdk-wrapper";
11
- /**
12
- * The namespace used by Lightning Out
13
- */
14
8
  export declare const AGENTFORCE_CLIENT_NAMESPACE = "runtime_copilot";
15
- /**
16
- * The component name used by Lightning Out
17
- */
18
9
  export declare const AGENTFORCE_CLIENT_COMPONENT_NAME = "accSdkWrapper";
19
- /**
20
- * Rendering mode for the Agentforce client
21
- */
22
10
  export declare const RenderingMode: Readonly<{
23
- INLINE: "inline";
24
- FLOATING: "floating";
11
+ readonly INLINE: "inline";
12
+ readonly FLOATING: "floating";
25
13
  }>;
26
- type RenderingModeValue = (typeof RenderingMode)[keyof typeof RenderingMode];
27
- /**
28
- * Styling options for the Agentforce client
29
- * Accepts any style property key-value pairs
30
- */
14
+ export type RenderingModeValue = (typeof RenderingMode)[keyof typeof RenderingMode];
31
15
  export type StyleTokens = Record<string, string>;
32
- /**
33
- * Agentforce client configuration options
34
- */
35
16
  export interface AgentforceClientConfig {
36
- /** Styling options */
37
17
  styleTokens?: StyleTokens;
38
- /** Agent identifier used to select which agent to load */
39
18
  agentId?: string;
40
- /** Rendering configuration */
41
19
  renderingConfig?: {
42
20
  mode?: RenderingModeValue;
43
21
  width?: string | number;
44
22
  height?: string | number;
45
23
  };
46
24
  }
47
- /**
48
- * Options for embedding the Agentforce client
49
- */
50
25
  export interface EmbedAgentforceClientOptions {
51
- /** CSS selector or HTMLElement */
52
26
  container: string | HTMLElement;
53
- /** Salesforce org origin URL (used as endpoint for component resolution) */
54
27
  salesforceOrigin?: string;
55
- /** Lightning Out application ID */
56
28
  appId?: string;
57
- /** Frontdoor URL for authentication */
58
29
  frontdoorUrl?: string;
59
- /** Agentforce client configuration */
60
30
  agentforceClientConfig?: AgentforceClientConfig;
61
31
  }
62
- /**
63
- * Result of embedding the Agentforce client
64
- */
65
32
  export interface EmbedAgentforceClientResult {
66
- /** The Lightning Out application element */
67
33
  loApp: LightningOutApplication;
68
- /** The chat client component element */
69
34
  chatClientComponent: HTMLElement;
70
35
  }
71
36
  /**
72
- * Embeds the Agentforce Conversation Client into a specified DOM container.
73
- *
74
- * @param options - Configuration options
75
- * @returns The created elements
76
- * @throws Error if required options are missing
37
+ * Embeds the Agentforce Conversation Client into a DOM container.
38
+ * Embed is hidden (opacity 0) until the frame receives the "accready" event.
77
39
  *
78
40
  * @example
79
- * ```ts
80
- * embedAgentforceClient({
81
- * container: '#agentforce-conversation-client-container',
41
+ * const { loApp, chatClientComponent } = embedAgentforceClient({
42
+ * container: '#agentforce-container',
82
43
  * salesforceOrigin: 'https://myorg.my.salesforce.com',
83
- * agentforceClientConfig: { styleTokens: { MessageBlockInboundColor: '#0176d3' } }
84
- * });
85
- * ```
86
- *
87
- * @example
88
- * ```ts
89
- * // Listen for Lightning Out events after embedding
90
- * const { loApp } = embedAgentforceClient({ ... });
91
- *
92
- * loApp.addEventListener('lo.application.ready', () => {
93
- * console.log('Lightning Out is ready');
94
- * });
95
- *
96
- * loApp.addEventListener('lo.component.ready', (event) => {
97
- * console.log('Component ready:', event.detail.componentName);
44
+ * agentforceClientConfig: { renderingConfig: { mode: 'Floating' } }
98
45
  * });
99
- * ```
100
46
  */
101
47
  export declare function embedAgentforceClient(options?: EmbedAgentforceClientOptions | null): EmbedAgentforceClientResult;
102
- export {};
103
48
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAErE;;GAEG;AACH,eAAO,MAAM,6BAA6B,oCAAoC,CAAC;AAE/E;;GAEG;AACH,eAAO,MAAM,2BAA2B,oBAAoB,CAAC;AAE7D;;GAEG;AACH,eAAO,MAAM,gCAAgC,kBAAkB,CAAC;AA8ChE;;GAEG;AACH,eAAO,MAAM,aAAa;;;EAGxB,CAAC;AAEH,KAAK,kBAAkB,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,OAAO,aAAa,CAAC,CAAC;AAK7E;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEjD;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACtC,sBAAsB;IACtB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,eAAe,CAAC,EAAE;QACjB,IAAI,CAAC,EAAE,kBAAkB,CAAC;QAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QACxB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;KACzB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC5C,kCAAkC;IAClC,SAAS,EAAE,MAAM,GAAG,WAAW,CAAC;IAChC,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mCAAmC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;CAChD;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC3C,4CAA4C;IAC5C,KAAK,EAAE,uBAAuB,CAAC;IAC/B,wCAAwC;IACxC,mBAAmB,EAAE,WAAW,CAAC;CACjC;AA0LD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,qBAAqB,CACpC,OAAO,CAAC,EAAE,4BAA4B,GAAG,IAAI,GAC3C,2BAA2B,CA0B7B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAMrE,eAAO,MAAM,6BAA6B,oCAAoC,CAAC;AAC/E,eAAO,MAAM,2BAA2B,oBAAoB,CAAC;AAC7D,eAAO,MAAM,gCAAgC,kBAAkB,CAAC;AAEhE,eAAO,MAAM,aAAa;;;EAGf,CAAC;AAEZ,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,OAAO,aAAa,CAAC,CAAC;AAMpF,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEjD,MAAM,WAAW,sBAAsB;IACtC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE;QACjB,IAAI,CAAC,EAAE,kBAAkB,CAAC;QAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QACxB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;KACzB,CAAC;CACF;AAED,MAAM,WAAW,4BAA4B;IAC5C,SAAS,EAAE,MAAM,GAAG,WAAW,CAAC;IAChC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;CAChD;AAED,MAAM,WAAW,2BAA2B;IAC3C,KAAK,EAAE,uBAAuB,CAAC;IAC/B,mBAAmB,EAAE,WAAW,CAAC;CACjC;AAwUD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACpC,OAAO,CAAC,EAAE,4BAA4B,GAAG,IAAI,GAC3C,2BAA2B,CAuB7B"}
package/dist/index.js CHANGED
@@ -4,232 +4,275 @@
4
4
  * For full license text, see the LICENSE.txt file
5
5
  */
6
6
  import { LightningOutApplication } from "@lightning-out/application";
7
- /**
8
- * The ACC wrapper component name used by Lightning Out
9
- */
7
+ // ═══════════════════════════════════════════════════════════════════════════════
8
+ // PUBLIC CONSTANTS (API surface)
9
+ // ═══════════════════════════════════════════════════════════════════════════════
10
10
  export const AGENTFORCE_CLIENT_ELEMENT_TAG = "runtime_copilot-acc-sdk-wrapper";
11
- /**
12
- * The namespace used by Lightning Out
13
- */
14
11
  export const AGENTFORCE_CLIENT_NAMESPACE = "runtime_copilot";
15
- /**
16
- * The component name used by Lightning Out
17
- */
18
12
  export const AGENTFORCE_CLIENT_COMPONENT_NAME = "accSdkWrapper";
19
- /**
20
- * Base styles for the floating mode
21
- */
22
- const FLOATING_BASE = Object.freeze({
23
- display: "block",
24
- position: "fixed",
25
- maxWidth: "calc(100vw - 4rem)",
26
- maxHeight: "calc(100dvh - 4rem)",
27
- transition: "all 0s ease",
28
- background: "transparent",
29
- border: "none",
30
- outline: "none",
31
- borderRadius: "16px",
32
- boxShadow: "2px 2px 20px rgba(0,0,0,0.2)",
33
- bottom: "24px",
34
- right: "24px",
35
- zIndex: "999",
36
- });
37
- /**
38
- * Minimized styles for the floating mode
39
- */
40
- const FLOATING_MINIMIZED = Object.freeze({ width: "145px", height: "56px" });
41
- /**
42
- * Maximized styles for the floating mode
43
- */
44
- const FLOATING_MAXIMIZED = Object.freeze({
45
- width: "380px",
46
- height: "540px",
47
- "--agentic-chat-container-height": "540px",
48
- boxShadow: "0 10px 25px -3px rgba(0,0,0,0.1),0 4px 12px -2px rgba(0,0,0,0.05),0 0 2px 0 rgba(0,0,0,0.05),0 20px 45px -5px rgba(0,0,0,0.08)",
49
- transition: "all 0.3s ease",
50
- });
51
- /**
52
- * Base styles for the inline mode
53
- */
54
- const INLINE_BASE = Object.freeze({
55
- display: "block",
56
- borderRadius: "0.5em",
57
- });
58
- /**
59
- * Rendering mode for the Agentforce client
60
- */
61
13
  export const RenderingMode = Object.freeze({
62
14
  INLINE: "inline",
63
15
  FLOATING: "floating",
64
16
  });
65
- const ACC_MAXIMIZE_EVENT = "accmaximize";
66
- const ACC_MINIMIZE_EVENT = "accminimize";
67
- function applyStyles(el, styles) {
68
- Object.entries(styles).forEach(([key, value]) => {
69
- if (key.startsWith("--")) {
70
- el.style.setProperty(key, value);
71
- }
72
- else {
73
- el.style[key] = value;
74
- }
75
- });
17
+ // ═══════════════════════════════════════════════════════════════════════════════
18
+ // INTERNAL CONSTANTS
19
+ // ═══════════════════════════════════════════════════════════════════════════════
20
+ const EVENTS = Object.freeze({
21
+ ACC_MAXIMIZE: "accmaximize",
22
+ ACC_MINIMIZE: "accminimize",
23
+ ACC_READY: "accready",
24
+ });
25
+ const STYLE_ID = "agentforce-client-injected-styles";
26
+ const FLOATING_DIMENSIONS = Object.freeze({
27
+ MINIMIZED_HEIGHT: "56px",
28
+ MAXIMIZED_HEIGHT: "742px",
29
+ });
30
+ // ═══════════════════════════════════════════════════════════════════════════════
31
+ // STYLES – Injected CSS (overrides acc-sdk-wrapper inline width/height via !important)
32
+ // ═══════════════════════════════════════════════════════════════════════════════
33
+ const AGENTFORCE_CLIENT_CSS = `
34
+ :root {
35
+ --minimized-iframe-width: 180px !important;
36
+ --minimized-iframe-height: 70px !important;
76
37
  }
77
- function applyFloatingMinimized(el) {
78
- applyStyles(el, {
79
- ...FLOATING_MINIMIZED,
80
- boxShadow: FLOATING_BASE.boxShadow,
81
- transition: FLOATING_BASE.transition,
82
- });
38
+
39
+ .acc-container:has(> .acc-frame.inline) {
40
+ height: 100%;
41
+ width: 100%;
83
42
  }
84
- function applyFloatingMaximized(el) {
85
- applyStyles(el, FLOATING_MAXIMIZED);
43
+
44
+ .sds-overrides {
45
+ width: auto;
86
46
  }
87
- function toCssLength(value) {
88
- return typeof value === "number" ? `${value}px` : value;
47
+
48
+ .acc-container > .acc-frame {
49
+ display: block;
50
+ position: fixed;
51
+ background: transparent;
52
+ border: none;
53
+ outline: none;
54
+ border-radius: 20px;
55
+ bottom: 24px;
56
+ right: 24px;
57
+ height: 0 !important;
58
+ width: 0 !important;
59
+ max-width: calc(100vw - 4rem);
60
+ max-height: calc(100dvh - 4rem);
61
+ z-index: 999;
89
62
  }
90
- function applyInlineFromConfig(el, { width, height }) {
91
- if (width != null)
92
- el.style.width = toCssLength(width);
93
- if (height != null) {
94
- const heightValue = toCssLength(height);
95
- el.style.height = heightValue;
96
- el.style.setProperty("--agentic-chat-container-height", heightValue);
63
+
64
+ .acc-container > .acc-frame.inline,
65
+ .acc-container > .acc-frame.inline.maximize {
66
+ height: 100% !important;
67
+ width: 100% !important;
68
+ position: static;
69
+ bottom: 0;
70
+ right: 0;
71
+ max-height: 100%;
72
+ max-width: 100%;
73
+ box-shadow: none;
74
+ border-radius: 0;
75
+ }
76
+
77
+ .acc-container > .acc-frame.inline:not(.maximize) {
78
+ width: var(--acc-width, auto) !important;
79
+ height: var(--acc-height, auto) !important;
80
+ }
81
+
82
+ .acc-container > .acc-frame.initial {
83
+ height: var(--minimized-iframe-height, 56px) !important;
84
+ width: var(--minimized-iframe-width, 145px) !important;
85
+ transition: all 0s ease;
86
+ }
87
+
88
+ .acc-container > .acc-frame.minimize {
89
+ height: var(--minimized-iframe-height, 56px) !important;
90
+ width: var(--minimized-iframe-width, 145px) !important;
91
+ transition: width 0.25s ease-in-out, height 0.25s ease-in-out;
92
+ }
93
+
94
+ .acc-container > .acc-frame.maximize {
95
+ width: 400px !important;
96
+ height: 600px !important;
97
+ background: #ffffff;
98
+ box-shadow: 0 10px 25px -3px rgba(0, 0, 0, 0.1), 0 4px 12px -2px rgba(0, 0, 0, 0.05),
99
+ 0 0 2px 0 rgba(0, 0, 0, 0.05), 0 20px 45px -5px rgba(0, 0, 0, 0.08);
100
+ transition: all 0.3s ease;
101
+ }
102
+
103
+ .acc-container > lightning-out-application {
104
+ background: transparent;
105
+ }
106
+
107
+ @media (max-width: 639px) {
108
+ .acc-container > .acc-frame.maximize {
109
+ bottom: 0;
110
+ left: 0;
111
+ right: 0;
112
+ width: 100% !important;
113
+ height: 100vh !important;
114
+ height: 100dvh !important;
115
+ border-radius: 0;
116
+ max-width: 100%;
117
+ max-height: 100vh;
118
+ overflow-y: auto;
119
+ overflow-x: hidden;
120
+ -webkit-overflow-scrolling: touch;
121
+ transition: height 0.2s ease-in-out;
97
122
  }
123
+
124
+ .acc-container:has(> .acc-frame.maximize) {
125
+ position: fixed;
126
+ width: 100%;
127
+ height: 100%;
128
+ overflow: hidden;
129
+ }
130
+ }
131
+ `;
132
+ function injectStyles(additionalCss = "") {
133
+ if (document.getElementById(STYLE_ID))
134
+ return;
135
+ const style = document.createElement("style");
136
+ style.id = STYLE_ID;
137
+ style.textContent = AGENTFORCE_CLIENT_CSS + (additionalCss ? "\n" + additionalCss : "");
138
+ document.head.appendChild(style);
139
+ }
140
+ function toCssLength(value) {
141
+ return typeof value === "number" ? `${value}px` : value;
98
142
  }
99
143
  function normalizeRenderingMode(value) {
100
- if (value === RenderingMode.INLINE || value === RenderingMode.FLOATING) {
144
+ if (value === RenderingMode.INLINE || value === RenderingMode.FLOATING)
101
145
  return value;
102
- }
103
146
  return undefined;
104
147
  }
105
148
  function getRenderingContext(clientConfig) {
106
149
  const renderingConfig = clientConfig?.renderingConfig ?? {};
107
- const normalizedMode = normalizeRenderingMode(renderingConfig.mode);
108
- const mode = normalizedMode ?? RenderingMode.FLOATING;
150
+ const mode = normalizeRenderingMode(renderingConfig.mode) ?? RenderingMode.FLOATING;
109
151
  const isFloating = mode !== RenderingMode.INLINE;
110
152
  return { mode, isFloating, renderingConfig };
111
153
  }
112
- function createChatClientElement() {
154
+ function applyInlineSizing(container, { width, height }) {
155
+ if (width != null)
156
+ container.style.setProperty("--acc-width", toCssLength(width));
157
+ if (height != null) {
158
+ const h = toCssLength(height);
159
+ container.style.setProperty("--acc-height", h);
160
+ container.style.setProperty("--agentic-chat-container-height", h);
161
+ }
162
+ }
163
+ function createFrameElement() {
113
164
  const el = document.createElement(AGENTFORCE_CLIENT_ELEMENT_TAG);
114
165
  el.classList.add("acc-frame");
115
166
  return el;
116
167
  }
117
- function applyInitialClientStyles(el, context) {
168
+ function applyFrameInitialState(el, context, container) {
169
+ el.style.opacity = "0";
170
+ el.style.pointerEvents = "none";
171
+ el.style.setProperty("--agentic-chat-container-height", "100vh");
118
172
  if (context.isFloating) {
119
- applyStyles(el, FLOATING_BASE);
120
- applyFloatingMinimized(el);
173
+ el.classList.add("floating");
174
+ el.classList.remove("maximize", "minimize");
175
+ el.classList.add("initial");
121
176
  }
122
177
  else {
123
- applyStyles(el, INLINE_BASE);
124
- applyInlineFromConfig(el, context.renderingConfig);
178
+ el.classList.add("inline");
179
+ applyInlineSizing(container, context.renderingConfig);
125
180
  }
126
181
  }
127
- function attachResizeHandlers(el, isFloating) {
128
- const setSizeClass = (className) => {
129
- el.classList.remove("maximize", "minimize");
130
- el.classList.add(className);
182
+ function attachFrameResizeHandlers(el, container, isFloating, loApp) {
183
+ const onAccReady = () => {
184
+ el.style.opacity = "";
185
+ el.style.pointerEvents = "";
186
+ if (loApp) {
187
+ loApp.style.opacity = "";
188
+ loApp.style.pointerEvents = "";
189
+ }
131
190
  };
132
- const handleMaximize = () => {
133
- setSizeClass("maximize");
134
- if (isFloating)
135
- applyFloatingMaximized(el);
191
+ el.addEventListener(EVENTS.ACC_READY, onAccReady);
192
+ if (!isFloating)
193
+ return;
194
+ const onMaximize = () => {
195
+ el.classList.remove("initial", "minimize");
196
+ el.classList.add("maximize");
136
197
  };
137
- const handleMinimize = () => {
138
- setSizeClass("minimize");
139
- if (isFloating)
140
- applyFloatingMinimized(el);
198
+ const onMinimize = () => {
199
+ el.classList.remove("maximize");
200
+ el.classList.add("minimize");
201
+ container.style.setProperty("--agentic-chat-container-height", FLOATING_DIMENSIONS.MINIMIZED_HEIGHT);
141
202
  };
142
- el.addEventListener(ACC_MAXIMIZE_EVENT, handleMaximize);
143
- el.addEventListener(ACC_MINIMIZE_EVENT, handleMinimize);
203
+ el.addEventListener(EVENTS.ACC_MAXIMIZE, onMaximize);
204
+ el.addEventListener(EVENTS.ACC_MINIMIZE, onMinimize);
144
205
  }
145
- function createAndMountChatClient(container, clientConfig) {
206
+ function createAndMountFrame(container, clientConfig, loApp) {
207
+ injectStyles();
146
208
  const config = { ...(clientConfig ?? {}) };
147
209
  const context = getRenderingContext(config);
148
- const el = createChatClientElement();
210
+ const el = createFrameElement();
149
211
  el.configuration = config;
150
- applyInitialClientStyles(el, context);
151
- attachResizeHandlers(el, context.isFloating);
212
+ applyFrameInitialState(el, context, container);
213
+ attachFrameResizeHandlers(el, container, context.isFloating, loApp);
152
214
  container.appendChild(el);
153
215
  return el;
154
216
  }
155
- /**
156
- * Resolves a container parameter to an HTMLElement
157
- * @param container - CSS selector or HTMLElement
158
- * @returns The resolved HTMLElement or null if not found
159
- * @internal
160
- */
161
- function resolveContainer(container) {
162
- if (container instanceof HTMLElement)
163
- return container;
164
- if (typeof container === "string")
165
- return document.querySelector(container);
166
- return null;
167
- }
168
- /**
169
- * Create and configure the Lightning Out application and chat client component
170
- * @param container - The container element
171
- * @param salesforceOrigin - The Salesforce origin URL
172
- * @param agentforceClientConfig - Configuration for the Agentforce client
173
- * @returns The created Lightning Out app and chat client component
174
- * @internal
175
- */
217
+ // ═══════════════════════════════════════════════════════════════════════════════
218
+ // LIGHTNING OUT LO app creation and error handling
219
+ // ═══════════════════════════════════════════════════════════════════════════════
176
220
  function createAndMountLoApp(container, salesforceOrigin, appId, frontdoorUrl) {
177
221
  const loApp = new LightningOutApplication();
178
- if (salesforceOrigin) {
222
+ if (salesforceOrigin)
179
223
  loApp.setAttribute("org-url", salesforceOrigin);
180
- }
181
224
  loApp.setAttribute("components", `${AGENTFORCE_CLIENT_NAMESPACE}/${AGENTFORCE_CLIENT_COMPONENT_NAME}`);
182
- if (appId) {
225
+ if (appId)
183
226
  loApp.setAttribute("app-id", appId);
184
- }
185
- if (frontdoorUrl) {
227
+ if (frontdoorUrl)
186
228
  loApp.setAttribute("frontdoor-url", frontdoorUrl);
187
- }
188
- loApp.style.background = "transparent";
229
+ loApp.style.opacity = "0";
230
+ loApp.style.pointerEvents = "none";
231
+ attachLoEventHandlers(loApp);
189
232
  container.appendChild(loApp);
190
233
  return loApp;
191
234
  }
192
- function attachLoAppErrorHandler(loApp) {
193
- loApp.addEventListener("lo.application.error", (event) => {
194
- console.error("Agentforce Conversation Client: Lightning Out error:", event.detail);
235
+ function attachLoEventHandlers(loApp) {
236
+ loApp.addEventListener("lo.application.ready", (e) => {
237
+ console.log("Agentforce Conversation Client: Lightning Out ready", e.detail != null ? e.detail : "");
238
+ });
239
+ loApp.addEventListener("lo.application.error", (e) => {
240
+ console.error("Agentforce Conversation Client: Lightning Out error:", e.detail);
241
+ });
242
+ loApp.addEventListener("lo.iframe.error", (e) => {
243
+ console.error("Agentforce Conversation Client: Lightning Out iframe error:", e.detail);
195
244
  });
196
245
  }
246
+ // ═══════════════════════════════════════════════════════════════════════════════
247
+ // CONTAINER & EMBED
248
+ // ═══════════════════════════════════════════════════════════════════════════════
249
+ function resolveContainer(container) {
250
+ if (container instanceof HTMLElement)
251
+ return container;
252
+ if (typeof container === "string")
253
+ return document.querySelector(container);
254
+ return null;
255
+ }
197
256
  function embedIntoContainer(containerElement, options) {
198
257
  const { salesforceOrigin, appId, frontdoorUrl, agentforceClientConfig = {} } = options;
258
+ containerElement.classList.add("acc-container");
199
259
  const loApp = createAndMountLoApp(containerElement, salesforceOrigin, appId, frontdoorUrl);
200
- attachLoAppErrorHandler(loApp);
201
- const chatClientComponent = createAndMountChatClient(containerElement, agentforceClientConfig);
260
+ const chatClientComponent = createAndMountFrame(containerElement, agentforceClientConfig, loApp);
202
261
  return { loApp, chatClientComponent };
203
262
  }
263
+ // ═══════════════════════════════════════════════════════════════════════════════
264
+ // PUBLIC API
265
+ // ═══════════════════════════════════════════════════════════════════════════════
204
266
  /**
205
- * Embeds the Agentforce Conversation Client into a specified DOM container.
206
- *
207
- * @param options - Configuration options
208
- * @returns The created elements
209
- * @throws Error if required options are missing
267
+ * Embeds the Agentforce Conversation Client into a DOM container.
268
+ * Embed is hidden (opacity 0) until the frame receives the "accready" event.
210
269
  *
211
270
  * @example
212
- * ```ts
213
- * embedAgentforceClient({
214
- * container: '#agentforce-conversation-client-container',
271
+ * const { loApp, chatClientComponent } = embedAgentforceClient({
272
+ * container: '#agentforce-container',
215
273
  * salesforceOrigin: 'https://myorg.my.salesforce.com',
216
- * agentforceClientConfig: { styleTokens: { MessageBlockInboundColor: '#0176d3' } }
217
- * });
218
- * ```
219
- *
220
- * @example
221
- * ```ts
222
- * // Listen for Lightning Out events after embedding
223
- * const { loApp } = embedAgentforceClient({ ... });
224
- *
225
- * loApp.addEventListener('lo.application.ready', () => {
226
- * console.log('Lightning Out is ready');
227
- * });
228
- *
229
- * loApp.addEventListener('lo.component.ready', (event) => {
230
- * console.log('Component ready:', event.detail.componentName);
274
+ * agentforceClientConfig: { renderingConfig: { mode: 'Floating' } }
231
275
  * });
232
- * ```
233
276
  */
234
277
  export function embedAgentforceClient(options) {
235
278
  const { container, salesforceOrigin, appId, frontdoorUrl, agentforceClientConfig = {}, } = options ?? {};
@@ -45,7 +45,7 @@ describe("Agentforce Conversation Client SDK", () => {
45
45
  });
46
46
  }).toThrow("Agentforce Conversation Client: container is required");
47
47
  });
48
- it("throws when salesforceOrigin is missing", () => {
48
+ it("throws when neither salesforceOrigin nor frontdoorUrl is provided", () => {
49
49
  expect(() => {
50
50
  embedAgentforceClient({
51
51
  container: "#test-container",
@@ -130,23 +130,19 @@ describe("Agentforce Conversation Client SDK", () => {
130
130
  });
131
131
  chatClientComponent.dispatchEvent(new Event("accmaximize"));
132
132
  expect(chatClientComponent.classList.contains("maximize")).toBe(true);
133
- expect(chatClientComponent.style.width).toBe("380px");
134
- expect(chatClientComponent.style.height).toBe("540px");
135
133
  chatClientComponent.dispatchEvent(new Event("accminimize"));
136
134
  expect(chatClientComponent.classList.contains("minimize")).toBe(true);
137
- expect(chatClientComponent.style.width).toBe("145px");
138
- expect(chatClientComponent.style.height).toBe("56px");
139
135
  });
140
136
  it("applies inline width/height when configured", () => {
141
- const { chatClientComponent } = embedAgentforceClient({
137
+ embedAgentforceClient({
142
138
  container: "#test-container",
143
139
  salesforceOrigin: "https://test.salesforce.com",
144
140
  agentforceClientConfig: {
145
141
  renderingConfig: { mode: "inline", width: 420, height: 600 },
146
142
  },
147
143
  });
148
- expect(chatClientComponent.style.width).toBe("420px");
149
- expect(chatClientComponent.style.height).toBe("600px");
150
- expect(chatClientComponent.style.getPropertyValue("--agentic-chat-container-height")).toBe("600px");
144
+ expect(container.style.getPropertyValue("--acc-width")).toBe("420px");
145
+ expect(container.style.getPropertyValue("--acc-height")).toBe("600px");
146
+ expect(container.style.getPropertyValue("--agentic-chat-container-height")).toBe("600px");
151
147
  });
152
148
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@salesforce/agentforce-conversation-client",
3
3
  "description": "Agentforce Conversation Client SDK for embedding via Lightning Out 2.0",
4
- "version": "1.25.0",
4
+ "version": "1.25.2",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "type": "module",
7
7
  "main": "./dist/index.js",
@@ -37,5 +37,5 @@
37
37
  "publishConfig": {
38
38
  "access": "public"
39
39
  },
40
- "gitHead": "3e523f7686a9863422228d253bb538c123a2ff53"
40
+ "gitHead": "6e4299053c2bdad6b1eb6d81c983368bd539e711"
41
41
  }