postcss / postcss-simple-vars

PostCSS plugin for Sass-like variables
MIT License
415 stars 36 forks source link

Reset value using webpack? #57

Closed alansouzati closed 8 years ago

alansouzati commented 8 years ago

I have the following css using simple vars:

$brandColor: #8C50FF;

.common {
  color: $brandColor;
  text-decoration: none;
}

Now I want to replace the brandColor value in my webpack config, based on the docs I tried:

   vars({
        variables: {
            brandColor: '#3e00b6'
        }
    })

The actual value remains #8C50FF. If I remove the $brandColor: #8C50FF; entry, then the value is set.

It would be great to not require the variables to be present always and set a default one instead.

ai commented 8 years ago

Sure. I will look on next week.

ai commented 8 years ago

You want to protect variables from overriding in CSS? Why you want this?

I think this logic is counterintuitive. Most users will expect, that $brandColor: #8C50FF; will override default value.

ai commented 8 years ago

I added a test to clear my view to API: https://github.com/postcss/postcss-simple-vars/blob/master/test.js#L141-L145

alansouzati commented 8 years ago

So, I'm building a library where folks should be able to use themeable components.

The default use case is where you don't want to care about colors, fonts, or anything like that. You just want to use a component, for example <Anchor href="dsadas" /> and have the default colors applied.

The default code for my css inside the Anchor component is:

$brandColor: #8C50FF;

.common {
  color: $brandColor;
  text-decoration: none;
}

When you build this using webpack, you fall into this default use case where you don't want to bother about the colors. So your configuration looks like this:

module: {
        loaders: [
            {
                test: /\.js$/,
                loaders: ['babel']
            },
            {
                test: /\.css$/,
                loader: 'style!css?sourceMap&modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss'
            }
        ]
    },
    postcss: () => [atImport(), mixins, vars, cssnext, modulesValues]

Please note that vars is empty and I'm not interested in having a theme here.

Now, let's say your brand color will change, typical case when you are creating a new theme. So, you go ahead and provide the brandColor variable inside your webpack. I was under the impression that this value will be used, instead of the one inside the component that the user has not access to.

There is the webpack configuration for the new brandColor:

module: {
        loaders: [
            {
                test: /\.js$/,
                loaders: ['babel']
            },
            {
                test: /\.css$/,
                loader: 'style!css?sourceMap&modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss'
            }
        ]
    },
    postcss: () => [atImport(), mixins, vars({ variables: { brandColor: '#3e00b6'}}), cssnext, modulesValues]

Please let me know if I'm missing something and/or how to achieve this with PostCSS.

In SASS this is how you do it:

$brandColor: #8C50FF !default;

.common {
  color: $brandColor;
  text-decoration: none;
}

then inside index.scss you do:

$brandColor: #3e00b6;

@import 'anchor.scss'
ai commented 8 years ago

Copying Sass !default behavior is not the best way. We could do much better.

We have special plugin for theming: https://www.npmjs.com/package/postcss-theme

If you want $-like variables you could do:

var defaultTheme = require('./default-theme.json');
var theme = Object.assign(defaultTheme, userTheme || {});
…
require('postcss-simple-vars')({
  variables: theme
})
alansouzati commented 8 years ago

Well, this does not handle the different use cases that I had. For example, my goal was not to touch any theme if the user in not interested in theming.

In this case they must do:

var defaultTheme = require('./default-theme.json');
…
require('postcss-simple-vars')({
  variables: defaultTheme
})

And how about structural differences in the styles that a simple variable cannot handle?

I have a project that I'm about to publish that uses my branch of postcss-simple-vars. As soon as I have it, I'm going to share here so that you understand better what I'm trying to achieve.

ai commented 8 years ago

@alansouzati I thought that var defaultTheme = require('./default-theme.json'); will be inside you plugin. User will use your component library as plugin:

So. it could send a config or didn’t send it:

postcss([
  require('postcss-my-library')
])
postcss([
  require('postcss-my-library')({ color: 'blue' })
])

It is a better way to handle all your magic inside, because good PostCSS plugins should be free from dependencies with other PostCSS plugins. Because some users may want to use cssnext instead of PreCSS.

ai commented 8 years ago

@alansouzati

And how about structural differences in the styles that a simple variable cannot handle?

Could you show some example? I am bad this abstract questions ;).

alansouzati commented 8 years ago

give me like 10min, i will publish the simple project that I did. it is most likely using postcss in a bad way.

ai commented 8 years ago

@alansouzati sure, show you you current code. I will try to help.

Right now we are thinking, maybe we need some special tool in PostCSS to create this component libraries more easy.

Your experience could give some ideas. With power of PostCSS we could do some new level for component libraries.

ai commented 8 years ago

BTW, could you create a issue in postcss/postcss repo and post your code there. Anyway it is not connected for this plugin and also your discussion could be interesting for other developers.

alansouzati commented 8 years ago

sure thing. i will create the issue and i can help too (with PRs 👍 ), this project is very interesting and I want to make sure we are following your best practices.

urstrulyKarthik commented 5 years ago

Can we provide this behavior with an option? Let the default behavior continue but invert the behavior to do this through configuration? what do you think?