App Page
Give every page of your app the same header and gutter, so each one starts at the same place.
import { AppPage } from '@youj/react'
Installation & usage
npm i @youj/reactFor an app already set up with npx @youj/cli init, which installs the peers (@youj/core, @youj/motion, motion and Base UI) and wires the provider. New app? Start at Installation.
Put each page of your app in AppPage, inside your frame's content area. Build an app frame puts the sidebar, top bar, account menu and search around it. The in-app screens use it, so a page of your own sits beside them with the same header and the same edges.
import { AppPage, Button } from '@youj/react'
export function Invoices() {
return (
<AppPage title="Invoices" description="Everything you've billed this year." actions={<Button>New invoice</Button>} width="fill">
{/* your sections */}
</AppPage>
)
}width sets how far the body runs. page (the default) stops at 1280px at 100% scale and centers, so a wide screen gets margins. fill takes the whole width, for a dashboard, a table, a board or a canvas. readable stops at 1024px and centers, for a page that is one form, such as settings. A page of tables, cards or lists fills; cap a field's own width rather than the page's.
The page is a container, so what's inside lays out by the page's width rather than the window's: use @3xl: and @6xl: in your sections. The gutter is 16px, 24px from a 48rem page and 32px from 72rem; the frame's top bars (see Build an app frame) follow the same gutter.
Description
A page with its title, a line under it, two actions at the end, and its sections on the page's gutter.
Code
app-page-demo.tsx, the Demo story. The component itself comes from the package.
Reference
Propstitle, description, actions, width…
Props
| Prop | Type | |
|---|---|---|
title | ReactNodeThe page's heading. | – |
description | ReactNodeA line under the title. | – |
actions | ReactNodeThe header's buttons, at its end: a primary action, a range control, a menu. | – |
headingLevel | 1 | 2 | 3The title's heading level; your sections' titles sit one below it. default 1 | 1 |
width | 'page' | 'fill' | 'readable'How wide the body runs: default 'page' | 'page' |
classNames | Partial<Record<'header' | 'body', string>>Extra classes for the header and for the body (the padded column that holds the header and your sections). | – |
children | ReactNodeThe page's sections, stacked on the page's gutter. | – |
Other props pass through: extends ComponentProps<'div'>. | ||
data-slot marks its parts: app-page, app-page-body, app-page-header, app-page-title, app-page-description and app-page-actions.
Reduced motionAppPage is static
Reduced motion
AppPage is static. Nothing changes under reduced motion.
AccessibilityHeading level, landmarks
Accessibility
- The title is an
h1by default. SetheadingLevelwhen the page sits under another heading, and give your sections the level below it. - AppPage draws no landmark of its own: the frame's
mainholds it. Under a top bar that already names the page, the frame'sAppFrame(the copy-inframe-shell) hides the title visually and keeps it for screen readers, so the page still has its heading.