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

ve-theme-variants

v0.0.3

Published

Simplifies creation of theme based token variants for Vanilla Extract

Downloads

5

Readme

Vanilla Extract Theme Variants

A helper for creating theme based token variants for Vanilla Extract.

Usage

npm i ve-theme-variants

See the Next example app for a full example.

What is it?

These functions just abstract away a bit of the theming paradigm I use with Vanilla Extract.

You define component level variants for use in recipe(), stylevariants() or style() in the theme directly. They don't have to by actual style rules but that's how I like to do it, so I can just spread the vars into style without any manipulation.

Here's a pseudo example of how you might create a Surface component with this method

// surfaceVariants.ts
export const surfaceVariants = {
  light: {
    surface0: { backgroundColor: color["zinc-100"] },
    surface1: { backgroundColor: color["zinc-200"] },
    surface2: { backgroundColor: color["zinc-300"] },
  },
  dark: {
    surface0: { backgroundColor: color["zinc-950"] },
    surface1: { backgroundColor: color["zinc-900"] },
    surface2: { backgroundColor: color["zinc-800"] },
  },
};
// theme.css.ts
export const { themeVars } = createThemeVariants(surfaceVariantsContract, [
  surfaceVariants,
]);
// surface.css.ts
export const surface = recipe({
  variants: {
    level: {
      0: style(themeVars.surface0),
      1: style(themeVars.surface1),
      2: style(themeVars.surface2),
    },
  },
  defaultVariants: {
    level: 0,
  },
});

createThemeVariants()

// theme.css.ts

import { createThemeVariants } from "ve-theme-variants";

export const { themeVars, themeClasses, themeSelectors } = createThemeVariants(
  // this is the theme contract
  {
    brand: {
      primary: "null",
    },
    surface: {
      1: {
        background: "null",
      },
      2: {
        background: "null",
      },
    },
  },
  // these are the themed variants.
  // this is an array so you can create each
  // variant in isolation.
  [
    // brand
    {
      light: {
        brand: {
          primary: "blue",
        },
      },
      dark: {
        brand: {
          primary: "darkblue",
        },
      },
    },
    // surface
    {
      light: {
        surface: {
          1: {
            background: "#FFFFFF",
          },
          2: {
            background: "#F8F8F8",
          },
        },
      },
      dark: {
        surface: {
          1: {
            background: "#000000",
          },
          2: {
            background: "#0C090A",
          },
        },
      },
    },
  ]
);

Return type

the function returns an object with these properties:

  • themeVars are the css variables you can import and use in your css.ts files e.g themeVars.brand.primary = 'var(--brand-primary)'
  • themeClasses are the classes which when applied, will use that theme key's variants e.g if you apply themeClasses.dark to the body, dark variants will be used throughout. You can also apply a theme class to a nested element if you want to force that theme for a particular tree.
  • themeSelectors are the theme classes with & included, for targeting a theme in the Vanilla Extract style function.

Using your own mapFn

By default createThemeVariants maps the variable names to kebab-case (using just-kebab-case), and strips out selectors and :& from style keys.

You can pass a mapFn as the 3rd argument if you want to customize this

  createThemeVariants(contract, tokens,  (_value, path) => path.join("_").replace(/[&:,.()]+/g, "")

See Formatting the variable names

Using your own theme keys

By default createThemeVariants expects light and dark theme keys. You can pass your own union type into the function like this:

const themeVariants = createThemeVariants<
  "dark" | "light" | "print" | "high-contrast"
>();

createRootTheme()

A light wrapper on top of createGlobalThemeContract that applies the provided tokens to the :root and formats them to kebab case.

createRootTheme also takes an optional mapFn argument to customize the mapping.

// root.css.ts

import { createRootTheme } from "ve-theme-variants";

export const { color } = createRootTheme({
  color: {
    primary: "blue",
  },
});

// color.primary === 'var(--color-primary)'