You are currently on Anvil1, which is now in maintenance mode. Visit Anvil2 to get the latest version of the design system.
patterns / null
Page Header
Page Header
The Page Header represents the top section of the site, directly below the global header. High level informational displays, actions, and navigation may exist in the page header.
Overview
Most pages in the application have a repeatable pattern of components. This documentation provides the general best practice for what can be added to a header, where in it, and when to use it. This pattern is used in conjunction with our Page component.
Principles
Consistency in structure and page relation. On any given page, how the header arranges descriptions, actions, and navigation should be similar across the application.
Prioritize small vertical height. Many pages in the ServiceTitan app are dense. Headers should help users complete their tasks on a page, but should get out of the way for the page’s main content.
Consistency in foundational styles. There are many ways to subtly visualize the same header. Standardizing the foundational choices, from text sizes to button variations, improves familiarity to users.
Header Anatomy
Page Headers are broken up into three general functions: The description of the page, actions on the page, and navigation within the page.
Descriptions provide a more detailed overview of what the page is about. In general this will be a single line of text, but can be customized to fit the specific needs of a page. A title should always be used with a description.
Tags provide useful metadata about the page. The relative importance of this data varies from page to page: the visual variations provided by Tags can help prioritize them in the header.
<Pageheader={
<StackalignItems="center"spacing={2}wrap='wrap'>
<Stack.Itemfill>
<StackalignItems="center"spacing={1}>
<Headlinesize="large"className="m-b-0">
Batch #33: Plumbing Small Parts
</Headline>
<Tagcolor='info'compact>Scheduled</Tag>
</Stack>
</Stack.Item>
</Stack>
}>
<Dividerspacing="4"/>
Content of the page.
</Page>
<Pageheader={
<>
<StackalignItems="center"spacing={2}wrap='wrap'>
<Stack.Itemfill>
<StackalignItems="center"spacing={1}>
<Headlinesize="large"className="m-b-0">
Old Equipment
</Headline>
</Stack>
</Stack.Item>
</Stack>
<div>
<TagGroupclassName="m-t-1 m-b-2">
<Tagcolor='success'>Active</Tag>
<Tagsubtle>Unsold Estimates</Tag>
</TagGroup>
<BodyTextsubdued>A standard description for the entire page.</BodyText>
</div>
</>
}>
<Dividerspacing="4"/>
Content of the page.
</Page>
Actions
Actions can refer to many different activities a user can perform at the page level.
Types of Actions
The majority of page-level actions should be located within the header. Some actions are more appropriate for the page footer. Actions that only apply to a section of the page, or tied to a Table, should
Add / Create
Starting a Flow
Edit page contents
Switch to
Secondary page actions, such as download, share, print, import, etc.
A generic action that brings the user to a new page, Takeover, or Modal.
Most actions can be represented through Buttons. These appear on the right side of the page. Except for the overflow menu, the most important actions are on the right-most side of the header. There should only be between 0-1 primary actions (visually a solid blue button) in the page header. Button actions should not be explicitly tied to a Table.
An overflow menu is placed on the right-most side of the header. This menu is useful when there are many page-level actions, the number of potential overflow actions varies by context, and there is a need to purposefully deemphasize actions (e.g. delete). The disadvantage of an overflow menu is the lack of discoverability of the actions and the extra clicks it takes to complete an action.
Page-level search and filtering are separated from Button-based actions. When they manipulate data on the page, they appear below the description area, starting on the left. When they manipulate data across many pages, they are to the left of other persistent Button-based actions.
Breadcrumbs are an optional, supplemental navigational element that helps users understand where they are in the app. Breadcrumbs don’t show where a user has been, but shows the underlying site structure to a user. If a page can be accessed through multiple parent pages (i.e. poly-hierarchical), a single pathway should be designated. Assuming a page title exists, the page you are on should not be represented in the breadcrumbs.
constExample=()=>{
const breadcrumbs =(
<BreadcrumbclassName="m-b-1">
<Breadcrumb.Linklabel="Root page"/>
<Breadcrumb.Linklabel="Subpage"/>
<Breadcrumb.Linklabel="Current page"/>
</Breadcrumb>
);
const title =(text ='Page Title')=><Headlinesize="large"className="m-b-0">{text}</Headline>;
const actions =<Buttonsmall>Action</Button>;
return(
<Pageheader={
<>
{breadcrumbs}
<StackalignItems="center"spacing={2}wrap='wrap'>
<Stack.Itemfill>
{title('Page Title')}
</Stack.Item>
{actions}
</Stack>
</>
}>
<Dividerspacing="4"/>
Content of the page.
</Page>
);
}
render(<Example/>)
When to use Breadcrumbs
If the page has a parent page (i.e. a page represented in the sidebar or global header)
When a user has likely entered the page from outside the hierarchy
When not to use Breadcrumbs
When there is no parent page to return to, such as if the page appears in a Sidebar.
Within a flow or wizard. The Back Link can be used instead.
To replace any other navigational structure.
Tertiary navigation via Tabs
A tertiary navigation (primary navigation being the global header, secondary being the sidebar) can be added to the Page header. This is represented through the Tab component. Tabs in the header can be divided into two purposes: to navigate to different pages related to the title, and to filter content on the page, such as a table.
Page-level Tabs
Use page-level Tabs when the header content above the Tabs does not change between tab switches. Types of content below the page typically varies between tabs.
constExample=()=>{
const title =(text ='Page Title')=><Headlinesize="large"className="m-b-0">{text}</Headline>;
return(
<Pageheader={
<>
<StackalignItems="center"spacing={2}wrap='wrap'>
<Stack.Itemfill>
{title('Sync Log')}
</Stack.Item>
</Stack>
<TabGroupclassName="m-t-3">
<Tabactive>Services</Tab>
<Tab>Material</Tab>
<Tab>Equipment</Tab>
</TabGroup>
</>
}>
Content of the page.
</Page>
);
}
render(<Example/>)
Notifications
Banner notifications should appear at the bottom of the page header, above the start of the page content.
<BodyTextsubduedclassName="m-t-1">A standard description for the entire page.</BodyText>
);
return(
<Pageheader={
<>
{breadcrumbs}
<StackalignItems="center"spacing={2}wrap='wrap'>
<Stack.Itemfill>
{title('Page Title')}
</Stack.Item>
{actions}
</Stack>
{description}
</>
}>
<Dividerspacing="4"/>
<Banner
icon
title="You are viewing an inactive item."
className="m-b-4"
/>
Content of the page.
</Page>
);
}
render(<Example/>)
Boxed Style Headers
The header can be customized to be "boxed" from the content below it. It applies a full-width white background. This styling can be used when incorporating a custom fixed header style, or when the page is very dense in content. When using, it is recommended to consistently use it across the same section of the app. Caution should be used when using this style, as it is visually heavier, and is a little more difficult to technically maintain.
constExample=()=>{
const breadcrumbs =(
<BreadcrumbclassName="m-b-1">
<Breadcrumb.Linklabel="Root page"/>
<Breadcrumb.Linklabel="Subpage"/>
<Breadcrumb.Linklabel="Current page"/>
</Breadcrumb>
);
const title =(text ='Page Title')=><Headlinesize="large"className="m-b-0">{text}</Headline>;