@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/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as react from 'react';
2
- import { ReactNode } from 'react';
2
+ import { ReactNode, CSSProperties } from 'react';
3
+ import * as _channlize_core from '@channlize/core';
3
4
  import { ChannlizeConfig, ChannlizeClient, CreateContactResponse, ChannlizeError, ContactFormData, ChatMessage, ChatSession, TrackEventOptions } from '@channlize/core';
4
5
  export { AuthenticationError, ChannlizeConfig, ChannlizeError, ChatMessage, ChatSession, ContactFormData, CreateChatSessionResponse, CreateContactResponse, EventSeverity, FileAttachment, RateLimitError, SendMessageResponse, TrackEventOptions, ValidationError } from '@channlize/core';
5
6
 
@@ -44,6 +45,12 @@ interface UseChatSessionOptions {
44
45
  sessionId?: string;
45
46
  persistSession?: boolean;
46
47
  storageKey?: string;
48
+ /**
49
+ * Log connection and session details to the console (`[channlize]`
50
+ * prefix). Off by default; failures are always reported through `error`
51
+ * and `onError`.
52
+ */
53
+ debug?: boolean;
47
54
  }
48
55
  interface UseChatSessionReturn {
49
56
  session: ChatSession | null;
@@ -54,6 +61,11 @@ interface UseChatSessionReturn {
54
61
  sendMessage: (content: string, attachments?: File[]) => Promise<void>;
55
62
  startSession: () => Promise<void>;
56
63
  endSession: () => Promise<void>;
64
+ /**
65
+ * Reopen the real-time stream for the current session after it failed
66
+ * (`error.code === 'SSE_ERROR'`). Routine reconnects are automatic.
67
+ */
68
+ reconnect: () => void;
57
69
  }
58
70
  /**
59
71
  * Hook for managing chat sessions with real-time messaging
@@ -61,57 +73,195 @@ interface UseChatSessionReturn {
61
73
  declare function useChatSession(options?: UseChatSessionOptions): UseChatSessionReturn;
62
74
 
63
75
  /**
64
- * Returns a stable `track` function bound to the provider client for event tracking (browser / widget key).
76
+ * Returns a stable `track` function bound to the provider client for log
77
+ * tracking (browser / widget key; shown under Log tracking in the
78
+ * dashboard). To post a Slack message when something happens, use Events
79
+ * (`notify` from `@channlize/core`) on your server instead.
65
80
  */
66
81
  declare function useChannlizeAnalytics(): {
67
- track: (name: string, options?: TrackEventOptions) => Promise<{
68
- success: boolean;
69
- id: string;
70
- }>;
82
+ track: (name: string, options?: TrackEventOptions) => Promise<_channlize_core.TrackEventResult>;
71
83
  };
72
84
 
85
+ /** `auto` and `system` both follow `prefers-color-scheme`. */
86
+ type ContactFormTheme = 'auto' | 'system' | 'light' | 'dark';
87
+ /** Whether a built-in field is shown, and whether it must be filled in. */
88
+ type ContactFieldMode = 'required' | 'optional' | 'hidden';
89
+ interface ContactFormTopic {
90
+ /** Identifies the option, e.g. for `defaultValues.topic` from a URL */
91
+ value: string;
92
+ /**
93
+ * Shown in the select, sent as `customFields.topic`, and used as the
94
+ * subject when that is blank. Defaults to `value`.
95
+ */
96
+ label?: string;
97
+ }
98
+ /** The built-in fields' values (also what `defaultValues` takes). */
99
+ interface ContactFormValues {
100
+ name: string;
101
+ email: string;
102
+ company: string;
103
+ subject: string;
104
+ topic: string;
105
+ message: string;
106
+ }
107
+ interface ContactFormCustomField {
108
+ name: string;
109
+ label: string;
110
+ type: 'text' | 'email' | 'textarea' | 'select';
111
+ required?: boolean;
112
+ options?: string[];
113
+ placeholder?: string;
114
+ }
115
+ /** Every user-facing string in the form, for copy changes or translation. */
116
+ interface ContactFormLabels {
117
+ name: string;
118
+ email: string;
119
+ company: string;
120
+ subject: string;
121
+ topic: string;
122
+ message: string;
123
+ namePlaceholder: string;
124
+ emailPlaceholder: string;
125
+ companyPlaceholder: string;
126
+ subjectPlaceholder: string;
127
+ topicPlaceholder: string;
128
+ messagePlaceholder: string;
129
+ optional: string;
130
+ submit: string;
131
+ submitting: string;
132
+ successTitle: string;
133
+ successMessage: string;
134
+ sendAnother: string;
135
+ /** Shown under a required field left empty */
136
+ errorRequired: string;
137
+ /** Shown under a required select left on the placeholder */
138
+ errorSelect: string;
139
+ errorEmail: string;
140
+ /** `{min}` is replaced with the minimum length */
141
+ errorTooShort: string;
142
+ /** `{max}` is replaced with the maximum length */
143
+ errorTooLong: string;
144
+ /** Announced when a submit is blocked by invalid fields */
145
+ errorSummary: string;
146
+ /** Shown when sending fails */
147
+ errorGeneric: string;
148
+ /** Shown when the API rate limit is hit */
149
+ errorRateLimit: string;
150
+ /** Small print under the submit button; '' hides it */
151
+ footnote: string;
152
+ }
153
+ declare const defaultContactFormLabels: ContactFormLabels;
73
154
  interface FormProps {
74
- /** Custom fields to include in the form */
75
- customFields?: Array<{
76
- name: string;
77
- label: string;
78
- type: 'text' | 'email' | 'textarea' | 'select';
79
- required?: boolean;
80
- options?: string[];
81
- }>;
155
+ /** Custom fields to include in the form (sent as `customFields`) */
156
+ customFields?: ContactFormCustomField[];
82
157
  /** Callback when form is successfully submitted */
83
- onSuccess?: () => void;
158
+ onSuccess?: (response: CreateContactResponse) => void;
84
159
  /** Callback when form submission fails */
85
160
  onError?: (error: Error) => void;
86
161
  /** Custom CSS classes */
87
162
  className?: string;
88
- /** Custom styles for form elements */
163
+ /** Custom styles for form elements (applied inline, so they win over the theme) */
89
164
  styles?: {
90
- form?: React.CSSProperties;
91
- field?: React.CSSProperties;
92
- label?: React.CSSProperties;
93
- input?: React.CSSProperties;
94
- textarea?: React.CSSProperties;
95
- button?: React.CSSProperties;
96
- error?: React.CSSProperties;
97
- success?: React.CSSProperties;
165
+ form?: CSSProperties;
166
+ field?: CSSProperties;
167
+ label?: CSSProperties;
168
+ input?: CSSProperties;
169
+ textarea?: CSSProperties;
170
+ button?: CSSProperties;
171
+ error?: CSSProperties;
172
+ success?: CSSProperties;
98
173
  };
99
- /** Button text */
174
+ /** Button text (same as `labels.submit`) */
100
175
  submitText?: string;
101
- /** Success message */
176
+ /** Success message (same as `labels.successMessage`) */
102
177
  successMessage?: string;
178
+ /** Colour scheme (default `light`). `auto` / `system` follow `prefers-color-scheme`. */
179
+ theme?: ContactFormTheme;
180
+ /** Accent colour (button, focus ring). Hex recommended. */
181
+ primaryColor?: string;
182
+ /** Text colour on the accent colour. Defaults to white or near-black, whichever is readable. */
183
+ primaryTextColor?: string;
184
+ /** `card` (default) draws a themed surface with padding; `plain` inherits the host's. */
185
+ variant?: 'card' | 'plain';
186
+ /** Skip the built-in stylesheet entirely (class names stay for your own CSS) */
187
+ unstyled?: boolean;
188
+ /**
189
+ * Built-in fields. Email and message are always required.
190
+ * Defaults: name `required`, subject `optional`, company `hidden`,
191
+ * topic `optional` when `topics` is set.
192
+ */
193
+ fields?: {
194
+ name?: ContactFieldMode;
195
+ company?: ContactFieldMode;
196
+ subject?: ContactFieldMode;
197
+ topic?: ContactFieldMode;
198
+ };
199
+ /** Options of the topic select; it is shown only when this is set */
200
+ topics?: Array<string | ContactFormTopic>;
201
+ /**
202
+ * Initial values, e.g. a topic from the URL (`?topic=sales`). A topic
203
+ * matches an option's value or label, case-insensitively.
204
+ */
205
+ defaultValues?: Partial<ContactFormValues>;
206
+ /** Override any user-facing string */
207
+ labels?: Partial<ContactFormLabels>;
208
+ /** Minimum message length (default `10`, what the Channlize API accepts) */
209
+ minMessageLength?: number;
210
+ /** Maximum message length (default `5000`) */
211
+ maxMessageLength?: number;
212
+ /** Add a hidden honeypot field; bots that fill it get a fake success (default `true`) */
213
+ honeypot?: boolean;
214
+ /** Show the built-in success state after sending (default `true`) */
215
+ showSuccessState?: boolean;
216
+ /** Prefix of the fields' ids (default `channlize`, e.g. `channlize-email`) */
217
+ idPrefix?: string;
103
218
  }
104
219
 
105
220
  /**
106
- * ContactForm component - Alias for Form component
107
- * Provides a form for collecting contact information and messages
221
+ * ContactForm component
222
+ *
223
+ * A themed, accessible contact form that posts to Channlize (and from there
224
+ * to your Slack). Inline validation, loading / success / error states, an
225
+ * optional topic select and company field, and a honeypot spam guard.
226
+ * Must be rendered inside `<ChannlizeProvider>`.
108
227
  */
109
228
  declare function ContactForm(props: FormProps): react.JSX.Element;
229
+ type ContactFormProps = FormProps;
110
230
 
231
+ type ChatTheme = 'auto' | 'light' | 'dark';
232
+ /** Every user-facing string in the chat, for copy changes or translation. */
233
+ interface SupportChatLabels {
234
+ online: string;
235
+ connecting: string;
236
+ reconnecting: string;
237
+ offline: string;
238
+ connectionLost: string;
239
+ startFailed: string;
240
+ retry: string;
241
+ today: string;
242
+ yesterday: string;
243
+ you: string;
244
+ sending: string;
245
+ failed: string;
246
+ remove: string;
247
+ moreOptions: string;
248
+ minimize: string;
249
+ endChat: string;
250
+ endChatTitle: string;
251
+ endChatDescription: string;
252
+ endChatConfirm: string;
253
+ cancel: string;
254
+ attach: string;
255
+ removeAttachment: string;
256
+ messages: string;
257
+ conversationEnded: string;
258
+ charactersLeft: string;
259
+ }
260
+ declare const defaultSupportChatLabels: SupportChatLabels;
111
261
  interface SupportChatProps extends UseChatSessionOptions {
112
262
  /** Custom CSS classes */
113
263
  className?: string;
114
- /** Custom styles for chat elements */
264
+ /** Custom styles for chat elements (applied inline, so they win over the theme) */
115
265
  styles?: {
116
266
  container?: React.CSSProperties;
117
267
  header?: React.CSSProperties;
@@ -127,20 +277,48 @@ interface SupportChatProps extends UseChatSessionOptions {
127
277
  };
128
278
  /** Placeholder text for message input */
129
279
  placeholder?: string;
130
- /** Header title */
280
+ /** Header title: your team or brand name */
131
281
  title?: string;
132
- /** Button text */
282
+ /** Accessible label (and tooltip) of the send button */
133
283
  sendButtonText?: string;
134
284
  /** Show timestamps on messages */
135
285
  showTimestamps?: boolean;
136
286
  /** Allow file attachments */
137
287
  allowAttachments?: boolean;
288
+ /** Logo or team avatar URL, shown in the header and on the welcome screen */
289
+ avatarUrl?: string;
290
+ /** Custom avatar element (overrides `avatarUrl`) */
291
+ avatar?: ReactNode;
292
+ /** Text after "Online" in the header, e.g. "Replies in a few minutes". Set to '' to hide. */
293
+ statusText?: string;
294
+ /** Welcome heading shown before the first message */
295
+ greeting?: string;
296
+ /** Welcome text shown under the greeting */
297
+ welcomeMessage?: string;
298
+ /** Quick replies shown on the welcome screen; clicking one sends it */
299
+ suggestions?: string[];
300
+ /** Colour scheme. `auto` follows `prefers-color-scheme`. */
301
+ theme?: ChatTheme;
302
+ /** Accent colour (header, customer bubbles, send button). Hex recommended. */
303
+ primaryColor?: string;
304
+ /** Text colour on the accent colour. Defaults to white or near-black, whichever is readable. */
305
+ primaryTextColor?: string;
306
+ /** Locale for dates and times (defaults to the browser locale) */
307
+ locale?: string;
308
+ /** Maximum message length */
309
+ maxLength?: number;
310
+ /** Show "End conversation" in the header menu */
311
+ allowEndChat?: boolean;
312
+ /** When set, a minimize button is shown in the header and Esc calls it */
313
+ onMinimize?: () => void;
314
+ /** Override any user-facing string */
315
+ labels?: Partial<SupportChatLabels>;
138
316
  }
139
317
  /**
140
318
  * SupportChat component - Real-time chat interface
141
319
  * Provides a complete chat UI with message history and real-time updates
142
320
  */
143
- declare function SupportChat({ autoConnect, metadata, onMessage, onError, sessionId, persistSession, storageKey, className, styles, placeholder, title, sendButtonText, showTimestamps, allowAttachments, }: SupportChatProps): react.JSX.Element;
321
+ declare function SupportChat({ autoConnect, metadata, onMessage, onError, sessionId, persistSession, storageKey, debug, className, styles, placeholder, title, sendButtonText, showTimestamps, allowAttachments, avatarUrl, avatar, statusText, greeting, welcomeMessage, suggestions, theme, primaryColor, primaryTextColor, locale, maxLength, allowEndChat, onMinimize, labels: labelOverrides, }: SupportChatProps): react.JSX.Element;
144
322
 
145
323
  interface ChannlizeChatProps {
146
324
  /** Channlize configuration */
@@ -158,29 +336,36 @@ interface ChannlizeChatProps {
158
336
  buttonIcon?: ReactNode;
159
337
  /** Button size in pixels */
160
338
  buttonSize?: number;
161
- /** Button colors */
339
+ /** Launcher colours. Default to `primaryColor`. */
162
340
  buttonColors?: {
163
341
  background?: string;
164
342
  hover?: string;
165
343
  text?: string;
166
344
  };
167
345
  /** Chat window props (passed to SupportChat) */
168
- chatProps?: Omit<SupportChatProps, 'autoConnect'>;
346
+ chatProps?: Omit<SupportChatProps, 'autoConnect' | 'onMinimize'>;
347
+ /** Accent colour for the launcher and chat window (hex recommended) */
348
+ primaryColor?: string;
349
+ /** Colour scheme. `auto` (default) follows `prefers-color-scheme`. */
350
+ theme?: ChatTheme;
169
351
  /** Whether to start closed or open */
170
352
  defaultOpen?: boolean;
171
- /** Whether to show badge with unread count */
353
+ /**
354
+ * Show `unreadCount` on the launcher instead of the built-in count. Without
355
+ * it, the launcher counts agent replies received while the chat is closed.
356
+ */
172
357
  showBadge?: boolean;
173
- /** Unread count (for badge) */
358
+ /** Unread count (for badge, used with `showBadge`) */
174
359
  unreadCount?: number;
175
360
  /** Custom z-index */
176
361
  zIndex?: number;
177
- /** Whether to show on mobile */
362
+ /** Whether to show the launcher on small screens (< 640px) */
178
363
  showOnMobile?: boolean;
179
364
  /** Callback when chat opens */
180
365
  onOpen?: () => void;
181
366
  /** Callback when chat closes */
182
367
  onClose?: () => void;
183
- /** Whether to enable animations */
368
+ /** Whether to enable animations (always reduced with `prefers-reduced-motion`) */
184
369
  enableAnimations?: boolean;
185
370
  /** Custom class for button container */
186
371
  buttonClassName?: string;
@@ -201,13 +386,16 @@ interface ChannlizeChatProps {
201
386
  * projectId: "your-project-id",
202
387
  * }}
203
388
  * position="bottom-right"
389
+ * primaryColor="#2563eb"
204
390
  * chatProps={{
205
- * title: "Customer Support",
206
- * placeholder: "How can we help?"
391
+ * title: "Acme Support",
392
+ * greeting: "Hi there!",
393
+ * welcomeMessage: "Ask us anything.",
207
394
  * }}
208
395
  * />
209
396
  * ```
210
397
  */
211
- declare function ChannlizeChat({ config, position, offset, buttonElement, buttonIcon, buttonSize, buttonColors, chatProps, defaultOpen, showBadge, unreadCount, zIndex, showOnMobile, onOpen, onClose, enableAnimations, buttonClassName, chatClassName, }: ChannlizeChatProps): react.JSX.Element | null;
398
+ declare function ChannlizeChat({ config, position, offset, buttonElement, buttonIcon, buttonSize, buttonColors, chatProps, primaryColor, theme, defaultOpen, showBadge, unreadCount, zIndex, showOnMobile, onOpen, onClose, enableAnimations, buttonClassName, chatClassName, }: ChannlizeChatProps): react.JSX.Element | null;
212
399
 
213
- export { ChannlizeChat, ChannlizeProvider, ContactForm, SupportChat, useChannlize, useChannlizeAnalytics, useChatSession, useContactForm };
400
+ export { ChannlizeChat, ChannlizeProvider, ContactForm, SupportChat, defaultContactFormLabels, defaultSupportChatLabels, useChannlize, useChannlizeAnalytics, useChatSession, useContactForm };
401
+ export type { ChannlizeChatProps, ChannlizeProviderProps, ChatTheme, ContactFieldMode, ContactFormCustomField, ContactFormLabels, ContactFormProps, ContactFormTheme, ContactFormTopic, ContactFormValues, SupportChatLabels, SupportChatProps, UseChatSessionOptions, UseChatSessionReturn, UseContactFormOptions, UseContactFormReturn };