Skip to content

fix(lint): handle newlines in useVueValidVElse and useVueValidVElseIf#8821

Merged
dyc3 merged 8 commits intobiomejs:mainfrom
playhardgopro:main
Jan 23, 2026
Merged

fix(lint): handle newlines in useVueValidVElse and useVueValidVElseIf#8821
dyc3 merged 8 commits intobiomejs:mainfrom
playhardgopro:main

Conversation

@playhardgopro
Copy link
Contributor

@playhardgopro playhardgopro commented Jan 20, 2026

Important

This PR was generated with the help of Antigravity (Google DeepMind), an AI coding assistant.

Summary

This PR fixes multiple bugs in the Vue conditional rules (useVueValidVIf, useVueValidVElse, and useVueValidVElseIf):

  1. Interspersed whitespace: Fixed false positives when conditional elements are separated by whitespace/newlines. The rules now correctly traverse previous siblings and skip ignorable nodes.
  2. Self-closing tags in v-if: Fixed a bug in useVueValidVIf where it incorrectly identified the containing element for directives on self-closing tags, leading to false positive conflict diagnostics with parent element attributes.
  3. Multiline tag support: Switched to text_trimmed() for directive name comparisons across all rules to ensure directives are correctly identified even when preceded by newlines in multiline tag formatting.

Motivation:
These issues caused incorrect linting errors in standard Vue template patterns, such as documented conditional blocks or nested components using self-closing syntax.

Changes:

  • Updated has_previous_sibling_with_v_if_or_else_if to traverse siblings iteratively, skipping nodes containing only whitespace (using text_trimmed().is_empty()).
  • Refactored find_conflicting_else_directives to check the HtmlAttributeList of the directive's parent directly, supporting both normal and self-closing tags.
  • Standardized directive name checks using text_trimmed().

Test Plan

The fixes are verified using the project's spec test suite with new comprehensive test cases:

  • Added cases to valid.vue for all three rules covering:
    • Multi-line tags.
    • Whitespace between conditional siblings.
    • Nested conditionals using self-closing tags (e.g., <span v-if="cond"/> inside a v-else block).
  • All spec tests pass successfully:
    cargo test -p biome_html_analyze --test spec_tests
  • Updated snapshots reflect the new valid patterns.

Docs

Not applicable as these are bug fixes for existing rules and do not introduce new options.

@changeset-bot
Copy link

changeset-bot bot commented Jan 20, 2026

🦋 Changeset detected

Latest commit: 061a512

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 14 packages
Name Type
@biomejs/biome Patch
@biomejs/cli-win32-x64 Patch
@biomejs/cli-win32-arm64 Patch
@biomejs/cli-darwin-x64 Patch
@biomejs/cli-darwin-arm64 Patch
@biomejs/cli-linux-x64 Patch
@biomejs/cli-linux-arm64 Patch
@biomejs/cli-linux-x64-musl Patch
@biomejs/cli-linux-arm64-musl Patch
@biomejs/wasm-web Patch
@biomejs/wasm-bundler Patch
@biomejs/wasm-nodejs Patch
@biomejs/backend-jsonrpc Patch
@biomejs/prettier-compare Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions bot added A-Linter Area: linter L-HTML Language: HTML and super languages labels Jan 20, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 20, 2026

Walkthrough

Replaces directive name comparisons to use text_trimmed() where directive tokens are inspected, refactors v-if conflict detection to derive conflicts from the directive/attribute context (using HtmlAttributeList) instead of element-based containment, and updates sibling traversal to handle whitespace/newlines and self-closing tags. Adds and updates tests with multiline and nested Vue conditional templates. No public API changes.

Possibly related PRs

Suggested labels

A-Diagnostic

Suggested reviewers

  • dyc3
  • ematipico
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main fix: handling newlines in Vue conditional lint rules, which aligns with the primary changes across useVueValidVElse and useVueValidVElseIf.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, detailing specific bugs fixed, implementation changes, and test coverage across all three rules.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Member

@ematipico ematipico left a comment

Choose a reason for hiding this comment

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

Since you haven't opened an issue, I find it very difficult to understand what we're fixing. You could have shared a playground too.

For example, I believe the comments aren't playing any part in the issue, because I couldn't reproduce the problem with the snapshot you used.

@playhardgopro
Copy link
Contributor Author

playhardgopro commented Jan 21, 2026

Please use the following code snippet:

<template>
	<div>
		<div v-if="condition"></div>
		<div v-else><span v-if="condition2" /></div>

		<div
			v-if="condition"
			data-attr1
			data-attr2
			data-attr3
			data-attr4
			data-attr5
			data-attr6
		/>
		<div v-else></div>
	</div>
</template>

I am also sharing a link to the playground

@playhardgopro playhardgopro changed the title fix(lint): handle newlines and comments in useVueValidVElse and useVueValidVElseIf fix(lint): handle newlines in useVueValidVElse and useVueValidVElseIf Jan 21, 2026
Copy link
Contributor

@dyc3 dyc3 left a comment

Choose a reason for hiding this comment

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

I don't think that sample you posted is in any of your new snapshot tests.

@playhardgopro playhardgopro requested a review from dyc3 January 23, 2026 03:02
Copy link
Member

@ematipico ematipico left a comment

Choose a reason for hiding this comment

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

I believe the issue can be fixed with just text_rimmed(). No other changes are required for fix the problem

@dyc3 dyc3 merged commit 63e68a1 into biomejs:main Jan 23, 2026
14 checks passed
@github-actions github-actions bot mentioned this pull request Jan 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Linter Area: linter L-HTML Language: HTML and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants