/** * PXM Video Component * * A logic-only, highly flexible custom element for embedding videos from YouTube, Vimeo, Mux, MP4, and more. * * Bring your own styling and animation: This component provides structure and behavior only—all styling is controlled by your CSS. * * Features: * - Supports YouTube, Vimeo, Mux, MP4, and custom sources * - Automatic or custom thumbnail support * - Dual-attribute pattern: ARIA for accessibility, data- attributes for styling/JS * - Full keyboard navigation (Enter, Space, etc.) * - Public API for play, pause, mute, seek, fullscreen, etc. * - Event-driven animation system (all state changes fire pxm:video:* events) * - Dynamic content support (MutationObserver) * - Graceful error handling and fallbacks * * Keyboard Navigation: * - `Enter` or `Space` on thumbnail: Play video * - `Tab`/`Shift+Tab`: Move focus * - All video controls are accessible via keyboard (native or custom) * * Basic Usage: * ```html * * ``` * * With Custom Thumbnail: * ```html * *
* Custom thumbnail * *
*
* ``` * * Consumer Styling Examples: * ```css * pxm-video[data-state="playing"] { /* Your styles for playing state *\/ } * pxm-video[data-disabled="true"] { opacity: 0.5; } * pxm-video [data-thumbnail] { cursor: pointer; } * /* Use data- attributes for all styling hooks *\/ * ``` * * Events: * - `pxm:video:before-play` (cancelable) * - `pxm:video:play` * - `pxm:video:pause` * - `pxm:video:mute` * - `pxm:video:unmute` * - `pxm:video:seek` * - `pxm:video:fullscreen` * - `pxm:video:error` * * Accessibility: * - Manages essential ARIA attributes: aria-pressed, aria-disabled, aria-label, etc. * - Sets data- attributes for all state (data-state, data-disabled, etc.) * - Consumer is responsible for roles, labels, and additional ARIA as needed * * SSR / Hydration Support: * - No Shadow DOM, so SSR is seamless * - Initial state is read from DOM attributes * * Public API: * - play(), pause(), mute(), unmute(), seek(time), enterFullscreen(), exitFullscreen() * * Dynamic Content: * - Observes for changes to child nodes (MutationObserver) * * Error Handling: * - All operations wrapped in error boundaries * - Graceful fallbacks for unsupported sources or errors * * @element pxm-video * @export PxmVideo */ /** * Video component configuration interface */ export interface VideoConfig { src: string; type: 'youtube' | 'vimeo' | 'mux' | 'mp4' | 'other'; thumbnail?: string; autoplay?: boolean; muted?: boolean; controls?: boolean; width?: string | number; height?: string | number; title?: string; description?: string; } /** * Video component options interface */ export interface VideoOptions { autoplay?: boolean; muted?: boolean; controls?: boolean; width?: string | number; height?: string | number; } /** * Video component state interface */ export interface VideoState { isPlaying: boolean; isLoaded: boolean; error?: string; } /** * Video source type definition */ export type VideoSource = { url: string; type: VideoConfig['type']; }; export interface PxmVideoAPI { play(): void; pause(): void; mute(): void; unmute(): void; seek(time: number): void; enterFullscreen(): void; exitFullscreen(): void; } /** * Custom video element that supports multiple video sources including YouTube, Vimeo, Mux, and MP4 * Provides thumbnail generation and lazy loading capabilities */ export declare class PxmVideo extends HTMLElement implements PxmVideoAPI { private config; private state; private videoElement; private iframeElement; private thumbnailElement; /** * Observed attributes for the custom element */ static get observedAttributes(): string[]; constructor(); /** * Called when the element is added to the DOM */ connectedCallback(): void; /** * Called when an observed attribute changes */ attributeChangedCallback(name: string, oldValue: string, newValue: string): void; /** * Called when the element is removed from the DOM */ disconnectedCallback(): void; /** * Gets the default configuration for the video component */ private getDefaultConfig; /** * Updates the configuration based on attribute changes */ private updateConfigFromAttribute; /** * Initializes configuration from HTML attributes */ private initializeFromAttributes; /** * Initializes from existing DOM content */ private initializeFromContent; /** * Ensures keyboard navigation is supported for the thumbnail. * Enter/Space on thumbnail plays the video. tabindex is set for accessibility. */ private setupThumbnailElement; /** * Initializes the video component */ private init; /** * Replaces the placeholder image in auto thumbnail mode with the actual video thumbnail */ private replaceAutoThumbnail; /** * Generates a thumbnail from an MP4 video and updates an existing img element */ private generateMP4ThumbnailForElement; /** * Clears existing content from the component */ private clearContent; /** * Generates a thumbnail based on the video source type */ private generateThumbnail; /** * Parses the video source URL to determine its type */ private parseVideoSource; /** * Generates a YouTube thumbnail */ private generateYouTubeThumbnail; /** * Generates a Vimeo thumbnail using their API */ private generateVimeoThumbnail; /** * Generates a Mux thumbnail (currently creates default thumbnail) * TODO: Implement Mux thumbnail generation when API is available */ private generateMuxThumbnail; /** * Generates a thumbnail from an MP4 video by capturing a frame */ private generateMP4Thumbnail; /** * Creates a default thumbnail when other methods fail */ private createDefaultThumbnail; /** * Creates a thumbnail container with common styles and attributes */ private createThumbnailContainer; /** * Appends a thumbnail to the component and sets up event listeners */ private appendThumbnail; /** * Plays the video by removing the thumbnail and creating the appropriate player */ private playVideo; private createAndAnimateVideo; /** * Removes the thumbnail element */ private removeThumbnail; /** * Creates a YouTube player iframe */ private createYouTubePlayer; /** * Creates a Vimeo player iframe */ private createVimeoPlayer; /** * Creates a Mux player (currently delegates to standard video player) */ private createMuxPlayer; /** * Creates a standard HTML5 video player */ private createVideoPlayer; /** * Creates an iframe element with common attributes */ private createIframe; /** * Creates a wrapper for video players with responsive styling */ private createPlayerWrapper; /** * Extracts YouTube video ID from various URL formats */ private extractYouTubeId; /** * Extracts Vimeo video ID from URL */ private extractVimeoId; /** * Handles errors by logging and optionally displaying to user */ private handleError; /** * Cleans up video element resources */ private cleanupVideoElement; /** * Cleans up all component resources */ private cleanup; /** * Updates ARIA and data- attributes for all stateful properties * * Managed ARIA attributes: * - aria-pressed: reflects playing state * - aria-expanded: reflects whether video is playing (expanded) * - aria-label: reflects play/pause/muted state * * Consumer is responsible for roles, labels, and additional ARIA as needed. */ private updateState; /** * Play the video. Fires pxm:video:before-play (cancelable) and pxm:video:play events. * Wrapped in error boundary for graceful error handling. */ play(): void; /** * Pause the video. Fires pxm:video:before-pause (cancelable) and pxm:video:pause events. * Wrapped in error boundary for graceful error handling. */ pause(): void; /** * Mute the video. Fires pxm:video:before-mute (cancelable) and pxm:video:mute events. * Wrapped in error boundary for graceful error handling. */ mute(): void; /** * Unmute the video. Fires pxm:video:before-unmute (cancelable) and pxm:video:unmute events. * Wrapped in error boundary for graceful error handling. */ unmute(): void; /** * Seek to a specific time. Fires pxm:video:before-seek (cancelable) and pxm:video:seek events. * Wrapped in error boundary for graceful error handling. */ seek(time: number): void; /** * Enter fullscreen. Fires pxm:video:before-fullscreen (cancelable) and pxm:video:fullscreen events. * Wrapped in error boundary for graceful error handling. */ enterFullscreen(): void; /** * Exit fullscreen. Fires pxm:video:before-exit-fullscreen (cancelable) and pxm:video:exit-fullscreen events. * Wrapped in error boundary for graceful error handling. */ exitFullscreen(): void; /** * Dispatches a pxm:video:error event with error details */ private dispatchError; }