feat(site): feature and preset reference UI + docs integration (#1258)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Darius Cepulis
2026-04-14 17:19:01 -05:00
committed by GitHub
co-authored by Claude Opus 4.6
parent 5301202a18
commit d4b805ea69
35 changed files with 643 additions and 234 deletions
@@ -0,0 +1,228 @@
---
import { getCollection } from 'astro:content';
import ContentWidth from '@/components/frames/ContentWidth.astro';
import MarkdownCode from '@/components/typography/MarkdownCode.astro';
import Table from '@/components/typography/Table.astro';
import Tbody from '@/components/typography/Tbody.astro';
import Td from '@/components/typography/Td.astro';
import Th from '@/components/typography/Th.astro';
import Thead from '@/components/typography/Thead.astro';
import Tr from '@/components/typography/Tr.astro';
import { isValidFramework } from '@/types/docs';
import type { PresetReference as PresetReferenceType } from '@/types/preset-reference';
import DocsLink from '../DocsLink.astro';
import FrameworkCase from '../FrameworkCase.astro';
import InlineMarkdown from './InlineMarkdown.astro';
const entries = await getCollection('presetReference');
const PINNED_PRESETS = ['video', 'audio'];
const presets: PresetReferenceType[] = entries
.map((e) => e.data)
.sort((a, b) => {
const aPin = PINNED_PRESETS.indexOf(a.name);
const bPin = PINNED_PRESETS.indexOf(b.name);
if (aPin !== -1 && bPin !== -1) return aPin - bPin;
if (aPin !== -1) return -1;
if (bPin !== -1) return 1;
return a.name.localeCompare(b.name);
});
const { framework } = Astro.params;
const pkg = framework && isValidFramework(framework) ? `@videojs/${framework}` : '@videojs/html';
/**
* Feature slug overrides for cases where kebabCase(featureName) doesn't
* match the docs page slug.
*/
const FEATURE_SLUG_OVERRIDES: Record<string, string> = {
textTrack: 'text-tracks',
};
/**
* Native media elements used by presets that don't have a custom element.
* The pipeline can't detect these since they're not classes with `static tagName`.
*/
const NATIVE_MEDIA_ELEMENTS: Record<string, string> = {
video: 'video',
audio: 'audio',
};
function featureDocsSlug(featureName: string): string {
const override = FEATURE_SLUG_OVERRIDES[featureName];
if (override) return `reference/feature-${override}`;
const kebab = featureName.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
return `reference/feature-${kebab}`;
}
function htmlMediaElement(preset: PresetReferenceType): string | undefined {
return preset.html.mediaElement ?? NATIVE_MEDIA_ELEMENTS[preset.name];
}
const listFormat = new Intl.ListFormat('en', { style: 'long', type: 'unit' });
---
<ContentWidth>
<Table maxWidth={false} outerClass="my-6">
<Thead>
<Tr>
<Th>Import</Th>
<Th>Description</Th>
<Th><span class="sr-only">Details</span></Th>
</Tr>
</Thead>
<Tbody>
{
presets.map((preset) => {
const id = `preset-${preset.name}`;
const htmlMedia = htmlMediaElement(preset);
return (
<>
<Tr
id={id}
data-preset-row
class="group cursor-pointer data-expanded:border-transparent dark:data-expanded:border-transparent intent:bg-manila-75 dark:intent:bg-soot"
>
<Td class="align-top">
<MarkdownCode>{`${pkg}/${preset.name}`}</MarkdownCode>
</Td>
<Td class="align-top">
{preset.description && (
<InlineMarkdown content={preset.description} />
)}
</Td>
<Td class="align-top">
<button
aria-expanded="false"
aria-controls={`${id}-detail`}
aria-label={`Details for ${preset.name} preset`}
data-preset-toggle
>
<span
aria-hidden="true"
class="inline-block group-data-expanded:rotate-90"
>
</span>
</button>
</Td>
</Tr>
<Tr id={`${id}-detail`} hidden>
<Td colspan="3" class="p-0">
<div class="px-6 py-4">
<dl
class="grid grid-cols-(--grid-cols) gap-x-6 gap-y-3"
style="--grid-cols: auto 1fr"
>
<dt class="font-bold">Feature bundle</dt>
<dd>
<MarkdownCode>{preset.featureBundle}</MarkdownCode>
</dd>
<dt class="font-bold">Features</dt>
<dd>
{preset.features.length > 0
? listFormat
.formatToParts(preset.features)
.map((part) =>
part.type === "element" ? (
<DocsLink
class="inline-block whitespace-nowrap"
slug={featureDocsSlug(part.value)}
>
{part.value}
</DocsLink>
) : (
<span>{part.value}</span>
),
)
: ""}
</dd>
<dt class="font-bold">Skins</dt>
<dd>
<FrameworkCase frameworks={["react"]}>
{preset.react.skins.length > 0
? listFormat
.formatToParts(
preset.react.skins.map((s) => s.name),
)
.map((part) =>
part.type === "element" ? (
<MarkdownCode class="inline-block whitespace-nowrap">{`<${part.value}>`}</MarkdownCode>
) : (
<span>{part.value}</span>
),
)
: ""}
</FrameworkCase>
<FrameworkCase frameworks={["html"]}>
{preset.html.skins.length > 0
? listFormat
.formatToParts(
preset.html.skins.map(
(s) => s.tagName ?? s.name,
),
)
.map((part) =>
part.type === "element" ? (
<MarkdownCode class="inline-block whitespace-nowrap">{`<${part.value}>`}</MarkdownCode>
) : (
<span>{part.value}</span>
),
)
: ""}
</FrameworkCase>
</dd>
<dt class="font-bold">Default media element</dt>
<dd>
<FrameworkCase frameworks={["react"]}>
<MarkdownCode>{`<${preset.react.mediaElement}>`}</MarkdownCode>
</FrameworkCase>
<FrameworkCase frameworks={["html"]}>
{htmlMedia ? (
<MarkdownCode>{`<${htmlMedia}>`}</MarkdownCode>
) : (
""
)}
</FrameworkCase>
</dd>
</dl>
</div>
</Td>
</Tr>
</>
);
})
}
</Tbody>
</Table>
</ContentWidth>
<script>
document
.querySelectorAll<HTMLButtonElement>("[data-preset-toggle]")
.forEach((button) => {
button.addEventListener("click", () => {
const expanded = button.getAttribute("aria-expanded") === "true";
button.setAttribute("aria-expanded", String(!expanded));
const row = button.closest<HTMLTableRowElement>("[data-preset-row]");
if (row) row.toggleAttribute("data-expanded", !expanded);
const detail = document.getElementById(
button.getAttribute("aria-controls")!,
);
if (detail) detail.hidden = expanded;
});
});
document
.querySelectorAll<HTMLTableRowElement>("[data-preset-row]")
.forEach((row) => {
row.addEventListener("click", (e) => {
if ((e.target as Element).closest("a, button")) return;
row.querySelector<HTMLButtonElement>("[data-preset-toggle]")?.click();
});
});
</script>