UNPKG

media-chrome

Version:

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

127 lines (107 loc) 3.58 kB
import { MediaChromeButton } from './media-chrome-button.js'; import { globalThis, document } from './utils/server-safe-globals.js'; import { MediaUIEvents, MediaUIAttributes } from './constants.js'; import { getNumericAttr, setNumericAttr } from './utils/element-utils.js'; import { t } from './utils/i18n.js'; import { getSlotted, updateIconText } from './utils/element-utils.js'; export const Attributes = { SEEK_OFFSET: 'seekoffset', }; const DEFAULT_SEEK_OFFSET = 30; const forwardIcon = `<svg aria-hidden="true" viewBox="0 0 20 24"><defs><style>.text{font-size:8px;font-family:Arial-BoldMT, Arial;font-weight:700;}</style></defs><text class="text value" transform="translate(8.9 19.87)">${DEFAULT_SEEK_OFFSET}</text><path d="M10 6V3l5.61 4L10 10.94V8a5.54 5.54 0 0 0-1.9 10.48v2.12A7.5 7.5 0 0 1 10 6Z"/></svg>`; const slotTemplate: HTMLTemplateElement = document.createElement('template'); slotTemplate.innerHTML = ` <slot name="icon">${forwardIcon}</slot> `; const DEFAULT_TIME = 0; /** * @slot icon - The element shown for the seek forward button’s display. * * @attr {string} seekoffset - Adjusts how much time (in seconds) the playhead should seek forward. * @attr {string} mediacurrenttime - (read-only) Set to the current media time. * * @cssproperty [--media-seek-forward-button-display = inline-flex] - `display` property of button. */ class MediaSeekForwardButton extends MediaChromeButton { static get observedAttributes(): string[] { return [ ...super.observedAttributes, MediaUIAttributes.MEDIA_CURRENT_TIME, Attributes.SEEK_OFFSET, ]; } constructor(options = {}) { super({ slotTemplate, tooltipContent: t('Seek forward'), ...options, }); } connectedCallback(): void { this.seekOffset = getNumericAttr( this, Attributes.SEEK_OFFSET, DEFAULT_SEEK_OFFSET ); super.connectedCallback(); } attributeChangedCallback( attrName: string, _oldValue: string | null, newValue: string | null ): void { if (attrName === Attributes.SEEK_OFFSET) { this.seekOffset = getNumericAttr( this, Attributes.SEEK_OFFSET, DEFAULT_SEEK_OFFSET ); } super.attributeChangedCallback(attrName, _oldValue, newValue); } // Own props /** * Seek amount in seconds */ get seekOffset(): number { return getNumericAttr(this, Attributes.SEEK_OFFSET, DEFAULT_SEEK_OFFSET); } set seekOffset(value: number) { setNumericAttr(this, Attributes.SEEK_OFFSET, value); this.setAttribute( 'aria-label', t('seek forward {seekOffset} seconds', { seekOffset: this.seekOffset }) ); updateIconText(getSlotted(this, 'icon'), this.seekOffset as any); } // Props derived from Media UI Attributes /** * The current time in seconds */ get mediaCurrentTime(): number { return getNumericAttr( this, MediaUIAttributes.MEDIA_CURRENT_TIME, DEFAULT_TIME ); } set mediaCurrentTime(time: number) { setNumericAttr(this, MediaUIAttributes.MEDIA_CURRENT_TIME, time); } handleClick(): void { const detail = this.mediaCurrentTime + this.seekOffset; const evt = new globalThis.CustomEvent(MediaUIEvents.MEDIA_SEEK_REQUEST, { composed: true, bubbles: true, detail, }); this.dispatchEvent(evt); } } if (!globalThis.customElements.get('media-seek-forward-button')) { globalThis.customElements.define( 'media-seek-forward-button', MediaSeekForwardButton ); } export default MediaSeekForwardButton;