# Toast

> Organism — orn-ui

> ⚠️ Requires <UIProvider>: This component (like every orn-ui component) must render inside a <UIProvider> ancestor, or it throws at runtime. See https://orn-ui-docs.vercel.app/getting-started.md

> Runs on Expo SDK 54, 55, 56 and 57, and on bare React Native >=0.81 with react >=19.1. No native modules — works in Expo Go, no prebuild.

## Installation

Install just this component (copies the source into your project, no npm dependency)
```bash
npx orn-ui add toast
```

Or install the whole package and import it
```tsx
pnpm add orn-ui
import { Toast } from 'orn-ui/toast';
```

Depends on: core (theme + icons), transition

## Variants

### Static (placed by hand, no provider)

```tsx
<View style={{ gap: 8 }}>
  <Toast title="Invoice sent" message="Sent to acme@studio.com" variant="success" />
  <Toast title="Payment failed" variant="error" onDismiss={() => {}} />
</View>
```

## Full demo source

```tsx
const variants: VariantDef[] = [
  {
    label: 'Imperative — useToast().show()',
    content: (
      <View style={{ gap: 8 }}>
        <Button title="Success" onPress={() => show({ title: 'Invoice sent', variant: 'success' })} />
        <Button
          title="Error"
          variant="outline"
          onPress={() => show({ title: 'Payment failed', message: 'Try another card.', variant: 'error' })}
        />
        <Button
          title="Warning"
          variant="outline"
          onPress={() => show({ title: 'Unsaved changes', variant: 'warning' })}
        />
        <Button title="Info" variant="outline" onPress={() => show({ title: 'Syncing…', variant: 'info' })} />
      </View>
    ),
  },
  {
    label: 'From business logic — showToast()/showConfirm(), no hook',
    content: (
      <View style={{ gap: 8 }}>
        <Body>Both buttons call a plain async function that imports showToast/showConfirm/showAlert.</Body>
        <Button title="Delete invoice #4821" variant="outline" onPress={() => deleteInvoice('4821')} />
        <Button title="Sync (fails)" variant="outline" onPress={() => syncInvoices()} />
      </View>
    ),
  },
  {
    label: 'Options: duration, tappable, stacking',
    content: (
      <View style={{ gap: 8 }}>
        <Button
          title="Stays until dismissed"
          variant="outline"
          onPress={() => show({ title: 'Sticky toast', message: 'duration: 0', duration: 0 })}
        />
        <Button
          title="Tappable"
          variant="outline"
          onPress={() => show({ title: 'Tap me', message: 'Runs onPress and closes', onPress: () => {} })}
        />
        <Button
          title="Fire three at once"
          variant="outline"
          onPress={() => {
            show({ title: 'First', variant: 'info' });
            show({ title: 'Second', variant: 'success' });
            show({ title: 'Third', variant: 'warning' });
          }}
        />
        <Button title="Dismiss all" variant="ghost" onPress={hideAll} />
      </View>
    ),
  },
  {
    label: 'Static (placed by hand, no provider)',
    content: (
      <View style={{ gap: 8 }}>
        <Toast title="Invoice sent" message="Sent to acme@studio.com" variant="success" />
        <Toast title="Payment failed" variant="error" onDismiss={() => {}} />
      </View>
    ),
  },
];
return <VariantList variants={variants} />;
```

## Props

| Name | Type | Default | Description |
|---|---|---|---|
| `title` | `string` | — | — |
| `message?` | `string` | — | — |
| `variant?` | `'success' \| 'error' \| 'warning' \| 'info'` | info | — |
| `onPress?` | `() => void` | — | Fires when the toast is tapped (on top of dismissing it). |
| `onDismiss?` | `() => void` | — | — |
| `hideCloseButton?` | `boolean` | — | Hides the close X. The toast still auto-dismisses on a timer. |
| `style?` | `StyleProp<ViewStyle>` | — | — |
