diff design_system/src/components/notifications.js @ 254:2b6e732087ff

[ui] Add complete native component catalog Co-authored-by: Copilot <[email protected]>
author MrJuneJune <me@mrjunejune.com>
date Tue, 04 Aug 2026 15:12:09 -0700
parents fdf3816959cb
children 60a876c4587a
line wrap: on
line diff
--- a/design_system/src/components/notifications.js	Tue Aug 04 12:21:19 2026 -0700
+++ b/design_system/src/components/notifications.js	Tue Aug 04 15:12:09 2026 -0700
@@ -13,6 +13,12 @@
     (allowEmpty || value.trim().length > 0);
 }
 
+/**
+ * Validates and normalizes a notification event record.
+ *
+ * @param {*} value Candidate event detail.
+ * @return {?Object} Frozen normalized record, or null when invalid.
+ */
 export function validateNotification(value) {
   if (!value ||
       value.version !== 1 ||
@@ -53,6 +59,12 @@
   });
 }
 
+/**
+ * Validates a programmatic notification dismissal record.
+ *
+ * @param {*} value Candidate event detail.
+ * @return {?string} Valid notification ID, or null when invalid.
+ */
 export function validateNotificationDismiss(value) {
   if (!value ||
       value.version !== 1 ||
@@ -72,6 +84,11 @@
   };
 }
 
+/**
+ * Renders a bounded, scoped, Sonner-like notification queue.
+ *
+ * @extends {HTMLElement}
+ */
 export class ZenNotifications extends HTMLElement {
   static version = 1;
 
@@ -363,6 +380,8 @@
       const tone = document.createElement("span");
       tone.className = "zen-notification-tone";
       tone.setAttribute("aria-hidden", "true");
+      const toneIcon = document.createElement("zen-icon");
+      tone.append(toneIcon);
 
       const content = document.createElement("div");
       content.className = "zen-notification-content";
@@ -373,7 +392,9 @@
       const dismiss = document.createElement("button");
       dismiss.type = "button";
       dismiss.className = "zen-notification-dismiss";
-      dismiss.textContent = "×";
+      const dismissIcon = document.createElement("zen-icon");
+      dismissIcon.setAttribute("name", "close");
+      dismiss.append(dismissIcon);
       dismiss.addEventListener("click", () => {
         this.dismiss(record.id, "dismissed");
       });
@@ -402,18 +423,19 @@
         dismiss,
         message,
         tone,
+        toneIcon,
       };
       this.#resizeObserver?.observe(article);
     }
 
     const view = record.view;
     view.article.dataset.tone = record.tone;
-    view.tone.textContent = {
-      info: "i",
-      success: "✓",
-      warning: "!",
-      error: "×",
-    }[record.tone];
+    view.toneIcon.setAttribute("name", {
+      info: "info",
+      success: "check",
+      warning: "alert",
+      error: "error",
+    }[record.tone]);
     view.message.textContent = record.message;
     view.dismiss.setAttribute(
       "aria-label",