@signalwire/web-components 1.0.0-dev-20260504184154 → 1.0.0-dev-20260508182243
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/UI/controls/sw-ui-dialpad.d.ts +1 -1
- package/dist/components/UI/controls/sw-ui-dialpad.d.ts.map +1 -1
- package/dist/components/UI/controls/sw-ui-dialpad.js +9 -8
- package/dist/components/UI/controls/sw-ui-dialpad.js.map +1 -1
- package/dist/components/UI/controls/sw-ui-dropup.d.ts +1 -1
- package/dist/components/UI/controls/sw-ui-dropup.d.ts.map +1 -1
- package/dist/components/UI/controls/sw-ui-dropup.js +9 -8
- package/dist/components/UI/controls/sw-ui-dropup.js.map +1 -1
- package/dist/components/UI/controls/sw-ui-split-button.d.ts +1 -1
- package/dist/components/UI/controls/sw-ui-split-button.d.ts.map +1 -1
- package/dist/components/UI/controls/sw-ui-split-button.js +13 -12
- package/dist/components/UI/controls/sw-ui-split-button.js.map +1 -1
- package/dist/components/UI/host-reset.d.ts +16 -0
- package/dist/components/UI/host-reset.d.ts.map +1 -0
- package/dist/components/UI/host-reset.js +20 -0
- package/dist/components/UI/host-reset.js.map +1 -0
- package/dist/components/UI/sw-ui-alert.d.ts +1 -1
- package/dist/components/UI/sw-ui-alert.d.ts.map +1 -1
- package/dist/components/UI/sw-ui-alert.js +14 -13
- package/dist/components/UI/sw-ui-alert.js.map +1 -1
- package/dist/components/UI/sw-ui-transcript-view.d.ts +1 -1
- package/dist/components/UI/sw-ui-transcript-view.d.ts.map +1 -1
- package/dist/components/UI/sw-ui-transcript-view.js +6 -5
- package/dist/components/UI/sw-ui-transcript-view.js.map +1 -1
- package/dist/components/sw-call-status.d.ts +1 -1
- package/dist/components/sw-call-status.d.ts.map +1 -1
- package/dist/components/sw-call-status.js +6 -5
- package/dist/components/sw-call-status.js.map +1 -1
- package/dist/components/sw-call-widget/sw-call-widget.d.ts +1 -1
- package/dist/components/sw-call-widget/sw-call-widget.d.ts.map +1 -1
- package/dist/components/sw-call-widget/sw-call-widget.js +14 -13
- package/dist/components/sw-call-widget/sw-call-widget.js.map +1 -1
- package/dist/components/sw-click-to-call.d.ts +1 -1
- package/dist/components/sw-click-to-call.d.ts.map +1 -1
- package/dist/components/sw-click-to-call.js +9 -8
- package/dist/components/sw-click-to-call.js.map +1 -1
- package/dist/components/sw-device-selector/sw-device-selector.d.ts +1 -1
- package/dist/components/sw-device-selector/sw-device-selector.d.ts.map +1 -1
- package/dist/components/sw-device-selector/sw-device-selector.js +5 -4
- package/dist/components/sw-device-selector/sw-device-selector.js.map +1 -1
- package/dist/components/sw-directory.d.ts +1 -1
- package/dist/components/sw-directory.d.ts.map +1 -1
- package/dist/components/sw-directory.js +6 -5
- package/dist/components/sw-directory.js.map +1 -1
- package/dist/components/sw-participant-controls.d.ts +1 -1
- package/dist/components/sw-participant-controls.d.ts.map +1 -1
- package/dist/components/sw-participant-controls.js +6 -5
- package/dist/components/sw-participant-controls.js.map +1 -1
- package/dist/components/sw-participants.d.ts +1 -1
- package/dist/components/sw-participants.d.ts.map +1 -1
- package/dist/components/sw-participants.js +20 -19
- package/dist/components/sw-participants.js.map +1 -1
- package/dist/embed/signalwire-web-components-embed.iife.js +109 -95
- package/dist/embed/signalwire-web-components-embed.iife.js.map +1 -1
- package/dist/embed/signalwire-web-components-embed.umd.cjs +109 -95
- package/dist/embed/signalwire-web-components-embed.umd.cjs.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sw-participants.js","sources":["../../src/components/sw-participants.ts"],"sourcesContent":["/**\n * SwParticipants Component\n *\n * Renders member overlays based on layoutLayers.\n * Excludes self member and provides slot for <self-media> child component.\n *\n * Input precedence (most specific wins): `.call` > context.\n *\n * @example\n * ```html\n * <sw-participants></sw-participants>\n * <sw-participants .call=${call}></sw-participants>\n * ```\n *\n * @slot - Default slot for overlay content.\n * @slot controls-{memberId} - Per-participant menu content (e.g. `sw-participant-controls`).\n *\n * @fires sw-participant-mute-audio - User muted/unmuted a participant's audio. Detail: `{ participant, memberId }`.\n * @fires sw-participant-mute-video - User muted/unmuted a participant's video. Detail: `{ participant, memberId }`.\n * @fires sw-participant-remove - User removed a participant. Detail: `{ participant, memberId }`.\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 { CallParticipant, CallSelfParticipant } from '@signalwire/js';\nimport type { Call, LayoutLayer } from '../types/index.js';\nimport { callStateContext, type CallState } from '../context/call-state-context.js';\n\n@customElement('sw-participants')\nexport class SwParticipants extends LitElement {\n static styles = css`\n :host {\n display: contents;\n }\n\n .member-overlay {\n box-sizing: border-box;\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 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 .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 .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 @consume({ context: callStateContext, subscribe: true })\n @state()\n private _callState?: CallState;\n\n /** Explicit Call — when set, subscribes directly and bypasses context. */\n @property({ type: Object }) call?: Call;\n\n @state() private _directLayoutLayers: LayoutLayer[] = [];\n @state() private _directParticipants: CallParticipant[] = [];\n @state() private _directSelf: CallSelfParticipant | null = null;\n\n private _directSubscriptions: Subscription[] = [];\n\n @state()\n private _openMenuId: string | null = null;\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 private _handleEscape = (e: KeyboardEvent): void => {\n if (e.key === 'Escape' && this._openMenuId !== null) {\n this._openMenuId = null;\n }\n };\n\n connectedCallback() {\n super.connectedCallback();\n document.addEventListener('click', this._handleOutsideClick);\n document.addEventListener('keydown', this._handleEscape);\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n document.removeEventListener('click', this._handleOutsideClick);\n document.removeEventListener('keydown', this._handleEscape);\n this._teardownDirect();\n }\n\n protected updated(changed: Map<string, unknown>): void {\n super.updated(changed);\n if (changed.has('call')) {\n this._teardownDirect();\n if (this.call) {\n this._directSubscriptions.push(\n this.call.layoutLayers$.subscribe((l) => (this._directLayoutLayers = l)),\n this.call.participants$.subscribe((p) => (this._directParticipants = p)),\n this.call.self$.subscribe((s) => (this._directSelf = s))\n );\n }\n }\n }\n\n private _teardownDirect(): void {\n this._directSubscriptions.forEach((s) => s.unsubscribe());\n this._directSubscriptions = [];\n this._directLayoutLayers = [];\n this._directParticipants = [];\n this._directSelf = null;\n }\n\n // ── Helpers ────────────────────────────────────────────────────────\n\n private _toggleMenu(memberId: string, e: Event): void {\n e.stopPropagation();\n this._openMenuId = this._openMenuId === memberId ? null : memberId;\n }\n\n private _getParticipant(memberId: string) {\n const participants = this.call ? this._directParticipants : this._callState?.participants ?? [];\n return participants.find((p) => p.id === memberId);\n }\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 try {\n if (participant.audioMuted) {\n await participant.unmute();\n } else {\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 private async _handleMuteVideo(memberId: string, e: Event): Promise<void> {\n e.stopPropagation();\n const participant = this._getParticipant(memberId);\n if (!participant) return;\n try {\n if (participant.videoMuted) {\n await participant.unmuteVideo();\n } else {\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 private async _handleRemove(memberId: string, e: Event): Promise<void> {\n e.stopPropagation();\n const participant = this._getParticipant(memberId);\n if (!participant?.remove) return;\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 // ── Render ─────────────────────────────────────────────────────────\n\n private _renderMenuIcon() {\n return html`\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\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 private _renderMenuDropdown(memberId: string) {\n const participant = this._getParticipant(memberId);\n const isOpen = this._openMenuId === memberId;\n\n return html`\n <div\n class=\"menu-dropdown ${isOpen ? 'open' : ''}\"\n role=\"menu\"\n aria-label=\"Participant actions\"\n >\n <button\n class=\"menu-item\"\n role=\"menuitem\"\n @click=${(e: Event) => this._handleMuteAudio(memberId, e)}\n aria-label=\"${participant?.audioMuted ? 'Unmute audio' : 'Mute audio'}\"\n >\n ${participant?.audioMuted ? 'Unmute' : 'Mute'}\n </button>\n <button\n class=\"menu-item\"\n role=\"menuitem\"\n @click=${(e: Event) => this._handleMuteVideo(memberId, e)}\n aria-label=\"${participant?.videoMuted ? 'Enable video' : 'Disable video'}\"\n >\n ${participant?.videoMuted ? 'Enable video' : 'Disable video'}\n </button>\n <button\n class=\"menu-item danger\"\n role=\"menuitem\"\n @click=${(e: Event) => this._handleRemove(memberId, e)}\n aria-label=\"Remove participant\"\n >\n Remove\n </button>\n </div>\n `;\n }\n\n private _renderOverlay(layer: LayoutLayer, isSelf: boolean) {\n const memberId = layer.member_id!;\n const classes = `member-overlay${isSelf ? ' is-self' : ''}`;\n\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 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 <slot name=\"controls-${memberId}\"></slot>\n </div>\n `;\n }\n\n render() {\n const layers = this.call ? this._directLayoutLayers : this._callState?.layoutLayers ?? [];\n const selfId = this.call ? this._directSelf?.id : this._callState?.self?.id;\n\n const overlays = layers\n .filter((layer) => layer.member_id)\n .map((layer) => this._renderOverlay(layer, layer.member_id === selfId));\n\n return html`\n ${overlays}\n <slot></slot>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'sw-participants': SwParticipants;\n }\n}\n"],"names":["SwParticipants","LitElement","target","changed","l","p","s","memberId","e","_a","participant","html","isOpen","layer","isSelf","classes","style","layers","selfId","_b","_d","_c","overlays","css","__decorateClass","consume","callStateContext","state","property","customElement"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sw-participants.js","sources":["../../src/components/sw-participants.ts"],"sourcesContent":["/**\n * SwParticipants Component\n *\n * Renders member overlays based on layoutLayers.\n * Excludes self member and provides slot for <self-media> child component.\n *\n * Input precedence (most specific wins): `.call` > context.\n *\n * @example\n * ```html\n * <sw-participants></sw-participants>\n * <sw-participants .call=${call}></sw-participants>\n * ```\n *\n * @slot - Default slot for overlay content.\n * @slot controls-{memberId} - Per-participant menu content (e.g. `sw-participant-controls`).\n *\n * @fires sw-participant-mute-audio - User muted/unmuted a participant's audio. Detail: `{ participant, memberId }`.\n * @fires sw-participant-mute-video - User muted/unmuted a participant's video. Detail: `{ participant, memberId }`.\n * @fires sw-participant-remove - User removed a participant. Detail: `{ participant, memberId }`.\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 { CallParticipant, CallSelfParticipant } from '@signalwire/js';\nimport type { Call, LayoutLayer } from '../types/index.js';\nimport { callStateContext, type CallState } from '../context/call-state-context.js';\nimport { hostReset } from './UI/host-reset.js';\n\n@customElement('sw-participants')\nexport class SwParticipants extends LitElement {\n static styles = [hostReset, css`\n :host {\n display: contents;\n }\n\n .member-overlay {\n box-sizing: border-box;\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 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 .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 .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 @consume({ context: callStateContext, subscribe: true })\n @state()\n private _callState?: CallState;\n\n /** Explicit Call — when set, subscribes directly and bypasses context. */\n @property({ type: Object }) call?: Call;\n\n @state() private _directLayoutLayers: LayoutLayer[] = [];\n @state() private _directParticipants: CallParticipant[] = [];\n @state() private _directSelf: CallSelfParticipant | null = null;\n\n private _directSubscriptions: Subscription[] = [];\n\n @state()\n private _openMenuId: string | null = null;\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 private _handleEscape = (e: KeyboardEvent): void => {\n if (e.key === 'Escape' && this._openMenuId !== null) {\n this._openMenuId = null;\n }\n };\n\n connectedCallback() {\n super.connectedCallback();\n document.addEventListener('click', this._handleOutsideClick);\n document.addEventListener('keydown', this._handleEscape);\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n document.removeEventListener('click', this._handleOutsideClick);\n document.removeEventListener('keydown', this._handleEscape);\n this._teardownDirect();\n }\n\n protected updated(changed: Map<string, unknown>): void {\n super.updated(changed);\n if (changed.has('call')) {\n this._teardownDirect();\n if (this.call) {\n this._directSubscriptions.push(\n this.call.layoutLayers$.subscribe((l) => (this._directLayoutLayers = l)),\n this.call.participants$.subscribe((p) => (this._directParticipants = p)),\n this.call.self$.subscribe((s) => (this._directSelf = s))\n );\n }\n }\n }\n\n private _teardownDirect(): void {\n this._directSubscriptions.forEach((s) => s.unsubscribe());\n this._directSubscriptions = [];\n this._directLayoutLayers = [];\n this._directParticipants = [];\n this._directSelf = null;\n }\n\n // ── Helpers ────────────────────────────────────────────────────────\n\n private _toggleMenu(memberId: string, e: Event): void {\n e.stopPropagation();\n this._openMenuId = this._openMenuId === memberId ? null : memberId;\n }\n\n private _getParticipant(memberId: string) {\n const participants = this.call ? this._directParticipants : this._callState?.participants ?? [];\n return participants.find((p) => p.id === memberId);\n }\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 try {\n if (participant.audioMuted) {\n await participant.unmute();\n } else {\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 private async _handleMuteVideo(memberId: string, e: Event): Promise<void> {\n e.stopPropagation();\n const participant = this._getParticipant(memberId);\n if (!participant) return;\n try {\n if (participant.videoMuted) {\n await participant.unmuteVideo();\n } else {\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 private async _handleRemove(memberId: string, e: Event): Promise<void> {\n e.stopPropagation();\n const participant = this._getParticipant(memberId);\n if (!participant?.remove) return;\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 // ── Render ─────────────────────────────────────────────────────────\n\n private _renderMenuIcon() {\n return html`\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\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 private _renderMenuDropdown(memberId: string) {\n const participant = this._getParticipant(memberId);\n const isOpen = this._openMenuId === memberId;\n\n return html`\n <div\n class=\"menu-dropdown ${isOpen ? 'open' : ''}\"\n role=\"menu\"\n aria-label=\"Participant actions\"\n >\n <button\n class=\"menu-item\"\n role=\"menuitem\"\n @click=${(e: Event) => this._handleMuteAudio(memberId, e)}\n aria-label=\"${participant?.audioMuted ? 'Unmute audio' : 'Mute audio'}\"\n >\n ${participant?.audioMuted ? 'Unmute' : 'Mute'}\n </button>\n <button\n class=\"menu-item\"\n role=\"menuitem\"\n @click=${(e: Event) => this._handleMuteVideo(memberId, e)}\n aria-label=\"${participant?.videoMuted ? 'Enable video' : 'Disable video'}\"\n >\n ${participant?.videoMuted ? 'Enable video' : 'Disable video'}\n </button>\n <button\n class=\"menu-item danger\"\n role=\"menuitem\"\n @click=${(e: Event) => this._handleRemove(memberId, e)}\n aria-label=\"Remove participant\"\n >\n Remove\n </button>\n </div>\n `;\n }\n\n private _renderOverlay(layer: LayoutLayer, isSelf: boolean) {\n const memberId = layer.member_id!;\n const classes = `member-overlay${isSelf ? ' is-self' : ''}`;\n\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 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 <slot name=\"controls-${memberId}\"></slot>\n </div>\n `;\n }\n\n render() {\n const layers = this.call ? this._directLayoutLayers : this._callState?.layoutLayers ?? [];\n const selfId = this.call ? this._directSelf?.id : this._callState?.self?.id;\n\n const overlays = layers\n .filter((layer) => layer.member_id)\n .map((layer) => this._renderOverlay(layer, layer.member_id === selfId));\n\n return html`\n ${overlays}\n <slot></slot>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'sw-participants': SwParticipants;\n }\n}\n"],"names":["SwParticipants","LitElement","target","changed","l","p","s","memberId","e","_a","participant","html","isOpen","layer","isSelf","classes","style","layers","selfId","_b","_d","_c","overlays","hostReset","css","__decorateClass","consume","callStateContext","state","property","customElement"],"mappings":"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"}
|