mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
chore: update examples to have sidebar and more examples link on non (#767)
This commit is contained in:
@@ -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
@@ -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 & 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 & 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>
|
||||
@@ -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"
|
||||
>← 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"
|
||||
>
|
||||
← 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"
|
||||
>← 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,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');
|
||||
|
||||
@@ -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 & 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 & 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]"
|
||||
>← 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"
|
||||
>← 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"
|
||||
>
|
||||
← 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>
|
||||
|
||||
@@ -50,4 +50,5 @@ function App() {
|
||||
);
|
||||
}
|
||||
|
||||
createRoot(document.getElementById('root')!).render(<App />);
|
||||
const root = document.getElementById('root');
|
||||
if (root) createRoot(root).render(<App />);
|
||||
|
||||
@@ -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'),
|
||||
|
||||
Reference in New Issue
Block a user