@helpway/react 0.3.4 → 0.4.1

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/README.md CHANGED
@@ -1,129 +1,112 @@
1
1
  # @helpway/react
2
2
 
3
- Official React SDK for [Helpway](https://helpway.ai) — AI-powered customer support in a single component.
4
-
5
- Two integration levels in one package:
6
-
7
- - **Drop-in**: mount `<HelpwayWidget apiKey="..." />` anywhere in your tree and you're done.
8
- - **Headless**: use `SupportProvider` + hooks (`useWidget`, `useConversations`, `useTimeline`, `useComposer`) to build your own chat UI against the same realtime backend.
3
+ Official React SDK for [Helpway](https://helpway.ai) — AI-powered customer support widget with full programmatic control.
9
4
 
10
5
  ## Install
11
6
 
12
7
  ```bash
13
8
  npm install @helpway/react
14
- # or
15
- bun add @helpway/react
16
- # or
17
- pnpm add @helpway/react
18
9
  ```
19
10
 
20
11
  Peer dependencies: `react` ≥ 18 and `react-dom` ≥ 18.
21
12
 
22
- ## Drop-in
23
-
24
- Grab your public API key from the Helpway dashboard → Settings → API keys (format: `pk_live_…`).
13
+ ## Quick start
25
14
 
26
15
  ```tsx
27
- // app/layout.tsx (Next.js App Router)
28
16
  import { HelpwayWidget } from "@helpway/react";
29
17
 
30
- export default function RootLayout({ children }: { children: React.ReactNode }) {
18
+ export default function App() {
31
19
  return (
32
- <html>
33
- <body>
34
- {children}
35
- <HelpwayWidget apiKey="pk_live_XXXXXXXX" />
36
- </body>
37
- </html>
20
+ <>
21
+ <YourApp />
22
+ <HelpwayWidget apiKey="pk_live_xxx" />
23
+ </>
38
24
  );
39
25
  }
40
26
  ```
41
27
 
42
- ```tsx
43
- // main.tsx (Vite / CRA)
44
- import { HelpwayWidget } from "@helpway/react";
45
- import { StrictMode } from "react";
46
- import { createRoot } from "react-dom/client";
47
- import App from "./App";
48
-
49
- createRoot(document.getElementById("root")!).render(
50
- <StrictMode>
51
- <App />
52
- <HelpwayWidget apiKey="pk_live_XXXXXXXX" />
53
- </StrictMode>,
54
- );
28
+ ## Programmatic API (`window.Helpway`)
29
+
30
+ After the widget bootstraps, a type-safe global API is available:
31
+
32
+ ```ts
33
+ window.Helpway.open() // open panel
34
+ window.Helpway.close() // close panel
35
+ window.Helpway.toggle() // toggle open/close
36
+ window.Helpway.dismiss() // hide launcher + panel
37
+ window.Helpway.show() // re-show after dismiss
38
+ window.Helpway.shutdown() // full session reset
39
+
40
+ window.Helpway.identify({ // link visitor to contact
41
+ externalId: "u_123",
42
+ email: "jane@acme.com",
43
+ name: "Jane Doe",
44
+ })
45
+
46
+ window.Helpway.newConversation("Help!") // open new conversation
47
+ window.Helpway.openConversation("conv_abc") // open specific conversation
48
+
49
+ window.Helpway.unreadCount // getter: number
50
+ window.Helpway.isOpen // getter: boolean
51
+
52
+ window.Helpway.on("open", () => {}) // subscribe to events
53
+ window.Helpway.on("unreadChange", (n) => {})
54
+ window.Helpway.on("messageReceived", (msg) => {})
55
+ window.Helpway.off("open", handler) // unsubscribe
55
56
  ```
56
57
 
57
- The component injects the Helpway widget loader script into `document.body`, handles StrictMode double-mounts, and removes the script on unmount.
58
+ TypeScript users get full auto-complete — the package augments `Window` automatically.
58
59
 
59
- ### Props
60
+ ## Props
60
61
 
61
- | Prop | Type | Default | Description |
62
- | -------- | -------- | ------------------------------------ | --------------------------------------------- |
63
- | `apiKey` | `string` | — | Public key from the dashboard. Required. |
64
- | `src` | `string` | `https://api.helpway.ai/widget.js` | Override for staging / self-hosted setups. |
62
+ | Prop | Type | Default | Description |
63
+ |---|---|---|---|
64
+ | `apiKey` | `string` | — | **Required.** Public key from dashboard. |
65
+ | `apiUrl` | `string` | `https://api.helpway.ai` | Override for staging / self-hosted. |
66
+ | `locale` | `string` | auto-detect | Widget language (`"en"`, `"tr"`, `"de"`…). |
67
+ | `hideLauncher` | `boolean` | `false` | Hide the default floating bubble. |
68
+ | `customLauncherSelector` | `string` | — | CSS selector for custom trigger element. |
69
+ | `onReady` | `(api: HelpwayAPI) => void` | — | Full API object after bootstrap. |
70
+ | `onOpen` | `() => void` | — | Panel opened. |
71
+ | `onClose` | `() => void` | — | Panel closed. |
72
+ | `onUnreadChange` | `(count: number) => void` | — | Unread count changed. |
65
73
 
66
- ### Identifying logged-in users
74
+ ## Custom launcher
67
75
 
68
- After your user signs in, call the global `Helpway` identify function so the dashboard sees their real name and email instead of `Anonymous`:
76
+ ```tsx
77
+ <HelpwayWidget
78
+ apiKey="pk_live_xxx"
79
+ hideLauncher
80
+ customLauncherSelector="#my-btn"
81
+ />
69
82
 
70
- ```ts
71
- window.Helpway("identify", {
72
- uniqueId: user.id,
73
- name: user.name,
74
- email: user.email,
75
- });
83
+ <button id="my-btn">Support</button>
76
84
  ```
77
85
 
78
- ## Headless
86
+ ## Headless hooks
79
87
 
80
- If you want to render your own chat UI (custom bubbles, different layout, embedded in your app instead of a floating button), use the provider + hooks:
88
+ Build your own chat UI with the same realtime backend:
81
89
 
82
90
  ```tsx
83
91
  import { SupportProvider, useConversations, useTimeline, useComposer } from "@helpway/react";
84
92
 
85
- function ChatSurface() {
86
- const { conversations, activeConversationId, setActive } = useConversations();
87
- const { items } = useTimeline();
88
- const { draft, setDraft, send } = useComposer();
89
-
90
- return (
91
- <div>
92
- {/* render conversations, messages, composer — full control */}
93
- </div>
94
- );
93
+ function Chat() {
94
+ const { conversations } = useConversations();
95
+ const { items } = useTimeline(conversations[0]?.id);
96
+ const { text, setText, submit } = useComposer(conversations[0]?.id);
97
+ // ...render your own UI
95
98
  }
96
99
 
97
- export default function App() {
98
- return (
99
- <SupportProvider apiKey="pk_live_XXXXXXXX">
100
- <ChatSurface />
101
- </SupportProvider>
102
- );
103
- }
100
+ <SupportProvider apiKey="pk_live_xxx">
101
+ <Chat />
102
+ </SupportProvider>
104
103
  ```
105
104
 
106
- Exported hooks:
105
+ Available hooks: `useWidget`, `useConversations`, `useTimeline`, `useComposer`, `usePresence`, `useUnread`, `useRealtime`.
107
106
 
108
- - `useWidget()` — global state, openers/closers
109
- - `useConversations()` — list + active conversation
110
- - `useTimeline()` — messages + events for the active conversation
111
- - `useComposer()` — draft state + send/attach
112
- - `usePresence()` — online team members
113
- - `useUnread()` — unread counts
114
- - `useRealtime()` — raw WebSocket event stream
115
-
116
- Full API docs: [helpway.ai/docs/react](https://helpway.ai/docs/react)
117
-
118
- ## Styling
119
-
120
- The default themed widget ships opinionated styles. If you use `DefaultWidget`, pull in the stylesheet once:
121
-
122
- ```ts
123
- import "@helpway/react/styles.css";
124
- ```
107
+ ## Docs
125
108
 
126
- The headless hooks have no styles — bring your own.
109
+ Full documentation: [helpway.ai/docs](https://helpway.ai/docs)
127
110
 
128
111
  ## License
129
112
 
package/dist/index.d.ts CHANGED
@@ -1,48 +1,12 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as _helpway_widget_core from '@helpway/widget-core';
3
- import { WidgetStore } from '@helpway/widget-core';
4
- export { ConversationSummary, RealtimeEvent, TimelineItem, WidgetState, WidgetStore, clearVisitorId, formatRelativeTime, formatTime, getInitials, getOrCreateVisitorId } from '@helpway/widget-core';
3
+ import { HelpwayAPI, WidgetStore } from '@helpway/widget-core';
4
+ export { ConversationSummary, HelpwayAPI, RealtimeEvent, TimelineItem, WidgetEventName, WidgetEvents, WidgetState, WidgetStore, clearVisitorId, formatRelativeTime, formatTime, getInitials, getOrCreateVisitorId } from '@helpway/widget-core';
5
5
  import * as react from 'react';
6
6
  import react__default, { ReactNode } from 'react';
7
7
  import * as _helpway_types from '@helpway/types';
8
8
  import { TimelineItem, RealtimeEvent, TimelineItemPart } from '@helpway/types';
9
9
 
10
- interface IdentifyData {
11
- externalId: string;
12
- email?: string;
13
- name?: string;
14
- image?: string;
15
- metadata?: Record<string, unknown>;
16
- }
17
- /** Use a slice of the widget store with auto re-render */
18
- declare function useWidgetStore<T>(selector: (state: WidgetStore) => T): T;
19
- /** Hook to identify the current visitor (link to customer contact) */
20
- declare function useIdentify(): (data: IdentifyData) => Promise<void>;
21
- interface SupportProviderProps {
22
- /** Public API key (pk_xxx) */
23
- apiKey: string;
24
- /** API base URL (default: auto-detect from script tag or window) */
25
- apiUrl?: string;
26
- /** Widget locale (e.g., "fr", "de"). Falls back to navigator.language → "en" */
27
- locale?: string;
28
- /** Deep link: auto-open this conversation after bootstrap (from ?hw_conv= URL param) */
29
- initialConversationId?: string;
30
- /** Callback to expose widget API to parent (for embed loader) */
31
- onReady?: (api: {
32
- identify: (data: IdentifyData) => Promise<void>;
33
- openConversation: (id: string) => void;
34
- }) => void;
35
- children: ReactNode;
36
- }
37
- /**
38
- * Root provider for the Helpway widget.
39
- * Creates tRPC client, WebSocket connection, and state store.
40
- *
41
- * Visitor identity is managed via server-side cookies (hw_visitor).
42
- * No localStorage or client-side ID management needed.
43
- */
44
- declare function SupportProvider({ apiKey, apiUrl, locale, initialConversationId, onReady, children, }: SupportProviderProps): react_jsx_runtime.JSX.Element;
45
-
46
10
  interface HelpwayWidgetProps {
47
11
  /**
48
12
  * Public API key from the Helpway dashboard. Required.
@@ -67,12 +31,27 @@ interface HelpwayWidgetProps {
67
31
  initialConversationId?: string;
68
32
  /**
69
33
  * Called once after the widget has bootstrapped and exposes
70
- * programmatic APIs (identify, openConversation).
34
+ * the full programmatic API object (also available as `window.Helpway`).
71
35
  */
72
- onReady?: (api: {
73
- identify: (data: IdentifyData) => Promise<void>;
74
- openConversation: (id: string) => void;
75
- }) => void;
36
+ onReady?: (api: HelpwayPublicAPI) => void;
37
+ /**
38
+ * Hide the default floating launcher button. Use with
39
+ * `customLauncherSelector` or `window.Helpway.open()` to trigger
40
+ * the widget from your own UI.
41
+ */
42
+ hideLauncher?: boolean;
43
+ /**
44
+ * CSS selector for a custom trigger element (e.g. `"#support-btn"`).
45
+ * Clicking the matched element calls `Helpway.open()`. Combine with
46
+ * `hideLauncher` to fully replace the default bubble.
47
+ */
48
+ customLauncherSelector?: string;
49
+ /** Fires when the widget panel opens */
50
+ onOpen?: () => void;
51
+ /** Fires when the widget panel closes */
52
+ onClose?: () => void;
53
+ /** Fires when the unread count changes */
54
+ onUnreadChange?: (count: number) => void;
76
55
  /**
77
56
  * @deprecated Legacy prop from the v0.1 script-loader era. If set,
78
57
  * the `/widget.js` suffix is stripped to derive `apiUrl`. New code
@@ -80,12 +59,46 @@ interface HelpwayWidgetProps {
80
59
  */
81
60
  src?: string;
82
61
  }
62
+
63
+ type HelpwayPublicAPI = HelpwayAPI;
83
64
  /**
84
65
  * Render this once at the root of your app (e.g. in `_app.tsx`,
85
66
  * `layout.tsx`, or `main.tsx`). Unmounting cleanly tears down the
86
67
  * widget and its WebSocket connection — useful for route-scoped mounts.
87
68
  */
88
- declare function HelpwayWidget({ apiKey, apiUrl, locale, initialConversationId, onReady, src, }: HelpwayWidgetProps): react_jsx_runtime.JSX.Element;
69
+ declare function HelpwayWidget({ apiKey, apiUrl, locale, initialConversationId, onReady, hideLauncher, customLauncherSelector, onOpen, onClose, onUnreadChange, src, }: HelpwayWidgetProps): react_jsx_runtime.JSX.Element;
70
+
71
+ interface IdentifyData {
72
+ externalId: string;
73
+ email?: string;
74
+ name?: string;
75
+ image?: string;
76
+ metadata?: Record<string, unknown>;
77
+ }
78
+ /** Use a slice of the widget store with auto re-render */
79
+ declare function useWidgetStore<T>(selector: (state: WidgetStore) => T): T;
80
+ /** Hook to identify the current visitor (link to customer contact) */
81
+ declare function useIdentify(): (data: IdentifyData) => Promise<void>;
82
+ interface SupportProviderProps {
83
+ apiKey: string;
84
+ apiUrl?: string;
85
+ locale?: string;
86
+ initialConversationId?: string;
87
+ onReady?: (api: HelpwayAPI) => void;
88
+ customLauncherSelector?: string;
89
+ onOpen?: () => void;
90
+ onClose?: () => void;
91
+ onUnreadChange?: (count: number) => void;
92
+ children: ReactNode;
93
+ }
94
+ /**
95
+ * Root provider for the Helpway widget.
96
+ * Creates tRPC client, WebSocket connection, and state store.
97
+ *
98
+ * Visitor identity is managed via server-side cookies (hw_visitor).
99
+ * No localStorage or client-side ID management needed.
100
+ */
101
+ declare function SupportProvider({ apiKey, apiUrl, locale, initialConversationId, onReady, customLauncherSelector, onOpen, onClose, onUnreadChange, children, }: SupportProviderProps): react_jsx_runtime.JSX.Element;
89
102
 
90
103
  /**
91
104
  * Core widget state — connection status, visitor identity, website info.
@@ -216,8 +229,8 @@ declare function useRealtime(handler: (event: RealtimeEvent) => void): void;
216
229
  * Unified support widget — Intercom-style with tab navigation.
217
230
  * Two tabs: Home + Messages. Sub-views: conversation + new conversation.
218
231
  */
219
- declare function DefaultWidget({ initialOpen }?: {
220
- initialOpen?: boolean;
232
+ declare function DefaultWidget({ hideLauncher }?: {
233
+ hideLauncher?: boolean;
221
234
  }): react_jsx_runtime.JSX.Element;
222
235
 
223
236
  interface MessageBubbleProps {
@@ -292,4 +305,4 @@ declare function MarkdownContent({ bodyHtml, bodyMarkdown, className, }: {
292
305
  className?: string;
293
306
  }): react_jsx_runtime.JSX.Element | null;
294
307
 
295
- export { Composer, DefaultWidget, HelpwayWidget, type HelpwayWidgetProps, type IdentifyData, MarkdownContent, MessageBubble, MessageList, SupportProvider, linkifyText, renderMarkdown, useComposer, useConversations, useIdentify, usePresence, useRealtime, useTimeline, useUnread, useWidget, useWidgetStore };
308
+ export { Composer, DefaultWidget, type HelpwayPublicAPI, HelpwayWidget, type HelpwayWidgetProps, type IdentifyData, MarkdownContent, MessageBubble, MessageList, SupportProvider, linkifyText, renderMarkdown, useComposer, useConversations, useIdentify, usePresence, useRealtime, useTimeline, useUnread, useWidget, useWidgetStore };