npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

outclass

v0.2.0

Published

CSS class manipulation tool

Downloads

3

Readme

Outclass

npm dependencies npm bundle size npm license

Currently in pre-release version, expect breaking changes.

Outclass is a CSS class manipulation tool. It can be used to create strings of CSS classes dynamically, for example:

import { out } from "outclass";

// Generates a string of unique class names
out.parse("flex", "rounded", "flex");
// flex rounded

// Implements the builder pattern
out.set("blur w-4").remove("w-4").add("shadow w-2").parse();
// blur shadow w-2

// Has a variants system
out.variant({ sm: "p-2", lg: "p-4" }).choose("sm").parse();
// p-2

// Is patchable
const patch = out.remove("m-2").add("m-4");
out.set("border m-2").apply(patch).parse();
// border m-4

// All in a single call
out.parse({
  add: "m-4",
  apply: patch,
  variant: { sm: "p-2", lg: "p-4" },
  choose: "sm",
});
// m-4 p-2

Installation

Outclass is available on npm as ECMAScript module (ESM) and works on any JavaScript runtime:

# Node.js
npm add outclass
pnpm add outclass
yarn add outclass

# Deno
deno add npm:outclass

# Bun
bun add outclass

And in the browser:

<script type="module">
  import { out } from "https://esm.sh/outclass";
</script>

The out object can be imported from the outclass module:

import { out } from "outclass";

Documentation

Outclass lets you to create strings of CSS classes. Internally it keeps a list of classes and offers methods to manipulate it. The parse method returns a single string consisting of a space-separated list of unique CSS classes, which can be used in the class attribute of HTML elements.

There are two main ways of use, which can be combined as desired:

  • A builder: to programmatically add and remove classes
  • A variant system: to specify and select style variants

Inputs

Most methods takes as arguments multiple strings and arrays of strings (infinitely nested):

out.parse("flex", ["grow"], [["p-2"]]);
// flex grow p-2

Each input string is splitted into single classes on white-spaces:

out.add("flex grow").remove("grow").remove("flex").parse();
// ""

It only understand string inputs, but for convenience it also takes, null, undefined and boolean values, so it can be used with the && operator and ?. optional chaining:

const isMuted = false;
const props = { classes: "bg-slate-700" };
out.parse([
  isMuted && "cursor-not-allowed",
  props?.classes,
  [null, undefined, false, true],
]);
// bg-slate-700 flex grow

Immutability

The out object is immutable, each call to its methods returns a new instance:

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

out.parse();
// ""

style.parse();
// text-end

This makes it more convenient as you can use it directly in method chaining without the need to create new instances of it every time:

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

Using the builder

The out object implements the builder pattern, the add and remove methods add and remove classes respectively, the set method replaces the current list of classes with a new one:

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

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

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

Using variants

The variant method is used to specify variants of style, for example a size variant can have options small and large and a color variant can have options violet and blue. The choose method selects which variants to use. Only one option per variant can be selected at a time:

out
  .variant({ small: "p-2", large: "p-4" })
  .variant({ violet: "bg-violet-500", blue: "bg-blue-500" })
  .choose("small blue")
  .parse();
// p-2 bg-violet-500

Variants can have compound options, which are option with multiple names separated by spaces. Compound options are selected when all names are passed to the choose method:

out
  .variant({ small: "p-2", large: "p-4" })
  .variant({ violet: "bg-violet-500", blue: "bg-blue-500" })
  .variant({ "small violet": "rounded" })
  .choose("small violet")
  .parse();
// p-2 bg-violet-500 rounded

The choose method can be called multiple times to change the selected variants, this means that it can be used to specify the default variant and then change it later:

out
  .variant({ small: "p-2", large: "p-4" })
  .choose("small")
  .choose("large", "small")
  .parse();
// p-2

Patching

The apply method is used to apply patches to the list of classes. Patches are evaluated last, after manipulation of the main object are, and the order they are applied is kept. A patch simply is a out object:

const patch = out.remove("m-2").add("m-4");
out.set("border m-2").apply(patch).parse();
// border m-4

const pick = out.choose("small");
out.variant({ small: "p-2", large: "p-4" }).choose("large").apply(pick).parse();
// p-2

All in a single call

All functionality can be combined in a single call to the with method, which takes an object where each key is a method name and the value is the arguments to pass to that method:

// All in a single call
out
  .with({
    set: "grid grow"
    remove: "grid",
    add: "flex",
    apply: out.choose("small"),
    variant: { sm: "p-2", lg: "p-4" },
    choose: "large",
  })
  .parse();
// grow flex p-4

The parse method

The parse can be called with no arguments to get the current list of classes, but it can also be called with a string, in which case it acts as the add method, or with an object, in which case it acts as the with method:

out.set("flex").parse("grow");
// flex grow

out.set("flex").parse({
  add: "m-4",
  variant: { sm: "p-2", lg: "p-4" },
  choose: "sm",
});
// flex m-4 p-2

TailwindCSS

Outclass is especially useful when used with atomic or utility-first CSS frameworks such as TailwindCSS. To enable VS Code IntelliSense for TailwindCSS classes, 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*",
      "[\"'`]([^\"'`]*)[\"'`]"
    ]
  ]
}

Acknowledgements

Inspiration for this project comes mainly from the amazing job done by cva and clsx.