diff --git a/.gitignore b/.gitignore
index 1db5807c..1ff50e18 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,7 +23,6 @@ out/
packages/*/types/
*.tsbuildinfo
.turbo/
-generated-icons/
coverage/
*.lcov
.nyc_output/
@@ -138,4 +137,4 @@ bun.lockb
# -------------------------
# AI Agent Config (Generated)
# -------------------------
-.opencode
\ No newline at end of file
+.opencode
diff --git a/packages/__tech-preview__/react/src/icons/generated-icons/FullscreenEnter.tsx b/packages/__tech-preview__/react/src/icons/generated-icons/FullscreenEnter.tsx
new file mode 100644
index 00000000..8696d46f
--- /dev/null
+++ b/packages/__tech-preview__/react/src/icons/generated-icons/FullscreenEnter.tsx
@@ -0,0 +1,20 @@
+/**
+ * @fileoverview Auto-generated React component from SVG
+ *
+ * This file is automatically generated by SVGR from SVG files located in:
+ * packages/icons/assets/
+ *
+ * DO NOT EDIT THIS FILE DIRECTLY.
+ *
+ * To modify this icon:
+ * 1. Edit the corresponding SVG file in packages/icons/assets/
+ * 2. Run `pnpm -F react generate:icons` in this package to regenerate components
+ *
+ * @generated
+ */
+import type { IconProps } from '../types';
+const SvgFullscreenEnter = ({
+ color = 'currentColor',
+ ...props
+}: IconProps): JSX.Element => ;
+export default SvgFullscreenEnter;
\ No newline at end of file
diff --git a/packages/__tech-preview__/react/src/icons/generated-icons/FullscreenEnterAlt.tsx b/packages/__tech-preview__/react/src/icons/generated-icons/FullscreenEnterAlt.tsx
new file mode 100644
index 00000000..467633e2
--- /dev/null
+++ b/packages/__tech-preview__/react/src/icons/generated-icons/FullscreenEnterAlt.tsx
@@ -0,0 +1,20 @@
+/**
+ * @fileoverview Auto-generated React component from SVG
+ *
+ * This file is automatically generated by SVGR from SVG files located in:
+ * packages/icons/assets/
+ *
+ * DO NOT EDIT THIS FILE DIRECTLY.
+ *
+ * To modify this icon:
+ * 1. Edit the corresponding SVG file in packages/icons/assets/
+ * 2. Run `pnpm -F react generate:icons` in this package to regenerate components
+ *
+ * @generated
+ */
+import type { IconProps } from '../types';
+const SvgFullscreenEnterAlt = ({
+ color = 'currentColor',
+ ...props
+}: IconProps): JSX.Element => ;
+export default SvgFullscreenEnterAlt;
\ No newline at end of file
diff --git a/packages/__tech-preview__/react/src/icons/generated-icons/FullscreenExit.tsx b/packages/__tech-preview__/react/src/icons/generated-icons/FullscreenExit.tsx
new file mode 100644
index 00000000..89429670
--- /dev/null
+++ b/packages/__tech-preview__/react/src/icons/generated-icons/FullscreenExit.tsx
@@ -0,0 +1,20 @@
+/**
+ * @fileoverview Auto-generated React component from SVG
+ *
+ * This file is automatically generated by SVGR from SVG files located in:
+ * packages/icons/assets/
+ *
+ * DO NOT EDIT THIS FILE DIRECTLY.
+ *
+ * To modify this icon:
+ * 1. Edit the corresponding SVG file in packages/icons/assets/
+ * 2. Run `pnpm -F react generate:icons` in this package to regenerate components
+ *
+ * @generated
+ */
+import type { IconProps } from '../types';
+const SvgFullscreenExit = ({
+ color = 'currentColor',
+ ...props
+}: IconProps): JSX.Element => ;
+export default SvgFullscreenExit;
\ No newline at end of file
diff --git a/packages/__tech-preview__/react/src/icons/generated-icons/FullscreenExitAlt.tsx b/packages/__tech-preview__/react/src/icons/generated-icons/FullscreenExitAlt.tsx
new file mode 100644
index 00000000..6df82e0f
--- /dev/null
+++ b/packages/__tech-preview__/react/src/icons/generated-icons/FullscreenExitAlt.tsx
@@ -0,0 +1,20 @@
+/**
+ * @fileoverview Auto-generated React component from SVG
+ *
+ * This file is automatically generated by SVGR from SVG files located in:
+ * packages/icons/assets/
+ *
+ * DO NOT EDIT THIS FILE DIRECTLY.
+ *
+ * To modify this icon:
+ * 1. Edit the corresponding SVG file in packages/icons/assets/
+ * 2. Run `pnpm -F react generate:icons` in this package to regenerate components
+ *
+ * @generated
+ */
+import type { IconProps } from '../types';
+const SvgFullscreenExitAlt = ({
+ color = 'currentColor',
+ ...props
+}: IconProps): JSX.Element => ;
+export default SvgFullscreenExitAlt;
\ No newline at end of file
diff --git a/packages/__tech-preview__/react/src/icons/generated-icons/Pause.tsx b/packages/__tech-preview__/react/src/icons/generated-icons/Pause.tsx
new file mode 100644
index 00000000..5386aae8
--- /dev/null
+++ b/packages/__tech-preview__/react/src/icons/generated-icons/Pause.tsx
@@ -0,0 +1,20 @@
+/**
+ * @fileoverview Auto-generated React component from SVG
+ *
+ * This file is automatically generated by SVGR from SVG files located in:
+ * packages/icons/assets/
+ *
+ * DO NOT EDIT THIS FILE DIRECTLY.
+ *
+ * To modify this icon:
+ * 1. Edit the corresponding SVG file in packages/icons/assets/
+ * 2. Run `pnpm -F react generate:icons` in this package to regenerate components
+ *
+ * @generated
+ */
+import type { IconProps } from '../types';
+const SvgPause = ({
+ color = 'currentColor',
+ ...props
+}: IconProps): JSX.Element => ;
+export default SvgPause;
\ No newline at end of file
diff --git a/packages/__tech-preview__/react/src/icons/generated-icons/Play.tsx b/packages/__tech-preview__/react/src/icons/generated-icons/Play.tsx
new file mode 100644
index 00000000..d7208ddc
--- /dev/null
+++ b/packages/__tech-preview__/react/src/icons/generated-icons/Play.tsx
@@ -0,0 +1,20 @@
+/**
+ * @fileoverview Auto-generated React component from SVG
+ *
+ * This file is automatically generated by SVGR from SVG files located in:
+ * packages/icons/assets/
+ *
+ * DO NOT EDIT THIS FILE DIRECTLY.
+ *
+ * To modify this icon:
+ * 1. Edit the corresponding SVG file in packages/icons/assets/
+ * 2. Run `pnpm -F react generate:icons` in this package to regenerate components
+ *
+ * @generated
+ */
+import type { IconProps } from '../types';
+const SvgPlay = ({
+ color = 'currentColor',
+ ...props
+}: IconProps): JSX.Element => ;
+export default SvgPlay;
\ No newline at end of file
diff --git a/packages/__tech-preview__/react/src/icons/generated-icons/Spinner.tsx b/packages/__tech-preview__/react/src/icons/generated-icons/Spinner.tsx
new file mode 100644
index 00000000..08c0f034
--- /dev/null
+++ b/packages/__tech-preview__/react/src/icons/generated-icons/Spinner.tsx
@@ -0,0 +1,20 @@
+/**
+ * @fileoverview Auto-generated React component from SVG
+ *
+ * This file is automatically generated by SVGR from SVG files located in:
+ * packages/icons/assets/
+ *
+ * DO NOT EDIT THIS FILE DIRECTLY.
+ *
+ * To modify this icon:
+ * 1. Edit the corresponding SVG file in packages/icons/assets/
+ * 2. Run `pnpm -F react generate:icons` in this package to regenerate components
+ *
+ * @generated
+ */
+import type { IconProps } from '../types';
+const SvgSpinner = ({
+ color = 'currentColor',
+ ...props
+}: IconProps): JSX.Element => ;
+export default SvgSpinner;
\ No newline at end of file
diff --git a/packages/__tech-preview__/react/src/icons/generated-icons/VolumeHigh.tsx b/packages/__tech-preview__/react/src/icons/generated-icons/VolumeHigh.tsx
new file mode 100644
index 00000000..0e192b75
--- /dev/null
+++ b/packages/__tech-preview__/react/src/icons/generated-icons/VolumeHigh.tsx
@@ -0,0 +1,20 @@
+/**
+ * @fileoverview Auto-generated React component from SVG
+ *
+ * This file is automatically generated by SVGR from SVG files located in:
+ * packages/icons/assets/
+ *
+ * DO NOT EDIT THIS FILE DIRECTLY.
+ *
+ * To modify this icon:
+ * 1. Edit the corresponding SVG file in packages/icons/assets/
+ * 2. Run `pnpm -F react generate:icons` in this package to regenerate components
+ *
+ * @generated
+ */
+import type { IconProps } from '../types';
+const SvgVolumeHigh = ({
+ color = 'currentColor',
+ ...props
+}: IconProps): JSX.Element => ;
+export default SvgVolumeHigh;
\ No newline at end of file
diff --git a/packages/__tech-preview__/react/src/icons/generated-icons/VolumeLow.tsx b/packages/__tech-preview__/react/src/icons/generated-icons/VolumeLow.tsx
new file mode 100644
index 00000000..ea3e997d
--- /dev/null
+++ b/packages/__tech-preview__/react/src/icons/generated-icons/VolumeLow.tsx
@@ -0,0 +1,20 @@
+/**
+ * @fileoverview Auto-generated React component from SVG
+ *
+ * This file is automatically generated by SVGR from SVG files located in:
+ * packages/icons/assets/
+ *
+ * DO NOT EDIT THIS FILE DIRECTLY.
+ *
+ * To modify this icon:
+ * 1. Edit the corresponding SVG file in packages/icons/assets/
+ * 2. Run `pnpm -F react generate:icons` in this package to regenerate components
+ *
+ * @generated
+ */
+import type { IconProps } from '../types';
+const SvgVolumeLow = ({
+ color = 'currentColor',
+ ...props
+}: IconProps): JSX.Element => ;
+export default SvgVolumeLow;
\ No newline at end of file
diff --git a/packages/__tech-preview__/react/src/icons/generated-icons/VolumeOff.tsx b/packages/__tech-preview__/react/src/icons/generated-icons/VolumeOff.tsx
new file mode 100644
index 00000000..52fd6711
--- /dev/null
+++ b/packages/__tech-preview__/react/src/icons/generated-icons/VolumeOff.tsx
@@ -0,0 +1,20 @@
+/**
+ * @fileoverview Auto-generated React component from SVG
+ *
+ * This file is automatically generated by SVGR from SVG files located in:
+ * packages/icons/assets/
+ *
+ * DO NOT EDIT THIS FILE DIRECTLY.
+ *
+ * To modify this icon:
+ * 1. Edit the corresponding SVG file in packages/icons/assets/
+ * 2. Run `pnpm -F react generate:icons` in this package to regenerate components
+ *
+ * @generated
+ */
+import type { IconProps } from '../types';
+const SvgVolumeOff = ({
+ color = 'currentColor',
+ ...props
+}: IconProps): JSX.Element => ;
+export default SvgVolumeOff;
\ No newline at end of file
diff --git a/packages/__tech-preview__/react/src/icons/generated-icons/index.ts b/packages/__tech-preview__/react/src/icons/generated-icons/index.ts
new file mode 100644
index 00000000..677234d4
--- /dev/null
+++ b/packages/__tech-preview__/react/src/icons/generated-icons/index.ts
@@ -0,0 +1,24 @@
+/**
+ * @fileoverview Auto-generated index file for React icon components
+ *
+ * This file is automatically generated by SVGR from SVG files located in:
+ * packages/icons/assets/
+ *
+ * DO NOT EDIT THIS FILE DIRECTLY.
+ *
+ * To modify icons or add new ones:
+ * 1. Add/edit SVG files in packages/core/icons/assets/
+ * 2. Run `pnpm -F react generate:icons` in this package to regenerate components
+ *
+ * @generated
+ */
+export { default as FullscreenEnterAltIcon } from "./FullscreenEnterAlt";
+export { default as FullscreenEnterIcon } from "./FullscreenEnter";
+export { default as FullscreenExitAltIcon } from "./FullscreenExitAlt";
+export { default as FullscreenExitIcon } from "./FullscreenExit";
+export { default as PauseIcon } from "./Pause";
+export { default as PlayIcon } from "./Play";
+export { default as SpinnerIcon } from "./Spinner";
+export { default as VolumeHighIcon } from "./VolumeHigh";
+export { default as VolumeLowIcon } from "./VolumeLow";
+export { default as VolumeOffIcon } from "./VolumeOff";
diff --git a/packages/__tech-preview__/react/tsdown.config.ts b/packages/__tech-preview__/react/tsdown.config.ts
index 4ae7c504..51e3ec53 100644
--- a/packages/__tech-preview__/react/tsdown.config.ts
+++ b/packages/__tech-preview__/react/tsdown.config.ts
@@ -1,7 +1,15 @@
-import { execSync } from 'node:child_process';
+import { existsSync, readdirSync } from 'node:fs';
import { defineConfig } from 'tsdown';
import buildStyles from './build/build-styles.ts';
+const GENERATED_ICONS_DIR = new URL('./src/icons/generated-icons', import.meta.url).pathname;
+
+function hasGeneratedIcons(): boolean {
+ if (!existsSync(GENERATED_ICONS_DIR)) return false;
+ const files = readdirSync(GENERATED_ICONS_DIR);
+ return files.some((f) => f.endsWith('.tsx'));
+}
+
export default defineConfig({
entry: {
index: './src/index.ts',
@@ -22,7 +30,14 @@ export default defineConfig({
},
hooks: {
'build:prepare': async () => {
- execSync('pnpm generate:icons', { stdio: 'inherit' });
+ // Generated icons are committed to git due to @svgr/cli having a bug where it
+ // unconditionally requires 'prettier' at module load time (before parsing CLI args),
+ // which fails in pnpm's strict dependency isolation. Skip generation if icons exist.
+ // To regenerate: pnpm -F @videojs/react-preview generate:icons
+ if (hasGeneratedIcons()) return;
+ throw new Error(
+ 'Generated icons not found. Run: pnpm -F @videojs/react-preview generate:icons',
+ );
},
'build:done': async () => {
await buildStyles();
@@ -31,4 +46,4 @@ export default defineConfig({
loader: {
'.svg': 'text',
},
-});
+});
\ No newline at end of file
diff --git a/site/src/components/HomePageDemo/Base.tsx b/site/src/components/HomePageDemo/Base.tsx
index 6e422efc..3b90b86b 100644
--- a/site/src/components/HomePageDemo/Base.tsx
+++ b/site/src/components/HomePageDemo/Base.tsx
@@ -18,7 +18,7 @@ function generateReactCode(skin: Skin): string {
const skinComponent = skin === 'frosted' ? 'FrostedSkin' : 'MinimalSkin';
const skinImport = skin === 'frosted' ? 'frosted' : 'minimal';
- return `// npm install @videojs/react@next
+ return `// npm install @videojs/react-preview
import { VideoProvider, ${skinComponent}, Video } from '@videojs/react-preview';
import '@videojs/react-preview/skins/${skinImport}.css';
@@ -34,7 +34,7 @@ export const VideoPlayer = () => {
}
function generateJS(skin: Skin): string {
- return `// npm install @videojs/html@next
+ return `// npm install @videojs/html-preview
import '@videojs/html-preview/skins/${skin}';`;
}
diff --git a/site/src/content/docs/concepts/architecture.mdx b/site/src/content/docs/concepts/architecture.mdx
index 096778fc..09e74b1b 100644
--- a/site/src/content/docs/concepts/architecture.mdx
+++ b/site/src/content/docs/concepts/architecture.mdx
@@ -74,8 +74,8 @@ Here's a complete example showing all three tiers:
```tsx
-import { VideoProvider, FrostedSkin, Video } from '@videojs/react';
-import '@videojs/react/skins/frosted.css';
+import { VideoProvider, FrostedSkin, Video } from '@videojs/react-preview';
+import '@videojs/react-preview/skins/frosted.css';
function Player() {
return (
@@ -115,9 +115,9 @@ function Player() {
```ts
-import '@videojs/html/skins/frosted';
+import '@videojs/html-preview/skins/frosted';
```
-
\ No newline at end of file
+
diff --git a/site/src/content/docs/concepts/skins.mdx b/site/src/content/docs/concepts/skins.mdx
index 8f8237b2..2fc1db57 100644
--- a/site/src/content/docs/concepts/skins.mdx
+++ b/site/src/content/docs/concepts/skins.mdx
@@ -32,8 +32,8 @@ A modern, glassy design with backdrop blur effects and polished interactions.
```tsx
-import { VideoProvider, FrostedSkin, Video } from '@videojs/react';
-import '@videojs/react/skins/frosted.css';
+import { VideoProvider, FrostedSkin, Video } from '@videojs/react-preview';
+import '@videojs/react-preview/skins/frosted.css';
@@ -62,8 +62,8 @@ A clean, straightforward design that focuses on simplicity and clarity.
```tsx
-import { VideoProvider, MinimalSkin, Video } from '@videojs/react';
-import '@videojs/react/skins/minimal.css';
+import { VideoProvider, MinimalSkin, Video } from '@videojs/react-preview';
+import '@videojs/react-preview/skins/minimal.css';
@@ -111,7 +111,7 @@ A skin is simply a component that:
```tsx
-import { MediaContainer, PlayButton, TimeSlider } from '@videojs/react';
+import { MediaContainer, PlayButton, TimeSlider } from '@videojs/react-preview';
export function CustomSkin({ children, className }) {
return (
@@ -153,4 +153,4 @@ Read more about components in the compon
## Coming Soon
- More built-in skins for different use cases
-- CLI tool for ejecting and customizing skins
\ No newline at end of file
+- CLI tool for ejecting and customizing skins
diff --git a/site/src/content/docs/how-to/installation.mdx b/site/src/content/docs/how-to/installation.mdx
index 48949e34..f5ceb97f 100644
--- a/site/src/content/docs/how-to/installation.mdx
+++ b/site/src/content/docs/how-to/installation.mdx
@@ -3,6 +3,7 @@ title: Installation
description: Get started with Video.js v10 by choosing your framework, styles, skin, and media renderer
---
+
import FrameworkCase from '@/components/docs/FrameworkCase.astro';
import ServerCode from '@/components/Code/ServerCode.astro';
import DocsLink from '@/components/docs/DocsLink.astro';
@@ -24,16 +25,16 @@ Video.js v10 supports both React and vanilla JavaScript/HTML through Web Compone
First, select your preferred framework in the framework selector at the top of the sidebarpage.
-Then, install the appropriate package, taking care to use the `@next` dist.
+Then, install the package:
```bash
-npm install @videojs/react@next
+npm install @videojs/react-preview
```
```bash
-npm install @videojs/html@next
+npm install @videojs/html-preview
```
@@ -50,16 +51,16 @@ Currently, Video.js v10 uses CSS for styling these skins. More styling approache
```tsx
-import '@videojs/react/skins/frosted.css';
+import '@videojs/react-preview/skins/frosted.css';
// or
-import '@videojs/react/skins/minimal.css';
+import '@videojs/react-preview/skins/minimal.css';
```
```ts
-import '@videojs/html/skins/frosted';
+import '@videojs/html-preview/skins/frosted';
// or
-import '@videojs/html/skins/minimal';
+import '@videojs/html-preview/skins/minimal';
```
@@ -78,8 +79,8 @@ More renderers for formats like DASH, and services like YouTube and Vimeo are pl
```tsx
-import { VideoProvider, FrostedSkin, Video } from '@videojs/react';
-import '@videojs/react/skins/frosted.css';
+import { VideoProvider, FrostedSkin, Video } from '@videojs/react-preview';
+import '@videojs/react-preview/skins/frosted.css';
export default function App() {
return (
@@ -98,7 +99,7 @@ export default function App() {
```ts
-import '@videojs/html/skins/frosted';
+import '@videojs/html-preview/skins/frosted';
document.body.innerHTML = `
@@ -115,4 +116,4 @@ document.body.innerHTML = `
```
-That's it! You now have a fully functional Video.js player. Go forth and play.
\ No newline at end of file
+That's it! You now have a fully functional Video.js player. Go forth and play.
diff --git a/site/src/examples/html/fullscreen-button/fullscreen-button.js b/site/src/examples/html/fullscreen-button/fullscreen-button.js
index 8c62e210..f991418b 100644
--- a/site/src/examples/html/fullscreen-button/fullscreen-button.js
+++ b/site/src/examples/html/fullscreen-button/fullscreen-button.js
@@ -1,5 +1,5 @@
-import '@videojs/html/define/media-fullscreen-button';
-import '@videojs/html/icons';
+import "@videojs/html-preview/define/media-fullscreen-button";
+import "@videojs/html-preview/icons";
// The web components will automatically register themselves
// No additional setup needed
diff --git a/site/src/examples/html/mute-button/mute-button.js b/site/src/examples/html/mute-button/mute-button.js
index 204d3420..37a4e1dd 100644
--- a/site/src/examples/html/mute-button/mute-button.js
+++ b/site/src/examples/html/mute-button/mute-button.js
@@ -1,5 +1,5 @@
-import '@videojs/html/define/media-mute-button';
-import '@videojs/html/icons';
+import "@videojs/html-preview/define/media-mute-button";
+import "@videojs/html-preview/icons";
// The web components will automatically register themselves
// No additional setup needed
diff --git a/site/src/examples/html/play-button/play-button.js b/site/src/examples/html/play-button/play-button.js
index 0a988b53..78d0a0a3 100644
--- a/site/src/examples/html/play-button/play-button.js
+++ b/site/src/examples/html/play-button/play-button.js
@@ -1,5 +1,5 @@
-import '@videojs/html/define/media-play-button';
-import '@videojs/html/icons';
+import "@videojs/html-preview/define/media-play-button";
+import "@videojs/html-preview/icons";
// The web components will automatically register themselves
// No additional setup needed
diff --git a/site/src/utils/ejectCodeGenerator.ts b/site/src/utils/ejectCodeGenerator.ts
index 7bd2e25e..4eabf020 100644
--- a/site/src/utils/ejectCodeGenerator.ts
+++ b/site/src/utils/ejectCodeGenerator.ts
@@ -11,7 +11,7 @@ type Skin = 'frosted' | 'minimal';
*/
export function generateReactComponent(skin: Skin): string {
if (skin === 'frosted') {
- return `// npm install @videojs/react@next
+ return `// npm install @videojs/react-preview
import type { PropsWithChildren } from 'react';
import { CurrentTimeDisplay, DurationDisplay, FullscreenButton, MediaContainer, MuteButton, PlayButton, Popover, PreviewTimeDisplay, TimeSlider, Tooltip, VolumeSlider } from '@videojs/react-preview';
@@ -120,7 +120,7 @@ export default function FrostedSkin({ children, className = '' }: SkinProps): JS
);
}`;
} else {
- return `// npm install @videojs/react@next
+ return `// npm install @videojs/react-preview
import type { PropsWithChildren } from 'react';
import { CurrentTimeDisplay, DurationDisplay, FullscreenButton, MediaContainer, MuteButton, PlayButton, Popover, PreviewTimeDisplay, TimeSlider, Tooltip, VolumeSlider } from '@videojs/react-preview';
@@ -1898,7 +1898,7 @@ media-tooltip {
export function generateHTMLJS(skin: Skin): string {
return `import './${skin}.css';
-// npm install @videojs/html@next
+// npm install @videojs/html-preview
import '@videojs/html-preview/icons';
// be sure to import video-provider first for proper context initialization
import '@videojs/html-preview/define/video-provider';