diff --git a/packages/sandbox/templates/constants.ts b/packages/sandbox/app/constants.ts
similarity index 100%
rename from packages/sandbox/templates/constants.ts
rename to packages/sandbox/app/constants.ts
diff --git a/packages/sandbox/src/index.html b/packages/sandbox/app/index.html
similarity index 90%
rename from packages/sandbox/src/index.html
rename to packages/sandbox/app/index.html
index a2779a90..79f1c51b 100644
--- a/packages/sandbox/src/index.html
+++ b/packages/sandbox/app/index.html
@@ -6,7 +6,6 @@
Sandbox
-
diff --git a/packages/sandbox/app/main.tsx b/packages/sandbox/app/main.tsx
new file mode 100644
index 00000000..38834311
--- /dev/null
+++ b/packages/sandbox/app/main.tsx
@@ -0,0 +1,16 @@
+import type { SourceId } from '@app/shared/sources';
+import '@app/styles.css';
+import { App } from '@app/shell/app';
+import type { Skin } from '@app/types';
+import { skinStore, sourceStore } from '@app/utils/stores';
+import { createRoot } from 'react-dom/client';
+
+// Sync query-param overrides to localStorage BEFORE React mounts,
+// so useWebStorage hooks pick up the correct initial values.
+const params = new URLSearchParams(location.search);
+const skinParam = params.get('skin') as Skin | null;
+if (skinParam) skinStore.setValue(skinParam);
+const sourceParam = params.get('source') as SourceId | null;
+if (sourceParam) sourceStore.setValue(sourceParam);
+
+createRoot(document.getElementById('root')!).render();
diff --git a/packages/sandbox/templates/shared/html/skin-tags.ts b/packages/sandbox/app/shared/html/skin-tags.ts
similarity index 91%
rename from packages/sandbox/templates/shared/html/skin-tags.ts
rename to packages/sandbox/app/shared/html/skin-tags.ts
index 1adb95d5..b51be993 100644
--- a/packages/sandbox/templates/shared/html/skin-tags.ts
+++ b/packages/sandbox/app/shared/html/skin-tags.ts
@@ -1,4 +1,4 @@
-import type { Skin } from '../../types';
+import type { Skin } from '@app/types';
type SkinTagMap = Record;
diff --git a/packages/sandbox/templates/shared/html/stylesheets.ts b/packages/sandbox/app/shared/html/stylesheets.ts
similarity index 95%
rename from packages/sandbox/templates/shared/html/stylesheets.ts
rename to packages/sandbox/app/shared/html/stylesheets.ts
index c4563643..0ddea10f 100644
--- a/packages/sandbox/templates/shared/html/stylesheets.ts
+++ b/packages/sandbox/app/shared/html/stylesheets.ts
@@ -1,4 +1,4 @@
-import type { Skin } from '../../types';
+import type { Skin } from '@app/types';
const videoStylesheets: Record = {
default: new URL('@videojs/html/video/skin.css', import.meta.url).href,
diff --git a/packages/sandbox/templates/shared/html/tailwind-setup.ts b/packages/sandbox/app/shared/html/tailwind-setup.ts
similarity index 93%
rename from packages/sandbox/templates/shared/html/tailwind-setup.ts
rename to packages/sandbox/app/shared/html/tailwind-setup.ts
index d899c1b1..9c0336a8 100644
--- a/packages/sandbox/templates/shared/html/tailwind-setup.ts
+++ b/packages/sandbox/app/shared/html/tailwind-setup.ts
@@ -1,8 +1,8 @@
+import tailwindCSS from '@app/styles.css?inline';
import { MinimalAudioSkinTailwindElement } from '@videojs/html/audio/minimal-skin.tailwind';
import { AudioSkinTailwindElement } from '@videojs/html/audio/skin.tailwind';
import { MinimalVideoSkinTailwindElement } from '@videojs/html/video/minimal-skin.tailwind';
import { VideoSkinTailwindElement } from '@videojs/html/video/skin.tailwind';
-import tailwindCSS from '../../styles.css?inline';
const tailwindStyles = new CSSStyleSheet();
tailwindStyles.replaceSync(tailwindCSS);
diff --git a/packages/sandbox/templates/shared/react/providers.ts b/packages/sandbox/app/shared/react/providers.ts
similarity index 100%
rename from packages/sandbox/templates/shared/react/providers.ts
rename to packages/sandbox/app/shared/react/providers.ts
diff --git a/packages/sandbox/templates/shared/react/skins.tsx b/packages/sandbox/app/shared/react/skins.tsx
similarity index 96%
rename from packages/sandbox/templates/shared/react/skins.tsx
rename to packages/sandbox/app/shared/react/skins.tsx
index adaa2540..2314371a 100644
--- a/packages/sandbox/templates/shared/react/skins.tsx
+++ b/packages/sandbox/app/shared/react/skins.tsx
@@ -1,8 +1,8 @@
+import type { Skin, Styling } from '@app/types';
import type { AudioSkinProps } from '@videojs/react/audio';
import { AudioSkin, AudioSkinTailwind, MinimalAudioSkin, MinimalAudioSkinTailwind } from '@videojs/react/audio';
import type { VideoSkinProps } from '@videojs/react/video';
import { MinimalVideoSkin, MinimalVideoSkinTailwind, VideoSkin, VideoSkinTailwind } from '@videojs/react/video';
-import type { Skin, Styling } from '../../types';
type VideoSkinComponentProps = { skin: Skin; styling: Styling } & VideoSkinProps;
diff --git a/packages/sandbox/templates/shared/react/use-skin.ts b/packages/sandbox/app/shared/react/use-skin.ts
similarity index 62%
rename from packages/sandbox/templates/shared/react/use-skin.ts
rename to packages/sandbox/app/shared/react/use-skin.ts
index f82b2d4a..22a13c56 100644
--- a/packages/sandbox/templates/shared/react/use-skin.ts
+++ b/packages/sandbox/app/shared/react/use-skin.ts
@@ -1,6 +1,6 @@
+import { getInitialSkin, onSkinChange } from '@app/shared/sandbox-listener';
+import type { Skin } from '@app/types';
import { useEffect, useState } from 'react';
-import type { Skin } from '../../types';
-import { getInitialSkin, onSkinChange } from '../sandbox-listener';
export function useSkin(): Skin {
const [skin, setSkin] = useState(getInitialSkin);
diff --git a/packages/sandbox/templates/shared/react/use-source.ts b/packages/sandbox/app/shared/react/use-source.ts
similarity index 65%
rename from packages/sandbox/templates/shared/react/use-source.ts
rename to packages/sandbox/app/shared/react/use-source.ts
index ca55f148..99f49064 100644
--- a/packages/sandbox/templates/shared/react/use-source.ts
+++ b/packages/sandbox/app/shared/react/use-source.ts
@@ -1,6 +1,6 @@
+import { getInitialSource, onSourceChange } from '@app/shared/sandbox-listener';
+import type { SourceId } from '@app/shared/sources';
import { useEffect, useState } from 'react';
-import { getInitialSource, onSourceChange } from '../sandbox-listener';
-import type { SourceId } from '../sources';
export function useSource(audioOnly?: boolean): SourceId {
const [source, setSource] = useState(() => getInitialSource(audioOnly));
diff --git a/packages/sandbox/templates/shared/sandbox-listener.ts b/packages/sandbox/app/shared/sandbox-listener.ts
similarity index 94%
rename from packages/sandbox/templates/shared/sandbox-listener.ts
rename to packages/sandbox/app/shared/sandbox-listener.ts
index 0108eeb4..8ec0b86a 100644
--- a/packages/sandbox/templates/shared/sandbox-listener.ts
+++ b/packages/sandbox/app/shared/sandbox-listener.ts
@@ -1,5 +1,5 @@
-import type { Skin } from '../types';
-import { createWebStorageStore } from '../utils/create-web-storage-store';
+import type { Skin } from '@app/types';
+import { createWebStorageStore } from '@app/utils/create-web-storage-store';
import { DEFAULT_AUDIO_SOURCE, SOURCES, type SourceId } from './sources';
const params = new URLSearchParams(window.location.search);
diff --git a/packages/sandbox/templates/shared/sources.ts b/packages/sandbox/app/shared/sources.ts
similarity index 96%
rename from packages/sandbox/templates/shared/sources.ts
rename to packages/sandbox/app/shared/sources.ts
index 0b740a9a..669e28ff 100644
--- a/packages/sandbox/templates/shared/sources.ts
+++ b/packages/sandbox/app/shared/sources.ts
@@ -20,7 +20,7 @@ export const SOURCES: Record(null);
- // Derive the page URL
const pagePath = getPagePath(platform, styling, preset);
- // Update URL when filters change
+ // Keep the URL in sync with all state (including skin + source)
useEffect(() => {
- const params = new URLSearchParams({ platform, styling, preset });
- const url = `/?${params.toString()}`;
- history.replaceState(null, '', url);
- }, [platform, styling, preset]);
+ const params = new URLSearchParams({ platform, styling, preset, skin, source });
+ history.replaceState(null, '', `/?${params}`);
+ }, [platform, styling, preset, skin, source]);
// Send postMessage to iframe for skin changes (skip initial mount — iframe reads localStorage)
- const skinRef = useRef(skin);
+ const skinMountRef = useRef(true);
useEffect(() => {
- if (skinRef.current === skin) return;
- skinRef.current = skin;
+ if (skinMountRef.current) {
+ skinMountRef.current = false;
+ return;
+ }
iframeRef.current?.contentWindow?.postMessage({ type: 'skin-change', skin }, '*');
}, [skin]);
// Send postMessage to iframe for source changes (skip initial mount — iframe reads localStorage)
- const sourceRef = useRef(source);
+ const sourceMountRef = useRef(true);
useEffect(() => {
- if (sourceRef.current === source) return;
- sourceRef.current = source;
+ if (sourceMountRef.current) {
+ sourceMountRef.current = false;
+ return;
+ }
iframeRef.current?.contentWindow?.postMessage({ type: 'source-change', source }, '*');
}, [source]);
diff --git a/packages/sandbox/templates/shell/navbar.tsx b/packages/sandbox/app/shell/navbar.tsx
similarity index 96%
rename from packages/sandbox/templates/shell/navbar.tsx
rename to packages/sandbox/app/shell/navbar.tsx
index 6e2692a9..ce0d3094 100644
--- a/packages/sandbox/templates/shell/navbar.tsx
+++ b/packages/sandbox/app/shell/navbar.tsx
@@ -1,6 +1,6 @@
-import type { SKINS } from '../constants';
-import type { SourceId } from '../shared/sources';
-import type { Platform, Preset, Skin, Styling } from '../types';
+import type { SKINS } from '@app/constants';
+import type { SourceId } from '@app/shared/sources';
+import type { Platform, Preset, Skin, Styling } from '@app/types';
type NavbarProps = {
platform: Platform;
@@ -31,8 +31,8 @@ const PLATFORM_LABELS: Record = {
const PRESET_LABELS: Record = {
video: 'Video',
- 'hls-video': 'HlsVideo',
- 'simple-hls-video': 'SimpleHlsVideo',
+ 'hls-video': 'HLS Video',
+ 'simple-hls-video': 'Simple HLS Video',
audio: 'Audio',
'background-video': 'Background Video',
};
diff --git a/packages/sandbox/templates/shell/preview.tsx b/packages/sandbox/app/shell/preview.tsx
similarity index 94%
rename from packages/sandbox/templates/shell/preview.tsx
rename to packages/sandbox/app/shell/preview.tsx
index da1ebd3a..19f755e1 100644
--- a/packages/sandbox/templates/shell/preview.tsx
+++ b/packages/sandbox/app/shell/preview.tsx
@@ -1,6 +1,6 @@
+import type { SourceId } from '@app/shared/sources';
+import type { Skin } from '@app/types';
import { forwardRef } from 'react';
-import type { SourceId } from '../shared/sources';
-import type { Skin } from '../types';
type PreviewProps = {
pagePath: string;
diff --git a/packages/sandbox/templates/styles.css b/packages/sandbox/app/styles.css
similarity index 95%
rename from packages/sandbox/templates/styles.css
rename to packages/sandbox/app/styles.css
index 4c739555..adb0f409 100644
--- a/packages/sandbox/templates/styles.css
+++ b/packages/sandbox/app/styles.css
@@ -1,4 +1,5 @@
@import "tailwindcss";
+@source "../app";
@source "../src";
@source "../templates";
/* NOTE: This is non-standard since you'd usually eject the Tailwind skin into your own project and not import it from node_modules. */
diff --git a/packages/sandbox/templates/types.ts b/packages/sandbox/app/types.ts
similarity index 100%
rename from packages/sandbox/templates/types.ts
rename to packages/sandbox/app/types.ts
diff --git a/packages/sandbox/templates/utils/create-web-storage-store.ts b/packages/sandbox/app/utils/create-web-storage-store.ts
similarity index 100%
rename from packages/sandbox/templates/utils/create-web-storage-store.ts
rename to packages/sandbox/app/utils/create-web-storage-store.ts
diff --git a/packages/sandbox/app/utils/stores.ts b/packages/sandbox/app/utils/stores.ts
new file mode 100644
index 00000000..ede6d8c5
--- /dev/null
+++ b/packages/sandbox/app/utils/stores.ts
@@ -0,0 +1,6 @@
+import type { SourceId } from '@app/shared/sources';
+import type { Skin } from '@app/types';
+import { createWebStorageStore } from './create-web-storage-store';
+
+export const skinStore = createWebStorageStore('local', 'skin', 'default');
+export const sourceStore = createWebStorageStore('local', 'source', 'hls-1');
diff --git a/packages/sandbox/templates/utils/use-external-store.ts b/packages/sandbox/app/utils/use-external-store.ts
similarity index 100%
rename from packages/sandbox/templates/utils/use-external-store.ts
rename to packages/sandbox/app/utils/use-external-store.ts
diff --git a/packages/sandbox/app/utils/use-skin-switcher.ts b/packages/sandbox/app/utils/use-skin-switcher.ts
new file mode 100644
index 00000000..821b5a31
--- /dev/null
+++ b/packages/sandbox/app/utils/use-skin-switcher.ts
@@ -0,0 +1,8 @@
+import type { Skin } from '@app/types';
+import { skinStore } from './stores';
+import { useExternalStore } from './use-external-store';
+
+export function useSkinSwitcher(): [Skin, (value: Skin) => void] {
+ const value = useExternalStore(skinStore);
+ return [value, skinStore.setValue];
+}
diff --git a/packages/sandbox/app/utils/use-source-switcher.ts b/packages/sandbox/app/utils/use-source-switcher.ts
new file mode 100644
index 00000000..0a8150c6
--- /dev/null
+++ b/packages/sandbox/app/utils/use-source-switcher.ts
@@ -0,0 +1,8 @@
+import type { SourceId } from '@app/shared/sources';
+import { sourceStore } from './stores';
+import { useExternalStore } from './use-external-store';
+
+export function useSourceSwitcher(): [SourceId, (value: SourceId) => void] {
+ const value = useExternalStore(sourceStore);
+ return [value, sourceStore.setValue];
+}
diff --git a/packages/sandbox/templates/utils/use-web-storage.ts b/packages/sandbox/app/utils/use-web-storage.ts
similarity index 100%
rename from packages/sandbox/templates/utils/use-web-storage.ts
rename to packages/sandbox/app/utils/use-web-storage.ts
diff --git a/packages/sandbox/package.json b/packages/sandbox/package.json
index 58ab715f..47975bf8 100644
--- a/packages/sandbox/package.json
+++ b/packages/sandbox/package.json
@@ -4,9 +4,10 @@
"private": true,
"type": "module",
"scripts": {
- "dev": "tsx setup.ts && vite",
- "build": "tsx setup.ts && vite build",
+ "dev": "tsx scripts/setup.ts && vite",
+ "build": "tsx scripts/setup.ts && vite build",
"preview": "vite preview",
+ "reset": "tsx scripts/reset.ts",
"sync": "tsx scripts/sync.ts"
},
"dependencies": {
@@ -17,8 +18,7 @@
"@videojs/skins": "workspace:*",
"@videojs/spf": "workspace:*",
"@videojs/store": "workspace:*",
- "@videojs/utils": "workspace:*",
- "wouter": "^3.0.0"
+ "@videojs/utils": "workspace:*"
},
"devDependencies": {
"@tailwindcss/vite": "^4.2.0",
diff --git a/packages/sandbox/scripts/reset.ts b/packages/sandbox/scripts/reset.ts
new file mode 100644
index 00000000..f0fb27f7
--- /dev/null
+++ b/packages/sandbox/scripts/reset.ts
@@ -0,0 +1,49 @@
+import chalk from 'chalk';
+import fs from 'fs-extra';
+
+import { confirm, filePath, getChanges, printDiff, srcPath, templatesPath } from './shared.js';
+
+const changes = getChanges();
+
+// Files in src that differ from templates (will be overwritten)
+const modified = changes.filter((d) => d.state === 'distinct');
+// Files only in src (will be deleted)
+const added = changes.filter((d) => d.state === 'left');
+
+if (modified.length === 0 && added.length === 0) {
+ console.log(chalk.gray('\nNo local changes. Already in sync with templates.\n'));
+ process.exit(0);
+}
+
+console.log(chalk.bold('\nThe following local changes will be lost:\n'));
+
+for (const change of modified) {
+ const label = filePath(change);
+ console.log(chalk.yellow(` ~ ${label}`));
+ printDiff(templatesPath(change), srcPath(change), label);
+}
+
+for (const change of added) {
+ console.log(chalk.red(` + ${filePath(change)} (will be deleted)`));
+}
+
+console.log();
+
+const ok = await confirm('Reset src/ to templates? This cannot be undone.');
+
+if (!ok) {
+ console.log(chalk.gray('\nAborted. No files were changed.\n'));
+ process.exit(0);
+}
+
+for (const change of modified) {
+ await fs.copy(templatesPath(change), srcPath(change), { overwrite: true });
+ console.log(chalk.green(` ✔ Reset ${filePath(change)}`));
+}
+
+for (const change of added) {
+ await fs.remove(srcPath(change));
+ console.log(chalk.red(` ✔ Deleted ${filePath(change)}`));
+}
+
+console.log(chalk.bold.green('\nReset complete!\n'));
diff --git a/packages/sandbox/setup.ts b/packages/sandbox/scripts/setup.ts
similarity index 85%
rename from packages/sandbox/setup.ts
rename to packages/sandbox/scripts/setup.ts
index 5e687e09..8ee48df2 100644
--- a/packages/sandbox/setup.ts
+++ b/packages/sandbox/scripts/setup.ts
@@ -1,10 +1,11 @@
import { copyFileSync, existsSync, mkdirSync, readdirSync, statSync } from 'node:fs';
import { resolve } from 'node:path';
-const root = import.meta.dirname;
+const root = resolve(import.meta.dirname, '..');
const templatesDir = resolve(root, 'templates');
const srcDir = resolve(root, 'src');
+/** Recursively copy template files into `src/`, preserving relative paths. */
function mirror(dir: string) {
for (const entry of readdirSync(dir)) {
const templatePath = resolve(dir, entry);
diff --git a/packages/sandbox/scripts/shared.ts b/packages/sandbox/scripts/shared.ts
new file mode 100644
index 00000000..d76b6bb0
--- /dev/null
+++ b/packages/sandbox/scripts/shared.ts
@@ -0,0 +1,77 @@
+import path from 'node:path';
+import chalk from 'chalk';
+import { createTwoFilesPatch } from 'diff';
+import type { Result } from 'dir-compare';
+import { compareSync } from 'dir-compare';
+import fs from 'fs-extra';
+import prompts from 'prompts';
+
+export const SRC = './src';
+export const TEMPLATES = './templates';
+
+export interface Change {
+ state: 'left' | 'right' | 'distinct';
+ name: string;
+ relativePath: string;
+}
+
+export function getChanges(): Change[] {
+ const res: Result = compareSync(SRC, TEMPLATES, { compareContent: true });
+
+ return (res.diffSet ?? [])
+ .filter((d) => d.state !== 'equal' && d.type1 !== 'directory' && d.type2 !== 'directory')
+ .map((d) => ({
+ state: d.state as Change['state'],
+ name: (d.name1 ?? d.name2)!,
+ relativePath: d.relativePath,
+ }))
+ .filter((d) => d.name != null);
+}
+
+function colorizePatch(patch: string): string {
+ return patch
+ .split('\n')
+ .map((line) => {
+ if (line.startsWith('---') || line.startsWith('+++')) return chalk.dim(line);
+ if (line.startsWith('-')) return chalk.red(line);
+ if (line.startsWith('+')) return chalk.green(line);
+ if (line.startsWith('@@')) return chalk.cyan(line);
+ return chalk.gray(line);
+ })
+ .join('\n');
+}
+
+export function printDiff(oldPath: string, newPath: string, label: string): void {
+ const oldContent = fs.existsSync(oldPath) ? fs.readFileSync(oldPath, 'utf8') : '';
+ const newContent = fs.existsSync(newPath) ? fs.readFileSync(newPath, 'utf8') : '';
+ const patch = createTwoFilesPatch(label, label, oldContent, newContent, undefined, undefined, { context: 3 });
+
+ // Strip the first two header lines (Index + ===) that createTwoFilesPatch adds
+ const lines = patch.split('\n');
+ const body = lines.slice(2).join('\n');
+
+ console.log(colorizePatch(body));
+}
+
+export function filePath(change: Change): string {
+ return path.join(change.relativePath, change.name);
+}
+
+export function srcPath(change: Change): string {
+ return path.join(SRC, change.relativePath, change.name);
+}
+
+export function templatesPath(change: Change): string {
+ return path.join(TEMPLATES, change.relativePath, change.name);
+}
+
+export async function confirm(message: string): Promise {
+ const { ok } = await prompts({
+ type: 'confirm',
+ name: 'ok',
+ message,
+ initial: false,
+ });
+
+ return ok === true;
+}
diff --git a/packages/sandbox/scripts/sync.ts b/packages/sandbox/scripts/sync.ts
index aa49f47c..2be5872d 100644
--- a/packages/sandbox/scripts/sync.ts
+++ b/packages/sandbox/scripts/sync.ts
@@ -1,76 +1,32 @@
-import path from 'node:path';
import chalk from 'chalk';
-import { createTwoFilesPatch } from 'diff';
-import { compareSync } from 'dir-compare';
import fs from 'fs-extra';
-import prompts from 'prompts';
-const SOURCE = './src';
-const TEMPLATES = './templates';
-// Some file always live in src
-const IGNORE = new Set(['index.html', 'main.tsx']);
+import { confirm, filePath, getChanges, printDiff, SRC, srcPath, TEMPLATES, templatesPath } from './shared.js';
-function colorizePatch(patch: string): string {
- return patch
- .split('\n')
- .map((line) => {
- if (line.startsWith('---') || line.startsWith('+++')) return chalk.dim(line);
- if (line.startsWith('-')) return chalk.red(line);
- if (line.startsWith('+')) return chalk.green(line);
- if (line.startsWith('@@')) return chalk.cyan(line);
- return chalk.gray(line);
- })
- .join('\n');
-}
+console.log(chalk.bold(`\nComparing ${SRC} → ${TEMPLATES}\n`));
-function printDiff(oldPath: string, newPath: string, label: string): void {
- const oldContent = fs.existsSync(oldPath) ? fs.readFileSync(oldPath, 'utf8') : '';
- const newContent = fs.existsSync(newPath) ? fs.readFileSync(newPath, 'utf8') : '';
- const patch = createTwoFilesPatch(label, label, oldContent, newContent, undefined, undefined, { context: 3 });
-
- // Strip the first two header lines (Index + ===) that createTwoFilesPatch adds
- const lines = patch.split('\n');
- const body = lines.slice(2).join('\n');
-
- console.log(colorizePatch(body));
-}
-
-console.log(chalk.bold(`\nComparing ${SOURCE} → ${TEMPLATES}\n`));
-
-const res = compareSync(SOURCE, TEMPLATES, { compareContent: true });
-
-const changes = (res.diffSet ?? []).filter(
- (d) =>
- d.state !== 'equal' &&
- d.type1 !== 'directory' &&
- d.type2 !== 'directory' &&
- !IGNORE.has(d.name1 ?? '') &&
- !IGNORE.has(d.name2 ?? '')
-);
+const changes = getChanges();
if (changes.length === 0) {
console.log(chalk.gray('No differences found. Directories are in sync.'));
process.exit(0);
}
-for (const diff of changes) {
- const name = diff.name1 ?? diff.name2;
- if (!name) continue;
+for (const change of changes) {
+ const label = filePath(change);
- const filePath = path.join(diff.relativePath, name);
-
- if (diff.state === 'left') {
- console.log(chalk.green(` + ${filePath} (new in src)`));
- printDiff('', path.join(SOURCE, diff.relativePath, name), filePath);
+ if (change.state === 'left') {
+ console.log(chalk.green(` + ${label} (new in src)`));
+ printDiff('', srcPath(change), label);
}
- if (diff.state === 'right') {
- console.log(chalk.red(` - ${filePath} (only in templates)`));
+ if (change.state === 'right') {
+ console.log(chalk.red(` - ${label} (only in templates)`));
}
- if (diff.state === 'distinct') {
- console.log(chalk.yellow(` ~ ${filePath} (modified)`));
- printDiff(path.join(TEMPLATES, diff.relativePath, name), path.join(SOURCE, diff.relativePath, name), filePath);
+ if (change.state === 'distinct') {
+ console.log(chalk.yellow(` ~ ${label} (modified)`));
+ printDiff(templatesPath(change), srcPath(change), label);
}
}
@@ -78,12 +34,7 @@ console.log();
console.log(chalk.bold(`${changes.length} change(s) found.`));
console.log();
-const { ok } = await prompts({
- type: 'confirm',
- name: 'ok',
- message: `Copy all changes from ${SOURCE} to ${TEMPLATES}?`,
- initial: false,
-});
+const ok = await confirm(`Copy all changes from ${SRC} to ${TEMPLATES}?`);
if (!ok) {
console.log(chalk.gray('\nAborted. No files were copied.'));
@@ -91,17 +42,12 @@ if (!ok) {
}
// Only copy changed/new files from src — skip 'right' entries (only in templates)
-for (const diff of changes) {
- if (diff.state === 'right') continue; // don't delete files that only exist in templates
+for (const change of changes) {
+ if (change.state === 'right') continue;
- if (!diff.name1) continue;
-
- const relPath = path.join(diff.relativePath, diff.name1);
- const src = path.join(SOURCE, relPath);
- const dest = path.join(TEMPLATES, relPath);
-
- await fs.copy(src, dest, { overwrite: true });
- console.log(chalk.green(` ✔ Copied ${relPath}`));
+ const dest = templatesPath(change);
+ await fs.copy(srcPath(change), dest, { overwrite: true });
+ console.log(chalk.green(` ✔ Copied ${filePath(change)}`));
}
console.log(chalk.bold.green('\nDone!\n'));
diff --git a/packages/sandbox/src/main.tsx b/packages/sandbox/src/main.tsx
deleted file mode 100644
index 53004947..00000000
--- a/packages/sandbox/src/main.tsx
+++ /dev/null
@@ -1,4 +0,0 @@
-import { createRoot } from 'react-dom/client';
-import { App } from './shell/app';
-
-createRoot(document.getElementById('root')!).render();
diff --git a/packages/sandbox/templates/html-audio-tailwind/index.html b/packages/sandbox/templates/html-audio-tailwind/index.html
index dbdec75b..ab51a4ad 100644
--- a/packages/sandbox/templates/html-audio-tailwind/index.html
+++ b/packages/sandbox/templates/html-audio-tailwind/index.html
@@ -6,7 +6,6 @@
Sandbox — HTML Audio Tailwind
-
diff --git a/packages/sandbox/templates/html-audio-tailwind/main.ts b/packages/sandbox/templates/html-audio-tailwind/main.ts
index b7fa7b9d..d90fd12d 100644
--- a/packages/sandbox/templates/html-audio-tailwind/main.ts
+++ b/packages/sandbox/templates/html-audio-tailwind/main.ts
@@ -1,12 +1,13 @@
+import '@app/styles.css';
import '@videojs/html/audio/player';
import '@videojs/html/audio/skin.tailwind';
import '@videojs/html/audio/minimal-skin.tailwind';
-import { TAILWIND_SKIN_TAGS } from '../shared/html/skin-tags';
-import { setupAudioTailwind } from '../shared/html/tailwind-setup';
-import { getInitialSkin, getInitialSource, onSkinChange, onSourceChange } from '../shared/sandbox-listener';
-import type { SourceId } from '../shared/sources';
-import { SOURCES } from '../shared/sources';
-import type { Skin } from '../types';
+import { TAILWIND_SKIN_TAGS } from '@app/shared/html/skin-tags';
+import { setupAudioTailwind } from '@app/shared/html/tailwind-setup';
+import { getInitialSkin, getInitialSource, onSkinChange, onSourceChange } from '@app/shared/sandbox-listener';
+import type { SourceId } from '@app/shared/sources';
+import { SOURCES } from '@app/shared/sources';
+import type { Skin } from '@app/types';
setupAudioTailwind();
diff --git a/packages/sandbox/templates/html-audio/index.html b/packages/sandbox/templates/html-audio/index.html
index b1618bd2..73b10839 100644
--- a/packages/sandbox/templates/html-audio/index.html
+++ b/packages/sandbox/templates/html-audio/index.html
@@ -6,7 +6,6 @@
Sandbox — HTML Audio
-
diff --git a/packages/sandbox/templates/html-audio/main.ts b/packages/sandbox/templates/html-audio/main.ts
index e7fa6650..a32f5a3f 100644
--- a/packages/sandbox/templates/html-audio/main.ts
+++ b/packages/sandbox/templates/html-audio/main.ts
@@ -1,12 +1,13 @@
+import '@app/styles.css';
import '@videojs/html/audio/player';
import '@videojs/html/audio/skin';
import '@videojs/html/audio/minimal-skin';
-import { CSS_SKIN_TAGS } from '../shared/html/skin-tags';
-import { loadAudioStylesheets } from '../shared/html/stylesheets';
-import { getInitialSkin, getInitialSource, onSkinChange, onSourceChange } from '../shared/sandbox-listener';
-import type { SourceId } from '../shared/sources';
-import { SOURCES } from '../shared/sources';
-import type { Skin } from '../types';
+import { CSS_SKIN_TAGS } from '@app/shared/html/skin-tags';
+import { loadAudioStylesheets } from '@app/shared/html/stylesheets';
+import { getInitialSkin, getInitialSource, onSkinChange, onSourceChange } from '@app/shared/sandbox-listener';
+import type { SourceId } from '@app/shared/sources';
+import { SOURCES } from '@app/shared/sources';
+import type { Skin } from '@app/types';
const html = String.raw;
diff --git a/packages/sandbox/templates/html-background-video/index.html b/packages/sandbox/templates/html-background-video/index.html
index 648f155b..39951d8f 100644
--- a/packages/sandbox/templates/html-background-video/index.html
+++ b/packages/sandbox/templates/html-background-video/index.html
@@ -6,7 +6,6 @@
Sandbox — HTML Background Video
-
diff --git a/packages/sandbox/templates/html-background-video/main.ts b/packages/sandbox/templates/html-background-video/main.ts
index 9ddf0823..f049d579 100644
--- a/packages/sandbox/templates/html-background-video/main.ts
+++ b/packages/sandbox/templates/html-background-video/main.ts
@@ -1,8 +1,9 @@
+import '@app/styles.css';
import '@videojs/html/background/skin.css';
import '@videojs/html/background/player';
import '@videojs/html/background/skin';
import '@videojs/html/background/video';
-import { BACKGROUND_VIDEO_SRC } from '../shared/sources';
+import { BACKGROUND_VIDEO_SRC } from '@app/shared/sources';
const html = String.raw;
diff --git a/packages/sandbox/templates/html-hls-video/index.html b/packages/sandbox/templates/html-hls-video/index.html
index 70e9ffcf..a081ee0e 100644
--- a/packages/sandbox/templates/html-hls-video/index.html
+++ b/packages/sandbox/templates/html-hls-video/index.html
@@ -6,7 +6,6 @@
Sandbox — HTML Video
-
diff --git a/packages/sandbox/templates/html-hls-video/main.ts b/packages/sandbox/templates/html-hls-video/main.ts
index 37dd7683..b39a87ea 100644
--- a/packages/sandbox/templates/html-hls-video/main.ts
+++ b/packages/sandbox/templates/html-hls-video/main.ts
@@ -1,13 +1,14 @@
+import '@app/styles.css';
import '@videojs/html/video/player';
import '@videojs/html/media/hls-video';
import '@videojs/html/video/skin';
import '@videojs/html/video/minimal-skin';
-import { CSS_SKIN_TAGS } from '../shared/html/skin-tags';
-import { loadVideoStylesheets } from '../shared/html/stylesheets';
-import { getInitialSkin, getInitialSource, onSkinChange, onSourceChange } from '../shared/sandbox-listener';
-import type { SourceId } from '../shared/sources';
-import { SOURCES } from '../shared/sources';
-import type { Skin } from '../types';
+import { CSS_SKIN_TAGS } from '@app/shared/html/skin-tags';
+import { loadVideoStylesheets } from '@app/shared/html/stylesheets';
+import { getInitialSkin, getInitialSource, onSkinChange, onSourceChange } from '@app/shared/sandbox-listener';
+import type { SourceId } from '@app/shared/sources';
+import { SOURCES } from '@app/shared/sources';
+import type { Skin } from '@app/types';
const html = String.raw;
diff --git a/packages/sandbox/templates/html-simple-hls-video/index.html b/packages/sandbox/templates/html-simple-hls-video/index.html
index 70e9ffcf..a081ee0e 100644
--- a/packages/sandbox/templates/html-simple-hls-video/index.html
+++ b/packages/sandbox/templates/html-simple-hls-video/index.html
@@ -6,7 +6,6 @@
Sandbox — HTML Video
-
diff --git a/packages/sandbox/templates/html-simple-hls-video/main.ts b/packages/sandbox/templates/html-simple-hls-video/main.ts
index 9ecdc84a..730d0820 100644
--- a/packages/sandbox/templates/html-simple-hls-video/main.ts
+++ b/packages/sandbox/templates/html-simple-hls-video/main.ts
@@ -1,13 +1,14 @@
+import '@app/styles.css';
import '@videojs/html/video/player';
import '@videojs/html/media/simple-hls-video';
import '@videojs/html/video/skin';
import '@videojs/html/video/minimal-skin';
-import { CSS_SKIN_TAGS } from '../shared/html/skin-tags';
-import { loadVideoStylesheets } from '../shared/html/stylesheets';
-import { getInitialSkin, getInitialSource, onSkinChange, onSourceChange } from '../shared/sandbox-listener';
-import type { SourceId } from '../shared/sources';
-import { SOURCES } from '../shared/sources';
-import type { Skin } from '../types';
+import { CSS_SKIN_TAGS } from '@app/shared/html/skin-tags';
+import { loadVideoStylesheets } from '@app/shared/html/stylesheets';
+import { getInitialSkin, getInitialSource, onSkinChange, onSourceChange } from '@app/shared/sandbox-listener';
+import type { SourceId } from '@app/shared/sources';
+import { SOURCES } from '@app/shared/sources';
+import type { Skin } from '@app/types';
const html = String.raw;
diff --git a/packages/sandbox/templates/html-video-tailwind/index.html b/packages/sandbox/templates/html-video-tailwind/index.html
index da7a0139..1e28faa2 100644
--- a/packages/sandbox/templates/html-video-tailwind/index.html
+++ b/packages/sandbox/templates/html-video-tailwind/index.html
@@ -6,7 +6,6 @@
Sandbox — HTML Video Tailwind
-
diff --git a/packages/sandbox/templates/html-video-tailwind/main.ts b/packages/sandbox/templates/html-video-tailwind/main.ts
index 0547a67f..7f6dca21 100644
--- a/packages/sandbox/templates/html-video-tailwind/main.ts
+++ b/packages/sandbox/templates/html-video-tailwind/main.ts
@@ -1,12 +1,13 @@
+import '@app/styles.css';
import '@videojs/html/video/player';
import '@videojs/html/video/skin.tailwind';
import '@videojs/html/video/minimal-skin.tailwind';
-import { TAILWIND_SKIN_TAGS } from '../shared/html/skin-tags';
-import { setupVideoTailwind } from '../shared/html/tailwind-setup';
-import { getInitialSkin, getInitialSource, onSkinChange, onSourceChange } from '../shared/sandbox-listener';
-import type { SourceId } from '../shared/sources';
-import { SOURCES } from '../shared/sources';
-import type { Skin } from '../types';
+import { TAILWIND_SKIN_TAGS } from '@app/shared/html/skin-tags';
+import { setupVideoTailwind } from '@app/shared/html/tailwind-setup';
+import { getInitialSkin, getInitialSource, onSkinChange, onSourceChange } from '@app/shared/sandbox-listener';
+import type { SourceId } from '@app/shared/sources';
+import { SOURCES } from '@app/shared/sources';
+import type { Skin } from '@app/types';
setupVideoTailwind();
diff --git a/packages/sandbox/templates/html-video/index.html b/packages/sandbox/templates/html-video/index.html
index 70e9ffcf..a081ee0e 100644
--- a/packages/sandbox/templates/html-video/index.html
+++ b/packages/sandbox/templates/html-video/index.html
@@ -6,7 +6,6 @@
Sandbox — HTML Video
-
diff --git a/packages/sandbox/templates/html-video/main.ts b/packages/sandbox/templates/html-video/main.ts
index 139504d4..2f780bb2 100644
--- a/packages/sandbox/templates/html-video/main.ts
+++ b/packages/sandbox/templates/html-video/main.ts
@@ -1,12 +1,13 @@
+import '@app/styles.css';
import '@videojs/html/video/player';
import '@videojs/html/video/skin';
import '@videojs/html/video/minimal-skin';
-import { CSS_SKIN_TAGS } from '../shared/html/skin-tags';
-import { loadVideoStylesheets } from '../shared/html/stylesheets';
-import { getInitialSkin, getInitialSource, onSkinChange, onSourceChange } from '../shared/sandbox-listener';
-import type { SourceId } from '../shared/sources';
-import { SOURCES } from '../shared/sources';
-import type { Skin } from '../types';
+import { CSS_SKIN_TAGS } from '@app/shared/html/skin-tags';
+import { loadVideoStylesheets } from '@app/shared/html/stylesheets';
+import { getInitialSkin, getInitialSource, onSkinChange, onSourceChange } from '@app/shared/sandbox-listener';
+import type { SourceId } from '@app/shared/sources';
+import { SOURCES } from '@app/shared/sources';
+import type { Skin } from '@app/types';
const html = String.raw;
diff --git a/packages/sandbox/templates/index.html b/packages/sandbox/templates/index.html
deleted file mode 100644
index a2779a90..00000000
--- a/packages/sandbox/templates/index.html
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
- Sandbox
-
-
-
-
-
-
-
-
-
diff --git a/packages/sandbox/templates/main.tsx b/packages/sandbox/templates/main.tsx
deleted file mode 100644
index 53004947..00000000
--- a/packages/sandbox/templates/main.tsx
+++ /dev/null
@@ -1,4 +0,0 @@
-import { createRoot } from 'react-dom/client';
-import { App } from './shell/app';
-
-createRoot(document.getElementById('root')!).render();
diff --git a/packages/sandbox/templates/react-audio-tailwind/index.html b/packages/sandbox/templates/react-audio-tailwind/index.html
index 1b58a419..ebc897a2 100644
--- a/packages/sandbox/templates/react-audio-tailwind/index.html
+++ b/packages/sandbox/templates/react-audio-tailwind/index.html
@@ -6,7 +6,6 @@
Sandbox — React Audio Tailwind
-
diff --git a/packages/sandbox/templates/react-audio-tailwind/main.tsx b/packages/sandbox/templates/react-audio-tailwind/main.tsx
index 9948c4d1..f8af9bb0 100644
--- a/packages/sandbox/templates/react-audio-tailwind/main.tsx
+++ b/packages/sandbox/templates/react-audio-tailwind/main.tsx
@@ -1,10 +1,11 @@
+import '@app/styles.css';
+import { AudioProvider } from '@app/shared/react/providers';
+import { AudioSkinComponent } from '@app/shared/react/skins';
+import { useSkin } from '@app/shared/react/use-skin';
+import { useSource } from '@app/shared/react/use-source';
+import { SOURCES } from '@app/shared/sources';
import { Audio } from '@videojs/react/audio';
import { createRoot } from 'react-dom/client';
-import { AudioProvider } from '../shared/react/providers';
-import { AudioSkinComponent } from '../shared/react/skins';
-import { useSkin } from '../shared/react/use-skin';
-import { useSource } from '../shared/react/use-source';
-import { SOURCES } from '../shared/sources';
function App() {
const skin = useSkin();
diff --git a/packages/sandbox/templates/react-audio/index.html b/packages/sandbox/templates/react-audio/index.html
index 496b0b8f..1f2d2633 100644
--- a/packages/sandbox/templates/react-audio/index.html
+++ b/packages/sandbox/templates/react-audio/index.html
@@ -6,7 +6,6 @@
Sandbox — React Audio
-
diff --git a/packages/sandbox/templates/react-audio/main.tsx b/packages/sandbox/templates/react-audio/main.tsx
index 897cc6b8..e7d31697 100644
--- a/packages/sandbox/templates/react-audio/main.tsx
+++ b/packages/sandbox/templates/react-audio/main.tsx
@@ -1,12 +1,13 @@
+import '@app/styles.css';
import '@videojs/react/audio/skin.css';
import '@videojs/react/audio/minimal-skin.css';
+import { AudioProvider } from '@app/shared/react/providers';
+import { AudioSkinComponent } from '@app/shared/react/skins';
+import { useSkin } from '@app/shared/react/use-skin';
+import { useSource } from '@app/shared/react/use-source';
+import { SOURCES } from '@app/shared/sources';
import { Audio } from '@videojs/react/audio';
import { createRoot } from 'react-dom/client';
-import { AudioProvider } from '../shared/react/providers';
-import { AudioSkinComponent } from '../shared/react/skins';
-import { useSkin } from '../shared/react/use-skin';
-import { useSource } from '../shared/react/use-source';
-import { SOURCES } from '../shared/sources';
function App() {
const skin = useSkin();
diff --git a/packages/sandbox/templates/react-background-video/index.html b/packages/sandbox/templates/react-background-video/index.html
index cfabe4c1..44567c35 100644
--- a/packages/sandbox/templates/react-background-video/index.html
+++ b/packages/sandbox/templates/react-background-video/index.html
@@ -6,7 +6,6 @@
Sandbox — React Background Video
-
diff --git a/packages/sandbox/templates/react-background-video/main.tsx b/packages/sandbox/templates/react-background-video/main.tsx
index 567d6572..b5c1eb28 100644
--- a/packages/sandbox/templates/react-background-video/main.tsx
+++ b/packages/sandbox/templates/react-background-video/main.tsx
@@ -1,8 +1,9 @@
+import '@app/styles.css';
import '@videojs/react/background/skin.css';
+import { BackgroundVideoProvider } from '@app/shared/react/providers';
+import { BACKGROUND_VIDEO_SRC } from '@app/shared/sources';
import { BackgroundVideo, BackgroundVideoSkin } from '@videojs/react/background';
import { createRoot } from 'react-dom/client';
-import { BackgroundVideoProvider } from '../shared/react/providers';
-import { BACKGROUND_VIDEO_SRC } from '../shared/sources';
function App() {
return (
diff --git a/packages/sandbox/templates/react-hls-video/index.html b/packages/sandbox/templates/react-hls-video/index.html
index 29ec7003..77317e25 100644
--- a/packages/sandbox/templates/react-hls-video/index.html
+++ b/packages/sandbox/templates/react-hls-video/index.html
@@ -6,7 +6,6 @@
Sandbox — React Video
-
diff --git a/packages/sandbox/templates/react-hls-video/main.tsx b/packages/sandbox/templates/react-hls-video/main.tsx
index dadccb8c..f9e2e17b 100644
--- a/packages/sandbox/templates/react-hls-video/main.tsx
+++ b/packages/sandbox/templates/react-hls-video/main.tsx
@@ -1,12 +1,13 @@
+import '@app/styles.css';
import '@videojs/react/video/skin.css';
import '@videojs/react/video/minimal-skin.css';
+import { VideoProvider } from '@app/shared/react/providers';
+import { VideoSkinComponent } from '@app/shared/react/skins';
+import { useSkin } from '@app/shared/react/use-skin';
+import { useSource } from '@app/shared/react/use-source';
+import { SOURCES } from '@app/shared/sources';
import { HlsVideo } from '@videojs/react/media/hls-video';
import { createRoot } from 'react-dom/client';
-import { VideoProvider } from '../shared/react/providers';
-import { VideoSkinComponent } from '../shared/react/skins';
-import { useSkin } from '../shared/react/use-skin';
-import { useSource } from '../shared/react/use-source';
-import { SOURCES } from '../shared/sources';
function App() {
const skin = useSkin();
diff --git a/packages/sandbox/templates/react-simple-hls-video/index.html b/packages/sandbox/templates/react-simple-hls-video/index.html
index 29ec7003..77317e25 100644
--- a/packages/sandbox/templates/react-simple-hls-video/index.html
+++ b/packages/sandbox/templates/react-simple-hls-video/index.html
@@ -6,7 +6,6 @@
Sandbox — React Video
-
diff --git a/packages/sandbox/templates/react-simple-hls-video/main.tsx b/packages/sandbox/templates/react-simple-hls-video/main.tsx
index 23a81b9f..0f9d44eb 100644
--- a/packages/sandbox/templates/react-simple-hls-video/main.tsx
+++ b/packages/sandbox/templates/react-simple-hls-video/main.tsx
@@ -1,12 +1,13 @@
+import '@app/styles.css';
import '@videojs/react/video/skin.css';
import '@videojs/react/video/minimal-skin.css';
+import { VideoProvider } from '@app/shared/react/providers';
+import { VideoSkinComponent } from '@app/shared/react/skins';
+import { useSkin } from '@app/shared/react/use-skin';
+import { useSource } from '@app/shared/react/use-source';
+import { SOURCES } from '@app/shared/sources';
import { SimpleHlsVideo } from '@videojs/react/media/simple-hls-video';
import { createRoot } from 'react-dom/client';
-import { VideoProvider } from '../shared/react/providers';
-import { VideoSkinComponent } from '../shared/react/skins';
-import { useSkin } from '../shared/react/use-skin';
-import { useSource } from '../shared/react/use-source';
-import { SOURCES } from '../shared/sources';
function App() {
const skin = useSkin();
diff --git a/packages/sandbox/templates/react-video-tailwind/index.html b/packages/sandbox/templates/react-video-tailwind/index.html
index 20753fb3..ac6f661d 100644
--- a/packages/sandbox/templates/react-video-tailwind/index.html
+++ b/packages/sandbox/templates/react-video-tailwind/index.html
@@ -6,7 +6,6 @@
Sandbox — React Video Tailwind
-
diff --git a/packages/sandbox/templates/react-video-tailwind/main.tsx b/packages/sandbox/templates/react-video-tailwind/main.tsx
index be43d2c6..2e043669 100644
--- a/packages/sandbox/templates/react-video-tailwind/main.tsx
+++ b/packages/sandbox/templates/react-video-tailwind/main.tsx
@@ -1,10 +1,11 @@
+import '@app/styles.css';
+import { VideoProvider } from '@app/shared/react/providers';
+import { VideoSkinComponent } from '@app/shared/react/skins';
+import { useSkin } from '@app/shared/react/use-skin';
+import { useSource } from '@app/shared/react/use-source';
+import { SOURCES } from '@app/shared/sources';
import { Video } from '@videojs/react/video';
import { createRoot } from 'react-dom/client';
-import { VideoProvider } from '../shared/react/providers';
-import { VideoSkinComponent } from '../shared/react/skins';
-import { useSkin } from '../shared/react/use-skin';
-import { useSource } from '../shared/react/use-source';
-import { SOURCES } from '../shared/sources';
function App() {
const skin = useSkin();
diff --git a/packages/sandbox/templates/react-video/index.html b/packages/sandbox/templates/react-video/index.html
index 29ec7003..77317e25 100644
--- a/packages/sandbox/templates/react-video/index.html
+++ b/packages/sandbox/templates/react-video/index.html
@@ -6,7 +6,6 @@
Sandbox — React Video
-
diff --git a/packages/sandbox/templates/react-video/main.tsx b/packages/sandbox/templates/react-video/main.tsx
index a21208fc..ab2b1ab5 100644
--- a/packages/sandbox/templates/react-video/main.tsx
+++ b/packages/sandbox/templates/react-video/main.tsx
@@ -1,12 +1,13 @@
+import '@app/styles.css';
import '@videojs/react/video/skin.css';
import '@videojs/react/video/minimal-skin.css';
+import { VideoProvider } from '@app/shared/react/providers';
+import { VideoSkinComponent } from '@app/shared/react/skins';
+import { useSkin } from '@app/shared/react/use-skin';
+import { useSource } from '@app/shared/react/use-source';
+import { SOURCES } from '@app/shared/sources';
import { Video } from '@videojs/react/video';
import { createRoot } from 'react-dom/client';
-import { VideoProvider } from '../shared/react/providers';
-import { VideoSkinComponent } from '../shared/react/skins';
-import { useSkin } from '../shared/react/use-skin';
-import { useSource } from '../shared/react/use-source';
-import { SOURCES } from '../shared/sources';
function App() {
const skin = useSkin();
diff --git a/packages/sandbox/templates/simple-hls-html/index.html b/packages/sandbox/templates/simple-hls-html/index.html
index 4f0a71f1..f1fae711 100644
--- a/packages/sandbox/templates/simple-hls-html/index.html
+++ b/packages/sandbox/templates/simple-hls-html/index.html
@@ -4,7 +4,6 @@
Sandbox — SimpleHLS + Video.js
-
diff --git a/packages/sandbox/templates/simple-hls-html/main.ts b/packages/sandbox/templates/simple-hls-html/main.ts
index 91c4ac73..0489f177 100644
--- a/packages/sandbox/templates/simple-hls-html/main.ts
+++ b/packages/sandbox/templates/simple-hls-html/main.ts
@@ -1,3 +1,4 @@
+import '@app/styles.css';
// SimpleHlsVideo + Video.js integration sandbox
// http://localhost:5173/simple-hls-html/
//
diff --git a/packages/sandbox/templates/simple-hls-react/index.html b/packages/sandbox/templates/simple-hls-react/index.html
index 1a342c6f..827120c3 100644
--- a/packages/sandbox/templates/simple-hls-react/index.html
+++ b/packages/sandbox/templates/simple-hls-react/index.html
@@ -4,7 +4,6 @@
Sandbox — SimpleHLS + Video.js (React)
-
diff --git a/packages/sandbox/templates/simple-hls-react/main.tsx b/packages/sandbox/templates/simple-hls-react/main.tsx
index b71b2572..9c6fb754 100644
--- a/packages/sandbox/templates/simple-hls-react/main.tsx
+++ b/packages/sandbox/templates/simple-hls-react/main.tsx
@@ -1,3 +1,4 @@
+import '@app/styles.css';
// SimpleHlsVideo + Video.js integration sandbox — React
// http://localhost:5173/simple-hls-react/
//
diff --git a/packages/sandbox/templates/spf-segment-loading/index.html b/packages/sandbox/templates/spf-segment-loading/index.html
index a7ddf303..13221f86 100644
--- a/packages/sandbox/templates/spf-segment-loading/index.html
+++ b/packages/sandbox/templates/spf-segment-loading/index.html
@@ -4,7 +4,6 @@
Sandbox — SPF Segment Loading POC
-