@clivly/chat-widget 0.15.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,6 +1,24 @@
1
1
  import { Root } from "react-dom/client";
2
2
  import { CSSProperties, ReactElement } from "react";
3
- //#region src/theme.d.ts
3
+ /**
4
+ * Where the widget sits on the host page, and what its launcher looks like.
5
+ *
6
+ * Until 0.16 the widget rendered in normal flow wherever it was mounted — the
7
+ * script tag inserted it directly after itself, so most embeds showed a
8
+ * full-width-label pill at the end of the page rather than a floating button.
9
+ * Floating in a corner is now the default; `"inline"` keeps the old behaviour
10
+ * for a host that positions the widget itself.
11
+ */
12
+ type ChatWidgetPlacement = "bottom-left" | "bottom-right" | "inline";
13
+ /**
14
+ * - `"auto"` (default): the labelled pill on wide screens, a 48px icon-only
15
+ * button below 48rem, where a pill covers the host's own controls.
16
+ * - `"pill"`: always the labelled pill.
17
+ * - `"icon"`: always the icon-only button.
18
+ *
19
+ * The label stays the button's accessible name in every variant.
20
+ */
21
+ type ChatWidgetLauncher = "auto" | "icon" | "pill";
4
22
  /**
5
23
  * Theme resolution for the widget.
6
24
  *
@@ -25,8 +43,6 @@ interface ResolveThemeOptions {
25
43
  * the majority of pages.
26
44
  */
27
45
  export declare function resolveTheme(theme: ChatWidgetTheme, { root, view }?: ResolveThemeOptions): ResolvedTheme;
28
- //#endregion
29
- //#region src/types.d.ts
30
46
  type WidgetSenderType = "visitor" | "operator" | "system";
31
47
  interface WidgetConfig {
32
48
  brandColor?: string | null;
@@ -143,8 +159,6 @@ interface WidgetErrorEvent {
143
159
  type: "error";
144
160
  }
145
161
  type WidgetServerEvent = WidgetAssistantStatusEvent | WidgetConversationSnapshotEvent | WidgetErrorEvent | WidgetMessageAckEvent | WidgetMessageCreatedEvent | WidgetSessionReadyEvent | WidgetSupportStateEvent;
146
- //#endregion
147
- //#region src/transport.d.ts
148
162
  interface ChatTransportHandlers {
149
163
  onClose: () => void;
150
164
  onError: (error: Error) => void;
@@ -183,8 +197,21 @@ interface CreateLoopbackTransportOptions {
183
197
  replyDelayMs?: number;
184
198
  }
185
199
  export declare function createLoopbackTransport({ operatorName, operatorReply, replyDelayMs }?: CreateLoopbackTransportOptions): CreateChatTransport;
186
- //#endregion
187
- //#region src/chat-widget.d.ts
200
+ /**
201
+ * Where the widget keeps the visitor token that resumes a conversation.
202
+ *
203
+ * Keyed by widget AND by who the token was issued to. One key per widget used
204
+ * to hand the token to whoever opened the widget next on that browser — after
205
+ * a sign-out, or between two people who don't sign in at all — and the server
206
+ * resumed the previous person's thread for them (chat widget session review
207
+ * 2026-10-28, S1). The server now refuses that resume on its own; this keeps
208
+ * each person's token to themselves so a returning visitor still resumes.
209
+ *
210
+ * The identity part is a short hash of the normalised email, so the address
211
+ * itself isn't written into storage keys. It only partitions storage: the
212
+ * server's identity check is the security boundary, not this.
213
+ */
214
+ type VisitorTokenStorage = Pick<Storage, "getItem" | "setItem"> & Partial<Pick<Storage, "removeItem">>;
188
215
  interface ChatWidgetProps {
189
216
  className?: string;
190
217
  createTransport?: CreateChatTransport;
@@ -208,8 +235,23 @@ interface ChatWidgetProps {
208
235
  defaultVisitor?: Partial<ChatWidgetVisitor>;
209
236
  getSession: GetSession;
210
237
  initiallyOpen?: boolean;
238
+ /** Launcher shape; see {@link ChatWidgetLauncher}. Defaults to `"auto"`. */
239
+ launcher?: ChatWidgetLauncher;
240
+ /** The launcher's visible text, and always its accessible name. */
211
241
  launcherLabel?: string;
212
- storage?: Pick<Storage, "getItem" | "setItem">;
242
+ /**
243
+ * Where the widget sits; see {@link ChatWidgetPlacement}. Defaults to
244
+ * `"bottom-right"`, floating clear of the device's safe-area insets. Stacks
245
+ * at `--clivly-chat-z-index` (default 2147483000) — lower it through
246
+ * `style` to sit beneath the host's own dialogs.
247
+ */
248
+ placement?: ChatWidgetPlacement;
249
+ /**
250
+ * Where the visitor token is kept, per widget and per visitor (see
251
+ * visitor-token-storage.ts). `removeItem` is optional; with it, the
252
+ * pre-0.16 shared token is retired after its first use.
253
+ */
254
+ storage?: VisitorTokenStorage;
213
255
  /**
214
256
  * Inline styles on the widget root. The intended use is overriding palette
215
257
  * tokens — `{ "--clivly-chat-panel": "#0b0f19" }` — which works because
@@ -224,14 +266,12 @@ interface ChatWidgetProps {
224
266
  theme?: ChatWidgetTheme;
225
267
  widgetId: string;
226
268
  }
227
- export declare function ChatWidget({ className, createTransport, defaultVisitor, getSession, initiallyOpen, launcherLabel, storage, style, theme, widgetId }: ChatWidgetProps): ReactElement;
269
+ export declare function ChatWidget({ className, createTransport, defaultVisitor, getSession, initiallyOpen, launcher, launcherLabel, placement, storage, style, theme, widgetId }: ChatWidgetProps): ReactElement;
228
270
  export declare function ChatLauncher(): null;
229
271
  export declare function ChatPanel(): null;
230
272
  export declare function MessageComposer(): null;
231
273
  export declare function PreChatForm(): null;
232
274
  export declare function ConversationView(): null;
233
- //#endregion
234
- //#region src/browser-mount.d.ts
235
275
  interface MountChatWidgetOptions$1 extends Omit<ChatWidgetProps, "getSession" | "widgetId"> {
236
276
  container: Element | ShadowRoot;
237
277
  sessionUrl: string;
@@ -256,8 +296,6 @@ interface ScriptMountResult$1 extends ChatWidgetMount$1 {
256
296
  }
257
297
  declare function mountChatWidgetScript$1(script?: HTMLScriptElement): ScriptMountResult$1;
258
298
  declare function autoMountChatWidgetScript$1(script?: HTMLScriptElement | null): ScriptMountResult$1 | null;
259
- //#endregion
260
- //#region src/clivly-transport.d.ts
261
299
  interface CreateClivlyTransportOptions$1 {
262
300
  createSocket?: (url: string, protocols?: string | string[]) => WebSocket;
263
301
  }
@@ -269,15 +307,11 @@ interface CreateClivlyTransportOptions$1 {
269
307
  * produce a silently dead socket.
270
308
  */
271
309
  declare function createClivlyTransport$1(options?: CreateClivlyTransportOptions$1): CreateChatTransport;
272
- //#endregion
273
- //#region src/session.d.ts
274
310
  interface CreateSessionFetcherOptions {
275
311
  fetchImpl?: typeof fetch;
276
312
  sessionUrl: string;
277
313
  }
278
314
  export declare function createSessionFetcher({ fetchImpl, sessionUrl }: CreateSessionFetcherOptions): GetSession;
279
- //#endregion
280
- //#region src/index.d.ts
281
315
  export type ChatWidgetMount = ChatWidgetMount$1;
282
316
  export type MountChatWidgetOptions = MountChatWidgetOptions$1;
283
317
  export type ScriptMountResult = ScriptMountResult$1;
@@ -286,5 +320,4 @@ export type CreateClivlyTransportOptions = CreateClivlyTransportOptions$1;
286
320
  export declare const createClivlyTransport: typeof createClivlyTransport$1;
287
321
  export declare const mountChatWidget: typeof mountChatWidget$1;
288
322
  export declare const mountChatWidgetScript: typeof mountChatWidgetScript$1;
289
- //#endregion
290
- export type { ChatTransportConnection, ChatTransportHandlers, ChatWidgetProps, ChatWidgetTheme, ChatWidgetVisitor, CreateChatTransport, CreateChatTransportOptions, CreateLoopbackTransportOptions, CreateWebSocketTransportOptions, GetSession, GetSessionOptions, ResolvedTheme, WidgetAssistantStatusEvent, WidgetClientCreateMessageEvent, WidgetClientEvent, WidgetClientReadEvent, WidgetClientTopicEvent, WidgetConfig, WidgetContact, WidgetConversation, WidgetConversationSnapshotEvent, WidgetErrorEvent, WidgetMessage, WidgetMessageAckEvent, WidgetMessageCreatedEvent, WidgetSenderType, WidgetServerEvent, WidgetSessionPayload, WidgetSessionReadyEvent, WidgetSummary, WidgetSupport, WidgetSupportState, WidgetSupportStateEvent, WidgetSupportTopic };
323
+ export type { ChatTransportConnection, ChatTransportHandlers, ChatWidgetLauncher, ChatWidgetPlacement, ChatWidgetProps, ChatWidgetTheme, ChatWidgetVisitor, CreateChatTransport, CreateChatTransportOptions, CreateLoopbackTransportOptions, CreateWebSocketTransportOptions, GetSession, GetSessionOptions, ResolvedTheme, WidgetAssistantStatusEvent, WidgetClientCreateMessageEvent, WidgetClientEvent, WidgetClientReadEvent, WidgetClientTopicEvent, WidgetConfig, WidgetContact, WidgetConversation, WidgetConversationSnapshotEvent, WidgetErrorEvent, WidgetMessage, WidgetMessageAckEvent, WidgetMessageCreatedEvent, WidgetSenderType, WidgetServerEvent, WidgetSessionPayload, WidgetSessionReadyEvent, WidgetSummary, WidgetSupport, WidgetSupportState, WidgetSupportStateEvent, WidgetSupportTopic };
package/dist/index.d.mts CHANGED
@@ -1,6 +1,24 @@
1
1
  import { Root } from "react-dom/client";
2
2
  import { CSSProperties, ReactElement } from "react";
3
- //#region src/theme.d.ts
3
+ /**
4
+ * Where the widget sits on the host page, and what its launcher looks like.
5
+ *
6
+ * Until 0.16 the widget rendered in normal flow wherever it was mounted — the
7
+ * script tag inserted it directly after itself, so most embeds showed a
8
+ * full-width-label pill at the end of the page rather than a floating button.
9
+ * Floating in a corner is now the default; `"inline"` keeps the old behaviour
10
+ * for a host that positions the widget itself.
11
+ */
12
+ type ChatWidgetPlacement = "bottom-left" | "bottom-right" | "inline";
13
+ /**
14
+ * - `"auto"` (default): the labelled pill on wide screens, a 48px icon-only
15
+ * button below 48rem, where a pill covers the host's own controls.
16
+ * - `"pill"`: always the labelled pill.
17
+ * - `"icon"`: always the icon-only button.
18
+ *
19
+ * The label stays the button's accessible name in every variant.
20
+ */
21
+ type ChatWidgetLauncher = "auto" | "icon" | "pill";
4
22
  /**
5
23
  * Theme resolution for the widget.
6
24
  *
@@ -25,8 +43,6 @@ interface ResolveThemeOptions {
25
43
  * the majority of pages.
26
44
  */
27
45
  export declare function resolveTheme(theme: ChatWidgetTheme, { root, view }?: ResolveThemeOptions): ResolvedTheme;
28
- //#endregion
29
- //#region src/types.d.ts
30
46
  type WidgetSenderType = "visitor" | "operator" | "system";
31
47
  interface WidgetConfig {
32
48
  brandColor?: string | null;
@@ -143,8 +159,6 @@ interface WidgetErrorEvent {
143
159
  type: "error";
144
160
  }
145
161
  type WidgetServerEvent = WidgetAssistantStatusEvent | WidgetConversationSnapshotEvent | WidgetErrorEvent | WidgetMessageAckEvent | WidgetMessageCreatedEvent | WidgetSessionReadyEvent | WidgetSupportStateEvent;
146
- //#endregion
147
- //#region src/transport.d.ts
148
162
  interface ChatTransportHandlers {
149
163
  onClose: () => void;
150
164
  onError: (error: Error) => void;
@@ -183,8 +197,21 @@ interface CreateLoopbackTransportOptions {
183
197
  replyDelayMs?: number;
184
198
  }
185
199
  export declare function createLoopbackTransport({ operatorName, operatorReply, replyDelayMs }?: CreateLoopbackTransportOptions): CreateChatTransport;
186
- //#endregion
187
- //#region src/chat-widget.d.ts
200
+ /**
201
+ * Where the widget keeps the visitor token that resumes a conversation.
202
+ *
203
+ * Keyed by widget AND by who the token was issued to. One key per widget used
204
+ * to hand the token to whoever opened the widget next on that browser — after
205
+ * a sign-out, or between two people who don't sign in at all — and the server
206
+ * resumed the previous person's thread for them (chat widget session review
207
+ * 2026-10-28, S1). The server now refuses that resume on its own; this keeps
208
+ * each person's token to themselves so a returning visitor still resumes.
209
+ *
210
+ * The identity part is a short hash of the normalised email, so the address
211
+ * itself isn't written into storage keys. It only partitions storage: the
212
+ * server's identity check is the security boundary, not this.
213
+ */
214
+ type VisitorTokenStorage = Pick<Storage, "getItem" | "setItem"> & Partial<Pick<Storage, "removeItem">>;
188
215
  interface ChatWidgetProps {
189
216
  className?: string;
190
217
  createTransport?: CreateChatTransport;
@@ -208,8 +235,23 @@ interface ChatWidgetProps {
208
235
  defaultVisitor?: Partial<ChatWidgetVisitor>;
209
236
  getSession: GetSession;
210
237
  initiallyOpen?: boolean;
238
+ /** Launcher shape; see {@link ChatWidgetLauncher}. Defaults to `"auto"`. */
239
+ launcher?: ChatWidgetLauncher;
240
+ /** The launcher's visible text, and always its accessible name. */
211
241
  launcherLabel?: string;
212
- storage?: Pick<Storage, "getItem" | "setItem">;
242
+ /**
243
+ * Where the widget sits; see {@link ChatWidgetPlacement}. Defaults to
244
+ * `"bottom-right"`, floating clear of the device's safe-area insets. Stacks
245
+ * at `--clivly-chat-z-index` (default 2147483000) — lower it through
246
+ * `style` to sit beneath the host's own dialogs.
247
+ */
248
+ placement?: ChatWidgetPlacement;
249
+ /**
250
+ * Where the visitor token is kept, per widget and per visitor (see
251
+ * visitor-token-storage.ts). `removeItem` is optional; with it, the
252
+ * pre-0.16 shared token is retired after its first use.
253
+ */
254
+ storage?: VisitorTokenStorage;
213
255
  /**
214
256
  * Inline styles on the widget root. The intended use is overriding palette
215
257
  * tokens — `{ "--clivly-chat-panel": "#0b0f19" }` — which works because
@@ -224,14 +266,12 @@ interface ChatWidgetProps {
224
266
  theme?: ChatWidgetTheme;
225
267
  widgetId: string;
226
268
  }
227
- export declare function ChatWidget({ className, createTransport, defaultVisitor, getSession, initiallyOpen, launcherLabel, storage, style, theme, widgetId }: ChatWidgetProps): ReactElement;
269
+ export declare function ChatWidget({ className, createTransport, defaultVisitor, getSession, initiallyOpen, launcher, launcherLabel, placement, storage, style, theme, widgetId }: ChatWidgetProps): ReactElement;
228
270
  export declare function ChatLauncher(): null;
229
271
  export declare function ChatPanel(): null;
230
272
  export declare function MessageComposer(): null;
231
273
  export declare function PreChatForm(): null;
232
274
  export declare function ConversationView(): null;
233
- //#endregion
234
- //#region src/browser-mount.d.ts
235
275
  interface MountChatWidgetOptions$1 extends Omit<ChatWidgetProps, "getSession" | "widgetId"> {
236
276
  container: Element | ShadowRoot;
237
277
  sessionUrl: string;
@@ -256,8 +296,6 @@ interface ScriptMountResult$1 extends ChatWidgetMount$1 {
256
296
  }
257
297
  declare function mountChatWidgetScript$1(script?: HTMLScriptElement): ScriptMountResult$1;
258
298
  declare function autoMountChatWidgetScript$1(script?: HTMLScriptElement | null): ScriptMountResult$1 | null;
259
- //#endregion
260
- //#region src/clivly-transport.d.ts
261
299
  interface CreateClivlyTransportOptions$1 {
262
300
  createSocket?: (url: string, protocols?: string | string[]) => WebSocket;
263
301
  }
@@ -269,15 +307,11 @@ interface CreateClivlyTransportOptions$1 {
269
307
  * produce a silently dead socket.
270
308
  */
271
309
  declare function createClivlyTransport$1(options?: CreateClivlyTransportOptions$1): CreateChatTransport;
272
- //#endregion
273
- //#region src/session.d.ts
274
310
  interface CreateSessionFetcherOptions {
275
311
  fetchImpl?: typeof fetch;
276
312
  sessionUrl: string;
277
313
  }
278
314
  export declare function createSessionFetcher({ fetchImpl, sessionUrl }: CreateSessionFetcherOptions): GetSession;
279
- //#endregion
280
- //#region src/index.d.ts
281
315
  export type ChatWidgetMount = ChatWidgetMount$1;
282
316
  export type MountChatWidgetOptions = MountChatWidgetOptions$1;
283
317
  export type ScriptMountResult = ScriptMountResult$1;
@@ -286,5 +320,4 @@ export type CreateClivlyTransportOptions = CreateClivlyTransportOptions$1;
286
320
  export declare const createClivlyTransport: typeof createClivlyTransport$1;
287
321
  export declare const mountChatWidget: typeof mountChatWidget$1;
288
322
  export declare const mountChatWidgetScript: typeof mountChatWidgetScript$1;
289
- //#endregion
290
- export type { ChatTransportConnection, ChatTransportHandlers, ChatWidgetProps, ChatWidgetTheme, ChatWidgetVisitor, CreateChatTransport, CreateChatTransportOptions, CreateLoopbackTransportOptions, CreateWebSocketTransportOptions, GetSession, GetSessionOptions, ResolvedTheme, WidgetAssistantStatusEvent, WidgetClientCreateMessageEvent, WidgetClientEvent, WidgetClientReadEvent, WidgetClientTopicEvent, WidgetConfig, WidgetContact, WidgetConversation, WidgetConversationSnapshotEvent, WidgetErrorEvent, WidgetMessage, WidgetMessageAckEvent, WidgetMessageCreatedEvent, WidgetSenderType, WidgetServerEvent, WidgetSessionPayload, WidgetSessionReadyEvent, WidgetSummary, WidgetSupport, WidgetSupportState, WidgetSupportStateEvent, WidgetSupportTopic };
323
+ export type { ChatTransportConnection, ChatTransportHandlers, ChatWidgetLauncher, ChatWidgetPlacement, ChatWidgetProps, ChatWidgetTheme, ChatWidgetVisitor, CreateChatTransport, CreateChatTransportOptions, CreateLoopbackTransportOptions, CreateWebSocketTransportOptions, GetSession, GetSessionOptions, ResolvedTheme, WidgetAssistantStatusEvent, WidgetClientCreateMessageEvent, WidgetClientEvent, WidgetClientReadEvent, WidgetClientTopicEvent, WidgetConfig, WidgetContact, WidgetConversation, WidgetConversationSnapshotEvent, WidgetErrorEvent, WidgetMessage, WidgetMessageAckEvent, WidgetMessageCreatedEvent, WidgetSenderType, WidgetServerEvent, WidgetSessionPayload, WidgetSessionReadyEvent, WidgetSummary, WidgetSupport, WidgetSupportState, WidgetSupportStateEvent, WidgetSupportTopic };