Main

Defines the page region, title, content gutter, reading width and vertical rhythm.

import { Main } from "@usefragments/ui";Source

Preview

Loading Full Measure preview…

import { Button } from '@usefragments/ui';
import { Main } from '@usefragments/ui';

const content = <p>No findings need attention.</p>;

<Main measure="full">

Usage

Use when

  • Laying out a page's header, description, content, and footer
  • Giving a page one consistent gutter and measure

Avoid when

  • Shell-level navigation chrome (use AppShell)
  • Arbitrary spacing inside a component (use Stack)

Implementation notes

  • One Main per page owns the gutter; AppShell.Main adds none, so do not nest them
  • measure="narrow" caps content for reading; "full" uses the whole canvas
  • Main.Title is the page h1 at the display role (24, strong, ink 1); pass as="h2" for a panel title
  • Main.Description is 12px ink 2 and wraps at the --fui-main-description-max-inline measure (68 characters)
  • Compose regions with Main.Header, Main.Title, Main.Description, Main.Content, Main.Footer

Installation

pnpm add @usefragments/ui

Import styles once from @usefragments/ui/styles. See the installation guide for framework and theme setup.

Anatomy

Import Main once, then compose its parts with dot notation.

  • Main.Header
  • Main.Title
  • Main.Description
  • Main.Content
  • Main.Footer

Content fills the canvas, inset only by the page gutter.

import { Button } from '@usefragments/ui';
import { Main } from '@usefragments/ui';

const content = <p>No findings need attention.</p>;

<Main measure="full">
  <Main.Header>
    <Main.Title>Findings</Main.Title>
    <Main.Description>Every review finding raised against this repository, newest first.</Main.Description>
  </Main.Header>
  <Main.Content>{content}</Main.Content>
  <Main.Footer>
    <Button variant="soft">Export</Button>
  </Main.Footer>
</Main>

Examples

Narrow Measure

Caps content at the reading measure and centres it on wide screens.

Loading Narrow Measure preview…

import { Field } from "@usefragments/ui";
import { Input } from "@usefragments/ui";
import { Button } from '@usefragments/ui';
import { Main } from '@usefragments/ui';

const form = (

API reference

Component props
Prop
Type
Default
Description
alignStackAlign | undefinedcenterstartendbaselinestretchNot setCross-axis alignment
asMainElement | undefineddivmainsectionmainThe page region element. `main` gets id="main-content" unless you pass an id.
childrenRequiredReact.ReactNodeNot setPage regions: Main.Header (with Main.Title and Main.Description), Main.Content, Main.Footer
classNamestring | undefinedNot set—
collapseBelowstring | undefinedNot setA CSS length. The children sit side by side in equal shares while the Stack itself is at least this wide, and stack into a column below it. Measured against the Stack's own width, never the viewport, so it holds inside panes and cards. Implies a row; `direction` is ignored.
Content.alignStackAlign | undefinedcenterstartendbaselinestretchNot setCross-axis alignment
Content.asStackElement | undefineddivarticleasidefooterheadermainnavolsectionulNot setHost element; `ul` and `ol` keep list semantics, dividers included
Content.childrenRequiredReact.ReactNodeNot set—
Content.classNamestring | undefinedNot set—
Content.collapseBelowstring | undefinedNot setA CSS length. The children sit side by side in equal shares while the Stack itself is at least this wide, and stack into a column below it. Measured against the Stack's own width, never the viewport, so it holds inside panes and cards. Implies a row; `direction` is ignored.
Content.directionStackDirection | undefinedrowcolumnNot setDirection children flow in
Content.dividedboolean | undefinedNot setDraw a Separator between children (horizontal in a column, vertical in a row). Inside `ul`/`ol` each divider is a hidden `li`. Ignored when `collapseBelow` is set, since the flow can change under it.
Content.gapStackGap | undefinedxssmmdlgnonexlNot setSpace between children, on the layout gap scale (0, 4, 8, 12, 16, 24)
Content.justifyStackJustify | undefinedcenterstartendbetweenNot setMain-axis distribution
Content.styleReact.CSSProperties | undefinedNot set—
Content.wrapboolean | undefinedNot setLet children wrap onto new lines
Description.alignStackAlign | undefinedcenterstartendbaselinestretchNot setCross-axis alignment
Description.asStackElement | undefineddivarticleasidefooterheadermainnavolsectionulNot setHost element; `ul` and `ol` keep list semantics, dividers included
Description.childrenRequiredReact.ReactNodeNot set—
Description.classNamestring | undefinedNot set—
Description.collapseBelowstring | undefinedNot setA CSS length. The children sit side by side in equal shares while the Stack itself is at least this wide, and stack into a column below it. Measured against the Stack's own width, never the viewport, so it holds inside panes and cards. Implies a row; `direction` is ignored.
Description.directionStackDirection | undefinedrowcolumnNot setDirection children flow in
Description.dividedboolean | undefinedNot setDraw a Separator between children (horizontal in a column, vertical in a row). Inside `ul`/`ol` each divider is a hidden `li`. Ignored when `collapseBelow` is set, since the flow can change under it.
Description.gapStackGap | undefinedxssmmdlgnonexlNot setSpace between children, on the layout gap scale (0, 4, 8, 12, 16, 24)
Description.justifyStackJustify | undefinedcenterstartendbetweenNot setMain-axis distribution
Description.styleReact.CSSProperties | undefinedNot set—
Description.wrapboolean | undefinedNot setLet children wrap onto new lines
dividedboolean | undefinedNot setDraw a Separator between children (horizontal in a column, vertical in a row). Inside `ul`/`ol` each divider is a hidden `li`. Ignored when `collapseBelow` is set, since the flow can change under it.
Footer.alignStackAlign | undefinedcenterstartendbaselinestretchNot setCross-axis alignment
Footer.asStackElement | undefineddivarticleasidefooterheadermainnavolsectionulNot setHost element; `ul` and `ol` keep list semantics, dividers included
Footer.childrenRequiredReact.ReactNodeNot set—
Footer.classNamestring | undefinedNot set—
Footer.collapseBelowstring | undefinedNot setA CSS length. The children sit side by side in equal shares while the Stack itself is at least this wide, and stack into a column below it. Measured against the Stack's own width, never the viewport, so it holds inside panes and cards. Implies a row; `direction` is ignored.
Footer.directionStackDirection | undefinedrowcolumnNot setDirection children flow in
Footer.dividedboolean | undefinedNot setDraw a Separator between children (horizontal in a column, vertical in a row). Inside `ul`/`ol` each divider is a hidden `li`. Ignored when `collapseBelow` is set, since the flow can change under it.
Footer.gapStackGap | undefinedxssmmdlgnonexlNot setSpace between children, on the layout gap scale (0, 4, 8, 12, 16, 24)
Footer.justifyStackJustify | undefinedcenterstartendbetweenNot setMain-axis distribution
Footer.styleReact.CSSProperties | undefinedNot set—
Footer.wrapboolean | undefinedNot setLet children wrap onto new lines
Header.alignStackAlign | undefinedcenterstartendbaselinestretchNot setCross-axis alignment
Header.asStackElement | undefineddivarticleasidefooterheadermainnavolsectionulNot setHost element; `ul` and `ol` keep list semantics, dividers included
Header.childrenRequiredReact.ReactNodeNot set—
Header.classNamestring | undefinedNot set—
Header.collapseBelowstring | undefinedNot setA CSS length. The children sit side by side in equal shares while the Stack itself is at least this wide, and stack into a column below it. Measured against the Stack's own width, never the viewport, so it holds inside panes and cards. Implies a row; `direction` is ignored.
Header.directionStackDirection | undefinedrowcolumnNot setDirection children flow in
Header.dividedboolean | undefinedNot setDraw a Separator between children (horizontal in a column, vertical in a row). Inside `ul`/`ol` each divider is a hidden `li`. Ignored when `collapseBelow` is set, since the flow can change under it.
Header.gapStackGap | undefinedxssmmdlgnonexlNot setSpace between children, on the layout gap scale (0, 4, 8, 12, 16, 24)
Header.justifyStackJustify | undefinedcenterstartendbetweenNot setMain-axis distribution
Header.styleReact.CSSProperties | undefinedNot set—
Header.wrapboolean | undefinedNot setLet children wrap onto new lines
justifyStackJustify | undefinedcenterstartendbetweenNot setMain-axis distribution
measureMainMeasure | undefinedfullnarrowfullMaximum width applied to the page composition
styleReact.CSSProperties | undefinedNot set—
Title.as"h1" | "h2" | undefinedh1h2Not setThe heading level.
Title.childrenRequiredReact.ReactNodeNot set—
wrapboolean | undefinedNot setLet children wrap onto new lines
idstring | undefinedNot setOverrides the default main-content landmark id for a main element.

Accessibility

  • The default <main> carries id="main-content", the Header.SkipLink target
  • Use as="section" or as="div" when another <main> already exists
  • Main.Title renders the page's h1

Next steps