forked from pdsls.dev/pdsls
this repo has no description

add toast slide animation

juli.ee 85a31a92 ed7cdacc

verified
Changed files
+34 -1
src
components
styles
+12 -1
src/components/notification.tsx
··· 9 9 }; 10 10 11 11 const [notifications, setNotifications] = createSignal<Notification[]>([]); 12 + const [removingIds, setRemovingIds] = createSignal<Set<string>>(new Set()); 12 13 13 14 export const addNotification = (notification: Omit<Notification, "id">) => { 14 15 const id = `notification-${Date.now()}-${Math.random()}`; ··· 21 22 }; 22 23 23 24 export const removeNotification = (id: string) => { 24 - setNotifications(notifications().filter((n) => n.id !== id)); 25 + setRemovingIds(new Set([...removingIds(), id])); 26 + setTimeout(() => { 27 + setNotifications(notifications().filter((n) => n.id !== id)); 28 + setRemovingIds((ids) => { 29 + const newIds = new Set(ids); 30 + newIds.delete(id); 31 + return newIds; 32 + }); 33 + }, 250); 25 34 }; 26 35 27 36 export const NotificationContainer = () => { ··· 35 44 "border-blue-500 dark:border-blue-400": notification.type === "info", 36 45 "border-green-500 dark:border-green-400": notification.type === "success", 37 46 "border-red-500 dark:border-red-400": notification.type === "error", 47 + "animate-[slideIn_0.25s_ease-in]": !removingIds().has(notification.id), 48 + "animate-[slideOut_0.25s_ease-in]": removingIds().has(notification.id), 38 49 }} 39 50 onClick={() => removeNotification(notification.id)} 40 51 >
+22
src/styles/index.css
··· 43 43 .ri--bluesky { 44 44 --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M12 11.388c-.906-1.761-3.372-5.044-5.665-6.662c-2.197-1.55-3.034-1.283-3.583-1.033C2.116 3.978 2 4.955 2 5.528c0 .575.315 4.709.52 5.4c.68 2.28 3.094 3.05 5.32 2.803c-3.26.483-6.157 1.67-2.36 5.898c4.178 4.325 5.726-.927 6.52-3.59c.794 2.663 1.708 7.726 6.444 3.59c3.556-3.59.977-5.415-2.283-5.898c2.225.247 4.64-.523 5.319-2.803c.205-.69.52-4.825.52-5.399c0-.575-.116-1.55-.752-1.838c-.549-.248-1.386-.517-3.583 1.033c-2.293 1.621-4.76 4.904-5.665 6.664'/%3E%3C/svg%3E"); 45 45 } 46 + 47 + @keyframes slideIn { 48 + 0% { 49 + transform: translateY(20px); 50 + opacity: 0; 51 + } 52 + 100% { 53 + transform: translateY(0); 54 + opacity: 1; 55 + } 56 + } 57 + 58 + @keyframes slideOut { 59 + 0% { 60 + transform: translateY(0); 61 + opacity: 1; 62 + } 63 + 100% { 64 + transform: translateY(20px); 65 + opacity: 0; 66 + } 67 + }