App layout
The AppLayout
component should be the root view component of all your pages. It renders children as flex column.
Page layout, columns and sidebar
The PageLayout
component should be used to compose the navigation and main content of your page. It will render children as flex row.
It expects PageLayout.Column
and PageLayout.Sidebar
as children for the main building blocks, however it does render children as flex so it's possible to compose your own layout using custom elements.
Columns
The PageLayout.Column
component is used inside PageLayout
to create columns in your page content.
It renders children as flex column.
By default each PageLayout.Column
will fill the remaining space. You can use the optional width
to specify a fixed width for a specific column.
Note: Styling of each column for things like dividers, padding and background are up to the consumer.
<PageLayout> <PageLayout.Column role="aside" width={200}> <Box paddingY="large" paddingX="xlarge"> <Heading level="4">Fixed width column</Heading> <Text></Text> </Box> </PageLayout.Column> <Divider vertical /> <PageLayout.Column role="main"> <Box paddingY="large" paddingX="xlarge"> <Heading level="4"> Space fill column</Heading> <Text> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </Text> </Box> </PageLayout.Column> <Divider vertical /> <PageLayout.Column role="aside" width={200}> <Box paddingY="large" paddingX="xlarge"> <Heading level="4">Fixed width column</Heading> <Text></Text> </Box> </PageLayout.Column></PageLayout>
Side bar
The PageLayout.Sidebar
component is used inside PageLayout
. It provides common side bar functionality such as fill height, fixed width and expand/collapse. It renders children as flex column.
Use the SidebarNavigation
component inside PageLayout.Sidebar
for a complete side bar navigation experience.
<Flex height={500}> <PageLayout> <PageLayout.Sidebar> <Box padding="xlarge"> <Heading level="4">Side bar</Heading> </Box> </PageLayout.Sidebar> </PageLayout></Flex>
usePageLayout
The usePageLayout
hook is used to get the current state of the sidebar and programatically
expand/collapse it.
const NestedComponent = () => { const { isSidebarOpen, setIsSidebarOpen } = usePageLayout(); return ( <Box> <Text>Nested component</Text> <Button label="Toggle sidebar" onClick={() => setIsSidebarOpen((isSidebarOpen) => !isSidebarOpen)} /> </Box> );};return ( <Flex height={500}> <PageLayout> <PageLayout.Sidebar> <Box padding="xlarge"> <Heading level="4">Side bar</Heading> </Box> </PageLayout.Sidebar> <PageLayout.Column role="main"> <Box padding="xxlarge"> <NestedComponent /> </Box> </PageLayout.Column> </PageLayout> </Flex>);
Receipes
Combine all the components to achieve certain layouts.
Horizontal navigation + single column body
const { palette } = useTheme();const pages = [ { label: 'Payruns', href: 'payruns' }, { label: 'STP', href: 'stp' }, { label: 'Employees', href: 'employees' }, { label: 'Settings', href: 'settings' },];return ( <AppLayout> <AppLayout.Header> <Flex height="100%" paddingX="xlarge" alignItems="center" flex={1} style={{ borderBottom: `1px solid ${palette.global.border}`, boxSizing: 'border-box', }} > <TabList style={{ height: '100%', display: 'flex', flex: '1' }}> {pages.map((page, i) => { return ( <TabItem as={Link} key={page.href} href={page.href} isSelected={i === 2} > {page.label} </TabItem> ); })} </TabList> <Flex flex={1} justifyContent="flex-end"> <Text weight="bold">User menu</Text> </Flex> </Flex> </AppLayout.Header> <PageLayout> <PageLayout.Column role="main"> <Stack flex={1} padding="xlarge"> <Heading level="4">Main body</Heading> <Text> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </Text> </Stack> </PageLayout.Column> </PageLayout> </AppLayout>);
Horizontal navigation + multi column body
const { palette } = useTheme();const pages = [ { label: 'Payruns', href: 'payruns' }, { label: 'STP', href: 'stp' }, { label: 'Employees', href: 'employees' }, { label: 'Settings', href: 'settings' },];return ( <AppLayout> <AppLayout.Header> <Flex height="100%" paddingX="xlarge" alignItems="center" flex={1} style={{ borderBottom: `1px solid ${palette.global.border}`, boxSizing: 'border-box', }} > <TabList style={{ height: '100%', display: 'flex', flex: '1' }}> {pages.map((page, i) => { return ( <TabItem as={Link} key={page.href} href={page.href} isSelected={i === 2} > {page.label} </TabItem> ); })} </TabList> <Flex flex={1} justifyContent="flex-end"> <Text weight="bold">User menu</Text> </Flex> </Flex> </AppLayout.Header> <PageLayout> <PageLayout.Column role="aside" width="200px"> <Stack flex={1} padding="xlarge"> <Heading level="4">Some dynamic list</Heading> </Stack> </PageLayout.Column> <Divider vertical /> <PageLayout.Column role="main"> <Stack flex={1} padding="xlarge"> <Heading level="4">Dynamic list content</Heading> <Text> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </Text> </Stack> </PageLayout.Column> </PageLayout> </AppLayout>);
Horizontal navigation + side bar navigation + body
const { palette } = useTheme();const pages = [ { label: 'Payruns', href: 'payruns' }, { label: 'STP', href: 'stp' }, { label: 'Employees', href: 'employees' }, { label: 'Settings', href: 'settings' },];return ( <AppLayout> <AppLayout.Header> <Flex height="100%" paddingX="xlarge" alignItems="center" flex={1} style={{ borderBottom: `1px solid ${palette.global.border}`, boxSizing: 'border-box', }} > <TabList style={{ height: '100%', display: 'flex', flex: '1' }}> {pages.map((page, i) => { return ( <TabItem as={Link} key={page.href} href={page.href} isSelected={i === 3} > {page.label} </TabItem> ); })} </TabList> <Flex flex={1} justifyContent="flex-end"> <Text weight="bold">User menu</Text> </Flex> </Flex> </AppLayout.Header> <PageLayout> <PageLayout.Sidebar> <Stack flex={1} background="muted"> <Box padding="xxlarge"> <Heading level="4">Settings</Heading> </Box> <Divider /> <SidebarNavigation selectedNavigationKey="super-funds"> <SidebarNavigationItem label="General" href="general" navigationKey="general" /> <SidebarNavigationItem label="Company details" href="company-details" navigationKey="company-details" /> <SidebarNavigationItem label="Email verification" href="email-verification" navigationKey="email-verification" /> <SidebarNavigationItem label="Superannuation funds" href="super-funds" navigationKey="super-funds" /> <SidebarNavigationItem label="Pay schedules" href="pay-schedules" navigationKey="pay-schedules" /> <SidebarNavigationItem label="Pay items" href="pay-items" navigationKey="pay-items" /> <SidebarNavigationItem label="Suppliers" href="suppliers" navigationKey="suppliers" /> </SidebarNavigation> </Stack> </PageLayout.Sidebar> <PageLayout.Column role="main"> <Stack flex={1} padding="xlarge"> <Heading level="4">Main body</Heading> <Text> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </Text> </Stack> </PageLayout.Column> </PageLayout> </AppLayout>);
Side bar navigation + body
const { palette } = useTheme();const pages = [ { label: 'Payruns', href: 'payruns' }, { label: 'STP', href: 'stp' }, { label: 'Employees', href: 'employees' }, { label: 'Settings', href: 'settings' },];return ( <AppLayout> <PageLayout> <PageLayout.Sidebar> <Stack flex={1} background="muted"> <Box padding="xxlarge"> <Heading level="4">Settings</Heading> </Box> <Divider /> <SidebarNavigation selectedNavigationKey="super-funds"> <SidebarNavigationItem label="General" href="general" navigationKey="general" /> <SidebarNavigationItem label="Company details" href="company-details" navigationKey="company-details" /> <SidebarNavigationItem label="Email verification" href="email-verification" navigationKey="email-verification" /> <SidebarNavigationItem label="Superannuation funds" href="super-funds" navigationKey="super-funds" /> <SidebarNavigationItem label="Pay schedules" href="pay-schedules" navigationKey="pay-schedules" /> <SidebarNavigationItem label="Pay items" href="pay-items" navigationKey="pay-items" /> <SidebarNavigationItem label="Suppliers" href="suppliers" navigationKey="suppliers" /> </SidebarNavigation> </Stack> </PageLayout.Sidebar> <PageLayout.Column role="main"> <Stack flex={1} padding="xlarge"> <Heading level="4">Main body</Heading> <Text> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </Text> </Stack> </PageLayout.Column> </PageLayout> </AppLayout>);