Files
v10/site/src/components/docs/api-reference/PresetReference.astro
T

221 lines
8.7 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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';
/**
* 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 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((f) => f.name))
.map((part) => {
if (part.type !== "element") {
return <span>{part.value}</span>;
}
const feature = preset.features.find(
(f) => f.name === part.value,
)!;
return feature.hasReference ? (
<DocsLink
class="inline-block whitespace-nowrap"
slug={feature.slug}
>
{feature.name}
</DocsLink>
) : (
<span class="inline-block whitespace-nowrap">
{feature.name}
</span>
);
})
: ""}
</dd>
<dt class="font-bold">Skins</dt>
<dd>
<FrameworkCase frameworks={["react"]}>
{preset.react.skins.length > 0
? preset.react.skins.map((skin) => (
<div class="mb-2 last:mb-0">
<MarkdownCode class="inline-block whitespace-nowrap">{`<${skin.name}>`}</MarkdownCode>
{skin.cssImport && (
<div class="mt-0.5">
<MarkdownCode class="inline-block text-code whitespace-nowrap">{`import '${skin.cssImport}';`}</MarkdownCode>
</div>
)}
</div>
))
: ""}
</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>