UNPKG

media-chrome

Version:

Custom elements (web components) for making audio and video player controls that look great in your website or app.

110 lines (93 loc) 3.27 kB
/* <media-control-bar> Auto position contorls in a line and set some base colors */ import { MediaStateReceiverAttributes } from './constants.js'; import type MediaController from './media-controller.js'; import { document, globalThis } from './utils/server-safe-globals.js'; const template: HTMLTemplateElement = document.createElement('template'); template.innerHTML = /*html*/ ` <style> :host { ${/* Need position to display above video for some reason */ ''} box-sizing: border-box; display: var(--media-control-display, var(--media-control-bar-display, inline-flex)); color: var(--media-text-color, var(--media-primary-color, rgb(238 238 238))); --media-loading-indicator-icon-height: 44px; } ::slotted(media-time-range), ::slotted(media-volume-range) { min-height: 100%; } ::slotted(media-time-range), ::slotted(media-clip-selector) { flex-grow: 1; } ::slotted([role="menu"]) { position: absolute; } </style> <slot></slot> `; /** * @attr {string} mediacontroller - The element `id` of the media controller to connect to (if not nested within). * * @cssproperty --media-primary-color - Default color of text and icon. * @cssproperty --media-secondary-color - Default color of button background. * @cssproperty --media-text-color - `color` of button text. * * @cssproperty --media-control-bar-display - `display` property of control bar. * @cssproperty --media-control-display - `display` property of control. */ class MediaControlBar extends globalThis.HTMLElement { #mediaController: MediaController | null; static get observedAttributes(): string[] { return [MediaStateReceiverAttributes.MEDIA_CONTROLLER]; } constructor() { super(); if (!this.shadowRoot) { // Set up the Shadow DOM if not using Declarative Shadow DOM. this.attachShadow({ mode: 'open' }); this.shadowRoot.appendChild(template.content.cloneNode(true)); } } attributeChangedCallback( attrName: string, oldValue: string | null, newValue: string | null ): void { if (attrName === MediaStateReceiverAttributes.MEDIA_CONTROLLER) { if (oldValue) { this.#mediaController?.unassociateElement?.(this); this.#mediaController = null; } if (newValue && this.isConnected) { // @ts-ignore this.#mediaController = this.getRootNode()?.getElementById(newValue); this.#mediaController?.associateElement?.(this); } } } connectedCallback(): void { const mediaControllerId = this.getAttribute( MediaStateReceiverAttributes.MEDIA_CONTROLLER ); if (mediaControllerId) { // @ts-ignore this.#mediaController = (this.getRootNode() as Document)?.getElementById( mediaControllerId ); this.#mediaController?.associateElement?.(this); } } disconnectedCallback(): void { // Use cached mediaController, getRootNode() doesn't work if disconnected. this.#mediaController?.unassociateElement?.(this); this.#mediaController = null; } } if (!globalThis.customElements.get('media-control-bar')) { globalThis.customElements.define('media-control-bar', MediaControlBar); } export default MediaControlBar;