npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@xsolla/xui-toast

v0.150.0

Published

A cross-platform React toast notification system for displaying brief, auto-dismissing messages. Built on a provider/context architecture with a hook-based API, the Toast package supports multiple variants, configurable positioning, custom durations, cust

Readme

Toast

A cross-platform React toast notification system for displaying brief, auto-dismissing messages. Built on a provider/context architecture with a hook-based API, the Toast package supports multiple variants, configurable positioning, custom durations, custom icons, and programmatic dismiss — on both React (web) and React Native.

Installation

npm install @xsolla/xui-toast @xsolla/xui-core
# or
yarn add @xsolla/xui-toast @xsolla/xui-core

Peer dependencies: react >= 16.8.0, styled-components >= 4

Architecture

The toast system uses a Provider → Context → Hook pattern:

┌─────────────────────────────────────────────────┐
│  ToastProvider                                   │
│  ┌────────────┐  ┌───────────────────────────┐  │
│  │ ToastContext│  │ ToastGroup (portal / abs) │  │
│  │  - toasts  │  │  ┌───────┐ ┌───────┐      │  │
│  │  - addToast│──▶  │ Toast │ │ Toast │ ...  │  │
│  │  - dismiss │  │  └───────┘ └───────┘      │  │
│  └────────────┘  └───────────────────────────┘  │
│        ▲                                         │
│        │  useToast()                             │
│  ┌─────┴──────┐                                  │
│  │  Your App  │                                  │
│  └────────────┘                                  │
└─────────────────────────────────────────────────┘
  1. ToastProvider — Wraps your application. Manages toast state (an array of ToastData), auto-dismiss timers, and renders the ToastGroup container.
  2. ToastContext — React context that exposes addToast, dismissToast, and dismissAllToasts to descendants.
  3. useToast — Consumer hook that provides convenience methods (success, info, warning, error, dismiss, dismissAll).
  4. ToastGroup — Renders the stack of visible toasts. On web, uses ReactDOM.createPortal to escape z-index stacking contexts. On React Native, uses absolute positioning.
  5. Toast — The individual notification component with icon, message, and optional close button.

Quick Start

1. Wrap your app with ToastProvider

React (Web):

import { XUIProvider } from '@xsolla/xui-core';
import { ToastProvider } from '@xsolla/xui-toast';

export default function App() {
  return (
    <XUIProvider initialMode="dark" initialProductContext="b2b">
      <ToastProvider>
        <YourApp />
      </ToastProvider>
    </XUIProvider>
  );
}

React Native:

import React from 'react';
import { View } from 'react-native';
import { XUIProvider } from '@xsolla/xui-core';
import { ToastProvider } from '@xsolla/xui-toast';
import { MainNavigator } from './navigation';

export default function App() {
  return (
    <XUIProvider mode="dark">
      <ToastProvider position="top">
        <View style={{ flex: 1 }}>
          <MainNavigator />
        </View>
      </ToastProvider>
    </XUIProvider>
  );
}

Important for React Native: The ToastProvider renders toasts using absolute positioning. Ensure your app's root container has flex: 1 so toasts position correctly relative to the screen.

2. Show toasts with useToast

import { useToast } from '@xsolla/xui-toast';

function SaveButton() {
  const toast = useToast();

  const handleSave = async () => {
    try {
      await saveData();
      toast.success('Changes saved successfully');
    } catch {
      toast.error('Failed to save changes');
    }
  };

  return <button onClick={handleSave}>Save</button>;
}

Demo

Showing Toast Variants

Each variant conveys a different semantic meaning and displays a corresponding icon:

import { useToast } from '@xsolla/xui-toast';

export default function ToastExample() {
  const toast = useToast();

  return (
    <div style={{ display: 'flex', gap: 8 }}>
      <button onClick={() => toast.success('Quest has been activated')}>
        Success
      </button>
      <button onClick={() => toast.info('You received 50 Xsolla Points')}>
        Info
      </button>
      <button onClick={() => toast.warning('Your session is about to expire')}>
        Warning
      </button>
      <button onClick={() => toast.error('Failed to save changes')}>
        Error
      </button>
    </div>
  );
}

Showing Toasts (React Native)

The useToast hook works identically in React Native. Use onPress instead of onClick:

import React from 'react';
import { View } from 'react-native';
import { Button } from '@xsolla/xui-button';
import { useToast } from '@xsolla/xui-toast';

export default function ToastExample() {
  const toast = useToast();

  return (
    <View style={{ gap: 8 }}>
      <Button onPress={() => toast.success('Quest has been activated')}>
        Success
      </Button>
      <Button onPress={() => toast.info('You received 50 Xsolla Points')}>
        Info
      </Button>
      <Button onPress={() => toast.warning('Your session is about to expire')}>
        Warning
      </Button>
      <Button onPress={() => toast.error('Failed to save changes')}>
        Error
      </Button>
    </View>
  );
}

Toast Variants (Standalone Toast Component)

The Toast component can be used standalone outside the provider for static display or custom layouts:

import { Toast } from '@xsolla/xui-toast';

export default function ToastVariants() {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 8, maxWidth: 400 }}>
      <Toast id="1" variant="success" message="Quest has been activated" onClose={() => {}} />
      <Toast id="2" variant="info" message="You received 50 Xsolla Points" onClose={() => {}} />
      <Toast id="3" variant="warning" message="Your session is about to expire" onClose={() => {}} />
      <Toast id="4" variant="error" message="Failed to save changes" onClose={() => {}} />
    </div>
  );
}

Custom Duration

Control how long toasts remain visible. The default is 5000ms. Set duration: 0 to disable auto-dismiss entirely:

import { useToast } from '@xsolla/xui-toast';

export default function CustomDuration() {
  const toast = useToast();

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
      <button onClick={() => toast.toast({ message: 'Stays for 10 seconds', duration: 10000 })}>
        Long Duration (10s)
      </button>
      <button onClick={() => toast.toast({ message: 'Stays for 2 seconds', duration: 2000 })}>
        Short Duration (2s)
      </button>
      <button onClick={() => toast.toast({ message: 'Dismiss me manually', duration: 0 })}>
        No Auto-Dismiss
      </button>
    </div>
  );
}

You can also set a global default duration on the provider:

<ToastProvider defaultDuration={3000}>
  <App />
</ToastProvider>

Custom Icons

Override the default variant icon by passing a ReactNode via the icon option:

import { useToast } from '@xsolla/xui-toast';
import { Star } from '@xsolla/xui-icons';

function CustomIconExample() {
  const toast = useToast();

  return (
    <button
      onClick={() =>
        toast.toast({
          message: 'You earned a gold star!',
          variant: 'success',
          icon: <Star />,
        })
      }
    >
      Show Custom Icon Toast
    </button>
  );
}

Dismissing Toasts Programmatically

Every toast.*() call returns a unique ID. Use it to dismiss a specific toast:

import * as React from 'react';
import { useToast } from '@xsolla/xui-toast';

export default function DismissExample() {
  const toast = useToast();
  const [lastToastId, setLastToastId] = React.useState<string | null>(null);

  const showToast = () => {
    const id = toast.info('New notification');
    setLastToastId(id);
  };

  return (
    <div style={{ display: 'flex', gap: 8 }}>
      <button onClick={showToast}>Show Toast</button>
      <button onClick={() => lastToastId && toast.dismiss(lastToastId)}>
        Dismiss Last
      </button>
      <button onClick={() => toast.dismissAll()}>Dismiss All</button>
    </div>
  );
}

Position Configuration

Toasts can be anchored to the top or bottom of the viewport:

import { ToastProvider, useToast } from '@xsolla/xui-toast';

function ToastTrigger() {
  const toast = useToast();
  return <button onClick={() => toast.info('Toast at the bottom!')}>Show Toast</button>;
}

export default function BottomPosition() {
  return (
    <ToastProvider position="bottom">
      <ToastTrigger />
    </ToastProvider>
  );
}

Multiple Toasts

Multiple toasts stack vertically in the order they are created:

import { useToast } from '@xsolla/xui-toast';

function MultipleToastsExample() {
  const toast = useToast();

  const showMultiple = () => {
    toast.success('First toast - Success');
    setTimeout(() => toast.info('Second toast - Info'), 200);
    setTimeout(() => toast.warning('Third toast - Warning'), 400);
  };

  return <button onClick={showMultiple}>Show Multiple Toasts</button>;
}

API Reference

ToastProvider

The root provider component that manages toast state and renders the toast container.

| Prop | Type | Default | Description | | :--- | :--- | :------ | :---------- | | children | ReactNode | — | Application content. | | position | "top" \| "bottom" | "top" | Position of the toast container on screen. | | defaultDuration | number | 5000 | Default auto-dismiss duration in milliseconds. Set to 0 to disable auto-dismiss globally. | | maxWidth | number | 100% | Maximum width of the toast container in pixels. If not set, toasts stretch to full viewport width. |

useToast

A hook that returns methods to show and dismiss toasts. Must be called within a ToastProvider — throws an error otherwise.

Return type: UseToastReturn

| Method | Signature | Description | | :----- | :-------- | :---------- | | toast | (options: ToastOptions) => string | Show a toast with full control over options. Returns the toast ID. | | success | (message: string, options?) => string | Show a success toast with a check icon. | | info | (message: string, options?) => string | Show an info toast with an info icon. | | warning | (message: string, options?) => string | Show a warning toast with an alert icon. | | error | (message: string, options?) => string | Show an error toast with an alert icon. | | dismiss | (id: string) => void | Dismiss a specific toast by its ID. | | dismissAll | () => void | Dismiss all visible toasts at once. |

Toast

The individual toast notification component. Used internally by ToastGroup, but can be rendered standalone for static display.

| Prop | Type | Default | Description | | :--- | :--- | :------ | :---------- | | id | string | — | Unique identifier for the toast (required). | | message | string | — | Toast message text (required). | | variant | "success" \| "info" \| "warning" \| "error" | "info" | Visual variant that determines the icon color. | | icon | ReactNode | — | Custom icon element. When omitted, a default icon for the variant is used. | | onClose | () => void | — | Callback fired when the close button is clicked. If omitted, the close button is hidden. |

ToastOptions

Options object passed to the toast() method or as the second argument to shorthand methods.

| Property | Type | Default | Description | | :------- | :--- | :------ | :---------- | | message | string | — | Toast message text (required). | | variant | "success" \| "info" \| "warning" \| "error" | "info" | Toast variant. | | icon | ReactNode | — | Custom icon element. | | duration | number | Provider's defaultDuration | Auto-dismiss duration in ms. Use 0 to keep the toast until manually dismissed. |

ToastData

Internal data structure for a toast instance (available via ToastContext).

| Property | Type | Description | | :------- | :--- | :---------- | | id | string | Unique identifier generated by the provider. | | variant | ToastVariant | The toast variant. | | message | string | Toast message text. | | icon | ReactNode \| undefined | Custom icon, if provided. | | duration | number \| undefined | Auto-dismiss duration. |

ToastContext

The React context object. Typically consumed via useToast, but available for advanced use cases:

import { useContext } from 'react';
import { ToastContext } from '@xsolla/xui-toast';

function CustomToastConsumer() {
  const ctx = useContext(ToastContext);
  if (!ctx) throw new Error('Must be within ToastProvider');

  return <span>Active toasts: {ctx.toasts.length}</span>;
}

Variant Reference

| Variant | Use Case | Default Icon | Icon Color Theme Path | | :------ | :------- | :----------- | :-------------------- | | success | Positive outcomes, confirmations | <Check /> | theme.colors.content.success.primary | | info | General information, neutral messages | <AlertCircle /> | theme.colors.content.inverse | | warning | Caution, requires user attention | <AlertCircle /> | theme.colors.content.warning.primary | | error | Errors, failures, critical issues | <AlertCircle /> | theme.colors.content.alert.primary |

Theming

Toast uses the inverse color scheme (dark background with light text) to stand out from the application content:

Colors

theme.colors.background.inverse     // Toast background
theme.colors.content.inverse        // Toast text and info icon color

theme.colors.content.success.primary // Success icon color
theme.colors.content.warning.primary // Warning icon color
theme.colors.content.alert.primary   // Error icon color

Sizing

Toast dimensions come from theme.sizing.toast():

| Token | Value | Description | | :---- | :---- | :---------- | | minHeight | 64 | Minimum toast height | | paddingHorizontal | 12 | Left/right padding | | paddingVertical | 8 | Top/bottom padding | | borderRadius | 4 | Corner radius | | gap | 12 | Space between icon, text, and close button | | iconSize | 24 | Icon dimensions | | closeButtonSize | 24 | Close button tap target | | closeIconSize | 20 | Close icon dimensions | | fontSize | 16 | Message text size | | lineHeight | 20 | Message line height | | maxWidth | 400 | Maximum toast width (theme default; overridden by ToastProvider maxWidth prop) | | containerPadding | 12 | Padding between toast container and screen edges | | groupGap | 4 | Vertical gap between stacked toasts |

Platform Support

This package supports both React (web) and React Native with an identical API.

React (Web)

  • Uses ReactDOM.createPortal to render toasts at the document body level
  • Toasts appear above all other content regardless of z-index stacking contexts
  • Works with any React web framework (Next.js, Vite, Create React App, Remix, etc.)

React Native

  • Uses absolute positioning within the app container
  • Toasts render within the component tree (no portal equivalent in RN)
  • Works with React Navigation, Expo, and bare React Native projects

Cross-Platform Comparison

| Feature | Web | React Native | | :------ | :-- | :----------- | | Provider setup | ToastProvider | XUIProvider + ToastProvider | | Hook API | useToast() | useToast() (identical) | | Event handlers | onClick | onPress | | Root container | Any element | Must have flex: 1 | | Position: top | Fixed to viewport top | Absolute to container top | | Position: bottom | Fixed to viewport bottom | Absolute to container bottom | | Rendering | ReactDOM.createPortal into document.body | Absolute-positioned Box in tree |

React Native Example with Navigation

import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { XUIProvider } from '@xsolla/xui-core';
import { ToastProvider } from '@xsolla/xui-toast';
import { RootNavigator } from './navigation';

export default function App() {
  return (
    <SafeAreaProvider>
      <XUIProvider mode="dark">
        <ToastProvider position="top">
          <NavigationContainer>
            <RootNavigator />
          </NavigationContainer>
        </ToastProvider>
      </XUIProvider>
    </SafeAreaProvider>
  );
}

Accessibility

  • Each toast renders with role="alert" and aria-live="polite" for screen reader announcements
  • The close button includes aria-label="Dismiss toast" for assistive technology
  • Icons are decorative and do not interfere with accessibility
  • Keyboard users can Tab to the close button and press Enter to dismiss
  • Toast messages are limited to 2 lines (numberOfLines={2}) for readability

Troubleshooting

"useToast must be used within a ToastProvider"

The useToast hook was called in a component that is not a descendant of ToastProvider. Ensure your component tree has a ToastProvider ancestor:

// Correct — hook is inside the provider tree
<ToastProvider>
  <ComponentThatCallsUseToast />
</ToastProvider>

// Wrong — hook is outside the provider
<ComponentThatCallsUseToast />
<ToastProvider>
  <OtherContent />
</ToastProvider>

Toasts not visible on React Native

Make sure the container inside ToastProvider has flex: 1. Without this, the absolute-positioned toast group has no reference height:

<ToastProvider>
  <View style={{ flex: 1 }}> {/* Required */}
    <App />
  </View>
</ToastProvider>

Toasts appear behind a modal or overlay

On web, ToastGroup uses z-index: 9999. If your modal or overlay uses a higher z-index, the toasts may be hidden. Consider placing the ToastProvider above your modal provider in the tree, or adjusting z-index values.

Auto-dismiss not working

Ensure duration is not set to 0. A duration of 0 disables auto-dismiss. Check both the per-toast duration option and the provider's defaultDuration prop.