Toast
A succinct message that is displayed temporarily.
Hello
Your toast is ready.
<ToastTrigger variant="outline" toast_target="toast-default">Show default Toast</ToastTrigger>
<Toast id="toast-default" duration="4000">
<ToastContent
type="default"
title="Hello"
description="Your toast is ready."
/>
</Toast>
Installation
uvx --from basic-components components add toast
pipx run --spec basic-components components add toast
pip install basic-components && components add toast
- Copy Toast components below to your local environment
- Place them in the components/ui/toast directory in your project
- Configure your jinja environment for JinjaX
- Add the cn() helper function to your global jinja environment
Usage
<ToastTrigger variant="outline" toast_target="toast-default">Show default Toast</ToastTrigger>
<Toast id="toast-default" duration="4000">
<ToastContent
type="default"
title="Hello"
description="Your toast is ready."
/>
</Toast>
Attributes
Component | Prop | Type | Default | Description |
---|---|---|---|---|
Toast | id |
String | The css id for the Toast. | |
Toast | duration |
Number | 30000 |
Duration in milliseconds before toast auto-dismisses. |
ToastContent | type |
String | "default" |
Style variant of the toast. Options: "default" , "success" , "error" , "warning" , "destructive" . |
ToastContent | title |
String | "" |
The title text displayed in the toast. |
ToastContent | description |
String | "" |
The description text displayed below the title. |
ToastTrigger | variant |
String | "default" |
The Button component variant to use. |
ToastTrigger | toast_target |
String | The target toast identifier to trigger. |
Toast components require an id
so that the dispatch event can call the component to display it.
Code
{# def
id: str,
className: str = "",
duration: int = 30000, # duration in milliseconds
#}
<div id="toast"
x-data="{
show: false,
timeoutId: null,
resetTimeout() {
clearTimeout(this.timeoutId);
this.timeoutId = setTimeout(() => { this.show = false }, {{ duration }});
},
handleShow() {
console.log('this is handleShow');
// If already showing, briefly hide and show again to restart animation
if (this.show) {
this.show = false;
setTimeout(() => {
this.show = true;
this.resetTimeout();
}, 100);
} else {
this.show = true;
//this.resetTimeout();
}
}
}"
@show-toast.window="console.log('TOAST'); console.log($event.detail); console.log('{{ id }}'); if($event.detail === '{{ id }}' || $event.detail.value === '{{ id }}') { handleShow(); } else { console.error('failed to show'); }"
x-show="show"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform translate-y-full"
x-transition:enter-end="opacity-100 transform translate-y-0"
x-transition:leave="transition ease-in duration-200"
x-transition:leave-start="opacity-100 transform translate-x-0"
x-transition:leave-end="opacity-0 transform translate-x-full"
class="{{ className }} fixed bottom-5 right-5"
role="alert"
>
{{ content }}
</div>
{# def
type: str = "default",
title: str = "",
description: str = "",
width = "min-w-96"
#}
{% set type_class = {
"default": "bg-white text-zinc-900 border border-zinc-200 dark:bg-zinc-950 dark:text-zinc-50 dark:border-zinc-700",
"success": "bg-green-100 text-green-900 border border-green-200 dark:bg-green-900 dark:text-green-100 dark:border-green-800",
"error": "bg-red-100 text-red-900 border border-red-200 dark:bg-red-900 dark:text-red-100 dark:border-red-800",
"warning": "bg-yellow-100 text-yellow-900 border border-yellow-200 dark:bg-yellow-900 dark:text-yellow-100 dark:border-yellow-800",
"destructive": "border-red-500 bg-red-500 text-zinc-50 dark:border-red-900 dark:bg-red-900 dark:text-zinc-50"
}[type] %}
<div class="{{ type_class }} w-full max-w-md rounded-md p-4 shadow-lg">
<button
@click="show = false"
class="absolute right-2 top-2 text-zinc-500 hover:text-zinc-700 dark:hover:text-zinc-300"
>
<XIcon alt="Close" class="h-4 w-4"/>
</button>
<div class="pr-6 {{ width }}">
<p class="font-medium">{{ title }}</p>
<p class="text-sm ">{{ description }}</p>
</div>
</div>
{# def
className: str = "",
variant: str = "default",
toast_target: str,
#}
{% set click_action="$dispatch('show-toast', '" + toast_target + "')" %}
<Button :@click="{{ click_action }}" class="{{ className }}" :variant="{{ variant }}">
{{ content }}
</Button>
Examples
Success
Success!
Your operation was successful.
<ToastTrigger variant="outline" toast_target="toast-success">Show Success Toast</ToastTrigger>
<Toast id="toast-success">
<ToastContent
type="success"
title="Success!"
description="Your operation was successful."
/>
</Toast>
Warning
Warning!
This is your warning.
<ToastTrigger variant="outline" toast_target="toast-warning">Show Warning Toast</ToastTrigger>
<Toast id="toast-warning">
<ToastContent
type="warning"
title="Warning!"
description="This is your warning."
/>
</Toast>
Error
Error!
An error has occurred.
<ToastTrigger variant="outline" toast_target="toast-error">Show Error Toast</ToastTrigger>
<Toast id="toast-error">
<ToastContent
type="error"
title="Error!"
description="An error has occurred."
/>
</Toast>
Destructive
Uh oh! Something went wrong.
There was a problem with your request.
<ToastTrigger variant="outline" toast_target="toast-warning">Show Toast</ToastTrigger>
<Toast id="toast-warning">
<ToastContent
type="destructive"
title="Uh oh! Something went wrong."
description="There was a problem with your request."
/>
</Toast>