import * as React from 'react';
import { DataTable, type DataTableColumn } from '@/components/data-table';
import { useMessages } from '~/i18n';
import type { PropDoc, SpecTable } from '~/registry/types';
import { SectionHeading } from './section';
/**
* The two reference tables a component page ends with, both drawn by the kit's
* own `DataTable`.
*
* They were hand-written `
` markup, which is exactly the kind of thing a
* doc site should not be doing while the package it documents ships a table:
* the pinned first column, the horizontal scroll shadows and the sort affordance
* were all being re-implemented badly, and any change to the kit's table left
* these two behind. The props table is now sortable by name for free, which is
* what you want on a component with thirty of them.
*/
export function PropTable({ props }: { props: readonly PropDoc[] }) {
const m = useMessages();
const columns: DataTableColumn[] = React.useMemo(
() => [
{
key: 'name',
title: m.table.prop,
dataIndex: 'name',
sortable: true,
/* Pinned because the type column is the wide one: scrolling right to
read a signature must not take the prop's name off screen. */
fixed: 'left',
className: 'font-mono text-xs whitespace-nowrap',
/* The asterisk is `aria-hidden` and the word is `sr-only`, the same
split `FieldLabel` uses: the marker draws the requirement, the text
announces it. A required prop is a compile error to omit, so this is
the one column where it belongs. */
render: (_value, prop) =>
prop.required ? (
<>
{prop.name}
*
{m.table.required}
>
) : (
prop.name
),
},
{
key: 'type',
title: m.table.type,
dataIndex: 'type',
className: 'font-mono text-xs text-muted-foreground',
},
{
key: 'default',
title: m.table.default,
render: (_value, prop) => prop.default ?? '—',
className: 'font-mono text-xs whitespace-nowrap text-muted-foreground',
},
{
key: 'description',
title: m.table.description,
dataIndex: 'description',
minWidth: 260,
className: 'text-muted-foreground',
},
],
[m]
);
return (
{/* `h2` — see the note in `playground.tsx`. */}
);
}
/**
* Measurements taken from the Figma component set. This is the number you check
* when a control looks a pixel off — the live component is above it on the same
* page, so there is nothing to switch between.
*
* A `SpecTable` is positional (`head` plus rows of cells) rather than keyed, so
* the rows are lifted into records here. The index is the row key: two rows of
* a spec table can legitimately be identical.
*/
export function SpecTableView({ spec }: { spec: SpecTable }) {
const m = useMessages();
const rows = React.useMemo(
() => spec.rows.map((cells, index) => ({ index, cells })),
[spec.rows]
);
const columns: DataTableColumn<(typeof rows)[number]>[] = React.useMemo(
() =>
spec.head.map((title, column) => ({
key: column,
title,
render: (_value, row) => row.cells[column] ?? '',
className: 'font-mono text-xs',
})),
[spec.head]
);
return (
);
}