@clivly/chat-widget 0.7.2 → 0.7.3

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.
Files changed (2) hide show
  1. package/README.md +140 -108
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,128 +1,155 @@
1
- # @clivly/chat-widget
1
+ # `@clivly/chat-widget`
2
2
 
3
- Embeddable chat widget for Clivly conversations.
3
+ Embeddable chat widget package for Clivly conversations.
4
4
 
5
- ## Install
5
+ > **Preview-quality surface.** Install with `npm install @clivly/chat-widget`.
6
+ > The end-to-end path (SDK session handler, `/widget.js` serving, operator
7
+ > inbox) is implemented and covered by integration tests; treat it as
8
+ > design-partner quality while the conversations UX settles.
6
9
 
7
- ```bash
8
- npm install @clivly/chat-widget
9
- ```
10
-
11
- Peer dependencies:
12
-
13
- ```bash
14
- npm install react react-dom
15
- ```
16
-
17
- This package is a Tier 2 surface in
18
- [STABILITY.md](https://github.com/amani-joseph/clivly.com/blob/master/STABILITY.md).
19
- Stable releases publish on npm's `latest` tag. Use `@next` only when you are
20
- testing a prerelease build.
10
+ > **New here?** Start with
11
+ > [Adding the chat widget](../../docs/guides/adding-the-chat-widget.md) — the
12
+ > end-to-end integration guide (widget record, session route, embed, operator
13
+ > inbox). This README is the API-level reference for the package's entrypoints.
21
14
 
22
- For the end-to-end integration flow, start with:
23
- [Adding the chat widget](https://github.com/amani-joseph/clivly.com/blob/master/docs/guides/adding-the-chat-widget.md).
15
+ This package currently exposes four stable entrypoints with different intended
16
+ use cases.
24
17
 
25
18
  ## Entrypoints
26
19
 
27
20
  ### `@clivly/chat-widget`
28
21
 
29
- Use the package root for React components plus browser-safe helpers.
22
+ Use the package root for app-side integration code.
30
23
 
31
- Exports include:
24
+ It exports:
32
25
 
33
- - `ChatWidget`
34
- - `ChatLauncher`
35
- - `ChatPanel`
36
- - `ConversationView`
37
- - `MessageComposer`
38
- - `PreChatForm`
26
+ - React widget components
39
27
  - `createSessionFetcher()`
40
28
  - `createClivlyTransport()`
41
- - `createWebSocketTransport()`
42
- - `createLoopbackTransport()`
43
- - `mountChatWidget()`
44
- - `mountChatWidgetScript()`
45
- - `autoMountChatWidgetScript()`
29
+ - side-effect-free mount helpers
46
30
 
47
31
  Example:
48
32
 
49
33
  ```ts
50
34
  import {
51
- ChatWidget,
52
- createSessionFetcher,
35
+ createSessionFetcher,
36
+ createClivlyTransport,
37
+ mountChatWidget,
53
38
  } from "@clivly/chat-widget";
39
+
40
+ const getSession = createSessionFetcher({
41
+ sessionUrl: "/api/clivly/chat/session",
42
+ });
54
43
  ```
55
44
 
56
45
  ### `@clivly/chat-widget/browser`
57
46
 
58
- Browser entry that auto-mounts at module evaluation time when `document`
59
- exists. It also exports `mountChatWidget()`, `mountChatWidgetScript()`, and
60
- `autoMountChatWidgetScript()`.
47
+ Use this entry for the browser auto-mount module build.
48
+
49
+ This entry:
50
+
51
+ - exports `mountChatWidget()`
52
+ - exports `mountChatWidgetScript()`
53
+ - exports `autoMountChatWidgetScript()`
54
+ - auto-mounts at module evaluation time when `document` exists
55
+
56
+ This is the module-side equivalent of the script-tag embed behavior.
61
57
 
62
58
  ### `@clivly/chat-widget/mount`
63
59
 
64
- Use this when you want the mounting helpers without the browser entry's
60
+ Use this entry when you want the mount helpers without the browser entry's
65
61
  auto-mount side effect.
66
62
 
67
- ### `@clivly/chat-widget/script`
68
-
69
- Maps to the generated global bundle at `dist/widget.global.js` for script-tag or
70
- CDN-style delivery.
63
+ This is the safest browser/helper entry for host-controlled mounting.
71
64
 
72
- ## React usage
65
+ It exports:
73
66
 
74
- ```tsx
75
- import { ChatWidget, createSessionFetcher } from "@clivly/chat-widget";
76
-
77
- <ChatWidget
78
- widgetId="support"
79
- getSession={createSessionFetcher({
80
- sessionUrl: "/api/clivly/widget/session",
81
- })}
82
- />;
83
- ```
67
+ - `mountChatWidget()`
68
+ - `mountChatWidgetScript()`
69
+ - `autoMountChatWidgetScript()`
70
+ - `MountChatWidgetOptions`
71
+ - `ChatWidgetMount`
72
+ - `ScriptMountResult`
84
73
 
85
- ## Script-tag usage
74
+ ### `@clivly/chat-widget/script`
86
75
 
87
- ```html
88
- <script
89
- src="https://api.clivly.com/widget.js"
90
- data-widget-id="support"
91
- data-session-url="/api/clivly/widget/session"
92
- defer
93
- ></script>
94
- ```
76
+ This entry maps to the generated global/browser artifact:
95
77
 
96
- Supported attributes:
78
+ - `dist/widget.global.js`
97
79
 
98
- | Attribute | Required | Purpose |
99
- | --- | --- | --- |
100
- | `data-widget-id` | yes | Public widget slug from the Clivly dashboard |
101
- | `data-session-url` | yes | Your backend route that mounts `createChatSessionHandler()` |
102
- | `data-theme` | no | `auto`, `light`, or `dark` |
103
- | `data-socket-url-template` | no | Legacy socket override; usually unnecessary |
80
+ Use it for script-tag delivery, CDN-style consumption, or any future server path
81
+ that serves the bundled widget directly.
104
82
 
105
83
  ## Theming
106
84
 
107
- The widget ships light and dark palettes and follows the host by default.
85
+ The widget ships light and dark palettes and follows the host app by default.
86
+ For integration recipes (Tailwind, next-themes, a custom toggle) see
87
+ [the guide's theming section](../../docs/guides/adding-the-chat-widget.md#theming).
108
88
 
109
- `theme` accepts:
89
+ ### `theme`
110
90
 
111
91
  | Value | Behaviour |
112
92
  | --- | --- |
113
- | `"auto"` | Follows `data-theme` on `<html>`, then `dark` / `light` classes on `<html>`, then `prefers-color-scheme` |
114
- | `"light"` / `"dark"` | Pinned theme |
93
+ | `"auto"` *(default)* | Follows the host: `data-theme="dark"`/`"light"` on `<html>`, then a `dark`/`light` class on `<html>`, then `prefers-color-scheme`. Re-resolves live. |
94
+ | `"light"` / `"dark"` | Pinned. Host signals are ignored and nothing is observed. |
115
95
 
116
- Set it as a React prop, a script-tag `data-theme`, or through
117
- `mountChatWidget()` options. `mountChatWidgetScript()` also returns
118
- `setTheme(theme)` for hosts with a custom toggle.
96
+ Set it as a prop (`<ChatWidget theme="dark" />`), as `data-theme` on the script
97
+ tag, or as `theme` in `mountChatWidget()` options. An unrecognised
98
+ `data-theme` value falls back to `"auto"` rather than throwing.
119
99
 
120
- The resolved theme is written to `data-clivly-theme="light|dark"` on the widget
121
- root.
100
+ `mountChatWidgetScript()` also returns `setTheme(theme)` for hosts whose toggle
101
+ does not touch `<html>`:
122
102
 
123
- ## Session bootstrap
103
+ ```ts
104
+ const { setTheme } = mountChatWidgetScript(script);
105
+ setTheme("dark"); // pin
106
+ setTheme("auto"); // hand control back to the host
107
+ ```
108
+
109
+ The resolved theme is applied as `data-clivly-theme="light|dark"` on the widget
110
+ root, together with `color-scheme`, so native scrollbars, autofill, and the
111
+ caret follow the panel.
112
+
113
+ ### Palette tokens
114
+
115
+ Every colour reads through a CSS custom property. React hosts can override any
116
+ of them inline — inline declarations beat both palette rules, so no specificity
117
+ work is needed:
118
+
119
+ ```tsx
120
+ <ChatWidget style={{ "--clivly-chat-panel": "#0b0f19" }} widgetId="support" />
121
+ ```
122
+
123
+ | Token | Light | Dark |
124
+ | --- | --- | --- |
125
+ | `--clivly-chat-accent` | `#185adb` | `#4f8cff` |
126
+ | `--clivly-chat-accent-contrast` | `#ffffff` | `#0b1220` |
127
+ | `--clivly-chat-panel` | `#ffffff` | `#111827` |
128
+ | `--clivly-chat-input` | `transparent` | `#0b1220` |
129
+ | `--clivly-chat-border` | `#d6dde8` | `#2a3546` |
130
+ | `--clivly-chat-text` | `#132238` | `#e8edf5` |
131
+ | `--clivly-chat-muted` | `#60738a` | `#93a2b8` |
132
+ | `--clivly-chat-visitor` | `#ecf3ff` | `#1e3a6b` |
133
+ | `--clivly-chat-operator` | `#f5f7fa` | `#1b2534` |
134
+ | `--clivly-chat-shadow` | `rgba(19, 34, 56, 0.18)` | `rgba(0, 0, 0, 0.5)` |
135
+ | `--clivly-chat-error-bg` | `#fff1f1` | `#2c1618` |
136
+ | `--clivly-chat-error-border` | `#f2c2c2` | `#5c2a2e` |
137
+ | `--clivly-chat-error-text` | `#9f2d2d` | `#ffb4b4` |
138
+
139
+ The widget record's `brandColor` overrides `--clivly-chat-accent` in **both**
140
+ themes — the widget will not silently lighten your brand. If your brand colour
141
+ is very dark it will be low-contrast on the dark panel; pick a lighter accent,
142
+ or override the token per theme in a React host.
143
+
144
+ Deep per-token overrides are not available on the script-tag path: it mounts
145
+ into a Shadow DOM, so host CSS cannot reach the widget's internals. Use
146
+ `brandColor` and the two themes there.
147
+
148
+ ## Session bootstrap shape
149
+
150
+ The widget expects a session bootstrap endpoint that returns a
151
+ `WidgetSessionPayload`.
124
152
 
125
- The widget expects a bootstrap endpoint that returns a `WidgetSessionPayload`.
126
153
  Important fields include:
127
154
 
128
155
  - `token`
@@ -132,21 +159,39 @@ Important fields include:
132
159
  - `messages`
133
160
  - optional `socketUrl`
134
161
 
135
- When `socketUrl` is present, the widget prefers it over reconstructing one from
136
- `socketUrlTemplate`.
162
+ When `socketUrl` is present, the widget prefers it over reconstructing the
163
+ socket URL from a client-side template.
164
+
165
+ ## Transport behavior
137
166
 
138
- ## Transport behaviour
167
+ The package includes:
139
168
 
140
- The default browser mount order is:
169
+ - `createClivlyTransport()` for real Clivly backends
170
+ - `createWebSocketTransport()` for explicit socket wiring
171
+ - `createLoopbackTransport()` for local UI/testing flows
141
172
 
142
- 1. use a caller-provided `createTransport`
173
+ The default browser mount behavior is:
174
+
175
+ 1. use a caller-provided `createTransport` when present
143
176
  2. otherwise prefer `session.socketUrl`
144
- 3. otherwise fall back to `socketUrlTemplate`
177
+ 3. otherwise fall back to `socketUrlTemplate` when provided
178
+
179
+ ## Build outputs
180
+
181
+ The package currently produces:
145
182
 
146
- ## Host-side session route
183
+ - `dist/index.*`
184
+ - `dist/browser.*`
185
+ - `dist/browser-mount.*`
186
+ - `dist/widget.global.js`
147
187
 
148
- The widget talks to your backend, not directly to Clivly. Mount the session
149
- handler from the SDK on your own origin:
188
+ The `browser` and `browser-mount` outputs are built as standalone entrypoints.
189
+
190
+ ## Host-side pairing
191
+
192
+ The host-side session handler is the bridge between a backend holding
193
+ `CLIVLY_SECRET_KEY` and the widget's `sessionUrl`. Import it from `clivly/sdk`,
194
+ which is available from the `clivly` package `clivly init` already installs:
150
195
 
151
196
  ```ts
152
197
  import { createChatSessionHandler } from "clivly/sdk";
@@ -156,23 +201,10 @@ export const POST = createChatSessionHandler({
156
201
  });
157
202
  ```
158
203
 
159
- The current scaffolded/default route path is:
160
-
161
- ```text
162
- /api/clivly/widget/session
163
- ```
164
-
165
- Use the handler rather than hand-writing the proxy. It forwards `origin`
166
- correctly, accepts `visitorToken: null` for first-time visitors, and returns a
167
- clean JSON `502` when Clivly is unreachable.
168
-
169
- ## More docs
170
-
171
- - End-to-end guide:
172
- [Adding the chat widget](https://github.com/amani-joseph/clivly.com/blob/master/docs/guides/adding-the-chat-widget.md)
173
- - Release notes:
174
- [CHANGELOG.md](https://github.com/amani-joseph/clivly.com/blob/master/CHANGELOG.md)
175
-
176
- ## License
204
+ `@clivly/sdk` exports the same handler if you depend on it directly. Don't import
205
+ from `clivly` (the package root) — that entry is the CLI and is Node-only.
177
206
 
178
- MIT
207
+ Use the handler rather than hand-writing the proxy: it puts `origin` in the
208
+ request body (the backend requires it there, and only falls back to the `Origin`
209
+ header), accepts `visitorToken: null` for a first-time visitor, and turns an
210
+ unreachable Clivly into a JSON `502` instead of a thrown `fetch`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clivly/chat-widget",
3
- "version": "0.7.2",
3
+ "version": "0.7.3",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Clivly chat widget — embeddable React and script-tag entrypoints for Clivly conversations.",