Skip to content

feat(css): support unquoted concatenation in SCSS interpolation expressions - #10020

Merged
denbezrukov merged 1 commit into
mainfrom
db/scss-interpolation-6
Apr 17, 2026
Merged

feat(css): support unquoted concatenation in SCSS interpolation expressions#10020
denbezrukov merged 1 commit into
mainfrom
db/scss-interpolation-6

Conversation

@denbezrukov

Copy link
Copy Markdown
Contributor

This PR was created with AI assistance (Codex).

Summary

Fixes SCSS formatting for unquoted interpolation concatenation.

Biome no longer inserts spaces into forms such as $variable#{something}, #{something}$variable, $a#{b}$c, and
#{a}$b#{c}. These values now keep their direct adjacency when formatted.

Test Plan

new snapshots

@changeset-bot

changeset-bot Bot commented Apr 17, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: d5402c5

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 L-CSS Language: CSS and super languages labels Apr 17, 2026
@coderabbitai

coderabbitai Bot commented Apr 17, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

This PR enhances the SCSS formatter to properly handle unquoted concatenation scenarios. It introduces a customisable separator rule for component value list formatting, allowing callers to conditionally suppress whitespace insertion between specific adjacent items. The change specifically targets SCSS variable and interpolation pairs, preserving formatting fidelity for patterns like $variable#{something} without unwanted spacing. Test fixtures validate the new behaviour across multiple concatenation combinations.

Possibly related PRs

Suggested reviewers

  • ematipico
  • dyc3
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: adding support for unquoted concatenation in SCSS interpolation expressions, which is precisely what the changeset implements.
Description check ✅ Passed The description is directly related to the changeset, explaining that the PR fixes SCSS formatting for unquoted interpolation concatenation and specifying the exact forms that are now handled correctly.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch db/scss-interpolation-6

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
crates/biome_css_formatter/src/utils/component_value_list.rs (1)

201-230: Minor: omit_separator also suppresses the PreserveInline/OnePerLine/at_group_boundary hard-line-break paths.

Because the whole if !is_comma && !omit_separator { … } block is skipped, a future caller that combines a non-Fill layout with a predicate that returns true would silently drop a hard line break between those items. It's a non-issue for the SCSS expression-item-list caller (Fill, no commas between the var/interp pair), so no change is required here.

If you want to future-proof, consider letting the predicate only suppress the soft_line_break_or_space() branch while still honouring the leading-newline / group-boundary hard breaks — e.g. compute omit_separator per-branch rather than gating the outer if. Totally optional.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_css_formatter/src/utils/component_value_list.rs` around lines
201 - 230, The current outer guard if !is_comma && !omit_separator prevents hard
breaks from firing; refactor the condition so omit_separator only suppresses the
soft_line_break_or_space() path while still allowing the leading-newline and
group-boundary hard-line-break branches to run. Concretely, inside the block
guarded by if !is_comma { … } (use is_comma_delimiter(&element) to compute
is_comma) keep the PreserveInline/OnePerLine branch and the at_group_boundary
branch checking element.syntax().has_leading_newline() and at_group_boundary
respectively and write hard_line_break()/space() as before, but only gate the
final soft_line_break_or_space() call on !omit_separator (use the existing
omit_separator variable) so omit_separator prevents only soft-line separators
and not hard-line-breaks.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@crates/biome_css_formatter/src/utils/component_value_list.rs`:
- Around line 201-230: The current outer guard if !is_comma && !omit_separator
prevents hard breaks from firing; refactor the condition so omit_separator only
suppresses the soft_line_break_or_space() path while still allowing the
leading-newline and group-boundary hard-line-break branches to run. Concretely,
inside the block guarded by if !is_comma { … } (use is_comma_delimiter(&element)
to compute is_comma) keep the PreserveInline/OnePerLine branch and the
at_group_boundary branch checking element.syntax().has_leading_newline() and
at_group_boundary respectively and write hard_line_break()/space() as before,
but only gate the final soft_line_break_or_space() call on !omit_separator (use
the existing omit_separator variable) so omit_separator prevents only soft-line
separators and not hard-line-breaks.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0a1b8a43-2dc0-464c-bb72-01fd3c97bb48

📥 Commits

Reviewing files that changed from the base of the PR and between a738f58 and d5402c5.

⛔ Files ignored due to path filters (3)
  • crates/biome_css_formatter/tests/specs/css/scss/declaration/unquoted-concatenation.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_parser/tests/css_test_suite/ok/scss/value/list.scss.snap is excluded by !**/*.snap and included by **
  • crates/biome_css_parser/tests/css_test_suite/ok/scss/value/unquoted-concatenation.scss.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (5)
  • crates/biome_css_formatter/src/scss/lists/expression_item_list.rs
  • crates/biome_css_formatter/src/utils/component_value_list.rs
  • crates/biome_css_formatter/tests/specs/css/scss/declaration/unquoted-concatenation.scss
  • crates/biome_css_parser/tests/css_test_suite/ok/scss/value/list.scss
  • crates/biome_css_parser/tests/css_test_suite/ok/scss/value/unquoted-concatenation.scss

@codspeed-hq

codspeed-hq Bot commented Apr 17, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 29 untouched benchmarks
⏩ 227 skipped benchmarks1


Comparing db/scss-interpolation-6 (d5402c5) with main (d6c44d1)

Open in CodSpeed

Footnotes

  1. 227 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 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nice!

@denbezrukov
denbezrukov merged commit fc829ef into main Apr 17, 2026
28 checks passed
@denbezrukov
denbezrukov deleted the db/scss-interpolation-6 branch April 17, 2026 19:47
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 L-CSS Language: CSS and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants