Skip to content

Toast

Toasts are used to convey the status of a non-critical action that requires no user feedback within a page.

Figma logo
  • Toast is a static component that is dynamically displayed via React Portals
  • Toaster and ToastContext are only required ONCE within your app
    • <Toaster open={open} onExited={onExited}>{toast}</Toaster>
    • <ToastContext.Provider value={{ showToast, hideToast }} />
  • Use for quick feedback during/after specific user actions or for system-level feedback
  • Contrast with alerts—persistent, more complex, broader use cases
  • Use only if no subsequent user action is required—don't include linked actions in toasts
    • Contrast with alerts—often include linked actions
  • Limit one message per toast
    • Group multiple actions of the same kind together into one toast
    • Use multiple toasts if you have to communicate different messages
  • Don't use toasts for:
    • Upsell/feature awareness
    • Complex info (including compliance updates)
    • Action required
  • Don't add toasts to modals or drawers
  • Don't use at the end of a flow as a success message. Should be seen during the flow to support along the way. At the end of the flow they may see a page level success message
  • Use only if no subsequent user action is required
  • Display the toast on the same page as the action that took place
  • Group multiple actions of the same kind together into one toast
  • Use multiple toasts in a row if you have to communicate different messages (they will appear one at a time in the MVP)
  • Display on the following page (ie. on the next page after selecting “submit”)
  • Use for complex info (including compliance updates)
  • Use for items that require action
  • Use for modals or drawers
  • Use buttons
  • Use illos
  • Use for upsell/feature awareness
  • Toasts should be dismissible
  • They animate up from the bottom of the page
  • They animate down to the bottom of the page when dismissed or timed out
  • Only one toast is shown at a time. A subsequent toast can animate in when one animates out.
  • Toasts are absolutely positioned 20 pixels from the bottom / left-hand corner of the bottom of a user’s screen (like a FAB)
  • Toasts float above all other content in our product on Level 3 in our Elevation system
Toast

A Toast communicates feedback of micro-actions within a page. Examples include:

  • File upload/download
  • Item saved/deleted
  • Item sent
  • Item scheduled
  • Item added/completed
  • Item approved/rejected (i.e. recording time off requests)
  • Item updated (i.e. settings)
Alert

An Alert communicates feedback at the page level. Examples include:

  • Submit button (or other CTAs)
  • System level items (server error, credit card error, etc.)
  • Critical account status items
  • Anything that requires user feedback or action
  • Communicates feedback at the end of a flow
  • Communicates compliance updates
React props
NameTypeDefaultDescription
description  stringThe description of the Toast.
getSeverityLabel  ((severity: "success" | "error") => string)sev => sevResolves the accessible label which indicates the severity of the notification.
label  RequiredstringThe title of the Toast.
onClose  ((event: MouseEvent<Element, MouseEvent>) => void)() => {}Callback fired when closing the Toast.
severity  successerrorsuccessThe level of severity for the Toast.
  • Toast text should be no more than 100 characters
  • Use shorthand form when appropriate
  • Leave out helper verbs if natural
You invited Jordan to enter their info
You invited Jordan to enter their info.

Exception: for toasts with multiple short sentences, use end punctuation. Occasionally, write it like this:

You invited Jordan to enter their info. Undo.
You invited Jordan to enter their info
Jordan's been invited to enter their info
“Fill out Jordan's I-9” is now a custom task
You made “Fill out Jordan's I-9” a custom task

The following testing snippet(s) offer suggestions for testing the component using React Testing Library with occasional help from Jest.

// Zenpayroll only
// For more info outside ZP, see:
// https://github.com/Gusto/workbench/blob/develop/packages/workbench/src/Toast/Toast.test.tsx
import ToastTestSetup from 'test-utils/toast_test_setup';
interface ToastTestBenchProps {
severity?: ToastProps['severity'];
description?: ToastProps['description'];
CloseButtonProps?: ToastProps['CloseButtonProps'];
getSeverityLabel?: ToastProps['getSeverityLabel'];
options?: ShowToastOptions;
}
const ToastTestBench: React.FC<ToastTestBenchProps> = ({
severity,
description,
getSeverityLabel,
CloseButtonProps,
options,
}) => {
const { showToast, hideToast } = useToast();
const [key, setKey] = useState(1);
return (
<button
type="button"
onClick={() => {
showToast(
key,
<Toast
severity={severity}
label={`Toast ${key}`}
description={description}
onClose={() => hideToast(key)}
CloseButtonProps={CloseButtonProps}
getSeverityLabel={getSeverityLabel}
/>,
options,
);
setKey(prevKey => prevKey + 1);
}}
>
Show toast
</button>
);
};
render(
<ToastTestSetup>
<ToastTestBench description="Descriptive text" />
</ToastTestSetup>,
);
const showButton = screen.getByRole('button', {
name: 'Show toast',
});
// open the toast
userEvent.click(showButton);
const toast = screen.getByLabelText('Toast 1');
// Role may also be queried for more specificity, but will need to use a regular
// expression or include the severity label:
//
// RegExp:
// const toast = screen.getByRole('alert', {
// name: /Toast 1/,
// });
//
// Severity label included:
// const toast = screen.getByRole('alert', {
// name: 'Success: Toast 1',
// });
expect(toast).toHaveAccessibleDescription('Descriptive text');
const closeButton = screen.getByLabelText('Close');
// close the toast
userEvent.click(closeButton);
expect(toast).not.toBeInTheDocument();