From 5f0ca355f96b0da33ebe2ab242cdac9cdf75aca5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?=
Date: Sun, 28 Jun 2026 18:25:43 +0200
Subject: [PATCH] fix(mental-health): a11y on the check-in result and option
controls
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
On submit the form (and its submit button) unmounts, dropping focus to the
body — move focus to the result heading so keyboard/AT users land on the new
content. Announce the item-9 crisis-resource card via role="alert" so a
screen-reader user hears the resources. Bump the PHQ/GAD scale and
functional-difficulty option buttons to the 44px touch-target floor.
---
.../mental-health/mental-wellbeing.tsx | 31 +++++++++++++++++--
1 file changed, 28 insertions(+), 3 deletions(-)
diff --git a/src/components/mental-health/mental-wellbeing.tsx b/src/components/mental-health/mental-wellbeing.tsx
index 21974aac3..1cd85d9c1 100644
--- a/src/components/mental-health/mental-wellbeing.tsx
+++ b/src/components/mental-health/mental-wellbeing.tsx
@@ -13,7 +13,7 @@
* positive PHQ-9 item-9 the server returns a calm, locale-aware crisis-resource
* set which is rendered immediately below the result.
*/
-import { useMemo, useState } from "react";
+import { useEffect, useMemo, useRef, useState } from "react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useTranslations, useFormatters } from "@/lib/i18n/context";
@@ -63,6 +63,16 @@ export function MentalWellbeing() {
const [functional, setFunctional] = useState(null);
const [result, setResult] = useState(null);
+ // a11y: on submit the form (incl. the submit button) unmounts and `phase`
+ // flips to "result". Move focus to the result heading so keyboard / screen-
+ // reader users are not dropped to `` and land on the new content.
+ const resultHeadingRef = useRef(null);
+ useEffect(() => {
+ if (phase === "result") {
+ resultHeadingRef.current?.focus();
+ }
+ }, [phase]);
+
const lower = (id: InstrumentId) => (id === "PHQ9" ? "phq9" : "gad7");
const { data: history } = useQuery({
@@ -191,6 +201,9 @@ export function MentalWellbeing() {
key={v}
type="button"
size="sm"
+ // 44px touch-target floor (WCAG 2.5.5) — these are the
+ // questionnaire option controls a full PHQ-9 taps 36 times.
+ className="min-h-11"
variant={items[i] === v ? "default" : "outline"}
aria-pressed={items[i] === v}
onClick={() =>
@@ -221,6 +234,8 @@ export function MentalWellbeing() {
key={v}
type="button"
size="sm"
+ // 44px touch-target floor (WCAG 2.5.5), matching the scale.
+ className="min-h-11"
variant={functional === v ? "default" : "outline"}
aria-pressed={functional === v}
onClick={() => setFunctional(v)}
@@ -251,7 +266,13 @@ export function MentalWellbeing() {
- {t("mentalHealth.result.title")}
+
+ {t("mentalHealth.result.title")}
+
@@ -281,7 +302,11 @@ export function MentalWellbeing() {
{result.crisis && (
-
+
{t("mentalHealth.crisis.title")}