[babel-plugin] Keep custom property rules inside @layer with useLayers#1752
Open
ryanda9910 wants to merge 1 commit into
Open
[babel-plugin] Keep custom property rules inside @layer with useLayers#1752ryanda9910 wants to merge 1 commit into
ryanda9910 wants to merge 1 commit into
Conversation
CSS custom properties (priority 1) share a `priorityLevel` (Math.floor(priority / 1000) === 0) with the priority-0 at-rules `@property`, `@keyframes` and `@position-try`. The layer-wrapping decision used `group[0][2]` (the priority of the first rule in the sorted group), so a priority-0 at-rule sorting ahead of a custom property made `pri > 0` false and pulled the whole group -- including the custom property -- out of its `@layer`. Unlayered CSS always wins the cascade over layered CSS, so external `@layer` rules could never override StyleX-generated custom property assignments, defeating the purpose of `useCSSLayers`. Partition each group so priority-0 at-rules stay unlayered (as intended by facebook#1071) while priority > 0 rules -- including custom properties -- are wrapped in their layer. Fixes facebook#1611
|
@ryanda9910 is attempting to deploy a commit to the Meta Open Source Team on Vercel. A member of the Team first needs to authorize it. |
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.
What changed / motivation ?
When
useCSSLayersis enabled,stylex.create()rules that set CSS custom properties (e.g.'--card-padding': '16px') could be emitted outside any@layer, making them impossible to override from external CSS layers.Root cause
Custom properties get priority
1(viagetAtRulePriority), which floors intopriorityLevelMath.floor(1 / 1000) === 0. That is the samepriorityLevelbucket as the priority-0at-rules@property,@keyframesand@position-try.The layer-wrapping decision in
processStylexRulesused the priority of the first rule in the sorted group:Rules are sorted by priority ascending, so whenever a priority-
0at-rule (e.g. a@keyframesfromanimationName) sorted ahead of a custom property in the same group,priwas0,pri > 0wasfalse, and the entire group — including the custom property — was emitted unlayered.The
pri > 0guard was originally added in #1071 to keep@property/@keyframes/@position-tryout of@layer(some CSS validators don't understand those at-rules inside a layer). It was never meant to exclude custom properties.Because unlayered CSS always beats layered CSS in the cascade, external
@layerrules could never override StyleX custom property assignments — defeating the point ofuseCSSLayers.Before (custom property escapes the layer):
After:
Fix
Partition each group by layerability: priority-
0at-rules stay unlayered (preserving #1071), while priority> 0rules — including custom properties,:rootvariable declarations and theme overrides — are wrapped in their layer. The decision is made per-rule instead of fromgroup[0], so a leading at-rule can no longer drag layerable rules out of their layer.Linked PR/Issues
Fixes #1611
Additional Context
transform-process-test.jsthat reproduces the exact scenario (a custom property alongside a priority-0@keyframesin the samepriorityLevel) and asserts the@keyframesstays unlayered while the custom property is wrapped in@layer priority1.useLayerssnapshots intransform-process-test.jswere updated: the priority-0at-rules (@property,@keyframes) still print unlayered, and the previously-leaking:rootvar declarations / theme overrides / custom property rules are now correctly wrapped in@layer priority1(which was previously declared in the header but empty).Verified locally (Node 22):
jest(babel-plugin): 960 passed, 858 snapshots passedflow check: No errorseslint+prettier --checkon changed files: cleanPre-flight checklist