# Toast



## Example

## Content

### Title and description

Use the `"title"` and `"description"` slots within `<ToastContent>` to provide structured content for the toast. The title is required, and description is optional.

```tsx
import {queue} from 'vanilla-starter/Toast';
import {Button} from 'vanilla-starter/Button';

function Example() {
  return (
    <Button
      onPress={() => queue.add({
        title: 'Update available',
        description: 'A new version is ready to install.'
      })}
    >
      Check for updates
    </Button>
  );
}
```

### Close button

Include a `<Button slot="close">` to allow users to dismiss the toast manually. This is important for accessibility.

<InlineAlert variant="notice">
  <Heading>Accessibility</Heading>
  <Content>We recommend that that the close button should be rendered as a sibling of `<ToastContent>` rather than inside it, so that screen readers announce the toast content without the close button first.</Content>
</InlineAlert>

## Auto-dismiss

Use the `timeout` option to automatically dismiss toasts after a period of time. For accessibility, toasts should have a minimum timeout of **5 seconds**. Timers automatically pause when the user focuses or hovers over a toast.

```tsx
import {queue} from 'vanilla-starter/Toast';
import {Button} from 'vanilla-starter/Button';

function Example() {
  return (
    <Button
      onPress={() => queue.add(
        {title: 'File has been saved!'},
        {timeout: 5000}
      )}
    >
      Save file
    </Button>
  );
}
```

<InlineAlert variant="notice">
  <Heading>Accessibility</Heading>
  <Content>Only auto-dismiss toasts when the information is not critical, or may be found elsewhere. Some users may require additional time to read toasts, and screen zoom users may miss them entirely.</Content>
</InlineAlert>

## Programmatic dismissal

Toasts can be programmatically dismissed using the key returned from `queue.add()`. This is useful when a toast becomes irrelevant before the user manually closes it.

```tsx
import {queue} from 'vanilla-starter/Toast';
import {Button} from 'vanilla-starter/Button';
import {useState} from 'react';

function Example() {
  let [toastKey, setToastKey] = useState(null);

  return (
    <Button
      onPress={() => {
        if (!toastKey) {
          setToastKey(queue.add(
            {title: 'Processing...'},
            {onClose: () => setToastKey(null)}
          ));
        } else {
          queue.close(toastKey);
        }
      }}
    >
      {toastKey ? 'Cancel' : 'Process'}
    </Button>
  );
}
```

## Accessibility

Toast regions are [landmark regions](https://www.w3.org/WAI/ARIA/apg/practices/landmark-regions/) that can be navigated using <Keyboard>F6</Keyboard> to move forward and <Keyboard>Shift</Keyboard> + <Keyboard>F6</Keyboard> to move backward. This provides an easy way for keyboard users to jump to toasts from anywhere in the app.

When a toast is closed, focus moves to the next toast if any. When the last toast is closed, focus is restored to where it was before.

## API

A `<ToastRegion>` is an ARIA landmark region labeled "Notifications" by default. It accepts a render function that receives each visible toast and renders a `<Toast>` component. Each toast is a non-modal ARIA [alertdialog](https://www.w3.org/WAI/ARIA/apg/patterns/alertdialog/) containing `<ToastContent>` and a close button.

```tsx
<ToastRegion>
  {({toast}) => (
    <Toast toast={toast}>
      <ToastContent>
        <Text slot="title" />
        <Text slot="description" />
      </ToastContent>
      <Button slot="close" />
    </Toast>
  )}
</ToastRegion>
```

### ToastRegion

### Toast

### ToastContent

`<ToastContent>` renders the main content of a toast, including the title and description slots. It accepts all HTML attributes.

### ToastQueue

A `ToastQueue` manages the state for a `<ToastRegion>`. The state is stored outside React so you can trigger toasts from anywhere in your application.
