Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions frontend/src/components/MetricsPDFButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ const MetricsPDFButton: FC<{
closeDelay={100}
showArrow
>
<FontAwesomeIcon
icon={faFileArrowDown}
className="ml-2 h-7 w-7 cursor-pointer text-gray-500 transition-colors duration-200 hover:text-gray-700"
<button
type="button"
onClick={async () => await fetchMetricsPDF(path, fileName)}
/>
className="ml-2 cursor-pointer text-gray-500 transition-colors duration-200 hover:text-gray-700"
aria-label="Download metrics as PDF"
>
<FontAwesomeIcon icon={faFileArrowDown} className="h-7 w-7" aria-hidden="true" />
</button>
</Tooltip>
)
}
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/components/NavDropDown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export default function NavDropdown({ link, pathname }: NavDropDownProps) {
<button
className="flex cursor-pointer items-center gap-2 whitespace-nowrap"
onClick={() => setIsOpen((prev) => !prev)}
aria-label={`${link.text} menu`}
aria-expanded={isOpen}
aria-haspopup="true"
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The aria-haspopup value should be "menu" to match the role="menu" on the dropdown container. Currently it's set to "true" which is equivalent to "menu", but using the explicit string value improves clarity and follows ARIA best practices.

Suggested change
aria-haspopup="true"
aria-haspopup="menu"

Copilot uses AI. Check for mistakes.
aria-controls={dropdownId}
Expand All @@ -65,13 +66,15 @@ export default function NavDropdown({ link, pathname }: NavDropDownProps) {
</button>
{isOpen && (
<div
role="menu"
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The menu items inside the role="menu" container should have role="menuitem" to properly implement the ARIA menu pattern. Without this, screen readers won't correctly identify these as menu items.

Copilot uses AI. Check for mistakes.
id={dropdownId}
className="absolute top-full left-0 z-10 mt-1 w-48 overflow-hidden rounded-md bg-white shadow-lg dark:bg-slate-800"
>
{link.submenu.map((submenu, idx) => (
<Link
key={`${submenu.href}-${idx}`}
href={submenu.href || '/'}
aria-current={pathname === submenu.href ? 'page' : undefined}
className={cn(
'block w-full px-4 py-2 text-left text-sm transition-colors',
pathname === submenu.href
Expand Down
7 changes: 3 additions & 4 deletions frontend/src/components/Pagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const Pagination: React.FC<PaginationProps> = ({
if (!isLoaded || totalPages <= 1) return null

return (
<div className="mt-8 flex flex-col items-center justify-center gap-3">
<nav className="mt-8 flex flex-col items-center justify-center gap-3" aria-label="Pagination">
<div className="flex flex-wrap items-center justify-center gap-2">
<Button
type="button"
Expand All @@ -74,10 +74,9 @@ const Pagination: React.FC<PaginationProps> = ({
{number === '...' ? (
<span
className="flex h-10 w-10 items-center justify-center text-gray-600 dark:text-gray-400"
role="presentation"
aria-label="More pages"
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ellipsis span has an aria-label but the icon inside is marked aria-hidden="true". This creates a conflict where screen readers will announce "More pages" but the visual content is hidden from assistive technology. Since the ellipsis is purely decorative and doesn't provide navigation, the entire span should be marked with aria-hidden="true" instead of having an aria-label.

Suggested change
aria-label="More pages"
aria-hidden="true"

Copilot uses AI. Check for mistakes.
>
<FontAwesomeIcon icon={faEllipsisH} className="h-5 w-5"></FontAwesomeIcon>
<FontAwesomeIcon icon={faEllipsisH} className="h-5 w-5" aria-hidden="true" />
</span>
) : (
<Button
Expand Down Expand Up @@ -106,7 +105,7 @@ const Pagination: React.FC<PaginationProps> = ({
Next
</Button>
</div>
</div>
</nav>
)
}

Expand Down
6 changes: 4 additions & 2 deletions frontend/src/components/ScrollToTop.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@ export default function ScrollToTop() {
<button
type="button"
onClick={scrollToTop}
aria-label="Scroll to top"
aria-label="Scroll to top of page"
aria-hidden={!isVisible}
tabIndex={isVisible ? 0 : -1}
className={`bg-owasp-blue/70 hover:bg-owasp-blue dark:bg-owasp-blue/30 hover:dark:bg-owasp-blue/50 fixed right-4 bottom-4 z-50 flex h-11 w-11 items-center justify-center rounded-full text-white shadow-lg transition-all duration-400 hover:scale-105 active:scale-100 dark:text-slate-300 ${isVisible ? 'pointer-events-auto opacity-100' : 'pointer-events-none opacity-0'} `}
>
<FontAwesomeIcon icon={faArrowUp} className="text-xl" />
<FontAwesomeIcon icon={faArrowUp} className="text-xl" aria-hidden="true" />
</button>
)
}
8 changes: 6 additions & 2 deletions frontend/src/components/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,30 +68,34 @@ const SearchBar: React.FC<SearchProps> = ({
}

return (
<div className="w-full max-w-md p-4">
<div className="w-full max-w-md p-4" role="search">
<div className="relative">
{!isLoaded ? (
<>
<FontAwesomeIcon
icon={faSearch}
className="pointer-events-none absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-gray-400"
aria-hidden="true"
/>
<input
ref={inputRef}
type="text"
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The input type should be "search" for semantic HTML, not "text". The HTML specification defines the search input type which provides better semantics for assistive technologies.

Suggested change
type="text"
type="search"

Copilot uses AI. Check for mistakes.
aria-label="search"
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The aria-label should start with a capital letter and be more descriptive to match the standard pattern. Consider using "Search" instead of "search" for consistency with other ARIA labels in the codebase.

Suggested change
aria-label="search"
aria-label="Search"

Copilot uses AI. Check for mistakes.
aria-describedby={searchQuery ? 'search-clear-button' : undefined}
value={searchQuery}
onChange={handleSearchChange}
placeholder={placeholder}
className="h-12 w-full rounded-lg border-1 border-gray-300 pr-10 pl-10 text-lg text-black focus:border-blue-500 focus:ring-2 focus:ring-blue-500 focus:outline-hidden dark:border-gray-600 dark:bg-gray-800 dark:text-white dark:focus:border-blue-300 dark:focus:ring-blue-300"
/>
{searchQuery && (
<button
id="search-clear-button"
type="button"
className="absolute top-1/2 right-2 -translate-y-1/2 rounded-full p-1 hover:bg-gray-100 focus:ring-2 focus:ring-gray-300 focus:outline-hidden"
onClick={handleClearSearch}
aria-label="Clear search"
>
<FontAwesomeIcon icon={faTimes} />
<FontAwesomeIcon icon={faTimes} aria-hidden="true" />
</button>
)}
</>
Expand Down