Toast

Exports

Import these components from @mbsw/ui.

dismissToast
showToast
Toast
ToastProvider

Props

The tables list common props for each component. See the full types for supported prop combinations and inherited HTML and Radix props.

Toast

Toast props
PropTypeRequirement
actionsToastAction | ToastAction[]Optional
closeLabelstringOptional
contentReactNodeOptional
descriptionNonEmptyToastContentOptional
hasActionsbooleanOptional
hasContentbooleanOptional
leadingIconReactNodeOptional
onClose(() => void)Optional
titleNonEmptyToastContentRequired

ToastProvider

ToastProvider props
PropTypeRequirement
containerLabelstringOptional

Type reference

Show full types

Full TypeScript definitions, including prop combinations and inherited props.

import { type HTMLAttributes, type ReactElement, type ReactNode, type ButtonHTMLAttributes, type ElementType, type RefAttributes, type SVGProps } from 'react';

import { type ToasterProps as SonnerToasterProps } from 'sonner';

export type ButtonVariant = 'solid' | 'outline' | 'ghost';

export type ButtonTone = 'primary' | 'secondary' | 'destructive' | 'highlight';

export type ButtonSize = 'lg' | 'md' | 'sm';

export type IconOnlyButtonSize = ButtonSize | 'xs';

type IconComponent = ElementType<SVGProps<SVGSVGElement>>;

type DataAttributes = {
    [key: `data-${string}`]: boolean | number | string | undefined;
};

type ButtonBaseProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children' | 'size'> & DataAttributes & {
    /** Highlight-only visual state. Callers retain aria-busy, disabled and event policy. */
    generating?: boolean;
    tone?: ButtonTone;
    variant?: ButtonVariant;
};

type NonEmptyButtonChild = Exclude<ReactNode, boolean | null | undefined>;

type NativeTextButtonProps = ButtonBaseProps & {
    asChild?: false;
    children: NonEmptyButtonChild;
    icon?: never;
    iconForeground?: never;
    iconOnly?: false;
    leadingIcon?: IconComponent;
    size?: ButtonSize;
    trailingIcon?: IconComponent;
};

type SlottedTextButtonProps = Omit<ButtonBaseProps, 'disabled'> & {
    asChild: true;
    children: ReactElement;
    disabled?: never;
    icon?: never;
    iconForeground?: never;
    iconOnly?: false;
    leadingIcon?: never;
    size?: ButtonSize;
    trailingIcon?: never;
};

type IconOnlyButtonContent = {
    children?: never;
    icon: IconComponent;
    /** Secondary direct icon slot only; children styling stays caller-owned. */
    iconForeground?: 'primary' | 'secondary';
} | {
    children: NonEmptyButtonChild;
    icon?: never;
    iconForeground?: never;
};

type IconOnlyButtonProps = ButtonBaseProps & IconOnlyButtonContent & {
    'aria-label': string;
    asChild?: false;
    iconOnly: true;
    leadingIcon?: never;
    size?: IconOnlyButtonSize;
    trailingIcon?: never;
};

export type ButtonProps = (NativeTextButtonProps & RefAttributes<HTMLButtonElement>) | (SlottedTextButtonProps & RefAttributes<HTMLElement>) | (IconOnlyButtonProps & RefAttributes<HTMLButtonElement>);

type ButtonComponent = {
    (props: ButtonProps): ReactElement | null;
    displayName?: string;
};

export declare const Button: ButtonComponent;

type NonEmptyToastContent = Exclude<ReactNode, boolean | null | undefined>;

export type ToastAction = ReactElement<ButtonProps, typeof Button>;

export type ToastProps = Omit<HTMLAttributes<HTMLDivElement>, 'aria-atomic' | 'aria-live' | 'aria-relevant' | 'children' | 'content' | 'role' | 'title'> & DataAttributes & {
    actions?: ToastAction | ToastAction[];
    closeLabel?: string;
    content?: ReactNode;
    description?: NonEmptyToastContent;
    hasActions?: boolean;
    hasContent?: boolean;
    leadingIcon?: ReactNode;
    onClose?: () => void;
    title: NonEmptyToastContent;
};

export type ToastProviderProps = Pick<SonnerToasterProps, 'className' | 'dir' | 'duration' | 'hotkey' | 'id' | 'style' | 'visibleToasts'> & {
    containerLabel?: string;
};

export type ShowToastOptions = Pick<ToastProps, 'actions' | 'className' | 'closeLabel' | 'content' | 'description' | 'leadingIcon' | 'hasActions' | 'hasContent' | 'title'> & {
    dismissible?: boolean;
    duration?: number;
    id?: number | string;
};

export declare const Toast: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "role" | "title" | "content" | "aria-atomic" | "aria-live" | "aria-relevant" | "children"> & DataAttributes & {
    actions?: ToastAction | ToastAction[];
    closeLabel?: string;
    content?: ReactNode;
    description?: NonEmptyToastContent;
    hasActions?: boolean;
    hasContent?: boolean;
    leadingIcon?: ReactNode;
    onClose?: () => void;
    title: NonEmptyToastContent;
} & import("react").RefAttributes<HTMLDivElement>>;

export declare function ToastProvider({ className, containerLabel, duration, style, visibleToasts, ...providerProps }: ToastProviderProps): import("react").JSX.Element;

export declare function showToast({ dismissible, duration, id, ...toastProps }: ShowToastOptions): number | string;

export declare function dismissToast(id?: number | string): number | string;