Components
- Accordion
- Alert
- Alert Dialog
- Autocomplete
- Avatar
- Badge
- Breadcrumb
- Button
- Card
- Checkbox
- Checkbox Group
- Collapsible
- Combobox
- Code Block
- Dialog
- Empty
- Field
- Fieldset
- Form
- Frame
- Group
- Input
- Label
- Menu
- Meter
- Number Field
- Pagination
- Popover
- Preview Card
- Progress
- Radio Group
- Scroll Area
- Select
- Separator
- Sheet
- Skeleton
- Slider
- Switch
- Table
- Tabs
- Textarea
- Toast
- Gooey Toast
- Toggle
- Toggle Group
- Toolbar
- Tooltip
Gooey Toast
A morphing toast notification with smooth, gooey animations and autopilot expansion.
top-right
"use client"
import { useState } from "react"
import { gooey, type GooeyPosition } from "@loveui/gooey-toast"
import { Button } from "@/components/ui/button"
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
export default function GooeyToastDemo() {
const [position, setPosition] = useState<GooeyPosition>("top-right")
const positions: GooeyPosition[] = [
"top-left",
"top-center",
"top-right",
"bottom-left",
"bottom-center",
"bottom-right",
]
const showToast = (
type: "default" | "success" | "error" | "warning" | "info"
) => {
const toasts = {
default: {
title: "Event has been created",
description: "Monday, January 3rd at 6:00pm",
},
success: {
title: "Success!",
description: "Your changes have been saved successfully.",
},
error: {
title: "Error occurred",
description: "Failed to save your changes. Please try again.",
},
warning: {
title: "Warning",
description: "Your session will expire in 5 minutes.",
},
info: {
title: "New feature available",
description: "Check out the new gooey toast component!",
},
}
const config = toasts[type]
if (type === "default") {
gooey.show({ ...config, position })
} else {
gooey[type]({ ...config, position })
}
}
return (
<div className="flex flex-col gap-4">
<div className="flex items-center gap-2">
<label htmlFor="position" className="text-sm font-medium">
Position:
</label>
<Select
value={position}
onValueChange={(v) => setPosition(v as GooeyPosition)}
>
<SelectTrigger id="position" className="w-[180px]">
<SelectValue />
</SelectTrigger>
<SelectContent>
{positions.map((pos) => (
<SelectItem key={pos} value={pos}>
{pos}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className="flex flex-wrap gap-2">
<Button variant="outline" onClick={() => showToast("default")}>
Default
</Button>
<Button variant="outline" onClick={() => showToast("success")}>
Success
</Button>
<Button variant="outline" onClick={() => showToast("error")}>
Error
</Button>
<Button variant="outline" onClick={() => showToast("warning")}>
Warning
</Button>
<Button variant="outline" onClick={() => showToast("info")}>
Info
</Button>
</div>
</div>
)
}
Installation
npx love-ui@latest add gooey-toastAdd the Toaster component to your app.
import { Toaster } from "@loveui/gooey-toast"
export default function RootLayout({ children }) {
return (
<html lang="en">
<head />
<body>
<main>{children}</main>
<Toaster />
</body>
</html>
)
}Usage
import { gooey } from "@loveui/gooey-toast"gooey.show({
title: "Event has been created",
description: "Monday, January 3rd at 6:00pm",
})By default, toasts appear in the top-right corner with automatic gooey morphing animations. You can change the position by setting the position prop on individual toasts or globally on the Toaster component.
Allowed values: top-left, top-center, top-right, bottom-left, bottom-center, bottom-right.
<Toaster position="bottom-center" />Examples
States
Gooey Toast supports different states with contextual colors and icons.
"use client"
import { gooey } from "@loveui/gooey-toast"
import { Button } from "@/components/ui/button"
export default function GooeyToastStates() {
return (
<div className="flex flex-wrap gap-2">
<Button
variant="outline"
onClick={() => {
gooey.success({
title: "Success!",
description: "Your changes have been saved.",
})
}}
>
Success
</Button>
<Button
variant="outline"
onClick={() => {
gooey.error({
title: "Error",
description: "Something went wrong. Please try again.",
})
}}
>
Error
</Button>
<Button
variant="outline"
onClick={() => {
gooey.warning({
title: "Warning",
description: "This action cannot be undone.",
})
}}
>
Warning
</Button>
<Button
variant="outline"
onClick={() => {
gooey.info({
title: "Did you know?",
description: "You can customize toast animations.",
})
}}
>
Info
</Button>
<Button
variant="outline"
onClick={() => {
gooey.action({
title: "Action Required",
description: "Please review your settings.",
})
}}
>
Action
</Button>
</div>
)
}
Promise
Drive toast states from promises for async operations.
"use client"
import { gooey } from "@loveui/gooey-toast"
import { Button } from "@/components/ui/button"
export default function GooeyToastPromise() {
const handlePromise = () => {
const promise = new Promise<{ name: string }>((resolve) => {
setTimeout(() => resolve({ name: "User" }), 2000)
})
gooey.promise(promise, {
loading: { title: "Loading..." },
success: (data) => ({
title: "Success!",
description: `Welcome back, ${data.name}!`,
}),
error: {
title: "Error",
description: "Failed to load data.",
},
})
}
return (
<Button variant="outline" onClick={handlePromise}>
Load Data
</Button>
)
}
With Action Button
Add interactive buttons to your toasts.
"use client"
import { gooey } from "@loveui/gooey-toast"
import { Button } from "@/components/ui/button"
export default function GooeyToastWithButton() {
return (
<Button
variant="outline"
onClick={() => {
const id = gooey.action({
title: "File deleted",
description: "Your file has been moved to trash.",
button: {
title: "Undo",
onClick: () => {
gooey.dismiss(id)
gooey.success({
title: "Restored",
description: "Your file has been restored.",
})
},
},
})
}}
>
Delete File
</Button>
)
}
Position
Control where toasts appear on the screen.
"use client"
import { gooey, type GooeyPosition } from "@loveui/gooey-toast"
import { Button } from "@/components/ui/button"
export default function GooeyToastPosition() {
const positions: GooeyPosition[] = [
"top-left",
"top-center",
"top-right",
"bottom-left",
"bottom-center",
"bottom-right",
]
return (
<div className="flex flex-wrap gap-2">
{positions.map((position) => (
<Button
key={position}
variant="outline"
onClick={() => {
gooey.show({
title: position,
description: `Toast shown at ${position}`,
position,
})
}}
>
{position}
</Button>
))}
</div>
)
}
API Reference
gooey
The main API for showing toasts.
Methods
gooey.show(options)- Show a basic toastgooey.success(options)- Show a success toastgooey.error(options)- Show an error toastgooey.warning(options)- Show a warning toastgooey.info(options)- Show an info toastgooey.action(options)- Show an action toastgooey.promise(promise, options)- Drive toast from promise statesgooey.dismiss(id)- Dismiss a specific toastgooey.clear(position?)- Clear all toasts or toasts at a specific position
Options
interface GooeyOptions {
title?: string
description?: ReactNode | string
position?: GooeyPosition
duration?: number | null // null for persistent
icon?: ReactNode | null
styles?: GooeyStyles
fill?: string // Background color
roundness?: number // Border radius
autopilot?: boolean | { expand?: number; collapse?: number }
button?: {
title: string
onClick: () => void
}
}Toaster Props
interface GooeyToasterProps {
position?: GooeyPosition // Default position for all toasts
offset?: number | string | {
top?: number | string
right?: number | string
bottom?: number | string
left?: number | string
}
options?: Partial<GooeyOptions> // Default options for all toasts
}Features
- Gooey Morphing: Smooth, organic shape transitions between states
- Autopilot Mode: Automatic expansion/collapse for better readability
- Promise-driven: Seamlessly handle async operations
- Customizable: Control colors, roundness, duration, and positioning
- Action Buttons: Add interactive elements to toasts
- Multiple Positions: Support for 6 different screen positions
- Spring Animations: Natural, physics-based motion