Import
import { Layout } from '@contentful/f36-components';// orimport { Layout } from '@contentful/f36-layout';
Layout Compound Components
The Layout exports the following compound components
Compound Component | Description | Typical Usage Area |
|---|---|---|
Layout.Header | Should contain a | header |
Layout.Sidebar | Allows for variants | leftSidebar, rightSidebar |
Layout.Body | Wrapper around all children, this compound component is essential for proper overflow and scrolling behaviors. | wrapper around all children of Layout |
Examples
Basic Layout with body only
function BasicLayoutExample() {const [submitting, setSubmitting] = useState(false);const submitForm = () => {setSubmitting(true);setTimeout(() => setSubmitting(false), 1000);};return (<Layout><Layout.Body><Box padding="none" marginBottom="spacingXl"><Form onSubmit={submitForm}><FormControl><FormControl.Label isRequired>Name</FormControl.Label><TextInput /><FormControl.HelpText>Please enter your first name</FormControl.HelpText></FormControl><FormControl><FormControl.Label>Description</FormControl.Label><Textarea /><FormControl.HelpText>Tell me about yourself</FormControl.HelpText></FormControl><Button variant="primary" type="submit" isDisabled={submitting}>{submitting ? 'Submitted' : 'Click me to submit'}</Button></Form></Box></Layout.Body></Layout>);}
Layout with header
function BasicLayoutExample() {const [submitting, setSubmitting] = useState(false);const submitForm = () => {setSubmitting(true);setTimeout(() => setSubmitting(false), 1000);};return (<Layoutheader={<Layout.Header><Header title="Your Details" /></Layout.Header>}><Layout.Body><Box padding="none" marginBottom="spacingXl"><Form onSubmit={submitForm}><FormControl><FormControl.Label isRequired>Name</FormControl.Label><TextInput /><FormControl.HelpText>Please enter your first name</FormControl.HelpText></FormControl><FormControl><FormControl.Label>Description</FormControl.Label><Textarea /><FormControl.HelpText>Tell me about yourself</FormControl.HelpText></FormControl><Button variant="primary" type="submit" isDisabled={submitting}>{submitting ? 'Submitted' : 'Click me to submit'}</Button></Form></Box></Layout.Body></Layout>);}
Layout with left sidebar
function BasicLayoutExample() {const [submitting, setSubmitting] = useState(false);const submitForm = () => {setSubmitting(true);setTimeout(() => setSubmitting(false), 1000);};return (<LayoutleftSidebar={<Layout.Sidebar><Box padding="none" marginBottom="spacingXl"><Paragraph>Sidebar Content</Paragraph></Box></Layout.Sidebar>}><Layout.Body><Box padding="none" marginBottom="spacingXl"><Form onSubmit={submitForm}><FormControl><FormControl.Label isRequired>Name</FormControl.Label><TextInput /><FormControl.HelpText>Please enter your first name</FormControl.HelpText></FormControl><FormControl><FormControl.Label>Description</FormControl.Label><Textarea /><FormControl.HelpText>Tell me about yourself</FormControl.HelpText></FormControl><Button variant="primary" type="submit" isDisabled={submitting}>{submitting ? 'Submitted' : 'Click me to submit'}</Button></Form></Box></Layout.Body></Layout>);}
Layout with right sidebar
function BasicLayoutExample() {const [submitting, setSubmitting] = useState(false);const submitForm = () => {setSubmitting(true);setTimeout(() => setSubmitting(false), 1000);};return (<LayoutrightSidebar={<Layout.Sidebar><Box padding="none" marginBottom="spacingXl"><Paragraph>Sidebar Content</Paragraph></Box></Layout.Sidebar>}><Layout.Body><Box padding="none" marginBottom="spacingXl"><Form onSubmit={submitForm}><FormControl><FormControl.Label isRequired>Name</FormControl.Label><TextInput /><FormControl.HelpText>Please enter your first name</FormControl.HelpText></FormControl><FormControl><FormControl.Label>Description</FormControl.Label><Textarea /><FormControl.HelpText>Tell me about yourself</FormControl.HelpText></FormControl><Button variant="primary" type="submit" isDisabled={submitting}>{submitting ? 'Submitted' : 'Click me to submit'}</Button></Form></Box></Layout.Body></Layout>);}
Layout with header and sidebars
function BasicLayoutExample() {const [submitting, setSubmitting] = useState(false);const submitForm = () => {setSubmitting(true);setTimeout(() => setSubmitting(false), 1000);};return (<Layoutheader={<Layout.Header><Header title="Your Details" /></Layout.Header>}leftSidebar={<Layout.Sidebar><Box padding="none" marginBottom="spacingXl"><Paragraph>Sidebar Content</Paragraph></Box></Layout.Sidebar>}rightSidebar={<Layout.Sidebar><Box padding="none" marginBottom="spacingXl"><Paragraph>Sidebar Content</Paragraph></Box></Layout.Sidebar>}><Layout.Body><Box padding="none" marginBottom="spacingXl"><Form onSubmit={submitForm}><FormControl><FormControl.Label isRequired>Name</FormControl.Label><TextInput /><FormControl.HelpText>Please enter your first name</FormControl.HelpText></FormControl><FormControl><FormControl.Label>Description</FormControl.Label><Textarea /><FormControl.HelpText>Tell me about yourself</FormControl.HelpText></FormControl><Button variant="primary" type="submit" isDisabled={submitting}>{submitting ? 'Submitted' : 'Click me to submit'}</Button></Form></Box></Layout.Body></Layout>);}
Full Screen Layout with header and sidebars
function BasicLayoutExample() {const [submitting, setSubmitting] = useState(false);const submitForm = () => {setSubmitting(true);setTimeout(() => setSubmitting(false), 1000);};return (<Layoutvariant="fullscreen"header={<Layout.Header><Header title="Your Details" /></Layout.Header>}leftSidebar={<Layout.Sidebar><Box padding="none" marginBottom="spacingXl"><Paragraph>Sidebar Content</Paragraph></Box></Layout.Sidebar>}rightSidebar={<Layout.Sidebar><Box padding="none" marginBottom="spacingXl"><Paragraph>Sidebar Content</Paragraph></Box></Layout.Sidebar>}><Layout.Body><Box padding="none" marginBottom="spacingXl"><Form onSubmit={submitForm}><FormControl><FormControl.Label isRequired>Name</FormControl.Label><TextInput /><FormControl.HelpText>Please enter your first name</FormControl.HelpText></FormControl><FormControl><FormControl.Label>Description</FormControl.Label><Textarea /><FormControl.HelpText>Tell me about yourself</FormControl.HelpText></FormControl><Button variant="primary" type="submit" isDisabled={submitting}>{submitting ? 'Submitted' : 'Click me to submit'}</Button></Form></Box></Layout.Body></Layout>);}
Layout areas
The Layout component offers 4 individual areas, which can be set via the props header, leftSidebar, rightSidebar, and as children (for the main content area).
Prop | Description | Recommended Child components |
|---|---|---|
children | Elements handed over as children to the Layout component render as the
Layout's body. Ideally, all children should be wrapped inside
| Layout.Body |
header | Elements in the header overarch the whole width of the layout component.
Child components should be wrapped inside | Layout.Header with Header as a child |
leftSidebar | rightSidebar | These child-components render on the left and right side of the body
content. They should be wrapped in | Layout.Sidebar |
** Note ** When passing at least one sidebar, a divider is added underneath the header. There is no divider otherwise.
Accessibility
- The Layout component renders a
<section>by default. If you use multiple layouts or want to improve landmark navigation, provide a unique aria-label Layout.Sidebarrenders as a semantic<aside>by defaultLayout.Headerrenders as a semantic<header>by default- Keyboard navigation and focus management for interactive content inside the layout should be implemented by the consumer.
Props (API reference)
Open in StorybookLayout
Name | Type | Default |
|---|---|---|
| children | ReactNode The body of the layout. | |
| className | string CSS class to be appended to the root element | |
| contentClassName | string Classname that will be passed to the main content div, which holds the sidebars and children div | |
| contentTestId | string | |
| header | string number bigint false true ReactElement<unknown, string | JSXElementConstructor<any>> Iterable<ReactNode> ReactPortal Promise<AwaitedReactNode> | |
| leftSidebar | string number bigint false true ReactElement<unknown, string | JSXElementConstructor<any>> Iterable<ReactNode> ReactPortal Promise<AwaitedReactNode> | |
| leftSidebarVariant | "narrow" "wide" Defines the width of the layout left sidebar. | 'narrow' (280px) |
| offsetTop | number Offset for layout heights calculation. Set to `0` for layout usage without navbar. | 60 (= navbar height) |
| rightSidebar | string number bigint false true ReactElement<unknown, string | JSXElementConstructor<any>> Iterable<ReactNode> ReactPortal Promise<AwaitedReactNode> | |
| rightSidebarVariant | "narrow" "wide" Defines the width of the layout right sidebar. | 'wide' (340px) |
| testId | string A [data-test-id] attribute used for testing purposes | |
| variant | "narrow" "wide" "fullscreen" Defines the width of the layout and its content. | 'wide' |
| withBoxShadow | false true |