Skip to the code
cf.

classNames

Write classNames(...args). It builds a class attribute value from any mix of arguments and returns the class names joined with single spaces, in the order they appear.

A non-empty string, or a number other than 0, is added as it is. An object adds each of its own enumerable keys whose value is truthy, in key order. An array is handled as if its items had been passed as arguments, at any depth. Everything else is skipped: false, null, undefined, 0, NaN, "", and true.

The result never has leading, trailing, or double spaces, and with nothing to add it's "". Duplicates are kept.

classNames("btn", { active: true, disabled: false }, ["lg", null]);
// "btn active lg"
classNames("card", isOpen && "open");
// "card open", or "card" when isOpen is false

What the tests check

  1. joins strings with single spaces
    expect(classNames("btn", "primary")).toBe("btn primary");
    expect(classNames("one")).toBe("one");
    
  2. adds the object keys whose values are truthy
    expect(classNames({ active: true, disabled: false, open: 1, hidden: null, "is-new": "yes" })).toBe("active open is-new");
    
  3. flattens arrays at any depth
    expect(classNames(["a", ["b", [{ c: true, x: false }]]], "d")).toBe("a b c d");
    
  4. skips falsy values and true
    expect(classNames(null, "a", false, undefined, 0, "", true, NaN, "b")).toBe("a b");
    
  5. keeps numbers other than 0
    expect(classNames("col", 12, 0)).toBe("col 12");
    
  6. keeps the order of arguments and keys
    expect(classNames({ b: true }, "a", { d: true, c: true })).toBe("b a d c");
    
  7. never adds stray spaces
    expect(classNames()).toBe("");
    expect(classNames(false, "a", null)).toBe("a");
    expect(classNames("", [], {}, "b", [null, false])).toBe("b");
    expect(classNames([null, false], { off: false })).toBe("");
    

Learn more

solution.jsSaved in this browser

Run tests runs every test on your code, here in your browser. The problem is solved when they all pass.

Ctrl + Enter runs the tests (⌘ + Enter on a Mac).