From 21fccb0ecd7ea597d8e4100d7df591cae9dd66ef Mon Sep 17 00:00:00 2001 From: Miranda Limonczenko Date: Fri, 21 Aug 2026 08:48:04 -0700 Subject: [PATCH] fix(www): name the /features page button controls (#49343) Closes FE-4097 https://github.com/user-attachments/assets/bc7cad1a-763e-469f-8a3b-e4d23bed94d9 _See bottom left of screen for screen reader captions._ ## Problem Two controls in the shared `/features/[slug]` template have no accessible name. Both live in the template, so both fire on all 79 feature pages. * The feature list dropdown trigger contains only a `List` icon. `button-name`, critical. * The breadcrumb back chevron wraps only a `ChevronLeft`. `link-name`, serious. ## Solution * Name both with `sr-only` text, matching the sibling prev and next controls in the same component and the theme switcher in the site header. * Label the product pill with its destination. It announced only "vector", with no indication it filters the catalog. Not an axe finding, since the product name already supplies a name. The label keeps the visible word so it satisfies WCAG 2.5.3 Label in Name. * Fix a stray `className="` inside the `iconClassName` string literal, which dropped the icons' width class. * Add `cursor-pointer` to `buttonClassName`. Tailwind 4 no longer sets a pointer cursor on buttons, so the middle control behaved differently from its two anchor siblings. This line belongs to FE-4227 and sits here only to keep two open PRs off adjacent lines of the same file. ## Manual testing 1. Open [/features/ai-integrations](https://zone-www-dot-com-git-www-features-chrome-access-1aef01-supabase.vercel.app/features/ai-integrations) using a Screenreader. 2. Tab through the three round controls at top right. They announce "Previous feature", "Browse all features", "Next feature". **Note:** The order of the elements is strange; captured in a separate ticket. 3. Tab to the round back control at top left. It announces "Back to all features". 4. Tab to the product pill beside it. It announces "All vector features", and the visible word "vector" is unchanged. 5. Hover each of the three round controls. All show a pointer cursor. 6. Run axe on the page. `button-name` and `link-name` report zero elements. Co-authored-by: Claude Opus 5 --- apps/www/components/PrevNextFeatureNav.tsx | 5 +++-- apps/www/pages/features/[slug].tsx | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/www/components/PrevNextFeatureNav.tsx b/apps/www/components/PrevNextFeatureNav.tsx index d5705c49ef2..a70f0242e31 100644 --- a/apps/www/components/PrevNextFeatureNav.tsx +++ b/apps/www/components/PrevNextFeatureNav.tsx @@ -23,8 +23,8 @@ interface Props { } const buttonClassName = - 'relative z-10 flex items-center gap-1 px-2 pointer-events-auto overflow-hidden h-[30px]! min-w-[30px]! max-w-[30px]! py-1 justify-center rounded-full border bg-default hover:bg-surface-100 hover:text-foreground hover:border-foreground-lighter transition-all' -const iconClassName = 'className="w-4 h-4 shrink-0' + 'relative z-10 flex items-center gap-1 px-2 cursor-pointer pointer-events-auto overflow-hidden h-[30px]! min-w-[30px]! max-w-[30px]! py-1 justify-center rounded-full border bg-default hover:bg-surface-100 hover:text-foreground hover:border-foreground-lighter transition-all' +const iconClassName = 'w-4 h-4 shrink-0' const PrevNextFeatureNav: React.FC = ({ className, @@ -69,6 +69,7 @@ const PrevNextFeatureNav: React.FC = ({ + Browse all features diff --git a/apps/www/pages/features/[slug].tsx b/apps/www/pages/features/[slug].tsx index 861850f92a2..b47ffd0b964 100644 --- a/apps/www/pages/features/[slug].tsx +++ b/apps/www/pages/features/[slug].tsx @@ -107,6 +107,7 @@ const FeaturePage: React.FC = ({ feature, prevFeature, nextFea + Back to all features {feature.products.map((product) => ( @@ -114,6 +115,7 @@ const FeaturePage: React.FC = ({ feature, prevFeature, nextFea key={`product-${product}`} href={`/features?products=${product}`} className="inline-flex" + aria-label={`All ${product} features`} passHref >