Docs
   Toast 
 Toast
A succinct message that is displayed temporarily.
import { toaster } from "@kobalte/core";
import { Button } from "@repo/tailwindcss/ui/button";
import {
	Toast,
	ToastContent,
	ToastDescription,
	ToastProgress,
	ToastTitle,
} from "@repo/tailwindcss/ui/toast";
 
const ToastDemo = () => {
	const showToast = () => {
		toaster.show((props) => (
			<Toast toastId={props.toastId}>
				<ToastContent>
					<ToastTitle>Scheduled: Catch up</ToastTitle>
					<ToastDescription>
						Friday, February 10, 2023 at 5:57 PM
					</ToastDescription>
				</ToastContent>
				<ToastProgress />
			</Toast>
		));
	};
 
	return (
		<Button variant="outline" onClick={showToast}>
			Add to calendar
		</Button>
	);
};
 
export default ToastDemo;Installation
npx shadcn-solid@latest add toastInstall the following dependencies:
npm install @kobalte/coreCopy and paste the following code into your project:
import { cn } from "@/libs/cn";
import type { PolymorphicProps } from "@kobalte/core/polymorphic";
import type {
	ToastDescriptionProps,
	ToastListProps,
	ToastRegionProps,
	ToastRootProps,
	ToastTitleProps,
} from "@kobalte/core/toast";
import { Toast as ToastPrimitive } from "@kobalte/core/toast";
import type { VariantProps } from "class-variance-authority";
import { cva } from "class-variance-authority";
import type {
	ComponentProps,
	ValidComponent,
	VoidComponent,
	VoidProps,
} from "solid-js";
import { mergeProps, splitProps } from "solid-js";
import { Portal } from "solid-js/web";
 
export const toastVariants = cva(
	"group pointer-events-auto relative flex flex-col gap-3 w-full items-center justify-between overflow-hidden rounded-md border p-4 pr-6 shadow-lg transition-all data-[swipe=cancel]:translate-y-0 data-[swipe=end]:translate-y-[var(--kb-toast-swipe-end-y)] data-[swipe=move]:translate-y-[--kb-toast-swipe-move-y] data-[swipe=move]:transition-none data-[opened]:animate-in data-[closed]:animate-out data-[swipe=end]:animate-out data-[closed]:fade-out-80 data-[closed]:slide-out-to-top-full data-[closed]:sm:slide-out-to-bottom-full data-[opened]:slide-in-from-top-full data-[opened]:sm:slide-in-from-bottom-full",
	{
		variants: {
			variant: {
				default: "border bg-background",
				destructive:
					"destructive group border-destructive bg-destructive text-destructive-foreground",
			},
		},
		defaultVariants: {
			variant: "default",
		},
	},
);
 
type toastProps<T extends ValidComponent = "li"> = ToastRootProps<T> &
	VariantProps<typeof toastVariants> & {
		class?: string;
	};
 
export const Toast = <T extends ValidComponent = "li">(
	props: PolymorphicProps<T, toastProps<T>>,
) => {
	const [local, rest] = splitProps(props as toastProps, ["class", "variant"]);
 
	return (
		<ToastPrimitive
			class={cn(toastVariants({ variant: local.variant }), local.class)}
			{...rest}
		/>
	);
};
 
type toastTitleProps<T extends ValidComponent = "div"> = ToastTitleProps<T> & {
	class?: string;
};
 
export const ToastTitle = <T extends ValidComponent = "div">(
	props: PolymorphicProps<T, toastTitleProps<T>>,
) => {
	const [local, rest] = splitProps(props as toastTitleProps, ["class"]);
 
	return (
		<ToastPrimitive.Title
			class={cn("text-sm font-semibold [&+div]:text-xs", local.class)}
			{...rest}
		/>
	);
};
 
type toastDescriptionProps<T extends ValidComponent = "div"> =
	ToastDescriptionProps<T> & {
		class?: string;
	};
 
export const ToastDescription = <T extends ValidComponent = "div">(
	props: PolymorphicProps<T, toastDescriptionProps<T>>,
) => {
	const [local, rest] = splitProps(props as toastDescriptionProps, ["class"]);
 
	return (
		<ToastPrimitive.Description
			class={cn("text-sm opacity-90", local.class)}
			{...rest}
		/>
	);
};
 
type toastRegionProps<T extends ValidComponent = "div"> =
	ToastRegionProps<T> & {
		class?: string;
	};
 
export const ToastRegion = <T extends ValidComponent = "div">(
	props: PolymorphicProps<T, toastRegionProps<T>>,
) => {
	const merge = mergeProps<toastRegionProps[]>(
		{
			swipeDirection: "down",
		},
		props,
	);
 
	return (
		<Portal>
			<ToastPrimitive.Region {...merge} />
		</Portal>
	);
};
 
type toastListProps<T extends ValidComponent = "ol"> = VoidProps<
	ToastListProps<T> & {
		class?: string;
	}
>;
 
export const ToastList = <T extends ValidComponent = "ol">(
	props: PolymorphicProps<T, toastListProps<T>>,
) => {
	const [local, rest] = splitProps(props as toastListProps, ["class"]);
 
	return (
		<ToastPrimitive.List
			class={cn(
				"fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse gap-2 p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]",
				local.class,
			)}
			{...rest}
		/>
	);
};
 
export const ToastContent = (props: ComponentProps<"div">) => {
	const [local, rest] = splitProps(props, ["class", "children"]);
 
	return (
		<div class={cn("flex w-full flex-col", local.class)} {...rest}>
			<div>{local.children}</div>
			<ToastPrimitive.CloseButton class="absolute right-1 top-1 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none group-hover:opacity-100 group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50">
				<svg
					xmlns="http://www.w3.org/2000/svg"
					class="h-4 w-4"
					viewBox="0 0 24 24"
				>
					<path
						fill="none"
						stroke="currentColor"
						stroke-linecap="round"
						stroke-linejoin="round"
						stroke-width="2"
						d="M18 6L6 18M6 6l12 12"
					/>
					<title>Close</title>
				</svg>
			</ToastPrimitive.CloseButton>
		</div>
	);
};
 
export const ToastProgress: VoidComponent = () => {
	return (
		<ToastPrimitive.ProgressTrack class="h-1 w-full overflow-hidden rounded-xl bg-primary/20 group-[.destructive]:bg-background/20">
			<ToastPrimitive.ProgressFill class="h-full w-[--kb-toast-progress-fill-width] bg-primary transition-all duration-150 ease-linear group-[.destructive]:bg-destructive-foreground" />
		</ToastPrimitive.ProgressTrack>
	);
};Install the following dependencies:
npm install @kobalte/coreCopy and paste the following code into your project:
import { cn } from "@/libs/cn";
import type { PolymorphicProps } from "@kobalte/core/polymorphic";
import type {
	ToastDescriptionProps,
	ToastListProps,
	ToastRegionProps,
	ToastRootProps,
	ToastTitleProps,
} from "@kobalte/core/toast";
import { Toast as ToastPrimitive } from "@kobalte/core/toast";
import type { VariantProps } from "class-variance-authority";
import { cva } from "class-variance-authority";
import type {
	ComponentProps,
	ValidComponent,
	VoidComponent,
	VoidProps,
} from "solid-js";
import { mergeProps, splitProps } from "solid-js";
import { Portal } from "solid-js/web";
 
export const toastVariants = cva(
	"group pointer-events-auto relative flex flex-col gap-3 w-full items-center justify-between overflow-hidden rounded-md border p-4 pr-6 shadow-lg data-[swipe=cancel]:translate-y-0 data-[swipe=end]:(translate-y-[var(--kb-toast-swipe-end-y)] animate-out) data-[swipe=move]:(translate-y-[--kb-toast-swipe-move-y] transition-none) data-[opened]:(animate-in slide-in-from-top-full sm:slide-in-from-bottom-full) data-[closed]:(animate-out fade-out-80 slide-out-to-top-full sm:slide-out-to-bottom-full)",
	{
		variants: {
			variant: {
				default: "border bg-background",
				destructive:
					"destructive group border-destructive bg-destructive text-destructive-foreground",
			},
		},
		defaultVariants: {
			variant: "default",
		},
	},
);
 
type toastProps<T extends ValidComponent = "li"> = ToastRootProps<T> &
	VariantProps<typeof toastVariants> & {
		class?: string;
	};
 
export const Toast = <T extends ValidComponent = "li">(
	props: PolymorphicProps<T, toastProps<T>>,
) => {
	const [local, rest] = splitProps(props as toastProps, ["class", "variant"]);
 
	return (
		<ToastPrimitive
			class={cn(toastVariants({ variant: local.variant }), local.class)}
			{...rest}
		/>
	);
};
 
type toastTitleProps<T extends ValidComponent = "div"> = ToastTitleProps<T> & {
	class?: string;
};
 
export const ToastTitle = <T extends ValidComponent = "div">(
	props: PolymorphicProps<T, toastTitleProps<T>>,
) => {
	const [local, rest] = splitProps(props as toastTitleProps, ["class"]);
 
	return (
		<ToastPrimitive.Title
			class={cn("text-sm font-semibold [&+div]:text-xs", local.class)}
			{...rest}
		/>
	);
};
 
type toastDescriptionProps<T extends ValidComponent = "div"> =
	ToastDescriptionProps<T> & {
		class?: string;
	};
 
export const ToastDescription = <T extends ValidComponent = "div">(
	props: PolymorphicProps<T, toastDescriptionProps<T>>,
) => {
	const [local, rest] = splitProps(props as toastDescriptionProps, ["class"]);
 
	return (
		<ToastPrimitive.Description
			class={cn("text-sm opacity-90", local.class)}
			{...rest}
		/>
	);
};
 
type toastRegionProps<T extends ValidComponent = "div"> =
	ToastRegionProps<T> & {
		class?: string;
	};
 
export const ToastRegion = <T extends ValidComponent = "div">(
	props: PolymorphicProps<T, toastRegionProps<T>>,
) => {
	const merge = mergeProps<toastRegionProps[]>(
		{
			swipeDirection: "down",
		},
		props,
	);
 
	return (
		<Portal>
			<ToastPrimitive.Region {...merge} />
		</Portal>
	);
};
 
type toastListProps<T extends ValidComponent = "ol"> = VoidProps<
	ToastListProps<T> & {
		class?: string;
	}
>;
 
export const ToastList = <T extends ValidComponent = "ol">(
	props: PolymorphicProps<T, toastListProps<T>>,
) => {
	const [local, rest] = splitProps(props as toastListProps, ["class"]);
 
	return (
		<ToastPrimitive.List
			class={cn(
				"fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse gap-2 p-4 sm:(bottom-0 right-0 top-auto flex-col) md:max-w-[420px]",
				local.class,
			)}
			{...rest}
		/>
	);
};
 
export const ToastContent = (props: ComponentProps<"div">) => {
	const [local, rest] = splitProps(props, ["class", "children"]);
 
	return (
		<div class={cn("flex w-full flex-col", local.class)} {...rest}>
			<div>{local.children}</div>
			<ToastPrimitive.CloseButton class="absolute right-1 top-1 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:(opacity-100 outline-none) group-hover:opacity-100 group-[.destructive]:(text-red-300 hover:text-red-50) bg-inherit">
				<svg
					xmlns="http://www.w3.org/2000/svg"
					class="h-4 w-4"
					viewBox="0 0 24 24"
				>
					<path
						fill="none"
						stroke="currentColor"
						stroke-linecap="round"
						stroke-linejoin="round"
						stroke-width="2"
						d="M18 6L6 18M6 6l12 12"
					/>
					<title>Close</title>
				</svg>
			</ToastPrimitive.CloseButton>
		</div>
	);
};
 
export const ToastProgress: VoidComponent = () => {
	return (
		<ToastPrimitive.ProgressTrack class="h-1 w-full overflow-hidden rounded-xl bg-primary/20 group-[.destructive]:bg-background/20">
			<ToastPrimitive.ProgressFill class="h-full w-[--kb-toast-progress-fill-width] bg-primary transition-all duration-150 ease-linear group-[.destructive]:bg-destructive-foreground" />
		</ToastPrimitive.ProgressTrack>
	);
};Usage
import { toaster } from "@kobalte/core";
import {
  Toast,
  ToastContent,
  ToastProgress,
  ToastTitle
} from "@/components/ui/toast";toaster.show(props => (
  <Toast toastId={props.toastId}>
    <ToastContent>
      <ToastTitle>Toast</ToastTitle>
    </ToastContent>
    <ToastProgress />
  </Toast>
))import { ToastRegion, ToastList } from "@/components/ui/toast"
 
const App = () => {
  return (
    <Router
      root={props => (
          <Suspense>
            <ColorModeScript />
            <ColorModeProvider>
              {props.children}
              <ToastRegion>
                <ToastList />
              </ToastRegion>
            </ColorModeProvider>
          </Suspense>
      )}
    >
      <FileRoutes />
    </Router>
  );
};
 
export default App;Examples
Destructive
import { toaster } from "@kobalte/core";
import { Button } from "@repo/tailwindcss/ui/button";
import {
	Toast,
	ToastContent,
	ToastDescription,
	ToastProgress,
	ToastTitle,
} from "@repo/tailwindcss/ui/toast";
 
const ToastDestructive = () => {
	const showToast = () =>
		toaster.show((props) => (
			<Toast toastId={props.toastId} variant="destructive">
				<ToastContent>
					<ToastTitle>Uh oh! Something went wrong.</ToastTitle>
					<ToastDescription>
						There was a problem with your request.
					</ToastDescription>
				</ToastContent>
				<ToastProgress />
			</Toast>
		));
 
	return (
		<Button variant="outline" onClick={showToast}>
			Add to calendar
		</Button>
	);
};
 
export default ToastDestructive;