Layout
The layout component included three main parts: Header
, Content
, and Footer
. You can design your Layout with the child layout components as in the following examples.
Example
function MyLayout() { const breadcrumbsData = [ { label: 'Deliverables', url: '/deliverables' }, { label: 'NetworkD', url: '/networkd' }, { label: 'Creative_H' } ]; const titleConfig = { text: 'Page Title', isEditable: true }; const actions = { iconActions: [ { id: 'fav', name: 'Star', tooltip: { content: 'Rate us' }, onClick: () => console.log('fav is clicked') }, { id: 'settings', name: 'CogWheel', tooltip: { content: 'App settings' }, onClick: () => console.log('settings is clicked') }, { id: 'share', name: 'Share', tooltip: { content: 'Share with your connection' }, onClick: () => console.log('share is clicked') }, { id: 'download', name: 'Download', tooltip: { content: 'Download report' }, onClick: () => console.log('download is clicked') } ], buttonActions: { primaryAction: { label: 'Primary', isLoading: true, disabled: true, tooltip: { content: 'Please wait...' }, onClick: () => console.log('primary action clicked') }, secondaryAction: { label: 'Secondary', onClick: () => console.log('secondary action clicked') } } }; const tabs = [ { id: '1', label: 'Examples', url: '#' }, { id: '2', label: 'Components', url: 'https://atlas.adjust.com/docs/components/introduction' }, { id: '3', label: 'Design Tokens', url: 'https://atlas.adjust.com/docs/design-tokens/introduction' }, { id: '4', label: 'Patterns', url: 'https://atlas.adjust.com/docs/patterns/introduction' } ]; const getSearchValue = (event) => { const searchValue = event.target.value; return console.log('search value:', searchValue); }; const search = { onChange: getSearchValue, placeholder: 'Search...' }; const FilterComponents = () => { const items = [ { label: 'apple', value: 'apple' }, { label: 'banana', value: 'banana' } ]; const [selectedItems, setSelectedItems] = useState(items); return ( <> <FilterButton name="Fruits" items={items} selectedItems={selectedItems} onApply={setSelectedItems} showResetButton /> <FilterButton name="Fruits" items={items} selectedItems={selectedItems} onApply={setSelectedItems} showResetButton /> </> ); }; const onTitleEdit = (updatedTitleValue) => { return console.log('edited title value', updatedTitleValue); }; const footeractions = { primaryAction: { onClick: () => console.log('primaryAction clicked'), label: 'Save', isLoading: true, disabled: true, tooltip: { content: 'Saving please wait...' }, dataTestId: 'primary-btn' }, secondaryAction: { onClick: () => console.log('secondaryAction clicked'), label: 'Reset', dataTestId: 'secondary-btn' }, destructiveAction: { onClick: () => console.log('destructiveAction clicked'), label: 'Delete', dataTestId: 'destructive-btn', disabled: true, tooltip: { content: 'Delete action is disabled' } } }; const columns = [ { Header: 'Name', accessor: 'name' }, { Header: 'Age', accessor: 'age', align: 'center' }, { Header: 'Room', accessor: 'room', align: 'right' } ]; const data = [ { name: 'Just a name', age: 21, room: 1 }, { name: 'Another name', age: 25, room: 2 } ]; return ( <Layout> <Layout.Header> <PageHeader breadcrumbs={breadcrumbsData} title={titleConfig} actions={actions} onTitleEdit={onTitleEdit} tabs={tabs} search={search} filters={<FilterComponents />} css={{ position: 'sticky', zIndex: 100 }} // to fit with Preview Container. To see header fixed to top of the page, change position: 'fixed', zIndex: 200 /> </Layout.Header> <Layout.Content> <Tile> <Text type="headline1">List</Text> <TableV2 data={data} columns={columns} /> </Tile> </Layout.Content> <Layout.Footer> <PageFooter primaryAction={footeractions.primaryAction} secondaryAction={footeractions.secondaryAction} destructiveAction={footeractions.destructiveAction} contextMessage="This is a contextual message." isFluidWidth css={{ position: 'relative' }} // to fit with Preview Container. /> </Layout.Footer> </Layout> ); }
Components
Header
The <Layout.Header />
component is responsible for keeping your page header in the layout grid.
Please use the PageHeader component for the header part.
<Layout noFooter> <Layout.Header> <PageHeader title={{ text: 'Header Title' }} kind="wizard" css={{ position: 'sticky', zIndex: 100 }} // to fit with Preview Container. To see header fixed to top of the page, change position: 'fixed', zIndex: 200 /> </Layout.Header> <Layout.Content noPadding>...</Layout.Content> </Layout>
Content
The <Layout.Content />
component is responsible for keeping your page content in the layout grid. It has two options:
noPadding: In case you don't want to use default padding in your content area, you can provide the prop noPadding
to the <Layout.Content />
component as in the following example.
<Layout noFooter> <Layout.Header> <PageHeader title={{ text: 'Header Title' }} kind="wizard" css={{ position: 'sticky', zIndex: 100 }} // to fit with Preview Container. To see header fixed to top of the page, change position: 'fixed', zIndex: 200 /> </Layout.Header> <Layout.Content noPadding> <span>Content without padding</span> </Layout.Content> </Layout>
onContentScroll: you can use this callback prop to get information about the scroll value inside <Layout.Content />
component.
function MyLayout() { const primaryAction = { onClick: () => console.log('primaryAction clicked'), label: 'Save', isLoading: true, disabled: true, tooltip: { content: 'Saving please wait...' }, dataTestId: 'primary-btn' }; const handleScroll = (scrollValue) => { return console.log(scrollValue); }; return ( <Layout> <Layout.Header> <PageHeader title={{ text: 'Header Title' }} kind="wizard" css={{ position: 'sticky', zIndex: 100 }} // to fit with Preview Container. To see header fixed to top of the page, change position: 'fixed', zIndex: 200 /> </Layout.Header> <Layout.Content onContentScroll={handleScroll}> <div> <Tile> <div>Some example content</div> </Tile> <Tile> <div>Some example content</div> </Tile> <Tile> <div>Some example content</div> </Tile> <Tile> <div style={{height: '500px'}}>Some example content</div> </Tile> <Tile> <div>Some example content</div> </Tile> <Tile> <div>Some example content</div> </Tile> </div> </Layout.Content> <Layout.Footer> <PageFooter primaryAction={primaryAction} contextMessage="This is a contextual message." css={{ position: 'relative' }} // to fit with Preview Container. /> </Layout.Footer> </Layout> ); }
Footer
The <Layout.Footer />
component is responsible for keeping your page footer in the layout grid. You also can exclude the footer from your layout by adding the prop noFooter
prop to the <Layout />
component.
Please use the PageFooter component for the footer part.
function MyLayout() { const primaryAction = { onClick: () => console.log('primaryAction clicked'), label: 'Save', isLoading: true, disabled: true, tooltip: { content: 'Saving please wait...' }, dataTestId: 'primary-btn' }; const handleScroll = (scrollValue) => { return console.log(scrollValue); }; return ( <Layout> <Layout.Header> <PageHeader title={{ text: 'Header Title' }} css={{ position: 'sticky', zIndex: 100 }} // to fit with Preview Container. To see header fixed to top of the page, change position: 'fixed', zIndex: 200 /> </Layout.Header> <Layout.Content onContentScroll={handleScroll}> ... </Layout.Content> <Layout.Footer> <PageFooter primaryAction={primaryAction} contextMessage="This is a contextual message." css={{ position: 'relative' }} // to fit with Preview Container. /> </Layout.Footer> </Layout> ); }
Variants
No Footer
You can exclude the <Layout.Footer />
component from your composition by adding the prop noFooter
to the <Layout />
component.
<Layout noFooter> <Layout.Header> <PageHeader title={{ text: 'Header Title' }} css={{ position: 'sticky', zIndex: 100 }} // to fit with Preview Container. To see header fixed to top of the page, change position: 'fixed', zIndex: 200 /> </Layout.Header> <Layout.Content> <div style={{ display: 'flex', justifyContent: 'center', height: '100%' }}> <EmptyState background="table" iconKey="warningOverload" size="large" headLine="Connection has been lost" bodyText="Data could not be loaded, or connection is missing." /> </div> </Layout.Content> </Layout>
Spinner
You can use the <Layout.Spinner />
component to show Spinner component while your layout is loading some pages or content.
Spinner is a part of the content, please be sure that you are wrapping <Layout.Spinner />
component inside the <Layout.Content />
component as in the following example.
<Layout noFooter> <Layout.Header> <PageHeader title={{ text: 'Header Title' }} css={{ position: 'sticky', zIndex: 100 }} // to fit with Preview Container. To see header fixed to top of the page, change position: 'fixed', zIndex: 200 /> </Layout.Header> <Layout.Content> <Layout.Spinner size="medium" /> </Layout.Content> </Layout>
Wizard
You can use the layout as a wizard layout by adding the boolean prop wizard
to the <Layout />
component.
In case of using a wizard layout, please be sure that you are providing the prop kind="wizard"
to the <PageHeader />
component as well.
function MyLayout() { const footeractions = { primaryAction: { onClick: () => console.log('primaryAction clicked'), label: 'Save', isLoading: true, disabled: true, tooltip: { content: 'Saving please wait...' }, dataTestId: 'primary-btn' }, secondaryAction: { onClick: () => console.log('secondaryAction clicked'), label: 'Reset', dataTestId: 'secondary-btn' }, destructiveAction: { onClick: () => console.log('destructiveAction clicked'), label: 'Delete', dataTestId: 'destructive-btn', disabled: true, tooltip: { content: 'Delete action is disabled' } } }; return ( <Layout wizard> <Layout.Header> <PageHeader title={{ text: 'Header Title' }} kind="wizard" css={{ position: 'sticky', zIndex: 100 }} // to fit with Preview Container. To see header fixed to top of the page, change position: 'fixed', zIndex: 200 /> </Layout.Header> <Layout.Content> <EmptyState background="table" iconKey="warningOverload" size="large" headLine="Connection has been lost" bodyText="Data could not be loaded, or connection is missing." /> </Layout.Content> <Layout.Footer> <PageFooter primaryAction={footeractions.primaryAction} secondaryAction={footeractions.secondaryAction} destructiveAction={footeractions.destructiveAction} contextMessage="This is a contextual message." isFluidWidth css={{ position: 'relative' }} // to fit with Preview Container. /> </Layout.Footer> </Layout> ); }
Props
Name | Type | Default |
---|---|---|
noFooter The appName will be used to inform layout to not use footer area in grid |
| — |
wizard The wizard will be used to inform layout to use wizard template layout |
| — |
children The sub layout components |
| — |
data-{foo} Data attributes can be used by testing libraries to retrieve components or assert their existence |
| — |
* - the prop is required. |