Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple selectors are not properly scoped #105

Closed
spmonahan opened this issue Apr 26, 2022 · 3 comments · Fixed by #110
Closed

Multiple selectors are not properly scoped #105

spmonahan opened this issue Apr 26, 2022 · 3 comments · Fixed by #110
Labels
🐞 bug Something isn't working 💡 good first issue Good for newcomers

Comments

@spmonahan
Copy link
Contributor

When writing multiple selectors separated by commas only the first selector is properly scoped with a class name.

Here's a link to an annotated repro case in CodeSandbox.

Current Behavior

A Griffel styles like

makeStyles({
  root: {
    ":active,:focus-within": {
      ...shorthands.borderColor("red")
    }
  }
});

Produces a selector like this in DevTools:

.f1mk9nzz:active, :focus-within {
    border-right-color: red;
}

Currently only the :active selector is scoped with a generated class name.

Expected Behavior

Both the :active and :focus-within selectors should be scoped with the same generated class name. So we should see something like this in DevTools:

.f1mk9nzz:active, .f1mk9nzz:focus-within {
    border-right-color: red;
}

Alternatively, if this syntax is not supported I should get an error in VSCode explaining to me that I cannot write styles in this way.

Notes

In Codesandbox I get an error (red squiggle under the selectors) when writing ":active,:focus-within" indicating to me that perhaps this way of writing styles is not supported by Griffel. However, I don't get this error when writing styles like this in VS Code so I'm not certain. I'm using griffel@1.0.3 in both Codesandbox and VSCode.

@layershifter layershifter added the 🐞 bug Something isn't working label Apr 26, 2022
@layershifter
Copy link
Member

layershifter commented Apr 26, 2022

Hey, this issue was fixed in makeStyles sometime ago, microsoft/fluentui#20348. But read below ⬇️

It breaks with rules that flip in RTL, the simplest example is:

makeStyles({
  root: {
    ":active,:focus-within": {
      paddingLeft: "10px"
    }
  }
});

⬇️⬇️⬇️

.f14f5aie:active,
.f14f5aie:focus-within {
  padding-left: 10px;
}

.f1sheuf0:active,
:focus-within {
  padding-right: 10px;
}

P.S. You can dump all rules with:

console.log(
  [...document.querySelectorAll("[data-make-styles-bucket]")]
    .flatMap(el => [...el.sheet.cssRules].map(rule => rule.cssText))
    .join("\n")
);

P.P.S. We have tryout page to check generated CSS.

P.P.P.S. Thanks for reporting 🙏

@layershifter layershifter added the 💡 good first issue Good for newcomers label Apr 26, 2022
@layershifter
Copy link
Member

layershifter commented Apr 26, 2022

The fix is needed in compileCSS.ts:

cssRule = `${classNameSelector}{${normalizedPseudo} ${cssDeclaration}};`;
if (rtlProperty) {
cssRule = `${cssRule}; ${rtlClassNameSelector}${normalizedPseudo} ${rtlCSSDeclaration};`;

It's not visible with template literals, but cssRule on 101 & 104 are different - there are missing curly brackets 🤦‍♂️

-cssRule = `${cssRule}; ${rtlClassNameSelector}${normalizedPseudo} ${rtlCSSDeclaration};`;
+cssRule = `${cssRule}; ${rtlClassNameSelector}{${normalizedPseudo} ${rtlCSSDeclaration}};`;

We also need to cover this with a unit test:

    it('handles complex nested selectors', () => {
      expect(resolveStyleRules({ '& > :first-child': { '& svg': { color: 'red' } } })).toMatchInlineSnapshot(`
        .fxfx2ih > :first-child svg {
          color: red;
        }
      `);
    });

+    it('handles comma separated selectors', () => {
+      expect(
+        resolveStyleRules({
+          ':active,:focus-within': {
+            paddingLeft: '10px',
+          },
+        }),
+      ).toMatchInlineSnapshot(`
+        .f14f5aie:active,
+        .f14f5aie:focus-within {
+          padding-left: 10px;
+        }
+        .f1sheuf0:active,
+        .f1sheuf0:focus-within {
+          padding-right: 10px;
+        }
+      `);
+    });

P.S. @spmonahan are you interested in contributing a fix? 😉

@spmonahan
Copy link
Contributor Author

Didn't see an issue for this in the issue log but glad it was (mostly) fixed already!

Thanks for the debugging tips -- they will be very helpful! I've been following the work on Griffel DevTools and while looking into this issue was thinking, "can't wait for DevTools!".

Happy to contribute a fix. Should have time to work on it today.

spmonahan added a commit to spmonahan/griffel that referenced this issue Apr 26, 2022
Fixes an issue where only the first selector in a list of
comma-separated selectors would be scoped with the generated class name
when flipping styles for RTL.

See: microsoft#105
layershifter pushed a commit that referenced this issue Apr 27, 2022
Fixes an issue where only the first selector in a list of
comma-separated selectors would be scoped with the generated class name
when flipping styles for RTL.

See: #105
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐞 bug Something isn't working 💡 good first issue Good for newcomers
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants