Files
v10/site/src/components/docs/api-reference/DetailRow.astro
T
2026-04-22 10:18:05 -05:00

132 lines
3.6 KiB
Plaintext

---
/**
* Expandable table row used by PropRow and StateRow.
*
* Uses button disclosure pattern: the summary row has real `<td>` cells,
* the detail row is a separate `<tr>` toggled via `aria-controls` + `hidden`.
* The entire summary row is clickable, delegating to the toggle button.
*
* The default slot provides the summary cells. This component appends the
* toggle-button cell and renders the expandable detail panel beneath.
*/
import clsx from 'clsx';
import MarkdownCode from '@/components/typography/MarkdownCode.astro';
import Td from '@/components/typography/Td.astro';
import Tr from '@/components/typography/Tr.astro';
import InlineMarkdown from './InlineMarkdown.astro';
interface Props {
id: string;
name: string;
type: string;
attributeName?: string;
detailedType?: string;
description?: string;
colspan: number;
}
const { id, name, attributeName, detailedType, description, colspan } = Astro.props;
const hasDetail = Boolean(attributeName || detailedType || description);
---
<Tr
id={id}
data-apiref-row
class={clsx(
hasDetail &&
"group cursor-pointer data-expanded:border-transparent dark:data-expanded:border-transparent intent:bg-manila-75 dark:intent:bg-soot",
)}
>
<slot />
<Td class="align-top">
{
hasDetail && (
<button
aria-expanded="false"
aria-controls={`${id}-detail`}
aria-label={`Details for ${name}`}
data-apiref-toggle
>
<span
aria-hidden="true"
class="inline-block group-data-expanded:rotate-90"
>
</span>
</button>
)
}
</Td>
</Tr>
{
hasDetail && (
<Tr id={`${id}-detail`} hidden>
<Td colspan={String(colspan)} 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"
>
{attributeName && (
<>
<dt class="font-bold">Attribute</dt>
<dd>
<MarkdownCode>{attributeName}</MarkdownCode>
</dd>
</>
)}
{description && (
<>
<dt class="font-bold">Description</dt>
<dd>
<InlineMarkdown content={description} />
</dd>
</>
)}
{detailedType && (
<>
<dt class="font-bold">Type</dt>
<dd>
<MarkdownCode>{detailedType}</MarkdownCode>
</dd>
</>
)}
</dl>
</div>
</Td>
</Tr>
)
}
<script>
document
.querySelectorAll<HTMLButtonElement>("[data-apiref-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-apiref-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-apiref-row]")
.forEach((row) => {
row.addEventListener("click", (e) => {
if ((e.target as Element).closest("a, button")) return;
row.querySelector<HTMLButtonElement>("[data-apiref-toggle]")?.click();
});
});
</script>