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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@zentrades-ui/theme

v0.2.1

Published

Theme runtime for Zen UI.

Downloads

594

Readme

@zentrades-ui/theme

React theme provider for Zen UI components. Provides light/dark mode support and custom theme overrides.

Installation

pnpm add @zentrades-ui/theme

Basic Usage

Wrap your application with ThemeProvider:

import { ThemeProvider } from "@zentrades-ui/theme";

function App() {
  return (
    <ThemeProvider theme="light">
      <YourApp />
    </ThemeProvider>
  );
}

Theme Modes

The provider supports light, dark, and system modes:

// Light mode
<ThemeProvider theme="light">

// Dark mode
<ThemeProvider theme="dark">

// Follow system preference
<ThemeProvider theme="system">

Dynamic Theme Switching

Use the useTheme hook to access and change the current theme:

import { useTheme } from "@zentrades-ui/theme";

function ThemeToggle() {
  const { theme, effectiveTheme, setTheme, toggleTheme } = useTheme();

  return (
    <div>
      <p>Current setting: {theme}</p>
      <p>Effective theme: {effectiveTheme}</p>
      <button onClick={toggleTheme}>Toggle Theme</button>
      <button onClick={() => setTheme("system")}>Use System</button>
    </div>
  );
}

Note: To use setTheme or toggleTheme, you must provide an onThemeChange handler to ThemeProvider:

function App() {
  const [theme, setTheme] = useState<"light" | "dark" | "system">("light");

  return (
    <ThemeProvider theme={theme} onThemeChange={setTheme}>
      <YourApp />
    </ThemeProvider>
  );
}

Custom Theme Overrides

You can customize colors, typography, spacing, and borders while keeping the rest of the Zen UI defaults:

import { ThemeProvider, type CustomTheme } from "@zentrades-ui/theme";

const myBrandTheme: CustomTheme = {
  // Color overrides (supports light/dark modes)
  colors: {
    light: {
      backgroundBrand: "#0066cc",
      backgroundBrandHover: "#0055aa",
      backgroundBrandPressed: "#004488",
      contentBrand: "#0066cc",
      borderBrand: "#0066cc",
    },
    dark: {
      backgroundBrand: "#3399ff",
      backgroundBrandHover: "#66b3ff",
      backgroundBrandPressed: "#99ccff",
      contentBrand: "#3399ff",
      borderBrand: "#3399ff",
    },
  },

  // Typography overrides (mode-independent)
  typography: {
    fontFamilies: {
      geist: "Inter, system-ui, sans-serif",
    },
    fontSizes: {
      m: "0.875rem",
    },
  },

  // Spacing overrides (mode-independent)
  spacing: {
    sm: "0.5rem",
    md: "1rem",
    lg: "1.5rem",
  },

  // Border overrides (mode-independent)
  borders: {
    radii: {
      md: "8px",
      lg: "12px",
    },
  },
};

function App() {
  return (
    <ThemeProvider theme="light" customTheme={myBrandTheme}>
      <YourApp />
    </ThemeProvider>
  );
}

How Custom Themes Work

  1. The default Zen UI theme is always applied as the base
  2. Your customTheme overrides only the specific tokens you define
  3. Switching between light/dark mode automatically applies the correct custom values
  4. TypeScript provides autocomplete for all available tokens

Available Tokens

You can import token lists to see all available options:

import {
  customizableColorTokens,
  customizableSpacingTokens,
  customizableFontSizeTokens,
  customizableLineHeightTokens,
  customizableFontWeightTokens,
  customizableFontFamilyTokens,
  customizableBorderRadiusTokens,
  customizableBorderWidthTokens,
} from "@zentrades-ui/theme";

console.log(customizableColorTokens);
// ['contentPrimary', 'contentSecondary', 'backgroundBrand', ...]

console.log(customizableSpacingTokens);
// ['none', '2xs', 'xs', 'sm', 'md', 'lg', 'xl', '2xl', ...]

console.log(customizableFontFamilyTokens);
// ['geist', 'mono']

Spacing Tokens

  • none, 2xs, xs, sm, md, lg, xl
  • 2xl, 3xl, 4xl, 5xl, 6xl, 7xl, 8xl, 9xl, 10xl, 11xl, 12xl
  • section, page, container

Typography Tokens

Font Families:

  • geist - Primary sans-serif font
  • mono - Monospace font

Font Sizes:

  • xs, s, m, l, xl, 2xl, 3xl, 4xl, 5xl, 6xl, 7xl, 8xl

Font Weights:

  • regular (400), medium (500), semibold (600), bold (700)

Line Heights:

  • xs, s, m, l, xl, 2xl, 3xl, 4xl, 5xl, 6xl, 7xl, 8xl

Letter Spacing:

  • none, xs, s, m

Border Tokens

Border Radius:

  • xs, sm, md, lg, xl, pill, circle

Border Width:

  • none, xs, s, m, l, xl

Content Colors

  • contentPrimary, contentSecondary, contentTertiary, contentQuaternary
  • contentPrimaryInverse, contentSecondaryInverse, contentTertiaryInverse
  • contentBrand, contentSecondaryBrand
  • contentLink, contentLinkHover, contentLinkPressed
  • contentInfo, contentInfoBold
  • contentNotice, contentNoticeBold
  • contentNegative, contentNegativeBold
  • contentPositive, contentPositiveBold
  • contentDisabled, contentDefaultWhite
  • contentAttention, contentActive

Background Colors

  • backgroundPrimary, backgroundSecondary
  • backgroundHover, backgroundPressed, backgroundSelected, backgroundSecondarySelected
  • backgroundBrand, backgroundBrandHover, backgroundBrandPressed
  • backgroundSecondaryBrand, backgroundSecondaryBrandHover, backgroundSecondaryBrandPressed, backgroundSecondaryBrandSubtle
  • backgroundInfo, backgroundInfoSubtle
  • backgroundNotice, backgroundNoticeSubtle
  • backgroundNegative, backgroundNegativeHover, backgroundNegativePressed, backgroundNegativeSubtle
  • backgroundPositive, backgroundPositiveSubtle
  • backgroundInverse, backgroundInverseHover
  • backgroundDisabled
  • backgroundAttention, backgroundActive

Border Colors

  • borderPrimary, borderSecondary, borderTertiary, borderQuaternary
  • borderBrand, borderSecondaryBrand
  • borderFocus, borderInverse, borderDisabled, borderMono
  • borderInfo, borderNotice, borderNegative, borderPositive
  • borderAttention, borderActive

Surface Colors

  • surfaceL0, surfaceL1, surfaceL2, surfaceL3, surfaceL4, surfaceL5, surfaceL6

Overlay Colors

  • overlay50, overlay50Inverse

Example: Complete Brand Customization

import { ThemeProvider, type CustomTheme } from "@zentrades-ui/theme";
import { Button, Input } from "@zentrades-ui/components";

// Blue brand theme
const blueBrandTheme: CustomTheme = {
  light: {
    // Primary brand colors
    backgroundBrand: "#2563eb",
    backgroundBrandHover: "#1d4ed8",
    backgroundBrandPressed: "#1e40af",
    contentBrand: "#2563eb",
    borderBrand: "#2563eb",

    // Selection colors
    backgroundSelected: "#dbeafe",

    // Focus ring
    borderFocus: "#2563eb",
  },
  dark: {
    backgroundBrand: "#3b82f6",
    backgroundBrandHover: "#60a5fa",
    backgroundBrandPressed: "#93c5fd",
    contentBrand: "#3b82f6",
    borderBrand: "#3b82f6",
    backgroundSelected: "#1e3a5f",
    borderFocus: "#3b82f6",
  },
};

function App() {
  return (
    <ThemeProvider theme="light" customTheme={blueBrandTheme}>
      <div style={{ padding: 24 }}>
        <Input placeholder="Enter your email" />
        <Button variant="primary">Subscribe</Button>
      </div>
    </ThemeProvider>
  );
}

Custom Target Element

Apply theme to a specific element instead of document.body:

const containerRef = useRef<HTMLDivElement>(null);

<div ref={containerRef}>
  <ThemeProvider theme="light" target={containerRef.current}>
    {/* Theme only applied within this container */}
  </ThemeProvider>
</div>

TypeScript

The package exports useful types:

import type {
  // Provider types
  ThemeProviderProps,
  ThemeMode,           // "light" | "dark"
  AllowedThemeOptions, // "light" | "dark" | "system"

  // Custom theme types
  CustomTheme,
  ColorCustomization,
  SpacingCustomization,
  TypographyCustomization,
  BorderCustomization,

  // Token name types
  ColorVarName,
  SpacingVarName,
  FontSizeVarName,
  LineHeightVarName,
  FontWeightVarName,
  LetterSpacingVarName,
  FontFamilyVarName,
  BorderRadiusVarName,
  BorderWidthVarName,

  Theme,
} from "@zentrades-ui/theme";

Exports

// Components & Hooks
export { ThemeProvider, useTheme } from "@zentrades-ui/theme";

// Token lists (for documentation/validation)
export {
  customizableColorTokens,
  customizableSpacingTokens,
  customizableFontSizeTokens,
  customizableLineHeightTokens,
  customizableFontWeightTokens,
  customizableLetterSpacingTokens,
  customizableFontFamilyTokens,
  customizableBorderRadiusTokens,
  customizableBorderWidthTokens,
} from "@zentrades-ui/theme";

// CSS variable references (for advanced usage in vanilla-extract)
export {
  colorVars,
  spacingVars,
  fontSizeVars,
  lineHeightVars,
  fontWeightVars,
  letterSpacingVars,
  fontFamilyVars,
  borderRadiusVars,
  borderWidthVars,
  lightTheme,
  darkTheme,
} from "@zentrades-ui/theme";