Sandbox Layout
The SandboxLayout component is the outer scaffold used by most full-page screens. It provides a stable grid shell with an optional left navigation panel, a fixed header, and a scrollable main content area. It’s a set of compound layout primitives — you compose the pieces you need.
Because it establishes full-viewport structure (min-height: 100vh, a fixed header, sticky panels), it’s documented here with its anatomy and code rather than an inline live preview.
import { SandboxLayout } from "@harnessio/ui/components";
<SandboxLayout.Root> {/* Optional left navigation column (sticky, full height) */} <SandboxLayout.LeftPanel>{/* nav */}</SandboxLayout.LeftPanel>
{/* Optional secondary nav column */} <SandboxLayout.LeftSubPanel>{/* sub-nav */}</SandboxLayout.LeftSubPanel>
<SandboxLayout.Main> <SandboxLayout.Header>{/* breadcrumbs / top bar */}</SandboxLayout.Header> <SandboxLayout.SubHeader>{/* tabs */}</SandboxLayout.SubHeader>
<SandboxLayout.Content maxWidth="5xl"> {/* page content */} </SandboxLayout.Content> </SandboxLayout.Main></SandboxLayout.Root>;Variations
Columns
Use SandboxLayout.Columns / SandboxLayout.Column to split content into a grid. columnWidths accepts any CSS grid-template-columns value (default 'repeat(2, 1fr)').
<SandboxLayout.Columns columnWidths="1fr 320px"> <SandboxLayout.Column>{/* primary */}</SandboxLayout.Column> <SandboxLayout.Column>{/* sidebar */}</SandboxLayout.Column></SandboxLayout.Columns>Installation
import { SandboxLayout } from "@harnessio/ui/components";
<SandboxLayout.Root> <SandboxLayout.Main> <SandboxLayout.Content maxWidth="5xl"> {/* page content */} </SandboxLayout.Content> </SandboxLayout.Main></SandboxLayout.Root>;Anatomy
SandboxLayout is a set of compound primitives. SandboxLayout.Root is a full-height grid (auto | 1fr); a navigation column sits in the first track and SandboxLayout.Main fills the second.
SandboxLayout.Root— the full-height grid shell (min-height: 100vh), rendered as<main role="main">. It takeschildrenonly.SandboxLayout.LeftPanel— the primary navigation column (fixed 220px, sticky, full height). It’s a<nav>and is hidden below themdbreakpoint.SandboxLayout.LeftSubPanel— an optional secondary nav column (fixed 300px) with a right border and its own scroll. UnlikeLeftPanel, it stays visible on small screens and is not sticky.SandboxLayout.Main— the main content section (<section>). PassfullWidthto let it flex to fill available space.SandboxLayout.Header— a fixed top header (<header role="banner">) sized to the breadcrumbs height.SandboxLayout.SubHeader— a secondary header row sized to the tabs-nav height, for section tabs.SandboxLayout.Content— the page body.maxWidth(sm–7xl) constrains and centers the content; leave it off for full-bleed.SandboxLayout.Columns/SandboxLayout.Column— a grid container and its cells for multi-column content.
Best practices
Do
- Use one
SandboxLayout.Rootper screen as the outermost element of the page. - Put primary navigation in
LeftPaneland reserveLeftSubPanelfor a secondary, context-specific nav. - Set
Content maxWidthon reading-heavy pages so lines don’t stretch across very wide viewports; leave it off for dashboards and tables that want the full width.
Don’t
- Don’t nest a second
Rootinside the layout — it establishes the viewport grid once. - Don’t rely on
LeftSubPanelfor critical navigation on small screens if it would crowd the content; it isn’t hidden belowmdthe wayLeftPanelis.
Accessibility
Landmarks
- The parts render as real landmarks:
Rootis<main role="main">,Headeris<header role="banner">,LeftPanelis a<nav aria-label="Left Navigation Panel">,LeftSubPanelis a labelled<section>, andMainis a labelled<section>. This gives assistive tech a navigable page structure out of the box. Columnsexposesrole="grid"withColumnasrole="gridcell".
Focus & states
Headeris fixed andLeftPanelis sticky, so they stay in view asContentscrolls. Keep interactive elements inside these regions reachable and not obscured by the fixed header.
Properties
SandboxLayout.Root
Prop | Required | Default | Type |
|---|---|---|---|
| children | false | ReactNode |
SandboxLayout.LeftPanel
Sticky, full-height left navigation column (220px), hidden below md.
Prop | Required | Default | Type |
|---|---|---|---|
| children | false | ReactNode | |
| className | false | string |
SandboxLayout.LeftSubPanel
Scrollable secondary nav column (300px) with a right border.
Prop | Required | Default | Type |
|---|---|---|---|
| children | false | ReactNode | |
| className | false | string |
SandboxLayout.Main
Prop | Required | Default | Type |
|---|---|---|---|
| children | false | ReactNode | |
| fullWidth | false | boolean | |
| className | false | string |
SandboxLayout.Header
Fixed top header, sized to the breadcrumbs height.
Prop | Required | Default | Type |
|---|---|---|---|
| children | false | ReactNode | |
| className | false | string |
SandboxLayout.SubHeader
Secondary header row, sized to the tabs-nav height.
Prop | Required | Default | Type |
|---|---|---|---|
| children | false | ReactNode | |
| className | false | string |
SandboxLayout.Content
Prop | Required | Default | Type |
|---|---|---|---|
| children | false | ReactNode | |
| maxWidth | false | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl' | '7xl' | |
| className | false | string |
SandboxLayout.Columns
Prop | Required | Default | Type |
|---|---|---|---|
| children | false | ReactNode | |
| columnWidths | false | 'repeat(2, 1fr)' | string |
| className | false | string |
SandboxLayout.Column
Prop | Required | Default | Type |
|---|---|---|---|
| children | false | ReactNode | |
| className | false | string |