refactor(react): clean up skin compiler config

This commit is contained in:
Rahim
2026-07-13 14:11:36 -07:00
parent 5c8af139f1
commit b44e532c79
+44 -24
View File
@@ -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}-`));
}