Surfaces
Containers with a visual boundary that group related content.
Card #
Content card (Bulma/Mantine/Bootstrap).
Deployed 4 minutes ago from main.
const cardImage = "/images/cover.jpg";
<Card style={{ "max-width": "22rem" }}>
<CardImage>
<img src={cardImage} alt="Project cover" width="640" height="280" />
</CardImage>
<CardContent>
<strong>marketing-site</strong>
<Text muted>Deployed 4 minutes ago from main.</Text>
</CardContent>
<CardFooter>
<CardFooterItem onClick={() => {}}>Visit</CardFooterItem>
<CardFooterItem onClick={() => {}}>Logs</CardFooterItem>
</CardFooter>
</Card>| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children | content | CardHeader, CardImage, CardContent, CardFooter, or any content. |
Also accepts the shared props: pass-through attributes, class, style, classes, styles, unstyled.
Parts
CardHeader #
Card header row.
Billing
<Card>
<CardHeader>
<CardHeaderTitle>Billing</CardHeaderTitle>
</CardHeader>
<CardContent>Pro plan · renews Oct 1</CardContent>
</Card>| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children | content | Content of this part. |
CardHeaderTitle #
Title text inside a card header.
Billing
<Card>
<CardHeader>
<CardHeaderTitle>Billing</CardHeaderTitle>
</CardHeader>
</Card>| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children | content | Content of this part. |
CardImage #
Full-bleed media at the top of a card.
const cardImage = "/images/cover.jpg";
<Card style={{ "max-width": "22rem" }}>
<CardImage>
<img src={cardImage} alt="Project cover" width="640" height="280" />
</CardImage>
</Card>| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children | content | Content of this part. |
CardContent #
Padded body of a card.
<Card>
<CardContent>Card content is padded and flows like body text.</CardContent>
</Card>| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children | content | Content of this part. |
CardFooter #
Card footer row of actions.
<Card>
<CardContent>Delete this project?</CardContent>
<CardFooter>
<CardFooterItem onClick={() => {}}>Cancel</CardFooterItem>
<CardFooterItem onClick={() => {}}>Delete</CardFooterItem>
</CardFooter>
</Card>| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children | content | Content of this part. |
CardFooterItem #
One action cell in a card footer (a button when onClick is set).
<Card>
<CardFooter>
<CardFooterItem onClick={() => {}}>
Save
</CardFooterItem>
<CardFooterItem onClick={() => {}}>Cancel</CardFooterItem>
</CardFooter>
</Card>| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children | content | Content of this part. | ||
onClick | (e: MouseEvent) => void | Makes the item a button; called when pressed. |
Box #
Bordered surface for grouping content.
<Box>Boxes group related content on a raised surface.</Box>| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children | content | Box content. |
Also accepts the shared props: pass-through attributes, class, style, classes, styles, unstyled.
Panel #
Side panel / filter panel (Bulma).
function Example() {
const repos = [
{ name: "arachne", visibility: "public" },
{ name: "marketing-site", visibility: "private" },
{ name: "design-tokens", visibility: "public" },
];
const tab = signal("all");
const active = signal("arachne");
const shown = () => repos.filter((r) => tab() === "all" || r.visibility === tab());
return (
<Panel label="Repositories" style={{ "max-width": "22rem" }}>
<PanelHeading>Repositories</PanelHeading>
<PanelTabs>
<For each={["all", "public", "private"]}>
{(id) => (
<PanelTab active={tab() === id} onClick={() => tab.set(id)}>
{id[0]?.toUpperCase() + id.slice(1)}
</PanelTab>
)}
</For>
</PanelTabs>
<For each={shown()}>
{(repo) => (
<PanelBlock active={active() === repo.name} onClick={() => active.set(repo.name)}>
{repo.name}
</PanelBlock>
)}
</For>
</Panel>
);
}| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children | content | PanelHeading, PanelTabs and PanelBlocks. | ||
label | string | Accessible name of the panel's <nav> landmark; set it when a page has several panels. |
Also accepts the shared props: pass-through attributes, class, style, classes, styles, unstyled.
Parts
PanelHeading #
Heading row of a panel.
<Panel label="Projects">
<PanelHeading>Repositories</PanelHeading>
<PanelBlock>arachne</PanelBlock>
</Panel>| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children | content | Content of this part. |
PanelTabs #
Tab row inside a panel.
function Example() {
const tab = signal("all");
return (
<Panel label="Filter tabs">
<PanelTabs>
<PanelTab active={tab() === "all"} onClick={() => tab.set("all")}>
All
</PanelTab>
<PanelTab active={tab() === "forks"} onClick={() => tab.set("forks")}>
Forks
</PanelTab>
</PanelTabs>
</Panel>
);
}| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children | content | Content of this part. |
PanelTab #
One tab in a panel's tab row.
function Example() {
const tab = signal("all");
return (
<Panel label="Sources">
<PanelTabs>
<PanelTab active={tab() === "all"} onClick={() => tab.set("all")}>
All
</PanelTab>
<PanelTab active={tab() === "forks"} onClick={() => tab.set("forks")}>
Forks
</PanelTab>
</PanelTabs>
</Panel>
);
}| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
active | boolean | Marks the selected tab. | ||
children | content | Tab label. | ||
onClick | (e: MouseEvent) => void | Called when the tab is pressed. |
PanelBlock #
Panel row; renders a <button> when onClick is set.
function Example() {
const active = signal("marketing-site");
return (
<Panel label="Recent projects">
<PanelBlock
active={active() === "marketing-site"}
onClick={() => active.set("marketing-site")}
>
marketing-site
</PanelBlock>
<PanelBlock active={active() === "docs"} onClick={() => active.set("docs")}>
docs
</PanelBlock>
</Panel>
);
}| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
active | boolean | Marks the selected row. | ||
children | content | Row content. | ||
onClick | (e: MouseEvent) => void | Makes the row a button; called when pressed. |
Paper & tiles #
Plain surfaces and tile layouts.
Paper #
Surface paper (Mantine).
<Paper padding="lg" shadow withBorder>
Paper is the plainest surface: padding, radius, optional border and shadow.
</Paper>| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children | content | Paper content. | ||
padding | "sm" | "md" | "lg" | Inner padding. | ||
shadow | boolean | Adds a soft shadow. | ||
withBorder | boolean | Adds a border. |
Tile #
Nestable tile grid (Bulma).
<Tile ancestor>
<Tile parent size={8}>
<Tile child>
<Box>Wide tile</Box>
</Tile>
</Tile>
<Tile parent>
<Tile child>
<Box>Narrow</Box>
</Tile>
</Tile>
</Tile>| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
ancestor | boolean | Outermost tile of a tile layout. | ||
child | boolean | A leaf tile holding content. | ||
children | content | Nested tiles or content. | ||
parent | boolean | A tile that contains child tiles. | ||
size | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Width in twelfths. | ||
vertical | boolean | Stack the inner tiles vertically. |
Block #
Vertical spacing block (Bulma).
<div>
<Block>A block adds the standard bottom margin between siblings.</Block>
<Block>Like this second one.</Block>
</div>| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children | content | Block content. |
Inset #
Recessed panel (canvas background, border) for secondary content inside a surface.
Recessed area for secondary content, like a settings preview.
<Inset>
<Text muted>Recessed area for secondary content, like a settings preview.</Text>
</Inset>| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children | content | Recessed content. |
Also accepts the shared props: pass-through attributes, class, style, classes, styles, unstyled.