@channlize/react 0.1.1 → 0.4.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/CHANGELOG.md CHANGED
@@ -1,5 +1,68 @@
1
1
  # @channlize/react
2
2
 
3
+ ## 0.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Release every `@channlize/*` package under one shared version. From 0.4.0 on, core, react, mcp and skills always publish together at the same version, so matching versions work together.
8
+ - 7b82215: Add a `debug` option to `useChatSession` and `SupportChat` (also through `ChannlizeChat`'s `chatProps`). The chat no longer writes to the console unless `debug` is on; it used to log every session step and SSE message. `ChannlizeProvider` keeps one client per configuration instead of creating one on every render, the chat calls the latest `onMessage` / `onError` without reopening the stream, and `UseContactFormOptions`, `UseContactFormReturn` and `ChannlizeProviderProps` are exported.
9
+
10
+ ### Patch Changes
11
+
12
+ - 5663cd2: Make `@channlize/core` the single source for what the packages share.
13
+
14
+ - core exports `DEFAULT_BASE_URL`, `DEFAULT_TIMEOUT`, `EVENT_SEVERITIES`, `EVENT_KEY_PATTERN`, `isValidEventKey`, `keyKind` (widget vs. server key), `readChannlizeEnv` (the `CHANNLIZE_*` variables) and `parseApiError` (the API's error shape). `createNotifier`, the client and `@channlize/mcp` use them instead of their own copies.
15
+ - `ChannlizeError` gains `requestId` and `details` (the API's error body, e.g. `limit`, `used` and `resetAt` on a plan-limit 429). When a legacy route puts its human-readable text in `error`, it becomes the message instead of `HTTP <status>`.
16
+ - The chat types document where the API differs from them (ISO string timestamps, session summaries without `messages`).
17
+ - `@channlize/react` and `@channlize/mcp` re-export the error classes as values, so `instanceof` works without importing core.
18
+ - mcp tool errors no longer end with a doubled period when a core error message ends with one.
19
+
20
+ - Updated dependencies [5663cd2]
21
+ - Updated dependencies
22
+ - @channlize/core@0.4.0
23
+
24
+ ## 0.3.0
25
+
26
+ ### Minor Changes
27
+
28
+ - ad8f04d: Redesign `ContactForm` to match the chat widget: scoped styles, `theme` (light / dark / auto / system), `primaryColor`, labels and placeholders, inline validation with accessible errors, loading / success / error states, a honeypot spam guard, and optional company and topic fields (`fields`, `topics`, `defaultValues`). Existing props keep working; `onSuccess` now also receives the API response. Export `ContactFormProps`, `ContactFormLabels` and `defaultContactFormLabels`.
29
+
30
+ ### Patch Changes
31
+
32
+ - Updated dependencies [69f414f]
33
+ - @channlize/core@0.2.1
34
+
35
+ ## 0.2.0
36
+
37
+ ### Minor Changes
38
+
39
+ - db7da26: Redesign the live-chat widget (`ChannlizeChat` / `SupportChat`).
40
+
41
+ - Header: brand avatar slot, title, and a calm status line ("Online · Replies in a few minutes"). The close button no longer overlaps anything; "End conversation" moved into a menu with a confirmation step; a clear minimize button.
42
+ - Messages: grouped by author with agent name and avatar, day separators, one timestamp per group (full date on hover), better bubble shapes, wrapping of long words and URLs, safe link detection (http/https only, no HTML), image and file attachment cards, and optimistic sending with "Sending…" / "Not sent · Retry · Remove".
43
+ - Welcome screen with `greeting`, `welcomeMessage` and optional `suggestions`.
44
+ - Composer: auto-growing textarea (Enter sends, Shift+Enter new line), send icon button disabled when empty, attach button with `allowAttachments`, `maxLength` counter, "Write a message…" placeholder.
45
+ - Connection: status and "Reconnecting…" banner are debounced, so the routine SSE reconnect every ~50s never flickers; a lost connection shows a banner with Retry.
46
+ - Theming: light and dark (`theme`, follows `prefers-color-scheme` by default), `primaryColor` / `primaryTextColor` with automatic readable text color; the hard-coded blue-to-purple gradient is gone. Existing `styles`, `buttonColors`, `className` props keep working.
47
+ - Launcher: new icon, unread badge counting agent replies received while closed (or `showBadge` + `unreadCount`), open/close animation that respects `prefers-reduced-motion`.
48
+ - Mobile: full-screen panel under 640px, safe-area insets, 16px input to avoid iOS zoom.
49
+ - Accessibility: the panel is a labelled dialog, focus moves in on open and back to the launcher on close, Esc closes, the message list is a polite live region, all icon buttons are labelled.
50
+ - Isolation: a scoped stylesheet with a reset under `.channlize-widget`; `ChannlizeChat` renders through a portal into `document.body`. Default `zIndex` is now `2147483000`.
51
+ - New props: `ChannlizeChat` `primaryColor`, `theme`; `SupportChat` `avatarUrl`, `avatar`, `statusText`, `greeting`, `welcomeMessage`, `suggestions`, `theme`, `primaryColor`, `primaryTextColor`, `locale`, `maxLength`, `allowEndChat`, `onMinimize`, `labels`. `useChatSession` returns `reconnect()`. Exported types: `SupportChatProps`, `SupportChatLabels`, `ChatTheme`, `ChannlizeChatProps`, `UseChatSessionOptions`, `UseChatSessionReturn`, and `defaultSupportChatLabels`.
52
+
53
+ ## 0.1.2
54
+
55
+ ### Patch Changes
56
+
57
+ - c113208: Add Events: post a Slack message from your server when something happens.
58
+
59
+ - `@channlize/core`: `client.notify(event, data?, { idempotencyKey?, channel? })` and a standalone `createNotifier()` that reads `CHANNLIZE_SERVER_API_KEY` / `CHANNLIZE_API_KEY` and `CHANNLIZE_PROJECT_ID`. Both call `POST /v1/notify` with the server API key (write scope). Event keys and data can be typed with `createNotifier<AppEvents>()` or by augmenting `ChannlizeEvents`. `trackEvent` / `trackServerEvent` are unchanged and now documented as log tracking. Fix: an explicit `baseUrl: undefined` or `timeout: undefined` no longer overrides the defaults.
60
+ - `@channlize/mcp`: new `notify_event` tool, enabled with `--server-api-key` / `CHANNLIZE_SERVER_API_KEY`.
61
+ - `@channlize/react`: docs only. `useChannlizeAnalytics().track` is documented as log tracking.
62
+
63
+ - Updated dependencies [c113208]
64
+ - @channlize/core@0.2.0
65
+
3
66
  ## 0.1.1
4
67
 
5
68
  ### Patch Changes
package/README.md CHANGED
@@ -61,7 +61,7 @@ function App() {
61
61
  return (
62
62
  <ChannlizeProvider
63
63
  config={{
64
- apiKey: 'your-api-key',
64
+ apiKey: 'your-widget-key',
65
65
  projectId: 'your-project-id',
66
66
  }}
67
67
  >
@@ -71,6 +71,8 @@ function App() {
71
71
  }
72
72
  ```
73
73
 
74
+ `ContactForm`, `SupportChat` and the hooks below must be rendered inside `ChannlizeProvider` (`ChannlizeChat` includes it).
75
+
74
76
  ### Contact Form Component
75
77
 
76
78
  ```tsx
@@ -113,7 +115,7 @@ import { SupportChat } from '@channlize/react';
113
115
  function SupportPage() {
114
116
  return (
115
117
  <SupportChat
116
- autoStart={true}
118
+ autoConnect={true}
117
119
  title="Customer Support"
118
120
  placeholder="How can we help you?"
119
121
  onMessage={(message) => {
@@ -158,7 +160,7 @@ function CustomContactForm() {
158
160
  await submit({
159
161
  name: 'John Doe',
160
162
  email: 'john@example.com',
161
- message: 'Hello!',
163
+ message: 'Hello, I have a question about pricing.', // at least 10 characters
162
164
  });
163
165
  };
164
166
 
@@ -254,16 +256,18 @@ function CustomChat() {
254
256
  | `buttonElement` | `ReactNode` | - | Custom button (overrides default) |
255
257
  | `buttonIcon` | `ReactNode` | - | Custom icon (used if buttonElement not provided) |
256
258
  | `buttonSize` | `number` | `56` | Button size in pixels |
257
- | `buttonColors` | `{ background?: string; hover?: string; text?: string }` | Blue gradient | Button colors |
258
- | `chatProps` | `SupportChatProps` | `{}` | Props passed to internal SupportChat component |
259
+ | `buttonColors` | `{ background?: string; hover?: string; text?: string }` | `primaryColor` | Launcher colors |
260
+ | `primaryColor` | `string` | `'#2563eb'` | Accent color for the launcher, header, customer bubbles and send button (hex recommended; text on it is picked for contrast) |
261
+ | `theme` | `'auto' \| 'light' \| 'dark'` | `'auto'` | Color scheme; `auto` follows `prefers-color-scheme` |
262
+ | `chatProps` | `SupportChatProps` | `{}` | Props passed to internal SupportChat component (title, greeting, suggestions...) |
259
263
  | `defaultOpen` | `boolean` | `false` | Whether to start open |
260
- | `showBadge` | `boolean` | `false` | Whether to show unread count badge |
261
- | `unreadCount` | `number` | `0` | Unread message count |
262
- | `zIndex` | `number` | `1000` | CSS z-index |
263
- | `showOnMobile` | `boolean` | `true` | Whether to show on mobile devices |
264
+ | `showBadge` | `boolean` | `false` | Show `unreadCount` instead of the built-in count of agent replies received while closed |
265
+ | `unreadCount` | `number` | `0` | Unread message count (with `showBadge`) |
266
+ | `zIndex` | `number` | `2147483000` | CSS z-index |
267
+ | `showOnMobile` | `boolean` | `true` | Whether to show the launcher on screens under 640px |
264
268
  | `onOpen` | `() => void` | - | Callback when chat opens |
265
269
  | `onClose` | `() => void` | - | Callback when chat closes |
266
- | `enableAnimations` | `boolean` | `true` | Enable smooth animations |
270
+ | `enableAnimations` | `boolean` | `true` | Enable animations (always reduced with `prefers-reduced-motion`) |
267
271
  | `buttonClassName` | `string` | `''` | Custom class for button container |
268
272
  | `chatClassName` | `string` | `''` | Custom class for chat container |
269
273
 
@@ -290,13 +294,25 @@ function CustomChat() {
290
294
  }}
291
295
  />
292
296
 
293
- // With custom chat options
297
+ // Branding, greeting and quick suggestions
298
+ <ChannlizeChat
299
+ config={{ apiKey: 'key', projectId: 'id' }}
300
+ primaryColor="#0f766e"
301
+ chatProps={{
302
+ title: 'Acme',
303
+ avatarUrl: 'https://acme.com/logo.png',
304
+ statusText: 'Replies in a few minutes',
305
+ greeting: 'Hi there!',
306
+ welcomeMessage: 'Ask us anything. We are here to help.',
307
+ suggestions: ['How does pricing work?', 'Talk to sales'],
308
+ allowAttachments: true,
309
+ }}
310
+ />
311
+
312
+ // Inline style overrides still apply on top of the theme
294
313
  <ChannlizeChat
295
314
  config={{ apiKey: 'key', projectId: 'id' }}
296
315
  chatProps={{
297
- title: "24/7 Support",
298
- placeholder: "Ask us anything...",
299
- showTimestamps: true,
300
316
  styles: {
301
317
  header: {
302
318
  background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
@@ -332,31 +348,78 @@ function CustomChat() {
332
348
 
333
349
  ### ContactForm
334
350
 
335
- A complete contact form component with validation and submission handling.
351
+ A themed, accessible contact form that posts to Channlize (and from there to
352
+ your Slack). Styles are scoped to `.channlize-contact`, so it looks the same on
353
+ any page and never leaks into it. It has inline validation, a focus move to the
354
+ first invalid field, errors linked to their fields with `aria-describedby`,
355
+ loading, success and error states, and a hidden honeypot field against simple
356
+ bots.
357
+
358
+ ```tsx
359
+ <ContactForm
360
+ theme="auto"
361
+ primaryColor="#2563eb"
362
+ fields={{ company: 'optional' }}
363
+ topics={['Sales', 'Support', 'Billing']}
364
+ defaultValues={{ topic: searchParams.get('topic') ?? undefined }}
365
+ labels={{ footnote: 'We usually reply within one business day.' }}
366
+ onSuccess={({ conversationId }) => console.log('Sent', conversationId)}
367
+ />
368
+ ```
336
369
 
337
370
  **Props:**
338
- - `customFields?: Array<CustomField>` - Additional form fields
339
- - `onSuccess?: () => void` - Success callback
371
+ - `customFields?: ContactFormCustomField[]` - Extra fields (`text`, `email`, `textarea`, `select`), sent as `customFields`
372
+ - `onSuccess?: (response: CreateContactResponse) => void` - Success callback
340
373
  - `onError?: (error: Error) => void` - Error callback
341
- - `className?: string` - CSS class name
342
- - `styles?: ContactFormStyles` - Custom styles object
343
- - `submitText?: string` - Submit button text
344
- - `successMessage?: string` - Success message text
374
+ - `className?: string` - CSS class name on the root
375
+ - `styles?` - Inline style overrides: `form`, `field`, `label`, `input`, `textarea`, `button`, `error`, `success`
376
+ - `submitText?: string` / `successMessage?: string` - Shortcuts for `labels.submit` / `labels.successMessage`
377
+ - `theme?: 'light' | 'dark' | 'auto' | 'system'` - Colour scheme (default `'light'`; `auto` and `system` follow `prefers-color-scheme`)
378
+ - `primaryColor?: string`, `primaryTextColor?: string` - Accent colour (button, focus ring) and the text on it
379
+ - `variant?: 'card' | 'plain'` - `card` (default) draws a themed surface; `plain` inherits the host's background
380
+ - `unstyled?: boolean` - Skip the built-in stylesheet (class names stay)
381
+ - `fields?: { name?, company?, subject?, topic? }` - Each `'required' | 'optional' | 'hidden'` (defaults: name required, subject optional, company hidden, topic optional when `topics` is set). Email and message are always required.
382
+ - `topics?: Array<string | { value: string; label?: string }>` - Shows a topic select. The chosen label is sent as `customFields.topic` and used as the subject when that is blank; `value` identifies the option for `defaultValues`
383
+ - `defaultValues?: Partial<{ name, email, company, subject, topic, message }>` - Prefill; `topic` matches an option's value or label case-insensitively (e.g. `?topic=sales`)
384
+ - `labels?: Partial<ContactFormLabels>` - Override any label, placeholder or message (see `defaultContactFormLabels`)
385
+ - `minMessageLength?: number` (default `10`, what the API accepts), `maxMessageLength?: number` (default `5000`)
386
+ - `honeypot?: boolean` - Hidden spam-trap field; a filled trap gets a fake success and nothing is sent (default `true`)
387
+ - `showSuccessState?: boolean` - Show the built-in success screen (default `true`); when `false` the form clears and announces success
388
+ - `idPrefix?: string` - Prefix of field ids (default `channlize`, e.g. `channlize-email`)
345
389
 
346
390
  ### SupportChat
347
391
 
348
- A real-time chat widget with message history and file attachments.
392
+ A real-time chat panel with grouped messages, day separators, safe link
393
+ detection, attachments, optimistic sending with retry, and a debounced
394
+ connection status (routine stream reconnects never flash in the UI). It fills
395
+ its parent, so give the parent a height.
349
396
 
350
397
  **Props:**
351
- - `autoStart?: boolean` - Auto-start chat session
398
+ - `autoConnect?: boolean` - Start (or resume) the session on mount (default `true`)
352
399
  - `metadata?: Record<string, unknown>` - Session metadata
353
400
  - `onMessage?: (message: ChatMessage) => void` - New message callback
354
401
  - `onError?: (error: Error) => void` - Error callback
402
+ - `sessionId?: string`, `persistSession?: boolean` (default `true`), `storageKey?: string` - Resume a session, and where its id is kept in `localStorage`
403
+ - `debug?: boolean` - Log connection and session details to the console (default `false`)
355
404
  - `className?: string` - CSS class name
356
- - `styles?: SupportChatStyles` - Custom styles object
357
- - `title?: string` - Chat header title
358
- - `placeholder?: string` - Input placeholder text
359
- - `maxHeight?: string` - Maximum container height
405
+ - `styles?` - Inline style overrides: `container`, `header`, `messagesContainer`, `message`, `userMessage`, `agentMessage`, `inputContainer`, `input`, `button`, `error`, `timestamp`
406
+ - `title?: string` - Team or brand name in the header (default `'Support'`)
407
+ - `avatarUrl?: string` / `avatar?: ReactNode` - Logo in the header and welcome screen (initials otherwise)
408
+ - `statusText?: string` - Shown after "Online" (default `'Replies in a few minutes'`; `''` hides it)
409
+ - `greeting?: string` / `welcomeMessage?: string` - Welcome screen copy
410
+ - `suggestions?: string[]` - Quick replies on the welcome screen
411
+ - `placeholder?: string` - Input placeholder (default `'Write a message…'`)
412
+ - `sendButtonText?: string` - Accessible label of the send icon button
413
+ - `showTimestamps?: boolean` - One time per message group, full date on hover (default `true`)
414
+ - `allowAttachments?: boolean` - Show the attach button (default `false`)
415
+ - `theme?: 'auto' | 'light' | 'dark'`, `primaryColor?: string`, `primaryTextColor?: string` - Theming
416
+ - `locale?: string` - Locale for dates and times (default: browser)
417
+ - `maxLength?: number` - Maximum message length (default `5000`)
418
+ - `allowEndChat?: boolean` - "End conversation" in the header menu, with confirmation (default `true`)
419
+ - `onMinimize?: () => void` - Shows a minimize button; Esc calls it
420
+ - `labels?: Partial<SupportChatLabels>` - Override any UI string (see `defaultSupportChatLabels`)
421
+
422
+ Keyboard: Enter sends, Shift+Enter adds a new line (on touch-only devices Enter adds a new line and the button sends).
360
423
 
361
424
  ## Hooks
362
425
 
@@ -384,6 +447,10 @@ Hook for managing chat sessions with real-time messaging.
384
447
  - `metadata?: Record<string, unknown>`
385
448
  - `onMessage?: (message: ChatMessage) => void`
386
449
  - `onError?: (error: ChannlizeError) => void`
450
+ - `sessionId?: string` - Resume this session instead of the stored one
451
+ - `persistSession?: boolean` - Keep the session id in `localStorage` so a reload resumes it (default `true`)
452
+ - `storageKey?: string` - `localStorage` key (default `channlize_session_<widget key>`)
453
+ - `debug?: boolean` - Log connection and session details to the console with a `[channlize]` prefix (default `false`). Failures are always reported through `error` and `onError`.
387
454
 
388
455
  **Returns:**
389
456
  - `session: ChatSession | null`
@@ -394,11 +461,25 @@ Hook for managing chat sessions with real-time messaging.
394
461
  - `sendMessage: (content: string, attachments?: File[]) => Promise<void>`
395
462
  - `startSession: () => Promise<void>`
396
463
  - `endSession: () => Promise<void>`
464
+ - `reconnect: () => void` - Reopen the real-time stream after it failed (`error.code === 'SSE_ERROR'`)
465
+
466
+ ### useChannlizeAnalytics (log tracking)
467
+
468
+ Records logs from the browser with the widget key; they show up under **Log tracking** in the dashboard.
469
+
470
+ ```tsx
471
+ const { track } = useChannlizeAnalytics();
472
+ track('cta_clicked', { properties: { section: 'hero' } });
473
+ ```
474
+
475
+ To post a Slack message when something happens (a signup, a payment), use **Events** from your server — `createNotifier` / `client.notify` in [`@channlize/core`](../core/README.md#events-notify-slack-from-your-server). Events need a server API key, so they are never sent from the browser.
397
476
 
398
477
  ## Styling
399
478
 
400
479
  All components accept a `styles` prop for custom styling. You can also use CSS classes with the `className` prop. Components use semantic class names prefixed with `channlize-`.
401
480
 
481
+ The chat widget ships its own small stylesheet, scoped under `.channlize-widget`, with a reset so host-page element styles (`button`, `h2`, `textarea`...) don't leak in, and nothing leaks out. `ChannlizeChat` renders into `document.body` through a portal so host transforms and `overflow` can't clip it. Theme tokens are CSS custom properties on `.channlize-widget` (`--chz-primary`, `--chz-on-primary`, `--chz-bg`, `--chz-text`, `--chz-muted`, `--chz-border`, `--chz-bubble`...) and can be overridden from your CSS.
482
+
402
483
  ### CSS Classes
403
484
 
404
485
  - `.channlize-contact-form`
@@ -408,7 +489,8 @@ All components accept a `styles` prop for custom styling. You can also use CSS c
408
489
  - `.channlize-chat-container`
409
490
  - `.channlize-chat-header`
410
491
  - `.channlize-chat-messages`
411
- - `.channlize-message`
492
+ - `.channlize-chat-status` (`data-status="online|connecting|offline"`)
493
+ - `.channlize-message` (`data-pos`, `data-status="sent|sending|failed"`)
412
494
  - `.channlize-message-user`
413
495
  - `.channlize-message-agent`
414
496
  - `.channlize-chat-input-container`
@@ -417,6 +499,15 @@ All components accept a `styles` prop for custom styling. You can also use CSS c
417
499
 
418
500
  This package is written in TypeScript and includes full type definitions. All components, hooks, and utilities are fully typed.
419
501
 
502
+ ## Documentation
503
+
504
+ - Guide: https://channlize.com/docs/react
505
+ - All docs: https://channlize.com/docs (quick start, API keys, troubleshooting)
506
+
507
+ ## Changelog
508
+
509
+ [CHANGELOG.md](./CHANGELOG.md) lists every release of `@channlize/react`. Product updates: https://channlize.com/docs/changelog
510
+
420
511
  ## License
421
512
 
422
513
  MIT