Skip to content

Commit d3a50a6

Browse files
authored
Merge pull request #34 from jorgebucaran/5.0.0
- Use ES modules. - Include CJS fallback for Node 10 and below. - Remove hasOwnProperty check. - Allow using a number as a class - Modernize benchmarks.
2 parents a3fb156 + 1521b8c commit d3a50a6

File tree

10 files changed

+136
-157
lines changed

10 files changed

+136
-157
lines changed

.github/workflows/test.yml

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,23 @@
1-
name: Run tests
2-
1+
name: CI
32
on: push
4-
53
jobs:
64
test:
7-
env:
5+
env:
86
NODE_ENV: development
97
runs-on: ubuntu-latest
108
strategy:
119
matrix:
12-
node-version: [6.x, 8.x, 10.x, 12.x]
10+
node-version: [12.x, 14.x]
1311
steps:
14-
- name: Checkout
15-
uses: actions/checkout@v1
16-
- name: Use Node.js ${{ matrix.node-version }}
17-
uses: actions/setup-node@v1
18-
with:
19-
node-version: ${{ matrix.node-version }}
20-
- name: Test
21-
run: |
22-
npm install -g codecov
23-
npm install
24-
npm test
25-
codecov
12+
- name: Checkout
13+
uses: actions/checkout@v1
14+
- name: Use Node.js ${{ matrix.node-version }}
15+
uses: actions/setup-node@v1
16+
with:
17+
node-version: ${{ matrix.node-version }}
18+
- name: Test
19+
run: |
20+
npm install -g codecov
21+
npm install
22+
npm test
23+
codecov

.gitignore

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,10 @@
1-
# IDE
2-
.idea
3-
.vscode
4-
5-
# Logs
6-
*.log*
7-
yarn.lock
8-
package-lock.json
1+
*.map
2+
*.br
3+
*.gz
94

10-
# Coverage
11-
coverage
12-
.nyc_output
5+
*.cjs
6+
*.min.js
137

14-
# Misc
8+
package-lock.json
159
node_modules
16-
*.xml
17-
.DS_Store
18-
19-
# Dist
20-
*.gz
21-
dist
10+
coverage

README.md

Lines changed: 54 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,99 +1,86 @@
1-
# Classcat [![npm](https://img.shields.io/npm/v/classcat.svg?label=&color=0080FF)](https://github.com/jorgebucaran/classcat/releases/latest)
1+
# Classcat
22

3-
> Build a space-separated [class attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/class) quickly.
3+
> Build a [`class`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/class) attribute string quickly.
44
5-
- Easily add and remove class names based on a truthy or falsy value.
6-
- Works best when paired with a view framework. which will it be?
7-
- Up to 2.5x faster than the alternatives ([run the benchmarks](#run-the-benchmarks)).
8-
- Ridiculously tiny at [260B](http://bundlephobia.com/result?p=classcat). No dependencies.
5+
- Framework agnostic, reusable, plain vanilla JavaScript.
6+
- Up to [2.5x faster]() than alternatives.
7+
- [217 B](http://bundlephobia.com/result?p=classcat) (minified+gzipped). 👌
98

10-
## Quickstart
9+
This module makes it easy to build a space-delimited `class` attribute string from an object or array of CSS class names. Just pair each class with a boolean value to add or remove them conditionally.
1110

12-
```console
13-
npm i classcat
14-
```
15-
16-
Don't want to set up a build step? Import it inside a `<script>` tag as a module. Don't worry; modules are supported in all evergreen, self-updating desktop, and mobile browsers.
17-
18-
```html
19-
<script type="module">
20-
import cc from "https://unpkg.com/classcat"
21-
</script>
22-
```
23-
24-
Classcat takes an array of strings or name-value object and joins all the [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) values into a space-separated string. Arrays may be nested too. That's really all there is to it. Here's the [first example](https://codepen.io/jorgebucaran/pen/NYgLwG?editors=0010) to get you started.
25-
26-
```jsx
11+
```js
2712
import cc from "classcat"
2813

29-
export const ToggleButton = ({ isOn }) => (
30-
<div class="btn">
14+
export const ToggleButton = ({ isOn, toggle }) => (
15+
<div className="btn" onClick={() => toggle(!isOn)}>
3116
<div
32-
class={cc({
17+
className={cc({
3318
circle: true,
3419
off: !isOn,
3520
on: isOn,
3621
})}
3722
/>
38-
<span class={cc({ textOff: !isOn })}>{isOn ? "ON" : "OFF"}</span>
23+
<span className={cc({ textOff: !isOn })}>{isOn ? "ON" : "OFF"}</span>
3924
</div>
4025
)
4126
```
4227

43-
## API
28+
[Try with React](https://codepen.io/jorgebucaran/pen/NYgLwG?editors=0010), [lit-html](https://codepen.io/jorgebucaran/pen/LjPJEp?editors=1000), [Mithril](https://codepen.io/jorgebucaran/pen/JjjOjwB?editors=1100), [Superfine](https://codepen.io/jorgebucaran/pen/wrMvjz?editors=1000)
4429

45-
### `cc(string | number | object | array)`
30+
## Installation
4631

47-
```js
48-
import cc from "classcat"
32+
```console
33+
npm install classcat
34+
```
4935

50-
cc("foo") //=> "foo"
36+
Or without a build step—import it right in your browser.
5137

52-
cc(["foo", "bar", "baz"]) //=> "foo bar baz"
38+
```html
39+
<script type="module">
40+
import cc from "https://unpkg.com/classcat"
41+
</script>
42+
```
5343

54-
cc({ foo: false, bar: null, baz: undefined }) //=> ""
44+
## API
5545

56-
cc({ foo: true, bar: false, baz: true }) //=> "foo baz"
46+
### `cc(names)`
5747

58-
cc([{ foo: true, bar: false }, "baz"]) //=> "foo baz"
48+
```ps
49+
cc(names: string | number | object | array): string
5950
```
6051

61-
## Run the benchmarks
52+
```js
53+
import cc from "classcat"
6254

63-
```console
64-
npm run build && npm i -C bench && npm -C bench start
55+
cc("elf") //=> "elf"
56+
57+
cc(["elf", "orc", "gnome"]) //=> "elf orc gnome"
58+
59+
cc({
60+
elf: false,
61+
orc: null,
62+
gnome: undefined,
63+
}) //=> ""
64+
65+
cc({
66+
elf: true,
67+
orc: false,
68+
gnome: true,
69+
}) //=> "elf gnome"
70+
71+
cc([
72+
{
73+
elf: true,
74+
orc: false,
75+
},
76+
"gnome",
77+
]) //=> "elf gnome"
6578
```
6679

80+
## Benchmarks
81+
6782
```console
68-
# Strings
69-
classcat × 15,927,163 ops/sec
70-
classnames × 2,694,533 ops/sec
71-
clsx × 8,542,847 ops/sec
72-
73-
# Objects
74-
classcat × 15,205,051 ops/sec
75-
classnames × 2,873,497 ops/sec
76-
clsx × 8,806,231 ops/sec
77-
78-
# Strings/Objects
79-
classcat × 13,834,475 ops/sec
80-
classnames × 3,013,424 ops/sec
81-
clsx × 5,890,821 ops/sec
82-
83-
# Arrays
84-
classcat × 3,649,723 ops/sec
85-
classnames × 709,177 ops/sec
86-
clsx × 2,513,014 ops/sec
87-
88-
# Arrays/Objects
89-
classcat × 4,290,009 ops/sec
90-
classnames × 1,856,967 ops/sec
91-
clsx × 3,099,573 ops/sec
92-
93-
# Arguments vs Array
94-
classcat × 3,089,353 ops/sec
95-
classnames × 828,906 ops/sec
96-
clsx × 3,057,879 ops/sec
83+
npm --prefix bench start
9784
```
9885

9986
## License
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import classcat from "../../src/index"
1+
import { runBenchmark } from "./runBenchmark.js"
2+
import classcat from "../index.js"
23
import classnames from "classnames"
34
import clsx from "clsx"
4-
import { runBenchmark } from "./runBenchmark"
55

66
runBenchmark(
77
[

bench/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
22
"private": true,
3+
"type": "module",
34
"scripts": {
4-
"start": "rollup -i src/index.js -o dist/index.js -f cjs -g benchmark,classnames && node dist/index.js"
5+
"start": "npm install && node index.js"
56
},
67
"devDependencies": {
7-
"rollup": "*",
88
"benchmark": "^2.1.4",
99
"classnames": "*",
1010
"clsx": "*"
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import { Suite } from "benchmark"
1+
import bench from "benchmark"
22

33
export const runBenchmark = (tests, modules) =>
44
Object.keys(tests).map((name, i) => {
55
console.log(`${i > 0 ? "\n" : ""}${name}`)
66
Object.keys(modules)
77
.reduce(
88
(bench, id) => bench.add(id, tests[name].bind({}, modules[id], id)),
9-
new Suite().on("cycle", ({ target: { name, hz } }) =>
9+
new bench.Suite().on("cycle", ({ target: { name, hz } }) =>
1010
console.log(`${name} × ${Math.floor(hz).toLocaleString()} ops/sec`)
1111
)
1212
)

index.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
export default function cc(names) {
2+
if (typeof names === "string" || typeof names === "number") return "" + names
3+
4+
let out = ""
5+
6+
if (Array.isArray(names)) {
7+
for (let i = 0, tmp; i < names.length; i++) {
8+
if ((tmp = cc(names[i])) !== "") {
9+
out += (out && " ") + tmp
10+
}
11+
}
12+
} else {
13+
for (let k in names) {
14+
if (names[k]) out += (out && " ") + k
15+
}
16+
}
17+
18+
return out
19+
}

package.json

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
{
22
"name": "classcat",
3-
"description": "Build a space-separated class attribute quickly.",
43
"version": "4.1.0",
54
"type": "module",
6-
"main": "dist/classcat.js",
7-
"module": "src/index.js",
8-
"unpkg": "src/index.js",
5+
"main": "index.cjs",
96
"typings": "classcat.d.ts",
10-
"license": "MIT",
7+
"description": "Build a class attribute string quickly.",
118
"repository": "jorgebucaran/classcat",
9+
"license": "MIT",
10+
"exports": {
11+
"./package.json": "./package.json",
12+
".": {
13+
"require": "./index.cjs",
14+
"import": "./index.js"
15+
}
16+
},
1217
"files": [
13-
"src",
14-
"dist",
15-
"classcat.d.ts"
18+
"*.*(c)[tj]s*"
1619
],
1720
"author": "Jorge Bucaran",
1821
"keywords": [
@@ -23,16 +26,13 @@
2326
],
2427
"scripts": {
2528
"test": "c8 twist tests/*.js",
26-
"build": "export pkg=$npm_package_name; npm run bundle && npm run minify",
27-
"bundle": "rollup -i src/index.js -o dist/$pkg.js --no-strict -mf umd -n $pkg",
28-
"minify": "terser dist/$pkg.js -o dist/$pkg.js -mc --source-map includeSources,url=$pkg.js.map",
29-
"prepare": "npm run build",
30-
"release": "v=$npm_package_version; npm run build && git commit -am $v && git tag -s $v -m $v && git push && git push --tags && npm publish"
29+
"build": "node -e \"fs.writeFileSync('index.cjs',fs.readFileSync('index.js','utf8').replace(/export default/,'module.exports ='),'utf8')\"",
30+
"deploy": "npm test && git commit --all --message $tag && git tag --sign $tag --message $tag && git push && git push --tags",
31+
"release": "tag=$npm_package_version npm run deploy && npm publish --access public",
32+
"prepare": "npm run build"
3133
},
3234
"devDependencies": {
3335
"c8": "*",
34-
"rollup": "*",
35-
"terser": "*",
3636
"twist": "*"
3737
}
3838
}

src/index.js

Lines changed: 0 additions & 19 deletions
This file was deleted.

0 commit comments

Comments
 (0)