Skip to content

Commit 8c2b974

Browse files
authored
fix(Alert): honour explicit role={undefined} to suppress role attribute (#490)
* 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 * 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.
1 parent 3590215 commit 8c2b974

1 file changed

Lines changed: 6 additions & 5 deletions

File tree

src/Alert.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,14 @@ export const Alert = memo(
7474
closable: isClosableByUser = false,
7575
isClosed: props_isClosed,
7676
onClose,
77-
role = "alert",
77+
role: roleFromProps,
7878
...rest
7979
} = props;
8080

81+
// Honour explicit `role={undefined}` to opt out of the role attribute (RGAA 8.7).
82+
// When role is omitted entirely, default to "alert" for screen reader announcements.
83+
const role = "role" in props ? roleFromProps : ("alert" as const);
84+
8185
assert<Equals<keyof typeof rest, never>>();
8286

8387
const id = useAnalyticsId({
@@ -90,7 +94,6 @@ export const Alert = memo(
9094
const [buttonElement, setButtonElement] = useState<HTMLButtonElement | null>(null);
9195

9296
const refShouldButtonGetFocus = useRef(false);
93-
const refShouldSetRole = useRef(false);
9497
const DescriptionTag = typeof description === "string" ? "p" : "div";
9598

9699
useEffect(() => {
@@ -100,7 +103,6 @@ export const Alert = memo(
100103
setIsClosed(isClosed => {
101104
if (isClosed && !props_isClosed) {
102105
refShouldButtonGetFocus.current = true;
103-
refShouldSetRole.current = true;
104106
}
105107

106108
return props_isClosed;
@@ -147,8 +149,7 @@ export const Alert = memo(
147149
className
148150
)}
149151
style={style}
150-
{...(refShouldSetRole.current && { "role": role })}
151-
{...(role ? { "role": role } : {})}
152+
{...(role !== undefined ? { "role": role } : {})}
152153
ref={ref}
153154
{...rest}
154155
>

0 commit comments

Comments
 (0)