@signalwire/web-components 4.0.0-beta.1 → 4.0.0-beta.11

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 (79) hide show
  1. package/README.md +9 -10
  2. package/dist/components/audio-level.d.ts +114 -0
  3. package/dist/components/audio-level.d.ts.map +1 -0
  4. package/dist/components/audio-level.js +203 -0
  5. package/dist/components/audio-level.js.map +1 -0
  6. package/dist/components/call-controls.d.ts +183 -0
  7. package/dist/components/call-controls.d.ts.map +1 -0
  8. package/dist/components/call-controls.js +606 -0
  9. package/dist/components/call-controls.js.map +1 -0
  10. package/dist/components/call-media.d.ts +118 -0
  11. package/dist/components/call-media.d.ts.map +1 -0
  12. package/dist/components/call-media.js +219 -0
  13. package/dist/components/call-media.js.map +1 -0
  14. package/dist/components/call-status.d.ts +83 -0
  15. package/dist/components/call-status.d.ts.map +1 -0
  16. package/dist/components/call-status.js +255 -0
  17. package/dist/components/call-status.js.map +1 -0
  18. package/dist/components/click-to-call.d.ts +151 -0
  19. package/dist/components/click-to-call.d.ts.map +1 -0
  20. package/dist/components/click-to-call.js +428 -0
  21. package/dist/components/click-to-call.js.map +1 -0
  22. package/dist/components/device-selector.d.ts +238 -0
  23. package/dist/components/device-selector.d.ts.map +1 -0
  24. package/dist/components/device-selector.js +685 -0
  25. package/dist/components/device-selector.js.map +1 -0
  26. package/dist/components/dialpad.d.ts +74 -0
  27. package/dist/components/dialpad.d.ts.map +1 -0
  28. package/dist/components/dialpad.js +372 -0
  29. package/dist/components/dialpad.js.map +1 -0
  30. package/dist/components/directory.d.ts +125 -0
  31. package/dist/components/directory.d.ts.map +1 -0
  32. package/dist/components/directory.js +503 -0
  33. package/dist/components/directory.js.map +1 -0
  34. package/dist/components/example-button.d.ts +21 -0
  35. package/dist/components/example-button.d.ts.map +1 -0
  36. package/dist/components/example-button.js +74 -0
  37. package/dist/components/example-button.js.map +1 -0
  38. package/dist/components/participant-controls.d.ts +123 -0
  39. package/dist/components/participant-controls.d.ts.map +1 -0
  40. package/dist/components/participant-controls.js +468 -0
  41. package/dist/components/participant-controls.js.map +1 -0
  42. package/dist/components/participants.d.ts +120 -0
  43. package/dist/components/participants.d.ts.map +1 -0
  44. package/dist/components/participants.js +394 -0
  45. package/dist/components/participants.js.map +1 -0
  46. package/dist/components/self-media.d.ts +78 -0
  47. package/dist/components/self-media.d.ts.map +1 -0
  48. package/dist/components/self-media.js +129 -0
  49. package/dist/components/self-media.js.map +1 -0
  50. package/dist/constants.d.ts +10 -0
  51. package/dist/constants.d.ts.map +1 -0
  52. package/dist/constants.js +5 -0
  53. package/dist/constants.js.map +1 -0
  54. package/dist/context/call-context.d.ts +13 -0
  55. package/dist/context/call-context.d.ts.map +1 -0
  56. package/dist/context/call-context.js +6 -0
  57. package/dist/context/call-context.js.map +1 -0
  58. package/dist/context/index.d.ts +2 -0
  59. package/dist/context/index.d.ts.map +1 -0
  60. package/dist/index.d.ts +29 -0
  61. package/dist/index.d.ts.map +1 -0
  62. package/dist/index.js +35 -5644
  63. package/dist/index.js.map +1 -1
  64. package/dist/react.d.ts +122 -0
  65. package/dist/types/index.d.ts +20 -0
  66. package/dist/types/index.d.ts.map +1 -0
  67. package/dist/types/index.js +12 -0
  68. package/dist/types/index.js.map +1 -0
  69. package/dist/utils/debounce.d.ts +10 -0
  70. package/dist/utils/debounce.d.ts.map +1 -0
  71. package/dist/utils/debounce.js +13 -0
  72. package/dist/utils/debounce.js.map +1 -0
  73. package/dist/utils/index.d.ts +3 -0
  74. package/dist/utils/index.d.ts.map +1 -0
  75. package/dist/utils/video.d.ts +34 -0
  76. package/dist/utils/video.d.ts.map +1 -0
  77. package/dist/utils/video.js +26 -0
  78. package/dist/utils/video.js.map +1 -0
  79. package/package.json +70 -3
@@ -0,0 +1,255 @@
1
+ import { LitElement as d, html as u, css as p } from "lit";
2
+ import { property as h, state as i, customElement as f } from "lit/decorators.js";
3
+ import { consume as m } from "@lit/context";
4
+ import { callContext as w } from "../context/call-context.js";
5
+ var g = Object.defineProperty, x = Object.getOwnPropertyDescriptor, o = (t, s, e, a) => {
6
+ for (var n = a > 1 ? void 0 : a ? x(s, e) : s, c = t.length - 1, l; c >= 0; c--)
7
+ (l = t[c]) && (n = (a ? l(s, e, n) : l(n)) || n);
8
+ return a && n && g(s, e, n), n;
9
+ };
10
+ let r = class extends d {
11
+ constructor() {
12
+ super(...arguments), this.call = null, this.status = "new", this.callStartTime = null, this.duration = "0:00", this.subscriptions = [], this.durationInterval = null;
13
+ }
14
+ connectedCallback() {
15
+ super.connectedCallback(), this.subscribeToCall();
16
+ }
17
+ disconnectedCallback() {
18
+ super.disconnectedCallback(), this.cleanup();
19
+ }
20
+ updated(t) {
21
+ (t.has("call") || t.has("contextCall")) && (this.cleanup(), this.subscribeToCall());
22
+ }
23
+ get activeCall() {
24
+ return this.call || this.contextCall || null;
25
+ }
26
+ subscribeToCall() {
27
+ const t = this.activeCall;
28
+ if (!(t != null && t.status$)) return;
29
+ const s = t.status$.subscribe((e) => {
30
+ const a = this.status;
31
+ this.status = e, e === "connected" && a !== "connected" ? this.startDurationTimer() : e !== "connected" && this.stopDurationTimer();
32
+ });
33
+ this.subscriptions.push(s);
34
+ }
35
+ startDurationTimer() {
36
+ this.callStartTime = Date.now(), this.duration = "0:00", this.durationInterval = window.setInterval(() => {
37
+ if (this.callStartTime) {
38
+ const t = Math.floor((Date.now() - this.callStartTime) / 1e3);
39
+ this.duration = this.formatDuration(t);
40
+ }
41
+ }, 1e3);
42
+ }
43
+ stopDurationTimer() {
44
+ this.durationInterval && (clearInterval(this.durationInterval), this.durationInterval = null), this.callStartTime = null, this.duration = "0:00";
45
+ }
46
+ formatDuration(t) {
47
+ const s = Math.floor(t / 3600), e = Math.floor(t % 3600 / 60), a = t % 60;
48
+ return s > 0 ? `${s}:${e.toString().padStart(2, "0")}:${a.toString().padStart(2, "0")}` : `${e}:${a.toString().padStart(2, "0")}`;
49
+ }
50
+ cleanup() {
51
+ this.subscriptions.forEach((t) => t.unsubscribe()), this.subscriptions = [], this.stopDurationTimer();
52
+ }
53
+ getStatusText() {
54
+ switch (this.status) {
55
+ case "new":
56
+ return "Ready";
57
+ case "trying":
58
+ return "Trying...";
59
+ case "connecting":
60
+ return "Connecting...";
61
+ case "ringing":
62
+ return "Ringing...";
63
+ case "connected":
64
+ return "Connected";
65
+ case "recovering":
66
+ return "Reconnecting...";
67
+ case "disconnecting":
68
+ return "Disconnecting...";
69
+ case "disconnected":
70
+ return "Disconnected";
71
+ case "failed":
72
+ return "Failed";
73
+ case "destroyed":
74
+ return "Ended";
75
+ default: {
76
+ const t = this.status;
77
+ return String(t);
78
+ }
79
+ }
80
+ }
81
+ render() {
82
+ const t = this.getStatusText(), s = this.status === "connected";
83
+ return u`
84
+ <div class="container" part="container">
85
+ <span class="status-indicator ${this.status}" aria-hidden="true"></span>
86
+ <span
87
+ class="status-text ${this.status}"
88
+ part="status-text"
89
+ role="status"
90
+ aria-live="polite"
91
+ >
92
+ ${t}
93
+ </span>
94
+ ${s ? u`<span class="duration" part="duration">${this.duration}</span>` : null}
95
+ </div>
96
+ `;
97
+ }
98
+ };
99
+ r.styles = p`
100
+ :host {
101
+ /* CSS Custom Properties for theming */
102
+ --sw-color-primary: #044cf6;
103
+ --sw-color-success: #10b981;
104
+ --sw-color-warning: #f59e0b;
105
+ --sw-color-danger: #ef4444;
106
+ --sw-color-text: #1f2937;
107
+ --sw-color-text-muted: #6b7280;
108
+ --sw-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
109
+ --sw-font-size-sm: 14px;
110
+ --sw-font-size-base: 16px;
111
+ --sw-font-size-lg: 18px;
112
+ --sw-space-1: 4px;
113
+ --sw-space-2: 8px;
114
+ --sw-space-3: 12px;
115
+ --sw-border-radius: 8px;
116
+
117
+ display: inline-flex;
118
+ align-items: center;
119
+ gap: var(--sw-space-2);
120
+ font-family: var(--sw-font-family);
121
+ font-size: var(--sw-font-size-base);
122
+ }
123
+
124
+ /* Dark mode support */
125
+ :host([data-theme='dark']) {
126
+ --sw-color-text: #f9fafb;
127
+ --sw-color-text-muted: #9ca3af;
128
+ }
129
+
130
+ @media (prefers-color-scheme: dark) {
131
+ :host(:not([data-theme='light'])) {
132
+ --sw-color-text: #f9fafb;
133
+ --sw-color-text-muted: #9ca3af;
134
+ }
135
+ }
136
+
137
+ .container {
138
+ display: inline-flex;
139
+ align-items: center;
140
+ gap: var(--sw-space-2);
141
+ padding: var(--sw-space-2) var(--sw-space-3);
142
+ border-radius: var(--sw-border-radius);
143
+ color: var(--sw-color-text);
144
+ }
145
+
146
+ .status-indicator {
147
+ width: 10px;
148
+ height: 10px;
149
+ border-radius: 50%;
150
+ flex-shrink: 0;
151
+ }
152
+
153
+ .status-indicator.new {
154
+ background-color: var(--sw-color-text-muted);
155
+ }
156
+
157
+ .status-indicator.connecting,
158
+ .status-indicator.ringing {
159
+ background-color: var(--sw-color-warning);
160
+ animation: pulse 1.5s ease-in-out infinite;
161
+ }
162
+
163
+ .status-indicator.connected {
164
+ background-color: var(--sw-color-success);
165
+ }
166
+
167
+ .status-indicator.disconnecting {
168
+ background-color: var(--sw-color-danger);
169
+ animation: pulse 1s ease-in-out infinite;
170
+ }
171
+
172
+ .status-indicator.trying {
173
+ background-color: var(--sw-color-warning);
174
+ animation: pulse 1.5s ease-in-out infinite;
175
+ }
176
+
177
+ .status-indicator.disconnected,
178
+ .status-indicator.failed {
179
+ background-color: var(--sw-color-danger);
180
+ }
181
+
182
+ .status-indicator.destroyed {
183
+ background-color: var(--sw-color-text-muted);
184
+ }
185
+
186
+ @keyframes pulse {
187
+ 0%,
188
+ 100% {
189
+ opacity: 1;
190
+ transform: scale(1);
191
+ }
192
+ 50% {
193
+ opacity: 0.5;
194
+ transform: scale(1.1);
195
+ }
196
+ }
197
+
198
+ .status-text {
199
+ font-weight: 500;
200
+ white-space: nowrap;
201
+ }
202
+
203
+ .status-text.trying,
204
+ .status-text.connecting,
205
+ .status-text.ringing {
206
+ color: var(--sw-color-warning);
207
+ }
208
+
209
+ .status-text.disconnecting {
210
+ color: var(--sw-color-danger);
211
+ }
212
+
213
+ .status-text.connected {
214
+ color: var(--sw-color-success);
215
+ }
216
+
217
+ .status-text.disconnected,
218
+ .status-text.failed {
219
+ color: var(--sw-color-danger);
220
+ }
221
+
222
+ .status-text.new,
223
+ .status-text.destroyed {
224
+ color: var(--sw-color-text-muted);
225
+ }
226
+
227
+ .duration {
228
+ font-variant-numeric: tabular-nums;
229
+ color: var(--sw-color-text-muted);
230
+ font-size: var(--sw-font-size-sm);
231
+ }
232
+ `;
233
+ o([
234
+ h({ attribute: !1 })
235
+ ], r.prototype, "call", 2);
236
+ o([
237
+ m({ context: w, subscribe: !0 }),
238
+ i()
239
+ ], r.prototype, "contextCall", 2);
240
+ o([
241
+ i()
242
+ ], r.prototype, "status", 2);
243
+ o([
244
+ i()
245
+ ], r.prototype, "callStartTime", 2);
246
+ o([
247
+ i()
248
+ ], r.prototype, "duration", 2);
249
+ r = o([
250
+ f("sw-call-status")
251
+ ], r);
252
+ export {
253
+ r as CallStatusComponent
254
+ };
255
+ //# sourceMappingURL=call-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"call-status.js","sources":["../../src/components/call-status.ts"],"sourcesContent":["/**\n * Call Status Component\n *\n * Displays current call state with status text and duration timer.\n * Shows animated indicators for transient states (connecting, ringing, disconnecting).\n *\n * @example\n * ```html\n * <sw-call-status .call=${call}></sw-call-status>\n * ```\n *\n * @cssprop [--sw-color-primary=#044cf6] - Primary brand color\n * @cssprop [--sw-color-success=#10b981] - Success/connected indicator color\n * @cssprop [--sw-color-warning=#f59e0b] - Warning/connecting indicator color\n * @cssprop [--sw-color-danger=#ef4444] - Danger/disconnecting indicator color\n * @cssprop [--sw-color-text=#1f2937] - Primary text color\n * @cssprop [--sw-color-text-muted=#6b7280] - Secondary/muted text and duration color\n * @cssprop [--sw-font-family=-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif] - Font family\n * @cssprop [--sw-font-size-sm=14px] - Small font size for duration\n * @cssprop [--sw-font-size-base=16px] - Base font size for status text\n * @cssprop [--sw-font-size-lg=18px] - Large font size\n * @cssprop [--sw-space-1=4px] - Smallest spacing unit\n * @cssprop [--sw-space-2=8px] - Small spacing unit\n * @cssprop [--sw-space-3=12px] - Medium spacing unit\n * @cssprop [--sw-border-radius=8px] - Border radius for container\n */\n\nimport { LitElement, html, css } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { consume } from '@lit/context';\nimport { Subscription } from 'rxjs';\nimport type { Observable } from 'rxjs';\nimport type { CallStatus } from '@signalwire/js';\nimport { callContext } from '../context/index.js';\n\n/**\n * Call interface for status component\n */\nexport interface CallStatusCall {\n status$: Observable<CallStatus>;\n}\n\n@customElement('sw-call-status')\nexport class CallStatusComponent extends LitElement {\n static styles = css`\n :host {\n /* CSS Custom Properties for theming */\n --sw-color-primary: #044cf6;\n --sw-color-success: #10b981;\n --sw-color-warning: #f59e0b;\n --sw-color-danger: #ef4444;\n --sw-color-text: #1f2937;\n --sw-color-text-muted: #6b7280;\n --sw-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n --sw-font-size-sm: 14px;\n --sw-font-size-base: 16px;\n --sw-font-size-lg: 18px;\n --sw-space-1: 4px;\n --sw-space-2: 8px;\n --sw-space-3: 12px;\n --sw-border-radius: 8px;\n\n display: inline-flex;\n align-items: center;\n gap: var(--sw-space-2);\n font-family: var(--sw-font-family);\n font-size: var(--sw-font-size-base);\n }\n\n /* Dark mode support */\n :host([data-theme='dark']) {\n --sw-color-text: #f9fafb;\n --sw-color-text-muted: #9ca3af;\n }\n\n @media (prefers-color-scheme: dark) {\n :host(:not([data-theme='light'])) {\n --sw-color-text: #f9fafb;\n --sw-color-text-muted: #9ca3af;\n }\n }\n\n .container {\n display: inline-flex;\n align-items: center;\n gap: var(--sw-space-2);\n padding: var(--sw-space-2) var(--sw-space-3);\n border-radius: var(--sw-border-radius);\n color: var(--sw-color-text);\n }\n\n .status-indicator {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n flex-shrink: 0;\n }\n\n .status-indicator.new {\n background-color: var(--sw-color-text-muted);\n }\n\n .status-indicator.connecting,\n .status-indicator.ringing {\n background-color: var(--sw-color-warning);\n animation: pulse 1.5s ease-in-out infinite;\n }\n\n .status-indicator.connected {\n background-color: var(--sw-color-success);\n }\n\n .status-indicator.disconnecting {\n background-color: var(--sw-color-danger);\n animation: pulse 1s ease-in-out infinite;\n }\n\n .status-indicator.trying {\n background-color: var(--sw-color-warning);\n animation: pulse 1.5s ease-in-out infinite;\n }\n\n .status-indicator.disconnected,\n .status-indicator.failed {\n background-color: var(--sw-color-danger);\n }\n\n .status-indicator.destroyed {\n background-color: var(--sw-color-text-muted);\n }\n\n @keyframes pulse {\n 0%,\n 100% {\n opacity: 1;\n transform: scale(1);\n }\n 50% {\n opacity: 0.5;\n transform: scale(1.1);\n }\n }\n\n .status-text {\n font-weight: 500;\n white-space: nowrap;\n }\n\n .status-text.trying,\n .status-text.connecting,\n .status-text.ringing {\n color: var(--sw-color-warning);\n }\n\n .status-text.disconnecting {\n color: var(--sw-color-danger);\n }\n\n .status-text.connected {\n color: var(--sw-color-success);\n }\n\n .status-text.disconnected,\n .status-text.failed {\n color: var(--sw-color-danger);\n }\n\n .status-text.new,\n .status-text.destroyed {\n color: var(--sw-color-text-muted);\n }\n\n .duration {\n font-variant-numeric: tabular-nums;\n color: var(--sw-color-text-muted);\n font-size: var(--sw-font-size-sm);\n }\n `;\n\n /**\n * Call object with status$ observable\n */\n @property({ attribute: false })\n call: CallStatusCall | null = null;\n\n /**\n * Call from context (if nested in sw-call-media)\n */\n @consume({ context: callContext, subscribe: true })\n @state()\n private contextCall?: CallStatusCall;\n\n /**\n * Current call status\n */\n @state()\n private status: CallStatus = 'new';\n\n /**\n * Call start time for duration calculation\n */\n @state()\n private callStartTime: number | null = null;\n\n /**\n * Formatted duration string\n */\n @state()\n private duration: string = '0:00';\n\n /**\n * RxJS subscriptions for cleanup\n */\n private subscriptions: Subscription[] = [];\n\n /**\n * Duration timer interval\n */\n private durationInterval: number | null = null;\n\n connectedCallback() {\n super.connectedCallback();\n this.subscribeToCall();\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.cleanup();\n }\n\n updated(changedProperties: Map<string, unknown>) {\n if (changedProperties.has('call') || changedProperties.has('contextCall')) {\n this.cleanup();\n this.subscribeToCall();\n }\n }\n\n private get activeCall(): CallStatusCall | null {\n return this.call || this.contextCall || null;\n }\n\n private subscribeToCall() {\n const call = this.activeCall;\n if (!call?.status$) return;\n\n const statusSub = call.status$.subscribe((status) => {\n const prevStatus = this.status;\n this.status = status;\n\n // Start duration timer when connected\n if (status === 'connected' && prevStatus !== 'connected') {\n this.startDurationTimer();\n } else if (status !== 'connected') {\n this.stopDurationTimer();\n }\n });\n\n this.subscriptions.push(statusSub);\n }\n\n private startDurationTimer() {\n this.callStartTime = Date.now();\n this.duration = '0:00';\n\n this.durationInterval = window.setInterval(() => {\n if (this.callStartTime) {\n const elapsed = Math.floor((Date.now() - this.callStartTime) / 1000);\n this.duration = this.formatDuration(elapsed);\n }\n }, 1000);\n }\n\n private stopDurationTimer() {\n if (this.durationInterval) {\n clearInterval(this.durationInterval);\n this.durationInterval = null;\n }\n this.callStartTime = null;\n this.duration = '0:00';\n }\n\n private formatDuration(seconds: number): string {\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const secs = seconds % 60;\n\n if (hours > 0) {\n return `${hours}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;\n }\n return `${minutes}:${secs.toString().padStart(2, '0')}`;\n }\n\n private cleanup() {\n this.subscriptions.forEach((sub) => sub.unsubscribe());\n this.subscriptions = [];\n this.stopDurationTimer();\n }\n\n private getStatusText(): string {\n switch (this.status) {\n case 'new':\n return 'Ready';\n case 'trying':\n return 'Trying...';\n case 'connecting':\n return 'Connecting...';\n case 'ringing':\n return 'Ringing...';\n case 'connected':\n return 'Connected';\n case 'recovering':\n return 'Reconnecting...';\n case 'disconnecting':\n return 'Disconnecting...';\n case 'disconnected':\n return 'Disconnected';\n case 'failed':\n return 'Failed';\n case 'destroyed':\n return 'Ended';\n default: {\n const _exhaustive: never = this.status;\n return String(_exhaustive);\n }\n }\n }\n\n render() {\n const statusText = this.getStatusText();\n const showDuration = this.status === 'connected';\n\n return html`\n <div class=\"container\" part=\"container\">\n <span class=\"status-indicator ${this.status}\" aria-hidden=\"true\"></span>\n <span\n class=\"status-text ${this.status}\"\n part=\"status-text\"\n role=\"status\"\n aria-live=\"polite\"\n >\n ${statusText}\n </span>\n ${showDuration\n ? html`<span class=\"duration\" part=\"duration\">${this.duration}</span>`\n : null}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'sw-call-status': CallStatusComponent;\n }\n}\n"],"names":["CallStatusComponent","LitElement","changedProperties","call","statusSub","status","prevStatus","elapsed","seconds","hours","minutes","secs","sub","_exhaustive","statusText","showDuration","html","css","__decorateClass","property","consume","callContext","state","customElement"],"mappings":"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"}
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Click to Call Component
3
+ *
4
+ * A single button widget to initiate calls to a preconfigured destination.
5
+ * Shows minimal UI with call status, duration, and basic controls.
6
+ *
7
+ * @example
8
+ * ```html
9
+ * <sw-click-to-call
10
+ * destination="sip:support@example.com"
11
+ * .client=${signalWire}
12
+ * label="Call Support"
13
+ * ></sw-click-to-call>
14
+ * ```
15
+ *
16
+ * @fires sw-dial - Fired when a call is initiated. Detail: `{ destination: string }`
17
+ * @fires sw-hangup - Fired when the hangup button is clicked.
18
+ * @fires sw-mute-toggle - Fired when the mute button is toggled. Detail: `{ muted: boolean }`
19
+ *
20
+ * @cssprop [--sw-color-primary=#044cf6] - Primary brand color
21
+ * @cssprop [--sw-color-primary-hover=#0339c4] - Primary color on hover
22
+ * @cssprop [--sw-color-success=#10b981] - Success/positive color
23
+ * @cssprop [--sw-color-success-hover=#0ea472] - Success color on hover
24
+ * @cssprop [--sw-color-danger=#ef4444] - Danger/destructive color
25
+ * @cssprop [--sw-color-danger-hover=#dc2626] - Danger color on hover
26
+ * @cssprop [--sw-color-warning=#f59e0b] - Warning color
27
+ * @cssprop [--sw-color-text=#1f2937] - Primary text color
28
+ * @cssprop [--sw-color-text-muted=#6b7280] - Secondary/muted text color
29
+ * @cssprop [--sw-color-text-inverse=#ffffff] - Inverse text color for buttons
30
+ * @cssprop [--sw-color-background=#ffffff] - Component background color
31
+ * @cssprop [--sw-color-background-hover=#f3f4f6] - Background color on hover
32
+ * @cssprop [--sw-color-border=#e5e7eb] - Border color
33
+ * @cssprop [--sw-font-family=-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif] - Font family
34
+ * @cssprop [--sw-font-size-sm=12px] - Small font size
35
+ * @cssprop [--sw-font-size-base=14px] - Base font size
36
+ * @cssprop [--sw-font-size-lg=16px] - Large font size
37
+ * @cssprop [--sw-space-1=4px] - Smallest spacing unit
38
+ * @cssprop [--sw-space-2=8px] - Small spacing unit
39
+ * @cssprop [--sw-space-3=12px] - Medium spacing unit
40
+ * @cssprop [--sw-space-4=16px] - Large spacing unit
41
+ * @cssprop [--sw-border-radius=8px] - Border radius for containers
42
+ * @cssprop [--sw-border-radius-full=9999px] - Fully rounded border radius for circular buttons
43
+ */
44
+ import { LitElement } from 'lit';
45
+ import type { Observable } from 'rxjs';
46
+ /**
47
+ * Call status type
48
+ */
49
+ export type ClickToCallStatus = 'idle' | 'connecting' | 'connected' | 'disconnecting' | 'error';
50
+ /**
51
+ * Self participant interface for click-to-call component
52
+ */
53
+ export interface ClickToCallSelf {
54
+ audioMuted$: Observable<boolean | undefined>;
55
+ mute(): Promise<void>;
56
+ unmute(): Promise<void>;
57
+ }
58
+ /**
59
+ * Call interface for click-to-call component
60
+ */
61
+ export interface ClickToCallCall {
62
+ status$: Observable<string>;
63
+ hangup(): Promise<void>;
64
+ self$?: Observable<ClickToCallSelf>;
65
+ self?: ClickToCallSelf;
66
+ }
67
+ /**
68
+ * Client interface for click-to-call component
69
+ */
70
+ export interface ClickToCallClient {
71
+ dial(destination: string, options?: {
72
+ audio?: boolean;
73
+ video?: boolean;
74
+ }): Promise<ClickToCallCall>;
75
+ }
76
+ export declare class ClickToCallComponent extends LitElement {
77
+ static styles: import("lit").CSSResult;
78
+ /**
79
+ * Client for initiating calls (SignalWire)
80
+ */
81
+ client: ClickToCallClient | null;
82
+ /**
83
+ * Destination address to call
84
+ */
85
+ destination: string;
86
+ /**
87
+ * Button label when idle
88
+ */
89
+ label: string;
90
+ /**
91
+ * Audio-only mode (no video)
92
+ */
93
+ audioOnly: boolean;
94
+ /**
95
+ * Current call status
96
+ */
97
+ private status;
98
+ /**
99
+ * Current call object
100
+ */
101
+ private call;
102
+ /**
103
+ * Is audio muted
104
+ */
105
+ private audioMuted;
106
+ /**
107
+ * Self participant reference for mute/unmute operations
108
+ */
109
+ private selfParticipant;
110
+ /**
111
+ * Call duration in seconds
112
+ */
113
+ private callDuration;
114
+ /**
115
+ * Error message
116
+ */
117
+ private errorMessage;
118
+ /**
119
+ * RxJS subscriptions for cleanup
120
+ */
121
+ private subscriptions;
122
+ /**
123
+ * Duration timer interval
124
+ */
125
+ private durationInterval;
126
+ /**
127
+ * Call start time
128
+ */
129
+ private callStartTime;
130
+ disconnectedCallback(): void;
131
+ private initiateCall;
132
+ private subscribeToCall;
133
+ private startDurationTimer;
134
+ private stopDurationTimer;
135
+ private formatDuration;
136
+ private handleCallEnded;
137
+ private toggleMute;
138
+ private hangup;
139
+ private cleanup;
140
+ private renderIdleState;
141
+ private renderConnectingState;
142
+ private renderConnectedState;
143
+ private renderErrorState;
144
+ render(): import("lit-html").TemplateResult<1>;
145
+ }
146
+ declare global {
147
+ interface HTMLElementTagNameMap {
148
+ 'sw-click-to-call': ClickToCallComponent;
149
+ }
150
+ }
151
+ //# sourceMappingURL=click-to-call.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"click-to-call.d.ts","sourceRoot":"","sources":["../../src/components/click-to-call.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAG5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAEvC;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,YAAY,GAAG,WAAW,GAAG,eAAe,GAAG,OAAO,CAAC;AAEhG;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,UAAU,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;IAC7C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;IAC5B,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,KAAK,CAAC,EAAE,UAAU,CAAC,eAAe,CAAC,CAAC;IACpC,IAAI,CAAC,EAAE,eAAe,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,CACF,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAC7C,OAAO,CAAC,eAAe,CAAC,CAAC;CAC7B;AAED,qBACa,oBAAqB,SAAQ,UAAU;IAClD,MAAM,CAAC,MAAM,0BA+MX;IAEF;;OAEG;IAEH,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAQ;IAExC;;OAEG;IAEH,WAAW,EAAE,MAAM,CAAM;IAEzB;;OAEG;IAEH,KAAK,EAAE,MAAM,CAAU;IAEvB;;OAEG;IAEH,SAAS,EAAE,OAAO,CAAQ;IAE1B;;OAEG;IAEH,OAAO,CAAC,MAAM,CAA6B;IAE3C;;OAEG;IAEH,OAAO,CAAC,IAAI,CAAgC;IAE5C;;OAEG;IAEH,OAAO,CAAC,UAAU,CAAkB;IAEpC;;OAEG;IACH,OAAO,CAAC,eAAe,CAAgC;IAEvD;;OAEG;IAEH,OAAO,CAAC,YAAY,CAAa;IAEjC;;OAEG;IAEH,OAAO,CAAC,YAAY,CAAc;IAElC;;OAEG;IACH,OAAO,CAAC,aAAa,CAAsB;IAE3C;;OAEG;IACH,OAAO,CAAC,gBAAgB,CAAuB;IAE/C;;OAEG;IACH,OAAO,CAAC,aAAa,CAAuB;IAE5C,oBAAoB;YAKN,YAAY;IAkC1B,OAAO,CAAC,eAAe;IAgCvB,OAAO,CAAC,kBAAkB;IAW1B,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,eAAe;YAgBT,UAAU;YAsBV,MAAM;IAYpB,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,eAAe;IAmBvB,OAAO,CAAC,qBAAqB;IAa7B,OAAO,CAAC,oBAAoB;IAiD5B,OAAO,CAAC,gBAAgB;IASxB,MAAM;CAeP;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,kBAAkB,EAAE,oBAAoB,CAAC;KAC1C;CACF"}