Skip to content

Change href-or-on-click ESLint rule to require href with onClick#9615

Open
TamerlanG wants to merge 14 commits into
elastic:mainfrom
TamerlanG:refactor/eui-eslint-rule
Open

Change href-or-on-click ESLint rule to require href with onClick#9615
TamerlanG wants to merge 14 commits into
elastic:mainfrom
TamerlanG:refactor/eui-eslint-rule

Conversation

@TamerlanG
Copy link
Copy Markdown

@TamerlanG TamerlanG commented Apr 27, 2026

Summary

We have cases where we would want both href and onClick, for example cmd-click behavior, collecting telemetry within the onClick, etc...

Changes:

  • Changed the href-or-on-click ESLint rule to warn when onClick is present without href.
  • Previously the rule warned when both href and onClick were supplied; now it encourages always including href alongside onClick so that Cmd+Click / "Open in new tab" works
  • Updated tests to match the new behavior

…esent

Instead of warning when both `href` and `onClick` are supplied,
the rule now warns when `onClick` is used without `href` on
link-like EUI components, encouraging proper link semantics
so that Cmd+Click / "Open in new tab" works.
@TamerlanG TamerlanG requested a review from a team as a code owner April 27, 2026 12:23
Copilot AI review requested due to automatic review settings April 27, 2026 12:23
@TamerlanG TamerlanG assigned TamerlanG and unassigned TamerlanG Apr 27, 2026
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

Updates the href-or-on-click custom ESLint rule in packages/eslint-plugin to encourage link-like EUI components to include an href when an onClick handler is provided, improving expected “open in new tab” behavior.

Changes:

  • Invert rule behavior to report when onClick is present without href (instead of reporting when both are present).
  • Reclassify the rule as a suggestion and update the rule’s documentation/message text accordingly.
  • Update and expand RuleTester cases to match the new expected valid/invalid patterns.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
packages/eslint-plugin/src/rules/href_or_on_click.ts Changes the rule logic to flag onClick without href and updates metadata/message text.
packages/eslint-plugin/src/rules/href_or_on_click.test.ts Updates valid/invalid test cases to reflect the new rule behavior.
Comments suppressed due to low confidence (1)

packages/eslint-plugin/src/rules/href_or_on_click.test.ts:85

  • Given the rule change, consider adding a test case that includes a JSX spread attribute (e.g. <EuiButton {...props} onClick={handleClick} />). If the rule is updated to bail out on spreads (to avoid false positives), this should be a valid case; if not, the test should assert the intended behavior explicitly.
    {
      code: dedent`
        module.export = () => (
          <EuiButtonEmpty href="/" onClick={handleClick} />
        )
      `,
      languageOptions,
    },
    {
      code: dedent`
        module.export = () => (
          <EuiLink href="/home" onClick={handleClick} />
        )
      `,
      languageOptions,
    },
    {
      code: dedent`
        module.export = () => (
          <SomeOtherComponent onClick={handleClick} />
        )
      `,
      languageOptions,
    },

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/eslint-plugin/src/rules/href_or_on_click.ts Outdated
Comment thread packages/eslint-plugin/src/rules/href_or_on_click.ts Outdated
@weronikaolejniczak
Copy link
Copy Markdown
Contributor

@TamerlanG for releasable packages like @elastic/eslint-plugin-eui we need a changelog. You can see the exemplary entries in our CHANGELOG_{YEAR}.md files (without the PR link, that is added automatically). So you'd need to add one in packages/eslint-plugin/changelogs/upcoming. The filename should be 9615.md.

Copy link
Copy Markdown
Contributor

@weronikaolejniczak weronikaolejniczak left a comment

Choose a reason for hiding this comment

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

We should also update README.md accordingly 😄

When props are spread (e.g. `<EuiButton {...linkProps} onClick={fn} />`),
we can't statically know if `href` is provided, so skip reporting to
avoid false positives. Uses the existing `hasSpread` utility.
Replace "Cmd+Click" with "Ctrl/Cmd+Click" and "Open in new tab"
with "Open link in new tab" so the message is accurate on all platforms.
@TamerlanG
Copy link
Copy Markdown
Author

Wait, I just noticed that this affects the buttons and badge too. Let's have this be just for links? I can create a separate rule for that?

wdyt @weronikaolejniczak and @tkajtoch

@weronikaolejniczak
Copy link
Copy Markdown
Contributor

@TamerlanG ah, so for EuiLink (link components) we want both onClick AND href but for EuiButton and EuiBadge that's not necessarily the case? Then yes, I would separate it out into a different rule that's specific for links. We could try to share as much code as possible with this one.

…lick`

Revert `href-or-on-click` to its original behavior (warn when both
`href` and `onClick` are present). Extract the new logic into a
separate `require-href-for-link` rule that only targets EuiLink and
warns when `onClick` is used without `href`.
@TamerlanG
Copy link
Copy Markdown
Author

I still have to add the changelog and update the readme, so lemme do that :)

@TamerlanG
Copy link
Copy Markdown
Author

added updates to readme and change log here: 20768c6

Comment thread packages/eslint-plugin/changelogs/upcoming/9615.md Outdated
Comment thread packages/eslint-plugin/README.md
Comment thread packages/eslint-plugin/src/rules/require_href_for_link.ts Outdated
Copy link
Copy Markdown
Contributor

@weronikaolejniczak weronikaolejniczak left a comment

Choose a reason for hiding this comment

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

I added a couple of nits. The only blocking thing is the changelog entry 😄

TamerlanG and others added 3 commits May 6, 2026 14:30
Co-authored-by: Weronika Olejniczak <32842468+weronikaolejniczak@users.noreply.github.com>
Co-authored-by: Weronika Olejniczak <32842468+weronikaolejniczak@users.noreply.github.com>
Co-authored-by: Weronika Olejniczak <32842468+weronikaolejniczak@users.noreply.github.com>
@elasticmachine
Copy link
Copy Markdown
Collaborator

💚 Build Succeeded

History

@elasticmachine
Copy link
Copy Markdown
Collaborator

💚 Build Succeeded

History

@weronikaolejniczak weronikaolejniczak self-requested a review May 6, 2026 13:42
Copy link
Copy Markdown
Contributor

@weronikaolejniczak weronikaolejniczak left a comment

Choose a reason for hiding this comment

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

I'll approve but as discussed on Slack, we'll merge it only after the next release

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.

4 participants