Files
ai-for-dummies/src/components/blocks/HandoffTable.astro
T
Marcos Paulo cac1115035 feat(blocks): add Localized type support to full-guide blocks
Widens prose props on FleetDiagram, HandoffTable, PhasePanel, RouteTable, SkillPackage, and WorktreeMap to accept {en, pt} as well as string, and conditionally renders language spans. Non-prose props (id, code, etc) were left as strings.
2026-09-05 21:59:29 +00:00

174 lines
4.3 KiB
TypeScript

---
// HandoffTable — the four-row "what crosses contexts" table.
//
// Static shell: the row data is passed in via `rows` so this component has
// no opinion on what each handoff package contains. The table structure is
// the load-bearing part of the design (dark header, blue row labels,
// muted body) and lives here so the next page that needs it gets the same
// beat for free.
type Localized = { en: string; pt: string };
interface Row {
/** The package name, rendered as a `<th>` (column 1). */
package: string | Localized;
/** What the package contains (column 2). */
contains: string | Localized;
/** Why this matters (column 3). */
why: string | Localized;
}
interface Props {
/** Column headers in render order. */
columns: [string | Localized, string | Localized, string | Localized];
rows: Row[];
}
const { columns, rows } = Astro.props;
---
<table class="handoff-table">
<thead>
<tr>
<th>
{
typeof columns[0] === 'string' ? (
columns[0]
) : (
<>
<>
<span data-language-content="en">{columns[0].en}</span>
<span data-language-content="pt" hidden>
{columns[0].pt}
</span>
</>
</>
)
}
</th>
<th>
{
typeof columns[1] === 'string' ? (
columns[1]
) : (
<>
<>
<span data-language-content="en">{columns[1].en}</span>
<span data-language-content="pt" hidden>
{columns[1].pt}
</span>
</>
</>
)
}
</th>
<th>
{
typeof columns[2] === 'string' ? (
columns[2]
) : (
<>
<>
<span data-language-content="en">{columns[2].en}</span>
<span data-language-content="pt" hidden>
{columns[2].pt}
</span>
</>
</>
)
}
</th>
</tr>
</thead>
<tbody>
{
rows.map((row) => (
<tr>
<th scope="row">
{typeof row.package === 'string' ? (
row.package
) : (
<>
<span data-language-content="en">{row.package.en}</span>
<span data-language-content="pt" hidden>
{row.package.pt}
</span>
</>
)}
</th>
<td>
{typeof row.contains === 'string' ? (
row.contains
) : (
<>
<span data-language-content="en">{row.contains.en}</span>
<span data-language-content="pt" hidden>
{row.contains.pt}
</span>
</>
)}
</td>
<td>
{typeof row.why === 'string' ? (
row.why
) : (
<>
<span data-language-content="en">{row.why.en}</span>
<span data-language-content="pt" hidden>
{row.why.pt}
</span>
</>
)}
</td>
</tr>
))
}
</tbody>
</table>
<style>
.handoff-table {
width: 100%;
margin-top: 30px;
border-collapse: collapse;
text-align: left;
}
.handoff-table th,
.handoff-table td {
padding: 17px 14px;
border-bottom: 1px solid var(--line);
}
.handoff-table thead {
color: var(--paper);
background: var(--ink);
/* token-gap: source uses 10px; no --step-* covers 10px; owner design-system-keeper */
font:
500 10px 'DM Mono',
monospace;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.handoff-table tbody th {
color: var(--blue);
/* token-gap: source uses 14px; no --step-* covers 14px; owner design-system-keeper */
font:
600 14px 'DM Mono',
monospace;
}
.handoff-table td {
color: var(--muted);
/* token-gap: source uses 13px; no --step-* covers 13px; owner design-system-keeper */
font-size: 13px;
}
@media (max-width: 800px) {
.handoff-table {
display: block;
overflow-x: auto;
}
.handoff-table {
min-width: 650px;
}
}
</style>