tsimport {XDSLayout} from '@xds/core/Layout'
| Guidance | Practices |
|---|---|
| Do | Use XDSLayout for page shells that need distinct zones like header, sidebar(s), content, and footer. |
| Do | Use XDSHStack and XDSVStack for simple directional stacking within a content area. |
| Don't | Use XDSLayout for simple stacking layouts — use XDSHStack or XDSVStack instead. |
| Don't | Nest multiple XDSLayout components — use one per page shell and compose content within its slots. |
| Prop | Type | Description |
|---|---|---|
content | ReactNode | Main content area (center). |
header | ReactNode | Header slot. |
footer | ReactNode | Footer slot. |
start | ReactNode | Start panel (left in LTR). |
end | ReactNode | End panel (right in LTR). |
height | 'fill' | 'auto' (default: 'fill') | Height behavior — fill the container or grow with content. |
| Prop | Type | Description |
|---|---|---|
children | ReactNode | Content. |
isScrollable | boolean (default: true) | Enable scrollable overflow. |
label | string | Accessible label for the landmark element. |
role | AriaRole | ARIA landmark role. |
| Prop | Type | Description |
|---|---|---|
children | ReactNode | Footer content. |
hasDivider | boolean (default: false) | Border at top edge. |
height | number | string | Footer height. |
label | string | Accessible label for the landmark element. |
role | AriaRole | ARIA landmark role. |
| Prop | Type | Description |
|---|---|---|
children | ReactNode | Header content. |
hasDivider | boolean (default: false) | Border at bottom edge. |
height | number | string | Header height. |
label | string | Accessible label for the landmark element. |
role | AriaRole | ARIA landmark role. |
| Prop | Type | Description |
|---|---|---|
children | ReactNode | Panel content. |
hasDivider | boolean (default: false) | Border on the appropriate edge. |
isScrollable | boolean (default: true) | Enable scrollable overflow. |
label | string | Accessible label for the landmark element. |
role | AriaRole | ARIA landmark role. |
tsx'use client';import {XDSLayout,XDSLayoutHeader,XDSLayoutContent,XDSLayoutFooter,XDSHStack,XDSVStack,} from '@xds/core/Layout';import {XDSCard} from '@xds/core/Card';import {XDSButton} from '@xds/core/Button';import {XDSHeading, XDSText} from '@xds/core/Text';export default function LayoutBasicCardLayout() {return (<XDSCard height={300}><XDSLayoutheader={<XDSLayoutHeader hasDivider><XDSHeading level={4}>Card Title</XDSHeading></XDSLayoutHeader>}content={<XDSLayoutContent><XDSVStack gap={3}><XDSText type="body">This is a basic card layout with a header, scrollable contentarea, and footer. The layout automatically handles padding andspacing between sections.</XDSText><XDSText type="body">When content exceeds the available height, the content areascrolls independently while the header and footer stay fixedin place.</XDSText><XDSText type="body">This pattern works well for modal dialogs, detail panels, andany card where the amount of content is unpredictable.</XDSText><XDSText type="body">The dividers between header, content, and footer provide clearvisual boundaries between the fixed and scrollable regions.</XDSText></XDSVStack></XDSLayoutContent>}footer={<XDSLayoutFooter hasDivider><XDSHStack gap={2} hAlign="end"><XDSButton label="Cancel" variant="secondary">Cancel</XDSButton><XDSButton label="Save" variant="primary">Save</XDSButton></XDSHStack></XDSLayoutFooter>}/></XDSCard>);}
tsx'use client';import {XDSLayout, XDSLayoutContent, XDSVStack} from '@xds/core/Layout';import {XDSCard} from '@xds/core/Card';import {XDSHeading, XDSText} from '@xds/core/Text';export default function LayoutContentOnlyLayout() {return (<XDSCard><XDSLayoutcontent={<XDSLayoutContent><XDSVStack gap={3}><XDSHeading level={4}>Simple Content</XDSHeading><XDSText type="body">A layout can have just content without header or footer. Thisis useful for simple cards or content blocks that don't needstructured sections.</XDSText></XDSVStack></XDSLayoutContent>}/></XDSCard>);}
tsx'use client';import {XDSLayout,XDSLayoutHeader,XDSLayoutContent,XDSLayoutFooter,XDSHStack,XDSVStack,} from '@xds/core/Layout';import {XDSButton} from '@xds/core/Button';import {XDSHeading, XDSText} from '@xds/core/Text';export default function LayoutContentWidth() {return (<XDSLayoutheight="fill"contentWidth={360}header={<XDSLayoutHeader hasDivider><XDSHeading level={4}>Centered Form</XDSHeading></XDSLayoutHeader>}content={<XDSLayoutContent><XDSVStack gap={3}><XDSText type="body">The contentWidth prop constrains content to a maximum width andcenters it within the layout. Dividers remain full-bleed whilecontent stays narrow and readable.</XDSText><XDSText type="body" color="secondary">Common widths: 640 for forms, 960 for content pages.</XDSText></XDSVStack></XDSLayoutContent>}footer={<XDSLayoutFooter hasDivider><XDSHStack gap={2} hAlign="end"><XDSButton label="Cancel" variant="secondary">Cancel</XDSButton><XDSButton label="Submit" variant="primary">Submit</XDSButton></XDSHStack></XDSLayoutFooter>}/>);}
tsx'use client';import {XDSLayout,XDSLayoutHeader,XDSLayoutContent,XDSLayoutPanel,XDSVStack,} from '@xds/core/Layout';import {XDSCard} from '@xds/core/Card';import {XDSHeading, XDSText} from '@xds/core/Text';import {XDSList, XDSListItem} from '@xds/core/List';export default function LayoutDualPanelLayout() {return (<XDSCard><XDSLayoutheader={<XDSLayoutHeader hasDivider><XDSHeading level={4}>File Browser</XDSHeading></XDSLayoutHeader>}start={<XDSLayoutPanel hasDivider><XDSVStack gap={1}><XDSText type="label" color="secondary">Folders</XDSText><XDSList><XDSListItem label="Documents" /><XDSListItem label="Projects" isSelected /><XDSListItem label="Downloads" /></XDSList></XDSVStack></XDSLayoutPanel>}content={<XDSLayoutContent><XDSVStack gap={2}><XDSText type="label" color="secondary">Files</XDSText><XDSCard variant="muted"><XDSText type="body">Select a folder to view its contents</XDSText></XDSCard></XDSVStack></XDSLayoutContent>}end={<XDSLayoutPanel hasDivider><XDSVStack gap={2}><XDSText type="label" color="secondary">Details</XDSText><XDSText type="body">Select a file to view details</XDSText></XDSVStack></XDSLayoutPanel>}/></XDSCard>);}
tsx'use client';import {XDSLayout,XDSLayoutHeader,XDSLayoutContent,XDSLayoutFooter,XDSHStack,} from '@xds/core/Layout';import {XDSCard} from '@xds/core/Card';import {XDSButton} from '@xds/core/Button';import {XDSSection} from '@xds/core/Section';import {XDSHeading, XDSText} from '@xds/core/Text';export default function LayoutFullBleedContent() {return (<XDSCard><XDSLayoutheader={<XDSLayoutHeader hasDivider><XDSHeading level={4}>Full Bleed Example</XDSHeading></XDSLayoutHeader>}content={<XDSLayoutContent padding={0}><XDSSection variant="wash"><XDSText type="body">XDSSection automatically escapes the parent container paddingto fill edge-to-edge. Useful for wash backgrounds, tables, orimages that need to span the full width.</XDSText></XDSSection></XDSLayoutContent>}footer={<XDSLayoutFooter hasDivider><XDSHStack gap={2} hAlign="end"><XDSButton label="Close" variant="secondary">Close</XDSButton></XDSHStack></XDSLayoutFooter>}/></XDSCard>);}
tsx'use client';import {XDSLayout,XDSLayoutHeader,XDSLayoutContent,XDSLayoutFooter,XDSLayoutPanel,XDSHStack,XDSVStack,} from '@xds/core/Layout';import {XDSCard} from '@xds/core/Card';import {XDSButton} from '@xds/core/Button';import {XDSHeading, XDSText} from '@xds/core/Text';import {XDSList, XDSListItem} from '@xds/core/List';export default function LayoutSidebarLayout() {return (<XDSCard><XDSLayoutheader={<XDSLayoutHeader hasDivider><XDSHeading level={4}>Settings</XDSHeading></XDSLayoutHeader>}start={<XDSLayoutPanel hasDivider role="navigation" width={140}><XDSList><XDSListItem label="General" isSelected /><XDSListItem label="Account" /><XDSListItem label="Privacy" /><XDSListItem label="Notifications" /><XDSListItem label="Security" /></XDSList></XDSLayoutPanel>}content={<XDSLayoutContent><XDSVStack gap={3}><XDSHeading level={5}>General Settings</XDSHeading><XDSText type="body">Configure your general preferences here. The sidebar navigationallows you to switch between different settings sections.</XDSText></XDSVStack></XDSLayoutContent>}footer={<XDSLayoutFooter hasDivider><XDSHStack gap={2} hAlign="end"><XDSButton label="Reset" variant="secondary">Reset</XDSButton><XDSButton label="Save Changes" variant="primary">Save Changes</XDSButton></XDSHStack></XDSLayoutFooter>}/></XDSCard>);}
tsx'use client';import {XDSLayout,XDSLayoutHeader,XDSLayoutContent,XDSLayoutFooter,XDSLayoutPanel,XDSHStack,XDSVStack,} from '@xds/core/Layout';import {XDSText, XDSHeading} from '@xds/core/Text';import {XDSButton} from '@xds/core/Button';import {XDSBadge} from '@xds/core/Badge';import {XDSList, XDSListItem} from '@xds/core/List';export default function LayoutShowcase() {return (<XDSLayoutheight="fill"header={<XDSLayoutHeader hasDivider><XDSHStack gap={2} vAlign="center"><XDSHeading level={4}>Projects</XDSHeading><XDSBadge variant="info" label="3 active" /></XDSHStack></XDSLayoutHeader>}start={<XDSLayoutPanel hasDivider width={140}><XDSList><XDSListItem label="Dashboard" isSelected /><XDSListItem label="Analytics" /><XDSListItem label="Settings" /></XDSList></XDSLayoutPanel>}content={<XDSLayoutContent><XDSVStack gap={2}><XDSHeading level={5}>Welcome back</XDSHeading><XDSText type="body" color="secondary">You have 3 active projects and 2 pending reviews.</XDSText></XDSVStack></XDSLayoutContent>}footer={<XDSLayoutFooter hasDivider><XDSHStack gap={2} hAlign="end"><XDSButton label="New Project" variant="primary">New Project</XDSButton></XDSHStack></XDSLayoutFooter>}/>);}