feat: add keyboard accessibility to TOC toggle#4973
Conversation
There was a problem hiding this comment.
Welcome to AsyncAPI. Thanks a lot for creating your first pull request. Please check out our contributors guide useful for opening a pull request.
Keep in mind there are also other channels you can use to interact with AsyncAPI community. For more details check out this issue.
📝 WalkthroughWalkthroughReplaced a non-semantic clickable container with a semantic Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
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 |
✅ Deploy Preview for asyncapi-website ready!Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
⚡️ Lighthouse report for the changes in this PR:
Lighthouse ran on https://deploy-preview-4973--asyncapi-website.netlify.app/ |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
components/TOC.tsx (1)
28-121: Fix Prettier/ESLint violations blocking CI.The pipeline reports multiple formatter/lint errors in this file (trailing commas, JSX quote style, and line wrapping). Please run the formatter or apply changes like below to unblock CI.
🧹 Proposed formatting fix (representative)
-export default function TOC({ - className, - cssBreakingPoint = 'xl', - toc, - contentSelector, - depth = 2, -}: ITOCProps) { +export default function TOC({ className, cssBreakingPoint = 'xl', toc, contentSelector, depth = 2 }: ITOCProps) { const [open, setOpen] = useState(false); if (!toc || !toc.length) return null; - const minLevel = toc.reduce( - (mLevel, item) => (!mLevel || item.lvl < mLevel ? item.lvl : mLevel), - 0, - ); + const minLevel = toc.reduce((mLevel, item) => (!mLevel || item.lvl < mLevel ? item.lvl : mLevel), 0); const tocItems = toc .filter((item) => item.lvl <= minLevel + depth) .map((item) => ({ ...item, content: item.content - .replace(/[\s]?\{#[\w\d\-_]+\}$/, '') + .replace(/[\s]?\{#[\w\d\-_]+\}$/, '') .replace(/(<([^>]+)>)/gi, ''), // ... - slugWithATag: (() => { + slugWithATag: (() => { // ... - })(), + })(), })); return ( <div className={twMerge( - `${className} ${tocItems.length ? '' : 'hidden'} - ${cssBreakingPoint === 'xl' ? 'xl:block' : 'lg:block'} md:top-24 md:max-h-(screen-14) mb-4 z-20`, + `${className} ${tocItems.length ? '' : 'hidden'} ${cssBreakingPoint === 'xl' ? 'xl:block' : 'lg:block'} md:top-24 md:max-h-(screen-14) mb-4 z-20`, )} > <button className={`flex cursor-pointer ${tocItems.length ? '' : 'hidden'} ${cssBreakingPoint === 'xl' ? 'xl:cursor-auto' : 'lg:cursor-auto'} xl:mt-2`} onClick={() => setOpen(!open)} aria-expanded={open} - aria-label="Toggle table of contents" + aria-label='Toggle table of contents' > <h5 className={twMerge( `${open && 'mb-4'} flex-1 text-primary-500 font-medium uppercase tracking-wide text-sm font-sans antialiased ${ cssBreakingPoint === 'xl' ? 'xl:mb-4 xl:text-xs xl:text-gray-900 xl:font-bold' : 'lg:mb-4 lg:text-xs lg:text-gray-900 lg:font-bold' }`, )} - data-testid="TOC-Heading" + data-testid='TOC-Heading' > On this page </h5> - <div - className={`text-underline p4 text-center ${cssBreakingPoint === 'xl' ? 'xl:hidden' : 'lg:hidden'}`} - > + <div className={`text-underline p4 text-center ${cssBreakingPoint === 'xl' ? 'xl:hidden' : 'lg:hidden'}`}> <ArrowRight className={`${open ? '-rotate-90' : 'rotate-90'} -mt-0.5 h-6 text-primary-500 transition duration-200 ease-in-out`} /> </div> </button> <div - className={`${!open && 'hidden'} ${cssBreakingPoint === 'xl' ? 'xl:block' : 'lg:block'}`} + className={`${!open && 'hidden'} ${cssBreakingPoint === 'xl' ? 'xl:block' : 'lg:block'}`} > <Scrollspy - items={tocItems.map((item) => - item.slug ? item.slug : item.slugWithATag, - )} - currentClassName="text-primary-500 font-bold" - componentTag="div" + items={tocItems.map((item) => (item.slug ? item.slug : item.slugWithATag))} + currentClassName='text-primary-500 font-bold' + componentTag='div' rootEl={contentSelector} offset={-120} > {tocItems.map((item, index) => ( <a className={`pl-${2 ** (item.lvl - 1)} font-normal mb-1 block font-sans text-sm text-gray-900 antialiased transition duration-100 ease-in-out hover:underline`} href={`#${item.slug ? item.slug : item.slugWithATag}`} key={index} - data-testid="TOC-Link" + data-testid='TOC-Link' > {item.content.replaceAll('`', '')} </a> ))}
🤖 Fix all issues with AI agents
In `@components/TOC.tsx`:
- Around line 75-101: The button in TOC.tsx contains non-phrasing elements and
lacks an explicit type; update the toggle to include type="button" and ensure
only phrasing content is inside the button: either move the <h5
data-testid="TOC-Heading">On this page</h5> out of the <button> (placing it
immediately before the button) or replace that <h5> with a <span> for inline
phrasing, and replace the inner <div> used for the ArrowRight icon with a
<span>; keep the existing onClick handler (setOpen), aria attributes, open state
usage, and ArrowRight classNames intact so behavior and styling remain
unchanged.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #4973 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 22 22
Lines 796 796
Branches 146 146
=========================================
Hits 796 796 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
@princerajpoot20 sir can you please have a look |
Description
Fixed keyboard accessibility issue in the TOC component by replacing non-semantic
Added aria-expanded={open} attribute to communicate toggle state to screen readers
Added aria-label Toggle table of contents to provide context for assistive technology users
Moved onClick handler from outer div to the button element for proper semantic structure
Maintained all existing visual styles and responsive behavior
Fixed issue
Fixes #4972
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.