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

Cannot composeVisitors with multiple Rules #789

Open
oofdere opened this issue Aug 4, 2024 · 2 comments
Open

Cannot composeVisitors with multiple Rules #789

oofdere opened this issue Aug 4, 2024 · 2 comments

Comments

@oofdere
Copy link

oofdere commented Aug 4, 2024

The below code outputs .foo{color:red;@light{&{color:green}}@dark{&{color:#ff0}}}. Each rule works on their own, for example if I delete the light rule then the dark rule works: .foo{color:red;@light{&{color:green}}@media (prefers-color-scheme:dark){&{color:#ff0}}}.

let { code, map } = transform({
    filename: 'test.css',
    minify: true,
    code: new TextEncoder().encode('.foo{color: red;@light {color: green;}; @dark {color:yellow;}}'),
    customAtRules: {
        light: {
            prelude: null,
            body: 'style-block'
        },
        dark: {
            prelude: null,
            body: 'style-block'
        }
    },
    visitor: composeVisitors([{
        Rule: {
            custom: {
                light({ body, loc }) {
                    return {
                        type: 'media',
                        value: {
                            rules: body.value,
                            loc,
                            query: {
                                mediaQueries: [
                                    {
                                        raw: '(prefers-color-scheme: light)'
                                    }
                                ]
                            }
                        }
                    }
                },
            }
        }
    },
    {
        Rule: {
            custom: {
                dark({ body, loc }) {
                    return {
                        type: 'media',
                        value: {
                            rules: body.value,
                            loc,
                            query: {
                                mediaQueries: [
                                    {
                                        raw: '(prefers-color-scheme: dark)'
                                    }
                                ]
                            }
                        }
                    }
                },
            }
        }
    }]),
});
@oofdere
Copy link
Author

oofdere commented Aug 4, 2024

For now I'm just using lodash's merge, while it does have pitfalls compared to composeVisitors it's a good temporary solution

export function composePlugins<C extends CustomAtRules>(plugins: (Plugin<C> | Visitor<C>)[]) {
    let customAtRules: CustomAtRules = {};
    let visitor: Visitor<CustomAtRules> = {};

    plugins.forEach(p => {
        if ('visitor' in p) {
            _.merge(visitor, p.visitor)
            if (p.customAtRules) { Object.assign(customAtRules, p.customAtRules) }
        } else {
            _.merge(visitor, p)

        }
    });

    return { customAtRules, visitor }
}

oofdere added a commit to oofdere/crosswind that referenced this issue Aug 4, 2024
@mayank99
Copy link
Contributor

mayank99 commented Oct 3, 2024

I've also noticed that composeVisitors drops some specific functions, such as StyleSheet and StyleSheetExit.

composeVisitors([
  {
    StyleSheet(s) {
      console.log(s); // This never gets called
    },
    StyleSheetExit(s) {
      console.log(s); // This never gets called
    },
  },
  {
    Rule: {},
  },
  {
    Rule: {},
  }
])

To work around this, I'm doing my own merging as well. It's not perfect but it works well for simple cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants