Skip to content

fix(web): avoid legacy dropdown id collisions#1958

Merged
elibosley merged 1 commit intomainfrom
codex/dropdown-id-compat
Mar 24, 2026
Merged

fix(web): avoid legacy dropdown id collisions#1958
elibosley merged 1 commit intomainfrom
codex/dropdown-id-compat

Conversation

@elibosley
Copy link
Member

@elibosley elibosley commented Mar 24, 2026

Summary

  • add a small compatibility shim that rewrites dropdown-related ids and ARIA references away from the legacy dropdown- segment
  • enable the shim during unified app mounting so dynamically added menu nodes are sanitized too
  • add a regression test covering the id and ARIA rewrites

Root Cause

Some legacy Unraid plugins target DOM ids containing dropdown-. Our Reka dropdown markup uses ids like reka-dropdown-menu-*, which lets those plugins accidentally hide the Connect menu immediately after it renders.

Testing

  • pnpm test test/components/Wrapper/mount-engine.test.ts

Summary by CodeRabbit

  • Bug Fixes
    • Dropdown menu ID attributes are now automatically normalized to ensure proper element relationships and maintain accessibility standards.

- Purpose: prevent legacy Unraid plugins from breaking the Connect hamburger/user-profile dropdown.

- Before: Reka generated ids containing dropdown-, which matched over-broad legacy plugin selectors and caused the menu to be hidden immediately.

- Problem: users with plugins like ZFS Master installed could not reliably open the dropdown menu in Connect.

- Now: dropdown ids and related ARIA references are normalized away from the conflicting dropdown- segment before those plugins can target them.

- How: mountUnifiedApp enables a small DOM compatibility observer and the web test covers id + ARIA rewriting behavior.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 24, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: d61fe73e-aa62-4a73-861c-ac06fcd7c8b5

📥 Commits

Reviewing files that changed from the base of the PR and between 0e004a7 and c54299c.

📒 Files selected for processing (3)
  • web/__test__/components/Wrapper/mount-engine.test.ts
  • web/src/components/Wrapper/mount-engine.ts
  • web/src/utils/dropdownIdCompatibility.ts

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.


Walkthrough

This change implements backwards compatibility for dropdown menu element IDs by automatically sanitizing legacy reka-dropdown-menu-* format identifiers to reka-menu-* format. The sanitization applies to element id, aria-controls, and aria-labelledby attributes both on initial document load and for dynamically added/modified DOM elements.

Changes

Cohort / File(s) Summary
Dropdown ID Compatibility Utility
web/src/utils/dropdownIdCompatibility.ts
New module providing enableDropdownIdCompatibility() function that sanitizes dropdown-prefixed IDs to menu-prefixed equivalents. Includes initial document sanitization and a MutationObserver to handle dynamic attribute and node changes.
Mount Engine Integration
web/src/components/Wrapper/mount-engine.ts
Invokes enableDropdownIdCompatibility() at the start of mountUnifiedApp() to ensure ID sanitization occurs before component mounting.
Mount Engine Tests
web/__test__/components/Wrapper/mount-engine.test.ts
Added test case validating that legacy reka-dropdown-menu-* IDs and their related ARIA attributes are correctly sanitized to reka-menu-* format after mounting.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 The dropdown IDs once conflicted and clashed,
But now we sanitize, keeping attributes matched!
From dropdown to menu, the migration runs smooth,
With observers watching, we've got the right groove. ✨

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/dropdown-id-compat

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c54299cbfc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +17 to +21
if (!value || !value.includes(CONFLICTING_ID_SEGMENT)) {
return;
}

element.setAttribute(attributeName, normalizeValue(value));

Choose a reason for hiding this comment

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

P1 Badge Scope ID sanitization to Reka dropdown IDs only

The new sanitizer rewrites every id, aria-controls, and aria-labelledby value that contains dropdown-, not just Reka’s reka-dropdown-menu-* IDs. Since mountUnifiedApp() enables this observer for the entire document, unrelated elements can have their IDs mutated (for example plugin DOM with id="...dropdown-..."), while other references like for, href="#...", or JS selectors are left unchanged, causing broken label associations and selector lookups. This should be constrained to the specific Reka dropdown ID patterns to avoid global DOM breakage.

Useful? React with 👍 / 👎.

@codecov
Copy link

codecov bot commented Mar 24, 2026

Codecov Report

❌ Patch coverage is 88.23529% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 51.77%. Comparing base (0e004a7) to head (c54299c).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
web/src/utils/dropdownIdCompatibility.ts 87.87% 8 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1958      +/-   ##
==========================================
+ Coverage   51.74%   51.77%   +0.02%     
==========================================
  Files        1028     1029       +1     
  Lines       70792    70860      +68     
  Branches     7881     7897      +16     
==========================================
+ Hits        36630    36686      +56     
- Misses      34039    34051      +12     
  Partials      123      123              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions
Copy link
Contributor

This plugin has been deployed to Cloudflare R2 and is available for testing.
Download it at this URL:

https://preview.dl.unraid.net/unraid-api/tag/PR1958/dynamix.unraid.net.plg

@elibosley elibosley merged commit 98d37bb into main Mar 24, 2026
12 of 13 checks passed
@elibosley elibosley deleted the codex/dropdown-id-compat branch March 24, 2026 17:57
elibosley added a commit that referenced this pull request Mar 25, 2026
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.

1 participant