>(new Set())
+ const [hovering, setHovering] = createSignal(false)
+
+ const onStartRemoving = (id: number): void => {
+ setRemovingIds((prev) => new Set([...prev, id]))
+ setTimeout(() => {
+ setRemovingIds((prev) => {
+ const next = new Set(prev)
+ next.delete(id)
+ return next
+ })
+ }, 400)
+ }
+
+ const effectiveIndex = (id: number): number => {
+ const removing = removingIds()
+ let idx = 0
+ for (const t of notifications()) {
+ if (t.id === id) return idx
+ if (!removing.has(t.id)) idx++
+ }
+ return idx
+ }
+
+ return (
+ setHovering(true)}
+ onMouseLeave={() => setHovering(false)}
+ class={classNames(
+ ' fixed top-6 left-1/2 -translate-x-1/2 w-[400px] z-[999] transition-[height] duration-[380ms] [cubic-bezier(0.34,1.1,0.64,1)]',
+ notifications().length ? 'pointer-events-auto' : 'pointer-events-none',
+ )}
+ style={{
+ height: hovering() ? `${Math.min(notifications().length, 5) * 72 + 2}px` : '80px',
+ 'transition-timing-function': 'cubic-bezier(0.34, 1.1, 0.64, 1)',
+ }}>
+
+ {(t) => (
+
+ )}
+
+
+ )
+}
diff --git a/src/types/notifications/interfaces.ts b/src/types/notifications/interfaces.ts
new file mode 100644
index 00000000..ebeeaee1
--- /dev/null
+++ b/src/types/notifications/interfaces.ts
@@ -0,0 +1,13 @@
+import { NOTIFICATION_TYPE } from './enums'
+
+export interface ToastOptions {
+ description?: string
+ duration?: number
+}
+
+export interface IToast extends ToastOptions {
+ type: NOTIFICATION_TYPE
+ id: number
+ message: string
+ duration: number
+}
diff --git a/tailwind.config.mjs b/tailwind.config.mjs
index bcdf9745..fcfa68b4 100644
--- a/tailwind.config.mjs
+++ b/tailwind.config.mjs
@@ -48,6 +48,15 @@ module.exports = {
gridTemplateColumns: {
'1/5': '1fr 5fr',
},
+ keyframes: {
+ shrink: {
+ from: { transform: 'scaleX(1)' },
+ to: { transform: 'scaleX(0)' },
+ },
+ },
+ animation: {
+ shrink: 'shrink 300ms ease-out forwards',
+ },
},
...theme,
},