0.1.0 • Published 8 years ago

less-interop v0.1.0

Weekly downloads
2
License
MIT
Repository
github
Last release
8 years ago

less-interop

Build
status Coverage
Status

Have you ever wanted to use variables from a LESS file directly in your JS code? If you're like me (believe in CSS-in-JS, and use Bootstrap v3 a lot which is written in LESS), there's a chance you've wanted to. In my opinion, any non-trivial web design benefits from reusing/overriding all the nicely thought-out variables defined by, say, Bootstrap, and often it makes sense to have this take place within JS code.

This library exposes a function that walks through a LESS abstract syntax tree and extracts all observed variables into a format that can be easily consumed in JS.

Currently, all variables in Bootstrap v3.3.5's variables.less file are successfully extracted.

I've tested this library with LESS v2.5.x. As I'm not confident it will work well outside v2.5.x, for now I'm pinning down the peerDependencies requirement to 2.5.x. If you notice it works well with versions outside this range, please submit a pull request.

How to use

var less = require('less');

// `require('less-interop')` returns a function.
var importLessVars = require('less-interop');

// An actual LESS source code in string form.
var source = '@random-color: #123456';

// Special options to configure LESS's parser.
// For now, I'm just going to use the default configuration.
var parseOptions = {};

// `less.parse` asynchronously parses a LESS source code into an abstract syntax
// tree, which you can acquire inside the callback.
less.parse(source, parseOptions, function (err, tree) {
  
  // Finally this library comes into play.
  // The function returned by `require('less-interop')` takes in one argument.
  // ***This argument should be `tree.rules`.***
  var importedVars = importLessVars(tree.rules);
  
  // The names of the LESS variables defined in the source code above will be
  // camel-cased and won't have the `@`, following JS convention.
  // eg) @random-color -> randomColor
  console.log(importedVars.randomColor); // will print '#123456'
  
});

Conversion rules/examples

Check out the following examples to see how LESS values will get converted in JS. Keep in mind that the primary goal here is to be able to use LESS variables directly in CSS-in-JS scenarios as smoothly as possible.

Colors will result in strings

LESSJS
#000'#000'
#123456'#123456'
rgb(100, 100, 100)'#646464'
rgba(100, 100, 100, 0.15)'rgba(100, 100, 100, 0.15)'
rgba(100, 100, 100, .15)'rgba(100, 100, 100, 0.15)'

Numbers will result in numbers (duh)

LESSJS
1.51.5

Strings will result in strings (duh)

LESSJS
"hello"'hello'
'hello''hello'

Quoted strings containing a whitespace will be quoted

LESSJS
"hello world"'"hello world"'

Note: strings that contain a whitespace but are not quoted will result in the words being joined with a comma. See the section "Multiple values being juxtaposed" below for an explanation.

LESSJS
hello world'hello, world'

Pixels will result in plain numbers

This is in accordance with React.js convention.

LESSJS
18px18

Percents will result in strings

LESSJS
15%'15%'

Function calls will be statically evaluated.

LESSJS
ceil(18.5)19
ceil(floor(18.5))18
darken(#428bca, 6.5%)'#337ab7'
darken(rgb(66, 139, 202), 6.5%)'#337ab7'

Math will be statically evaluated

LESSJS
3 + 47
19px + 120
ceil(3.5px + 1)5

Remember that pixels will result in plain JS numbers.

Variable references will be resolved

Variables that have been defined will be resolved to its value.

Throughout the following table, assume that @x: 18.5 has already been defined.

LESSJS
@x18.5
@x + 119.5
ceil(@x)19
ceil(@x + 1)20

Everything not mentioned so far will be converted into strings

Probably/hopefully. If you run into a buggy situation please submit an issue or a pull request!

LESSJS
bold'bold'
block'block'
inherit'inherit'
underline'underline'

Multiple values being juxtaposed

So this one is a bit complicated.

If all values in the list are strings, they will be joined with a comma.

LESSJS
"Helvetica Neue", Helvetica, Arial, sans-serif'"Helvetica Neue", Helvetica, Arial, sans-serif'

Otherwise, they will be joined with a whitespace.

LESSJS
0 10px 20px 15px'0 10px 20px 15px'
10px 20px'10px 20px'
0 1px 0 #fff'0 1px 0 #fff'
0 1px 2px rgba(0, 0, 0, .6)'0 1px 2px rgba(0, 0, 0, 0.6)'

A note about @import

This library will not resolve the @imports in your LESS code at all. All @import rules will simply be ignored. You are responsible for resolving the @imports yourself and recursively applying this library to each of the @imports. For an example of how this can be achieved, check out babel-plugin-less-interop.