fix(styled-jsx): handle top-level & nesting selector correctly in scopeSelector#95
Open
Copilot wants to merge 4 commits into
Open
fix(styled-jsx): handle top-level & nesting selector correctly in scopeSelector#95Copilot wants to merge 4 commits into
& nesting selector correctly in scopeSelector#95Copilot wants to merge 4 commits into
Conversation
Copilot
AI
changed the title
fix(styled-jsx): replace lone :scope with scope class to fix
fix(styled-jsx): Jun 24, 2026
& :global(...) selectors& :global(...) selectors compile to dead .jsx-HASH:scope selector
Copilot created this pull request from a session on behalf of
sapphi-red
June 24, 2026 10:44
View session
Copilot
AI
changed the title
fix(styled-jsx):
fix(styled-jsx): strip :scope from all & compound selectors, not just lone :scope
Jun 24, 2026
& :global(...) selectors compile to dead .jsx-HASH:scope selector
Copilot
AI
changed the title
fix(styled-jsx): strip :scope from all & compound selectors, not just lone :scope
Replace two-step &/:scope removal+insertion with single in-place replacement
Jun 24, 2026
& nesting selector correctly in scopeSelector
sapphi-red
reviewed
Jun 24, 2026
| if (globalIdx >= 0) { | ||
| // Emit any components before :global() in this compound | ||
| // Emit any components before :global() in this compound, skipping any | ||
| // leading :scope (originated from `&` — e.g. `&:global(.foo)` → `:scope:global(.foo)`) |
Member
There was a problem hiding this comment.
It's arguable that &:global(.foo) should be .jsx-hash.foo, but I think either is fine as &:global(.foo) is contradictory.
sapphi-red
approved these changes
Jun 24, 2026
@rolldown/plugin-babel
@rolldown/plugin-emotion
@rolldown/plugin-jsx-remove-attributes
oxc-unshadowed-visitor
@rolldown/pluginutils
@rolldown/plugin-styled-jsx
@rolldown/plugin-transform-imports
commit: |
11 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes the handling of top-level
&(CSS nesting) inscopeSelector. Previously the function had no awareness of:scopepseudo-classes (which lightningcss emits when it flattens a top-level&), so patterns like&:global(.foo)and& .barproduced incorrect or missing scoped selectors.Changes
src/css.tsisScopePseudohelper to detect:scopepseudo-classes emitted by lightningcss when expanding a top-level&&:global()handling: strip any leading:scope(from&) before unwrapping:global(), so&:global(.theme-dark)correctly emits.theme-darkinstead of leaving.jsx-HASH:scope:scopein-place with the scope class. This means&is substituted directly rather than removed and re-added at a different position&.active→.jsx-HASH.active(was.active.jsx-HASH)&.active:hover→.jsx-HASH.active:hover(was.active.jsx-HASH:hover)&patterns are unaffected:&:hover,&::before,&:not(...), bare&,& .childTest fixtures
issue-94— new fixture covering& :global(.foo)and& .localClass(the two patterns from issue& :global(...)selectors mis-compile to.jsx-HASH:scope... (dead selector) instead of.jsx-HASH... #94)scope-ampersand-patterns— new fixture exhaustively covering all top-level&combinations:&.class,&:pseudo,&::element,&:not(),&.class:pseudo,&:global(),& + combinator, and bare&Behaviour notes
The CSS semantics are equivalent in all cases — both
.active.jsx-HASHand.jsx-HASH.activerequire both classes to be present on the element. The change is purely in which position the scope class occupies in the compound selector.