Layout
Panel
A bounded work area: header with actions, scrolling body, footer with actions.
import { Panel } from '@jsonresume/ui'Source(opens in a new tab)
Examples
Senior Engineer · Stripe
- Location
- Remote (Americas)
- Salary
- $180k–$220k
Build the payments platform used by millions of businesses. You'll own services end to end, from design reviews to on-call, and work closely with product and design. The body scrolls; the header and footer stay put.
Show code
panel/job.tsx
import { Button, DescriptionList, Panel, Text } from '@jsonresume/ui';
import { X } from 'lucide-react';
import * as styles from './job.css';
export default function PanelJob() {
return (
<Panel
className={styles.root}
title="Senior Engineer · Stripe"
maxHeight="22rem"
actions={
<Button variant="ghost" size="icon" aria-label="Close panel">
<X aria-hidden="true" />
</Button>
}
footer={
<>
<Button variant="ghost">Hide</Button>
<Button variant="primary">Apply</Button>
</>
}
>
<DescriptionList
items={[
{ term: 'Location', description: 'Remote (Americas)' },
{ term: 'Salary', description: '$180k–$220k' },
]}
/>
<Text className={styles.copy}>
Build the payments platform used by millions of businesses. You'll
own services end to end, from design reviews to on-call, and work
closely with product and design. The body scrolls; the header and footer
stay put.
</Text>
</Panel>
);
}panel/job.css.ts
import { style } from '@vanilla-extract/css';
import { vars } from '@jsonresume/ui/tokens';
export const root = style({ width: 'min(100%, 26rem)' });
export const copy = style({ marginTop: vars.space[4] });Accessibility
- A region named by its heading; set headingLevel to fit the outline.
Props
<Panel>
| Prop | Type | Default | Description |
|---|---|---|---|
| title required | ReactNode | – | |
| actions | ReactNode | – | Controls in the header (close, more). |
| footer | ReactNode | – | Sticky footer, e.g. Apply / Cancel. |
| headingLevel | 234 | 2 | |
| maxHeight | string | – | Bound the panel's height (any CSS length); the body scrolls. |