What's New Panel

In-app announcement of recent changes.

What's new

html

<div class="wn wn--list" data-entries="2" style="--accent:#A8E6C1;">
  <div class="wn__head">
    <h3 class="wn__title">What&#39;s new</h3>
    <button type="button" class="wn__close" aria-label="Close">×</button>
  </div>
  <ul class="wn__list">
    <li class="wn__entry">
      <span class="wn__flag">New</span>
      <p class="wn__entry-title">Faster search across your workspace</p>
      <p class="wn__entry-date">12 Aug</p>
    </li>
    <li class="wn__entry">
      <p class="wn__entry-title">Dark mode for the mobile app</p>
      <p class="wn__entry-date">5 Aug</p>
    </li>
    <li class="wn__entry">
      <p class="wn__entry-title">Bulk export for reports</p>
      <p class="wn__entry-date">29 Jul</p>
    </li>
  </ul>
</div>
<style>
.wn { position: relative; font: 16px/1.5 system-ui, sans-serif; color: #241430; background: #FAF7F2; padding: 18px 20px; max-width: 320px; border-radius: 14px; border: 1px solid #24143018; }
.wn__head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; }
.wn__title { margin: 0; font-size: 15px; font-weight: 700; }
.wn__close { width: 22px; height: 22px; border: none; background: transparent; color: #24143070; font-size: 14px; cursor: pointer; border-radius: 6px; }
.wn__close:hover, .wn__close:focus-visible { background: #24143012; color: #241430; }
.wn__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.wn__entry { position: relative; }
.wn__entry-title { margin: 0 0 2px; font-size: 13px; font-weight: 600; }
.wn__entry-date { margin: 0; font-size: 11px; color: #24143090; }
.wn__flag { display: inline-block; font-size: 9.5px; font-weight: 800; text-transform: uppercase; letter-spacing: .03em; padding: 2px 6px; border-radius: 999px; background: var(--accent); margin-bottom: 4px; }
.wn[data-entries="1"] .wn__entry:nth-child(n+2) { display: none; }
.wn[data-entries="2"] .wn__entry:nth-child(n+3) { display: none; }
.wn--timeline .wn__list { padding-left: 14px; border-left: 1.5px solid #24143018; }
.wn--timeline .wn__entry::before { content: ""; position: absolute; left: -18.5px; top: 4px; width: 8px; height: 8px; border-radius: 999px; background: var(--accent); }
.wn--compact .wn__entry { display: flex; align-items: baseline; gap: 8px; }
.wn--compact .wn__entry-date { order: -1; }
</style>

tailwind

<div class="wn-tw wn-tw--list relative max-w-[320px] p-4.5 rounded-2xl border border-[#24143018] bg-[#FAF7F2] text-[#241430] font-sans" data-entries="2" style="--accent:#A8E6C1">
  <div class="flex justify-between items-center mb-2.5">
    <h3 class="m-0 text-[15px] font-bold">What&#39;s new</h3>
    <button type="button" class="w-5.5 h-5.5 rounded-md text-[#24143070] hover:bg-[#24143012] hover:text-[#241430]" aria-label="Close">×</button>
  </div>
  <ul class="wn-tw__list list-none m-0 p-0 flex flex-col gap-3">
    <li class="wn-tw__entry relative">
      <span class="inline-block text-[9.5px] font-extrabold uppercase tracking-wide px-1.5 py-0.5 rounded-full mb-1" style="background:#A8E6C1">New</span>
      <p class="m-0 mb-0.5 text-[13px] font-semibold">Faster search across your workspace</p>
      <p class="m-0 text-[11px] text-[#24143090]">12 Aug</p>
    </li>
    <li class="wn-tw__entry relative">
      <p class="m-0 mb-0.5 text-[13px] font-semibold">Dark mode for the mobile app</p>
      <p class="m-0 text-[11px] text-[#24143090]">5 Aug</p>
    </li>
    <li class="wn-tw__entry relative">
      <p class="m-0 mb-0.5 text-[13px] font-semibold">Bulk export for reports</p>
      <p class="m-0 text-[11px] text-[#24143090]">29 Jul</p>
    </li>
  </ul>
</div>
<style>
.wn-tw[data-entries="1"] .wn-tw__entry:nth-child(n+2) { display: none; }
.wn-tw[data-entries="2"] .wn-tw__entry:nth-child(n+3) { display: none; }
.wn-tw--timeline .wn-tw__list { padding-left: 14px; border-left: 1.5px solid #24143018; }
.wn-tw--timeline .wn-tw__entry::before { content: ""; position: absolute; left: -18.5px; top: 4px; width: 8px; height: 8px; border-radius: 999px; background: var(--accent); }
.wn-tw--compact .wn-tw__entry { display: flex; align-items: baseline; gap: 8px; }
</style>

react

export function WhatsNewPanel({
  title = "What&#39;s new",
  entriesShown = 2,
  newFlag = true,
  accent = "#A8E6C1",
  style = "list",
  dismissLabel = "Close",
}) {
  const entries = [
    { title: "Faster search across your workspace", date: "12 Aug" },
    { title: "Dark mode for the mobile app", date: "5 Aug" },
    { title: "Bulk export for reports", date: "29 Jul" },
  ].slice(0, entriesShown);
  const compact = style === "compact";
  const timeline = style === "timeline";
  return (
    <div style={{ position: "relative", font: "16px/1.5 system-ui, sans-serif", color: "#241430", background: "#FAF7F2", padding: "18px 20px", maxWidth: 320, borderRadius: 14, border: "1px solid #24143018" }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 10 }}>
        <h3 style={{ margin: 0, fontSize: 15, fontWeight: 700 }}>{title}</h3>
        <button type="button" aria-label={dismissLabel} style={{ width: 22, height: 22, border: "none", background: "transparent", color: "#24143070", fontSize: 14, borderRadius: 6, cursor: "pointer" }}>×</button>
      </div>
      <ul style={{ listStyle: "none", margin: 0, padding: timeline ? "0 0 0 14px" : 0, borderLeft: timeline ? "1.5px solid #24143018" : "none", display: "flex", flexDirection: "column", gap: 12 }}>
        {entries.map((e, i) => (
          <li key={e.title} style={{ position: "relative", display: compact ? "flex" : "block", alignItems: compact ? "baseline" : "normal", gap: compact ? 8 : 0 }}>
            {timeline && <span style={{ position: "absolute", left: -18.5, top: 4, width: 8, height: 8, borderRadius: 999, background: accent }} />}
            {i === 0 && newFlag && (
              <span style={{ display: "inline-block", fontSize: 9.5, fontWeight: 800, textTransform: "uppercase", letterSpacing: ".03em", padding: "2px 6px", borderRadius: 999, background: accent, marginBottom: 4 }}>New</span>
            )}
            <p style={{ margin: "0 0 2px", fontSize: 13, fontWeight: 600 }}>{e.title}</p>
            <p style={{ margin: 0, fontSize: 11, color: "#24143090" }}>{e.date}</p>
          </li>
        ))}
      </ul>
    </div>
  );
}