Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: lukeed/clsx
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: c5b2b21ab8aea48ff0b48649f386a2c7280fabf2
Choose a base ref
...
head repository: lukeed/clsx
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 6da37d67472ea9eb177a4ea9a9fa2f3f4a3c445e
Choose a head ref
  • 10 commits
  • 9 files changed
  • 3 contributors

Commits on Aug 19, 2020

  1. chore: enable sponsor button

    lukeed authored Aug 19, 2020
    Copy the full SHA
    400b848 View commit details

Commits on Mar 19, 2021

  1. chore: update "string variadic" tests (#30)

    * tests: test string variadic w/ actual variable string args
    
    * fix(test): prevent syntax error
    
    Co-authored-by: Luke Edwards <luke.edwards05@gmail.com>
    gingerrific and lukeed authored Mar 19, 2021
    Copy the full SHA
    74cefa6 View commit details

Commits on Jul 2, 2022

  1. feat: add named clsx export alias (#44)

    * Provide named export for clsx
    
    * update readme
    
    * update types
    
    * update test file
    
    Co-authored-by: Luke Edwards <luke.edwards05@gmail.com>
    danikaze and lukeed authored Jul 2, 2022
    Copy the full SHA
    56ab81f View commit details
  2. chore: update CI matrix

    lukeed committed Jul 2, 2022
    Copy the full SHA
    bc4f827 View commit details
  3. chore: tape -> uvu tests

    lukeed committed Jul 2, 2022
    Copy the full SHA
    1c36d10 View commit details
  4. 1.2.0

    lukeed committed Jul 2, 2022
    Copy the full SHA
    89407de View commit details

Commits on Jul 5, 2022

  1. chore: build CJS & UMD files manually;

    - mixed exports (named + default) broke old bundt... because it's discouraged
    - closes #50
    lukeed committed Jul 5, 2022
    Copy the full SHA
    3712966 View commit details

Commits on Jul 6, 2022

  1. chore(bin): mkdir if missing

    lukeed committed Jul 6, 2022
    Copy the full SHA
    2114f5b View commit details
  2. chore: revert version bump

    lukeed committed Jul 6, 2022
    Copy the full SHA
    62d6071 View commit details
  3. 1.2.1

    lukeed committed Jul 6, 2022
    Copy the full SHA
    6da37d6 View commit details
Showing with 161 additions and 134 deletions.
  1. +1 −0 .github/FUNDING.yml
  2. +10 −7 .github/workflows/ci.yml
  3. +38 −0 bin/index.js
  4. +3 −8 clsx.d.ts
  5. +5 −7 package.json
  6. +2 −0 readme.md
  7. +3 −1 src/index.js
  8. +39 −51 test/classnames.js
  9. +60 −60 test/index.js
1 change: 1 addition & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
github: lukeed
17 changes: 10 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -8,10 +8,10 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
nodejs: [6, 8, 10, 12]
nodejs: [8, 10, 12, 14, 16]
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: ${{ matrix.nodejs }}

@@ -25,19 +25,22 @@ jobs:
run: npm install

- name: (coverage) Install
if: matrix.nodejs >= 12
if: matrix.nodejs >= 16
run: npm install -g nyc

- name: Build
run: npm run build

- name: Test
run: npm test
if: matrix.nodejs < 12
if: matrix.nodejs < 16

- name: (coverage) Test
run: nyc --include=src npm test
if: matrix.nodejs >= 12
if: matrix.nodejs >= 16

- name: (coverage) Report
if: matrix.nodejs >= 12
if: matrix.nodejs >= 16
run: |
nyc report --reporter=text-lcov > coverage.lcov
bash <(curl -s https://codecov.io/bash)
38 changes: 38 additions & 0 deletions bin/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// @ts-check
const fs = require('fs');
const zlib = require('zlib');
const { minify } = require('terser');
const pkg = require('../package.json');

if (!fs.existsSync('dist')) fs.mkdirSync('dist');

/**
* @param {string} file
* @param {string} source
*/
function write(file, source) {
let isModule = !source.startsWith('!function');
let result = minify(source, {
module: isModule,
compress: true,
});

fs.writeFileSync(file, result.code);
console.log('~> "%s" (%d b)', file, zlib.gzipSync(result.code).byteLength);
}

let input = fs.readFileSync('src/index.js', 'utf8');

// copy for ESM
write(pkg.module, input);

// transform ESM -> CJS exports
write(pkg.main, input.replace('export function', 'function').replace(
'export default clsx;',
'module.exports = clsx;\n'
+ 'module.exports.clsx = clsx;'
));

// transform ESM -> UMD exports
input = input.replace('export function', 'function').replace('export default clsx;', 'return clsx.clsx=clsx, clsx;');
write(pkg.unpkg, '!function(global,factory){"object"==typeof exports&&"undefined"!=typeof module?module.exports=factory():"function"==typeof define&&define.amd?define(factory):global.clsx=factory()}(this,function(){' + input + '});');
11 changes: 3 additions & 8 deletions clsx.d.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
export type ClassValue = ClassArray | ClassDictionary | string | number | null | boolean | undefined;
export type ClassDictionary = Record<string, any>;
export type ClassArray = ClassValue[];

export interface ClassDictionary {
[id: string]: any;
}

export interface ClassArray extends Array<ClassValue> { }

declare const clsx: (...classes: ClassValue[]) => string;

export declare function clsx(...inputs: ClassValue[]): string;
export default clsx;
12 changes: 5 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "clsx",
"version": "1.1.1",
"version": "1.2.1",
"repository": "lukeed/clsx",
"description": "A tiny (228B) utility for constructing className strings conditionally.",
"module": "dist/clsx.m.js",
@@ -17,9 +17,8 @@
"node": ">=6"
},
"scripts": {
"build": "bundt",
"pretest": "npm run build",
"test": "tape -r esm test/*.js | tap-spec"
"build": "node bin",
"test": "uvu -r esm test"
},
"files": [
"*.d.ts",
@@ -31,9 +30,8 @@
"classnames"
],
"devDependencies": {
"bundt": "1.0.1",
"esm": "3.2.25",
"tap-spec": "5.0.0",
"tape": "4.9.1"
"terser": "4.8.0",
"uvu": "0.5.4"
}
}
2 changes: 2 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
@@ -20,6 +20,8 @@ $ npm install --save clsx

```js
import clsx from 'clsx';
// or
import { clsx } from 'clsx';

// Strings (variadic)
clsx('foo', true && 'bar', 'baz');
4 changes: 3 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@ function toVal(mix) {
return str;
}

export default function () {
export function clsx() {
var i=0, tmp, x, str='';
while (i < arguments.length) {
if (tmp = arguments[i++]) {
@@ -38,3 +38,5 @@ export default function () {
}
return str;
}

export default clsx;
90 changes: 39 additions & 51 deletions test/classnames.js
Original file line number Diff line number Diff line change
@@ -2,84 +2,71 @@
* Ported from `classnames` for compatibility checks.
*/

import test from 'tape';
import fn from '../src';
import { test } from 'uvu';
import * as assert from 'uvu/assert';
import clsx from '../src';

test('(compat) keeps object keys with truthy values', t => {
const out = fn({ a:true, b:false, c:0, d:null, e:undefined, f:1 });
t.is(out, 'a f');
t.end();
test('(compat) keeps object keys with truthy values', () => {
const out = clsx({ a:true, b:false, c:0, d:null, e:undefined, f:1 });
assert.is(out, 'a f');
});

test('(compat) joins arrays of class names and ignore falsy values', t => {
const out = fn('a', 0, null, undefined, true, 1, 'b');
t.is(out, 'a 1 b');
t.end();
test('(compat) joins arrays of class names and ignore falsy values', () => {
const out = clsx('a', 0, null, undefined, true, 1, 'b');
assert.is(out, 'a 1 b');
});

test('(compat) supports heterogenous arguments', t => {
t.is(fn({ a:true }, 'b', 0), 'a b');
t.end();
test('(compat) supports heterogenous arguments', () => {
assert.is(clsx({ a:true }, 'b', 0), 'a b');
});

test('(compat) should be trimmed', t => {
t.is(fn('', 'b', {}, ''), 'b');
t.end();
test('(compat) should be trimmed', () => {
assert.is(clsx('', 'b', {}, ''), 'b');
});

test('(compat) returns an empty string for an empty configuration', t => {
t.is(fn({}), '');
t.end();
test('(compat) returns an empty string for an empty configuration', () => {
assert.is(clsx({}), '');
});

test('(compat) supports an array of class names', t => {
t.is(fn(['a', 'b']), 'a b');
t.end();
test('(compat) supports an array of class names', () => {
assert.is(clsx(['a', 'b']), 'a b');
});

test('(compat) joins array arguments with string arguments', t => {
t.is(fn(['a', 'b'], 'c'), 'a b c');
t.is(fn('c', ['a', 'b']), 'c a b');
t.end();
test('(compat) joins array arguments with string arguments', () => {
assert.is(clsx(['a', 'b'], 'c'), 'a b c');
assert.is(clsx('c', ['a', 'b']), 'c a b');
});

test('(compat) handles multiple array arguments', t => {
t.is(fn(['a', 'b'], ['c', 'd']), 'a b c d');
t.end();
test('(compat) handles multiple array arguments', () => {
assert.is(clsx(['a', 'b'], ['c', 'd']), 'a b c d');
});

test('(compat) handles arrays that include falsy and true values', t => {
t.is(fn(['a', 0, null, undefined, false, true, 'b']), 'a b');
t.end();
test('(compat) handles arrays that include falsy and true values', () => {
assert.is(clsx(['a', 0, null, undefined, false, true, 'b']), 'a b');
});

test('(compat) handles arrays that include arrays', t => {
t.is(fn(['a', ['b', 'c']]), 'a b c');
t.end();
test('(compat) handles arrays that include arrays', () => {
assert.is(clsx(['a', ['b', 'c']]), 'a b c');
});

test('(compat) handles arrays that include objects', t => {
t.is(fn(['a', { b:true, c:false }]), 'a b');
t.end();
test('(compat) handles arrays that include objects', () => {
assert.is(clsx(['a', { b:true, c:false }]), 'a b');
});

test('(compat) handles deep array recursion', t => {
t.is(fn(['a', ['b', ['c', { d:true }]]]), 'a b c d');
t.end();
test('(compat) handles deep array recursion', () => {
assert.is(clsx(['a', ['b', ['c', { d:true }]]]), 'a b c d');
});

test('(compat) handles arrays that are empty', t => {
t.is(fn('a', []), 'a');
t.end();
test('(compat) handles arrays that are empty', () => {
assert.is(clsx('a', []), 'a');
});

test('(compat) handles nested arrays that have empty nested arrays', t => {
t.is(fn('a', [[]]), 'a');
t.end();
test('(compat) handles nested arrays that have empty nested arrays', () => {
assert.is(clsx('a', [[]]), 'a');
});

test('(compat) handles all types of truthy and falsy property values as expected', t => {
const out = fn({
test('(compat) handles all types of truthy and falsy property values as expected', () => {
const out = clsx({
// falsy:
null: null,
emptyString: '',
@@ -100,6 +87,7 @@ test('(compat) handles all types of truthy and falsy property values as expected
greaterZero: 1
});

t.is(out, 'nonEmptyString whitespace function emptyObject nonEmptyObject emptyList nonEmptyList greaterZero');
t.end();
assert.is(out, 'nonEmptyString whitespace function emptyObject nonEmptyObject emptyList nonEmptyList greaterZero');
});

test.run();
Loading