A simple javascript utility for conditionally joining class names together, inspired by classNames but with a twist.
npm install class-lists
Use with node.js, browserify or webpack:
// es5
var classLists = require('class-lists');
// es6
import classLists from 'class-lists';
Alternatively, you can simply include index.js
on your page with a standalone <script>
tag and it will export a global classLists
method (useful if you're doing Rails), or define the module if you are using RequireJS.
The classLists
function takes [ideally] any number of arguments which can be either a string or a tuple. Since tuples are not first class citizens in JS, they are represented by regular arrays (with 2 or 3 items).
var visible = true,
open = false
// strings
classLists('header', 'is-visible'); // => 'header is-visible'
// strings + lists
classLists('header',
[visible, 'is-visible'],
[open, 'is-open'],
); // => 'header is-visible'
// booleans
classLists('header',
[visible, 'is-visible', 'is-hidden'],
[open, 'is-open', 'is-closed']
); // => 'header is-visible is-closed'
// with css modules
var styles = {
'is-visible': 'is-visible-fn38j',
'is-open': 'is-open-g3oiw'
} // this is a mock! :D
classLists(styles, 'header',
[visible, 'is-visible'],
[open, 'is-open']
); // => 'header is-visible-fn38j'
Since it doesn't rely on objects you don't need to use the special es6 syntax for dynamic keys:
var state = 'open'
// classNames version es5
var opts = {}
opts['is-' + state] = state
classNames(opts) // => 'is-open'
// classLists version es5
classLists([state, 'is-' + state']) // => 'is-open'
// classNames version es6
classNames({[‘is-${state}‘]: state}) // => 'is-open'
// classLists version es6
classLists([state, ‘is-${state}‘]) // => 'is-open'
Using tuples instead of objects gives you the ability to have classes defined based on a boolean for both true and false scenarios:
// classNames version
var open = true
classNames({
'is-open': open,
'is-closed': !open
})
// classLists version
classLists([
open, ['is-open', 'is-closed]
])
Doesn't require to call bind when you use css modules:
var styles = require('./styles.css')
// classNames
var classNames = require('classnames/bind')
classNames.bind(styles)
classNames({open: true})
// classLists
var classLists = require('class-lists') // same module
classNames(styles, [true, 'open'])
If you're a performance freak, the fact it doesn't deal with objects makes classLists a little faster. Take a look at the benchmark online (current versions, may change in the future).
Here are my local benchmarks:
Project | Params | Results |
---|---|---|
classNames | strings | 6.1M ops/sec |
classLists | strings | 6.5M ops/sec +6% |
classNames | object | 2.1M ops/sec |
classLists | lists | 6.0M ops/sec +280% |
classNames | strings & objects | 2.2M ops/sec |
classLists | strings & lists | 5.5M ops/sec +250% |
classNames | mix | 1.5M ops/sec |
classLists | mix | 4.0M ops/sec +266% |
classNames | css-modules | 0.6M ops/sec |
classLists | css-modules | 3.8M ops/sec +633% |
- Send PR with tests passing (
npm test
). It will also ensure that the code has good standards withstandard
. Make sure your changes do not degrade performance considerable, preferably not at all. Do not bump version in your PR. - Once the PR is ok, then update the version according to SemVer and I'll realease it.
That's all.