mirror of
https://github.com/zoriya/v10.git
synced 2026-08-08 07:07:10 +00:00
110 lines
4.1 KiB
TypeScript
110 lines
4.1 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';
|
|
|
|
const BUTTON_RENDER_TARGET = /Button$/;
|
|
|
|
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.ref.import('./src/presets/types', 'BaseVideoSkinProps', { type: true });
|
|
const ReactNode = code.ref.import('react', 'ReactNode', { type: true });
|
|
|
|
// Utils
|
|
const cn = code.ref.import('@videojs/utils/style', 'cn');
|
|
const isString = code.ref.import('@videojs/utils/predicate', 'isString');
|
|
const isRenderProp = code.ref.import('@/utils/use-render', 'isRenderProp');
|
|
|
|
// Components
|
|
const Poster = code.ref.import('@/ui/poster', 'Poster');
|
|
|
|
return [
|
|
code.edit.import.rewrite({
|
|
[CORE_COMPONENTS_SOURCE]: coreComponentImport,
|
|
[ICON_COMPONENTS_SOURCE]: '@/icons',
|
|
[SOURCE_TAILWIND_SOURCE]: GENERATED_TAILWIND_SOURCE,
|
|
}),
|
|
tailwind({ mode: 'preserve' }),
|
|
code.edit.jsx.element({
|
|
when: code.match.jsx.tag('Tooltip.Trigger'),
|
|
transform: code.edit.jsx.moveChildToProp('render'),
|
|
}),
|
|
code.edit.jsx.element({
|
|
when: code.match.jsx.tag('Controls.Root'),
|
|
transform: code.edit.jsx.addProp('data-controls', ''),
|
|
}),
|
|
code.edit.jsx.element({
|
|
when: code.match.jsx.tag('Container'),
|
|
transform: code.edit.jsx.addPropsSpread('rest'),
|
|
}),
|
|
code.edit.jsx.element({
|
|
when: code.match.jsx.tag('Text'),
|
|
transform: code.edit.jsx.replaceTag('span'),
|
|
}),
|
|
code.edit.jsx.element({
|
|
when: code.match.jsx.tag('Poster'),
|
|
transform: () => {
|
|
return code.create.jsx.renderIf(
|
|
'poster',
|
|
code.create.jsx.element(Poster, {
|
|
src: code.create.value.onlyIf({ value: 'poster', condition: isString }),
|
|
render: code.create.value.onlyIf({ value: 'poster', condition: isRenderProp }),
|
|
})
|
|
);
|
|
},
|
|
}),
|
|
code.edit.jsx.element({
|
|
when: code.match.jsx.tag(BUTTON_RENDER_TARGET),
|
|
transform: code.edit.jsx.addProp('type', 'button'),
|
|
}),
|
|
code.edit.jsx.prop({
|
|
when: code.match.all(code.match.jsx.prop('className'), code.match.value.array()),
|
|
transform: ({ value }) => code.create.value.call(cn, code.create.value.arrayItems(value)),
|
|
}),
|
|
code.edit.interface.property({
|
|
when: code.match.all(code.match.interface.name(/Props$/), code.match.interface.property('children')),
|
|
transform: code.edit.interface.setType(() =>
|
|
code.create.type.union(code.create.type.named(ReactNode), code.create.type.undefined())
|
|
),
|
|
}),
|
|
code.edit.interface.declaration({
|
|
when: code.match.interface.name('DefaultVideoSkinProps'),
|
|
transform: code.edit.interface.extends(BaseVideoSkinProps),
|
|
}),
|
|
code.edit.function.declaration({
|
|
when: code.match.function.name('DefaultVideoSkin'),
|
|
transform: code.edit.function.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();
|
|
}
|