Skip to content

fix(template-no-nested-interactive): More useful error message#2772

Merged
NullVoxPopuli merged 3 commits intoember-cli:masterfrom
johanrd:fix/nested-interactive-message-context
Apr 30, 2026
Merged

fix(template-no-nested-interactive): More useful error message#2772
NullVoxPopuli merged 3 commits intoember-cli:masterfrom
johanrd:fix/nested-interactive-message-context

Conversation

@johanrd
Copy link
Copy Markdown
Contributor

@johanrd johanrd commented Apr 30, 2026

Summary

The current template-no-nested-interactive error message gives only the bare tag of each side:

Do not nest interactive element <button> inside <div>.

When the parent is a <div> (or <span>, etc.) the message hides why it was classified as interactive — authors have to inspect the rule source or work backwards from INTERACTIVE_ROLES / isHtmlInteractiveContent to figure out that role, contenteditable, or tabindex triggered the rule.

This PR makes the message name the disambiguating attribute when the bare tag would be uninformative:

Do not nest interactive element <button> inside <div role="menu">.
Do not nest interactive element <input> inside <div contenteditable>.
Do not nest interactive element <div tabindex="1"> inside <button>.
Do not nest interactive element <div role="button"> inside <button>.

Self-explanatory native interactive tags (button, input, a, label, select, textarea, details, summary, embed, iframe, audio[controls], video[controls], img[usemap], canvas, object[usemap]) keep their bare-tag form, since the tag itself already conveys interactivity. Applied symmetrically on both the parent and child sides.

The change is purely diagnostic — no rule firing/non-firing decisions are altered.

Implementation

  • New describeInteractive(node) helper at module scope. Surfaces:
    • role="X" when X is in INTERACTIVE_ROLES
    • contenteditable (and contenteditable="plaintext-only" when that exact spec keyword is used; '' / 'true' / bare attribute collapse to contenteditable)
    • tabindex="X" when interactivity comes from tabindex on a tag that isn't otherwise interactive
  • Stored as describe on each interactiveStack entry at push time, used as data.parent.
  • Computed fresh for the child at report time, used as data.child.

Test impact

  • 99 existing tests pass.
  • One existing message assertion updated (<button><div tabindex="1"></div></button> → child now says <div tabindex="1"> instead of <div>).
  • New invalid cases added covering role="menu" parent (regression test for the original report), contenteditable parent, contenteditable="plaintext-only" parent, and role="button" child enrichment.

Test plan

  • pnpm exec vitest run tests/lib/rules/template-no-nested-interactive.js — 99/99 pass
  • Verified MDN-canonical menu pattern (<ul role="menu"><li role="presentation"><a role="menuitem" href>) still passes the rule
  • Verified <li role="menuitem"><button> correctly fires with the new message naming the parent's role

johanrd added 3 commits April 30, 2026 17:29
… error message

The error said "Do not nest interactive element <button> inside <div>." which
hides why the rule fired — authors had to inspect the rule source to find
that role/contenteditable/tabindex on the parent or child was the trigger.

Now the message names the disambiguating attribute when the bare tag would
be uninformative:

  Do not nest interactive element <button> inside <div role="menu">.
  Do not nest interactive element <input> inside <div contenteditable>.
  Do not nest interactive element <div tabindex="1"> inside <button>.

Self-explanatory native interactive tags (button, input, a, etc.) keep
their bare-tag form to avoid redundant noise. Applied symmetrically to
both parent and child sides.
@johanrd johanrd changed the title fix(template-no-nested-interactive): surface triggering attribute in error message fix(template-no-nested-interactive): More useful error message Apr 30, 2026
@NullVoxPopuli NullVoxPopuli merged commit b8acaa9 into ember-cli:master Apr 30, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants