Skip to content

Instantly share code, notes, and snippets.

@roginfarrer
Last active July 2, 2024 13:04
Show Gist options
  • Save roginfarrer/8d2be13b51cd706f0c37df4459d68f4c to your computer and use it in GitHub Desktop.
Save roginfarrer/8d2be13b51cd706f0c37df4459d68f4c to your computer and use it in GitHub Desktop.

Revisions

  1. roginfarrer revised this gist Jun 4, 2022. 1 changed file with 10 additions and 0 deletions.
    10 changes: 10 additions & 0 deletions nestedGlobalStyle.ts
    Original file line number Diff line number Diff line change
    @@ -30,3 +30,13 @@ function globalUtil(selector: string, styles: RecursiveGlobalStyle) {
    );
    });
    }

    const handleAmpersand = (key: string, nestedKey: string): string => {
    let finalSelector = nestedKey;
    if (nestedKey.startsWith("&")) {
    finalSelector = nestedKey.replace("&", key);
    } else {
    finalSelector = `${key} ${nestedKey.replace("&", key)}`;
    }
    return finalSelector;
    };
  2. roginfarrer revised this gist Jun 4, 2022. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions readme.md
    Original file line number Diff line number Diff line change
    @@ -20,7 +20,7 @@ This little function wraps the `globalStyle` utility to support nested selectors
    ```tsx
    nestedGlobalStyle('.foo', {
    color: 'blue',
    p: {
    'li, p': {
    color: 'red',
    '&:hover': {
    color: 'yellow',
    @@ -32,7 +32,7 @@ nestedGlobalStyle('.foo', {
    })

    // .foo { color: blue; }
    // .foo p { color: red; }
    // .foo p:hover { color: yellow; }
    // .foo li, .foo p { color: red; }
    // .foo li:hover, .foo p:hover { color: yellow; }
    // .foo::after { margin: 23px; }
    ```
  3. roginfarrer created this gist Jun 4, 2022.
    32 changes: 32 additions & 0 deletions nestedGlobalStyle.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,32 @@
    import { globalStyle, GlobalStyleRule } from "@vanilla-extract/css";

    interface RecursiveGlobalStyle {
    [k: string]: GlobalStyleRule | RecursiveGlobalStyle;
    }

    function globalUtil(selector: string, styles: RecursiveGlobalStyle) {
    const write = (
    key: string[],
    value: RecursiveGlobalStyle | GlobalStyleRule
    ) => {
    Object.entries(value).forEach(([nestedK, nestedV]) => {
    if (typeof nestedV === "string" || typeof nestedV === "number") {
    globalStyle(key.map((k) => handleAmpersand(selector, k)).join(", "), {
    [nestedK]: nestedV,
    });
    } else {
    write(
    key.map((k) => handleAmpersand(k, nestedK)),
    nestedV
    );
    }
    });
    };

    Object.entries(styles).forEach(([key, value]) => {
    write(
    key.split(",").map((k) => k.trim()),
    value
    );
    });
    }
    38 changes: 38 additions & 0 deletions readme.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,38 @@
    Vanilla Extract's `globalStyle` function is intended to style global selectors. One of its limitations is that it doesn't support SASS-like nested selectors. The selector passed to the first argument is as deep as the selector can go.

    ```tsx
    // ✅ Good!
    globalStyle('.foo', {
    color: 'blue',
    });

    // ❌ No bueno
    globalStyle('.foo', {
    color: 'blue',
    p: {
    color: 'red'
    }
    });
    ```

    This little function wraps the `globalStyle` utility to support nested selectors. It also supports referencing the parent selector with `&`, though it hasn't been thoroughly tested for more complex selectors.

    ```tsx
    nestedGlobalStyle('.foo', {
    color: 'blue',
    p: {
    color: 'red',
    '&:hover': {
    color: 'yellow',
    }
    },
    '&::after': {
    margin: '23px'
    }
    })

    // .foo { color: blue; }
    // .foo p { color: red; }
    // .foo p:hover { color: yellow; }
    // .foo::after { margin: 23px; }
    ```