Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/buzz-help.md
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ revokes all of them, and a pairing unused for 30 days expires.
kind, and **From** by sender (Anyone, People or Agents). Turn on **Unread** to see only what you haven't read:
there, a row's ✓ marks it as read and it leaves the list, with **Undo** for a moment; when nothing is left it
says **All caught up**. If loading fails, use **Retry activity** on the page or preview to retry; recovered
activity clears the loading error.
activity clears the loading error. Pink dots identify unread conversations in Activity and unread activity in channel and DM sidebar rows.
A DM row whose unread messages are all in one thread opens that thread; later DM messages outside it stay
unread until you open the whole DM, which its row then does.
**Reactions** shows recent reactions to your messages, with shared emoji grouped together per message and each person’s remaining emoji in their own row; selecting it turns Unread off.
Expand Down
5 changes: 4 additions & 1 deletion scripts/design-system/check-contrast.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ const BOUNDARY_ROLES = [
"--status-avatar-online-border",
"--status-away",
"--status-offline",
"--status-unread",
// Chart marks need 3:1 against the surfaces a chart sits on.
"--chart-series-1",
"--chart-series-2",
Expand Down Expand Up @@ -470,7 +471,9 @@ function audit(mode, map, baseline) {
}
for (const role of BOUNDARY_ROLES) {
const surfaces =
role.startsWith("--status-avatar-") || role === "--status-away"
role.startsWith("--status-avatar-") ||
role === "--status-away" ||
role === "--status-unread"
? [
...BOUNDARY_SURFACES,
"--affordance-selected",
Expand Down
2 changes: 1 addition & 1 deletion src/bundled/channels/Channels.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -886,7 +886,7 @@ details:not([open]) > summary .sectionChevron {
width: 0.375rem;
height: 0.375rem;
border-radius: 50%;
background: var(--affordance-prominent-mark);
background: var(--status-unread);
Comment thread
hitanshup marked this conversation as resolved.
Resolved
}
.threadActivityDot {
cursor: help;
Expand Down
2 changes: 1 addition & 1 deletion src/features/messages/MessageListRow.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
width: var(--space-2);
height: var(--space-2);
border-radius: var(--radius-pill);
background: var(--text-navigation-unread);
background: var(--status-unread);
}

.rowDate {
Expand Down
2 changes: 2 additions & 0 deletions src/shared/design-system/styles/tokens.css
Original file line number Diff line number Diff line change
Expand Up @@ -1161,6 +1161,7 @@
--status-avatar-online-border: var(--green-11);
--status-away: var(--amber-10);
--status-offline: var(--neutral-8);
--status-unread: var(--magenta-9);
/* Chart series marks, in this order; validated as a set for colour-vision
* separation and 3:1 against the panel. Text never uses them. */
--chart-series-1: var(--blue-10);
Expand Down Expand Up @@ -1314,6 +1315,7 @@
--status-avatar-online-border: var(--green-11);
--status-away: var(--amber-10);
--status-offline: var(--neutral-10);
--status-unread: var(--magenta-11);
/* Dark steps stay in the band where no series outshines the others. */
--chart-series-1: var(--blue-9);
--chart-series-2: var(--orange-8);
Expand Down
7 changes: 7 additions & 0 deletions src/shared/design-system/tokens/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -813,6 +813,13 @@ export const ROLE_GROUPS: RoleGroup[] = [
use: "Offline presence dot.",
status: "core",
},
{
token: "status-unread",
variable: "--status-unread",
pointsAt: "magenta-9 light / magenta-11 dark",
use: "Unread dots in Activity and channel/DM sidebars; independent of the chosen accent. Selected sidebar rows retain their paired selection ink.",
status: "core",
},
],
},
{
Expand Down
4 changes: 4 additions & 0 deletions tests/browser/inbox.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,10 @@ test("Inbox opens the exact thread, shares read state, and fits the workspace",
const opener = mentionRow.getByRole("button", { name: /^Open / });
const dot = opener.getByRole("img", { name: "Unread", exact: true });
await expect(dot).toBeVisible();
await expect(dot.locator("span")).toHaveCSS(
"background-color",
mode === "light" ? "rgb(223, 30, 133)" : "rgb(244, 188, 207)",
);
const dotLayout = await dot.evaluate((element) => {
const button = element.closest("button");
const label = button.querySelector(".navigation-item-label");
Expand Down
26 changes: 22 additions & 4 deletions tests/browser/sidebar-unread.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ test("session changes discard the previous sidebar targets and manual unread sti
}
});

test("priority dots stay aligned and use the prominent mark color in both modes", async ({
test("priority dots stay aligned and use pink unread color in both modes", async ({
page,
app,
}, info) => {
Expand Down Expand Up @@ -584,16 +584,34 @@ test("priority dots stay aligned and use the prominent mark color in both modes"
const primary = await page.evaluate(() => {
const root = getComputedStyle(document.documentElement);
const probe = document.createElement("span");
probe.style.backgroundColor = root.getPropertyValue(
"--affordance-prominent-mark",
);
probe.style.backgroundColor = root.getPropertyValue("--status-unread");
document.body.append(probe);
const color = getComputedStyle(probe).backgroundColor;
probe.remove();
return color;
});
await expect(dot).toHaveCSS("background-color", primary);
}
// The existing selected-row recipe uses its accent fill's paired ink.
// A pink dot would disappear on the light Magenta selection fill.
await page.evaluate(() => {
document.documentElement.dataset.colorMode = "light";
document.documentElement.dataset.accent = "magenta";
});
const dm = row(page, "dm-030");
await dm.click();
await expect(dm).toHaveAttribute("aria-current", "page");
await dm.click({ button: "right" });
await page
.getByRole("menuitem", { name: "Mark as read", exact: true })
.click();
await expect(page.getByRole("menu")).toHaveCount(0);
await dm.click({ button: "right" });
await page
.getByRole("menuitem", { name: "Mark as unread", exact: true })
.click();
await expect(dot).toBeVisible();
await expect(dot).toHaveCSS("background-color", "rgb(255, 255, 255)");
});

// One small real-app journey owns preview wiring and CSS geometry. The component
Expand Down