An opinionated toast notification library for Vue 3, with SVG morphing, spring physics, and a minimal API.
سَمْت — composure, demeanor. صَمْت — silence.
One word in Latin letters; two in Arabic. The difference is whether you read it with a sīn (س) or a ṣād (ص). A good toast is both at once: it arrives with composure and leaves in silence.
samt is a Vue port inspired by sileo by hiaaryan. Its interaction design, animation feel, and API shape come from there — this package is an independent Vue 3 implementation of those ideas. If samt is useful to you, go star the original too.
pnpm add @zamanapp/samtVue 3.5+ is a peer dependency.
Add <Samt> once at your app root and import the CSS:
<!-- App.vue -->
<script setup>
import { Samt } from "@zamanapp/samt";
import "@zamanapp/samt/styles.css";
</script>
<template>
<Samt />
<RouterView />
</template>Then fire a toast from anywhere:
import { samt } from "@zamanapp/samt";
samt.success({ title: "Saved!" });import { samt } from "@zamanapp/samt";
samt.success({ title: "Saved!" });
samt.error({ title: "Something went wrong", description: "Please try again." });
samt.warning({ title: "Low disk space" });
samt.info({ title: "New version available" });
samt.action({
title: "Undo?",
button: { title: "Undo", onClick: () => restore() },
});Every method returns the toast's id, which you can use to dismiss or update it.
Fire as many as you like — toasts stack per position, fan out on hover, and cap
out with the oldest dismissed first. Tune the cap, fan-out, and alignment with
the <Samt> props below.
samt.success({ title: "Top center", position: "top-center" });
samt.info({ title: "Bottom left", position: "bottom-left" });Positions: top-left, top-center, top-right, bottom-left,
bottom-center, bottom-right. Set a default for every toast on <Samt>.
samt.promise transitions a single toast through loading → success/error:
samt.promise(saveUser(), {
loading: { title: "Saving…" },
success: (user) => ({ title: `Saved ${user.name}` }),
error: (err) => ({ title: "Save failed", description: err.message }),
});Reuse an explicit id to morph a toast in place instead of stacking a new one:
samt.info({ id: "sync", title: "Syncing…" });
// later
samt.success({ id: "sync", title: "Synced" }); // morphs the same toast
samt.dismiss(id); // dismiss one
samt.clear(); // clear all
samt.clear("top-right"); // clear one positionuseToast is a thin wrapper for use inside components:
<script setup>
import { useToast } from "@zamanapp/samt";
const toast = useToast();
toast.success({ title: "Done!" });
</script>| Prop | Type | Default | Description |
|---|---|---|---|
position |
SamtPosition |
"top-right" |
Default position for toasts. |
theme |
"light" | "dark" | "system" |
— | Colour theme. |
offset |
number | { top?, right?, bottom?, left? } |
— | Distance from the viewport edges. |
maxToasts |
number |
width-derived | Max toasts per position before the oldest is evicted. |
expand |
boolean |
true |
Whether hovering fans the stack into a list. |
stackAlign |
"start" | "end" |
"end" |
Nudge direction for centered stacks (corners auto-derive). |
SamtOptions (accepted by every samt.* method):
| Option | Type | Description |
|---|---|---|
title |
string |
Heading text. |
description |
string | VNode | Component |
Body content. |
duration |
number | null |
Auto-dismiss ms; null keeps it until dismissed. |
position |
SamtPosition |
Override the default position. |
icon |
VNode | null |
Custom icon (null hides it). |
button |
{ title, onClick } |
Action button. |
id |
string |
Reuse to update a toast in place. |
roundness |
number |
Corner radius. |
styles |
{ title?, description?, badge?, button? } |
Per-part class overrides. |
autopilot |
boolean | { expand?, collapse? } |
Auto expand/collapse timing. |
MIT — see LICENSE.
