diff design_system/src/styles/components.css @ 253:fdf3816959cb

[ui] Add Sonner-like notification stack Co-authored-by: Copilot <[email protected]>
author MrJuneJune <me@mrjunejune.com>
date Tue, 04 Aug 2026 12:21:19 -0700
parents 7a7581f040e8
children 2b6e732087ff
line wrap: on
line diff
--- a/design_system/src/styles/components.css	Tue Aug 04 11:57:16 2026 -0700
+++ b/design_system/src/styles/components.css	Tue Aug 04 12:21:19 2026 -0700
@@ -213,13 +213,25 @@
     --zen-notification-bottom-inset,
     var(--zen-space-4)
   );
-  display: grid;
   inline-size: min(24rem, calc(100vi - 2rem));
-  gap: var(--zen-space-3);
-  pointer-events: none;
+  height: var(--zen-notification-collapsed-height, 0);
+  --zen-notification-gap: 12px;
+  pointer-events: auto;
+  isolation: isolate;
+  transition: height 220ms cubic-bezier(0.2, 0.8, 0.2, 1);
+}
+
+zen-notifications > [data-zen-notification-stack]:is(
+  :hover,
+  :focus-within
+) {
+  height: var(--zen-notification-expanded-height, 0);
 }
 
 zen-notifications > [data-zen-notification-stack] > article {
+  position: absolute;
+  inset-inline: 0;
+  inset-block-end: 0;
   display: grid;
   grid-template-columns: 1.75rem minmax(0, 1fr) 2rem;
   align-items: start;
@@ -230,8 +242,46 @@
   box-shadow: var(--zen-shadow-md);
   background: var(--zen-color-surface-raised);
   color: var(--zen-color-text);
+  opacity: var(--zen-notification-collapsed-opacity, 1);
+  pointer-events: none;
+  transform:
+    translate3d(
+      0,
+      var(--zen-notification-collapsed-offset, 0),
+      0
+    )
+    scale(var(--zen-notification-scale, 1));
+  transform-origin: center bottom;
+  transition:
+    opacity 180ms ease,
+    transform 220ms cubic-bezier(0.2, 0.8, 0.2, 1);
+  will-change: transform;
+  animation: zen-notification-enter 160ms ease-out;
+}
+
+zen-notifications > [data-zen-notification-stack] > article[data-depth="0"] {
   pointer-events: auto;
-  animation: zen-notification-enter 160ms ease-out;
+}
+
+zen-notifications > [data-zen-notification-stack]:is(
+  :hover,
+  :focus-within
+) > article {
+  opacity: 1;
+  pointer-events: auto;
+  transform:
+    translate3d(
+      0,
+      var(--zen-notification-offset, 0px),
+      0
+    )
+    scale(1);
+}
+
+zen-notifications > [data-zen-notification-stack] > article[data-removing] {
+  opacity: 0;
+  pointer-events: none;
+  transform: translate3d(110%, 0, 0) scale(0.96);
 }
 
 .zen-notification-tone {
@@ -324,7 +374,6 @@
 @keyframes zen-notification-enter {
   from {
     opacity: 0;
-    transform: translateY(0.75rem);
   }
 }
 
@@ -347,5 +396,10 @@
 
   zen-notifications > [data-zen-notification-stack] > article {
     animation: none;
+    transition: none;
+  }
+
+  zen-notifications > [data-zen-notification-stack] {
+    transition: none;
   }
 }