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
2+ steps, overview of information is important
2+ steps, flows have complex data interaction
Simple, Quick Setups
When setups require minimal guidance and steps, different layouts can be used, each with its own advantages.
Modal
Use a Modal layout when content is limited and context underneath a Modal is not needed.
<Modal
open
closable
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>
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.
<Drawer
header={"Add Appointment"}
open
portal={false}
footer={
<ButtonGroup>
<Button>Cancel</Button>
<Button primary>Schedule</Button>
</ButtonGroup>
}
>
<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>
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.
<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>
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
<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>
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.
<State initial={1}>
{([index, setIndex]) => (
<Takeover
portal={false}
focusTrapOptions={{disabled: true}}
title="Add Widget Profile"
backLabel="Previous Page"
footer={(
<Stack justifyContent="space-between" direction="row-reverse" className="w-100">
<ButtonGroup>
<Button onClick={() => setIndex(index <= 0 ? 0 : index - 1)}>Back</Button>
<Button onClick={() => setIndex(index >= 3 ? 3 : index + 1)} primary>Continue</Button>
</ButtonGroup>
</Stack>
)}
onBack={() => { return; }}
onClose={() => { return; }}
sectioned
contentWrapperClass="d-f flex-column"
>
<Takeover.Section>
<ProgressTracker currentIndex={index}>
<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) &&
<Takeover.Section className="of-auto">
<Headline className="m-t-2">Name Profile</Headline>
<BodyText className="m-b-4">...</BodyText>
</Takeover.Section>
}
{(index === 1) &&
<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={[
{ 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 }
]}
striped={false}
>
<TableColumn field="id" title="Id" width="60px" />
<TableColumn
field="name"
title="Name"
format="{0:c}"
cell={(prop) => (
<td>
<Stack spacing={1} alignItems="center">
<Avatar name={prop.dataItem.name} size="s" autoColor />
<BodyText size="small">{prop.dataItem.name}</BodyText>
</Stack>
</td>
)}
/>
<TableColumn field="price" title="Price" width="180px" format="{0:c}" />
</Table>
</Takeover.Section>
}
{(index === 2) &&
<Takeover.Section className="of-auto">
<Headline className="m-t-2">Configure Pay Types</Headline>
<BodyText className="m-b-4">...</BodyText>
</Takeover.Section>
}
{(index === 3) &&
<Takeover.Section className="of-auto">
<Headline className="m-t-2">Review</Headline>
<BodyText className="m-b-4">...</BodyText>
</Takeover.Section>
}
</Takeover>
)}
</State>
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.
<State initial={2}>
{([index, setIndex]) => (
<Takeover
portal={false}
focusTrapOptions={{disabled: true}}
title="Audience Builder"
backLabel="Previous Page"
footer={(
<Stack justifyContent="space-between" direction="row-reverse" className="w-100">
<ButtonGroup>
<Button onClick={() => setIndex(index <= 0 ? 0 : index - 1)}>Back</Button>
<Button onClick={() => setIndex(index >= 2 ? 2 : index + 1)} primary>Continue</Button>
</ButtonGroup>
</Stack>
)}
onBack={() => { return; }}
onClose={() => { return; }}
sectioned
contentWrapperClass="d-f flex-column"
>
<Takeover.Section>
<ProgressTracker currentIndex={index}>
<ProgressTracker.Step label="Overview" />
<ProgressTracker.Step label="Audience" />
<ProgressTracker.Step label="Review & Submit" />
</ProgressTracker>
</Takeover.Section>
{(index === 0) &&
<Takeover.Section className="of-auto">
<Headline size="large" className="m-t-2 m-b-2">Overview</Headline>
<BodyText className="m-b-4">...</BodyText>
</Takeover.Section>
}
{(index === 1) &&
<Takeover.Section className="of-auto">
<Headline size="large" className="m-t-2 m-b-2">Audience</Headline>
<BodyText className="m-b-4">...</BodyText>
</Takeover.Section>
}
{(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" /></Eyebrow>
<BodyText>3,500</BodyText>
</Stack.Item>
</Stack>
<Button outline>Edit</Button>
</Card.Section>
</Card>
</Layout>
</Takeover.Section>
}
</Takeover>
)}
</State>
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?