Patterns
How the components combine into jsonresume.org pages.
Page anatomy
Yellow header, gray title band, white content, alternating bands, quiet footer.
page structure
<SkipLink />
<SiteHeader brand={<Logo />}>…</SiteHeader>
<main id="main">
<PageHeader title="Themes" description="…" />
<Section>
<Container>…content…</Container>
</Section>
<Section tone="subtle">
<Container>…related content…</Container>
</Section>
</main>
<SiteFooter links={[…]} />Landing page
A Hero followed by a row of Features on a gray band.
JSON Resume
The open-source initiative to create a JSON-based standard for resumes. For developers, by developers.
hero/promo.tsx
import { Button, Hero } from '@jsonresume/ui';
export default function HeroPromo() {
return (
<Hero
title="JSON Resume"
lede="The open-source initiative to create a JSON-based standard for resumes. For developers, by developers."
actions={
<Button variant="primary" size="lg">
Read more
</Button>
}
/>
);
}What is this?
JSON Resume is a standard created to empower developers.
Themes
Browse our gallery of resume themes made by the community.
Open Source
Every part of JSON Resume is open source on GitHub.
feature/row.tsx
import { Button, Container, Feature, Grid, Section } from '@jsonresume/ui';
export default function FeatureRow() {
return (
<Section tone="subtle">
<Container>
<Grid minColumnWidth="14rem" gap={8}>
<Feature title="What is this?" action={<Button>Get started</Button>}>
JSON Resume is a standard created to empower developers.
</Feature>
<Feature title="Themes" action={<Button>View themes</Button>}>
Browse our gallery of resume themes made by the community.
</Feature>
<Feature title="Open Source" action={<Button>View on GitHub</Button>}>
Every part of JSON Resume is open source on GitHub.
</Feature>
</Grid>
</Container>
</Section>
);
}Documentation page
A NavList beside Prose, inside a wide Container.
This styleguide is the reference implementation: a sticky NavList in a 14rem column and the article in the rest, collapsing to a single column below 992px.
Forms
Your resume is read from a gist named resume.json.
Enter an email address like name@example.com.
Show code
field/basic.tsx
import { Field, Input, Stack } from '@jsonresume/ui';
import * as styles from './basic.css';
export default function FieldBasic() {
return (
<Stack gap={5} className={styles.root}>
<Field label="Full name" required>
<Input autoComplete="name" />
</Field>
<Field
label="GitHub username"
hint="Your resume is read from a gist named resume.json."
>
<Input placeholder="thomasdavis" />
</Field>
<Field
label="Email"
error="Enter an email address like name@example.com."
>
<Input type="email" defaultValue="thomas@" />
</Field>
</Stack>
);
}field/basic.css.ts
import { style } from '@vanilla-extract/css';
export const root = style({ width: 'min(100%, 22rem)' });- One column, labels above controls, hints above the control.
- Validate on submit, then on change for fields that have shown an error.
- One primary button, on the end, named for the outcome.
Destructive actions
Show code
dialog/confirm.tsx
'use client';
import {
Button,
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogTitle,
DialogTrigger,
} from '@jsonresume/ui';
export default function DialogConfirm() {
return (
<Dialog>
<DialogTrigger asChild>
<Button variant="danger">Delete resume</Button>
</DialogTrigger>
<DialogContent>
<DialogTitle>Delete your resume?</DialogTitle>
<DialogDescription>
Your gist stays on GitHub. This only removes the registry copy and its
cached renders.
</DialogDescription>
<DialogFooter>
<DialogClose asChild>
<Button variant="ghost">Cancel</Button>
</DialogClose>
<DialogClose asChild>
<Button variant="primary">Delete</Button>
</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>
);
}