0.1.0 • Published 11 months ago

outclass v0.1.0

Weekly downloads
-
License
MIT
Repository
-
Last release
11 months ago

Outclass

Currently in pre-release version, expect breaking changes.

Outclass is a CSS class string manipulation tool, it allows you to define classes in a dynamic and composable way. For example:

import { out } from "outclass";

out.parse("flex rounded", "p-2");
// flex rounded p-2

out.parse([
    "w-32 h-32"
    isActive ? "cursor-pointer" : "cursor-not-allowed",
    isDirty && "border-2",
]);
// w-32 h-32 cursor-pointer, when isActive is true and isDirty is false

const customStyle = out.remove("p-2").add("p-4");
out.apply(customStyle).parse("flex p-2");
// flex p-4

Outclass is especially useful when used with atomic or utility-first CSS frameworks such as TailwindCSS and UnoCSS, read the documentation or try the playground on CodeSandbox.

Main features

  • Zero dependencies
  • Framework agnostic
  • Fully typed
  • Fully tested
  • Tiny: ~ 1KB minified + brotli

Installation

Node

npm  add outclass
yarn add outclass
pnpm add outclass

Bun

bun add outclass

Deno

import { out } from "https://esm.sh/gh/b1n01/outclass";

In the browser

<script type="module">
  import { out } from "https://esm.sh/gh/b1n01/outclass";
  out.parse("flex");
</script>

Documentation

All methods are exposed by the out object, which can be imported from the outclass module:

// Local esm module
import { out } from "outclass";

// Remote esm module
import { out } from "https://esm.sh/gh/b1n01/outclass";

// CommonJs
const { out } = require("outclass");

Parsing

Generally speaking the core functionality is converting some input into a single string consisting of a space-separated list of unique CSS classes, where the order of the input is preserved and, in case of duplicate values, only the first instance is kept.

For this purpose there is the parse method. It takes strings and arrays of strings as input, also handling nested values:

out.parse("flex p-2");
// flex p-2

out.parse("rounded", "m-4");
// rounded m-4

out.parse(["border-2", "h-8"]);
// border-2 h-8

out.parse(["drop-shadow"], ["opacity-50"]);
// drop-shadow opacity-50

out.parse([["bg-cover"]]);
// bg-cover

It also takes null, undefined and boolean values, empty strings and empty arrays, so it can be used with the && operator and ?. optional chaining:

out.parse("", null, undefined, true, false, []);
// ""

const props = { classes: "bg-slate-700" };
out.parse(isMuted && "cursor-not-allowed", props?.classes);
// cursor-not-allowed bg-slate-700, when isMuted is true

Building

The out object is also a builder, which meas it offers some "actions" methods to dynamically build string of classes: add, remove and set, respectively to add, remove and overwrite classes.

out.add("flex p-2").remove("p-2").parse();
// flex

out.add("h-12 bg-violet-400").set("rounded").parse();
// rounded

Actions accepts the same arguments as the parse method does:

out.add(["clear-right", ["columns-2"]]).parse();
// clear-right columns-2

Combining actions methods with the parse method results in the parse method to act as the add method:

out.add("place-self-start").parse("m-4");
// place-self-start m-4

Immutability

Actions methods always return a new instance of out, making it immutable:

const style = out.add("text-end");

out.parse();
// ""

style.parse();
// text-end

This, as already shown in the examples, allows for method chaining:

out.set("box-content p-4").add("inline").apply(out.remove("p-4")).parse();
// box-content inline

Compose

Object of type out can be composed together using the apply method.

const style = out.add("tracking-wide");
out.apply(style).parse();
// tracking-wide

Applied classes are queued up and evaluated after the classes of the main object:

out.apply(out.remove("m-2")).add("self-end m-2").parse();
// self-end

Composability is not limited to one level of depth:

out.apply(out.apply(out.add("flex"))).parse();
// flex

Actions map

To apply multiple actions in a single method call you can use the with method. It takes an "actions map" which is an object that contains multiple actions:

out
  .with({
    set: "space-x-4",
    add: "flex-wrap overflow-clip",
    remove: "flex-wrap",
    apply: out.add("order-4"),
  })
  .parse();
// space-x-4 overflow-clip order-4

Actions map can also be used as parameters of the parse method:

out.parse({ add: "grow", apply: out.add("order-8")}):
// grow order-8

Integrations

VS Code TailwindCSS IntelliSense

To enable TailwindCSS IntelliSense on Outclass methods calls, add this regex to your .vscode/settings.json:

{
  "tailwindCSS.experimental.classRegex": [
    // Enable IntelliSense on Outclass method calls outside "className" and "class" attributes
    [
      "\\.(?:parse|add|remove|set|with)\\s*\\(\\s*([\\s\\S]*?)\\s*\\)\\s*",
      "[\"'`]([^\"'`]*)[\"'`]"
    ]
  ]
}