Overview

Having a consistent place for navigation and similar elements is one of the key nature of good UI design. These page layouts show guidelines for element positioning to support different use cases and include examples and details to stay consistent with other pages.

Use Cases

Use CaseOption(s)
When adding a large data set to a pageTable Page
When adding a small data set that is primarily visualCard Page
Configuration of featuresSettings Page

Table Page

A table is one of the most complex objects that can live on a page. It can have infinite combinations of features which makes putting it in a page with consistency challenging. Below are our guidelines to achieve consistency for page with a table.

Default

Commonly used layout for most pages that contains table.

scaled: true
---
const BasicTablePageExample = () => {
    const [isActive, setActive] = React.useState(0)
    const items = [
        { id: 1, name: 'Rose Milk Tea', price: 4.75 },
        { id: 2, name: 'Honey Milk Tea', price: 5.75 },
        { id: 3, name: 'Horchata Milk Tea', price: 5.00 },
        { id: 4, name: 'KitKat Milk Tea', price: 5.75 },
        { id: 6, name: 'Caramel Milk Tea', price: 4.75 },
        { id: 7, name: 'Original Milk Tea', price: 4.75 },
        { id: 8, name: 'Mango Milk Tea', price: 5.00 },
        { id: 9, name: 'Oolong Milk Tea', price: 4.75 }
    ];
    return (
        <Frame
            style={{minHeight:500}}
            header={<div style={{height: 56}}><div style={{ backgroundColor: 'black', height: 56, position: 'fixed', top: 0, width: '100%', zIndex: 1 }} /></div>}
        >
            <Page
                header={
                    <>
                        <Stack alignItems="center" spacing={2} wrap='wrap'>
                            <Stack.Item fill>
                                <Headline size="large" className="m-b-0">Page Header</Headline>
                            </Stack.Item>
                            <Button small primary>Create Flow</Button>
                        </Stack>
                    </>
                }
                sidebar={
                    <Sidebar>
                        <SideNav title="Drinks">
                            <SideNav.Item onClick={() => setActive(0)} active={isActive===0}>Milk Tea</SideNav.Item>
                            <SideNav.Item onClick={() => setActive(1)} active={isActive===1}>Coffee</SideNav.Item>
                            <SideNav.Item onClick={() => setActive(2)} active={isActive===2}>Smoothie</SideNav.Item>
                        </SideNav>
                        <Sidebar.Section>
                            <Card>Hello World</Card>
                        </Sidebar.Section>
                    </Sidebar>
                }
            >
                <Layout>
                    <Table data={items}>
                        <TableColumn field="id" title="Id" width="60px" />
                        <TableColumn field="name" title="Name" />
                        <TableColumn field="price" title="Price" width="180px" format="{0:c}" />
                    </Table>
                </Layout>
            </Page>
        </Frame>
    )
}
render (BasicTablePageExample)

Wide

Used when table requires additional space on the page.

scaled: true
---
const WideTablePageExample = () => {
    const [isActive, setActive] = React.useState(0)
    const items = [
        { id: 1, name: 'Rose Milk Tea', price: 4.75 },
        { id: 2, name: 'Honey Milk Tea', price: 5.75 },
        { id: 3, name: 'Horchata Milk Tea', price: 5.00 },
        { id: 4, name: 'KitKat Milk Tea', price: 5.75 },
        { id: 6, name: 'Caramel Milk Tea', price: 4.75 },
        { id: 7, name: 'Original Milk Tea', price: 4.75 },
        { id: 8, name: 'Mango Milk Tea', price: 5.00 },
        { id: 9, name: 'Oolong Milk Tea', price: 4.75 }
    ];
    return (
        <Frame
            style={{minHeight:500}}
            header={<div style={{height: 56}}><div style={{ backgroundColor: 'black', height: 56, position: 'fixed', top: 0, width: '100%', zIndex: 1 }} /></div>}
        >
            <Page
                maxWidth='wide'
                header={
                    <>
                        <Stack alignItems="center" spacing={2} wrap='wrap'>
                            <Stack.Item fill>
                                <Headline size="large" className="m-b-0">Page Header</Headline>
                            </Stack.Item>
                            <Button small primary>Create Flow</Button>
                        </Stack>
                    </>
                }
                sidebar={
                    <Sidebar>
                        <SideNav title="Drinks">
                            <SideNav.Item onClick={() => setActive(0)} active={isActive===0}>Milk Tea</SideNav.Item>
                            <SideNav.Item onClick={() => setActive(1)} active={isActive===1}>Coffee</SideNav.Item>
                            <SideNav.Item onClick={() => setActive(2)} active={isActive===2}>Smoothie</SideNav.Item>
                        </SideNav>
                        <Sidebar.Section>
                            <Card>Hello World</Card>
                        </Sidebar.Section>
                    </Sidebar>
                }
            >
                <Layout>
                    <Table data={items}>
                        <TableColumn field="id" title="Id" width="60px" />
                        <TableColumn field="name" title="Name" />
                        <TableColumn field="price" title="Price" width="180px" format="{0:c}" />
                    </Table>
                </Layout>
            </Page>
        </Frame>
    )
}
render (WideTablePageExample)

Card Page

A card page is used to show a smaller data set that is primarily visual, such as displaying images of an item.

scaled: true
title: Default
---
const BasicCardExample = () => {
    const [isActive, setActive] = React.useState(0)
    const items = [
        { id: 1, name: 'Rose Milk Tea', price: 4.75 },
        { id: 2, name: 'Honey Milk Tea', price: 5.75 },
        { id: 3, name: 'Horchata Milk Tea', price: 5.00 },
        { id: 4, name: 'KitKat Milk Tea', price: 5.75 },
        { id: 6, name: 'Caramel Milk Tea', price: 4.75 },
        { id: 7, name: 'Original Milk Tea', price: 4.75 },
        { id: 8, name: 'Mango Milk Tea', price: 5.00 },
        { id: 9, name: 'Oolong Milk Tea', price: 4.75 }
    ];
    return (
        <Frame header={<div style={{height: 56}}><div style={{ backgroundColor: 'black', height: 56, position: 'fixed', top: 0, width: '100%', zIndex: 1 }} /></div>}>
            <Page
                header={
                    <>
                        <Stack alignItems="center" spacing={2} wrap='wrap'>
                            <Stack.Item fill>
                                <Headline size="large" className="m-b-0">Page Header</Headline>
                            </Stack.Item>
                            <Button small primary>Create Flow</Button>
                        </Stack>
                    </>
                }
                sidebar={
                    <Sidebar>
                        <SideNav title="Drinks">
                            <SideNav.Item onClick={() => setActive(0)} active={isActive===0}>Milk Tea</SideNav.Item>
                            <SideNav.Item onClick={() => setActive(1)} active={isActive===1}>Coffee</SideNav.Item>
                            <SideNav.Item onClick={() => setActive(2)} active={isActive===2}>Smoothie</SideNav.Item>
                        </SideNav>
                        <Sidebar.Section>
                            <Card>Hello World</Card>
                        </Sidebar.Section>
                    </Sidebar>
                }
            >
                <Layout type="2Col" spacing="relaxed">
                    {items.map(
                        (item, index) => {
                            return (
                                <Layout.Section key={index}>
                                    <Card hoverable>
                                        <Card.Section>
                                            <Icon name="local_drink" /><BodyText inline className="h3 m-l-2 m-b-1">{item.name}</BodyText>
                                        </Card.Section>
                                        <Card.Section light className="c-neutral-90 fs-2">{item.price}</Card.Section>
                                    </Card>
                                </Layout.Section>
                            )
                        }
                    )}
                </Layout>
            </Page>
        </Frame>
    )
}
render (BasicCardExample)

Settings Page

Default

scaled: true
---
const DefaultSettingsPageExample = () => {
    const [isActive, setActive] = React.useState(0)
    return (
        <Frame header={<div style={{height: 56}}><div style={{ backgroundColor: 'black', height: 56, position: 'fixed', top: 0, width: '100%', zIndex: 1 }} /></div>}>
            <Page
                header={
                    <Headline size="large">Page Header</Headline>
                }
                sidebar={
                    <Sidebar>
                        <SideNav title="Settings">
                            <SideNav.Item onClick={() => setActive(0)} active={isActive===0}>Settings #1</SideNav.Item>
                            <SideNav.Item onClick={() => setActive(1)} active={isActive===1}>Settings #2</SideNav.Item>
                            <SideNav.Item onClick={() => setActive(2)} active={isActive===2}>Settings #3</SideNav.Item>
                        </SideNav>
                    </Sidebar>
                }
            >
                <hr style={{border: '#eeeeee solid 1px', margin: '32px 0'}}/>
                <Layout
                    type="support"
                    direction="left"
                >
                    <Layout.Section>
                        <Headline size="small">Section Title</Headline>
                        <BodyText size="small" subdued>Dolor incididunt veniam ex quis esse amet eu duis duis minim incididunt labore laboris ex.</BodyText>
                    </Layout.Section>
                    <Layout.Section>
                        <Card>
                            <Form>
                                <Form.Input label="Form Label" placeholder="Placeholder" />
                                <Form.Group widths="equal">
                                    <Form.Input label="Form Label" placeholder="Placeholder" />
                                    <Form.Input label="Form Label" placeholder="Placeholder" />
                                </Form.Group>
                                <ButtonGroup direction="row-reverse">
                                    <Button primary >Save</Button>
                                    <Button>Cancel</Button>
                                </ButtonGroup>
                            </Form>
                        </Card>
                    </Layout.Section>
                </Layout>
                <hr style={{border: '#eeeeee solid 1px', margin: '32px 0'}}/>
                <Layout
                    type="support"
                    direction="left">
                >
                    <Layout.Section>
                        <Headline size="small">Section Title</Headline>
                        <BodyText size="small" subdued>Dolor incididunt veniam ex quis esse amet eu duis duis minim incididunt labore laboris ex.</BodyText>
                    </Layout.Section>
                    <Layout.Section>
                        <Card className="m-b-1">
                             <Stack alignItems='center' spacing={2}>
                                <div className="bg-blue-grey-100 d-f align-items-center justify-content-center" style={{borderRadius:'100%', width: 40, height: 40}}><Icon name="business" className="c-blue-grey-600" /></div>
                                <Stack.Item fill>
                                    <BodyText bold>Item Title</BodyText>
                                    <BodyText subdued>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</BodyText>
                                </Stack.Item>
                                <Button fill="subtle" primary>Edit</Button>
                            </Stack>
                        </Card>
                        <Card className="m-b-1">
                             <Stack alignItems='center' spacing={2}>
                                <div className="bg-blue-grey-100 d-f align-items-center justify-content-center" style={{borderRadius:'100%', width: 40, height: 40}}><Icon name="business" className="c-blue-grey-600" /></div>
                                <Stack.Item fill>
                                    <BodyText bold>Item Title</BodyText>
                                    <BodyText subdued>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</BodyText>
                                </Stack.Item>
                                <Button fill="subtle" primary>Edit</Button>
                            </Stack>
                        </Card>
                        <Card className="m-b-1">
                             <Stack alignItems='center' spacing={2}>
                                <div className="bg-blue-grey-100 d-f align-items-center justify-content-center" style={{borderRadius:'100%', width: 40, height: 40}}><Icon name="business" className="c-blue-grey-600" /></div>
                                <Stack.Item fill>
                                    <BodyText bold>Item Title</BodyText>
                                    <BodyText subdued>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</BodyText>
                                </Stack.Item>
                                <Button fill="subtle" primary>Edit</Button>
                            </Stack>
                        </Card>
                    </Layout.Section>
                </Layout>
            </Page>
        </Frame>
    )
}
render (DefaultSettingsPageExample)

Single Save

Use when bulk saving is required on page level.

scaled: true
---
const AlternativeSettingsPageExample = () => {
    const [isActive, setActive] = React.useState(0)
    return (
        <Frame header={<div style={{height: 56}}><div style={{ backgroundColor: 'black', height: 56, position: 'fixed', top: 0, width: '100%', zIndex: 1 }} /></div>}>
            <Page
                header={
                    <Headline size="large">Page Header</Headline>
                }
                sidebar={
                    <Sidebar>
                        <SideNav title="Settings">
                            <SideNav.Item onClick={() => setActive(0)} active={isActive===0}>Settings #1</SideNav.Item>
                            <SideNav.Item onClick={() => setActive(1)} active={isActive===1}>Settings #2</SideNav.Item>
                            <SideNav.Item onClick={() => setActive(2)} active={isActive===2}>Settings #3</SideNav.Item>
                        </SideNav>
                    </Sidebar>
                }
            >
                <hr style={{border: '#eeeeee solid 1px', margin: '32px 0'}}/>
                <Layout
                    type="support"
                    direction="left"
                >
                    <Layout.Section>
                        <Headline size="small">Section Title</Headline>
                        <BodyText size="small" subdued>Dolor incididunt veniam ex quis esse amet eu duis duis minim incididunt labore laboris ex.</BodyText>
                    </Layout.Section>
                    <Layout.Section>
                        <Card>
                            <Form>
                                <Form.Input label="Form Label" placeholder="Placeholder" />
                                <Form.Group widths="equal">
                                    <Form.Input label="Form Label" placeholder="Placeholder" />
                                    <Form.Input label="Form Label" placeholder="Placeholder" />
                                </Form.Group>
                            </Form>
                        </Card>
                    </Layout.Section>
                </Layout>
                <hr style={{border: '#eeeeee solid 1px', margin: '32px 0'}}/>
                <Layout
                    type="support"
                    direction="left"
                >
                    <Layout.Section>
                        <Headline size="small">Section Title</Headline>
                        <BodyText size="small" subdued>Dolor incididunt veniam ex quis esse amet eu duis duis minim incididunt labore laboris ex.</BodyText>
                    </Layout.Section>
                    <Layout.Section>
                        <Card>
                            <Form>
                                <Form.Input label="Form Label" placeholder="Placeholder" />
                                <Form.Group widths="equal">
                                    <Form.Input label="Form Label" placeholder="Placeholder" />
                                    <Form.Input label="Form Label" placeholder="Placeholder" />
                                </Form.Group>
                                <Form.Group widths="equal">
                                    <Form.Input label="Form Label" placeholder="Placeholder" />
                                    <Form.Input label="Form Label" placeholder="Placeholder" />
                                </Form.Group>
                                <Form.Group widths="equal">
                                    <Form.Input label="Form Label" placeholder="Placeholder" />
                                    <Form.Input label="Form Label" placeholder="Placeholder" />
                                </Form.Group>
                            </Form>
                        </Card>
                    </Layout.Section>
                </Layout>
                <hr style={{border: '#eeeeee solid 1px', margin: '32px 0'}}/>
                <Layout
                    type="support"
                    direction="left"
                >
                    <Layout.Section>
                        <Headline size="small">Section Title</Headline>
                        <BodyText size="small" subdued>Dolor incididunt veniam ex quis esse amet eu duis duis minim incididunt labore laboris ex.</BodyText>
                    </Layout.Section>
                    <Layout.Section>
                        <Card>
                            <Form>
                                <Form.Input label="Form Label" placeholder="Placeholder" />
                                <Form.Group widths="equal">
                                    <Form.Input label="Form Label" placeholder="Placeholder" />
                                    <Form.Input label="Form Label" placeholder="Placeholder" />
                                </Form.Group>
                                <Form.Group widths="equal">
                                    <Form.Input label="Form Label" placeholder="Placeholder" />
                                    <Form.Input label="Form Label" placeholder="Placeholder" />
                                </Form.Group>
                                <Form.Group widths="equal">
                                    <Form.Input label="Form Label" placeholder="Placeholder" />
                                    <Form.Input label="Form Label" placeholder="Placeholder" />
                                </Form.Group>
                            </Form>
                        </Card>
                    </Layout.Section>
                </Layout>
                <div className="bg-white p-x-3 p-y-2 position-fixed w-100" style={{boxSizing: 'border-box', bottom: 0, left: 0, borderTop: `1px solid ${tokens.colorNeutral60}`}}>
                    <ButtonGroup direction="row-reverse">
                        <Button primary>Save Changes</Button>
                        <Button>Cancel</Button>
                    </ButtonGroup>
                </div>
            </Page>
        </Frame>
    )
}
render (AlternativeSettingsPageExample)

Anatomy of a Page

The screen of a page is built through several Anvil composition components. Components marked as deprecated, such as the Grid and Container, are not typically apart of building a page.

Frame

The Frame provides the technical structure to the application. It holds the various sub-components of a particular page.

Page

The Page is the outer wrapper for a screen. It provides the background color and width of the page's main content.

The Sidebar is an optional configuration on the left side of the Page. Content inside it is usually through the Side Nav.

Layout

The Layout provides the building blocks of individual pages. Layouts control basic column configurations of content.


Best Practices

  • Table placement should be towards the bottom of the viewport if possible.
  • Be consistent with sibling page content widths and additional elements on the page.
  • Use the same layout width on the entire page page for better alignment and consistency.
  • If secondary navigation is required, consider using tabs.