Skip to content

Page

Page is a layout primitive for the root of a routed view. It renders a flex column that fills its parent’s height, an optional level-1 heading, and a <main> element that takes the remaining space and clips overflow.

Use Page when every view in an application should share the same outer structure: a column that fills the available height, with the content region below an optional title.

  • Full-height flex column layout
  • Optional visible h1 title
  • A <main> content region that grows to fill the remaining space
  • Standard div attributes forwarded to the root element
import { Page } from '@cratis/components/Common';
export const AuthorsPage = () => (
<Page title='Authors'>
<p>Page content goes here</p>
</Page>
);

By default the title is not rendered. Pass showTitle to render it as an h1 above the content:

<Page title='Authors' showTitle>
<p>Page content goes here</p>
</Page>

When showTitle is false, title is not written to the DOM at all: it does not set document.title, an aria-label, or any other attribute. Set the browser tab title and any hidden heading yourself.

panel adds a bare panel class to the <main> element. The Components stylesheets ship no rule for that class, so it has no visible effect until your own CSS defines .panel:

<Page title='Dashboard' panel>
<p>Content inside the main region</p>
</Page>
PropTypeDefaultDescription
titlestringRequiredPage title. Rendered only when showTitle is true.
showTitlebooleanfalseRenders title as an h1 above the content.
panelbooleanfalseAdds a panel class to <main>. No styling for it ships with Components.
childrenReactNode—Page content, rendered inside <main>.
other propsHTMLAttributes<HTMLDivElement>—Forwarded to the root div (id, style, aria-*, data-*, event handlers, className).

A className you pass is added after the root’s layout classes, so the root keeps its flex column and full height. In Components 4.14.1 and earlier, a passed className replaced those layout classes instead.

  • The root is a flex column that fills its parent’s height (height: 100%, flex: 1).
  • The optional h1 sits at the top.
  • <main> fills the remaining space as a flex column and hides overflow. Put a scrolling element inside it when the content can be taller than the view.

Page renders a <main> landmark. Use one Page per view, and do not put it inside another <main> element, because a document should have only one visible main landmark.

<Page title='Users' showTitle>
<UserList />
</Page>

The content is yours to lay out. Components ships no utility classes, so use your own CSS or inline styles:

<Page title='Dashboard' showTitle>
<section aria-label='Totals' style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '1rem' }}>
<StatCard title='Users' value={totalUsers} />
<StatCard title='Orders' value={totalOrders} />
<StatCard title='Revenue' value={totalRevenue} />
</section>
<section aria-label='Recent activity' style={{ marginTop: '1rem', overflow: 'auto' }}>
<RecentActivity />
</section>
</Page>

StatCard and RecentActivity stand for your own components.

<Page title='Reports' data-view='reports' style={{ backgroundColor: 'var(--cratis-surface-ground)' }}>
<ReportViewer />
</Page>

Page has no routing or data dependencies. Render it as the element of a route in any router, and put any Components or product-owned content inside it.