Skip to content
React NativeBeta

Toaster

Brief messages that stack, auto-dismiss, pause on touch and swipe away. Fire them with toast() from anywhere.

Beta. React Native support is in beta. APIs may change or break between prereleases (npm tag native).

On this page
Web preview — real device may differ
tsx
import { useState } from "react";
import { Text } from "react-native";
import { Button } from "@/component-lib/button";
import { useKitTheme } from "@/component-lib/shared/native";
import { toast, Toaster, type ToastPosition } from "@/component-lib/toaster";
import { Row, Section } from "./layout"; // Section and Row: page layout for the demo
 
const wait = (ms: number, fail = false) =>
  new Promise<string>((resolve, reject) => setTimeout(() => (fail ? reject(new Error("Timed out")) : resolve("42 rows")), ms));
 
export function ToasterDemo() {
  const { tokens } = useKitTheme();
  const [position, setPosition] = useState<ToastPosition>("top-center");
 
  return (
    <>
      {/* Normally mounted once at the app root; here so the demo stands alone. */}
      <Toaster position={position} />
 
      <Section title="toast · types">
        <Row>
          <Button variant="outline" onPress={() => toast("Draft saved")}>
            Default
          </Button>
          <Button variant="outline" onPress={() => toast.success("Payment received", { description: "₹12,500 from Ward 4" })}>
            Success
          </Button>
          <Button variant="outline" onPress={() => toast.error("Upload failed", { description: "Check your connection." })}>
            Error
          </Button>
        </Row>
        <Row>
          <Button variant="outline" onPress={() => toast.warning("Storage almost full")}>
            Warning
          </Button>
          <Button variant="outline" onPress={() => toast.info("New version available")}>
            Info
          </Button>
          <Button
            variant="outline"
            onPress={() => {
              const id = toast.loading("Syncing…");
              setTimeout(() => toast.update(id, { type: "success", title: "Synced", duration: 3000 }), 1500);
            }}
          >
            Loading → done
          </Button>
        </Row>
      </Section>
 
      <Section title="toast · actions and promise">
        <Row>
          <Button
            variant="secondary"
            onPress={() =>
              toast("Invoice deleted", {
                action: { label: "Undo", onClick: () => toast.success("Restored") },
                cancel: { label: "Dismiss", onClick: () => undefined },
                duration: 8000,
              })
            }
          >
            With undo
          </Button>
          <Button
            variant="secondary"
            onPress={() =>
              void toast
                .promise(wait(1500), {
                  loading: "Importing…",
                  success: (rows) => `Imported ${rows}`,
                  error: (e) => `Import failed: ${(e as Error).message}`,
                })
                .catch(() => undefined)
            }
          >
            Promise
          </Button>
          <Button
            variant="secondary"
            onPress={() =>
              void toast
                .promise(wait(1200, true), { loading: "Exporting…", error: "Export failed" })
                .catch(() => undefined)
            }
          >
            Promise fails
          </Button>
        </Row>
        <Button variant="ghost" onPress={() => toast.dismiss()}>
          Dismiss all
        </Button>
      </Section>
 
      <Section title="Toaster · position">
        <Row>
          {(["top-center", "bottom-center", "top-right", "bottom-left"] as const).map((p) => (
            <Button key={p} size="sm" variant={p === position ? "primary" : "outline"} onPress={() => setPosition(p)}>
              {p}
            </Button>
          ))}
        </Row>
        <Text style={{ color: tokens.muted }}>Swipe a toast sideways to dismiss it; hold it to pause its timer.</Text>
      </Section>
    </>
  );
}

Install

npx @grampro/kit@native add Toaster

Usage

tsx
import { Toaster, toast } from "@/component-lib/toaster";
 
// Once, inside KitProvider:
<Toaster />
 
// Anywhere:
toast.success("Invoice sent");

Props

ToasterProps

PropTypeDescription
positionToastPositionDefault "top-center" (the web defaults to top-right; a phone has no corner to spare).
limitnumberOpen toasts on screen at once; the rest wait their turn. Default 3.
durationnumberDefault auto-close delay in milliseconds. Default 5000.
closeButtonbooleanShow a close button on dismissible toasts. Default true.
iconsPartial<Record<ToastType, ReactNode>>Replace the icon per type; null hides it.
storeToastStoreA store from createToastStore(). Defaults to the one behind toast().
styleStyleProp<ViewStyle>The region holding the toasts.
stylesToasterStyles
localeTextPartial<ToasterLocaleText>

Native and web

  • Defaults to top-center on native and keeps clear of the notch and gesture bar.
  • Known gap: a toast fired from inside an open Modal or Dialog shows once it closes.
  • Web version: Toaster on the web.