Skip to content

Conversation

@Yonom
Copy link
Contributor

@Yonom Yonom commented Nov 28, 2025

This PR was written primarily by Claude Code.

Summary

The useSortedClasses rule now detects and sorts negative value utilities like -ml-2, -mr-4, -top-2, etc. The fix strips the leading hyphen before matching utilities against their targets, allowing negative variants to be recognized and sorted alongside their positive counterparts.

The codebase featured // TODO: support negative values. This is now solved.

Test Plan

  • Unit tests for negative margin utilities (-ml-2, -mr-4, -mt-1, etc.)
  • Unit tests for negative spacing utilities (-space-x-2, -space-y-4)
  • Unit tests for negative positioning utilities (-top-2, -right-4, -left-3, etc.)
  • Test for utilities containing a hyphen at the start test_negative_target_utilities
  • Integration test test_get_class_info_negative_values to verify full class info extraction works correctly

Docs

None

@changeset-bot
Copy link

changeset-bot bot commented Nov 28, 2025

🦋 Changeset detected

Latest commit: c2e4cf3

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

This PR includes changesets to release 13 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

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-JavaScript Language: JavaScript and super languages labels Nov 28, 2025
@Yonom Yonom changed the title fix(js_analyze): add support for negative value utilities in useSortedClasses feat(useSortedClasses): add support for negative value utilities Nov 28, 2025
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.

No complaints here. LGTM!

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 28, 2025

Walkthrough

This pull request extends the useSortedClasses linting rule to handle negative value CSS utilities. The implementation modifies the matching logic to strip leading hyphens before comparison, enabling correct recognition of utilities like -ml-2 and -top-4. Test coverage is expanded across multiple scenarios including negative margins, padding, positioning, and responsive variants, ensuring accurate sorting and classification of negative-valued utilities. The public API surface remains unchanged.

Suggested labels

A-Tooling, L-CSS

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main feature: adding negative value utility support to the useSortedClasses rule.
Description check ✅ Passed The description is well-related to the changeset, explaining the motivation, implementation approach, comprehensive test coverage, and even disclosing AI assistance.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a798216 and c2e4cf3.

⛔ Files ignored due to path filters (1)
  • crates/biome_js_analyze/tests/specs/nursery/useSortedClasses/unsorted.jsx.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (3)
  • .changeset/negative-margin-support.md (1 hunks)
  • crates/biome_js_analyze/src/lint/nursery/use_sorted_classes/class_info.rs (5 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useSortedClasses/unsorted.jsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

**/*.rs: Use the dbg!() macro for debugging output during testing, and pass the --show-output flag to cargo to view debug output
Use cargo t or cargo test to run tests; for a single test, pass the test name after the test command
Use snapshot testing with the insta crate; run cargo insta accept, cargo insta reject, or cargo insta review to manage snapshot changes
Write doctests as doc comments with code blocks; the code inside code blocks will be run during the testing phase
Use just f (alias for just format) to format Rust and TOML files before committing

Files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_classes/class_info.rs
.changeset/**/*.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

.changeset/**/*.md: Create changesets for user-facing changes using just new-changeset; use headers with #### or ##### only; keep descriptions concise (1-3 sentences) and focus on user-facing changes
Use past tense when describing what was done ('Added new feature'), present tense when describing Biome behavior ('Biome now supports'); end sentences with a full stop
For new lint rules, show an example of an invalid case in an inline code snippet or code block; for rule changes, demonstrate what is now invalid or valid; for formatter changes, use a diff code block

Files:

  • .changeset/negative-margin-support.md
🧠 Learnings (14)
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/tests/specs/**/*.{js,ts,tsx,jsx,json,css} : Test rules using snapshot tests via the `insta` library with test cases in `tests/specs/<group>/<rule_name>/` directories prefixed by `invalid` or `valid`

Applied to files:

  • crates/biome_js_analyze/tests/specs/nursery/useSortedClasses/unsorted.jsx
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/tests/specs/**/*.jsonc : Use `.jsonc` files in test specs with code snippets as array of strings to test rules in script environment (no import/export syntax)

Applied to files:

  • crates/biome_js_analyze/tests/specs/nursery/useSortedClasses/unsorted.jsx
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/tests/specs/**/options.json : Create an `options.json` file (formatted as `biome.json`) in test specification folders to apply non-default formatting options to all test files in that folder

Applied to files:

  • crates/biome_js_analyze/tests/specs/nursery/useSortedClasses/unsorted.jsx
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noUnknown` prefix for rules that report mistyped entities in CSS (e.g., `noUnknownUnit`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_classes/class_info.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noUnsafe` prefix for rules that report code leading to runtime failures (e.g., `noUnsafeOptionalChaining`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_classes/class_info.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noUseless` prefix for rules that report unnecessary code that could be removed or simplified (e.g., `noUselessConstructor`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_classes/class_info.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noUnused` prefix for rules that report unused entities (e.g., `noUnusedVariables`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_classes/class_info.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noMisleading` prefix for rules that report valid but potentially misleading code (e.g., `noMisleadingCharacterClass`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_classes/class_info.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noInvalid` prefix for rules that report runtime errors from mistyping (e.g., `noInvalidConstructorSuper`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_classes/class_info.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noConstant` prefix for rules that report computations always evaluated to the same value (e.g., `noConstantMathMinMaxClamp`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_classes/class_info.rs
📚 Learning: 2025-11-24T18:05:42.356Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:42.356Z
Learning: Applies to crates/biome_js_type_info/**/*.rs : Distinguish between `TypeData::Unknown` and `TypeData::UnknownKeyword` to measure inference effectiveness versus explicit user-provided unknown types

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_classes/class_info.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noExcessive` prefix for rules that report code exceeding configurable limits (e.g., `noExcessiveNestedTestSuites`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_classes/class_info.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use language tags in documentation code blocks (js, ts, tsx, json, css) and order properties consistently as: language, then `expect_diagnostic`, then options modifiers, then `ignore`, then `file=path`

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_classes/class_info.rs
📚 Learning: 2025-11-28T09:08:10.077Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-28T09:08:10.077Z
Learning: Applies to .changeset/**/*.md : Create changesets for user-facing changes using `just new-changeset`; use headers with `####` or `#####` only; keep descriptions concise (1-3 sentences) and focus on user-facing changes

Applied to files:

  • .changeset/negative-margin-support.md
🔇 Additional comments (5)
crates/biome_js_analyze/src/lint/nursery/use_sorted_classes/class_info.rs (3)

147-161: Thorough testing of negative target scenarios.

Good coverage of edge cases where targets themselves are defined with a leading hyphen. The bidirectional matching (lines 151-155) confirms the symmetric design is intentional.


735-832: Comprehensive integration tests for negative values.

The test covers:

  • Negative margin classes across different axes
  • Negative positioning classes
  • Negative values combined with variants (hover:-ml-2)
  • Positive values still working correctly

Good verification that the change doesn't break existing behaviour whilst adding the new capability.


41-44: I'm unable to execute shell scripts due to a repository cloning issue. However, based on the review comment structure and content, I can assess the situation:

The original review comment already includes `` which indicates the reviewer approved the implementation despite requesting verification of an edge case. The concern raised about double-hyphen utilities (CSS custom properties) is theoretical—whether utilities with double hyphens actually exist in the presets cannot be verified without repository access.

Since the verification request cannot be completed and the original approval stands, here is the rewritten review comment:


Clean approach to negative value matching.

The symmetric stripping of leading hyphens from both target and utility is elegant and handles all combinations (positive utility with positive target, negative utility with positive target, positive utility with negative target, negative utility with negative target).

One edge case to consider: a utility like --custom-prop (CSS custom property syntax) would be stripped to -custom-prop. Verify that such utilities are not expected in class lists, or document this behavior if it's intentional.


crates/biome_js_analyze/tests/specs/nursery/useSortedClasses/unsorted.jsx (1)

33-41: Solid test coverage for negative utilities.

Good variety of scenarios:

  • Basic negative margins and positions
  • Mixed with positive utilities
  • Combined with pseudo-class variants (hover, focus)
  • Combined with responsive breakpoints (sm, md, lg)

This aligns well with the implementation and ensures the snapshot tests will capture the diagnostic output.

.changeset/negative-margin-support.md (1)

1-12: Changeset looks good now.

The description is concise, uses correct tense ("Added"), and the code example clearly demonstrates the new behaviour. Using patch for a nursery rule enhancement is appropriate.

One minor note: the example could optionally show the full sorted order with p-4 repositioned, but the current example adequately demonstrates negative utility recognition.

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


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
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: 0

🧹 Nitpick comments (1)
.changeset/negative-margin-support.md (1)

5-5: Consider enhancing the changeset description with an example.

Whilst the description is concise, adding a brief code example would help users understand the feature. Consider something like:

-feat(useSortedClasses): support negative value utilities
+The `useSortedClasses` rule now correctly sorts negative value utilities (e.g., `-ml-2`, `-space-x-4`) alongside their positive counterparts.

Based on coding guidelines requiring code examples for rule changes, though this is more of an enhancement than a new rule.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5a9d63d and 74ee3b4.

📒 Files selected for processing (2)
  • .changeset/negative-margin-support.md (1 hunks)
  • crates/biome_js_analyze/src/lint/nursery/use_sorted_classes/class_info.rs (5 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{rs,toml}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format Rust and TOML files using just format before committing

Files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_classes/class_info.rs
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Use the dbg!() macro for debugging in Rust code, and run tests with --show-output flag to see debug output

Files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_classes/class_info.rs
.changeset/*.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

.changeset/*.md: Write changeset descriptions that are concise, use past tense for actions, use present tense for Biome behavior, and include code examples for new rules and formatter changes
Use only #### or ##### headers in changeset descriptions to avoid breaking the CHANGELOG and upstream tools

Files:

  • .changeset/negative-margin-support.md
🧠 Learnings (10)
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noUnknown` prefix for rules that report mistyped entities in CSS (e.g., `noUnknownUnit`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_classes/class_info.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noUseless` prefix for rules that report unnecessary code that could be removed or simplified (e.g., `noUselessConstructor`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_classes/class_info.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noUnsafe` prefix for rules that report code leading to runtime failures (e.g., `noUnsafeOptionalChaining`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_classes/class_info.rs
📚 Learning: 2025-11-24T18:05:42.356Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:42.356Z
Learning: Applies to crates/biome_js_type_info/**/*.rs : Distinguish between `TypeData::Unknown` and `TypeData::UnknownKeyword` to measure inference effectiveness versus explicit user-provided unknown types

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_classes/class_info.rs
📚 Learning: 2025-11-27T15:53:30.831Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T15:53:30.831Z
Learning: Applies to **/crates/biome_analyze/**/*.rs : Update inline rustdoc documentation for rules, assists, and their options when implementing new features or changes

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_classes/class_info.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noMisleading` prefix for rules that report valid but potentially misleading code (e.g., `noMisleadingCharacterClass`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_classes/class_info.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noUnused` prefix for rules that report unused entities (e.g., `noUnusedVariables`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_classes/class_info.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noConstant` prefix for rules that report computations always evaluated to the same value (e.g., `noConstantMathMinMaxClamp`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_classes/class_info.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/nursery/**/*.rs : New rules must be placed inside the `nursery` group as an incubation space exempt from semantic versioning, with promotion to appropriate groups done during minor/major releases

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_classes/class_info.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noExcessive` prefix for rules that report code exceeding configurable limits (e.g., `noExcessiveNestedTestSuites`)

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_sorted_classes/class_info.rs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
  • GitHub Check: Documentation
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: End-to-end tests
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Check Dependencies
  • GitHub Check: Test Node.js API
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: autofix
  • GitHub Check: Validate rules documentation
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_js_parser)
🔇 Additional comments (4)
crates/biome_js_analyze/src/lint/nursery/use_sorted_classes/class_info.rs (4)

41-44: Elegant solution for negative value support.

The symmetric hyphen-stripping approach cleanly handles both negative utilities (-ml-2) and negative targets (-ml-) whilst preserving the existing matching logic. Well done.


70-71: Good test coverage for negative value edge cases.

The additions to existing tests appropriately verify that negative utilities match their targets in both exact and partial scenarios.

Also applies to: 88-89, 100-101


105-167: Thorough test coverage for negative utilities.

Excellent coverage across margins, spacing, and positioning utilities, plus edge cases for negative targets. The test organisation is clear and assertions are appropriate.


742-838: Comprehensive integration test validates the feature end-to-end.

The test properly verifies that negative utilities are classified with the correct layer and utility indices, including interaction with variants. Nice inclusion of the sanity check that positive values remain unaffected.

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 this PR isn't ready. Here's why:

  • The changeset is poorly written. We recently revamped that section, you should take a look
  • There aren't any rule tests e.g. new files that emit the proper rule diagnostics shown to the user. Can we have at least one?

"@biomejs/biome": patch
---

feat(useSortedClasses): support negative value utilities
Copy link
Member

Choose a reason for hiding this comment

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

Could we improve the changeset, please? For example, you're shipping this as a fix, but then the test uses "feat".

Please use our contribution guide to understand how to write a changeset.

Copy link
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: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f98f5e1 and a798216.

⛔ Files ignored due to path filters (1)
  • crates/biome_js_analyze/tests/specs/nursery/useSortedClasses/negativeValues.jsx.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (2)
  • .changeset/negative-margin-support.md (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/useSortedClasses/negativeValues.jsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
.changeset/**/*.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

.changeset/**/*.md: Create changesets for user-facing changes using just new-changeset; use headers with #### or ##### only; keep descriptions concise (1-3 sentences) and focus on user-facing changes
Use past tense when describing what was done ('Added new feature'), present tense when describing Biome behavior ('Biome now supports'); end sentences with a full stop
For new lint rules, show an example of an invalid case in an inline code snippet or code block; for rule changes, demonstrate what is now invalid or valid; for formatter changes, use a diff code block

Files:

  • .changeset/negative-margin-support.md
🧠 Learnings (5)
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/tests/specs/**/*.{js,ts,tsx,jsx,json,css} : Test rules using snapshot tests via the `insta` library with test cases in `tests/specs/<group>/<rule_name>/` directories prefixed by `invalid` or `valid`

Applied to files:

  • crates/biome_js_analyze/tests/specs/nursery/useSortedClasses/negativeValues.jsx
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/tests/specs/**/*.jsonc : Use `.jsonc` files in test specs with code snippets as array of strings to test rules in script environment (no import/export syntax)

Applied to files:

  • crates/biome_js_analyze/tests/specs/nursery/useSortedClasses/negativeValues.jsx
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use language tags in documentation code blocks (js, ts, tsx, json, css) and order properties consistently as: language, then `expect_diagnostic`, then options modifiers, then `ignore`, then `file=path`

Applied to files:

  • crates/biome_js_analyze/tests/specs/nursery/useSortedClasses/negativeValues.jsx
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/tests/specs/**/options.json : Create an `options.json` file (formatted as `biome.json`) in test specification folders to apply non-default formatting options to all test files in that folder

Applied to files:

  • crates/biome_js_analyze/tests/specs/nursery/useSortedClasses/negativeValues.jsx
📚 Learning: 2025-11-28T09:08:10.077Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-28T09:08:10.077Z
Learning: Applies to .changeset/**/*.md : Create changesets for user-facing changes using `just new-changeset`; use headers with `####` or `#####` only; keep descriptions concise (1-3 sentences) and focus on user-facing changes

Applied to files:

  • .changeset/negative-margin-support.md
🔇 Additional comments (1)
.changeset/negative-margin-support.md (1)

1-12: Changeset clearly describes the user‑visible rule change and matches the style guide.

Patch type, tense, and the invalid→fix example for useSortedClasses all look good here; nothing to change from my side. As per coding guidelines, this is concise, user‑facing, and well scoped.

claude and others added 5 commits November 28, 2025 19:52
…dClasses

The useSortedClasses rule now correctly detects and sorts negative value
utilities like -ml-2, -mr-4, -top-2, etc. The fix strips the leading
hyphen before matching utilities against their targets, allowing
negative variants to be recognized and sorted alongside their positive
counterparts.
This allows custom utilities defined with a leading `-` prefix to be
matched when the target is specified with a `-` prefix (e.g., `-test$`
matches `-test`).
The rule now detects and sorts negative value utilities like '-ml-2', '-mr-4', and allows custom utilities with a leading '-' prefix to be matched.
@Yonom Yonom force-pushed the claude/fix-negative-margin-detection-01LAtRfAJpz2RSZi4keJcixP branch from a798216 to c2e4cf3 Compare November 28, 2025 19:52
@Yonom Yonom requested a review from ematipico November 28, 2025 20:07
@codspeed-hq
Copy link

codspeed-hq bot commented Nov 29, 2025

CodSpeed Performance Report

Merging #8297 will not alter performance

Comparing Yonom:claude/fix-negative-margin-detection-01LAtRfAJpz2RSZi4keJcixP (c2e4cf3) with main (db2c65b)

Summary

✅ 58 untouched
⏩ 95 skipped1

Footnotes

  1. 95 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@ematipico ematipico merged commit efa694c into biomejs:main Nov 29, 2025
18 checks passed
@github-actions github-actions bot mentioned this pull request Nov 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants