docs(site): add skins & architecture concept pages (#769)

Co-authored-by: Darius Cepulis <dcepulis@mux.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Steve Heffernan
2026-03-13 18:24:32 -05:00
committed by GitHub
co-authored by Darius Cepulis Claude Opus 4.6
parent b82b6dba7a
commit dbf717f1a7
58 changed files with 1940 additions and 587 deletions
+1 -1
View File
@@ -39,7 +39,7 @@ const renderTitle = title ?? defaultTitles[type];
<aside
class={twMerge(
clsx(
"mx-auto my-4 flex w-full max-w-3xl overflow-hidden rounded-xs border border-manila-75 dark:border-warm-gray",
"mx-auto my-8 flex w-full max-w-3xl overflow-hidden rounded-xs border border-manila-75 dark:border-warm-gray",
),
className,
)}
+1 -3
View File
@@ -20,6 +20,4 @@ const { url: href } = resolveDocsLinkUrl({
});
---
<A href={href}>
<slot />
</A>
<A href={href}><slot /></A>
@@ -0,0 +1,47 @@
---
import type { HTMLAttributes } from 'astro/types';
import { ChevronRight } from 'lucide-react';
import { isValidFramework } from '@/types/docs';
import { resolveDocsLinkUrl } from '@/utils/docs/routing';
interface Props extends Omit<HTMLAttributes<'a'>, 'href'> {
slug: string;
description?: string;
}
const { slug, description } = Astro.props;
const { framework: paramFramework } = Astro.params;
if (!paramFramework || !isValidFramework(paramFramework)) {
throw new Error(`Invalid or missing framework param "${paramFramework ?? 'undefined'}".`);
}
const { url: href } = resolveDocsLinkUrl({
targetSlug: slug,
contextFramework: paramFramework,
});
---
<div
class="docs-link-card mx-auto my-8 grid w-full max-w-3xl grid-cols-1 gap-4 has-[+_.docs-link-card]:mb-4 md:grid-cols-2 [&+.docs-link-card]:mt-4"
>
<a
href={href}
class="flex items-center justify-between gap-4 rounded-xs border border-manila-dark p-4 no-underline md:pl-6 dark:border-warm-gray intent:bg-manila-75 dark:intent:bg-warm-gray"
>
{
description ? (
<div>
<div class="font-bold">
<slot />
</div>
<div class="mt-2 text-p3">{description}</div>
</div>
) : (
<span>
<slot />
</span>
)
}
<ChevronRight size={14} />
</a>
</div>
@@ -16,12 +16,12 @@ function getGuideUrl(framework: SupportedFramework, slug: string): string {
}
---
<nav class="mx-auto grid w-full max-w-3xl grid-cols-1 gap-5 md:grid-cols-2">
<nav class="mx-auto grid w-full max-w-3xl grid-cols-1 gap-4 md:grid-cols-2">
{
prev ? (
<a
href={getGuideUrl(framework, prev.slug)}
class="grid items-center gap-x-2 rounded-xs border border-manila-75 bg-manila-50 p-4 dark:border-soot dark:bg-warm-gray intent:bg-manila-dark dark:intent:bg-soot"
class="grid items-center gap-x-2 rounded-xs border border-manila-dark p-4 dark:border-warm-gray intent:bg-manila-75 dark:intent:bg-warm-gray"
style="grid-template-areas: 'empty direction' 'icon title'; grid-template-columns: auto minmax(0,1fr); grid-template-rows: auto minmax(0,1fr);"
>
<div class="text-p3" style="grid-area: direction;">
@@ -42,7 +42,7 @@ function getGuideUrl(framework: SupportedFramework, slug: string): string {
next ? (
<a
href={getGuideUrl(framework, next.slug)}
class="grid items-center gap-x-2 rounded-xs border border-manila-75 bg-manila-50 p-4 text-right dark:border-soot dark:bg-warm-gray intent:bg-manila-dark dark:intent:bg-soot"
class="grid items-center gap-x-2 rounded-xs border border-manila-dark p-4 text-right dark:border-warm-gray intent:bg-manila-75 dark:intent:bg-warm-gray"
style="grid-template-areas: 'direction empty' 'title icon';grid-template-columns: minmax(0,1fr) auto; grid-template-rows: auto minmax(0,1fr);"
>
<div class="text-p3" style="grid-area: direction;">
@@ -3,13 +3,13 @@ import { Video, videoFeatures } from '@videojs/react/video';
import './BasicUsage.css';
const { Provider, Container, usePlayer } = createPlayer({
const Player = createPlayer({
features: videoFeatures,
});
function Controls() {
const store = usePlayer();
const paused = usePlayer((s) => s.paused);
const store = Player.usePlayer();
const paused = Player.usePlayer((s) => s.paused);
return (
<div className="react-create-player-basic__controls">
@@ -26,8 +26,8 @@ function Controls() {
export default function BasicUsage() {
return (
<Provider>
<Container className="react-create-player-basic">
<Player.Provider>
<Player.Container className="react-create-player-basic">
<Video
src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4"
autoPlay
@@ -35,7 +35,7 @@ export default function BasicUsage() {
playsInline
/>
<Controls />
</Container>
</Provider>
</Player.Container>
</Player.Provider>
);
}
@@ -1,14 +1,14 @@
import { createPlayer, useMedia } from '@videojs/react';
import { createPlayer } from '@videojs/react';
import { Video, videoFeatures } from '@videojs/react/video';
import './BasicUsage.css';
const { Provider, Container } = createPlayer({
const Player = createPlayer({
features: videoFeatures,
});
function MediaInfo() {
const media = useMedia();
const media = Player.useMedia();
if (!media) return null;
@@ -36,8 +36,8 @@ function MediaInfo() {
export default function BasicUsage() {
return (
<Provider>
<Container className="react-use-media-basic">
<Player.Provider>
<Player.Container className="react-use-media-basic">
<Video
src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4"
autoPlay
@@ -46,7 +46,7 @@ export default function BasicUsage() {
loop
/>
<MediaInfo />
</Container>
</Provider>
</Player.Container>
</Player.Provider>
);
}
@@ -1,14 +1,14 @@
import { createPlayer, usePlayer } from '@videojs/react';
import { createPlayer } from '@videojs/react';
import { Video, videoFeatures } from '@videojs/react/video';
import './Selector.css';
const { Provider, Container } = createPlayer({
const Player = createPlayer({
features: videoFeatures,
});
function StateDisplay() {
const state = usePlayer((s) => ({
const state = Player.usePlayer((s) => ({
paused: s.paused,
currentTime: s.currentTime,
duration: s.duration,
@@ -32,8 +32,8 @@ function StateDisplay() {
export default function Selector() {
return (
<Provider>
<Container className="react-use-player-selector">
<Player.Provider>
<Player.Container className="react-use-player-selector">
<Video
src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4"
autoPlay
@@ -42,7 +42,7 @@ export default function Selector() {
loop
/>
<StateDisplay />
</Container>
</Provider>
</Player.Container>
</Player.Provider>
);
}
@@ -1,14 +1,14 @@
import { createPlayer, usePlayer } from '@videojs/react';
import { createPlayer } from '@videojs/react';
import { Video, videoFeatures } from '@videojs/react/video';
import './StoreAccess.css';
const { Provider, Container } = createPlayer({
const Player = createPlayer({
features: videoFeatures,
});
function Controls() {
const store = usePlayer();
const store = Player.usePlayer();
return (
<div className="react-use-player-store__controls">
@@ -24,8 +24,8 @@ function Controls() {
export default function StoreAccess() {
return (
<Provider>
<Container className="react-use-player-store">
<Player.Provider>
<Player.Container className="react-use-player-store">
<Video
src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4"
autoPlay
@@ -34,7 +34,7 @@ export default function StoreAccess() {
loop
/>
<Controls />
</Container>
</Provider>
</Player.Container>
</Player.Provider>
);
}
@@ -1,14 +1,14 @@
import { createPlayer, usePlayer, useStore } from '@videojs/react';
import { createPlayer, useStore } from '@videojs/react';
import { Video, videoFeatures } from '@videojs/react/video';
import './Selector.css';
const { Provider, Container } = createPlayer({
const Player = createPlayer({
features: videoFeatures,
});
function DerivedState() {
const store = usePlayer();
const store = Player.usePlayer();
const derived = useStore(store, (s) => ({
remaining: s.duration - s.currentTime,
progress: s.duration > 0 ? (s.currentTime / s.duration) * 100 : 0,
@@ -30,8 +30,8 @@ function DerivedState() {
export default function Selector() {
return (
<Provider>
<Container className="react-use-store-selector">
<Player.Provider>
<Player.Container className="react-use-store-selector">
<Video
src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4"
autoPlay
@@ -40,7 +40,7 @@ export default function Selector() {
loop
/>
<DerivedState />
</Container>
</Provider>
</Player.Container>
</Player.Provider>
);
}
@@ -1,14 +1,14 @@
import { createPlayer, usePlayer, useStore } from '@videojs/react';
import { createPlayer, useStore } from '@videojs/react';
import { Video, videoFeatures } from '@videojs/react/video';
import './StoreAccess.css';
const { Provider, Container } = createPlayer({
const Player = createPlayer({
features: videoFeatures,
});
function SeekControls() {
const store = usePlayer();
const store = Player.usePlayer();
const s = useStore(store);
return (
@@ -25,8 +25,8 @@ function SeekControls() {
export default function StoreAccess() {
return (
<Provider>
<Container className="react-use-store-access">
<Player.Provider>
<Player.Container className="react-use-store-access">
<Video
src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4"
autoPlay
@@ -35,7 +35,7 @@ export default function StoreAccess() {
loop
/>
<SeekControls />
</Container>
</Provider>
</Player.Container>
</Player.Provider>
);
}
@@ -5,6 +5,6 @@ import H3 from './H3.astro';
const { class: className, ...props } = Astro.props;
---
<H3 as="h3" class:list={["mt-8", className]} {...props}>
<H3 as="h3" class:list={["mt-12", className]} {...props}>
<slot />
</H3>
+1 -1
View File
@@ -9,7 +9,7 @@ export const shared = {
a: 'underline intent:no-underline',
code: 'border border-manila-75 bg-manila-25 dark:bg-soot dark:border-warm-gray px-1 rounded font-mono text-code normal-case',
codeBlock: 'font-mono text-code',
em: 'font-bold',
em: 'italic',
li: 'text-p2',
ol: 'list-decimal list-outside pl-4 space-y-1',
strong: 'font-bold',