Skip to content

feat(css): support expression-based at-root queries - #12048

Merged
ematipico merged 3 commits into
mainfrom
dbezrukov/scss-dynamic-at-root-queries
Oct 3, 2026
Merged

ematipico merged 3 commits into
mainfrom
dbezrukov/scss-dynamic-at-root-queries

Conversation

@denbezrukov

Copy link
Copy Markdown
Contributor

This PR was developed with assistance from OpenAI Codex.

Summary

Adds parser and formatter support for expression-based SCSS @at-root queries.

@use "sass:list";
@use "sass:map";

$query: "without: rule";
$rules: media supports;

@at-root ($query) {
  .overlay {
    position: fixed;
  }
}

@at-root (without: $rules) {
  .rules {
    color: red;
  }
}

@at-root ("with" + "out": media) {
  .quoted {
    color: blue;
  }
}

@at-root (
  map.get((mode: without), mode):
    list.join(media, supports)
) {
  .computed {
    display: block;
  }
}

Test Plan

  • cargo test -p biome_css_parser
  • cargo test -p biome_css_formatter

@agentscanapp

agentscanapp Bot commented Sep 30, 2026

Copy link
Copy Markdown

A maintainer will take a look as soon as they can. In the meantime, please make sure that:

  • the description follows our PR template
  • any related issues are linked
  • existing tests still pass

@changeset-bot

changeset-bot Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 214f070

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@github-actions github-actions Bot added A-Parser Area: parser A-Formatter Area: formatter A-Tooling Area: internal tools L-CSS Language: CSS and super languages L-Grit Language: GritQL labels Sep 30, 2026
@denbezrukov denbezrukov changed the title Dbezrukov/scss dynamic at root queries feat(css): support expression-based at-root queries Sep 30, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Parser conformance results on

js/262

Test result main count This PR count Difference
Total 49797 49797 0
Passed 48773 48773 0
Failed 1024 1024 0
Panics 0 0 0
Coverage 97.94% 97.94% 0.00%

jsx/babel

Test result main count This PR count Difference
Total 40 40 0
Passed 37 37 0
Failed 3 3 0
Panics 0 0 0
Coverage 92.50% 92.50% 0.00%

markdown/commonmark

Test result main count This PR count Difference
Total 652 652 0
Passed 652 652 0
Failed 0 0 0
Panics 0 0 0
Coverage 100.00% 100.00% 0.00%

symbols/microsoft

Test result main count This PR count Difference
Total 6322 6322 0
Passed 2147 2147 0
Failed 4175 4175 0
Panics 0 0 0
Coverage 33.96% 33.96% 0.00%

ts/babel

Test result main count This PR count Difference
Total 662 662 0
Passed 592 592 0
Failed 70 70 0
Panics 0 0 0
Coverage 89.43% 89.43% 0.00%

ts/microsoft

Test result main count This PR count Difference
Total 17646 17646 0
Passed 13449 13449 0
Failed 4197 4197 0
Panics 0 0 0
Coverage 76.22% 76.22% 0.00%

yaml/yaml-test-suite

Test result main count This PR count Difference
Total 402 402 0
Passed 402 402 0
Failed 0 0 0
Panics 0 0 0
Coverage 100.00% 100.00% 0.00%

@coderabbitai

coderabbitai Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

🧰 Additional context used
📚 Code guidelines (1)
AGENTS.md — auto-discovered

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: biomejs/biome/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 118d5fe4-8556-4da4-8f19-fd9235224f57
📥 Commits

Reviewing files that changed from the base of the PR and between 7978e5e and 214f070.

⛔ Files ignored due to path filters (20)
  • crates/biome_css_factory/src/generated/node_factory.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_css_factory/src/generated/syntax_factory.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_css_formatter/tests/specs/scss/at-rule/dynamic-at-root-comments.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_formatter/tests/specs/scss/at-rule/dynamic-at-root-layout.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_formatter/tests/specs/scss/at-rule/dynamic-at-root-namespaced.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_formatter/tests/specs/scss/at-rule/dynamic-at-root-suppression.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_formatter/tests/specs/scss/at-rule/dynamic-at-root.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_parser/tests/css_test_suite/error/scss/at-rule/at-root.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_parser/tests/css_test_suite/error/scss/at-rule/dynamic-at-root-eof.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_parser/tests/css_test_suite/error/scss/at-rule/dynamic-at-root-recovery.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_parser/tests/css_test_suite/ok/at_rule/dynamic-at-root-unknown.css.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_parser/tests/css_test_suite/ok/scss/at-rule/at-root.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_parser/tests/css_test_suite/ok/scss/at-rule/dynamic-at-root-expressions.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_parser/tests/css_test_suite/ok/scss/at-rule/dynamic-at-root-syntax-only.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_parser/tests/css_test_suite/ok/scss/at-rule/dynamic-at-root.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_parser/tests/css_test_suite/ok/scss/at-rule/valid-modern-sweep.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_syntax/src/generated/kind.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_css_syntax/src/generated/macros.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_css_syntax/src/generated/nodes.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_css_syntax/src/generated/nodes_mut.rs is excluded by !**/generated/**, !**/generated/** and included by **
📒 Files selected for processing (3)
  • crates/biome_css_formatter/src/generated.rs
  • crates/biome_grit_patterns/src/grit_target_language/css_target_language/generated_mappings.rs
  • xtask/codegen/css.ungram

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.


Walkthrough

The parser now accepts general SCSS expressions and modifier-and-rules clauses in @at-root queries. The formatter supports the revised syntax, including comment placement and suppression handling. Parser and formatter fixtures cover valid queries, malformed input, layouts, comments and namespaced variables.

Suggested reviewers: dyc3

Priority: ⬇️ Low

Change: Feature

Merge Risk: ⚪ Minimal · up to 214f0

This change broadens SCSS @at-root query parsing and formatting. Malformed empty clauses still report errors and recover, and the supplied evidence shows no actionable merge-readiness risk.

Architecture Summary

Architecture risk: 🔵 Low · up to 214f0

The change affects 2 systems.

Changed systems: crates, xtask

Architecture concerns
No architecture-level concerns identified.

Review details

Systems and components

  • observed — crates (service) was modified; 23 changed files map to changed impact.
  • observed — xtask (service) was modified; 2 changed files map to changed impact.

Before / after behavior

  • observed — Modified behavior in crates/biome_css_formatter/src/comments.rs: The syntax imports add ScssAtRootQueryClause.
  • observed — Modified behavior in crates/biome_css_formatter/src/comments.rs: The comment-placement chain now tries handle_scss_at_root_query_comment after the SCSS expression-item trailing-line-comment handler and before the at-root selector handler.
  • observed — Modified behavior in crates/biome_css_formatter/src/comments.rs: Adds handle_scss_at_root_query_comment. It finds an enclosing ScssAtRootQueryClause, requires both its colon token and rules node, and attaches the comment as dangling to the clause only when the comment’s text range falls between the trimmed colon and rules boundaries; missing syntax elements or comments outside that range retain default placement.
  • observed — Modified behavior in crates/biome_css_formatter/src/scss/any/at_root_query.rs: Added the FormatAnyScssAtRootQuery rule, which formats either supported query variant by delegating to that node’s formatter.
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: support for expression-based SCSS @at-root queries.
Description check ✅ Passed The description explains the parser and formatter changes, gives relevant SCSS examples, and lists the planned tests.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


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

@codspeed

codspeed Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

⚠️ 3 benchmarks measured no execution time

Nothing ran under measurement, usually because the compiler removed the code under test. These results are not comparable, so they count as unchanged.

Preventing compiler optimizations

✅ 114 untouched benchmarks
⏩ 299 skipped benchmarks1

Performance Changes

Benchmark BASE HEAD Efficiency
⚠️ grit_query_anchor_kinds[code_snippet] < 1 ns < 1 ns N/A
⚠️ grit_query_anchor_kinds[metavariable] < 1 ns < 1 ns N/A
⚠️ grit_query_anchor_kinds[or_pattern] < 1 ns < 1 ns N/A

Comparing dbezrukov/scss-dynamic-at-root-queries (214f070) with main (4db3f58)

Open in CodSpeed

Footnotes

  1. 299 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. ↩

@denbezrukov
denbezrukov force-pushed the dbezrukov/scss-dynamic-at-root-queries branch from 7978e5e to 214f070 Compare October 3, 2026 07:10
@ematipico
ematipico merged commit 69fcd9b into main Oct 3, 2026
34 checks passed
@ematipico
ematipico deleted the dbezrukov/scss-dynamic-at-root-queries branch October 3, 2026 08:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Formatter Area: formatter A-Parser Area: parser A-Tooling Area: internal tools L-CSS Language: CSS and super languages L-Grit Language: GritQL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants