Skip to content

Latest commit

 

History

History
170 lines (118 loc) · 3.49 KB

README.md

File metadata and controls

170 lines (118 loc) · 3.49 KB

class-c

Chainable class name helper with first class CSS Module support

Installation

$ npm install class-c

Usage

Basic

c uses the tagged template syntax

import c from "class-c";

c`a b`; // => "a b"

// Extra whitespace will be removed
c`   a     b    `; // => "a b"
c`
  a
  b
`; // => "a b"

// Calling with a string can be useful for class forwarding, see CSS Modules section
c("a b"); // => "a b"

Function values

Functions passed into the template will be unwrapped to their return value

import c from "class-c";

c`a ${() => "b"}`; // => "a b"

Chaining

You can chain as many scopes as you'd like

c`a`.c`b c`.c`d`; // => "a b c d"

// This is more useful when used with CSS Modules, see CSS Modules section for more details
const styles = {
  a: "scoped-a",
  b: "scoped-b",
};

c(styles)`a b`.c`a b`; // => "scoped-a scoped-b a b"

Conditionals

Falsey values will be omitted, condition-by-class mapping is also supported. This can be useful with object shorthand. This also supports function conditions.

c`a ${condition && b}`; // => condition ? "a b" : "a"

c`a ${{ b: false, c: true }}`; // => "a c"

const focused = true;
const highlighted = false;
const open = true;

c`${{ focused, highlighted, open }}`; // => "focused open"

// Function conditions
const focused = () => true;
const highlighted = () => false;
const open = () => true;

c`${{ focused, highlighted, open }}`; // => "focused open"

// Function values may also return conditional maps
c`${() => ({ focused, highlighted, open })}`; // => "focused open"

CSS Modules

Calling c with a styles object will create a scoped context

const styles = {
  a: "scoped-a",
  b: "scoped-b",
};

c(styles)`a b`; // => "scoped-a scoped-b"

Chaining

Chaining will reset context which can be useful for forwarding classes

c(styles)`a b`.c`a b`; // => "scoped-a scoped-b a b"

// Forwarding classes
const someExternalClasses = "external-a external-b";
c(styles)`a b`.c(someExternalClasses); // => "scoped-a scoped-b external-a external-b"

Many references

If you need to use a context in many places, it can be convenient to make a new helper

const cs = c(styles);

cs`a`; // => "scoped-a"

// Chaining will still reset context
cs`b`.c`c`; // => "scoped-b"

Multiple modules/styles objects

const otherStyles = {
  a: "other-a",
  b: "other-b",
};

c(styles)`a b`.c(otherStyles)`a b`; // => "scoped-a scoped-b other-a other-b"
// Non existant classes will be removed
c(styles)`a nonexistant b`; // => "scoped-a scoped-b"

Prefixing and suffixing

const styles = {
  variant_a: "scoped-variant_a",
  variant_b: "scoped-variant_b",
};

const variant: "a" | "b" = "a";

c(styles)`variant_${variant}`; // => "scoped-variant_a"

const suffixStyles = {
  a_suffix: "scoped-a_suffix",
  b_suffix: "scoped-b_suffix",
};

c(suffixStyles)`${variant}_suffix`; // => "scoped-variant_a"