chore: update examples to have sidebar and more examples link on non (#767)

This commit is contained in:
Wesley Luyten
2026-03-06 18:01:39 -06:00
committed by GitHub
parent 206bc9b4ae
commit 573a9e57ed
17 changed files with 392 additions and 125 deletions
+1
View File
@@ -25,6 +25,7 @@
"dev:site": "turbo run dev --filter=site",
"dev": "turbo run dev --parallel",
"dev:packages": "turbo run dev --parallel --filter='./packages/*'",
"dev:sandbox": "turbo run dev --filter=@videojs/sandbox",
"lint": "biome check .",
"lint:fix": "biome check . --write",
"lint:fix:file": "biome check --write",
+112 -11
View File
@@ -6,16 +6,117 @@
<title>Sandbox</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body class="p-8 font-mono text-neutral-900">
<h1 class="text-2xl font-bold mb-6">Sandbox</h1>
<ul class="flex gap-4">
<li><a href="/core/" class="text-blue-600 underline hover:text-blue-800">Core</a></li>
<li><a href="/html/" class="text-blue-600 underline hover:text-blue-800">HTML</a></li>
<li><a href="/html-background/" class="text-blue-600 underline hover:text-blue-800">HTML Background</a></li>
<li><a href="/html-tailwind/" class="text-blue-600 underline hover:text-blue-800">HTML & Tailwind</a></li>
<li><a href="/react/" class="text-blue-600 underline hover:text-blue-800">React</a></li>
<li><a href="/react-background/" class="text-blue-600 underline hover:text-blue-800">React Background</a></li>
<li><a href="/react-tailwind/" class="text-blue-600 underline hover:text-blue-800">React & Tailwind</a></li>
</ul>
<body class="font-mono text-neutral-900 flex flex-col h-screen overflow-hidden">
<header
class="shrink-0 h-12 border-b border-neutral-200 bg-neutral-50 flex items-center justify-between px-4"
>
<span class="text-sm font-bold tracking-tight">Video.js v10</span>
<a
href="https://github.com/videojs/v10"
target="_blank"
rel="noopener noreferrer"
class="text-neutral-500 hover:text-neutral-900 transition-colors"
aria-label="GitHub repository"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
class="w-5 h-5"
aria-hidden="true"
>
<path
d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61-.546-1.385-1.335-1.755-1.335-1.755-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"
/>
</svg>
</a>
</header>
<div class="flex flex-1 overflow-hidden">
<nav
class="w-48 shrink-0 border-r border-neutral-200 bg-neutral-50 flex flex-col gap-1 p-4 overflow-y-auto"
>
<span class="text-xs font-bold uppercase tracking-widest text-neutral-400 mb-2"
>Sandbox</span
>
<a
href="/html/"
data-page="/html/"
class="nav-link px-3 py-2 rounded text-sm text-blue-600 hover:bg-neutral-100 hover:text-blue-800 transition-colors"
>HTML</a
>
<a
href="/html-background/"
data-page="/html-background/"
class="nav-link px-3 py-2 rounded text-sm text-blue-600 hover:bg-neutral-100 hover:text-blue-800 transition-colors"
>HTML Background</a
>
<a
href="/html-tailwind/"
data-page="/html-tailwind/"
class="nav-link px-3 py-2 rounded text-sm text-blue-600 hover:bg-neutral-100 hover:text-blue-800 transition-colors"
>HTML &amp; Tailwind</a
>
<a
href="/react/"
data-page="/react/"
class="nav-link px-3 py-2 rounded text-sm text-blue-600 hover:bg-neutral-100 hover:text-blue-800 transition-colors"
>React</a
>
<a
href="/react-background/"
data-page="/react-background/"
class="nav-link px-3 py-2 rounded text-sm text-blue-600 hover:bg-neutral-100 hover:text-blue-800 transition-colors"
>React Background</a
>
<a
href="/react-tailwind/"
data-page="/react-tailwind/"
class="nav-link px-3 py-2 rounded text-sm text-blue-600 hover:bg-neutral-100 hover:text-blue-800 transition-colors"
>React &amp; Tailwind</a
>
</nav>
<main class="flex-1 overflow-hidden">
<iframe
id="preview"
src="/html/"
class="w-full h-full border-0"
title="player demo"
></iframe>
</main>
</div>
<script>
const iframe = document.getElementById('preview');
const links = document.querySelectorAll('.nav-link');
function setActive(page) {
for (const link of links) {
const isActive = link.dataset.page === page;
link.classList.toggle('bg-neutral-200', isActive);
link.classList.toggle('font-semibold', isActive);
link.classList.toggle('text-blue-800', isActive);
}
}
setActive('/html/');
for (const link of links) {
link.addEventListener('click', (e) => {
e.preventDefault();
const page = link.dataset.page;
iframe.src = page;
setActive(page);
history.replaceState(null, '', page === '/html/' ? '/' : page);
});
}
// Restore active state from URL on load
const initial =
location.pathname === '/' ? '/html/' : location.pathname.replace(/([^/])$/, '$1/');
const match = [...links].find((l) => l.dataset.page === initial);
if (match) {
iframe.src = initial;
setActive(initial);
}
</script>
</body>
</html>
@@ -1,13 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Sandbox — Core</title>
<link rel="stylesheet" href="../styles.css" />
</head>
<body>
<div id="root"></div>
<script type="module" src="./main.ts"></script>
</body>
</html>
-3
View File
@@ -1,3 +0,0 @@
// http://localhost:5173/core/
// import { } from '@videojs/core';
@@ -4,10 +4,22 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Sandbox — HTML Background</title>
<link rel="stylesheet" href="../../styles.css" />
<link rel="stylesheet" href="../styles.css" />
</head>
<body>
<div id="root" style="width: 100vw; height: 100vh;"></div>
<a
id="home-link"
href="/"
class="fixed top-3 left-3 hidden text-xs font-mono text-neutral-600 hover:text-neutral-900 transition-colors bg-white/85 backdrop-blur-sm px-2.5 py-1 rounded-full border border-black/8 z-50"
aria-label="Back to sandbox home"
>&larr; More examples</a
>
<script>
if (window.self === window.top) {
document.getElementById('home-link').style.display = 'inline';
}
</script>
<div id="root" style="width: 100vw; height: 100vh"></div>
<script type="module" src="./main.ts"></script>
</body>
</html>
@@ -8,10 +8,14 @@ import '@videojs/html/background/video';
const html = String.raw;
document.getElementById('root')!.innerHTML = html`
<background-video-player>
<background-video-skin>
<background-video slot="media" src="https://stream.mux.com/Sc89iWAyNkhJ3P1rQ02nrEdCFTnfT01CZ2KmaEcxXfB008/low.mp4"></background-video>
</background-video-skin>
</background-video-player>
`;
const root = document.getElementById('root');
if (root) {
root.innerHTML = html`
<background-video-player>
<background-video-skin>
<background-video slot="media" src="https://stream.mux.com/Sc89iWAyNkhJ3P1rQ02nrEdCFTnfT01CZ2KmaEcxXfB008/low.mp4"></background-video>
</background-video-skin>
</background-video-player>
`;
}
@@ -7,6 +7,19 @@
<link rel="stylesheet" href="../styles.css" />
</head>
<body>
<a
id="home-link"
href="/"
class="fixed top-3 left-4 hidden text-xs font-mono text-neutral-400 hover:text-neutral-700 transition-colors"
aria-label="Back to sandbox home"
>
&larr; More examples
</a>
<script>
if (window.self === window.top) {
document.getElementById('home-link').style.display = 'inline';
}
</script>
<div class="flex flex-col justify-center items-center gap-4 my-4">
<select id="skin-select" aria-label="Skin"></select>
<div id="player" class="w-full aspect-video max-w-4xl mx-auto"></div>
@@ -7,36 +7,38 @@ import '@videojs/html/video/minimal-skin.tailwind';
import { SKINS } from '../constants';
import type { Skin } from '../types';
const html = String.raw;
const player = document.getElementById('player');
const select = document.getElementById('skin-select') as HTMLSelectElement | null;
const VIDEO_SRC = 'https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4';
if (player && select) {
const html = String.raw;
const skinTags: Record<Skin, string> = {
default: 'video-skin-tailwind',
minimal: 'video-minimal-skin-tailwind',
};
const VIDEO_SRC = 'https://stream.mux.com/lhnU49l1VGi3zrTAZhDm9LUUxSjpaPW9BL4jY25Kwo4/highest.mp4';
function render(skin: Skin) {
const tag = skinTags[skin];
const skinTags: Record<Skin, string> = {
default: 'video-skin-tailwind',
minimal: 'video-minimal-skin-tailwind',
};
document.getElementById('player')!.innerHTML = html`
<video-player>
<${tag}>
<video slot="media" src="${VIDEO_SRC}"></video>
</${tag}>
</video-player>
`;
function render(skin: Skin) {
const tag = skinTags[skin];
player!.innerHTML = html`
<video-player>
<${tag}>
<video slot="media" src="${VIDEO_SRC}"></video>
</${tag}>
</video-player>
`;
}
for (const skin of SKINS) {
const option = document.createElement('option');
option.value = skin;
option.textContent = skin;
select.appendChild(option);
}
select.addEventListener('change', () => render(select.value as Skin));
render('default');
}
// Skin switcher
const select = document.getElementById('skin-select') as HTMLSelectElement;
for (const skin of SKINS) {
const option = document.createElement('option');
option.value = skin;
option.textContent = skin;
select.appendChild(option);
}
select.addEventListener('change', () => render(select.value as Skin));
// Initial render
render('default');
@@ -7,6 +7,18 @@
<link rel="stylesheet" href="../styles.css" />
</head>
<body>
<a
id="home-link"
href="/"
class="fixed top-3 left-3 hidden text-xs font-mono text-neutral-500 hover:text-neutral-900 transition-colors z-50"
aria-label="Back to sandbox home"
>&larr; More examples</a
>
<script>
if (window.self === window.top) {
document.getElementById('home-link').style.display = 'inline';
}
</script>
<div class="flex flex-col justify-center items-center gap-4 my-4">
<select id="skin-select" aria-label="Skin"></select>
<div id="player" class="w-full aspect-video max-w-4xl mx-auto"></div>
+47 -45
View File
@@ -7,54 +7,56 @@ import '@videojs/html/video/minimal-skin';
import { SKINS } from '../constants';
import type { Skin } from '../types';
const html = String.raw;
const player = document.getElementById('player');
const select = document.getElementById('skin-select') as HTMLSelectElement | null;
const VIDEO_SRC = 'https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4';
if (player && select) {
const html = String.raw;
const skinTags: Record<Skin, string> = {
default: 'video-skin',
minimal: 'video-minimal-skin',
};
const VIDEO_SRC = 'https://stream.mux.com/lhnU49l1VGi3zrTAZhDm9LUUxSjpaPW9BL4jY25Kwo4/highest.mp4';
const stylesheets: Record<Skin, string> = {
default: new URL('@videojs/html/video/skin.css', import.meta.url).href,
minimal: new URL('@videojs/html/video/minimal-skin.css', import.meta.url).href,
};
const skinTags: Record<Skin, string> = {
default: 'video-skin',
minimal: 'video-minimal-skin',
};
let currentLink: HTMLLinkElement | null = null;
const stylesheets: Record<Skin, string> = {
default: new URL('@videojs/html/video/skin.css', import.meta.url).href,
minimal: new URL('@videojs/html/video/minimal-skin.css', import.meta.url).href,
};
function loadStylesheet(url: string) {
currentLink?.remove();
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = url;
document.head.appendChild(link);
currentLink = link;
let currentLink: HTMLLinkElement | null = null;
function loadStylesheet(url: string) {
currentLink?.remove();
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = url;
document.head.appendChild(link);
currentLink = link;
}
function render(skin: Skin) {
const tag = skinTags[skin];
loadStylesheet(stylesheets[skin]);
player!.innerHTML = html`
<video-player>
<${tag}>
<video slot="media" src="${VIDEO_SRC}"></video>
</${tag}>
</video-player>
`;
}
for (const skin of SKINS) {
const option = document.createElement('option');
option.value = skin;
option.textContent = skin;
select.appendChild(option);
}
select.addEventListener('change', () => render(select.value as Skin));
render('default');
}
function render(skin: Skin) {
const tag = skinTags[skin];
loadStylesheet(stylesheets[skin]);
document.getElementById('player')!.innerHTML = html`
<video-player>
<${tag}>
<video slot="media" src="${VIDEO_SRC}"></video>
</${tag}>
</video-player>
`;
}
// Skin switcher
const select = document.getElementById('skin-select') as HTMLSelectElement;
for (const skin of SKINS) {
const option = document.createElement('option');
option.value = skin;
option.textContent = skin;
select.appendChild(option);
}
select.addEventListener('change', () => render(select.value as Skin));
// Initial render
render('default');
+112 -11
View File
@@ -6,16 +6,117 @@
<title>Sandbox</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body class="p-8 font-mono text-neutral-900">
<h1 class="text-2xl font-bold mb-6">Sandbox</h1>
<ul class="flex gap-4">
<li><a href="/core/" class="text-blue-600 underline hover:text-blue-800">Core</a></li>
<li><a href="/html/" class="text-blue-600 underline hover:text-blue-800">HTML</a></li>
<li><a href="/html-background/" class="text-blue-600 underline hover:text-blue-800">HTML Background</a></li>
<li><a href="/html-tailwind/" class="text-blue-600 underline hover:text-blue-800">HTML & Tailwind</a></li>
<li><a href="/react/" class="text-blue-600 underline hover:text-blue-800">React</a></li>
<li><a href="/react-background/" class="text-blue-600 underline hover:text-blue-800">React Background</a></li>
<li><a href="/react-tailwind/" class="text-blue-600 underline hover:text-blue-800">React & Tailwind</a></li>
</ul>
<body class="font-mono text-neutral-900 flex flex-col h-screen overflow-hidden">
<header
class="shrink-0 h-12 border-b border-neutral-200 bg-neutral-50 flex items-center justify-between px-4"
>
<span class="text-sm font-bold tracking-tight">Video.js v10</span>
<a
href="https://github.com/videojs/v10"
target="_blank"
rel="noopener noreferrer"
class="text-neutral-500 hover:text-neutral-900 transition-colors"
aria-label="GitHub repository"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
class="w-5 h-5"
aria-hidden="true"
>
<path
d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61-.546-1.385-1.335-1.755-1.335-1.755-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"
/>
</svg>
</a>
</header>
<div class="flex flex-1 overflow-hidden">
<nav
class="w-48 shrink-0 border-r border-neutral-200 bg-neutral-50 flex flex-col gap-1 p-4 overflow-y-auto"
>
<span class="text-xs font-bold uppercase tracking-widest text-neutral-400 mb-2"
>Sandbox</span
>
<a
href="/html/"
data-page="/html/"
class="nav-link px-3 py-2 rounded text-sm text-blue-600 hover:bg-neutral-100 hover:text-blue-800 transition-colors"
>HTML</a
>
<a
href="/html-background/"
data-page="/html-background/"
class="nav-link px-3 py-2 rounded text-sm text-blue-600 hover:bg-neutral-100 hover:text-blue-800 transition-colors"
>HTML Background</a
>
<a
href="/html-tailwind/"
data-page="/html-tailwind/"
class="nav-link px-3 py-2 rounded text-sm text-blue-600 hover:bg-neutral-100 hover:text-blue-800 transition-colors"
>HTML &amp; Tailwind</a
>
<a
href="/react/"
data-page="/react/"
class="nav-link px-3 py-2 rounded text-sm text-blue-600 hover:bg-neutral-100 hover:text-blue-800 transition-colors"
>React</a
>
<a
href="/react-background/"
data-page="/react-background/"
class="nav-link px-3 py-2 rounded text-sm text-blue-600 hover:bg-neutral-100 hover:text-blue-800 transition-colors"
>React Background</a
>
<a
href="/react-tailwind/"
data-page="/react-tailwind/"
class="nav-link px-3 py-2 rounded text-sm text-blue-600 hover:bg-neutral-100 hover:text-blue-800 transition-colors"
>React &amp; Tailwind</a
>
</nav>
<main class="flex-1 overflow-hidden">
<iframe
id="preview"
src="/html/"
class="w-full h-full border-0"
title="player demo"
></iframe>
</main>
</div>
<script>
const iframe = document.getElementById('preview');
const links = document.querySelectorAll('.nav-link');
function setActive(page) {
for (const link of links) {
const isActive = link.dataset.page === page;
link.classList.toggle('bg-neutral-200', isActive);
link.classList.toggle('font-semibold', isActive);
link.classList.toggle('text-blue-800', isActive);
}
}
setActive('/html/');
for (const link of links) {
link.addEventListener('click', (e) => {
e.preventDefault();
const page = link.dataset.page;
iframe.src = page;
setActive(page);
history.replaceState(null, '', page === '/html/' ? '/' : page);
});
}
// Restore active state from URL on load
const initial =
location.pathname === '/' ? '/html/' : location.pathname.replace(/([^/])$/, '$1/');
const match = [...links].find((l) => l.dataset.page === initial);
if (match) {
iframe.src = initial;
setActive(initial);
}
</script>
</body>
</html>
@@ -4,10 +4,19 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Sandbox — React Background</title>
<link rel="stylesheet" href="../../styles.css" />
<link rel="stylesheet" href="../styles.css" />
</head>
<body>
<div id="root" style="width: 100vw; height: 100vh;"></div>
<a
id="home-link"
href="/"
class="fixed top-3 left-3 hidden text-xs font-mono text-neutral-600 hover:text-neutral-900 transition-colors bg-white/85 backdrop-blur-sm px-2.5 py-1 rounded-full border border-black/8 z-[9999]"
>&larr; More examples</a
>
<script>
if (window.self === window.top) document.getElementById('home-link').style.display = 'inline';
</script>
<div id="root" style="width: 100vw; height: 100vh"></div>
<script type="module" src="./background.tsx"></script>
</body>
</html>
@@ -7,6 +7,18 @@
<link rel="stylesheet" href="../styles.css" />
</head>
<body>
<a
id="home-link"
href="/"
class="fixed top-3 left-4 hidden text-xs font-mono text-neutral-400 hover:text-neutral-700 transition-colors"
aria-label="Back to sandbox home"
>&larr; More examples</a
>
<script>
if (window.self === window.top) {
document.getElementById('home-link').style.display = 'inline';
}
</script>
<div id="root"></div>
<script type="module" src="./main.tsx"></script>
</body>
@@ -49,4 +49,5 @@ function App() {
);
}
createRoot(document.getElementById('root')!).render(<App />);
const root = document.getElementById('root');
if (root) createRoot(root).render(<App />);
@@ -7,6 +7,19 @@
<link rel="stylesheet" href="../styles.css" />
</head>
<body>
<a
id="home-link"
href="/"
class="fixed top-3 left-4 hidden items-center text-xs font-mono text-neutral-400 hover:text-neutral-700 transition-colors"
aria-label="Back to sandbox home"
>
&larr; More examples
</a>
<script>
if (window.self === window.top) {
document.getElementById('home-link').style.display = 'inline';
}
</script>
<div id="root"></div>
<script type="module" src="./main.tsx"></script>
</body>
+2 -1
View File
@@ -50,4 +50,5 @@ function App() {
);
}
createRoot(document.getElementById('root')!).render(<App />);
const root = document.getElementById('root');
if (root) createRoot(root).render(<App />);
-1
View File
@@ -18,7 +18,6 @@ export default defineConfig({
rollupOptions: {
input: {
main: resolve(__dirname, 'src/index.html'),
core: resolve(__dirname, 'src/core/index.html'),
html: resolve(__dirname, 'src/html/index.html'),
'html-background': resolve(__dirname, 'src/html-background/index.html'),
'html-tailwind': resolve(__dirname, 'src/html-tailwind/index.html'),