├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── README.md ├── package.json ├── src └── index.js └── test └── simple.js /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "4" 4 | - "5" 5 | script: 6 | "npm run ci" 7 | sudo: false 8 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 2.0.0 2 | 3 | Renamed the package from `css-variable-loader` to `css-variables-loader`. 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CSS variable loader 2 | 3 | [![npm](https://img.shields.io/npm/v/css-variables-loader.svg)](https://www.npmjs.com/package/css-variables-loader) 4 | [![Build Status](https://travis-ci.org/Dashlane/css-variables-loader.svg?branch=master)](https://travis-ci.org/Dashlane/css-variables-loader) 5 | [![Dependency Status](https://gemnasium.com/Dashlane/css-variables-loader.svg)](https://gemnasium.com/Dashlane/css-variables-loader) 6 | 7 | Import your CSS variables into JavaScript. 8 | 9 | ## Assumptions 10 | 11 | This project assumes you use [W3C custom properties](https://www.w3.org/TR/css-variables/) for CSS variables. This is how they look: 12 | 13 | ```css 14 | :root { 15 | --my-theme-color: hsl(121, 90%, 90%); 16 | --my-accent-color: hsl(60, 90%, 90%); 17 | --my-font-size: 18px; 18 | } 19 | ``` 20 | 21 | Only the custom properties on the `:root` selector are currently supported. 22 | 23 | This project also assumes you have a Webpack-like setup for building your application. 24 | 25 | ## Usage 26 | 27 | Install the loader into your project with `npm install --save css-variables-loader`. 28 | 29 | In your JavaScript, use `var variables = require('!css-variables!../path/to/variables.css')`. 30 | 31 | Now `variables` is a map of variable names to values as strings. 32 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "css-variables-loader", 3 | "version": "2.0.2", 4 | "description": "Load CSS variables with Webpack", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "test": "ava", 8 | "ci": "ava" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+ssh://git@github.com/Dashlane/css-variables-loader.git" 13 | }, 14 | "author": "Denis Sokolov ", 15 | "license": "ISC", 16 | "bugs": { 17 | "url": "https://github.com/Dashlane/css-variables-loader/issues" 18 | }, 19 | "homepage": "https://github.com/Dashlane/css-variables-loader#readme", 20 | "devDependencies": { 21 | "ava": "^0.16.0" 22 | }, 23 | "dependencies": { 24 | "css": "^2.2.1" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | var css = require('css'); 2 | module.exports = function(source) { 3 | this.cacheable(); 4 | var result = {}; 5 | css.parse(source).stylesheet.rules 6 | .filter(rule => rule.selectors && rule.selectors.some(sel => sel === ':root')) 7 | .forEach(rule => rule.declarations 8 | .filter(decl => decl.type === 'declaration' && decl.property.indexOf('--') === 0) 9 | .forEach(decl => result[decl.property] = decl.value)); 10 | return 'module.exports = ' + JSON.stringify(result); 11 | }; 12 | -------------------------------------------------------------------------------- /test/simple.js: -------------------------------------------------------------------------------- 1 | /* eslint no-eval: 0 */ 2 | var test = require('ava'); 3 | var cssVariableLoader = require('..'); 4 | 5 | var loader = cssVariableLoader.bind({ cacheable: function(){} }); 6 | 7 | var check = function(name, css, result){ 8 | test(name, function(t){ 9 | var module = { exports: {} }; 10 | eval(loader(css)); 11 | t.deepEqual(module.exports, result); 12 | }); 13 | }; 14 | 15 | check('should handle a simple variable', 16 | ':root { --theme: red }', 17 | { '--theme': 'red' }) 18 | check('should handle multiple variables', 19 | ':root { --theme: red; --accent: blue }', 20 | { '--accent': 'blue', '--theme': 'red' }) 21 | check('should handle multiple declarations', 22 | ':root { --theme: red } :root { --accent: blue }', 23 | { '--accent': 'blue', '--theme': 'red' }) 24 | check('should not import non-variables', 25 | ':root { color: red }', 26 | {}) 27 | check('should only import from :root', 28 | ':hover { --theme: red }', 29 | {}) 30 | check('should import from :root among multiple selectors', 31 | ':hover, :root { --theme: red }', 32 | { '--theme': 'red' }) 33 | check('should not break when there is a comment', 34 | ':root { --theme: red; /* important info */ --accent: blue }', 35 | { '--accent': 'blue', '--theme': 'red' }) 36 | check('should not break when there is a file-level comment', 37 | '/* file info */ :root { --theme: red; /* important info */ --accent: blue }', 38 | { '--accent': 'blue', '--theme': 'red' }) 39 | --------------------------------------------------------------------------------