Naledi Mokoena
AcceptedQ-1042 · R 1 240 / mo
A page that lists things: header, filters, then the items.
An index of quotes, builds, members or any other collection; a single record is DetailLayout.
Every quote you have sent.
Q-1042 · R 1 240 / mo
Q-1041 · R 860 / mo
import {
Body,
Button,
Card,
FilterGroup,
ListLayout,
Pill,
ToggleChip,
} from "@hackcove/ui";
<ListLayout
title="Quotes"
subtitle="Every quote you have sent."
actions={<Button>New quote</Button>}
filters={
<FilterGroup legend="Status">
<ToggleChip pressed>All</ToggleChip>
<ToggleChip pressed={false}>Sent</ToggleChip>
</FilterGroup>
}
>
<Card as="article" title="Naledi Mokoena" status={<Pill tone="emerald">Accepted</Pill>}>
<Body as="p">Q-1042 · R 1 240 / mo</Body>
</Card>
<Card as="article" title="Pieter van Wyk" status={<Pill tone="slate">Sent</Pill>}>
<Body as="p">Q-1041 · R 860 / mo</Body>
</Card>
</ListLayout>filters sit under the header, then the rows: one Card per item.Every quote you have sent.
Q-1042 · R 1 240 / mo
import { Body, Card, PageHeader, Stack } from "@hackcove/ui";
<Stack>
<PageHeader title="Quotes" subtitle="Every quote you have sent." />
<Card as="article" title="Naledi Mokoena">
<Body as="p">Q-1042 · R 1 240 / mo</Body>
</Card>
</Stack>ListLayout is the one header, filters and list.Every quote you have sent.
Quotes you send show up here.
import { Body, Button, EmptyState, ListLayout } from "@hackcove/ui";
<ListLayout
title="Quotes"
subtitle="Every quote you have sent."
isEmpty
empty={
<EmptyState title="No quotes yet" actions={<Button>New quote</Button>}>
<Body as="p" color="secondary">
Quotes you send show up here.
</Body>
</EmptyState>
}
/>empty takes the list's place when isEmpty: say what is missing and what to do.Every quote you have sent.
import { ListLayout } from "@hackcove/ui";
<ListLayout title="Quotes" subtitle="Every quote you have sent." isEmpty />
isEmpty without empty leaves a blank page under the header.Every quote you have sent.
Naledi Mokoena
Q-1042 · R 1 240 / mo
Pieter van Wyk
Q-1041 · R 860 / mo
import {
AppShell,
Body,
BodyStrong,
Button,
Card,
FilterGroup,
ListLayout,
NavTabs,
ToggleChip,
} from "@hackcove/ui";
<AppShell
brand={<a href="#">Hack Cove</a>}
nav={
<NavTabs
label="Main"
items={[
{ label: "Quotes", href: "#quotes", active: true },
{ label: "Clients", href: "#clients" },
]}
/>
}
>
<ListLayout
title="Quotes"
subtitle="Every quote you have sent."
actions={<Button>New quote</Button>}
filters={
<FilterGroup legend="Status">
<ToggleChip pressed>All</ToggleChip>
<ToggleChip pressed={false}>Sent</ToggleChip>
<ToggleChip pressed={false}>Accepted</ToggleChip>
</FilterGroup>
}
>
<Card as="article">
<BodyStrong as="p">Naledi Mokoena</BodyStrong>
<Body as="p" color="secondary">
Q-1042 · R 1 240 / mo
</Body>
</Card>
<Card as="article">
<BodyStrong as="p">Pieter van Wyk</BodyStrong>
<Body as="p" color="secondary">
Q-1041 · R 860 / mo
</Body>
</Card>
</ListLayout>
</AppShell>actions in the header props; breadcrumbs and tabs go there too.filters sit between the header and the list: a FilterGroup of ToggleChips.children, one Card per item, or a Table; the layout spaces them.isEmpty and give empty an EmptyState that says what is missing and what to do next; isEmpty without empty is a blank page.PageHeader and Stack: the layout is the one right header, filters and list.h1.filters and children render as given, so each filter group keeps its own fieldset and legend.data-* and aria-* go on the list's wrapper.A list page: header, an optional filters slot, then the list, or empty when isEmpty.
actionsRight of the title on sm and up, below it on a phone.
ReactNodebreadcrumbsA Breadcrumbs above the title.
ReactNodeemptyShown in place of children when isEmpty.
ReactNodefiltersReactNodeisEmptybooleanfalsesubtitleReactNodetabsA NavTabs (or similar) under the title.
ReactNodetitle requiredReactNode