# Toaster (/cloud/desktop/toaster)



```ts title="Import"
import { Toaster } from "../components/toaster.tsx";
import { toast } from "@nyte-ai/ui/sonner";
```

File: `packages/desktop/src/renderer/src/components/toaster.tsx`. `Toaster` mounts Sonner once in
the app root; everything else calls `toast(...)` from `@nyte-ai/ui/sonner`, which re-exports the
`sonner` package.

## Configuration [#configuration]

| Setting                 | Value                                                             |
| ----------------------- | ----------------------------------------------------------------- |
| `theme`                 | From `useAppearanceSettings()`, so toasts follow the app theme.   |
| `position`              | `bottom-right`, `offset` 16, `gap` 8, `expand`                    |
| `closeButton`           | on; `closeButtonAriaLabel` "Dismiss notification"                 |
| `containerAriaLabel`    | "Notifications"                                                   |
| `icons`                 | success → `checkmark`, error and warning → `warning`, close → `x` |
| `toastOptions.unstyled` | `true`; every class name is a StyleX class                        |

Action, cancel, and close buttons all carry `focus.ring`.

## Usage rules [#usage-rules]

* Toasts are for outcomes the user did not just watch happen: a background failure, a folder that
  could not open, a copy confirmation. A form's own error stays in the form.
* Give a toast an `id` when it can fire repeatedly, so a retry replaces it instead of stacking.
  `open-workspace.tsx` uses `{ id: "workspace-open", duration: Infinity }` for a failure that
  should stay until dismissed.
* Titles are short and use `tabular-nums` (counts line up). Descriptions wrap with
  `text-wrap: pretty`.

```ts
toast.error("Couldn't open folder", {
  id: "workspace-open",
  duration: Infinity,
  description: reason,
});
toast.success("Copied");
```

## Accessibility [#accessibility]

Sonner renders a `role="region"` with the container label, and each toast as `role="status"` (or
`alert` for errors) so it is announced. The close button is a real button with a label.
