Skip to Content

Toast

A toast is a non-disruptive message that provides feedback based on a user action.

Usage

Before triggering a toast, you need to call the useToaster hook, which returns an object containing various methods for triggering the toast and changing the toaster settings.

import * as React from 'react';
import { useToaster, Button } from '@itwin/itwinui-react';

export default () => {
  const toaster = useToaster();

  return (
    <div className='demo-container'>
      <Button onClick={() => toaster.positive('Job processing completed.')}>
        Open toast
      </Button>
    </div>
  );
};

Note: useToaster must be called from the top level of a component which is rendered as a descendant of ThemeProvider.

Status

Toasts can be triggered using the status methods provided by the toaster object. The status method takes in a toast message and an options object for further customization. Four available statuses are:

  • positive()
  • negative()
  • warning()
  • informational()
import * as React from 'react';
import { useToaster, Button } from '@itwin/itwinui-react';

export default () => {
  const toaster = useToaster();

  return (
    <div className='demo-container'>
      <Button
        onClick={() => toaster.positive('This is a positive toast message.')}
      >
        Positive
      </Button>
      <Button
        onClick={() => toaster.negative('This is a negative toast message.')}
      >
        Negative
      </Button>
      <Button
        onClick={() => toaster.warning('This is a warning toast message.')}
      >
        Warning
      </Button>
      <Button
        onClick={() =>
          toaster.informational('This is an informational toast message.')
        }
      >
        Informational
      </Button>
    </div>
  );
};

For further customization with options, you can utilize link, which allows taking further actions directly from the toast, such as navigating to another page or triggering a specific function.

import * as React from 'react';
import { useToaster, Button } from '@itwin/itwinui-react';

export default () => {
  const toaster = useToaster();

  const displayToast = () => {
    toaster.positive('Job processing completed.', {
      link: {
        title: 'Link',
        onClick: () => {
          alert('Link was clicked!');
        },
      },
    });
  };

  return (
    <div className='demo-container'>
      <Button onClick={displayToast}>Toast with link</Button>
    </div>
  );
};

Settings

The object returned by useToaster also provides a setSettings method, which can be used to customize the placement and order of toasts.

placement supports the following values:

  • "top" (default)
  • "top-start"
  • "top-end"
  • "bottom"
  • "bottom-start"
  • "bottom-end"

"start" indicates the left side of viewport, while "end" represents the right side.

import * as React from 'react';
import { useToaster, Button, Select } from '@itwin/itwinui-react';

export default () => {
  const toaster = useToaster();

  return (
    <div className='demo-container'>
      <Select
        placeholder='Select placement'
        triggerProps={{
          'aria-label': 'Placement',
        }}
        options={[
          { value: 'top', label: 'Top' },
          { value: 'top-start', label: 'Top start' },
          { value: 'top-end', label: 'Top end' },
          { value: 'bottom', label: 'Bottom' },
          { value: 'bottom-start', label: 'Bottom start' },
          { value: 'bottom-end', label: 'Bottom end' },
        ]}
        onChange={(value) =>
          toaster.setSettings({
            placement: value,
          })
        }
      />
      <Button onClick={() => toaster.informational('This is a toast message.')}>
        Open toast
      </Button>
    </div>
  );
};

order supports the following values:

  • "auto" (default)
  • "descending"
  • "ascending"

When set to "descending", the most recent toasts are on top. When set to "ascending", the most recent toasts are on bottom. When set to "auto", it will behave like "descending" when placement is set to a value beginning with "top", otherwise it will behave like "ascending".

import * as React from 'react';
import { useToaster, Button, Select } from '@itwin/itwinui-react';

export default () => {
  const toaster = useToaster();

  return (
    <div className='demo-container'>
      <Select
        triggerProps={{
          'aria-label': 'Order',
        }}
        placeholder='Select order'
        options={[
          { value: 'ascending', label: 'Ascending' },
          { value: 'descending', label: 'Descending' },
          { value: 'auto', label: 'Auto' },
        ]}
        onChange={(value) =>
          toaster.setSettings({
            order: value,
          })
        }
      />
      <Button onClick={() => toaster.informational('This is a toast message.')}>
        Open toast
      </Button>
    </div>
  );
};

Closing toasts

When setting the hasCloseButton option available in the status method to true, each toast will be displayed with a close button, which allows the end user to close the toast manually.

import * as React from 'react';
import { useToaster, Button } from '@itwin/itwinui-react';

export default () => {
  const toaster = useToaster();

  return (
    <div className='demo-container'>
      <Button
        onClick={() =>
          toaster.positive('This is a positive message', {
            hasCloseButton: true,
          })
        }
      >
        Open toast
      </Button>
    </div>
  );
};

Additionally, to implement further actions upon the closing of each toast or to chain one toast after another, you can call the close() function returned from the status method.

import * as React from 'react';
import { useToaster, Button, Flex, ProgressRadial } from '@itwin/itwinui-react';

export default () => {
  const toaster = useToaster();

  const displayProcessToast = () => {
    const { close } = toaster.informational(
      <Flex>
        <ProgressRadial size='small' />
        Your process is running...
      </Flex>,
    );

    setTimeout(() => {
      close();
      toaster.positive('Process completed', {
        hasCloseButton: true,
      });
    }, 1000);
  };

  return <Button onClick={displayProcessToast}>Start process</Button>;
};

Closing also depends on the type of toast when used without hasCloseButton. By default, persisting toasts will not be closed automatically and will contain a close button while temporary toasts will automatically close after 7 seconds and will not contain a close button. The type of toasts can be specified by passing either "persisting" or "temporary" into the type option.

import * as React from 'react';
import { useToaster, Button } from '@itwin/itwinui-react';

export default () => {
  const toaster = useToaster();

  return (
    <div className='demo-container'>
      <Button
        onClick={() =>
          toaster.informational('This is a persisting toast.', {
            type: 'persisting',
          })
        }
      >
        Persisting toast
      </Button>
      <Button
        onClick={() =>
          toaster.informational('This is a temporary toast.', {
            type: 'temporary',
          })
        }
      >
        Temporary toast
      </Button>
    </div>
  );
};

To close all currently open toasts at once, use the closeAll() method offered by the toaster object.

import * as React from 'react';
import { useToaster, Button } from '@itwin/itwinui-react';

export default () => {
  const toaster = useToaster();

  return (
    <div className='demo-container'>
      <Button onClick={() => toaster.positive('Job 1 processing completed.')}>
        Open toast 1
      </Button>
      <Button onClick={() => toaster.positive('Job 2 processing completed.')}>
        Open toast 2
      </Button>
      <Button onClick={() => toaster.closeAll()}>Close All</Button>
    </div>
  );
};

The animateOutTo prop allows you to control the direction to which the toast animates out when closing. Specifically, it helps determine an “anchor” element that the toast will go towards when it is dismissed. This can be useful, for example, when you want to indicate to the user that the toasts are being saved into a “notifications” panel.

import * as React from 'react';
import { useToaster, Button } from '@itwin/itwinui-react';

export default () => {
  const toaster = useToaster();
  const buttonRef = React.useRef(null);

  React.useEffect(() => {
    toaster.setSettings({
      placement: 'top-end',
    });
  }, []);

  return (
    <div className='demo-container'>
      <Button
        ref={buttonRef}
        onClick={() =>
          toaster.positive('This is a positive toast message', {
            animateOutTo: buttonRef.current,
          })
        }
      >
        Anchor to button
      </Button>
    </div>
  );
};

Props

Prop Description Default
id
Internal id of the toast. Used for closing the toasts.
number
content
Content of the Toast message
ReactNode
domProps
Passes props to toast and content
{ toastProps?: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>; contentProps?: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>; }
category
Category of the Toast, which controls the border color, as well as the category icon.
ToastCategory
type
The Type of the Toast. Persisting Toasts will not be closed automatically, and will contain a close button. Temporary Toasts will automatically close after 7 seconds and will not contain a close button.
"persisting" | "temporary"
'temporary'
isVisible
Controlled boolean prop indicating whether the toast is visible.
boolean
duration
Duration of the toast in millisecond.
number
7000
hasCloseButton
Boolean indicating when the close button is visible. When false, the toast will not have any close button.
boolean
link
Props for a button/link that can be used to perform an action (e.g. to show additional information).
{ title: string; } & Omit<Omit<DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref">, "children">
onRemove
Function called when the toast is all the way closed.
() => void
animateOutTo
Element to which the toast will animate out to.
HTMLElement