mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
feat(site): replace home page tech preview player with real player (#580)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
410fc01350
commit
f623e676f2
Generated
-6
@@ -499,15 +499,9 @@ importers:
|
|||||||
'@videojs/html':
|
'@videojs/html':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../packages/html
|
version: link:../packages/html
|
||||||
'@videojs/html-preview':
|
|
||||||
specifier: workspace:*
|
|
||||||
version: link:../packages/__tech-preview__/html
|
|
||||||
'@videojs/react':
|
'@videojs/react':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../packages/react
|
version: link:../packages/react
|
||||||
'@videojs/react-preview':
|
|
||||||
specifier: workspace:*
|
|
||||||
version: link:../packages/__tech-preview__/react
|
|
||||||
astro:
|
astro:
|
||||||
specifier: ^5.14.4
|
specifier: ^5.14.4
|
||||||
version: 5.16.5(@netlify/blobs@10.5.0)(@types/node@22.19.3)(@vercel/functions@2.2.13)(jiti@2.6.1)(lightningcss@1.31.1)(rollup@4.53.3)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2)
|
version: 5.16.5(@netlify/blobs@10.5.0)(@types/node@22.19.3)(@vercel/functions@2.2.13)(jiti@2.6.1)(lightningcss@1.31.1)(rollup@4.53.3)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2)
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ export default defineConfig({
|
|||||||
vite: {
|
vite: {
|
||||||
plugins: [tailwindcss()],
|
plugins: [tailwindcss()],
|
||||||
optimizeDeps: {
|
optimizeDeps: {
|
||||||
exclude: ['@videojs/react-preview', '@videojs/react', '@videojs/html'],
|
exclude: ['@videojs/react', '@videojs/html'],
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
dedupe: ['react', 'react-dom'],
|
dedupe: ['react', 'react-dom'],
|
||||||
|
|||||||
@@ -28,9 +28,7 @@
|
|||||||
"@sentry/astro": "^10.32.1",
|
"@sentry/astro": "^10.32.1",
|
||||||
"@tailwindcss/vite": "^4.2.0",
|
"@tailwindcss/vite": "^4.2.0",
|
||||||
"@videojs/html": "workspace:*",
|
"@videojs/html": "workspace:*",
|
||||||
"@videojs/html-preview": "workspace:*",
|
|
||||||
"@videojs/react": "workspace:*",
|
"@videojs/react": "workspace:*",
|
||||||
"@videojs/react-preview": "workspace:*",
|
|
||||||
"astro": "^5.14.4",
|
"astro": "^5.14.4",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"es-toolkit": "^1.32.0",
|
"es-toolkit": "^1.32.0",
|
||||||
|
|||||||
@@ -5,37 +5,42 @@ import { framework, skin } from '@/stores/homePageDemos';
|
|||||||
import ClientCode from '../Code/ClientCode';
|
import ClientCode from '../Code/ClientCode';
|
||||||
|
|
||||||
function generateHTMLCode(skin: Skin): string {
|
function generateHTMLCode(skin: Skin): string {
|
||||||
const skinTag = `${skin}-skin`;
|
const skinTag = skin === 'frosted' ? 'video-skin' : 'video-minimal-skin';
|
||||||
|
const skinFile = skin === 'frosted' ? 'skin' : 'minimal-skin';
|
||||||
|
|
||||||
return `<video-provider>
|
return `<script type="module">
|
||||||
|
import 'https://cdn.jsdelivr.net/npm/videojs/html/video/player.js';
|
||||||
|
import 'https://cdn.jsdelivr.net/npm/videojs/html/video/${skinFile}.js';
|
||||||
|
</script>
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/videojs/html/video/${skinFile}.css" />
|
||||||
|
|
||||||
|
<video-player>
|
||||||
<${skinTag}>
|
<${skinTag}>
|
||||||
<video src="https://stream.mux.com/lhnU49l1VGi3zrTAZhDm9LUUxSjpaPW9BL4jY25Kwo4/highest.mp4"></video>
|
<video src="..."></video>
|
||||||
</${skinTag}>
|
</${skinTag}>
|
||||||
</video-provider>`;
|
</video-player>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateReactCode(skin: Skin): string {
|
function generateReactCode(skin: Skin): string {
|
||||||
const skinComponent = skin === 'frosted' ? 'FrostedSkin' : 'MinimalSkin';
|
const skinComponent = skin === 'frosted' ? 'VideoSkin' : 'MinimalVideoSkin';
|
||||||
const skinImport = skin === 'frosted' ? 'frosted' : 'minimal';
|
const skinCss = skin === 'frosted' ? 'skin' : 'minimal-skin';
|
||||||
|
|
||||||
return `// npm install @videojs/react-preview
|
return `import { createPlayer, Poster } from '@videojs/react';
|
||||||
import { VideoProvider, ${skinComponent}, Video } from '@videojs/react-preview';
|
import { ${skinComponent}, Video, videoFeatures } from '@videojs/react/video';
|
||||||
import '@videojs/react-preview/skins/${skinImport}.css';
|
import '@videojs/react/video/${skinCss}.css';
|
||||||
|
|
||||||
export const VideoPlayer = () => {
|
const Player = createPlayer({ features: [...videoFeatures] });
|
||||||
|
|
||||||
|
export function VideoPlayer() {
|
||||||
return (
|
return (
|
||||||
<VideoProvider>
|
<Player.Provider>
|
||||||
<${skinComponent}>
|
<${skinComponent}>
|
||||||
<Video src="https://stream.mux.com/lhnU49l1VGi3zrTAZhDm9LUUxSjpaPW9BL4jY25Kwo4/highest.mp4" />
|
<Video src="..." playsInline />
|
||||||
|
<Poster src="..." />
|
||||||
</${skinComponent}>
|
</${skinComponent}>
|
||||||
</VideoProvider>
|
</Player.Provider>
|
||||||
);
|
);
|
||||||
};`;
|
}`;
|
||||||
}
|
|
||||||
|
|
||||||
function generateJS(skin: Skin): string {
|
|
||||||
return `// npm install @videojs/html-preview
|
|
||||||
import '@videojs/html-preview/skins/${skin}';`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function BaseDemo({ className }: { className?: string }) {
|
export default function BaseDemo({ className }: { className?: string }) {
|
||||||
@@ -49,14 +54,10 @@ export default function BaseDemo({ className }: { className?: string }) {
|
|||||||
<Tab value="html" initial>
|
<Tab value="html" initial>
|
||||||
HTML
|
HTML
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab value="javascript">JavaScript</Tab>
|
|
||||||
</TabsList>
|
</TabsList>
|
||||||
<TabsPanel value="html" initial>
|
<TabsPanel value="html" initial>
|
||||||
<ClientCode code={generateHTMLCode($skin)} lang="html" />
|
<ClientCode code={generateHTMLCode($skin)} lang="html" />
|
||||||
</TabsPanel>
|
</TabsPanel>
|
||||||
<TabsPanel value="javascript">
|
|
||||||
<ClientCode code={generateJS($skin)} lang="javascript" />
|
|
||||||
</TabsPanel>
|
|
||||||
</TabsRoot>
|
</TabsRoot>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,33 +2,26 @@ import { useStore } from '@nanostores/react';
|
|||||||
import { Tab, TabsList, TabsPanel, TabsRoot } from '@/components/Tabs';
|
import { Tab, TabsList, TabsPanel, TabsRoot } from '@/components/Tabs';
|
||||||
import type { Skin } from '@/stores/homePageDemos';
|
import type { Skin } from '@/stores/homePageDemos';
|
||||||
import { framework, skin } from '@/stores/homePageDemos';
|
import { framework, skin } from '@/stores/homePageDemos';
|
||||||
import {
|
|
||||||
generateHTMLCSS,
|
|
||||||
generateHTMLJS,
|
|
||||||
generateHTMLMarkup,
|
|
||||||
generateReactComponent,
|
|
||||||
generateReactCSS as genReactCSS,
|
|
||||||
} from '@/utils/ejectCodeGenerator';
|
|
||||||
import ClientCode from '../Code/ClientCode';
|
import ClientCode from '../Code/ClientCode';
|
||||||
|
|
||||||
function generateReactCode(skin: Skin): string {
|
function generateReactCode(skin: Skin): string {
|
||||||
return generateReactComponent(skin);
|
return `react`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateReactCSS(skin: Skin): string {
|
function generateReactCSS(skin: Skin): string {
|
||||||
return genReactCSS(skin);
|
return `css`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateHTMLCode(skin: Skin): string {
|
function generateHTMLCode(skin: Skin): string {
|
||||||
return generateHTMLMarkup(skin);
|
return `html`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateCSS(skin: Skin): string {
|
function generateCSS(skin: Skin): string {
|
||||||
return generateHTMLCSS(skin);
|
return `css`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateJS(skin: Skin): string {
|
function generateJS(skin: Skin): string {
|
||||||
return generateHTMLJS(skin);
|
return `js`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function EjectDemo({ className }: { className?: string }) {
|
export default function EjectDemo({ className }: { className?: string }) {
|
||||||
|
|||||||
@@ -1,24 +1,23 @@
|
|||||||
import { useStore } from '@nanostores/react';
|
import { useStore } from '@nanostores/react';
|
||||||
import { FrostedSkin, HlsVideo, MinimalSkin, VideoProvider } from '@videojs/react-preview';
|
import { createPlayer, Poster } from '@videojs/react';
|
||||||
|
import { MinimalVideoSkin, Video, VideoSkin, videoFeatures } from '@videojs/react/video';
|
||||||
import { VJS8_DEMO_VIDEO } from '@/consts';
|
import { VJS8_DEMO_VIDEO } from '@/consts';
|
||||||
import { skin } from '@/stores/homePageDemos';
|
import { skin } from '@/stores/homePageDemos';
|
||||||
import '@videojs/react-preview/skins/frosted.css';
|
import '@videojs/react/video/skin.css';
|
||||||
import '@videojs/react-preview/skins/minimal.css';
|
import '@videojs/react/video/minimal-skin.css';
|
||||||
|
|
||||||
|
const Player = createPlayer({ features: [...videoFeatures] });
|
||||||
|
|
||||||
export default function HeroVideo({ className, poster }: { className?: string; poster: string }) {
|
export default function HeroVideo({ className, poster }: { className?: string; poster: string }) {
|
||||||
const $skin = useStore(skin);
|
const $skin = useStore(skin);
|
||||||
const SkinComponent = $skin === 'frosted' ? FrostedSkin : MinimalSkin;
|
const SkinComponent = $skin === 'frosted' ? VideoSkin : MinimalVideoSkin;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<VideoProvider>
|
<Player.Provider>
|
||||||
<SkinComponent className={className}>
|
<SkinComponent className={className}>
|
||||||
<HlsVideo
|
<Video src={VJS8_DEMO_VIDEO.mp4} playsInline />
|
||||||
// @ts-expect-error -- types are incorrect
|
<Poster src={poster} />
|
||||||
src={VJS8_DEMO_VIDEO.hls}
|
|
||||||
poster={poster}
|
|
||||||
playsInline
|
|
||||||
/>
|
|
||||||
</SkinComponent>
|
</SkinComponent>
|
||||||
</VideoProvider>
|
</Player.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,100 +1,8 @@
|
|||||||
---
|
---
|
||||||
title: Customize skins
|
title: Customize skins
|
||||||
description: Learn how to customize Video.js v10 skins by copying and modifying them
|
description: Learn how to customize Video.js skins
|
||||||
---
|
---
|
||||||
|
|
||||||
import FrameworkCase from '@/components/docs/FrameworkCase.astro';
|
|
||||||
import ServerCode from '@/components/Code/ServerCode.astro';
|
|
||||||
import { TabsRoot, TabsList, TabsPanel, Tab } from '@/components/Tabs.tsx';
|
|
||||||
import {
|
|
||||||
generateHTMLCSS,
|
|
||||||
generateHTMLJS,
|
|
||||||
generateHTMLMarkup,
|
|
||||||
generateReactComponent,
|
|
||||||
generateReactCSS,
|
|
||||||
} from '@/utils/ejectCodeGenerator';
|
|
||||||
|
|
||||||
|
|
||||||
Video.js v10 comes with pre-built skins like Frosted and Minimal, but you can fully customize them by "ejecting" the code and making it your own.
|
Video.js v10 comes with pre-built skins like Frosted and Minimal, but you can fully customize them by "ejecting" the code and making it your own.
|
||||||
|
|
||||||
While eventually we'll have a CLI that'll eject skins in your preferred framework and style, for now we invite you to try it out with these copy-paste-ready implementations.
|
🚧 Under construction 🚧
|
||||||
|
|
||||||
## Frosted skin
|
|
||||||
|
|
||||||
<FrameworkCase frameworks={["react"]}>
|
|
||||||
|
|
||||||
<TabsRoot client:idle>
|
|
||||||
<TabsList client:idle label="Frosted React implementation">
|
|
||||||
<Tab client:idle value="component" initial>FrostedSkin.tsx</Tab>
|
|
||||||
<Tab client:idle value="css">frosted.css</Tab>
|
|
||||||
</TabsList>
|
|
||||||
<TabsPanel client:idle value="component" initial>
|
|
||||||
<ServerCode code={generateReactComponent('frosted')} lang="tsx" />
|
|
||||||
</TabsPanel>
|
|
||||||
<TabsPanel client:idle value="css">
|
|
||||||
<ServerCode code={generateReactCSS('frosted')} lang="css" />
|
|
||||||
</TabsPanel>
|
|
||||||
</TabsRoot>
|
|
||||||
|
|
||||||
</FrameworkCase>
|
|
||||||
|
|
||||||
<FrameworkCase frameworks={["html"]}>
|
|
||||||
|
|
||||||
<TabsRoot client:idle>
|
|
||||||
<TabsList client:idle label="Frosted HTML implementation">
|
|
||||||
<Tab client:idle value="markup" initial>HTML</Tab>
|
|
||||||
<Tab client:idle value="js">JS</Tab>
|
|
||||||
<Tab client:idle value="css">CSS</Tab>
|
|
||||||
</TabsList>
|
|
||||||
<TabsPanel client:idle value="markup" initial>
|
|
||||||
<ServerCode code={generateHTMLMarkup('frosted')} lang="html" />
|
|
||||||
</TabsPanel>
|
|
||||||
<TabsPanel client:idle value="js">
|
|
||||||
<ServerCode code={generateHTMLJS('frosted')} lang="typescript" />
|
|
||||||
</TabsPanel>
|
|
||||||
<TabsPanel client:idle value="css">
|
|
||||||
<ServerCode code={generateHTMLCSS('frosted')} lang="css" />
|
|
||||||
</TabsPanel>
|
|
||||||
</TabsRoot>
|
|
||||||
|
|
||||||
</FrameworkCase>
|
|
||||||
|
|
||||||
## Minimal skin
|
|
||||||
|
|
||||||
<FrameworkCase frameworks={["react"]}>
|
|
||||||
|
|
||||||
<TabsRoot client:idle>
|
|
||||||
<TabsList client:idle label="Minimal React implementation">
|
|
||||||
<Tab client:idle value="react" initial>MinimalSkin.tsx</Tab>
|
|
||||||
<Tab client:idle value="css">minimal.css</Tab>
|
|
||||||
</TabsList>
|
|
||||||
<TabsPanel client:idle value="react" initial>
|
|
||||||
<ServerCode code={generateReactComponent('minimal')} lang="tsx" />
|
|
||||||
</TabsPanel>
|
|
||||||
<TabsPanel client:idle value="css">
|
|
||||||
<ServerCode code={generateReactCSS('minimal')} lang="css" />
|
|
||||||
</TabsPanel>
|
|
||||||
</TabsRoot>
|
|
||||||
|
|
||||||
</FrameworkCase>
|
|
||||||
|
|
||||||
<FrameworkCase frameworks={["html"]}>
|
|
||||||
|
|
||||||
<TabsRoot client:idle>
|
|
||||||
<TabsList client:idle label="Minimal HTML implementation">
|
|
||||||
<Tab client:idle value="html" initial>HTML</Tab>
|
|
||||||
<Tab client:idle value="js">JS</Tab>
|
|
||||||
<Tab client:idle value="css">CSS</Tab>
|
|
||||||
</TabsList>
|
|
||||||
<TabsPanel client:idle value="html" initial>
|
|
||||||
<ServerCode code={generateHTMLMarkup('minimal')} lang="html" />
|
|
||||||
</TabsPanel>
|
|
||||||
<TabsPanel client:idle value="js">
|
|
||||||
<ServerCode code={generateHTMLJS('minimal')} lang="typescript" />
|
|
||||||
</TabsPanel>
|
|
||||||
<TabsPanel client:idle value="css">
|
|
||||||
<ServerCode code={generateHTMLCSS('minimal')} lang="css" />
|
|
||||||
</TabsPanel>
|
|
||||||
</TabsRoot>
|
|
||||||
|
|
||||||
</FrameworkCase>
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user