Layout
The Layout component provides a set of flexible layout primitives for building consistent UI layouts. It includes Flex, Grid, Horizontal, and Vertical components with a clean, type-safe API.
Flex
The Flex component is a versatile layout container that allows you to arrange items in a row or column with various alignment and spacing options.
Basic flex (row direction)
Flex with column direction
Flex with alignment and justification
Flex with gap
Flex with wrap
Flex with custom element
Grid
The Grid component provides a powerful way to create grid layouts with precise control over columns, rows, and spacing.
Basic grid with equal columns
Grid with different column sizes
Grid with defined rows
Grid with numeric columns
Grid with numeric rows and columns
Grid with alignment and justification
Horizontal
The Horizontal component is a convenient wrapper around Flex that’s pre-configured for row layouts with consistent spacing options.
Horizontal with alignment
Vertical
The Vertical component is a convenient wrapper around Flex that’s pre-configured for column layouts with consistent spacing options.
Vertical with alignment
Two-column layout
Installation
import { Layout } from '@harnessio/ui/components'
// ...
return ( <Layout.Flex gap="md"> {/* children */} </Layout.Flex>)Anatomy
Layout is a collection of four primitives — Layout.Flex, Layout.Grid, Layout.Horizontal, and Layout.Vertical. Each renders a div by default and takes spacing from the design-system scale.
<Layout.Vertical gap="md"> <Layout.Horizontal justify="between" align="center"> {/* … */} </Layout.Horizontal></Layout.Vertical>- Flex — a flexbox container.
directiondefaults torow;align,justify, andwrapare unset until you provide them.growtogglesflex-grow. Flex has no default gap. - Grid — a CSS-grid container.
columnsandrowsaccept either a track string ("2fr 1fr","auto auto") applied verbatim, or a number, which expands to that many equal tracks (repeat(n, …)).flowmaps togrid-auto-flow. Grid has nodirection/wrap. - Horizontal / Vertical — thin wrappers around Flex that lock
directiontorow/column(it can’t be overridden) and defaultgaptomd. Everything else passes straight through to Flex. - Spacing —
gap,gapX, andgapYtake the token scale (none,4xs…4xl) and map togap-cn-*utilities, so spacing stays consistent with the rest of the system. - Polymorphism —
asrenders a different element (e.g.as="span") while keeping the same layout props.
Best practices
Do
- Reach for
Horizontal/Verticalfor the common row/column cases — they read clearly and already defaultgaptomd. - Use
Gridwhen you need real two-dimensional control (aligned columns and rows); useFlexfor one-dimensional flows. - Keep spacing on the token scale (
gap="md") instead of ad-hoc margins so rhythm stays consistent.
Don’t
- Don’t nest many
Flexcontainers to fake a grid — useGridwithcolumns. - Don’t reintroduce raw pixel gaps via
classNamewhen agaptoken exists.
Accessibility
Layout primitives are structural containers — they render a plain element (div by default) and add no roles or semantics of their own.
Labeling
- Because these are generic containers, give meaning through the elements you place inside them (headings, landmarks, lists) or by rendering a semantic element with
as(e.g.as="nav",as="ul").
Known limitations
- No implicit semantics. A
Layout.*won’t announce itself as a region or list; choose the right element viaaswhen structure matters to assistive tech.
Properties
Shared props
Accepted by all four layout primitives.
Prop | Required | Default | Type |
|---|---|---|---|
| gap | false | 'none' | '4xs' | '3xs' | '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | |
| gapX | false | GapSize | |
| gapY | false | GapSize | |
| as | false | 'div' | ElementType |
| className | false | string |
Flex
Prop | Required | Default | Type |
|---|---|---|---|
| direction | false | 'row' | 'row' | 'column' | 'row-reverse' | 'column-reverse' |
| align | false | 'start' | 'center' | 'end' | 'baseline' | 'stretch' | |
| justify | false | 'start' | 'center' | 'end' | 'between' | |
| wrap | false | 'nowrap' | 'wrap' | 'wrap-reverse' | |
| grow | false | boolean |
Grid
Prop | Required | Default | Type |
|---|---|---|---|
| columns | false | string | number | |
| rows | false | string | number | |
| flow | false | 'row' | 'column' | 'dense' | 'row dense' | 'column dense' | |
| align | false | 'start' | 'center' | 'end' | 'baseline' | 'stretch' | |
| justify | false | 'start' | 'center' | 'end' | 'between' |
Horizontal & Vertical
Wrappers around Flex. direction is fixed (row for Horizontal, column for Vertical) and cannot be overridden; all other Flex props pass through.
Prop | Required | Default | Type |
|---|---|---|---|
| gap | false | 'md' | GapSize |
| align | false | 'start' | 'center' | 'end' | 'baseline' | 'stretch' | |
| justify | false | 'start' | 'center' | 'end' | 'between' | |
| ...flexProps | false | Omit<FlexProps, 'direction'> |