feat(accessibility): enhance roadmap components with collapsible functionality and accessibility improvements#5286
Conversation
…tionality and accessibility improvements
✅ Deploy Preview for asyncapi-website ready!Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify project configuration. |
📝 WalkthroughWalkthroughThe roadmap component's collapsibility logic is enhanced to recognize both solutions and implementations, with a unified collapsible container. The pill component's title rendering is refactored to support distinct rendering paths for URLs, descriptions, and non-interactive states. Accessibility attributes (aria-controls, aria-expanded, aria-label) are added to the collapse button, and React preset support is added to the Babel test configuration. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #5286 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 22 22
Lines 796 830 +34
Branches 146 159 +13
=========================================
+ Hits 796 830 +34 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
⚡️ Lighthouse report for the changes in this PR:
Lighthouse ran on https://deploy-preview-5286--asyncapi-website.netlify.app/ |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
tests/roadmap/accessibility.test.tsx (1)
26-61: Add a regression test for implementation-only items.The production change now treats
implementationsas collapsible content too, but this suite only exercises thesolutionspath. A sibling test with onlyimplementationswould lock in the new branch this PR added.Suggested test
+ test('connects implementation-only roadmap items to controlled content', () => { + const markup = renderToStaticMarkup( + <RoadmapItem + item={{ + title: 'Implementation-only roadmap item', + implementations: [{ title: 'Nested implementation' }] + }} + colorClass='bg-blue-400' + /> + ); + + const controlsMatch = markup.match(/aria-controls="([^"]+)"/); + + expect(controlsMatch).not.toBeNull(); + expect(markup).toContain('aria-expanded="false"'); + expect(markup).toContain(`id="${controlsMatch?.[1]}"`); + expect(markup).toContain('aria-label="Expand Implementation-only roadmap item"'); + expect(markup).toContain('hidden=""'); + });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/roadmap/accessibility.test.tsx` around lines 26 - 61, Add a sibling regression test that mirrors the existing "connects collapsible roadmap items to controlled content" and "marks collapsible roadmap items as expanded when children are visible" tests but uses an item with implementations instead of solutions to exercise the new branch; render RoadmapItem with item={{ title: '...', implementations: [{ title: 'Impl child' }] }} and the same colorClass and assertions: check aria-controls exists and the matched id is present, aria-expanded="false" and aria-label="Expand <title>" and hidden="" for the collapsed case, and for the expanded case render with collapsed={false} and assert aria-expanded="true", aria-label="Collapse <title>" and that the implementation child text ("Impl child") is present.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@components/roadmap/RoadmapItem.tsx`:
- Around line 29-30: The collapsible control is enabled when solutions or
implementations fields exist even if they are empty; change the logic in the
isCollapsible computation to check actual child counts (e.g., use
item.solutions?.length and item.implementations?.length) so isCollapsible is
true only when the total number of children > 0, and apply the same count-based
check where the collapse control and content rendering are handled (referencing
isCollapsible, collapsibleContentId and the render block around lines 53-61) so
the toggle is not shown for empty lists.
In `@components/roadmap/RoadmapPill.tsx`:
- Line 77: The non-interactive fallback assigns titleElement to a plain span
with item.title, which loses the completed/checkmark rendering built by
titleContent; update the fallback so it uses the same construction as
titleContent (or delegate to titleContent) when item.done is true so the done
icon/checkmark remains visible for completed items—look for titleElement,
titleContent and the item.done logic in the RoadmapPill component and ensure the
fallback path composes the done state the same way as the primary titleContent.
---
Nitpick comments:
In `@tests/roadmap/accessibility.test.tsx`:
- Around line 26-61: Add a sibling regression test that mirrors the existing
"connects collapsible roadmap items to controlled content" and "marks
collapsible roadmap items as expanded when children are visible" tests but uses
an item with implementations instead of solutions to exercise the new branch;
render RoadmapItem with item={{ title: '...', implementations: [{ title: 'Impl
child' }] }} and the same colorClass and assertions: check aria-controls exists
and the matched id is present, aria-expanded="false" and aria-label="Expand
<title>" and hidden="" for the collapsed case, and for the expanded case render
with collapsed={false} and assert aria-expanded="true", aria-label="Collapse
<title>" and that the implementation child text ("Impl child") is present.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 5eb37f6c-cf5a-40da-9bca-f20b27fd3a41
📒 Files selected for processing (4)
components/roadmap/RoadmapItem.tsxcomponents/roadmap/RoadmapPill.tsxtests/babel.test.config.ctstests/roadmap/accessibility.test.tsx
| const isCollapsible = item.solutions !== undefined || item.implementations !== undefined; | ||
| const collapsibleContentId = useId(); |
There was a problem hiding this comment.
Base collapsibility on child count, not just field presence.
solutions: [] or implementations: [] currently marks the item as collapsible, but the child lists only render when .length is truthy. That leaves an expand/collapse control wired to an empty container.
Suggested fix
- const isCollapsible = item.solutions !== undefined || item.implementations !== undefined;
+ const hasSolutions = (item.solutions?.length ?? 0) > 0;
+ const hasImplementations = (item.implementations?.length ?? 0) > 0;
+ const isCollapsible = hasSolutions || hasImplementations;
const collapsibleContentId = useId();
@@
- {!isCollapsed && item?.solutions?.length && (
+ {!isCollapsed && hasSolutions && (
<RoadmapList className='ml-2 pt-3' colorClass='bg-blue-400' items={item.solutions} collapsed={false} />
)}
- {!isCollapsed && item?.implementations?.length && (
+ {!isCollapsed && hasImplementations && (
<RoadmapList className='ml-9 pt-3' colorClass='bg-black' items={item.implementations} collapsed={false} />
)}Also applies to: 53-61
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@components/roadmap/RoadmapItem.tsx` around lines 29 - 30, The collapsible
control is enabled when solutions or implementations fields exist even if they
are empty; change the logic in the isCollapsible computation to check actual
child counts (e.g., use item.solutions?.length and item.implementations?.length)
so isCollapsible is true only when the total number of children > 0, and apply
the same count-based check where the collapse control and content rendering are
handled (referencing isCollapsible, collapsibleContentId and the render block
around lines 53-61) so the toggle is not shown for empty lists.
| </> | ||
| ); | ||
|
|
||
| let titleElement = <span className='block text-left font-medium text-gray-900'>{item.title}</span>; |
There was a problem hiding this comment.
Keep the done icon in the non-interactive title path.
The fallback branch renders only item.title, so completed pills without a URL or description no longer show the checkmark that titleContent already builds. That’s a visible regression for done roadmap items.
Suggested fix
- let titleElement = <span className='block text-left font-medium text-gray-900'>{item.title}</span>;
+ let titleElement = <span className='block text-left font-medium text-gray-900'>{titleContent}</span>;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@components/roadmap/RoadmapPill.tsx` at line 77, The non-interactive fallback
assigns titleElement to a plain span with item.title, which loses the
completed/checkmark rendering built by titleContent; update the fallback so it
uses the same construction as titleContent (or delegate to titleContent) when
item.done is true so the done icon/checkmark remains visible for completed
items—look for titleElement, titleContent and the item.done logic in the
RoadmapPill component and ensure the fallback path composes the done state the
same way as the primary titleContent.



Description
This improves accessibility on the /roadmap page by making roadmap items work better with keyboard navigation and screen readers.
Changes made:
Replaced description-trigger interactions with proper elements where needed
Added visible keyboard focus styles for interactive roadmap controls
Added ARIA support for expandable roadmap items with aria-expanded, aria-controls, and accessible labels
Wired collapsible roadmap sections to stable IDs using useId()
Added tests to verify the accessibility markup for roadmap interactions
Related issue(s)
#5101
test

Summary by CodeRabbit
New Features
Improvements
Tests