@signalwire/web-components 4.0.0-beta.10 → 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 (46) hide show
  1. package/dist/components/audio-level.d.ts +8 -0
  2. package/dist/components/audio-level.d.ts.map +1 -1
  3. package/dist/components/audio-level.js.map +1 -1
  4. package/dist/components/call-controls.d.ts +28 -8
  5. package/dist/components/call-controls.d.ts.map +1 -1
  6. package/dist/components/call-controls.js +4 -4
  7. package/dist/components/call-controls.js.map +1 -1
  8. package/dist/components/call-media.d.ts +4 -0
  9. package/dist/components/call-media.d.ts.map +1 -1
  10. package/dist/components/call-media.js.map +1 -1
  11. package/dist/components/call-status.d.ts +15 -0
  12. package/dist/components/call-status.d.ts.map +1 -1
  13. package/dist/components/call-status.js +12 -11
  14. package/dist/components/call-status.js.map +1 -1
  15. package/dist/components/click-to-call.d.ts +29 -1
  16. package/dist/components/click-to-call.d.ts.map +1 -1
  17. package/dist/components/click-to-call.js +1 -1
  18. package/dist/components/click-to-call.js.map +1 -1
  19. package/dist/components/device-selector.d.ts +14 -0
  20. package/dist/components/device-selector.d.ts.map +1 -1
  21. package/dist/components/device-selector.js.map +1 -1
  22. package/dist/components/dialpad.d.ts +23 -9
  23. package/dist/components/dialpad.d.ts.map +1 -1
  24. package/dist/components/dialpad.js.map +1 -1
  25. package/dist/components/directory.d.ts +22 -0
  26. package/dist/components/directory.d.ts.map +1 -1
  27. package/dist/components/directory.js.map +1 -1
  28. package/dist/components/example-button.d.ts +1 -0
  29. package/dist/components/example-button.d.ts.map +1 -1
  30. package/dist/components/example-button.js.map +1 -1
  31. package/dist/components/participant-controls.d.ts +32 -3
  32. package/dist/components/participant-controls.d.ts.map +1 -1
  33. package/dist/components/participant-controls.js +3 -3
  34. package/dist/components/participant-controls.js.map +1 -1
  35. package/dist/components/participants.d.ts +4 -0
  36. package/dist/components/participants.d.ts.map +1 -1
  37. package/dist/components/participants.js.map +1 -1
  38. package/dist/index.d.ts +1 -1
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js.map +1 -1
  41. package/dist/react.d.ts +49 -28
  42. package/dist/types/index.d.ts +9 -33
  43. package/dist/types/index.d.ts.map +1 -1
  44. package/dist/types/index.js +6 -6
  45. package/dist/types/index.js.map +1 -1
  46. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"participants.js","sources":["../../src/components/participants.ts"],"sourcesContent":["/**\n * Participants Component\n *\n * Renders member overlays based on layoutLayers from the call context.\n * Excludes self member and provides slot for <self-media> child component.\n *\n * @example\n * ```html\n * <participants>\n * <self-media mirror=${true}></self-media>\n * </participants>\n * ```\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 { Call, LayoutLayer, Participant } from '../types/index.js';\nimport { getSelfId, castParticipants } from '../types/index.js';\nimport { callContext } from '../context/call-context.js';\n\n@customElement('sw-participants')\nexport class Participants extends LitElement {\n static styles = css`\n :host {\n display: contents; /* Doesn't create a box, children inherit positioning */\n }\n\n .member-overlay {\n box-sizing: border-box;\n /* Thick inset box-shadow with semi-transparent background for debugging */\n box-shadow: inset 0 0 0 8px rgba(255, 0, 0, 0.8);\n background-color: rgba(255, 0, 0, 0.1);\n }\n\n .member-overlay.is-self {\n /* Self overlay uses blue border to distinguish from other participants */\n box-shadow: inset 0 0 0 8px rgba(0, 0, 255, 0.8);\n background-color: rgba(0, 0, 255, 0.1);\n }\n\n /* Circular menu trigger button */\n .menu-trigger {\n position: absolute;\n top: 12px;\n left: 12px;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: rgba(0, 0, 0, 0.6);\n border: 2px solid rgba(255, 255, 255, 0.3);\n color: white;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition:\n background 0.2s ease,\n transform 0.2s ease,\n border-color 0.2s ease;\n z-index: 20;\n }\n\n .menu-trigger:hover {\n background: rgba(0, 0, 0, 0.8);\n border-color: rgba(255, 255, 255, 0.6);\n transform: scale(1.1);\n }\n\n .menu-trigger:focus {\n outline: none;\n border-color: #044cf6;\n box-shadow: 0 0 0 3px rgba(4, 78, 246, 0.4);\n }\n\n .menu-trigger svg {\n width: 20px;\n height: 20px;\n }\n\n /* Dropdown menu */\n .menu-dropdown {\n position: absolute;\n top: 12px;\n left: 56px;\n background: rgba(31, 41, 55, 0.95);\n backdrop-filter: blur(8px);\n border-radius: 8px;\n padding: 8px 0;\n min-width: 160px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);\n z-index: 30;\n opacity: 0;\n visibility: hidden;\n transform: translateX(-10px);\n transition:\n opacity 0.2s ease,\n transform 0.2s ease,\n visibility 0.2s ease;\n }\n\n .menu-dropdown.open {\n opacity: 1;\n visibility: visible;\n transform: translateX(0);\n }\n\n .menu-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n color: white;\n font-size: 14px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n cursor: pointer;\n transition: background 0.15s ease;\n border: none;\n background: none;\n width: 100%;\n text-align: left;\n }\n\n .menu-item:hover {\n background: rgba(255, 255, 255, 0.1);\n }\n\n .menu-item svg {\n width: 16px;\n height: 16px;\n flex-shrink: 0;\n }\n\n .menu-item.danger {\n color: #ef4444;\n }\n\n .menu-item.danger:hover {\n background: rgba(239, 68, 68, 0.2);\n }\n `;\n\n /**\n * Consumes call context from parent call-media component\n */\n @consume({ context: callContext, subscribe: true })\n @property({ attribute: false })\n private _call?: Call;\n\n /**\n * Public call property for direct assignment (when not nested in sw-call-media)\n */\n @property({ attribute: false })\n set call(value: Call | undefined) {\n this._call = value;\n this.cleanupSubscriptions();\n this.setupSubscriptions();\n }\n get call(): Call | undefined {\n return this._call;\n }\n\n /**\n * Current layout layers value from observable\n */\n private _layoutLayersValue: LayoutLayer[] = [];\n\n /**\n * Current participants from observable\n */\n private _participantsValue: Participant[] = [];\n\n /**\n * ID of participant with open menu\n */\n @state()\n private _openMenuId: string | null = null;\n\n /**\n * RxJS subscriptions for cleanup\n */\n private subscriptions: Subscription[] = [];\n\n /**\n * Lifecycle: Component connected to DOM\n */\n connectedCallback() {\n super.connectedCallback();\n this.setupSubscriptions();\n }\n\n /**\n * Lifecycle: React to property/context changes\n */\n protected updated(changedProperties: Map<string, unknown>): void {\n super.updated(changedProperties);\n if (changedProperties.has('_call') && this._call) {\n // Clean up old subscriptions first\n this.cleanupSubscriptions();\n // Set up new subscriptions\n this.setupSubscriptions();\n }\n }\n\n /**\n * Lifecycle: Component disconnected from DOM\n */\n disconnectedCallback() {\n super.disconnectedCallback();\n this.cleanupSubscriptions();\n }\n\n /**\n * Subscribe to call observables\n */\n private setupSubscriptions(): void {\n // Continue observing even if _call is undefined initially\n // This allows component to react when call becomes available\n if (!this._call) return;\n\n this.subscriptions.push(\n this._call.layoutLayers$.subscribe((layers: LayoutLayer[]) => {\n this._layoutLayersValue = layers;\n this.requestUpdate();\n })\n );\n\n // Subscribe to participants for menu actions\n if (this._call.participants$) {\n this.subscriptions.push(\n this._call.participants$.subscribe((participants: unknown[]) => {\n this._participantsValue = castParticipants(participants);\n this.requestUpdate();\n })\n );\n }\n\n // Close menu on outside click\n this._handleOutsideClick = this._handleOutsideClick.bind(this);\n document.addEventListener('click', this._handleOutsideClick);\n }\n\n /**\n * Handle click outside menu to close it\n */\n private _handleOutsideClick(e: Event): void {\n const target = e.target as Element;\n if (!target.closest('.menu-trigger') && !target.closest('.menu-dropdown')) {\n this._openMenuId = null;\n }\n }\n\n /**\n * Toggle menu for a participant\n */\n private _toggleMenu(memberId: string, e: Event): void {\n e.stopPropagation();\n this._openMenuId = this._openMenuId === memberId ? null : memberId;\n }\n\n /**\n * Get participant by member ID\n */\n private _getParticipant(memberId: string): Participant | undefined {\n return this._participantsValue.find((p) => p.id === memberId);\n }\n\n /**\n * Handle mute audio action\n */\n private async _handleMuteAudio(memberId: string, e: Event): Promise<void> {\n e.stopPropagation();\n const participant = this._getParticipant(memberId);\n if (!participant) return;\n\n try {\n if (participant.audioMuted && participant.unmute) {\n await participant.unmute();\n } else if (!participant.audioMuted && participant.mute) {\n await participant.mute();\n }\n this.dispatchEvent(\n new CustomEvent('sw-participant-mute-audio', {\n detail: { participant, memberId },\n bubbles: true,\n composed: true\n })\n );\n } catch {\n // Silently handle error\n }\n this._openMenuId = null;\n }\n\n /**\n * Handle mute video action\n */\n private async _handleMuteVideo(memberId: string, e: Event): Promise<void> {\n e.stopPropagation();\n const participant = this._getParticipant(memberId);\n if (!participant) return;\n\n try {\n if (participant.videoMuted && participant.unmuteVideo) {\n await participant.unmuteVideo();\n } else if (!participant.videoMuted && participant.muteVideo) {\n await participant.muteVideo();\n }\n this.dispatchEvent(\n new CustomEvent('sw-participant-mute-video', {\n detail: { participant, memberId },\n bubbles: true,\n composed: true\n })\n );\n } catch {\n // Silently handle error\n }\n this._openMenuId = null;\n }\n\n /**\n * Handle remove participant action\n */\n private async _handleRemove(memberId: string, e: Event): Promise<void> {\n e.stopPropagation();\n const participant = this._getParticipant(memberId);\n if (!participant?.remove) return;\n\n try {\n await participant.remove();\n this.dispatchEvent(\n new CustomEvent('sw-participant-remove', {\n detail: { participant, memberId },\n bubbles: true,\n composed: true\n })\n );\n } catch {\n // Silently handle error\n }\n this._openMenuId = null;\n }\n\n /**\n * Cleanup all subscriptions\n */\n private cleanupSubscriptions(): void {\n this.subscriptions.forEach((sub) => sub.unsubscribe());\n this.subscriptions = [];\n document.removeEventListener('click', this._handleOutsideClick);\n }\n\n /**\n * Render member overlays for all participants\n */\n private renderMemberOverlays() {\n if (!this._layoutLayersValue || this._layoutLayersValue.length === 0) {\n return null;\n }\n\n // Get selfId dynamically from call.self to handle cases where self is available after subscription setup\n const selfId = getSelfId(this._call);\n\n return this._layoutLayersValue\n .filter((layer) => layer.member_id)\n .map((layer) => this.renderOverlay(layer, layer.member_id === selfId));\n }\n\n /**\n * Render menu button SVG icon (three dots)\n */\n private renderMenuIcon() {\n return html`\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <circle cx=\"12\" cy=\"6\" r=\"2\" />\n <circle cx=\"12\" cy=\"12\" r=\"2\" />\n <circle cx=\"12\" cy=\"18\" r=\"2\" />\n </svg>\n `;\n }\n\n /**\n * Render menu dropdown for a participant\n */\n private renderMenuDropdown(memberId: string) {\n const participant = this._getParticipant(memberId);\n const isOpen = this._openMenuId === memberId;\n\n return html`\n <div class=\"menu-dropdown ${isOpen ? 'open' : ''}\">\n <button\n class=\"menu-item\"\n @click=${(e: Event) => this._handleMuteAudio(memberId, e)}\n aria-label=\"${participant?.audioMuted ? 'Unmute audio' : 'Mute audio'}\"\n >\n ${participant?.audioMuted\n ? html`<svg viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path\n d=\"M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z\"\n />\n </svg>`\n : html`<svg viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path\n d=\"M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z\"\n />\n </svg>`}\n ${participant?.audioMuted ? 'Unmute' : 'Mute'}\n </button>\n <button\n class=\"menu-item\"\n @click=${(e: Event) => this._handleMuteVideo(memberId, e)}\n aria-label=\"${participant?.videoMuted ? 'Enable video' : 'Disable video'}\"\n >\n ${participant?.videoMuted\n ? html`<svg viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path\n d=\"M21 6.5l-4 4V7c0-.55-.45-1-1-1H9.82L21 17.18V6.5zM3.27 2L2 3.27 4.73 6H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.21 0 .39-.08.54-.18L19.73 21 21 19.73 3.27 2z\"\n />\n </svg>`\n : html`<svg viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path\n d=\"M17 10.5V7c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1v-3.5l4 4v-11l-4 4z\"\n />\n </svg>`}\n ${participant?.videoMuted ? 'Enable video' : 'Disable video'}\n </button>\n <button\n class=\"menu-item danger\"\n @click=${(e: Event) => this._handleRemove(memberId, e)}\n aria-label=\"Remove participant\"\n >\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path\n d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\n />\n </svg>\n Remove\n </button>\n </div>\n `;\n }\n\n /**\n * Render individual member overlay\n */\n private renderOverlay(layer: LayoutLayer, isSelf: boolean = false) {\n const style = `\n position: absolute;\n top: ${layer.y}%;\n left: ${layer.x}%;\n width: ${layer.width}%;\n height: ${layer.height}%;\n opacity: ${layer.visible ? 1 : 0};\n overflow: visible;\n transition: top 0.3s ease, left 0.3s ease, width 0.3s ease, height 0.3s ease, opacity 0.3s ease;\n pointer-events: auto;\n z-index: 10;\n `;\n\n // member_id is guaranteed to exist by the filter in renderMemberOverlays\n const memberId = layer.member_id!;\n const classes = `member-overlay member-overlay-${memberId}${isSelf ? ' is-self' : ''}`;\n\n return html`\n <div class=\"${classes}\" part=\"overlay\" style=\"${style}\">\n ${!isSelf\n ? html`\n <button\n class=\"menu-trigger\"\n part=\"menu-trigger\"\n @click=${(e: Event) => this._toggleMenu(memberId, e)}\n aria-label=\"Participant menu\"\n aria-expanded=\"${this._openMenuId === memberId}\"\n aria-haspopup=\"menu\"\n >\n ${this.renderMenuIcon()}\n </button>\n ${this.renderMenuDropdown(memberId)}\n `\n : null}\n <span class=\"member-name\" part=\"name\"></span>\n <span class=\"member-indicators\" part=\"indicators\"></span>\n <slot name=\"controls-${memberId}\"></slot>\n </div>\n `;\n }\n\n /**\n * Render the component\n */\n render() {\n return html`\n ${this.renderMemberOverlays()}\n <slot></slot>\n `;\n }\n}\n\n/**\n * Declare global type for TypeScript\n */\ndeclare global {\n interface HTMLElementTagNameMap {\n 'sw-participants': Participants;\n }\n}\n"],"names":["Participants","LitElement","value","changedProperties","layers","participants","castParticipants","target","memberId","e","p","participant","sub","selfId","getSelfId","layer","html","isOpen","isSelf","style","classes","css","__decorateClass","consume","callContext","property","state","customElement"],"mappings":"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"}
1
+ {"version":3,"file":"participants.js","sources":["../../src/components/participants.ts"],"sourcesContent":["/**\n * Participants Component\n *\n * Renders member overlays based on layoutLayers from the call context.\n * Excludes self member and provides slot for <self-media> child component.\n *\n * @example\n * ```html\n * <participants>\n * <self-media mirror=${true}></self-media>\n * </participants>\n * ```\n *\n * @fires sw-participant-mute-audio - Fired to toggle a participant's audio. Detail: `{ participantId: string, muted: boolean }`\n * @fires sw-participant-mute-video - Fired to toggle a participant's video. Detail: `{ participantId: string, muted: boolean }`\n * @fires sw-participant-remove - Fired to remove a participant. Detail: `{ participantId: string }`\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 { Call, LayoutLayer, Participant } from '../types/index.js';\nimport { getSelfId, castParticipants } from '../types/index.js';\nimport { callContext } from '../context/call-context.js';\n\n@customElement('sw-participants')\nexport class Participants extends LitElement {\n static styles = css`\n :host {\n display: contents; /* Doesn't create a box, children inherit positioning */\n }\n\n .member-overlay {\n box-sizing: border-box;\n /* Thick inset box-shadow with semi-transparent background for debugging */\n box-shadow: inset 0 0 0 8px rgba(255, 0, 0, 0.8);\n background-color: rgba(255, 0, 0, 0.1);\n }\n\n .member-overlay.is-self {\n /* Self overlay uses blue border to distinguish from other participants */\n box-shadow: inset 0 0 0 8px rgba(0, 0, 255, 0.8);\n background-color: rgba(0, 0, 255, 0.1);\n }\n\n /* Circular menu trigger button */\n .menu-trigger {\n position: absolute;\n top: 12px;\n left: 12px;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: rgba(0, 0, 0, 0.6);\n border: 2px solid rgba(255, 255, 255, 0.3);\n color: white;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition:\n background 0.2s ease,\n transform 0.2s ease,\n border-color 0.2s ease;\n z-index: 20;\n }\n\n .menu-trigger:hover {\n background: rgba(0, 0, 0, 0.8);\n border-color: rgba(255, 255, 255, 0.6);\n transform: scale(1.1);\n }\n\n .menu-trigger:focus {\n outline: none;\n border-color: #044cf6;\n box-shadow: 0 0 0 3px rgba(4, 78, 246, 0.4);\n }\n\n .menu-trigger svg {\n width: 20px;\n height: 20px;\n }\n\n /* Dropdown menu */\n .menu-dropdown {\n position: absolute;\n top: 12px;\n left: 56px;\n background: rgba(31, 41, 55, 0.95);\n backdrop-filter: blur(8px);\n border-radius: 8px;\n padding: 8px 0;\n min-width: 160px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);\n z-index: 30;\n opacity: 0;\n visibility: hidden;\n transform: translateX(-10px);\n transition:\n opacity 0.2s ease,\n transform 0.2s ease,\n visibility 0.2s ease;\n }\n\n .menu-dropdown.open {\n opacity: 1;\n visibility: visible;\n transform: translateX(0);\n }\n\n .menu-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n color: white;\n font-size: 14px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n cursor: pointer;\n transition: background 0.15s ease;\n border: none;\n background: none;\n width: 100%;\n text-align: left;\n }\n\n .menu-item:hover {\n background: rgba(255, 255, 255, 0.1);\n }\n\n .menu-item svg {\n width: 16px;\n height: 16px;\n flex-shrink: 0;\n }\n\n .menu-item.danger {\n color: #ef4444;\n }\n\n .menu-item.danger:hover {\n background: rgba(239, 68, 68, 0.2);\n }\n `;\n\n /**\n * Consumes call context from parent call-media component\n */\n @consume({ context: callContext, subscribe: true })\n @property({ attribute: false })\n private _call?: Call;\n\n /**\n * Public call property for direct assignment (when not nested in sw-call-media)\n */\n @property({ attribute: false })\n set call(value: Call | undefined) {\n this._call = value;\n this.cleanupSubscriptions();\n this.setupSubscriptions();\n }\n get call(): Call | undefined {\n return this._call;\n }\n\n /**\n * Current layout layers value from observable\n */\n private _layoutLayersValue: LayoutLayer[] = [];\n\n /**\n * Current participants from observable\n */\n private _participantsValue: Participant[] = [];\n\n /**\n * ID of participant with open menu\n */\n @state()\n private _openMenuId: string | null = null;\n\n /**\n * RxJS subscriptions for cleanup\n */\n private subscriptions: Subscription[] = [];\n\n /**\n * Lifecycle: Component connected to DOM\n */\n connectedCallback() {\n super.connectedCallback();\n this.setupSubscriptions();\n }\n\n /**\n * Lifecycle: React to property/context changes\n */\n protected updated(changedProperties: Map<string, unknown>): void {\n super.updated(changedProperties);\n if (changedProperties.has('_call') && this._call) {\n // Clean up old subscriptions first\n this.cleanupSubscriptions();\n // Set up new subscriptions\n this.setupSubscriptions();\n }\n }\n\n /**\n * Lifecycle: Component disconnected from DOM\n */\n disconnectedCallback() {\n super.disconnectedCallback();\n this.cleanupSubscriptions();\n }\n\n /**\n * Subscribe to call observables\n */\n private setupSubscriptions(): void {\n // Continue observing even if _call is undefined initially\n // This allows component to react when call becomes available\n if (!this._call) return;\n\n this.subscriptions.push(\n this._call.layoutLayers$.subscribe((layers: LayoutLayer[]) => {\n this._layoutLayersValue = layers;\n this.requestUpdate();\n })\n );\n\n // Subscribe to participants for menu actions\n if (this._call.participants$) {\n this.subscriptions.push(\n this._call.participants$.subscribe((participants: unknown[]) => {\n this._participantsValue = castParticipants(participants);\n this.requestUpdate();\n })\n );\n }\n\n // Close menu on outside click\n this._handleOutsideClick = this._handleOutsideClick.bind(this);\n document.addEventListener('click', this._handleOutsideClick);\n }\n\n /**\n * Handle click outside menu to close it\n */\n private _handleOutsideClick(e: Event): void {\n const target = e.target as Element;\n if (!target.closest('.menu-trigger') && !target.closest('.menu-dropdown')) {\n this._openMenuId = null;\n }\n }\n\n /**\n * Toggle menu for a participant\n */\n private _toggleMenu(memberId: string, e: Event): void {\n e.stopPropagation();\n this._openMenuId = this._openMenuId === memberId ? null : memberId;\n }\n\n /**\n * Get participant by member ID\n */\n private _getParticipant(memberId: string): Participant | undefined {\n return this._participantsValue.find((p) => p.id === memberId);\n }\n\n /**\n * Handle mute audio action\n */\n private async _handleMuteAudio(memberId: string, e: Event): Promise<void> {\n e.stopPropagation();\n const participant = this._getParticipant(memberId);\n if (!participant) return;\n\n try {\n if (participant.audioMuted && participant.unmute) {\n await participant.unmute();\n } else if (!participant.audioMuted && participant.mute) {\n await participant.mute();\n }\n this.dispatchEvent(\n new CustomEvent('sw-participant-mute-audio', {\n detail: { participant, memberId },\n bubbles: true,\n composed: true\n })\n );\n } catch {\n // Silently handle error\n }\n this._openMenuId = null;\n }\n\n /**\n * Handle mute video action\n */\n private async _handleMuteVideo(memberId: string, e: Event): Promise<void> {\n e.stopPropagation();\n const participant = this._getParticipant(memberId);\n if (!participant) return;\n\n try {\n if (participant.videoMuted && participant.unmuteVideo) {\n await participant.unmuteVideo();\n } else if (!participant.videoMuted && participant.muteVideo) {\n await participant.muteVideo();\n }\n this.dispatchEvent(\n new CustomEvent('sw-participant-mute-video', {\n detail: { participant, memberId },\n bubbles: true,\n composed: true\n })\n );\n } catch {\n // Silently handle error\n }\n this._openMenuId = null;\n }\n\n /**\n * Handle remove participant action\n */\n private async _handleRemove(memberId: string, e: Event): Promise<void> {\n e.stopPropagation();\n const participant = this._getParticipant(memberId);\n if (!participant?.remove) return;\n\n try {\n await participant.remove();\n this.dispatchEvent(\n new CustomEvent('sw-participant-remove', {\n detail: { participant, memberId },\n bubbles: true,\n composed: true\n })\n );\n } catch {\n // Silently handle error\n }\n this._openMenuId = null;\n }\n\n /**\n * Cleanup all subscriptions\n */\n private cleanupSubscriptions(): void {\n this.subscriptions.forEach((sub) => sub.unsubscribe());\n this.subscriptions = [];\n document.removeEventListener('click', this._handleOutsideClick);\n }\n\n /**\n * Render member overlays for all participants\n */\n private renderMemberOverlays() {\n if (!this._layoutLayersValue || this._layoutLayersValue.length === 0) {\n return null;\n }\n\n // Get selfId dynamically from call.self to handle cases where self is available after subscription setup\n const selfId = getSelfId(this._call);\n\n return this._layoutLayersValue\n .filter((layer) => layer.member_id)\n .map((layer) => this.renderOverlay(layer, layer.member_id === selfId));\n }\n\n /**\n * Render menu button SVG icon (three dots)\n */\n private renderMenuIcon() {\n return html`\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <circle cx=\"12\" cy=\"6\" r=\"2\" />\n <circle cx=\"12\" cy=\"12\" r=\"2\" />\n <circle cx=\"12\" cy=\"18\" r=\"2\" />\n </svg>\n `;\n }\n\n /**\n * Render menu dropdown for a participant\n */\n private renderMenuDropdown(memberId: string) {\n const participant = this._getParticipant(memberId);\n const isOpen = this._openMenuId === memberId;\n\n return html`\n <div class=\"menu-dropdown ${isOpen ? 'open' : ''}\">\n <button\n class=\"menu-item\"\n @click=${(e: Event) => this._handleMuteAudio(memberId, e)}\n aria-label=\"${participant?.audioMuted ? 'Unmute audio' : 'Mute audio'}\"\n >\n ${participant?.audioMuted\n ? html`<svg viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path\n d=\"M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z\"\n />\n </svg>`\n : html`<svg viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path\n d=\"M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z\"\n />\n </svg>`}\n ${participant?.audioMuted ? 'Unmute' : 'Mute'}\n </button>\n <button\n class=\"menu-item\"\n @click=${(e: Event) => this._handleMuteVideo(memberId, e)}\n aria-label=\"${participant?.videoMuted ? 'Enable video' : 'Disable video'}\"\n >\n ${participant?.videoMuted\n ? html`<svg viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path\n d=\"M21 6.5l-4 4V7c0-.55-.45-1-1-1H9.82L21 17.18V6.5zM3.27 2L2 3.27 4.73 6H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.21 0 .39-.08.54-.18L19.73 21 21 19.73 3.27 2z\"\n />\n </svg>`\n : html`<svg viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path\n d=\"M17 10.5V7c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1v-3.5l4 4v-11l-4 4z\"\n />\n </svg>`}\n ${participant?.videoMuted ? 'Enable video' : 'Disable video'}\n </button>\n <button\n class=\"menu-item danger\"\n @click=${(e: Event) => this._handleRemove(memberId, e)}\n aria-label=\"Remove participant\"\n >\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path\n d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\n />\n </svg>\n Remove\n </button>\n </div>\n `;\n }\n\n /**\n * Render individual member overlay\n */\n private renderOverlay(layer: LayoutLayer, isSelf: boolean = false) {\n const style = `\n position: absolute;\n top: ${layer.y}%;\n left: ${layer.x}%;\n width: ${layer.width}%;\n height: ${layer.height}%;\n opacity: ${layer.visible ? 1 : 0};\n overflow: visible;\n transition: top 0.3s ease, left 0.3s ease, width 0.3s ease, height 0.3s ease, opacity 0.3s ease;\n pointer-events: auto;\n z-index: 10;\n `;\n\n // member_id is guaranteed to exist by the filter in renderMemberOverlays\n const memberId = layer.member_id!;\n const classes = `member-overlay member-overlay-${memberId}${isSelf ? ' is-self' : ''}`;\n\n return html`\n <div class=\"${classes}\" part=\"overlay\" style=\"${style}\">\n ${!isSelf\n ? html`\n <button\n class=\"menu-trigger\"\n part=\"menu-trigger\"\n @click=${(e: Event) => this._toggleMenu(memberId, e)}\n aria-label=\"Participant menu\"\n aria-expanded=\"${this._openMenuId === memberId}\"\n aria-haspopup=\"menu\"\n >\n ${this.renderMenuIcon()}\n </button>\n ${this.renderMenuDropdown(memberId)}\n `\n : null}\n <span class=\"member-name\" part=\"name\"></span>\n <span class=\"member-indicators\" part=\"indicators\"></span>\n <slot name=\"controls-${memberId}\"></slot>\n </div>\n `;\n }\n\n /**\n * Render the component\n */\n render() {\n return html`\n ${this.renderMemberOverlays()}\n <slot></slot>\n `;\n }\n}\n\n/**\n * Declare global type for TypeScript\n */\ndeclare global {\n interface HTMLElementTagNameMap {\n 'sw-participants': Participants;\n }\n}\n"],"names":["Participants","LitElement","value","changedProperties","layers","participants","castParticipants","target","memberId","e","p","participant","sub","selfId","getSelfId","layer","html","isOpen","isSelf","style","classes","css","__decorateClass","consume","callContext","property","state","customElement"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -14,7 +14,7 @@ export { DialpadComponent } from './components/dialpad.js';
14
14
  export { ClickToCallComponent } from './components/click-to-call.js';
15
15
  export { DirectoryComponent } from './components/directory.js';
16
16
  export { ParticipantControlsComponent } from './components/participant-controls.js';
17
- export type { Call, CallSelf, DeviceController, LayoutLayer, Participant } from './types/index.js';
17
+ export type { Call, CallParticipant, CallSelfParticipant, DeviceController, LayoutLayer, Participant } from './types/index.js';
18
18
  export * from './context/index.js';
19
19
  export { html, css, LitElement } from 'lit';
20
20
  export type { TemplateResult, CSSResult } from 'lit';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AAGpF,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGnG,cAAc,oBAAoB,CAAC;AAGnC,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAC5C,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AAQrD;;GAEG;AACH,eAAO,MAAM,OAAO,EAAE,MAAoB,CAAC;AAE3C;;GAEG;AACH,eAAO,MAAM,KAAK,EAAE,OAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AAGpF,YAAY,EAAE,IAAI,EAAE,eAAe,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG/H,cAAc,oBAAoB,CAAC;AAGnC,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAC5C,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AAQrD;;GAEG;AACH,eAAO,MAAM,OAAO,EAAE,MAAoB,CAAC;AAE3C;;GAEG;AACH,eAAO,MAAM,KAAK,EAAE,OAAc,CAAC"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["/**\n * @signalwire/web-components\n * UI Components Library built with Lit\n */\n\n// Export components\nexport { ExampleButton } from './components/example-button.js';\nexport { CallMedia } from './components/call-media.js';\nexport { Participants } from './components/participants.js';\nexport { SelfMedia } from './components/self-media.js';\nexport { AudioLevel } from './components/audio-level.js';\nexport { DeviceSelector } from './components/device-selector.js';\nexport { CallControls } from './components/call-controls.js';\nexport { CallStatusComponent } from './components/call-status.js';\nexport { DialpadComponent } from './components/dialpad.js';\nexport { ClickToCallComponent } from './components/click-to-call.js';\nexport { DirectoryComponent } from './components/directory.js';\nexport { ParticipantControlsComponent } from './components/participant-controls.js';\n\n// Export types (re-exported from core)\nexport type { Call, CallSelf, DeviceController, LayoutLayer, Participant } from './types/index.js';\n\n// Export context\nexport * from './context/index.js';\n\n// Re-export Lit utilities for convenience\nexport { html, css, LitElement } from 'lit';\nexport type { TemplateResult, CSSResult } from 'lit';\n\n// ============================================================================\n// Library Ready Event (for async/dynamic script loading)\n// ============================================================================\n\ndeclare const __VERSION__: string;\n\n/**\n * Library version from package.json, injected at build time.\n */\nexport const version: string = __VERSION__;\n\n/**\n * Flag indicating the library has been loaded and is ready to use.\n */\nexport const ready: boolean = true;\n\n/**\n * Emits 'signalwire:web-components:ready' event when the library is loaded.\n *\n * Scripts that might load BEFORE the library (check flag first):\n * ```js\n * if (window.SignalWireUI?.ready) {\n * // Library already loaded, use it directly\n * initApp();\n * } else {\n * window.addEventListener('signalwire:web-components:ready', () => initApp());\n * }\n * ```\n */\nconst emitReadyEvent = (): void => {\n if (typeof window !== 'undefined') {\n const event = new CustomEvent('signalwire:web-components:ready', {\n detail: { version: __VERSION__ }\n });\n window.dispatchEvent(event);\n }\n};\n\nemitReadyEvent();\n"],"names":["version","ready","emitReadyEvent","event"],"mappings":";;;;;;;;;;;;;;AAsCO,MAAMA,IAAkB,cAKlBC,IAAiB,IAexBC,IAAiB,MAAY;AACjC,MAAI,OAAO,SAAW,KAAa;AACjC,UAAMC,IAAQ,IAAI,YAAY,mCAAmC;AAAA,MAC/D,QAAQ,EAAE,SAAS,aAAA;AAAA,IAAY,CAChC;AACD,WAAO,cAAcA,CAAK;AAAA,EAC5B;AACF;AAEAD,EAAA;"}
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["/**\n * @signalwire/web-components\n * UI Components Library built with Lit\n */\n\n// Export components\nexport { ExampleButton } from './components/example-button.js';\nexport { CallMedia } from './components/call-media.js';\nexport { Participants } from './components/participants.js';\nexport { SelfMedia } from './components/self-media.js';\nexport { AudioLevel } from './components/audio-level.js';\nexport { DeviceSelector } from './components/device-selector.js';\nexport { CallControls } from './components/call-controls.js';\nexport { CallStatusComponent } from './components/call-status.js';\nexport { DialpadComponent } from './components/dialpad.js';\nexport { ClickToCallComponent } from './components/click-to-call.js';\nexport { DirectoryComponent } from './components/directory.js';\nexport { ParticipantControlsComponent } from './components/participant-controls.js';\n\n// Export types (re-exported from core)\nexport type { Call, CallParticipant, CallSelfParticipant, DeviceController, LayoutLayer, Participant } from './types/index.js';\n\n// Export context\nexport * from './context/index.js';\n\n// Re-export Lit utilities for convenience\nexport { html, css, LitElement } from 'lit';\nexport type { TemplateResult, CSSResult } from 'lit';\n\n// ============================================================================\n// Library Ready Event (for async/dynamic script loading)\n// ============================================================================\n\ndeclare const __VERSION__: string;\n\n/**\n * Library version from package.json, injected at build time.\n */\nexport const version: string = __VERSION__;\n\n/**\n * Flag indicating the library has been loaded and is ready to use.\n */\nexport const ready: boolean = true;\n\n/**\n * Emits 'signalwire:web-components:ready' event when the library is loaded.\n *\n * Scripts that might load BEFORE the library (check flag first):\n * ```js\n * if (window.SignalWireUI?.ready) {\n * // Library already loaded, use it directly\n * initApp();\n * } else {\n * window.addEventListener('signalwire:web-components:ready', () => initApp());\n * }\n * ```\n */\nconst emitReadyEvent = (): void => {\n if (typeof window !== 'undefined') {\n const event = new CustomEvent('signalwire:web-components:ready', {\n detail: { version: __VERSION__ }\n });\n window.dispatchEvent(event);\n }\n};\n\nemitReadyEvent();\n"],"names":["version","ready","emitReadyEvent","event"],"mappings":";;;;;;;;;;;;;;AAsCO,MAAMA,IAAkB,cAKlBC,IAAiB,IAexBC,IAAiB,MAAY;AACjC,MAAI,OAAO,SAAW,KAAa;AACjC,UAAMC,IAAQ,IAAI,YAAY,mCAAmC;AAAA,MAC/D,QAAQ,EAAE,SAAS,aAAA;AAAA,IAAY,CAChC;AACD,WAAO,cAAcA,CAAK;AAAA,EAC5B;AACF;AAEAD,EAAA;"}
package/dist/react.d.ts CHANGED
@@ -47,52 +47,73 @@ declare module 'react' {
47
47
  'sw-call-media': SWProps<CallMedia>;
48
48
 
49
49
  /** Local video overlay with optional mirror mode. */
50
- 'sw-self-media': SWProps<SelfMedia, {
51
- mirror?: boolean;
52
- }>;
50
+ 'sw-self-media': SWProps<
51
+ SelfMedia,
52
+ {
53
+ mirror?: boolean;
54
+ }
55
+ >;
53
56
 
54
57
  /** Mute, hangup, and screen-share controls. */
55
- 'sw-call-controls': SWProps<CallControls, {
56
- orientation?: 'horizontal' | 'vertical';
57
- 'show-tooltips'?: boolean;
58
- }>;
58
+ 'sw-call-controls': SWProps<
59
+ CallControls,
60
+ {
61
+ orientation?: 'horizontal' | 'vertical';
62
+ 'show-tooltips'?: boolean;
63
+ }
64
+ >;
59
65
 
60
66
  /** Call status display with duration timer. */
61
67
  'sw-call-status': SWProps<CallStatusComponent>;
62
68
 
63
69
  /** Media device dropdowns with optional preview. */
64
- 'sw-device-selector': SWProps<DeviceSelector, {
65
- 'show-preview'?: boolean;
66
- }>;
70
+ 'sw-device-selector': SWProps<
71
+ DeviceSelector,
72
+ {
73
+ 'show-preview'?: boolean;
74
+ }
75
+ >;
67
76
 
68
77
  /** Real-time audio level visualizer. */
69
- 'sw-audio-level': SWProps<AudioLevel, {
70
- bars?: number;
71
- orientation?: 'vertical' | 'horizontal';
72
- 'max-size'?: number;
73
- }>;
78
+ 'sw-audio-level': SWProps<
79
+ AudioLevel,
80
+ {
81
+ bars?: number;
82
+ orientation?: 'vertical' | 'horizontal';
83
+ 'max-size'?: number;
84
+ }
85
+ >;
74
86
 
75
87
  /** DTMF dialpad. */
76
- 'sw-dialpad': SWProps<DialpadComponent, {
77
- 'show-call-button'?: boolean;
78
- placeholder?: string;
79
- }>;
88
+ 'sw-dialpad': SWProps<
89
+ DialpadComponent,
90
+ {
91
+ 'show-call-button'?: boolean;
92
+ placeholder?: string;
93
+ }
94
+ >;
80
95
 
81
96
  /** Single-button call widget. */
82
- 'sw-click-to-call': SWProps<ClickToCallComponent, {
83
- destination?: string;
84
- label?: string;
85
- 'audio-only'?: boolean;
86
- }>;
97
+ 'sw-click-to-call': SWProps<
98
+ ClickToCallComponent,
99
+ {
100
+ destination?: string;
101
+ label?: string;
102
+ 'audio-only'?: boolean;
103
+ }
104
+ >;
87
105
 
88
106
  /** Searchable contact directory. */
89
107
  'sw-directory': SWProps<DirectoryComponent>;
90
108
 
91
109
  /** Per-participant mute, volume, and remove controls. */
92
- 'sw-participant-controls': SWProps<ParticipantControlsComponent, {
93
- 'show-volume'?: boolean;
94
- 'show-pin'?: boolean;
95
- }>;
110
+ 'sw-participant-controls': SWProps<
111
+ ParticipantControlsComponent,
112
+ {
113
+ 'show-volume'?: boolean;
114
+ 'show-pin'?: boolean;
115
+ }
116
+ >;
96
117
 
97
118
  /** Remote participant overlay list. */
98
119
  'sw-participants': SWProps<Participants>;
@@ -1,44 +1,20 @@
1
1
  /**
2
2
  * Type definitions for call-media components.
3
3
  *
4
- * Call and LayoutLayer types are imported from the SDK.
5
- * Other types are defined locally for web-component specific needs.
4
+ * Types are imported directly from the SDK to stay in sync.
6
5
  */
7
- import type { Observable } from 'rxjs';
8
- import type { Call, DeviceController, LayoutLayer } from '@signalwire/js';
9
- export type { Call, DeviceController, LayoutLayer };
6
+ import type { Call, CallParticipant, CallSelfParticipant, DeviceController, LayoutLayer } from '@signalwire/js';
7
+ export type { Call, CallParticipant, CallSelfParticipant, DeviceController, LayoutLayer };
8
+ export type Participant = CallParticipant;
10
9
  /**
11
- * Type helper for accessing call.self with proper typing
12
- * The SDK's Call.self is typed as unknown for flexibility
13
- */
14
- export interface CallSelf {
15
- id: string;
16
- }
17
- /**
18
- * Helper to safely get self ID from a Call
10
+ * Helper to safely get self ID from a Call.
11
+ * Call.self is typed as CallSelfParticipant | null.
19
12
  */
20
13
  export declare function getSelfId(call: Call | undefined): string | undefined;
21
14
  /**
22
- * Helper to cast participants from unknown[] to Participant[]
23
- * The SDK uses unknown[] for flexibility, but web-components knows the shape
15
+ * Type-safe cast for participants array.
16
+ * The SDK's Call.participants is typed as CallParticipant[], so this
17
+ * provides a semantic helper for web-components that receive unknown[].
24
18
  */
25
19
  export declare function castParticipants(participants: unknown[]): Participant[];
26
- /**
27
- * Participant interface for call participants
28
- * Web-component specific with optional methods
29
- */
30
- export interface Participant {
31
- id: string;
32
- name?: string;
33
- name$?: Observable<string>;
34
- audioMuted?: boolean;
35
- audioMuted$?: Observable<boolean>;
36
- videoMuted?: boolean;
37
- videoMuted$?: Observable<boolean>;
38
- mute?(): Promise<void>;
39
- unmute?(): Promise<void>;
40
- muteVideo?(): Promise<void>;
41
- unmuteVideo?(): Promise<void>;
42
- remove?(): Promise<void>;
43
- }
44
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AACvC,OAAO,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAG1E,YAAY,EAAE,IAAI,EAAE,gBAAgB,EAAE,WAAW,EAAE,CAAC;AAEpD;;;GAGG;AACH,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAGpE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,OAAO,EAAE,GAAG,WAAW,EAAE,CAEvE;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;IAC3B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IAClC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IAClC,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,MAAM,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,SAAS,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,WAAW,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAGhH,YAAY,EAAE,IAAI,EAAE,eAAe,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,WAAW,EAAE,CAAC;AAG1F,MAAM,MAAM,WAAW,GAAG,eAAe,CAAC;AAE1C;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAEpE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,OAAO,EAAE,GAAG,WAAW,EAAE,CAEvE"}
@@ -1,12 +1,12 @@
1
- function r(t) {
2
- const n = t == null ? void 0 : t.self;
3
- return n == null ? void 0 : n.id;
4
- }
5
1
  function e(t) {
2
+ var n;
3
+ return (n = t == null ? void 0 : t.self) == null ? void 0 : n.id;
4
+ }
5
+ function r(t) {
6
6
  return t;
7
7
  }
8
8
  export {
9
- e as castParticipants,
10
- r as getSelfId
9
+ r as castParticipants,
10
+ e as getSelfId
11
11
  };
12
12
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/types/index.ts"],"sourcesContent":["/**\n * Type definitions for call-media components.\n *\n * Call and LayoutLayer types are imported from the SDK.\n * Other types are defined locally for web-component specific needs.\n */\n\nimport type { Observable } from 'rxjs';\nimport type { Call, DeviceController, LayoutLayer } from '@signalwire/js';\n\n// Re-export SDK types for internal use\nexport type { Call, DeviceController, LayoutLayer };\n\n/**\n * Type helper for accessing call.self with proper typing\n * The SDK's Call.self is typed as unknown for flexibility\n */\nexport interface CallSelf {\n id: string;\n}\n\n/**\n * Helper to safely get self ID from a Call\n */\nexport function getSelfId(call: Call | undefined): string | undefined {\n const self = call?.self as CallSelf | undefined;\n return self?.id;\n}\n\n/**\n * Helper to cast participants from unknown[] to Participant[]\n * The SDK uses unknown[] for flexibility, but web-components knows the shape\n */\nexport function castParticipants(participants: unknown[]): Participant[] {\n return participants as Participant[];\n}\n\n/**\n * Participant interface for call participants\n * Web-component specific with optional methods\n */\nexport interface Participant {\n id: string;\n name?: string;\n name$?: Observable<string>;\n audioMuted?: boolean;\n audioMuted$?: Observable<boolean>;\n videoMuted?: boolean;\n videoMuted$?: Observable<boolean>;\n mute?(): Promise<void>;\n unmute?(): Promise<void>;\n muteVideo?(): Promise<void>;\n unmuteVideo?(): Promise<void>;\n remove?(): Promise<void>;\n}\n\n"],"names":["getSelfId","call","self","castParticipants","participants"],"mappings":"AAwBO,SAASA,EAAUC,GAA4C;AACpE,QAAMC,IAAOD,KAAA,gBAAAA,EAAM;AACnB,SAAOC,KAAA,gBAAAA,EAAM;AACf;AAMO,SAASC,EAAiBC,GAAwC;AACvE,SAAOA;AACT;"}
1
+ {"version":3,"file":"index.js","sources":["../../src/types/index.ts"],"sourcesContent":["/**\n * Type definitions for call-media components.\n *\n * Types are imported directly from the SDK to stay in sync.\n */\n\nimport type { Call, CallParticipant, CallSelfParticipant, DeviceController, LayoutLayer } from '@signalwire/js';\n\n// Re-export SDK types for internal use\nexport type { Call, CallParticipant, CallSelfParticipant, DeviceController, LayoutLayer };\n\n// Use SDK's CallParticipant as the canonical Participant type\nexport type Participant = CallParticipant;\n\n/**\n * Helper to safely get self ID from a Call.\n * Call.self is typed as CallSelfParticipant | null.\n */\nexport function getSelfId(call: Call | undefined): string | undefined {\n return call?.self?.id;\n}\n\n/**\n * Type-safe cast for participants array.\n * The SDK's Call.participants is typed as CallParticipant[], so this\n * provides a semantic helper for web-components that receive unknown[].\n */\nexport function castParticipants(participants: unknown[]): Participant[] {\n return participants as Participant[];\n}\n"],"names":["getSelfId","call","_a","castParticipants","participants"],"mappings":"AAkBO,SAASA,EAAUC,GAA4C;AAA/D,MAAAC;AACL,UAAOA,IAAAD,KAAA,gBAAAA,EAAM,SAAN,gBAAAC,EAAY;AACrB;AAOO,SAASC,EAAiBC,GAAwC;AACvE,SAAOA;AACT;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@signalwire/web-components",
3
- "version": "4.0.0-beta.10",
3
+ "version": "4.0.0-beta.11",
4
4
  "description": "UI components library built with Lit",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -115,7 +115,7 @@
115
115
  "rxjs": "^7.8.2"
116
116
  },
117
117
  "peerDependencies": {
118
- "@signalwire/js": "4.0.0-beta.10"
118
+ "@signalwire/js": "4.0.0-beta.11"
119
119
  },
120
120
  "devDependencies": {
121
121
  "@playwright/test": "^1.56.1",