diff --git a/packages/html/src/define/audio/minimal-skin.tailwind.ts b/packages/html/src/define/audio/minimal-skin.tailwind.ts index 42ba24da..6fd15cc2 100644 --- a/packages/html/src/define/audio/minimal-skin.tailwind.ts +++ b/packages/html/src/define/audio/minimal-skin.tailwind.ts @@ -1,4 +1,3 @@ -import { ReactiveElement } from '@videojs/element'; import { renderIcon } from '@videojs/icons/render/minimal'; import { playbackRate } from '@videojs/skins/default/tailwind/audio.tailwind'; import { @@ -17,9 +16,10 @@ import { time, tooltipState, } from '@videojs/skins/minimal/tailwind/audio.tailwind'; +import { createTemplate } from '@videojs/utils/dom'; import { cn } from '@videojs/utils/style'; import { safeDefine } from '../safe-define'; -import { SkinMixin } from '../skin-mixin'; +import { SkinElement } from '../skin-element'; // Side-effect imports: register all custom elements used in the template. import '../media/container'; @@ -137,9 +137,9 @@ function getTemplateHTML() { `; } -export class MinimalAudioSkinTailwindElement extends SkinMixin(ReactiveElement) { +export class MinimalAudioSkinTailwindElement extends SkinElement { static readonly tagName = 'audio-minimal-skin-tailwind'; - static getTemplateHTML = getTemplateHTML; + static template = createTemplate(getTemplateHTML()); } safeDefine(MinimalAudioSkinTailwindElement); diff --git a/packages/html/src/define/audio/minimal-skin.ts b/packages/html/src/define/audio/minimal-skin.ts index 1cef15b3..24540a9c 100644 --- a/packages/html/src/define/audio/minimal-skin.ts +++ b/packages/html/src/define/audio/minimal-skin.ts @@ -1,7 +1,7 @@ -import { ReactiveElement } from '@videojs/element'; import { renderIcon } from '@videojs/icons/render/minimal'; +import { createShadowStyle, createTemplate } from '@videojs/utils/dom'; import { safeDefine } from '../safe-define'; -import { createStyles, SkinMixin } from '../skin-mixin'; +import { SkinElement } from '../skin-element'; import styles from './minimal-skin.css?inline'; // Side-effect imports: register all custom elements used in the template. @@ -118,10 +118,10 @@ function getTemplateHTML() { `; } -export class MinimalAudioSkinElement extends SkinMixin(ReactiveElement) { +export class MinimalAudioSkinElement extends SkinElement { static readonly tagName = 'audio-minimal-skin'; - static styles = createStyles(styles); - static getTemplateHTML = getTemplateHTML; + static styles = createShadowStyle(styles); + static template = createTemplate(getTemplateHTML()); } safeDefine(MinimalAudioSkinElement); diff --git a/packages/html/src/define/audio/skin.tailwind.ts b/packages/html/src/define/audio/skin.tailwind.ts index 4e90fe52..177c8fb3 100644 --- a/packages/html/src/define/audio/skin.tailwind.ts +++ b/packages/html/src/define/audio/skin.tailwind.ts @@ -1,4 +1,3 @@ -import { ReactiveElement } from '@videojs/element'; import { renderIcon } from '@videojs/icons/render'; import { button, @@ -17,9 +16,10 @@ import { time, tooltipState, } from '@videojs/skins/default/tailwind/audio.tailwind'; +import { createTemplate } from '@videojs/utils/dom'; import { cn } from '@videojs/utils/style'; import { safeDefine } from '../safe-define'; -import { SkinMixin } from '../skin-mixin'; +import { SkinElement } from '../skin-element'; // Side-effect imports: register all custom elements used in the template. import '../media/container'; @@ -132,9 +132,9 @@ function getTemplateHTML() { `; } -export class AudioSkinTailwindElement extends SkinMixin(ReactiveElement) { +export class AudioSkinTailwindElement extends SkinElement { static readonly tagName = 'audio-skin-tailwind'; - static getTemplateHTML = getTemplateHTML; + static template = createTemplate(getTemplateHTML()); } safeDefine(AudioSkinTailwindElement); diff --git a/packages/html/src/define/audio/skin.ts b/packages/html/src/define/audio/skin.ts index 7af08ed7..0de80f85 100644 --- a/packages/html/src/define/audio/skin.ts +++ b/packages/html/src/define/audio/skin.ts @@ -1,7 +1,7 @@ -import { ReactiveElement } from '@videojs/element'; import { renderIcon } from '@videojs/icons/render'; +import { createShadowStyle, createTemplate } from '@videojs/utils/dom'; import { safeDefine } from '../safe-define'; -import { createStyles, SkinMixin } from '../skin-mixin'; +import { SkinElement } from '../skin-element'; import styles from './skin.css?inline'; // Side-effect imports: register all custom elements used in the template. @@ -113,10 +113,10 @@ function getTemplateHTML() { `; } -export class AudioSkinElement extends SkinMixin(ReactiveElement) { +export class AudioSkinElement extends SkinElement { static readonly tagName = 'audio-skin'; - static styles = createStyles(styles); - static getTemplateHTML = getTemplateHTML; + static styles = createShadowStyle(styles); + static template = createTemplate(getTemplateHTML()); } safeDefine(AudioSkinElement); diff --git a/packages/html/src/define/background/skin.ts b/packages/html/src/define/background/skin.ts index 9c2a4ebf..739397d9 100644 --- a/packages/html/src/define/background/skin.ts +++ b/packages/html/src/define/background/skin.ts @@ -1,18 +1,10 @@ import { ReactiveElement } from '@videojs/element'; -import { namedNodeMapToObject } from '@videojs/utils/dom'; +import { ensureGlobalStyle, namedNodeMapToObject } from '@videojs/utils/dom'; import { safeDefine } from '../safe-define'; import styles from './skin.css?inline'; const STYLES_ID = '__media-background-styles'; -function ensureBackgroundStyles(): void { - if (document.getElementById(STYLES_ID)) return; - const style = document.createElement('style'); - style.id = STYLES_ID; - style.textContent = styles; - document.head.appendChild(style); -} - function getTemplateHTML(_attrs: Record) { return /*html*/ ` @@ -31,7 +23,7 @@ export class BackgroundVideoSkinElement extends ReactiveElement { constructor() { super(); - ensureBackgroundStyles(); + ensureGlobalStyle(STYLES_ID, styles); if (!this.shadowRoot) { this.attachShadow((this.constructor as typeof BackgroundVideoSkinElement).shadowRootOptions); diff --git a/packages/html/src/define/skin-element.ts b/packages/html/src/define/skin-element.ts new file mode 100644 index 00000000..13e17591 --- /dev/null +++ b/packages/html/src/define/skin-element.ts @@ -0,0 +1,45 @@ +import { ReactiveElement } from '@videojs/element'; +import { + applyShadowStyles, + createShadowStyle, + ensureGlobalStyle, + renderTemplate, + type ShadowStyle, +} from '@videojs/utils/dom'; +import rootStyles from './base.css?inline'; +import sharedStyles from './shared.css?inline'; + +const STYLES_ID = '__media-styles'; +const sharedSheet = createShadowStyle(sharedStyles); + +/** + * Base element for skin definitions. Attaches a shadow root, clones + * `static template` into it, and applies shared + per-skin styles + * via `adoptedStyleSheets` (or `