mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
132 lines
3.6 KiB
Plaintext
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>
|