Overview

Setup flows, also known as creation or add flows, are an important part of user tasks. It includes the creation of a completely new resource or adding to an existing set. They have clearly defined goals, with varying degrees of contextual help and value proposition.

Use Cases

Use CaseOption(s)
Quick, single step setupModal, Drawer, Takeover, or in the Layout
2+ steps, overview of information is importantFlow Card
2+ steps, flows have complex data interactionTakeover + Progress Tracker

Simple, Quick Setups

When setups require minimal guidance and steps, different layouts can be used, each with its own advantages.

Use a Modal layout when content is limited and context underneath a Modal is not needed.

noPadding: true
frame: true
---
const Example1 = () => {
    return (
    <div style={{ height: '400px' }}>
        <Modal
            open={true}
            closable={true}
            title="Add Business Unit"
            footer={<Button primary>Add</Button>}
            portal={false}
            size="S"
        >
            <Form>
                <Form.AnvilSelect label="Choose your Business Unit" options={[]} portal={false} />
                <Form.Input label="Create your own Business Unit" />
            </Form>
        </Modal>
    </div>
    );
}
render (Example1);

Drawer

Use a Drawer layout when more space is needed relative to a Modal, and seeing the original context is helpful for setting up content.

noPadding: true
---
<div style={{ height: '570px', overflow: 'hidden', position: 'relative' }} className="p-3">
    <Drawer
        header={"Add Appointment"}
        open={true}
        portal={false}
        footer={
            <ButtonGroup>
                <Button>Cancel</Button>
                <Button primary>Schedule</Button>
            </ButtonGroup>
        }
        style={{ zIndex: 1 }} // Doc-specific style
    >
            <Form.Group widths="equal">
                <Form.Input label="Start Date" shortLabel={<Icon name='event' />} />
                <Form.AnvilSelect value={{text: "10:00AM – 12:00PM"}} label="Arrival Window" options={[]} />
            </Form.Group>
            <Form.Group widths="2">
                <Form.Input label="Start Time" />
            </Form.Group>
            <Form.Checkbox className="m-t-1" label="Edit Job End Time" />
            <Form.AnvilSelect
                multiple
                value={[{text: 'Jane Doe',value: 1},{text: 'Bob Ross',value: 2},{text: 'Jackie Robinson',value: 3},{text: 'Alexandria Garcia',value: 4},{text: 'Zack Bower',value: 5}]}
                options={[]}
                label="Technicians"
                trigger={{placeholder: 'Technicians', rows: 0}}
            />
            <Form.Checkbox checked className="m-t-1" label="Send Booking Confirmation" />
    </Drawer>
</div>

Takeover

Use a Takeover with a single step when a full page of content is necessary, and the context from the previous page is not needed.

Multi-step Flows

Many flows require multiple steps with a variety of components used to complete the setup. Anvil supports two general approaches to multi-step flows: the Flow Card and Takeover + Progress Tracker arrangement.

One Page, Many Steps Flow

The Flow Card is a useful arrangement to have a multi-step flow on a single page.

Use cases for a Flow Card UI arrangement

  • When it’s important to visualize that steps build on top of each other.
  • When a persistent summary of the setup is valuable to the user.
  • When individual steps are using less complex UIs.
const BasicExample = () => {
    return (
        <FlowCard currentIndex={1}>
            <FlowCard.Step
                title="Goal Setup"
                content={
                    <>
                        <Stack spacing={5} wrap="wrap" className="p-t-2">
                            <Stack.Item style={{ minWidth: '150px' }}>
                                <Eyebrow>Membership Trade(s)</Eyebrow>
                                <BodyText>HVAC and Plumbing</BodyText>
                            </Stack.Item>
                            <Stack.Item>
                                <Eyebrow>Widget Event</Eyebrow>
                                <BodyText>January</BodyText>
                            </Stack.Item>
                            <Stack.Item>
                                <Eyebrow>Gear Event</Eyebrow>
                                <BodyText>March</BodyText>
                            </Stack.Item>
                        </Stack>
                        <Stack spacing={5} wrap="wrap" className="m-t-4">
                            <Stack.Item style={{ minWidth: '150px' }}>
                                <Eyebrow>Widget Membership</Eyebrow>
                                <BodyText>Yes</BodyText>
                            </Stack.Item>
                            <Stack.Item>
                                <Eyebrow>Widget Frequency</Eyebrow>
                                <BodyText>Quarterly</BodyText>
                            </Stack.Item>
                        </Stack>
                    </>
                }
                headerAction={<Button fill="outline" small>Edit</Button>}
                saved
            />
            <FlowCard.Step
                title="Widget Revenue"
                content={
                    <>
                        <BodyText className="m-t-2">Text that helps explain this particular step in the flow. This will help them complete the flow with the information they need.</BodyText>

                        <Form className="w-75 m-t-4">
                            <Form.Group widths="equal">
                                <Form.Input label="Widget Event" shortLabel="$" />
                                <Form.Input label="Gear Event" shortLabel="$" />
                            </Form.Group>
                            <Form.Group widths="equal">
                                <Form.Input label="Widget Event" shortLabel="$" />
                                <Form.Input label="Gear Event" shortLabel="$" />
                            </Form.Group>
                            <Form.Group widths="equal">
                                <Form.Input label="Widget Event" shortLabel="$" />
                                <Form.Input label="Gear Event" shortLabel="$" />
                            </Form.Group>
                            <Form.Group widths="equal">
                                <Form.Field>
                                    <Eyebrow>Annual Total</Eyebrow>
                                    <BodyText>$200.00</BodyText>
                                </Form.Field>
                                <Form.Field>
                                    <Eyebrow>Annual Total</Eyebrow>
                                    <BodyText>$250.00</BodyText>
                                </Form.Field>
                            </Form.Group>
                        </Form>
                    </>
                }
                footerAction={
                    <ButtonGroup className="flex-row-reverse">
                        <Button
                            primary
                            className="m-l-1"
                        >
                            Next
                        </Button>
                        <Button>Cancel</Button>
                    </ButtonGroup>
                }
                active
            />
            <FlowCard.Step
                title="Widget Costs"
                headerAction={<Button small>Edit</Button>}
                orderNumber={3}
            />
        </FlowCard>
    );
}
render (BasicExample);

Multi Page Step Guidelines

  • The Flow Card has built-in capabilities for handling pre-setup and a summary view.
  • A post-setup Modal can be used in setups to give a clear end point in the flow.

Example of a pre-step state

const BasicExample = () => {
    return (
        <FlowCard>
            <FlowCard.Step
                title="Goal Setup"
                headerAction={<Button small primary outline>Start</Button>}
                orderNumber={1}
            />
            <FlowCard.Step
                title="Widget Revenue"
                orderNumber={2}
                disabled
            />
            <FlowCard.Step
                title="Widget Costs"
                orderNumber={3}
                disabled
            />
        </FlowCard>
    );
}
render (BasicExample);

Multi Page, Many Steps Flow

The Progress Tracker and Takeover arrangement are a useful layout for complex flows that need more space for information and layout.

frame: true
noPadding: true
---
const MultipleContentSections = () => {
    const [index, setIndex] = React.useState(0);
    const avatar = (test) => {
        return (
            <td>
            <Stack spacing={1} alignItems="center">
                <Avatar name={test.dataItem.name} size="s" autoColor />
                <BodyText size="small">{test.dataItem.name}</BodyText>
            </Stack>
            </td>
        );
    };

    const items = [
        { id: 1, name: 'Test', price: 18 },
        { id: 2, name: 'Chang', price: 19 },
        { id: 3, name: 'Aniseed Syrup', price: 10 },
        { id: 4, name: 'Chef Anton\'s Cajun Seasoning', price: 22 },
        { id: 5, name: 'Chef Anton\'s Gumbo Mix', price: 21.35 }
    ];

    return (
        <div style={{ height: '600px' }}>
            <Takeover
                title="Add Widget Profile"
                backLabel="Previous Page"
                complete={index === 4}
                footer={(
                    <Stack justifyContent="space-between" direction="row-reverse" className="w-100">
                        <ButtonGroup>
                            <Button>Back</Button>
                            <Button primary>Continue</Button>
                        </ButtonGroup>
                    </Stack>
                )}
                onBack={function(){ return;}}
                onClose={function(){ return;}}
                sectioned={true}
                contentWrapperClass="d-f flex-column"
            >
                <Takeover.Section>
                    <ProgressTracker currentIndex={1}>
                        <ProgressTracker.Step label="Name Profile" />
                        <ProgressTracker.Step label="Assign Technicians" />
                        <ProgressTracker.Step label="Configure Pay Types" />
                        <ProgressTracker.Step label="Review" />
                    </ProgressTracker>
                </Takeover.Section>
                {(index === 0 || index === 2) &&
                    <Takeover.Section className="of-auto">

                        <Headline className="m-t-2">Assign Technicians</Headline>
                        <BodyText className="m-b-4">Select which technician are involved in the widget creating process.</BodyText>

                        <Table data={items} striped={false}>
                            <TableColumn field="id" title="Id" width="60px"  />
                            <TableColumn field="name" title="Name" format="{0:c}" cell={avatar} />
                            <TableColumn field="price" title="Price" width="180px" format="{0:c}" />
                        </Table>
                    </Takeover.Section>
                }
            </Takeover>
        </div>
    )
}
render (MultipleContentSections)

Use cases for a Progress Tracker & Takeover UI arrangement:

  • When there are heavy UI treatments within individual steps that need space to be used.
  • When the context of previous steps is not critical for a user to refer back to.
  • When there are many sub-steps to be considered, this arrangement can also be paired with a Flow Card.
  • When the total number of steps is between 3 and 6.

Multi Page Step Guidelines

  • For pre-setup, an empty state can be used prior to a multi-page flow.
  • When the step count goes past 6, consider breaking up the flow into multi flows, or find ways to cut out content within the setup flow.
  • If information from other steps is necessary to complete a step, have that information readily available instead of having the user recall it.
  • A final, summary step is useful for users to look over to confirm the setup.
frame: true
noPadding: true
---
const MultipleContentSections = () => {
    const [index, setIndex] = React.useState(0);
    const avatar = (test) => {
        return (
            <td>
            <Stack spacing={1} alignItems="center">
                <Avatar name={test.dataItem.name} size="s" autoColor />
                <BodyText size="small">{test.dataItem.name}</BodyText>
            </Stack>
            </td>
        );
    };

    const items = [
        { id: 1, name: 'Test', price: 18 },
        { id: 2, name: 'Chang', price: 19 },
        { id: 3, name: 'Aniseed Syrup', price: 10 },
        { id: 4, name: 'Chef Anton\'s Cajun Seasoning', price: 22 },
        { id: 5, name: 'Chef Anton\'s Gumbo Mix', price: 21.35 }
    ];

    return (
        <div style={{ height: '600px' }}>
            <Takeover
                title="Audience Builder"
                backLabel="Previous Page"
                complete={index === 4}
                footer={(
                    <Stack justifyContent="space-between" direction="row-reverse" className="w-100">
                        <ButtonGroup>
                            <Button>Back</Button>
                            <Button primary>Submit</Button>
                        </ButtonGroup>
                    </Stack>
                )}
                onBack={function(){ return;}}
                onClose={function(){ return;}}
                sectioned={true}
                contentWrapperClass="d-f flex-column"
            >
                <Takeover.Section>
                    <ProgressTracker currentIndex={2}>
                        <ProgressTracker.Step label="Overview" />
                        <ProgressTracker.Step label="Audience" />
                        <ProgressTracker.Step label="Review & Submit" />
                    </ProgressTracker>
                </Takeover.Section>
                {(index === 0 || index === 2) &&
                    <Takeover.Section className="of-auto">

                        <Layout type="island">
                            <Headline size="large" className="m-t-2 m-b-2">Review & Submit</Headline>
                            <Card>
                                <Card.Section light><Headline className="m-b-0">Overview</Headline></Card.Section>
                                <Card.Section>

                                <Eyebrow>Campaign Name</Eyebrow>
                                <BodyText className="m-b-4">Expiring Widgets</BodyText>
                                <Stack spacing={5} className="m-b-4">
                                    <Stack.Item fill><Stack direction="column" spacing={4}>
                                        <Stack.Item>
                                            <Eyebrow>Widget Name</Eyebrow>
                                            <BodyText>Widget Last Chance</BodyText>
                                        </Stack.Item>
                                        <Stack.Item>
                                            <Eyebrow>Delivery Logic</Eyebrow>
                                            <BodyText>Automatic</BodyText>
                                        </Stack.Item>
                                        <Stack.Item>
                                            <Eyebrow>Sender Name</Eyebrow>
                                            <BodyText>Jane Doe</BodyText>
                                        </Stack.Item>
                                    </Stack></Stack.Item>
                                    <Stack.Item fill><Stack direction="column" spacing={4}>
                                        <Stack.Item>
                                            <Eyebrow>Launch Date</Eyebrow>
                                            <BodyText>January 1st 2020</BodyText>
                                        </Stack.Item>
                                        <Stack.Item>
                                            <Eyebrow>Sender Email</Eyebrow>
                                            <BodyText>janedoe@email.com</BodyText>
                                        </Stack.Item>
                                        <Stack.Item>
                                            <Eyebrow>Unit Status</Eyebrow>
                                            <BodyText>Active</BodyText>
                                        </Stack.Item>
                                    </Stack></Stack.Item>
                                </Stack>
                                <Button outline>Edit</Button>
                                </Card.Section>
                            </Card>

                            <Card>
                                <Card.Section light><Headline className="m-b-0">Audience</Headline></Card.Section>
                                <Card.Section>
                                    <Stack spacing={5} className="m-b-4">
                                            <Stack.Item fill>
                                                <Eyebrow>Audience</Eyebrow>
                                                <BodyText>Acme Industries</BodyText>
                                            </Stack.Item>
                                            <Stack.Item fill>
                                                <Eyebrow>Total Audience</Eyebrow>
                                                <BodyText>5,000</BodyText>
                                            </Stack.Item>
                                            <Stack.Item fill>
                                                <Eyebrow>Potential Reach <Icon name="help" subtle /></Eyebrow>
                                                <BodyText>3,500</BodyText>
                                            </Stack.Item>
                                    </Stack>
                                    <Button outline>Edit</Button>
                                </Card.Section>
                            </Card>
                        </Layout>

                    </Takeover.Section>
                }
            </Takeover>
        </div>
    )
}
render (MultipleContentSections)

General Best Practices

  • Communicate the value of the setup. Users who don’t understand the purpose of setting up something are less likely to complete the flow.
  • As a flow gets more complex, more contextual help will be necessary to guide the user through the task.
  • Keep step count down when possible. Some potential ways to accomplish this:
    • Identify what is useful to users to setup now, and what could wait later on.
    • What setup content could be automated? Is there any information that can be pre-filled?