Notification Drawer

Panel containing notifications.

Notifications

33 unread

Today

  • Priya Shah approved your request

  • Marcus Lee mentioned you in Roadmap

Yesterday

  • Backup completed successfully

html

<section class="drawer" aria-label="Notifications">
  <header class="drawer__head">
    <h2 class="drawer__title">Notifications</h2>
    <span class="drawer__badge" style="background:#A8E6C1;">3<span class="sr-only">3 unread</span></span>
  </header>
  <div class="drawer__body" data-grouping="grouped">
    <h3 class="drawer__group-heading">Today</h3>
    <ul class="drawer__list">
      <li class="drawer__item"><p class="drawer__text"><strong>Priya Shah</strong> approved your request</p><time class="drawer__time" datetime="2026-08-18T09:14">9:14 am</time></li>
      <li class="drawer__item"><p class="drawer__text"><strong>Marcus Lee</strong> mentioned you in Roadmap</p><time class="drawer__time" datetime="2026-08-18T08:02">8:02 am</time></li>
    </ul>
    <h3 class="drawer__group-heading">Yesterday</h3>
    <ul class="drawer__list">
      <li class="drawer__item"><p class="drawer__text">Backup completed successfully</p><time class="drawer__time" datetime="2026-08-17T22:40">Yesterday, 10:40 pm</time></li>
    </ul>
  </div>
  <footer class="drawer__footer"><button class="drawer__mark" type="button" style="color:#A8E6C1;">Mark all as read</button></footer>
</section>
<style>
.drawer { font: 14px/1.5 system-ui, sans-serif; width: 320px; background: #FAF7F2; color: #241430; border-radius: 12px; box-shadow: 0 10px 28px rgba(36,20,48,.18); overflow: hidden; }
.drawer__head { display: flex; align-items: center; justify-content: space-between; padding: 14px 16px; border-bottom: 1px solid #24143020; }
.drawer__title { margin: 0; font-size: 16px; font-weight: 600; }
.drawer__badge { min-width: 22px; height: 22px; padding: 0 6px; border-radius: 11px; display: inline-flex; align-items: center; justify-content: center; font: 700 12px system-ui, sans-serif; color: #241430; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
.drawer__body { padding: 8px 0; max-height: 260px; overflow-y: auto; }
.drawer__group-heading { margin: 8px 16px 4px; font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: #24143099; }
.drawer__list { list-style: none; margin: 0; padding: 0; }
.drawer__item { display: flex; justify-content: space-between; gap: 10px; padding: 8px 16px; }
.drawer__text { margin: 0; }
.drawer__time { flex-shrink: 0; color: #24143080; font-size: 12px; }
.drawer__footer { padding: 10px 16px; border-top: 1px solid #24143020; }
.drawer__mark { border: none; background: transparent; font: 600 13px system-ui, sans-serif; cursor: pointer; padding: 0; }
.drawer__mark:focus-visible { outline: 2px solid #241430; outline-offset: 2px; }
.drawer__body[data-grouping="flat"] .drawer__group-heading { display: none; }
</style>

tailwind

<section aria-label="Notifications" class="w-80 bg-[#FAF7F2] text-[#241430] rounded-xl shadow-lg overflow-hidden font-sans text-sm">
  <header class="flex items-center justify-between px-4 py-3.5 border-b border-[#24143020]">
    <h2 class="m-0 text-base font-semibold">Notifications</h2>
    <span class="min-w-[22px] h-[22px] px-1.5 rounded-full inline-flex items-center justify-center text-xs font-bold" style="background:#A8E6C1">3<span class="sr-only">3 unread</span></span>
  </header>
  <div class="drawer-tw-body py-2 max-h-64 overflow-y-auto" data-grouping="grouped">
    <h3 class="drawer-tw-heading mx-4 mt-2 mb-1 text-[11px] uppercase tracking-wide text-[#241430]/60">Today</h3>
    <ul class="list-none m-0 p-0">
      <li class="flex justify-between gap-2.5 px-4 py-2"><p class="m-0"><strong>Priya Shah</strong> approved your request</p><time class="shrink-0 text-[#241430]/50 text-xs" datetime="2026-08-18T09:14">9:14 am</time></li>
      <li class="flex justify-between gap-2.5 px-4 py-2"><p class="m-0"><strong>Marcus Lee</strong> mentioned you in Roadmap</p><time class="shrink-0 text-[#241430]/50 text-xs" datetime="2026-08-18T08:02">8:02 am</time></li>
    </ul>
    <h3 class="drawer-tw-heading mx-4 mt-2 mb-1 text-[11px] uppercase tracking-wide text-[#241430]/60">Yesterday</h3>
    <ul class="list-none m-0 p-0">
      <li class="flex justify-between gap-2.5 px-4 py-2"><p class="m-0">Backup completed successfully</p><time class="shrink-0 text-[#241430]/50 text-xs" datetime="2026-08-17T22:40">Yesterday, 10:40 pm</time></li>
    </ul>
  </div>
  <footer class="px-4 py-2.5 border-t border-[#24143020]"><button type="button" class="border-0 bg-transparent font-semibold text-[13px] cursor-pointer p-0" style="color:#A8E6C1">Mark all as read</button></footer>
</section>
<style>
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
.drawer-tw-body[data-grouping="flat"] .drawer-tw-heading { display: none; }
</style>

react

export function NotificationDrawer({
  heading = "Notifications",
  unreadCount = 3,
  grouping = "grouped",
  accent = "#A8E6C1",
  showFooter = true,
}) {
  const groups = grouping === "grouped"
    ? ["Today", "Yesterday"]
    : [null, null];
  return (
    <section aria-label={heading} style={{ width: 320, background: "#FAF7F2", color: "#241430", borderRadius: 12,
      boxShadow: "0 10px 28px rgba(36,20,48,.18)", overflow: "hidden", fontFamily: "system-ui, sans-serif", fontSize: 14 }}>
      <header style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "14px 16px", borderBottom: "1px solid #24143020" }}>
        <h2 style={{ margin: 0, fontSize: 16, fontWeight: 600 }}>{heading}</h2>
        <span style={{ minWidth: 22, height: 22, padding: "0 6px", borderRadius: 11, background: accent,
          display: "inline-flex", alignItems: "center", justifyContent: "center", fontSize: 12, fontWeight: 700 }}>
          {unreadCount}
          <span style={{ position: "absolute", width: 1, height: 1, overflow: "hidden", clip: "rect(0,0,0,0)" }}>{unreadCount} unread</span>
        </span>
      </header>
      <div style={{ padding: "8px 0", maxHeight: 260, overflowY: "auto" }}>
        {groups[0] && <h3 style={{ margin: "8px 16px 4px", fontSize: 11, textTransform: "uppercase", letterSpacing: .04, color: "#24143099" }}>{groups[0]}</h3>}
        <ul style={{ listStyle: "none", margin: 0, padding: 0 }}>
          <li style={{ display: "flex", justifyContent: "space-between", gap: 10, padding: "8px 16px" }}>
            <p style={{ margin: 0 }}><strong>Priya Shah</strong> approved your request</p>
            <time style={{ flexShrink: 0, color: "#24143080", fontSize: 12 }} dateTime="2026-08-18T09:14">9:14 am</time>
          </li>
          <li style={{ display: "flex", justifyContent: "space-between", gap: 10, padding: "8px 16px" }}>
            <p style={{ margin: 0 }}><strong>Marcus Lee</strong> mentioned you in Roadmap</p>
            <time style={{ flexShrink: 0, color: "#24143080", fontSize: 12 }} dateTime="2026-08-18T08:02">8:02 am</time>
          </li>
        </ul>
        {groups[1] && <h3 style={{ margin: "8px 16px 4px", fontSize: 11, textTransform: "uppercase", letterSpacing: .04, color: "#24143099" }}>{groups[1]}</h3>}
        <ul style={{ listStyle: "none", margin: 0, padding: 0 }}>
          <li style={{ display: "flex", justifyContent: "space-between", gap: 10, padding: "8px 16px" }}>
            <p style={{ margin: 0 }}>Backup completed successfully</p>
            <time style={{ flexShrink: 0, color: "#24143080", fontSize: 12 }} dateTime="2026-08-17T22:40">Yesterday, 10:40 pm</time>
          </li>
        </ul>
      </div>
      {showFooter && (
        <footer style={{ padding: "10px 16px", borderTop: "1px solid #24143020" }}>
          <button type="button" style={{ border: "none", background: "transparent", color: accent, fontWeight: 600, fontSize: 13, cursor: "pointer", padding: 0 }}>Mark all as read</button>
        </footer>
      )}
    </section>
  );
}