Skip to content

Fix multiple accessibility icons stacking by implementing inline positioning#1123

Merged
pattonwebz merged 9 commits into
developfrom
copilot/fix-951
Aug 6, 2025
Merged

Fix multiple accessibility icons stacking by implementing inline positioning#1123
pattonwebz merged 9 commits into
developfrom
copilot/fix-951

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Jul 28, 2025

When multiple accessibility issues were detected for the same DOM element, the icon buttons would stack on top of each other, making only the front-most button clickable. This created a poor user experience where users couldn't access all the issues for an element.

Root Cause:
The addTooltip function in src/frontendHighlighterApp/index.js was positioning all tooltips for the same target element at identical coordinates using the computePosition function from floating-ui, causing them to overlap completely.

Solution:
Modified the tooltip positioning logic to:

  1. Track existing tooltips targeting the same element using a data-targetElement attribute
  2. Calculate a horizontal offset based on the number of existing tooltips
  3. Position subsequent tooltips inline with a 5px gap between them

Before: Icons stacked and only the front one was usable
After: Icons appear horizontally inline and all are clickable

The fix maintains all existing functionality while ensuring users can interact with all accessibility issues for any given element.

Multiple accessibility icons now display inline instead of stacked

Fixes #951.

Warning

Firewall rules blocked me from connecting to one or more addresses

I tried to connect to the following addresses, but was blocked by firewall rules:

  • download.cypress.io
    • Triggering command: node index.js --exec install (dns block)
  • https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db
    • Triggering command: /usr/bin/php8.3 -n -c /tmp/f4u4Xf /usr/bin/composer install (http block)
  • https://api.github.com/repos/PHPCSStandards/PHPCSExtra/zipball/fa4b8d051e278072928e32d817456a7fdb57b6ca
    • Triggering command: /usr/bin/php8.3 -n -c /tmp/f4u4Xf /usr/bin/composer install (http block)
  • https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/5b5e3821314f947dd040c70f7992a64eac89025c
    • Triggering command: /usr/bin/php8.3 -n -c /tmp/f4u4Xf /usr/bin/composer install (http block)
  • https://api.github.com/repos/antecedent/patchwork/zipball/1bf183a3e1bd094f231a2128b9ecc5363c269245
    • Triggering command: /usr/bin/php8.3 -n -c /tmp/f4u4Xf /usr/bin/composer install (http block)
  • https://api.github.com/repos/phpstan/phpstan/zipball/3a6e423c076ab39dfedc307e2ac627ef579db162
    • Triggering command: /usr/bin/php8.3 -n -c /tmp/f4u4Xf /usr/bin/composer install (http block)

If you need me to access, download, or install something from one of these locations, you can either:


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Summary by CodeRabbit

  • Bug Fixes
    • Improved tooltip positioning to prevent overlap when multiple tooltips are associated with the same element. Tooltips are now spaced horizontally for better visibility.

Fixes: https://linear.app/equalize-digital/issue/PRO-72/when-an-element-has-multiple-errors-or-warnings-associated-inline-the

Fixes: #951

Copilot AI and others added 2 commits July 28, 2025 20:28
Co-authored-by: pattonwebz <3902039+pattonwebz@users.noreply.github.com>
…tioning

Co-authored-by: pattonwebz <3902039+pattonwebz@users.noreply.github.com>
Copilot AI changed the title [WIP] When an element has multiple errors or warnings associated, inline the icons instead of stacking them. Fix multiple accessibility icons stacking by implementing inline positioning Jul 28, 2025
Copilot AI requested a review from pattonwebz July 28, 2025 20:36
@pattonwebz pattonwebz marked this pull request as ready for review July 28, 2025 21:06
Copilot AI review requested due to automatic review settings July 28, 2025 21:06
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jul 28, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

The update modifies the tooltip positioning logic within the addTooltip method of the AccessibilityCheckerHighlight class. It introduces a mechanism to horizontally offset multiple tooltips for the same target element, preventing overlap by assigning each tooltip an inline position based on its order.

Changes

Cohort / File(s) Change Summary
Tooltip Positioning Enhancement
src/frontendHighlighterApp/index.js
Refactored tooltip logic to detect existing tooltips for a target element, assign a unique data attribute, and horizontally offset each tooltip to display them inline instead of stacked.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant AccessibilityCheckerHighlight
  participant DOM

  User->>AccessibilityCheckerHighlight: Triggers addTooltip(targetElement)
  AccessibilityCheckerHighlight->>DOM: Query for existing tooltips with matching data-target-element
  AccessibilityCheckerHighlight->>AccessibilityCheckerHighlight: Compute tooltipOffset based on count
  AccessibilityCheckerHighlight->>DOM: Create new tooltip with data-target-element attribute
  AccessibilityCheckerHighlight->>DOM: Position tooltip horizontally (left) using offset
  DOM-->>User: Tooltip(s) appear inline, not stacked
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Assessment against linked issues

Objective Addressed Explanation
Inline icons for multiple errors/warnings on the same element instead of stacking them (#951)

Poem

A row of tooltips, neat and bright,
No longer stacked, but side by side in light.
Each warning and error now finds its own space,
Giving users clarity, not a cluttered interface.
🐇✨ With every hop, our code grows right!


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Join our Discord community for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR fixes an accessibility issue where multiple accessibility icons for the same DOM element would stack on top of each other, making only the frontmost icon clickable. The solution implements inline horizontal positioning for multiple tooltips targeting the same element.

  • Modified tooltip positioning logic to track existing tooltips for the same target element
  • Added horizontal offset calculation to position multiple tooltips inline with a 5px gap
  • Maintained existing functionality while ensuring all accessibility issues remain accessible

Comment thread src/frontendHighlighterApp/index.js Outdated
Comment thread src/frontendHighlighterApp/index.js Outdated
Comment thread src/frontendHighlighterApp/index.js Outdated
@pattonwebz
Copy link
Copy Markdown
Member

@copilot tackle the code review comments. Decide yourself if you want to replace the magic number with a named const

Co-authored-by: pattonwebz <3902039+pattonwebz@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Jul 28, 2025

@copilot tackle the code review comments. Decide yourself if you want to replace the magic number with a named const

I've replaced the magic number with a named constant TOOLTIP_GAP = 5 to improve code readability and maintainability. The functionality remains the same - tooltips are positioned inline with a 5px gap between them. Commit: aac9041

Warning

Firewall rules blocked me from connecting to one or more addresses

I tried to connect to the following addresses, but was blocked by firewall rules:

  • download.cypress.io
    • Triggering command: node index.js --exec install (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

pattonwebz and others added 2 commits July 28, 2025 22:19
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@pattonwebz
Copy link
Copy Markdown
Member

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jul 28, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a788e66 and e3b5722.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (1)
  • src/frontendHighlighterApp/index.js (3 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: SteveJonesDev
PR: equalizedigital/accessibility-checker#921
File: src/pageScanner/checks/linked-image-alt-present.js:43-50
Timestamp: 2025-04-15T02:30:38.897Z
Learning: In the Accessibility Checker plugin, accessibility rules are separated by specific concerns. For example, linked images have separate rules for checking: (1) missing alt attributes and (2) empty alt attributes. The rule `linked_image_alt_present` specifically checks for the presence of alt attributes on linked images, while a separate rule `img_linked_alt_empty` handles validation of empty alt attributes. Suggestions should respect this separation of concerns.
Learnt from: pattonwebz
PR: equalizedigital/accessibility-checker#881
File: src/pageScanner/checks/duplicate-form-label-check.js:51-55
Timestamp: 2025-04-08T21:45:57.372Z
Learning: The Accessibility Checker intentionally flags multiple IDs in aria-labelledby as a failure, even though it's technically allowed in the ARIA spec. This design decision was made because multiple IDs can cause confusion with some screen readers, and the tool aims to discourage any form of duplicate labelling to ensure maximum compatibility.
Learnt from: pattonwebz
PR: equalizedigital/accessibility-checker#927
File: src/pageScanner/checks/img-alt-missing-check.js:35-37
Timestamp: 2025-04-18T14:27:18.140Z
Learning: In the Accessibility Checker plugin, the img_alt_missing rule specifically checks for missing alt attributes on images and image inputs, while empty alt attributes are handled by a separate rule. Each accessibility concern is deliberately separated into individual rules.
Learnt from: SteveJonesDev
PR: equalizedigital/accessibility-checker#1088
File: includes/classes/Rules/Rule/VideoPresentRule.php:41-42
Timestamp: 2025-07-18T01:18:27.812Z
Learning: In the Accessibility Checker plugin, the 'wcag' field can use custom values like '0.3' to represent best practice rules and manual testing requirements that don't map directly to specific WCAG success criteria but are still important for accessibility compliance.
Learnt from: SteveJonesDev
PR: equalizedigital/accessibility-checker#1088
File: includes/classes/Rules/Rule/EmptyParagraphTagRule.php:50-50
Timestamp: 2025-07-18T01:29:35.548Z
Learning: In the Accessibility Checker plugin, the 'wcag' field can use custom values like '0.1' to represent best practice rules and manual testing requirements that don't map directly to specific WCAG success criteria but are still important for accessibility compliance.
Learnt from: pattonwebz
PR: equalizedigital/accessibility-checker#927
File: src/pageScanner/checks/img-alt-missing-check.js:32-32
Timestamp: 2025-04-18T14:27:49.512Z
Learning: In the Accessibility Checker plugin, the img_alt_missing rule specifically checks for missing alt attributes (whether the attribute exists at all), while empty alt attributes (alt="") are handled by a separate rule. This separation of concerns is by design.
src/frontendHighlighterApp/index.js (1)

Learnt from: pattonwebz
PR: #927
File: src/pageScanner/checks/img-alt-missing-check.js:97-99
Timestamp: 2025-04-18T14:26:19.552Z
Learning: The minimum length check of > 5 characters for caption text in hasValidCaption() is intentional and should be preserved to maintain consistency with the original PHP implementation and to encourage more descriptive captions.

🪛 GitHub Actions: Lint JS
src/frontendHighlighterApp/index.js

[error] 349-349: ESLint: 'hashString' is not defined (no-undef)


[error] 349-349: ESLint: There must be a space after this paren (space-in-parens)


[error] 349-349: ESLint: There must be a space before this paren (space-in-parens)

🔇 Additional comments (2)
src/frontendHighlighterApp/index.js (2)

305-306: Good improvement with the named constant.

Extracting the magic number 5 to TOOLTIP_GAP constant improves maintainability and addresses the previous review feedback. The offset calculation logic is sound, but it depends on the tooltip detection logic working correctly (see previous comment).


319-319: LGTM! Correct horizontal positioning calculation.

The formula tooltipOffset * (tooltipWidth + TOOLTIP_GAP) correctly implements the horizontal inline positioning by spacing each tooltip by its width plus the defined gap.

Comment thread src/frontendHighlighterApp/index.js Outdated
Comment thread src/frontendHighlighterApp/index.js Outdated
This function computes a hash value from a given string, ensuring a positive result.
Updated the tooltip positioning logic to ensure that tooltips created before the current one are considered when calculating their position.
@pattonwebz
Copy link
Copy Markdown
Member

After a little tweaking, this is working

Peek.2025-07-28.22-54.mp4

@pattonwebz pattonwebz requested a review from SteveJonesDev July 28, 2025 21:58
Copy link
Copy Markdown
Member

@pattonwebz pattonwebz left a comment

Choose a reason for hiding this comment

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

This worked when I tested it

@pattonwebz pattonwebz added this to the v1.30.0 milestone Aug 4, 2025
Copy link
Copy Markdown
Member

@SteveJonesDev SteveJonesDev left a comment

Choose a reason for hiding this comment

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

This seems like a pretty smart fix. Approved.

@pattonwebz pattonwebz merged commit 0769ffa into develop Aug 6, 2025
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

When an element has multiple errors or warnings associated, inline the icons instead of stacking them.

4 participants