From 45f6a5ff0f5ac0dc0993b957643b840299f9b2e6 Mon Sep 17 00:00:00 2001 From: Konv Suu Date: Tue, 16 Jun 2026 15:05:02 +0800 Subject: [PATCH] Remove space before `;` delimiter in SCSS `if()` function (#19384) Co-authored-by: fisker --- changelog_unreleased/scss/19384.md | 13 ++++++ src/language-css/massage-ast/index.js | 33 +++++++++++++++ .../print/comma-separated-value-group.js | 16 +++++++ tests/format/scss/function/if/19355.scss | 14 +++++++ .../if/__snapshots__/format.test.js.snap | 42 +++++++++++++++++++ tests/format/scss/function/if/format.test.js | 1 + 6 files changed, 119 insertions(+) create mode 100644 changelog_unreleased/scss/19384.md create mode 100644 tests/format/scss/function/if/19355.scss create mode 100644 tests/format/scss/function/if/__snapshots__/format.test.js.snap create mode 100644 tests/format/scss/function/if/format.test.js diff --git a/changelog_unreleased/scss/19384.md b/changelog_unreleased/scss/19384.md new file mode 100644 index 000000000..56b9556b0 --- /dev/null +++ b/changelog_unreleased/scss/19384.md @@ -0,0 +1,13 @@ +#### Remove space before `;` delimiter in SCSS `if()` function (#19384 by @kovsu) + + +```scss +// Input +$value: if(sass($x): 1 ; else: 2); + +// Prettier stable +$value: if(sass($x): 1 ; else: 2); + +// Prettier main +$value: if(sass($x): 1; else: 2); +``` diff --git a/src/language-css/massage-ast/index.js b/src/language-css/massage-ast/index.js index 0448b512e..ad4857344 100644 --- a/src/language-css/massage-ast/index.js +++ b/src/language-css/massage-ast/index.js @@ -209,6 +209,39 @@ function massageAstNode(original, cloned, parent) { value: original.groups.map((node) => node.value).join(""), }; } + + if ( + original.type === "value-func" && + original.value === "if" && + original.group.type === "value-paren_group" && + original.group.groups.length === 1 && + original.group.groups[0].type === "value-comma_group" + ) { + const originalGroups = original.group.groups[0].groups; + const clonedGroups = cloned.group.groups[0].groups; + + // `if(sass(true): 10px ; else: 15px)` + // ^ + for (let index = originalGroups.length - 1; index >= 0; index--) { + const group = originalGroups[index]; + + if ( + group.type === "value-word" && + typeof group.value === "string" && + group.value.endsWith(";") + ) { + if (group.value === ";") { + const previousGroup = originalGroups[index - 1]; + if (previousGroup?.type === "value-number") { + clonedGroups.splice(index - 1, 2, { type: "#node-placeholder" }); + } + continue; + } + + clonedGroups[index] = { type: "#node-placeholder" }; + } + } + } } massageAstNode.ignoredProperties = ignoredProperties; diff --git a/src/language-css/print/comma-separated-value-group.js b/src/language-css/print/comma-separated-value-group.js index 78c0b0f34..8bf080ae3 100644 --- a/src/language-css/print/comma-separated-value-group.js +++ b/src/language-css/print/comma-separated-value-group.js @@ -140,6 +140,22 @@ function printCommaSeparatedValueGroup(path, options, print) { continue; } + // Don't print a space before the `;` branch delimiter in the SCSS `if()` + // function (i.e. `if(condition: value; else: value)`) + if ( + options.parser === "scss" && + iNextNode.type === "value-word" && + iNextNode.value === ";" && + path.match( + undefined, + (node, key) => key === "groups" && node.type === "value-paren_group", + (node, key) => + key === "group" && node.type === "value-func" && node.value === "if", + ) + ) { + continue; + } + // We should keep spaces between words in a embedded JS expression // examples: // styled.div` font-size: var(--font-size-h${({ level }) => level}); `; diff --git a/tests/format/scss/function/if/19355.scss b/tests/format/scss/function/if/19355.scss new file mode 100644 index 000000000..f3da073eb --- /dev/null +++ b/tests/format/scss/function/if/19355.scss @@ -0,0 +1,14 @@ +$a: if(sass($x): 1; else: white); +$a: if(sass($x): 1 ; else: white); +$b: if(sass($x): map.get($view, background); else: white); +$c: if(sass($x): map.get($view, background) ; else: white); + +@debug if(sass(true): 10px; else: 15px); +@debug if(sass(true): 10px ; else: 15px); +@debug if(sass(meta.variable-defined($var)): $var); + +@mixin foo($isDark, $view) { + .bar { + background-color: if(sass($isDark): map.get($view, background) ; else: white); + } +} diff --git a/tests/format/scss/function/if/__snapshots__/format.test.js.snap b/tests/format/scss/function/if/__snapshots__/format.test.js.snap new file mode 100644 index 000000000..5483e9561 --- /dev/null +++ b/tests/format/scss/function/if/__snapshots__/format.test.js.snap @@ -0,0 +1,42 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`19355.scss format 1`] = ` +====================================options===================================== +parsers: ["scss"] + printWidth: 80 (default) | +=====================================input====================================== +$a: if(sass($x): 1; else: white); +$a: if(sass($x): 1 ; else: white); +$b: if(sass($x): map.get($view, background); else: white); +$c: if(sass($x): map.get($view, background) ; else: white); + +@debug if(sass(true): 10px; else: 15px); +@debug if(sass(true): 10px ; else: 15px); +@debug if(sass(meta.variable-defined($var)): $var); + +@mixin foo($isDark, $view) { + .bar { + background-color: if(sass($isDark): map.get($view, background) ; else: white); + } +} + +=====================================output===================================== +$a: if(sass($x): 1; else: white); +$a: if(sass($x): 1; else: white); +$b: if(sass($x): map.get($view, background); else: white); +$c: if(sass($x): map.get($view, background); else: white); + +@debug if(sass(true): 10px; else: 15px); +@debug if(sass(true): 10px; else: 15px); +@debug if(sass(meta.variable-defined($var)): $var); + +@mixin foo($isDark, $view) { + .bar { + background-color: if( + sass($isDark): map.get($view, background); else: white + ); + } +} + +================================================================================ +`; diff --git a/tests/format/scss/function/if/format.test.js b/tests/format/scss/function/if/format.test.js new file mode 100644 index 000000000..88aa93e6a --- /dev/null +++ b/tests/format/scss/function/if/format.test.js @@ -0,0 +1 @@ +runFormatTest(import.meta, ["scss"]);