-
From 7d323815d9bc68e6f4162d69701d754f0e42e450 Mon Sep 17 00:00:00 2001
From: Jan Maarten <83665577+janmaarten-a11y@users.noreply.github.com>
Date: Fri, 29 May 2026 17:29:32 -0700
Subject: [PATCH 2/3] Prevent role="list" from being overridden by consumers
Move role="list" after the props spread so it cannot be overridden, and
omit role from TimelineProps to prevent passing it at the type level.
Matches the pattern used for Timeline.Break's role="presentation".
---
packages/react/src/Timeline/Timeline.tsx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/packages/react/src/Timeline/Timeline.tsx b/packages/react/src/Timeline/Timeline.tsx
index c8096d112a1..ec3c0cec6cb 100644
--- a/packages/react/src/Timeline/Timeline.tsx
+++ b/packages/react/src/Timeline/Timeline.tsx
@@ -4,7 +4,7 @@ import classes from './Timeline.module.css'
type StyledTimelineProps = {clipSidebar?: boolean | 'start' | 'end' | 'both'; className?: string}
-export type TimelineProps = StyledTimelineProps & React.ComponentPropsWithoutRef<'ol'>
+export type TimelineProps = StyledTimelineProps & Omit
, 'role'>
function resolveClipSidebar(clipSidebar: TimelineProps['clipSidebar']): string | undefined {
if (clipSidebar === true || clipSidebar === 'both') return 'both'
@@ -16,10 +16,10 @@ const Timeline = React.forwardRef(({clipSidebar
const resolvedClipSidebar = resolveClipSidebar(clipSidebar)
return (
Date: Fri, 29 May 2026 17:44:24 -0700
Subject: [PATCH 3/3] Suppress jsx-a11y/no-redundant-roles for role=list
The rule flags role="list" on as redundant, but it is required to
restore list semantics in Safari/VoiceOver when list-style: none is
applied.
---
packages/react/src/Timeline/Timeline.tsx | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/packages/react/src/Timeline/Timeline.tsx b/packages/react/src/Timeline/Timeline.tsx
index ec3c0cec6cb..a6dd97dd062 100644
--- a/packages/react/src/Timeline/Timeline.tsx
+++ b/packages/react/src/Timeline/Timeline.tsx
@@ -15,10 +15,11 @@ function resolveClipSidebar(clipSidebar: TimelineProps['clipSidebar']): string |
const Timeline = React.forwardRef(({clipSidebar, className, ...props}, forwardRef) => {
const resolvedClipSidebar = resolveClipSidebar(clipSidebar)
return (
+ // Explicit role restores list semantics in Safari/VoiceOver, which strips
+ // them when list-style: none is applied (WebKit intentional behaviour).
+ // eslint-disable-next-line jsx-a11y/no-redundant-roles