Spacing and sizes
A short spacing scale and one height per control size.
Spacing
const STEPS = [
{
name: "1",
value: "4px",
className: "h-4 rounded-xs bg-chart-bar w-1",
usage: "Inside small controls, between toolbar buttons.",
},
{
name: "2",
value: "8px",
className: "h-4 rounded-xs bg-chart-bar w-2",
usage: "Between header controls; header to list toolbar.",
},
{
name: "3",
value: "12px",
className: "h-4 rounded-xs bg-chart-bar w-3",
usage: "Row padding and the gap between row cells.",
},
{
name: "inset",
value: "20px",
className: "h-4 rounded-xs bg-chart-bar w-inset",
usage: "Rows inset from the content edge; page top padding.",
},
{
name: "gutter",
value: "32px",
className: "h-4 rounded-xs bg-chart-bar w-gutter",
usage: "Content gutter: header, toolbar, sections. Inset + row padding = gutter.",
},
];
export default function Spacing() {
return (
<div className="flex flex-col gap-3 bg-default font-sans text-body-md text-default">
{STEPS.map((step) => (
<div className="flex items-center gap-3" key={step.name}>
<code className="w-24 shrink-0 font-medium">{step.name}</code>
<span className="w-18 shrink-0 text-muted tabular-nums">{step.value}</span>
<div className="w-12 shrink-0">
<div className={step.className} />
</div>
<span className="text-muted">{step.usage}</span>
</div>
))}
</div>
);
}
Text in a row lines up with the page gutter: inset 20 + row padding 12 = gutter 32. The sidebar is w-sidebar, 232px.
Control sizes
const SIZES = [
{
name: "control-xs",
value: "22px",
className: "rounded-sm bg-control-pressed h-control-xs",
usage: "Inline dropdowns inside 14px body text.",
},
{
name: "control-sm",
value: "26px",
className: "rounded-sm bg-control-pressed h-control-sm",
usage: "Toolbar and action bar buttons, menu items.",
},
{
name: "control-md",
value: "28px",
className: "rounded-sm bg-control-pressed h-control-md",
usage: "Default: buttons, select and combobox triggers, sidebar items.",
},
{
name: "control-lg",
value: "30px",
className: "rounded-sm bg-control-pressed h-control-lg",
usage: "Default for inputs. Header buttons.",
},
{
name: "chip",
value: "24px",
className: "rounded-sm bg-control-pressed h-chip",
usage: "Filter chips.",
},
{
name: "row",
value: "32px",
className: "rounded-sm bg-control-pressed h-row",
usage: "Table rows. 1px apart, no dividers.",
},
{
name: "row-compact",
value: "28px",
className: "rounded-sm bg-control-pressed h-row-compact",
usage: "Compact tables, meter legends, waterfall trees.",
},
{
name: "row-dense",
value: "26px",
className: "rounded-sm bg-control-pressed h-row-dense",
usage: "Dense tables and waterfall rows.",
},
];
export default function Sizes() {
return (
<div className="flex flex-col gap-3 bg-default font-sans text-body-md text-default">
{SIZES.map((size) => (
<div className="flex items-center gap-3" key={size.name}>
<code className="w-24 shrink-0 font-medium">{size.name}</code>
<span className="w-18 shrink-0 text-muted tabular-nums">{size.value}</span>
<div className="w-30 shrink-0">
<div className={size.className} />
</div>
<span className="text-muted">{size.usage}</span>
</div>
))}
</div>
);
}
mdis the default for buttons and triggers; inputs default tolg.xsonly appears inside 14px body text.- Rows come in three heights:
row32,row-compact28 androw-dense26; nothing else is in between. - One page breakpoint,
mdat 900px: below it, side panels drop under the content. - Tables respond to their own width, not the page: below
table-compact(52rem) they switch to the compact column set, belowtable-stacked(36rem) rows stack.