<Toast
        title="Membership billing run is in process in the background."
        onClose={() => {}}
        portal={false}
        duration={0}
    >
        The system will notify you once{'\u00A0'}completed.
    </Toast>

Usage

Toast notifications are used when:

  • The user does not need to be interrupted.
  • The user is being informed of an event, with the option to take action.
  • The results of an action are delayed.
  • The notification could appear anywhere in the application.

All notifications share the non-interruptive function. Banner notifications are tied to a specific view and are usually generated immediately after a save. Announcement notifications convey an app-wide event and not feedback on a workflow. Snackbar notifications are less-intrusive, concise messages that inform a user that an action has been completed.

Status Variations

Info (Default)

Communicates operational information to the user. These are commonly used to denote the start of an operation, and usually includes follow up notifications. A one-off acknowledgement notification could also be a Snackbar. If content in an area needs to be blocked with an operation, a loading mask could be used over the Info Toast.

    <Toast
        title="The batch is processing."
        onClose={() => {}}
        onPrimaryActionClick={() => {}}
        primaryActionName={"View Progress"}
        portal={false}
        duration={0}
    >
        You will be notified once completed.
    </Toast>

Success

Communicates the success of an operation, e.g. a long-running process has finished. These are often paired with an info toast.

    <Toast
        status="success"
        title="All Done!"
        onClose={() => {}}
        portal={false}
        duration={0}
    >
        7 items were added.
        You can view a history of all changes in the <Link primary>Sync Log</Link>.
    </Toast>

Critical/Error

Toast errors are when an operation was unable to be performed or has failed. Page-specific and form errors should utilize the Banner notification. When applicable, users should be able to take action on an operation.

    <Toast
        status="critical"
        onPrimaryActionClick={() => {}}
        primaryActionName="View Errors"
        title="We were unable to process the bulk widget action."
        onClose={() => {}}
        portal={false}
        duration={0}
    />
    <Toast
        status="critical"
        title="Access to legacy reports is disabled."
        onClose={() => {}}
        portal={false}
        duration={0}
    />

Warning

Warnings are distinct from errors and represent issues that do not need an immediate resolution, but still need to be addressed. Unintended consequences in an operation and fallback choices are common examples. Users in general should be able to take action on a warning.

    <Toast
        status="warning"
        onPrimaryActionClick={() => {}}
        primaryActionName="Configure Payroll"
        title="Adjustment Completed"
        onClose={() => {}}
        portal={false}
        duration={0}
    >
        The adjustment will not affect the current payroll because it is already frozen.
    </Toast>
    <Toast
        status="warning"
        onPrimaryActionClick={() => {}}
        primaryActionName="View Job Value"
        onSecondaryActionClick={() => {}}
        secondaryActionName="Undo Estimate"
        title="Job value not found, an estimate has been applied"
        onClose={() => {}}
        portal={false}
        duration={0}
    />

Actions

0–2 actions can be added to each Toast. Action styling is predefined as one primary and one secondary action.

    <Toast
        status="critical"
        title="You need to be logged in to continue using the system"
        onPrimaryActionClick={() => {}}
        primaryActionName="Login"
        onSecondaryActionClick={() => {}}
        secondaryActionName="Reset Password"
        portal={false}
        duration={0}
    />

Close Action

In general, toast should be dismissible. Important, persistent events are the general exception.

    <Toast
        title="Bulk booking is in the process in the background."
        onClose={() => {}}
        portal={false}
        duration={0}
    />
    <Toast
        status="critical"
        title="We were unable to bulk book the selections."
        portal={false}
        duration={0}
    />

With a Progress Bar

When it is possible to calculate the time it takes to complete a task, a Toast can be paired with a Progress Bar.

const Example = () => {
    return (
        <Toast.Group portal={false}>
            <Toast
                status="info"
                title="Import Adjustments"
                portal={false}
                duration={0}
            >
                In progress
                <ProgressBar progress={30} small blue className="m-t-1" />
            </Toast>
            <Toast
                status="success"
                title="Successful Import"
                onPrimaryActionClick={() => {}}
                primaryActionName="View Import"
                portal={false}
                duration={0}
            >
                <ProgressBar progress={100} small green className="m-t-3" />
            </Toast>
            <Toast
                status="critical"
                title="Error in Import Adjustment"
                onPrimaryActionClick={() => {}}
                primaryActionName="Widget Page"
                portal={false}
                duration={0}
            >
                There was an error in processing the import.
                <ProgressBar progress={60} small red className="m-t-1" />
            </Toast>
        </Toast.Group>
    );
}
render (Example);

Duration

By default, Toasts expire after 8 seconds which is our recommended expiration duration. This can also be set to only expire on user action by removing the duration.


Grouped Toasts

Multiple Toasts can be displayed on the screen. In general, newer toasts should appear at the top of the group. By default, only 5 toasts are shown at a time. Older messages are hidden from view for newer messages.

const GroupExample = () => {
    const [state, setState] = React.useState({
        index: 1,
        items: []
    });
    return (
        <React.Fragment>
            <Toast.Group>
                {state.items.map(index => (
                    <Toast
                        key={index}
                        portal={false}
                        title={`Message #${index}`}
                        onClose={() => setState({
                            items: state.items.filter(idx => idx !== index)
                        })}
                        onPrimaryActionClick={() => setState({
                            items: state.items.filter(idx => idx !== index)
                        })}
                        primaryActionName="Close"
                        duration={0}
                    />
                ))}
            </Toast.Group>

            <Button onClick={() => setState({
                index: state.index + 1,
                items: [state.index].concat(state.items)
            })}>Demo Multiple Toasts</Button>
        </React.Fragment>
    )
};
render (GroupExample);

Best Practices

  • Titles should not stretch beyond two lines.
  • In a queue, priority is given to critical/error statuses, followed by order in which they are generated.
  • Don't use an action button to close the toast.
  • Don't use this pattern for handling page specific errors.
  • Avoid blaming the user for an operational error. Accept blame when we know it's our fault.
  • Avoid excessive use of the pattern. While these do not interrupt the user, they can be distracting.
  • Avoid technical jargon.

Related Components

  • To require a user interaction, use a Modal component.
  • For critical information that requires a specific decision, use a Dialog component.

For non-intrusive notifications:

  • Site-wide information about an event, use the Announcement notification.
  • Content specific to the page, use the Banner notification.
  • Quick, successful information, use the Snackbar notification.

Importing

import { Toast } from '@servicetitan/design-system';