Files
v10/packages/react/skins.compiler.config.ts
T

88 lines
2.9 KiB
TypeScript

import { defineConfig, transform } from '@videojs/compiler';
import { tailwind } from '@videojs/compiler/tailwind';
const CORE_COMPONENTS_SOURCE = '@videojs/core/components';
const ICON_COMPONENTS_SOURCE = '@videojs/icons/components';
const SOURCE_TAILWIND_SOURCE = './tailwind/video.tailwind';
const GENERATED_TAILWIND_SOURCE = '@videojs/skins/default/tailwind/video.tailwind';
export default defineConfig({
input: {
'default-video': '../skins/src/default/video.skin.tsx',
},
output: {
dir: 'src/presets/video',
entryFileNames: '[name].generated.tailwind.tsx',
banner: '// Generated by @videojs/compiler. Do not edit.\n',
},
plugins: [
transform((code) => {
// Types
const BaseVideoSkinProps = code.import('./src/presets/types', 'BaseVideoSkinProps', { type: true });
const ReactNode = code.import('react', 'ReactNode', { type: true });
// Utils
const cn = code.import('@videojs/utils/style', 'cn');
const isString = code.import('@videojs/utils/predicate', 'isString');
const isRenderProp = code.import('@/utils/use-render', 'isRenderProp');
// Components
const Poster = code.import('@/ui/poster', 'Poster');
return [
code.imports({
[CORE_COMPONENTS_SOURCE]: coreComponentImport,
[ICON_COMPONENTS_SOURCE]: '@/icons',
[SOURCE_TAILWIND_SOURCE]: GENERATED_TAILWIND_SOURCE,
}),
tailwind({ mode: 'preserve' }),
code
.interface(/Props$/)
.property('children')
.setType(() => code.type.union(code.type.named(ReactNode), code.type.undefined())),
code.interface('DefaultVideoSkinProps').extends(BaseVideoSkinProps),
code.jsx.element(/^(Tooltip|Popover)\.Trigger$/).childToProp('render'),
code.jsx.element('Controls.Root').addProp('data-controls', ''),
code.jsx.element('Container').spreadProps('rest'),
code.jsx.element('Text').replace('span'),
code.jsx.element('Poster').replace(() =>
code.jsx.if(
'poster',
code.jsx.create(Poster, {
src: code.value.when('poster', isString),
render: code.value.when('poster', isRenderProp),
})
)
),
code.jsx
.props('className')
.where(code.value.isArray())
.replace(({ value }) => code.value.call(cn, code.value.arrayItems(value))),
code.function('DefaultVideoSkin').addProps(['poster', { name: 'rest', spread: true }]),
];
}),
],
});
function coreComponentImport(name: string): { source: string; name: string } {
return {
source: name === 'Container' ? '@/player/context' : `@/ui/${componentModuleName(name)}`,
name,
};
}
function componentModuleName(name: string): string {
return name
.replace(/^AirPlay/, 'Airplay')
.replace(/^PiP/, 'Pip')
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
.toLowerCase();
}