diff --git a/.Jules/palette.md b/.Jules/palette.md index bb0f82a6..556b245c 100644 --- a/.Jules/palette.md +++ b/.Jules/palette.md @@ -9,3 +9,6 @@ ## 2026-06-13 - Added screen reader text for tooltip divs **Learning:** When using `title` attributes on non-interactive elements like icon-only `div`s for tooltips, screen readers might not announce them properly because they aren't focusable. The visual tooltip is not enough for accessibility. **Action:** Always add a visually hidden `[Tooltip Text]` inside non-interactive elements that rely on a `title` attribute so that screen readers have text content to announce. +## 2026-06-18 - Added keyboard accessibility to scrollable regions +**Learning:** Horizontally scrollable regions (like the `SectionRoadmap` component) are not accessible to keyboard-only users unless they can receive focus. Keyboard users must be able to focus the container to scroll its content using arrow keys. +**Action:** For proper keyboard accessibility in custom scrollable regions, always include `tabIndex={0}`, an appropriate `aria-label`, `role="region"`, and explicit focus visible styling (e.g., `focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-cyan-300`). diff --git a/apps/desktop/src/features/workspace/SectionRoadmap.tsx b/apps/desktop/src/features/workspace/SectionRoadmap.tsx index 593311c6..8f9ad0c1 100644 --- a/apps/desktop/src/features/workspace/SectionRoadmap.tsx +++ b/apps/desktop/src/features/workspace/SectionRoadmap.tsx @@ -1,5 +1,5 @@ import type { RehearsalSong, RehearsalRole } from "@bandscope/shared-types"; -import { useMemo } from "react"; +import { useId, useMemo } from "react"; import { createTranslator, detectPreferredLocale } from "../../i18n"; import { ConfidenceBadge } from "./ConfidenceBadge"; import { Card, CardContent, CardHeader } from "@/components/ui/card"; @@ -15,6 +15,7 @@ interface SectionRoadmapProps { /** Documented. */ export function SectionRoadmap({ song, activeRole, onSongUpdate }: SectionRoadmapProps) { + const sectionRoadmapTitleId = useId(); const locale = useMemo(() => detectPreferredLocale(), []); const t = useMemo(() => createTranslator(locale), [locale]); @@ -70,14 +71,19 @@ export function SectionRoadmap({ song, activeRole, onSongUpdate }: SectionRoadma return (
-

+

{t("sectionRoadmapScrollHint")}
-
+
{song.sections.map((section) => (