@thunderphone/widget 0.3.0 → 0.3.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.
Files changed (2) hide show
  1. package/README.md +64 -2
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -43,6 +43,68 @@ function App() {
43
43
  | `onError` | `(error) => void` | No | Called on errors. Error has `error` (code) and `message` fields |
44
44
  | `className` | `string` | No | Additional CSS class for the widget container |
45
45
 
46
+ ## Headless Hook
47
+
48
+ Use the `useThunderPhone` hook to build a completely custom UI while the widget handles the voice connection.
49
+
50
+ ```tsx
51
+ import { useThunderPhone } from '@thunderphone/widget'
52
+
53
+ function CustomCallButton() {
54
+ const phone = useThunderPhone({
55
+ apiKey: 'pk_live_your_publishable_key',
56
+ agentId: 123,
57
+ })
58
+
59
+ const handleClick = () => {
60
+ if (phone.state === 'connected') {
61
+ phone.disconnect()
62
+ } else {
63
+ phone.connect()
64
+ }
65
+ }
66
+
67
+ return (
68
+ <>
69
+ <button onClick={handleClick} disabled={phone.state === 'connecting'}>
70
+ {phone.state === 'connecting'
71
+ ? 'Connecting...'
72
+ : phone.state === 'connected'
73
+ ? 'End call'
74
+ : 'Start call'}
75
+ </button>
76
+ {phone.audio}
77
+ </>
78
+ )
79
+ }
80
+ ```
81
+
82
+ **Important:** Always render `phone.audio` somewhere in your component tree. It's an invisible element that handles the audio connection.
83
+
84
+ ### Hook Options
85
+
86
+ | Option | Type | Required | Description |
87
+ |--------|------|----------|-------------|
88
+ | `apiKey` | `string` | Yes | Your publishable API key |
89
+ | `agentId` | `number` | Yes | ID of the agent to connect to |
90
+ | `apiBase` | `string` | No | API base URL override |
91
+ | `onConnect` | `() => void` | No | Called when the voice session connects |
92
+ | `onDisconnect` | `() => void` | No | Called when the session ends |
93
+ | `onError` | `(error) => void` | No | Called on errors |
94
+
95
+ ### Hook Return Value
96
+
97
+ | Property | Type | Description |
98
+ |----------|------|-------------|
99
+ | `state` | `'idle' \| 'connecting' \| 'connected' \| 'disconnected' \| 'error'` | Current connection state |
100
+ | `connect` | `() => void` | Start a voice session |
101
+ | `disconnect` | `() => void` | End the current session |
102
+ | `toggleMute` | `() => void` | Toggle microphone mute |
103
+ | `isMuted` | `boolean` | Whether the mic is muted |
104
+ | `error` | `string \| undefined` | Error message if state is `'error'` |
105
+ | `agentName` | `string \| undefined` | Name of the connected agent |
106
+ | `audio` | `ReactNode` | Invisible element — must be rendered in the tree |
107
+
46
108
  ## Styling
47
109
 
48
110
  The widget uses plain CSS with `tp-` prefixed classes, so it won't conflict with your styles. You can override any of these classes:
@@ -80,8 +142,8 @@ Wildcard subdomains are supported: `*.example.com` matches `app.example.com`, `d
80
142
  If you're not using a bundler, you can load the widget via script tag. This version bundles React internally so no dependencies are needed.
81
143
 
82
144
  ```html
83
- <link rel="stylesheet" href="https://cdn.thunderphone.com/widget/v0.2.1/style.css" />
84
- <script src="https://cdn.thunderphone.com/widget/v0.2.1/widget.js"></script>
145
+ <link rel="stylesheet" href="https://cdn.thunderphone.com/widget/v0.3.0/style.css" />
146
+ <script src="https://cdn.thunderphone.com/widget/v0.3.0/widget.js"></script>
85
147
 
86
148
  <div id="thunderphone"></div>
87
149
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thunderphone/widget",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Embeddable voice widget for ThunderPhone AI agents",
5
5
  "repository": {
6
6
  "type": "git",