PageLayout
Page-body wrapper with a max-width container, default page margins, an optional grid mode, and a spacing scale.
Status: stable. Group: layout. Markdown version: /design-system/components/page-layout.md
When to use
PageLayout is the page-body wrapper: a max-width container with default page margins, an optional grid mode with columns, and a spacing scale. Several structure blocks (GridBlock, ProofBlock, ProjectMetaSection) build on it. Use it to open a page body or section shell; inside components prefer the Grid/FlexBox primitives.
When not to use
The contract records no forbidden uses.
Look-alikes
The contract names no look-alike with a deciding condition.
Props
| Prop | Type | Default | Description | Required |
|---|---|---|---|---|
children | React.ReactNode | none | Content to be displayed within the layout. | Yes |
maxWidth | "sm" | "md" | "lg" | "full" | "xl" | lg | Maximum width constraint for the content. | No |
grid | boolean | false | Whether to use the 12-column grid system. | No |
columns | number | none | Fixed number of equal columns when grid=true, written as an inline grid-template-columns that replaces the responsive 4/8/12 column ladder grid=true gives on its own. Ignored when grid is false. | No |
spacing | "compact" | "default" | "comfortable" | "spacious" | default | Vertical spacing between sections. | No |
withMargins | boolean | true | Apply consistent page margins. | No |
className | string | "" | Additional CSS class name. | No |
as | "article" | "main" | "div" | "section" | div | Semantic HTML element to use for the container. | No |
role | string | none | ARIA role for accessibility. | No |
ariaLabel | string | none | ARIA label for accessibility. | No |
style | React.CSSProperties | none | Inline style merged over the grid columns style; caller values win. | No |
Variants
- Allowed
maxWidthvalues:sm,md,lg,full,xl(defaultlg). - Available spacings:
compact,default,comfortable,spacious(defaultdefault). - Allowed
asvalues:article,main,div,section(defaultdiv).
Invalid combinations
- MUST NOT: When
columnsis set andgridis not set, then also setgrid.columnsonly applies whengridis true;griddefaults to false, so the column count is dropped. - MUST NOT: When
gridisfalse, then do not setcolumns.columnsonly applies whengridis true.
Keyboard
The contract records no keyboard interaction.
Rules
Every item under When not to use is a MUST NOT. MUST and SHOULD follow RFC 2119.
| Level | Rule | How it is checked |
|---|---|---|
| MUST NOT | When columns is set and grid is not set, then also set grid. columns only applies when grid is true; grid defaults to false, so the column count is dropped. | Checked by the MCP tool validate_component_usage (rule pagelayout-columns-need-grid). Also enforced in code: PageLayout.tsx gridStyle: returns {} when !grid. |
| MUST NOT | When grid is false, then do not set columns. columns only applies when grid is true. | Checked by the MCP tool validate_component_usage (rule pagelayout-columns-with-grid-off). Also enforced in code: PageLayout.tsx gridStyle: returns {} when !grid. |
| MUST | Required stories produce no axe violations at the configured severity. | Automated by npm run test:stories:matrix:ci. WCAG 2.5.8. |
| MUST | The accessibility tree (role, name, state) matches the committed snapshot for every required story. | Automated by npm run test:stories:matrix:ci. WCAG 1.3.1, 4.1.2. |
| MUST | The component remains legible and operable under a real browser forced-colors: active pass. | Automated by npm run test:stories:hc. |
| MUST | A human completed an end-to-end accessibility review of this component. | Manual review, last on 2026-11-04. |
| MUST NOT | Maintainers: Do not bypass design tokens or skip forced-colors verification at beta. | Release review; not machine-checked. |
Install and import
- Install:
npm install @digitaltableteur/react(version 0.9.1, restricted access on npm). - Import:
import { PageLayout } from "@digitaltableteur/react"; - Entry point:
@digitaltableteur/react/patternsexports it too. - Styles: import
@digitaltableteur/react/style.cssonce at the app boundary.
Links
- Machine-readable contract (Design System Contract 1.0)
- Markdown version of this page
- Component index as JSON
- All components
- Source: The implementation lives in a private repository. This page, its Markdown twin and the contract are generated from it at build time and are the public source of truth.