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

tailwind-plugin-css-themes

v0.1.2

Published

Tailwind themes with CSS variables.

Downloads

52

Readme

tailwind-plugin-css-themes

A Tailwind CSS plugin to create themes using CSS classes and variables.

Overview

Tailwind offers a "dark mode" feature, but that's not a true design system theme. CSS variable theming simplifies color management and developer experience by mapping semantic color names to existing design system color scales. Changing a theme becomes as simple as changing one CSS classes.

Tailwind CSS "theming" with Dark Mode

<!-- Card example w/ Tailwind CSS dark mode -->

<div class="bg-gray-900 dark:bg-gray-100 p-12">
  <h3 class="text-white dark:text-black">Card w/ light theme</h3>
  <p class="text-white/70 dark:text-black/70">
    This card example is styled using Tailwind's default color values with dark
    utility classes to modify the colors for dark mode.
  </p>
  <button class="text-blue-600 dark:text-blue-400">Action text</button>
</div>

In the "dark mode" approach, every color classes needs a dark: alternative color, resulting in twice the number of classes across your entire code base.

Tailwind CSS theming with this plugin

<!-- Card example w/ light theme -->

<div class="theme--light bg-background-primary p-12">
  <h3 class="text-content-primary">Card w/ light theme</h3>
  <p class="text-content-secondary">
    This card example is styled using Tailwind color values that were set up for
    you when you installed the plugin.
  </p>
  <button class="text-action">Action text</button>
</div>
<!-- Card example w/ dark theme -->

<div class="theme--dark bg-background-primary p-12">
  <h3 class="text-content-primary">Card w/ light theme</h3>
  <p class="text-content-secondary">
    This card example is styled using Tailwind color values that were set up for
    you when you installed the plugin.
  </p>
  <button class="text-action">Action text</button>
</div>

In the theme approach, we avoid dark: classes altogether in favor of the semantic theme class names with a single theme class to define the color mapping. The 2 components above share the same HTML, but the theme class name on the parent div sets the right theme values for all of the nested semantic class names.

Here's the same example in React TypeScript:

function Card({ theme }: { theme: "theme--light" | "theme--dark" }) {
  return (
    <div className={`${themeClass} p-12 bg-background-primary`}>
      <h3 className="text-content-primary">Card w/ {theme} theme</h3>
      <p className="text-content-secondary">
        This card example is styled using Tailwind color values that were set up
        for you when you installed the plugin.
      </p>
      <button className="text-action">Action text</button>
    </div>
  );
}

<!-- Card example w/ light theme -->
<Card theme="theme--light" />

<!-- Card example w/ dark theme -->
<Card theme="theme--dark" />

Usage

Installation

This installation assumes you have already installed Tailwind CSS in your project. See the official Tailwind CSS docs for more information.

Install plugin

npm install -D tailwind-plugin-css-themes

Note: tailwindcss is a peer dependency, so you need to have it installed.

Add the plugin to your Tailwind config

// tailwind.config.js

plugins: [require("tailwind-plugin-css-themes").default({})];

The plugin ships with a very basic light and dark theme by default. Once you add the plugin to your config, you can start using it in your HTML.

<!-- Card example w/ light theme -->

<div class="theme--light bg-background-primary">
  <h3>Card w/ light theme</h3>
  <p class="text-content-primary">
    This card example is styled using Tailwind color values that were set up for
    you when you installed the plugin.
  </p>
</div>

Themes

Themes are created similar to how you would add colors to your Tailwind config. Pass an object into the plugin containing a themes function. Create themes by returning an object of theme names containing custom color names (tokens) and values.

// tailwind.config.js

plugins: [
  require("tailwind-plugin-css-themes").default({
    themes: (colors) => {
      return {
        light: {
          "background-primary": colors?.zinc[100],
          "background-secondary": colors?.zinc[200],
          "content-primary": colors?.zinc[900],
          "content-secondary": colors?.zinc[700],
          accent: colors?.indigo[600],
        },
        dark: {
          "background-primary": colors?.zinc[900],
          "background-secondary": colors?.zinc[800],
          "content-primary": colors?.zinc[100],
          "content-secondary": colors?.zinc[300],
          accent: colors?.indigo[400],
        },
      };
    },
  }),
];

Behind the scenes, the plugin turns your themes into Tailwind component styles, which lets us apply the themes using CSS classes. The resulting CSS looks like this:

.theme--light {
  --background-primary: 244 244 245;
  --background-secondary: 228 228 231;
  --content-primary: 24 24 27;
  --content-secondary: 63 63 70;
  --accent: 99 102 241;
}
.theme--dark {
  --background-primary: 24 24 27;
  --background-secondary: 39 39 42;
  --content-primary: 244 244 245;
  --content-secondary: 212 212 216;
  --accent: 129 140 248;
}

Notice that the plugin prefixes your theme names with .theme--. This is simply a convention to prevent class name conflicts. You can change it by passing a prefix string into the plugin options.

We also convert the color values to RGB to ensure that Tailwind's text opacity modifiers remain working.

<!-- Using color tokens with opacity -->

<div class="theme--dark bg-background-primary p-12">
  <p class="text-content-primary/60">
    This text would be displayed in the text-content-primary color at 60%
    opacity.
  </p>
</div>

Development

This package is written in TypeScript and uses dnt (Deno to Node Transform) to build the package for NPM.

Install deno

See the official deno installation guide.

Build package locally in TypeScript, ESM, CJS

deno run -A scripts/build.ts

■ ■ ■ □