diff --git a/packages/react/skins.compiler.config.ts b/packages/react/skins.compiler.config.ts index 4cdd422a..7bc14277 100644 --- a/packages/react/skins.compiler.config.ts +++ b/packages/react/skins.compiler.config.ts @@ -2,16 +2,19 @@ import { type CompilerPlugin, defineConfig, transform } from '@videojs/compiler' import { tailwind } from '@videojs/compiler/tailwind'; import { kebabCase } from '@videojs/utils/string'; -const CORE_COMPONENTS_SOURCE = '@videojs/core/components'; -const ICON_COMPONENTS_SOURCE = '@videojs/icons/components'; +const SOURCE_CORE = '@videojs/core/components'; +const SOURCE_ICONS = '@videojs/icons/components'; + const SOURCE_TAILWIND_CSS = '../skins/src/default/video.tailwind.css'; const SOURCE_ANIMATIONS_CSS = '../skins/src/shared/animations.css'; const SOURCE_REGISTERED_PROPERTIES_CSS = '../skins/src/shared/registered-properties.css'; const SOURCE_SHARED_VARIABLES_CSS = '../skins/src/shared/variables.css'; const SOURCE_DEFAULT_VIDEO_CSS = '../skins/src/default/video.css'; + const INPUT = { 'default-video': '../skins/src/default/video.skin.tsx', }; + const GENERATED_DIR = 'src/presets/video/__generated__'; const GENERATED_BANNER = '// Generated by @videojs/compiler. Do not edit.\n'; @@ -41,11 +44,11 @@ export default defineConfig({ }, resolve: { element(context) { - const className = mediaClassName(context.tag, context.tokenName ?? context.defaultName); + const className = resolveMediaClassName(context.tag, context.tokenName ?? context.defaultName); return { className, - chunk: mediaChunk(className), + chunk: resolveMediaChunk(className), }; }, classList({ className, classes }) { @@ -53,11 +56,11 @@ export default defineConfig({ }, }, }), - reactSkinTransform(), + react(), ], }); -function reactSkinTransform(): CompilerPlugin { +function react(): CompilerPlugin { return transform((code) => { // Types const BaseVideoSkinProps = code.import('./src/presets/types', 'BaseVideoSkinProps', { type: true }); @@ -73,8 +76,8 @@ function reactSkinTransform(): CompilerPlugin { return [ code.imports({ - [CORE_COMPONENTS_SOURCE]: resolveComponentImport, - [ICON_COMPONENTS_SOURCE]: '@/icons', + [SOURCE_CORE]: resolveComponentImport, + [SOURCE_ICONS]: '@/icons', }), code @@ -121,13 +124,14 @@ function resolveComponentImportPath(name: string): string { return kebabCase(id).replace(/^-/, ''); } -function mediaClassName(tag: string, defaultName: string): string { +function resolveMediaClassName(tag: string, defaultName: string): string { const tokenName = normalizeTokenName(defaultName); if (tag === 'Container') return 'media-root'; if (/Button$/.test(tag)) return 'media-button'; if (tag === 'ErrorDialog.Close') return 'media-error-close'; - return prefixedDefaultName(tokenName); + + return getPrefixedDefaultName(tokenName); } function normalizeTokenName(name: string): string { @@ -143,15 +147,21 @@ function stripRootSuffix(name: string): string { return name.endsWith('-root') ? name.slice(0, -'-root'.length) : name; } -function mediaChunk(className: string): string { - if (matchesClass(className, 'media-tooltip', 'media-popover', 'media-volume-popover')) return 'popup'; - if (matchesClass(className, 'media-error')) return 'dialog'; - if (matchesClass(className, 'media-buffering')) return 'loading'; - if (matchesClass(className, 'media-controls')) return 'controls'; - if (matchesClass(className, 'media-time')) return 'time'; - if (matchesClass(className, 'media-slider', 'media-spinner')) return 'slider'; +function resolveMediaChunk(className: string): string { + if (matchesPrefix(className, 'media-tooltip', 'media-popover', 'media-volume-popover')) return 'popup'; + + if (matchesPrefix(className, 'media-error')) return 'dialog'; + + if (matchesPrefix(className, 'media-buffering')) return 'loading'; + + if (matchesPrefix(className, 'media-controls')) return 'controls'; + + if (matchesPrefix(className, 'media-time')) return 'time'; + + if (matchesPrefix(className, 'media-slider', 'media-spinner')) return 'slider'; + if ( - matchesClass( + matchesPrefix( className, 'media-indicator', 'media-volume-indicator', @@ -161,28 +171,38 @@ function mediaChunk(className: string): string { ) { return 'feedback'; } - if (matchesClass(className, 'media-button', 'media-seek-label')) return 'button'; + + if (matchesPrefix(className, 'media-button', 'media-seek-label')) return 'button'; + if (className.endsWith('-icon') && className !== 'media-spinner') return 'button'; + return 'base'; } function sharedClassNames(className: string): string[] { - if (matchesClass(className, 'media-controls-group-start', 'media-controls-group-end')) + if (matchesPrefix(className, 'media-controls-group-start', 'media-controls-group-end')) { return ['media-controls-group']; + } + if (className === 'media-slider-thumb-persistent') return ['media-slider-thumb']; - if (matchesClass(className, 'media-status-indicator-top', 'media-status-indicator-center')) { + + if (matchesPrefix(className, 'media-status-indicator-top', 'media-status-indicator-center')) { return ['media-status-indicator']; } - if (matchesClass(className, 'media-seek-label-backward', 'media-seek-label-forward')) return ['media-seek-label']; + + if (matchesPrefix(className, 'media-seek-label-backward', 'media-seek-label-forward')) return ['media-seek-label']; + if (className === 'media-error-close') return ['media-button']; + if (className === 'media-volume-popover') return ['media-popover']; + return []; } -function prefixedDefaultName(name: string): string { +function getPrefixedDefaultName(name: string): string { return name.startsWith('media-') ? name : `media-${name}`; } -function matchesClass(className: string, ...prefixes: string[]): boolean { +function matchesPrefix(className: string, ...prefixes: string[]): boolean { return prefixes.some((prefix) => className === prefix || className.startsWith(`${prefix}-`)); }