From 222d7d21ff93786b0c2274654963901fe9b10fd8 Mon Sep 17 00:00:00 2001
From: "google-labs-jules[bot]"
<161369871+google-labs-jules[bot]@users.noreply.github.com>
Date: Fri, 27 Feb 2026 09:04:19 +0000
Subject: [PATCH] Palette: Add dynamic aria-labels to notification bell
- Adds dynamic `aria-label` to the notification bell button (e.g., "Notifications, 3 unread").
- Marks the bell icon and unread dot as `aria-hidden="true"` to reduce screen reader noise.
- Documents the learning about dynamic state indicators in `.Jules/palette.md`.
Co-authored-by: vireapp <260846454+vireapp@users.noreply.github.com>
---
.Jules/palette.md | 9 ++++
.../notifications/notification-bell.tsx | 8 ++-
src/lib/supabase/server.ts | 2 +-
verify_bell.py | 50 +++++++++++++++++++
4 files changed, 66 insertions(+), 3 deletions(-)
create mode 100644 .Jules/palette.md
create mode 100644 verify_bell.py
diff --git a/.Jules/palette.md b/.Jules/palette.md
new file mode 100644
index 0000000..d6cdb4a
--- /dev/null
+++ b/.Jules/palette.md
@@ -0,0 +1,9 @@
+# Palette's Journal
+
+## 2024-05-22 - [Initial Setup]
+**Learning:** This journal was missing, so I created it to track critical UX/accessibility learnings.
+**Action:** Ensure this file is checked before starting work in the future.
+
+## 2024-05-22 - [Dynamic State Labels]
+**Learning:** Dynamic state indicators (like notification badges or status dots) often lack accessible text equivalents in this codebase, relying solely on visual cues (colors/dots).
+**Action:** Always check icon-only buttons for `aria-label` and ensure the label reflects the *current state* (e.g., "Notifications, 3 unread") rather than just the static name ("Notifications").
diff --git a/src/components/notifications/notification-bell.tsx b/src/components/notifications/notification-bell.tsx
index 318e870..9b4ea47 100644
--- a/src/components/notifications/notification-bell.tsx
+++ b/src/components/notifications/notification-bell.tsx
@@ -82,10 +82,14 @@ export function NotificationBell() {
variant="ghost"
size="icon"
className="relative text-foreground/70 hover:text-foreground hover:bg-accent/10"
+ aria-label={count > 0 ? `Notifications, ${count} unread` : "Notifications"}
>
-
+
{count > 0 && (
-
+
)}
diff --git a/src/lib/supabase/server.ts b/src/lib/supabase/server.ts
index 0cdb125..714d8cc 100644
--- a/src/lib/supabase/server.ts
+++ b/src/lib/supabase/server.ts
@@ -15,7 +15,7 @@ export async function createClient() {
setAll(cookiesToSet) {
try {
cookiesToSet.forEach(({ name, value, options }) =>
- cookieStore.set(name, value, options),
+ cookieStore.set(name, value, options)
);
} catch {
// The `setAll` method was called from a Server Component.
diff --git a/verify_bell.py b/verify_bell.py
new file mode 100644
index 0000000..e8bc36e
--- /dev/null
+++ b/verify_bell.py
@@ -0,0 +1,50 @@
+from playwright.sync_api import sync_playwright
+
+def verify_notification_bell():
+ with sync_playwright() as p:
+ browser = p.chromium.launch(headless=True)
+ page = browser.new_page()
+
+ try:
+ # 1. Navigate to the verification page
+ print("Navigating to verification page...")
+ page.goto("http://localhost:3000/verify-notification-bell")
+
+ # Wait for content to load
+ page.wait_for_selector("text=Notification Bell Verification", timeout=10000)
+
+ # 2. Find the notification button by its aria-label
+ # Initially count is 0, so label should be "Notifications"
+ print("Locating bell button...")
+ bell_button = page.locator("button[aria-label='Notifications']")
+
+ # 3. Assert it is visible
+ if bell_button.is_visible():
+ print("✅ Bell button found with correct aria-label 'Notifications'")
+ else:
+ print("❌ Bell button NOT found with expected aria-label")
+ # Try to find it by icon to see what the label actually is
+ all_buttons = page.locator("button").all()
+ for btn in all_buttons:
+ print(f"Found button with label: {btn.get_attribute('aria-label')}")
+
+ # 4. Check that the icon inside is hidden from screen readers
+ icon = bell_button.locator("svg.lucide-bell")
+ if icon.get_attribute("aria-hidden") == "true":
+ print("✅ Bell icon correctly marked as aria-hidden='true'")
+ else:
+ print(f"❌ Bell icon missing or incorrect aria-hidden: {icon.get_attribute('aria-hidden')}")
+
+ # 5. Take a screenshot
+ screenshot_path = "/home/jules/verification/notification-bell.png"
+ page.screenshot(path=screenshot_path)
+ print(f"Screenshot saved to {screenshot_path}")
+
+ except Exception as e:
+ print(f"Verification failed: {e}")
+ page.screenshot(path="/home/jules/verification/error.png")
+ finally:
+ browser.close()
+
+if __name__ == "__main__":
+ verify_notification_bell()