Layout tables
Five layout treatments for real data: a sticky header over a scrolling body, a height-capped scroll area with an edge fade, fixed equal columns with truncation, a wide set with a pinned first column, and a dense grid. Each renders a real semantic table with no props.
Installation
The styled layer is free and installs like any other ai2 component.
Run the following command
npx shadcn@latest add @ai2/table-layoutDependencies, the @ai2/tokens theme and the component file are installed together.
Copy the source
components/ui/table-layout.tsx"use client"
import type * as React from "react"
import { cn } from "@/lib/utils"
/* Layout table family: 5 layout treatments. A sticky header, a scrolling body, fixed
column widths (table-fixed + truncation), a wide data set (a sticky first column)
and dense rows. Color comes ONLY from semantic tokens, via alpha color-mix. No
animation, pure CSS; deterministic and renders with no props too. */
export type StyledSize = "sm" | "md" | "lg" | "xl"
type Column = { key: string; label: React.ReactNode }
type Row = Record<string, React.ReactNode>
type TableProps = {
className?: string
size?: StyledSize
columns?: Column[]
rows?: Row[]
}
/* A sensible default data set so it renders without props. */
const defaultColumns: Column[] = [
{ key: "name", label: "Name" },
{ key: "role", label: "Role" },
{ key: "status", label: "Status" },
]
const defaultRows: Row[] = [
{ name: "Ada Lovelace", role: "Engineer", status: "Active" },
{ name: "Alan Turing", role: "Researcher", status: "Active" },
{ name: "Grace Hopper", role: "Architect", status: "Away" },
{ name: "Katherine Johnson", role: "Analyst", status: "Active" },
]
/* A longer, deterministic list for the scrolling variants. */
const longRows: Row[] = defaultRows.concat(
defaultRows.map((r) => ({ ...r, name: `${String(r.name)} II` })),
defaultRows.map((r) => ({ ...r, name: `${String(r.name)} III` })),
defaultRows.map((r) => ({ ...r, name: `${String(r.name)} IV` }))
)
/* A multi-column data set for the wide variant. */
const wideColumns: Column[] = [
{ key: "name", label: "Name" },
{ key: "role", label: "Role" },
{ key: "team", label: "Team" },
{ key: "location", label: "Location" },
{ key: "started", label: "Started" },
{ key: "email", label: "Email" },
{ key: "status", label: "Status" },
]
const wideRows: Row[] = [
{ name: "Ada Lovelace", role: "Engineer", team: "Platform", location: "London", started: "2019", email: "ada@example.com", status: "Active" },
{ name: "Alan Turing", role: "Researcher", team: "Research", location: "Manchester", started: "2020", email: "alan@example.com", status: "Active" },
{ name: "Grace Hopper", role: "Architect", team: "Core", location: "New York", started: "2018", email: "grace@example.com", status: "Away" },
{ name: "Katherine Johnson", role: "Analyst", team: "Data", location: "Hampton", started: "2021", email: "katherine@example.com", status: "Active" },
]
/* A long-text data set for the fixed-width variant (so the clipping is visible). */
const fixedRows: Row[] = [
{ name: "Ada Lovelace", role: "Principal engineer, compiler and runtime platform", status: "Active" },
{ name: "Alan Turing", role: "Researcher, computability and machine intelligence", status: "Active" },
{ name: "Grace Hopper", role: "Architect, distributed systems and tooling", status: "Away" },
{ name: "Katherine Johnson", role: "Analyst, orbital mechanics and trajectory review", status: "Active" },
]
/* Hucre yogunlugu: padding + metin olcegi. */
const cell: Record<StyledSize, string> = {
sm: "px-2.5 py-1.5 text-xs",
md: "px-3 py-2 text-sm",
lg: "px-4 py-2.5 text-sm",
xl: "px-5 py-3 text-base",
}
const headCell: Record<StyledSize, string> = {
sm: "px-2.5 py-1.5 text-xs",
md: "px-3 py-2 text-xs",
lg: "px-4 py-2.5 text-sm",
xl: "px-5 py-3 text-sm",
}
/* An even tighter scale for the dense variant. */
const denseCell: Record<StyledSize, string> = {
sm: "px-2 py-0.5 text-xs",
md: "px-2 py-1 text-xs",
lg: "px-2.5 py-1 text-sm",
xl: "px-3 py-1.5 text-sm",
}
const tableBase = "w-full border-collapse text-left align-middle text-foreground"
const headBase = "font-medium text-muted-foreground"
function resolve(columns: Column[] | undefined, rows: Row[] | undefined, fbCols: Column[], fbRows: Row[]) {
return {
cols: columns && columns.length > 0 ? columns : fbCols,
data: rows && rows.length > 0 ? rows : fbRows,
}
}
/* StickyHeader: the header stays pinned to the top edge while the body scrolls vertically. */
export function StickyHeaderTable({ className, size = "md", columns, rows }: TableProps) {
const { cols, data } = resolve(columns, rows, defaultColumns, longRows)
return (
<div
data-slot="styled-table"
className={cn("max-h-64 w-full overflow-auto rounded-lg border border-border", className)}
>
<table className={tableBase}>
<thead className="sticky top-0 z-10">
<tr>
{cols.map((col) => (
<th
key={col.key}
scope="col"
className={cn(headBase, headCell[size], "border-b border-border bg-muted")}
>
{col.label}
</th>
))}
</tr>
</thead>
<tbody>
{data.map((row, i) => (
<tr key={i} className="border-b border-border/60 last:border-b-0">
{cols.map((col) => (
<td key={col.key} className={cell[size]}>
{row[col.key]}
</td>
))}
</tr>
))}
</tbody>
</table>
</div>
)
}
/* Scroll: sinirli yukseklikte kaydirilan govde, alt kenarda yumusama serit. */
export function ScrollTable({ className, size = "md", columns, rows }: TableProps) {
const { cols, data } = resolve(columns, rows, defaultColumns, longRows)
return (
<div
data-slot="styled-table"
className={cn("relative w-full rounded-lg border border-border", className)}
>
<div className="max-h-56 w-full overflow-auto rounded-lg">
<table className={tableBase}>
<thead>
<tr className="border-b border-border bg-muted">
{cols.map((col) => (
<th key={col.key} scope="col" className={cn(headBase, headCell[size])}>
{col.label}
</th>
))}
</tr>
</thead>
<tbody>
{data.map((row, i) => (
<tr key={i} className="border-b border-border/60 last:border-b-0">
{cols.map((col) => (
<td key={col.key} className={cell[size]}>
{row[col.key]}
</td>
))}
</tr>
))}
</tbody>
</table>
</div>
<div
aria-hidden="true"
className="pointer-events-none absolute inset-x-0 bottom-0 h-8 rounded-b-lg bg-gradient-to-t from-[color-mix(in_oklab,var(--color-background)_90%,transparent)] to-transparent"
/>
</div>
)
}
/* Fixed: table-fixed ile esit kolon genisligi, tasan metin kirpilir. */
export function FixedTable({ className, size = "md", columns, rows }: TableProps) {
const { cols, data } = resolve(columns, rows, defaultColumns, fixedRows)
return (
<div
data-slot="styled-table"
className={cn("w-full overflow-hidden rounded-lg border border-border", className)}
>
<table className={cn(tableBase, "table-fixed")}>
<thead>
<tr className="border-b border-border bg-muted">
{cols.map((col) => (
<th key={col.key} scope="col" className={cn(headBase, headCell[size], "truncate")}>
{col.label}
</th>
))}
</tr>
</thead>
<tbody>
{data.map((row, i) => (
<tr key={i} className="border-b border-border/60 last:border-b-0">
{cols.map((col) => (
<td key={col.key} className={cn(cell[size], "truncate")}>
{row[col.key]}
</td>
))}
</tr>
))}
</tbody>
</table>
</div>
)
}
/* Wide: the multi-column data set scrolls horizontally while the first column stays stuck to the left. */
export function WideTable({ className, size = "md", columns, rows }: TableProps) {
const { cols, data } = resolve(columns, rows, wideColumns, wideRows)
return (
<div
data-slot="styled-table"
className={cn("w-full overflow-x-auto rounded-lg border border-border", className)}
>
<table className={cn(tableBase, "min-w-[52rem]")}>
<thead>
<tr className="border-b border-border">
{cols.map((col, j) => (
<th
key={col.key}
scope="col"
className={cn(
headBase,
headCell[size],
"bg-muted whitespace-nowrap",
j === 0 && "sticky left-0 z-10 border-r border-border"
)}
>
{col.label}
</th>
))}
</tr>
</thead>
<tbody>
{data.map((row, i) => (
<tr key={i} className="border-b border-border/60 last:border-b-0">
{cols.map((col, j) => (
<td
key={col.key}
className={cn(
cell[size],
"whitespace-nowrap",
j === 0 &&
"sticky left-0 z-10 border-r border-border bg-background font-medium"
)}
>
{row[col.key]}
</td>
))}
</tr>
))}
</tbody>
</table>
</div>
)
}
/* Dense: cok yogun satirlar, ince ayraclar, maksimum veri yogunlugu. */
export function DenseTable({ className, size = "md", columns, rows }: TableProps) {
const { cols, data } = resolve(columns, rows, defaultColumns, longRows)
return (
<div
data-slot="styled-table"
className={cn("w-full overflow-x-auto rounded-lg border border-border", className)}
>
<table className={cn(tableBase, "leading-tight")}>
<thead>
<tr className="border-b border-border bg-muted">
{cols.map((col) => (
<th
key={col.key}
scope="col"
className={cn(headBase, denseCell[size], "whitespace-nowrap uppercase tracking-wide")}
>
{col.label}
</th>
))}
</tr>
</thead>
<tbody>
{data.map((row, i) => (
<tr
key={i}
className="border-b border-border/40 last:border-b-0 hover:bg-[color-mix(in_oklab,var(--color-foreground)_5%,transparent)]"
>
{cols.map((col) => (
<td key={col.key} className={cn(denseCell[size], "whitespace-nowrap")}>
{row[col.key]}
</td>
))}
</tr>
))}
</tbody>
</table>
</div>
)
}Manual installs skip the @ai2/tokens theme, so add the token CSS from the theming guide or the tone colors will be missing.
Variations
5 takes on the same idea. Each is its own export, and every one accepts a size prop (sm, md, lg, xl) aligned to the base Button scale.
Sticky header
The header stays pinned while the body scrolls vertically.
| Name | Role | Status |
|---|---|---|
| Ada Lovelace | Engineer | Active |
| Alan Turing | Researcher | Active |
| Grace Hopper | Architect | Away |
| Katherine Johnson | Analyst | Active |
| Ada Lovelace II | Engineer | Active |
| Alan Turing II | Researcher | Active |
| Grace Hopper II | Architect | Away |
| Katherine Johnson II | Analyst | Active |
| Ada Lovelace III | Engineer | Active |
| Alan Turing III | Researcher | Active |
| Grace Hopper III | Architect | Away |
| Katherine Johnson III | Analyst | Active |
| Ada Lovelace IV | Engineer | Active |
| Alan Turing IV | Researcher | Active |
| Grace Hopper IV | Architect | Away |
| Katherine Johnson IV | Analyst | Active |
import { StickyHeaderTable } from "@/components/ui/table-layout"
<StickyHeaderTable />| Name | Role | Status |
|---|---|---|
| Ada Lovelace | Engineer | Active |
| Alan Turing | Researcher | Active |
| Grace Hopper | Architect | Away |
| Katherine Johnson | Analyst | Active |
| Ada Lovelace II | Engineer | Active |
| Alan Turing II | Researcher | Active |
| Grace Hopper II | Architect | Away |
| Katherine Johnson II | Analyst | Active |
| Ada Lovelace III | Engineer | Active |
| Alan Turing III | Researcher | Active |
| Grace Hopper III | Architect | Away |
| Katherine Johnson III | Analyst | Active |
| Ada Lovelace IV | Engineer | Active |
| Alan Turing IV | Researcher | Active |
| Grace Hopper IV | Architect | Away |
| Katherine Johnson IV | Analyst | Active |
| Name | Role | Status |
|---|---|---|
| Ada Lovelace | Engineer | Active |
| Alan Turing | Researcher | Active |
| Grace Hopper | Architect | Away |
| Katherine Johnson | Analyst | Active |
| Ada Lovelace II | Engineer | Active |
| Alan Turing II | Researcher | Active |
| Grace Hopper II | Architect | Away |
| Katherine Johnson II | Analyst | Active |
| Ada Lovelace III | Engineer | Active |
| Alan Turing III | Researcher | Active |
| Grace Hopper III | Architect | Away |
| Katherine Johnson III | Analyst | Active |
| Ada Lovelace IV | Engineer | Active |
| Alan Turing IV | Researcher | Active |
| Grace Hopper IV | Architect | Away |
| Katherine Johnson IV | Analyst | Active |
| Name | Role | Status |
|---|---|---|
| Ada Lovelace | Engineer | Active |
| Alan Turing | Researcher | Active |
| Grace Hopper | Architect | Away |
| Katherine Johnson | Analyst | Active |
| Ada Lovelace II | Engineer | Active |
| Alan Turing II | Researcher | Active |
| Grace Hopper II | Architect | Away |
| Katherine Johnson II | Analyst | Active |
| Ada Lovelace III | Engineer | Active |
| Alan Turing III | Researcher | Active |
| Grace Hopper III | Architect | Away |
| Katherine Johnson III | Analyst | Active |
| Ada Lovelace IV | Engineer | Active |
| Alan Turing IV | Researcher | Active |
| Grace Hopper IV | Architect | Away |
| Katherine Johnson IV | Analyst | Active |
| Name | Role | Status |
|---|---|---|
| Ada Lovelace | Engineer | Active |
| Alan Turing | Researcher | Active |
| Grace Hopper | Architect | Away |
| Katherine Johnson | Analyst | Active |
| Ada Lovelace II | Engineer | Active |
| Alan Turing II | Researcher | Active |
| Grace Hopper II | Architect | Away |
| Katherine Johnson II | Analyst | Active |
| Ada Lovelace III | Engineer | Active |
| Alan Turing III | Researcher | Active |
| Grace Hopper III | Architect | Away |
| Katherine Johnson III | Analyst | Active |
| Ada Lovelace IV | Engineer | Active |
| Alan Turing IV | Researcher | Active |
| Grace Hopper IV | Architect | Away |
| Katherine Johnson IV | Analyst | Active |
Scroll
A height-capped scrolling body with a fade at the bottom edge.
| Name | Role | Status |
|---|---|---|
| Ada Lovelace | Engineer | Active |
| Alan Turing | Researcher | Active |
| Grace Hopper | Architect | Away |
| Katherine Johnson | Analyst | Active |
| Ada Lovelace II | Engineer | Active |
| Alan Turing II | Researcher | Active |
| Grace Hopper II | Architect | Away |
| Katherine Johnson II | Analyst | Active |
| Ada Lovelace III | Engineer | Active |
| Alan Turing III | Researcher | Active |
| Grace Hopper III | Architect | Away |
| Katherine Johnson III | Analyst | Active |
| Ada Lovelace IV | Engineer | Active |
| Alan Turing IV | Researcher | Active |
| Grace Hopper IV | Architect | Away |
| Katherine Johnson IV | Analyst | Active |
import { ScrollTable } from "@/components/ui/table-layout"
<ScrollTable />| Name | Role | Status |
|---|---|---|
| Ada Lovelace | Engineer | Active |
| Alan Turing | Researcher | Active |
| Grace Hopper | Architect | Away |
| Katherine Johnson | Analyst | Active |
| Ada Lovelace II | Engineer | Active |
| Alan Turing II | Researcher | Active |
| Grace Hopper II | Architect | Away |
| Katherine Johnson II | Analyst | Active |
| Ada Lovelace III | Engineer | Active |
| Alan Turing III | Researcher | Active |
| Grace Hopper III | Architect | Away |
| Katherine Johnson III | Analyst | Active |
| Ada Lovelace IV | Engineer | Active |
| Alan Turing IV | Researcher | Active |
| Grace Hopper IV | Architect | Away |
| Katherine Johnson IV | Analyst | Active |
| Name | Role | Status |
|---|---|---|
| Ada Lovelace | Engineer | Active |
| Alan Turing | Researcher | Active |
| Grace Hopper | Architect | Away |
| Katherine Johnson | Analyst | Active |
| Ada Lovelace II | Engineer | Active |
| Alan Turing II | Researcher | Active |
| Grace Hopper II | Architect | Away |
| Katherine Johnson II | Analyst | Active |
| Ada Lovelace III | Engineer | Active |
| Alan Turing III | Researcher | Active |
| Grace Hopper III | Architect | Away |
| Katherine Johnson III | Analyst | Active |
| Ada Lovelace IV | Engineer | Active |
| Alan Turing IV | Researcher | Active |
| Grace Hopper IV | Architect | Away |
| Katherine Johnson IV | Analyst | Active |
| Name | Role | Status |
|---|---|---|
| Ada Lovelace | Engineer | Active |
| Alan Turing | Researcher | Active |
| Grace Hopper | Architect | Away |
| Katherine Johnson | Analyst | Active |
| Ada Lovelace II | Engineer | Active |
| Alan Turing II | Researcher | Active |
| Grace Hopper II | Architect | Away |
| Katherine Johnson II | Analyst | Active |
| Ada Lovelace III | Engineer | Active |
| Alan Turing III | Researcher | Active |
| Grace Hopper III | Architect | Away |
| Katherine Johnson III | Analyst | Active |
| Ada Lovelace IV | Engineer | Active |
| Alan Turing IV | Researcher | Active |
| Grace Hopper IV | Architect | Away |
| Katherine Johnson IV | Analyst | Active |
| Name | Role | Status |
|---|---|---|
| Ada Lovelace | Engineer | Active |
| Alan Turing | Researcher | Active |
| Grace Hopper | Architect | Away |
| Katherine Johnson | Analyst | Active |
| Ada Lovelace II | Engineer | Active |
| Alan Turing II | Researcher | Active |
| Grace Hopper II | Architect | Away |
| Katherine Johnson II | Analyst | Active |
| Ada Lovelace III | Engineer | Active |
| Alan Turing III | Researcher | Active |
| Grace Hopper III | Architect | Away |
| Katherine Johnson III | Analyst | Active |
| Ada Lovelace IV | Engineer | Active |
| Alan Turing IV | Researcher | Active |
| Grace Hopper IV | Architect | Away |
| Katherine Johnson IV | Analyst | Active |
Fixed
table-fixed gives equal column widths and truncates overflow.
| Name | Role | Status |
|---|---|---|
| Ada Lovelace | Principal engineer, compiler and runtime platform | Active |
| Alan Turing | Researcher, computability and machine intelligence | Active |
| Grace Hopper | Architect, distributed systems and tooling | Away |
| Katherine Johnson | Analyst, orbital mechanics and trajectory review | Active |
import { FixedTable } from "@/components/ui/table-layout"
<FixedTable />| Name | Role | Status |
|---|---|---|
| Ada Lovelace | Principal engineer, compiler and runtime platform | Active |
| Alan Turing | Researcher, computability and machine intelligence | Active |
| Grace Hopper | Architect, distributed systems and tooling | Away |
| Katherine Johnson | Analyst, orbital mechanics and trajectory review | Active |
| Name | Role | Status |
|---|---|---|
| Ada Lovelace | Principal engineer, compiler and runtime platform | Active |
| Alan Turing | Researcher, computability and machine intelligence | Active |
| Grace Hopper | Architect, distributed systems and tooling | Away |
| Katherine Johnson | Analyst, orbital mechanics and trajectory review | Active |
| Name | Role | Status |
|---|---|---|
| Ada Lovelace | Principal engineer, compiler and runtime platform | Active |
| Alan Turing | Researcher, computability and machine intelligence | Active |
| Grace Hopper | Architect, distributed systems and tooling | Away |
| Katherine Johnson | Analyst, orbital mechanics and trajectory review | Active |
| Name | Role | Status |
|---|---|---|
| Ada Lovelace | Principal engineer, compiler and runtime platform | Active |
| Alan Turing | Researcher, computability and machine intelligence | Active |
| Grace Hopper | Architect, distributed systems and tooling | Away |
| Katherine Johnson | Analyst, orbital mechanics and trajectory review | Active |
Wide
A many-column set scrolls sideways while the first column stays pinned.
| Name | Role | Team | Location | Started | Status | |
|---|---|---|---|---|---|---|
| Ada Lovelace | Engineer | Platform | London | 2019 | ada@example.com | Active |
| Alan Turing | Researcher | Research | Manchester | 2020 | alan@example.com | Active |
| Grace Hopper | Architect | Core | New York | 2018 | grace@example.com | Away |
| Katherine Johnson | Analyst | Data | Hampton | 2021 | katherine@example.com | Active |
import { WideTable } from "@/components/ui/table-layout"
<WideTable />| Name | Role | Team | Location | Started | Status | |
|---|---|---|---|---|---|---|
| Ada Lovelace | Engineer | Platform | London | 2019 | ada@example.com | Active |
| Alan Turing | Researcher | Research | Manchester | 2020 | alan@example.com | Active |
| Grace Hopper | Architect | Core | New York | 2018 | grace@example.com | Away |
| Katherine Johnson | Analyst | Data | Hampton | 2021 | katherine@example.com | Active |
| Name | Role | Team | Location | Started | Status | |
|---|---|---|---|---|---|---|
| Ada Lovelace | Engineer | Platform | London | 2019 | ada@example.com | Active |
| Alan Turing | Researcher | Research | Manchester | 2020 | alan@example.com | Active |
| Grace Hopper | Architect | Core | New York | 2018 | grace@example.com | Away |
| Katherine Johnson | Analyst | Data | Hampton | 2021 | katherine@example.com | Active |
| Name | Role | Team | Location | Started | Status | |
|---|---|---|---|---|---|---|
| Ada Lovelace | Engineer | Platform | London | 2019 | ada@example.com | Active |
| Alan Turing | Researcher | Research | Manchester | 2020 | alan@example.com | Active |
| Grace Hopper | Architect | Core | New York | 2018 | grace@example.com | Away |
| Katherine Johnson | Analyst | Data | Hampton | 2021 | katherine@example.com | Active |
| Name | Role | Team | Location | Started | Status | |
|---|---|---|---|---|---|---|
| Ada Lovelace | Engineer | Platform | London | 2019 | ada@example.com | Active |
| Alan Turing | Researcher | Research | Manchester | 2020 | alan@example.com | Active |
| Grace Hopper | Architect | Core | New York | 2018 | grace@example.com | Away |
| Katherine Johnson | Analyst | Data | Hampton | 2021 | katherine@example.com | Active |
Dense
Maximum data density: tight rows and hairline separators.
| Name | Role | Status |
|---|---|---|
| Ada Lovelace | Engineer | Active |
| Alan Turing | Researcher | Active |
| Grace Hopper | Architect | Away |
| Katherine Johnson | Analyst | Active |
| Ada Lovelace II | Engineer | Active |
| Alan Turing II | Researcher | Active |
| Grace Hopper II | Architect | Away |
| Katherine Johnson II | Analyst | Active |
| Ada Lovelace III | Engineer | Active |
| Alan Turing III | Researcher | Active |
| Grace Hopper III | Architect | Away |
| Katherine Johnson III | Analyst | Active |
| Ada Lovelace IV | Engineer | Active |
| Alan Turing IV | Researcher | Active |
| Grace Hopper IV | Architect | Away |
| Katherine Johnson IV | Analyst | Active |
import { DenseTable } from "@/components/ui/table-layout"
<DenseTable />| Name | Role | Status |
|---|---|---|
| Ada Lovelace | Engineer | Active |
| Alan Turing | Researcher | Active |
| Grace Hopper | Architect | Away |
| Katherine Johnson | Analyst | Active |
| Ada Lovelace II | Engineer | Active |
| Alan Turing II | Researcher | Active |
| Grace Hopper II | Architect | Away |
| Katherine Johnson II | Analyst | Active |
| Ada Lovelace III | Engineer | Active |
| Alan Turing III | Researcher | Active |
| Grace Hopper III | Architect | Away |
| Katherine Johnson III | Analyst | Active |
| Ada Lovelace IV | Engineer | Active |
| Alan Turing IV | Researcher | Active |
| Grace Hopper IV | Architect | Away |
| Katherine Johnson IV | Analyst | Active |
| Name | Role | Status |
|---|---|---|
| Ada Lovelace | Engineer | Active |
| Alan Turing | Researcher | Active |
| Grace Hopper | Architect | Away |
| Katherine Johnson | Analyst | Active |
| Ada Lovelace II | Engineer | Active |
| Alan Turing II | Researcher | Active |
| Grace Hopper II | Architect | Away |
| Katherine Johnson II | Analyst | Active |
| Ada Lovelace III | Engineer | Active |
| Alan Turing III | Researcher | Active |
| Grace Hopper III | Architect | Away |
| Katherine Johnson III | Analyst | Active |
| Ada Lovelace IV | Engineer | Active |
| Alan Turing IV | Researcher | Active |
| Grace Hopper IV | Architect | Away |
| Katherine Johnson IV | Analyst | Active |
| Name | Role | Status |
|---|---|---|
| Ada Lovelace | Engineer | Active |
| Alan Turing | Researcher | Active |
| Grace Hopper | Architect | Away |
| Katherine Johnson | Analyst | Active |
| Ada Lovelace II | Engineer | Active |
| Alan Turing II | Researcher | Active |
| Grace Hopper II | Architect | Away |
| Katherine Johnson II | Analyst | Active |
| Ada Lovelace III | Engineer | Active |
| Alan Turing III | Researcher | Active |
| Grace Hopper III | Architect | Away |
| Katherine Johnson III | Analyst | Active |
| Ada Lovelace IV | Engineer | Active |
| Alan Turing IV | Researcher | Active |
| Grace Hopper IV | Architect | Away |
| Katherine Johnson IV | Analyst | Active |
| Name | Role | Status |
|---|---|---|
| Ada Lovelace | Engineer | Active |
| Alan Turing | Researcher | Active |
| Grace Hopper | Architect | Away |
| Katherine Johnson | Analyst | Active |
| Ada Lovelace II | Engineer | Active |
| Alan Turing II | Researcher | Active |
| Grace Hopper II | Architect | Away |
| Katherine Johnson II | Analyst | Active |
| Ada Lovelace III | Engineer | Active |
| Alan Turing III | Researcher | Active |
| Grace Hopper III | Architect | Away |
| Katherine Johnson III | Analyst | Active |
| Ada Lovelace IV | Engineer | Active |
| Alan Turing IV | Researcher | Active |
| Grace Hopper IV | Architect | Away |
| Katherine Johnson IV | Analyst | Active |
ai2 Layout tables: 5 styled variations on the token system
The ai2 Layout tables are a set of 5 decorative button variations from the styled layer of the @ai2 design system, built around data table layout treatments for scrolling, fixed and wide data. They are free and MIT licensed, and every color comes from a semantic token, so they theme with the rest of ai2 in light and dark.
Motion runs on framer-motion: row hover states run on token CSS transitions. The styled layer is opt-in, so the dependency only lands if you use it; the base components stay lean. Under reduced motion, the hover transitions are disabled and rows stay static.
What is in the ai2 Layout tables?
5 exports in one file: Sticky header, Scroll, Fixed, Wide and Dense. Each renders a native button and takes a size prop (sm, md, lg, xl) aligned to the base Button. They are separate from the base Button on purpose: the base keeps its clean variant, tone and size axes, while the styled layer carries the effects.
You own the file. Copy the one category file and you have all 5 variations, with no runtime dependency on ai2 itself.
Why use it
- On-system by construction: Every color resolves to an ai2 semantic token, so the buttons follow your theme in light and dark with no extra work.
- Effect without the sprawl: The decorations live in a dedicated styled file, so the base Button keeps its clean, predictable API.
- Accessible and honest: Each renders a real button element, keeps a visible focus ring, and respects prefers-reduced-motion.
Features
- Token-driven color: No hardcoded hex or oklch; the look recolors with your theme tokens.
- framer-motion: row hover states run on token CSS transitions.
- Reduced-motion aware: Under prefers-reduced-motion, the hover transitions are disabled and rows stay static.
- Size aligned to the base: Every variation takes sm, md, lg and xl matching the base Button height scale, so styled and base buttons line up in a row.
Production tips
- Use it for emphasis, not everywhere: Styled buttons draw the eye. Reserve them for the one action you want people to take on a screen, and use the base Button for the rest.
- Keep labels as verbs: The decoration adds weight, so a clear action label keeps the button scannable.
- Pick one variation per surface: The variations share a family; using two different ones in the same view competes for attention.
Works with the rest of ai2
The Layout tables sit alongside the base Button and the rest of the @ai2 registry. They share the same token file, so a styled action next to a base button or a badge stays visually consistent in both modes.