sass-extract-js
Plugin for sass-extractsass-extract to convert Sass global variables into a plain JS object.
Huh? Why?
I work on a team that uses Sass. We've got a shared variables file that gets referenced throughout our styleguide and in our components. I wanted to start using styled-components in some projects and wanted to keep things consistent but I didn't want to have to copy our Sass variables over. Using this plugin with sass-extractsass-extract, I can simply extract the global variables from our Sass stylesheet and they will be converted into a JS object that gets passed down to my components via styled-components'<ThemeProvider>
theming.Cool! How do I get it?
You'll need to install sass-extractsass-extract, sass-extract-loadersass-extract-loader, node-sassnode-sass, and this plugin.$ yarn add sass-extract sass-extract-loader node-sass sass-extract-js
(npm install works too)
Nice! How do I use it?
Assuming you're using webpack, you'll need to use sass-extract-loader to require/transform your sass variables file. Then you can pass the styles as a theme via a ThemeProvider component like this:// Require your sass variables using sass-extract-loader and specify the plugin
const theme = require('sass-extract-loader?{"plugins":["sass-extract-js"]}!./path/to/vars.scss');
// Pass the vars into your ThemeProvider component
render(
<ThemeProvider theme={theme}>
<App />
</ThemeProvider>
);
Then use themes in your styled components:
import styled from 'styled-components';
const Button = styled.button`
background-color: ${p => p.theme.primary}
`;
Sweet! What does the output look like?
Given a Sass file with some global variable declarations:$primary: rgb(255, 202, 77);
$seondary: #1A93C8;
$primary-light: lighten($primary, 20%);
$base-padding: 10px;
$base-margin: 0 1em;
$base-border: 1px solid #ccc;
$font-family-sans: 'Helvetica', 'Arial', sans-serif;
$base-font-size: 16px;
$line-height: $base-font-size * 1.8;
It will yield the following object:
{
primary: 'rgb(255, 202, 77)',
seondary: 'rgb(26, 147, 200)',
primaryLight: 'rgb(255, 232, 179)',
basePadding: '10px',
baseMargin: '0 1em',
baseBorder: '1px solid rgb(204, 204, 204)',
fontFamilySans: '\'Helvetica\', \'Arial\', sans-serif',
baseFontSize: '16px',
lineHeight: '28.8px'
}
Right on! But I need options.
Everybody loves options and we've got one:Option Name | Default | Description :---------- | :------ | :----------
camelCase
| true | Should SASS variable names be converted to camelCaseOptions Usage
sass-extract Plugin Options
As of sass-extract 2.0.0, options can be passed to plugins. Here's how:const rendered = sassExtract.renderSync({
file: './path/to/vars.scss'
}, {
plugins: [{ plugin: 'sass-extract-js', options: { camelCase: false } }]
});
Plugin Instance
You can also create a plugin instance with your desired options and pass the instance directly inside the plugins array.// Import the plugin factory directly
import createSassExtractJsPlugin from 'sass-extract-js/lib/plugin';
// Create a plugin instance, passing in your options
const sassExtractJsPlugin = createSassExtractJsPlugin({ camelCase: false });
// Call the `renderSync` function with the path to your Sass file
// and pass the plugin instance in the plugins array
const rendered = sassExtract.renderSync({
file: './path/to/vars.scss'
}, {
plugins: [sassExtractJsPlugin]
});
Using transformVars
directly
If, for some reason, you don't want to use this package as a sass-extract plugin, you can import the transformVars
function directly and use it. This is the main function that gets called in sass-extract's plugin pipeline. It expects as its input an object with extracted SASS variables, as generated by sass-extract. The function also accepts an options object.// Import the transformVars method directly
import transformVars from 'sass-extract-js/lib/transformVars';
// Call the function, passing in your options
const transformed = transformVars(objectWithExtractedStyles, { camelCase: false });