fix(a11y): a labelled rail row says its label and the exact unread count, not the capped badge first (E28)
With the labels on, the row's name was its text, badge first: 15 unread was heard as "9+ Alerts". The name is now the visible label plus the count, as the icon-only row's is, and the drawn badge is hidden.
This commit is contained in:
@@ -46,6 +46,22 @@ describe("NavRailItem", () => {
|
|||||||
const row = screen.getByRole("button", { name: "Alerts" });
|
const row = screen.getByRole("button", { name: "Alerts" });
|
||||||
expect(row.getAttribute("aria-current")).toBeNull();
|
expect(row.getAttribute("aria-current")).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// E28 audit: labelled, the name was the row's text, the corner badge first, so 20 unread was heard
|
||||||
|
// as "9+Alerts" where the icon-only row says "Notifications (20)".
|
||||||
|
it("labelled with a count: the visible label, then the exact count", () => {
|
||||||
|
render(
|
||||||
|
<NavRailItem
|
||||||
|
icon={Bell}
|
||||||
|
label="Notifications"
|
||||||
|
shortLabel="Alerts"
|
||||||
|
showLabel
|
||||||
|
badge={20}
|
||||||
|
onClick={() => {}}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
expect(screen.getByRole("button", { name: "Alerts (20)" })).toBeTruthy();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// F32: the rail's footer (language, About, Sign out) drew 32 and 36 squares with 16 and 20px glyphs
|
// F32: the rail's footer (language, About, Sign out) drew 32 and 36 squares with 16 and 20px glyphs
|
||||||
|
|||||||
@@ -97,10 +97,11 @@ export function NavRailItem({
|
|||||||
<Pressable
|
<Pressable
|
||||||
data-testid={testId}
|
data-testid={testId}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
// With the label visible the row's name IS that text (WCAG 2.5.3: the spoken name contains the
|
// With the label visible the row's name starts with that text (WCAG 2.5.3: the spoken name
|
||||||
// visible one); the full name stays in the tooltip. Icon-only, the full name is the name.
|
// contains the visible one); the full name stays in the tooltip. Icon-only, the full name is the
|
||||||
// The count rides in the name too, so "Messages, 3" is heard and not only seen.
|
// name. The exact count rides in the name either way, so "Messages (3)" is heard and not only
|
||||||
aria-label={showLabel ? undefined : shown ? `${label} (${badge})` : label}
|
// seen; the drawn badge is hidden (labelled, it was read first and capped: "9+Alerts").
|
||||||
|
aria-label={`${showLabel ? shortLabel : label}${shown ? ` (${badge})` : ""}`}
|
||||||
aria-current={active ? "page" : undefined}
|
aria-current={active ? "page" : undefined}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
RAIL_ROW,
|
RAIL_ROW,
|
||||||
@@ -117,7 +118,10 @@ export function NavRailItem({
|
|||||||
<span className="relative shrink-0">
|
<span className="relative shrink-0">
|
||||||
<Icon className={RAIL_GLYPH} aria-hidden="true" />
|
<Icon className={RAIL_GLYPH} aria-hidden="true" />
|
||||||
{shown && (
|
{shown && (
|
||||||
<span className="absolute -top-2 -right-2 grid h-4 min-w-4 place-items-center rounded-full bg-accent px-1 text-3xs leading-none font-bold text-accent-fg ring-2 ring-bg">
|
<span
|
||||||
|
aria-hidden="true"
|
||||||
|
className="absolute -top-2 -right-2 grid h-4 min-w-4 place-items-center rounded-full bg-accent px-1 text-3xs leading-none font-bold text-accent-fg ring-2 ring-bg"
|
||||||
|
>
|
||||||
{badge > 9 ? "9+" : badge}
|
{badge > 9 ? "9+" : badge}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user