From 7f14e03b587a7a8f743b040d0f0a1c149ee03560 Mon Sep 17 00:00:00 2001 From: jrlprost Date: Tue, 19 May 2026 11:31:12 +0200 Subject: [PATCH 1/2] fix(Alert): honour explicit role={undefined} to suppress role attribute When role={undefined} is passed, the component was still rendering role="alert" because the destructuring default applies to undefined values unconditionally. Fix: remove the default from the destructuring and use "role" in props to distinguish "caller did not pass role" (default to "alert") from "caller explicitly passed undefined" (no role attribute rendered). Fixes #478 --- src/Alert.tsx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Alert.tsx b/src/Alert.tsx index dade456bf..f71d6a0aa 100644 --- a/src/Alert.tsx +++ b/src/Alert.tsx @@ -74,10 +74,14 @@ export const Alert = memo( closable: isClosableByUser = false, isClosed: props_isClosed, onClose, - role = "alert", + role: roleFromProps, ...rest } = props; + // Honour explicit `role={undefined}` to opt out of the role attribute (RGAA 8.7). + // When role is omitted entirely, default to "alert" for screen reader announcements. + const role = "role" in props ? roleFromProps : ("alert" as const); + assert>(); const id = useAnalyticsId({ @@ -147,8 +151,8 @@ export const Alert = memo( className )} style={style} - {...(refShouldSetRole.current && { "role": role })} - {...(role ? { "role": role } : {})} + {...(refShouldSetRole.current && role !== undefined && { "role": role })} + {...(role !== undefined ? { "role": role } : {})} ref={ref} {...rest} > From 720ddd14ba04ba662cdd256f087db6f5f0e4ecf0 Mon Sep 17 00:00:00 2001 From: jrlprost Date: Wed, 20 May 2026 21:55:37 +0200 Subject: [PATCH 2/2] refactor(Alert): remove redundant role spread and refShouldSetRole ref The first spread was always overridden by the second one: when role !== undefined both spreads set the same value, and when role is undefined neither fires. Drop the dead ref and simplify to a single conditional spread. Addresses review comment from revolunet. --- src/Alert.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Alert.tsx b/src/Alert.tsx index f71d6a0aa..30dfe3b99 100644 --- a/src/Alert.tsx +++ b/src/Alert.tsx @@ -94,7 +94,6 @@ export const Alert = memo( const [buttonElement, setButtonElement] = useState(null); const refShouldButtonGetFocus = useRef(false); - const refShouldSetRole = useRef(false); const DescriptionTag = typeof description === "string" ? "p" : "div"; useEffect(() => { @@ -104,7 +103,6 @@ export const Alert = memo( setIsClosed(isClosed => { if (isClosed && !props_isClosed) { refShouldButtonGetFocus.current = true; - refShouldSetRole.current = true; } return props_isClosed; @@ -151,7 +149,6 @@ export const Alert = memo( className )} style={style} - {...(refShouldSetRole.current && role !== undefined && { "role": role })} {...(role !== undefined ? { "role": role } : {})} ref={ref} {...rest}