0.3.2 • Published 12 months ago

@poupe/theme-builder v0.3.2

Weekly downloads
-
License
MIT
Repository
github
Last release
12 months ago

@poupe/theme-builder

jsDocs.io npm version License: MIT

Design token management and theme generation system for Material Design 3 themes with automatic dark mode, CSS variables, and image-based color extraction.

Table of Contents

Features

  • 🎨 Material Design 3 color system with automatic dark themes
  • 🌓 Built-in dark mode support with CSS custom properties
  • 🖼️ Generate color palettes from images using Material algorithms
  • 🔧 Advanced color manipulation utilities (HCT, RGB, HSL, ARGB)
  • 📦 Lightweight, tree-shakable API with TypeScript support
  • 🧩 CSS variables generation for external customization
  • 🎭 Theme scheme variants (vibrant, expressive, content, etc.)
  • 🛠️ Server-side utilities for build-time theme generation

Installation

# npm
npm install -D @poupe/theme-builder

# yarn
yarn add -D @poupe/theme-builder

# pnpm
pnpm add -D @poupe/theme-builder

Usage

Basic Theme Creation

import { makeTheme } from '@poupe/theme-builder'

// Create Material Design 3 theme with color roles
const { dark, light } = makeTheme({
  primary: '#1976d2',
  secondary: '#9c27b0',
  tertiary: '#ff4081',
}, 'vibrant', 0.0)

// Access color roles
console.log(light.primary.value)      // Primary color in light theme
console.log(dark.onPrimary.value)     // Text color on primary in dark theme

CSS Theme Generation

import { makeCSSTheme } from '@poupe/theme-builder'

// Generate CSS variables for dark/light themes
const cssTheme = makeCSSTheme({
  primary: '#6750A4',
  secondary: '#958DA5',
  error: '#B3261E',
}, {
  scheme: 'content',
  contrastLevel: 0.5,
  prefix: 'md-',
  darkMode: ['.dark', 'media'],    // Multiple selectors with aliases
  lightMode: '.light',
})

// Built-in responsive aliases
makeCSSTheme(colors, {
  darkMode: ['dark', 'mobile'],    // Uses media queries
  lightMode: ['light', 'desktop']  // Now supports arrays too
})

// Advanced selector configuration
const advancedTheme = makeCSSTheme(colors, {
  darkMode: ['mobile', '.dark-mode'],   // Mobile screens + custom class
  lightMode: ['desktop', '.light-mode'], // Desktop + custom class
})

// Use generated CSS variables
console.log(cssTheme.vars.primary)     // '--md-primary'
console.log(cssTheme.styles)           // CSS rule objects

Theme from Image

import { fromImageElement } from '@poupe/theme-builder'

// Extract color from image element
async function createImageTheme(imageElement: HTMLImageElement) {
  const seedColor = await fromImageElement(imageElement)

  const { dark, light } = makeTheme({
    primary: seedColor.toHex(),
  }, 'expressive')

  return { dark, light }
}

Color Manipulation

import { hct, colord, hexString, makeTonalPalette } from '@poupe/theme-builder/core'

// HCT color space (Hue, Chroma, Tone)
const color = hct('#1976d2')
const lighter = color.withTone(80)     // Lighter variant
const muted = color.withChroma(30)     // Lower saturation

// Advanced color utilities
const c = colord('#1976d2')
console.log(c.toHsl())                 // HSL representation
console.log(c.lighten(0.2).toHex())    // Lightened color

// Format colors
console.log(hexString(lighter))        // Convert to hex string

// Create tonal palette with full tone range (0-100)
const palette = makeTonalPalette('#1976d2')
console.log(palette.tone(50))          // Medium tone
console.log(palette.tone(90))          // Light tone
console.log(palette.tone(10))          // Dark tone

// Harmonize colors to create cohesive palettes
const primary = hct('#1976d2')
const harmonized = makeTonalPalette('#9c27b0', primary)

API Reference

Main Exports

import {
  // Theme generation
  makeTheme,
  makeCSSTheme,

  // CSS utilities
  assembleCSSColors,
  defaultCSSThemeOptions,

  // Image extraction
  fromImageElement,

  // Color utilities (re-exported from core)
  hct,
  colord,
  hexString,
  rgbaString,
} from '@poupe/theme-builder'

Core Utilities

Color manipulation and formatting utilities:

import {
  // Color types and creation
  type Hct,
  type HexColor,
  hct,
  colord,

  // Color formatting
  hexString,
  rgbaString,

  // Color conversion
  argb,
  rgb,

  // CSS utilities (re-exported)
  formatCSSRules,
} from '@poupe/theme-builder/core'

Server Utilities

Server-side color processing, validation, and CSS response utilities:

import {
  // Parameter processing
  getColorParam,
  getThemeSchemeParam,

  // CSS formatting utilities
  stringifyCSSRulesArray,
  stringifyCSSRulesArrayStream,
  stringifyCSSRulesArrayAsStream,
  stringifyCSSRulesArrayAsResponse,
  stringifyCSSRulesArrayAsStreamingResponse,

  // Color types (re-exported)
  type HexColor,
  hct,
  colord,
} from '@poupe/theme-builder/server'

// Convert to CSS string (no trailing newline)
const cssString = stringifyCSSRulesArray([
  { '.theme': { '--primary': '#6750A4' } }
])

// Convert with camelCase to kebab-case normalization
const normalizedCSS = stringifyCSSRulesArray([
  { fontSize: '16px', backgroundColor: 'blue' }
], { normalizeProperties: true })
// Result: 'font-size: 16px;\nbackground-color: blue;'

// Create ReadableStream (perfect for Cloudflare Workers)
const stream = stringifyCSSRulesArrayAsStream([
  { '.theme': { '--primary': '#6750A4' } }
])
const response = new Response(stream, {
  headers: { 'Content-Type': 'text/css' }
})

// Create Response object with headers
const response = stringifyCSSRulesArrayAsResponse([
  { '.theme': { '--primary': '#6750A4' } }
])

// Create streaming Response for large CSS files
const streamingResponse = stringifyCSSRulesArrayAsStreamingResponse([
  // Large array of CSS rules
])

Color System

Material Design 3 color roles and theming:

  • Primary: Main brand color and variants (primary, onPrimary, primaryContainer, onPrimaryContainer)
  • Secondary: Supporting colors (secondary, onSecondary, secondaryContainer, onSecondaryContainer)
  • Tertiary: Accent colors (tertiary, onTertiary, tertiaryContainer, onTertiaryContainer)
  • Error: Error states (error, onError, errorContainer, onErrorContainer)
  • Neutral: Surface and outline colors (surface, onSurface, outline, etc.)
const { dark, light } = makeTheme({
  primary: '#6750A4',
  secondary: '#958DA5',
  tertiary: '#B58392',
  neutral: '#938F94',
  neutralVariant: '#948F94',
  error: '#B3261E',
}, 'content', 0.0)

// Access all color roles
console.log(light.primaryContainer.value)    // Primary container color
console.log(dark.onSurfaceVariant.value)     // Text on surface variant

CSS Variables

Automatic CSS custom property generation:

const cssTheme = makeCSSTheme({
  primary: '#6750A4',
}, {
  prefix: 'md-',           // Variable prefix
  darkMode: '.dark',       // Dark mode selector
  lightMode: '.light',     // Light mode selector (optional)
  darkSuffix: '-dark',     // Dark variable suffix
  lightSuffix: '-light',   // Light variable suffix
})

// Generated variables
cssTheme.vars.primary              // '--md-primary'
cssTheme.vars.onPrimary           // '--md-on-primary'
cssTheme.styles                   // CSS rule objects

Dark Mode

Built-in dark mode support with flexible selectors and aliases:

// Class-based dark mode (default)
makeCSSTheme(colors, { darkMode: '.dark' })

// Media query dark mode using built-in alias
makeCSSTheme(colors, { darkMode: 'media' })

// Multiple selectors
makeCSSTheme(colors, { darkMode: ['.dark', '.theme-dark'] })

// Built-in responsive aliases
makeCSSTheme(colors, {
  darkMode: ['dark', 'mobile'],  // Uses media queries
  lightMode: 'light'
})

// Custom selectors
makeCSSTheme(colors, {
  darkMode: '[data-theme="dark"]',
  lightMode: '[data-theme="light"]'
})

// Disable dark mode
makeCSSTheme(colors, { darkMode: false })

Built-in Selector Aliases

The theme builder includes convenient aliases for common media queries:

  • 'media' or 'dark''@media (prefers-color-scheme: dark)'
  • 'light''@media (prefers-color-scheme: light)'
  • 'mobile''@media (max-width: 768px)'
  • 'tablet''@media (min-width: 769px) and (max-width: 1024px)'
  • 'desktop''@media (min-width: 1025px)'
// Using aliases for responsive theming
const cssTheme = makeCSSTheme(colors, {
  darkMode: ['dark', 'tablet'],     // Dark mode + tablet screens
  lightMode: ['light', 'desktop'],  // Light mode + desktop screens
})

Integration with Poupe Ecosystem

Requirements

  • Node.js >=20.19.1
  • TypeScript-friendly environment

License

MIT licensed.

0.5.10

10 months ago

0.5.11

10 months ago

0.6.7

8 months ago

0.6.6

8 months ago

0.6.9

8 months ago

0.6.8

8 months ago

0.5.12

10 months ago

0.5.13

9 months ago

0.6.10

8 months ago

0.3.0

12 months ago

0.9.0

7 months ago

0.5.4

11 months ago

0.7.1

8 months ago

0.5.3

11 months ago

0.9.2

7 months ago

0.5.6

11 months ago

0.9.1

7 months ago

0.5.5

11 months ago

0.5.0

12 months ago

0.3.2

12 months ago

0.3.1

12 months ago

0.7.0

8 months ago

0.5.2

11 months ago

0.5.1

11 months ago

0.9.4

7 months ago

0.5.8

11 months ago

0.9.3

7 months ago

0.5.7

11 months ago

0.5.9

11 months ago

0.2.1

1 year ago

0.2.0

1 year ago

0.8.1

8 months ago

0.6.3

8 months ago

0.4.5

12 months ago

0.2.7

12 months ago

0.8.0

8 months ago

0.6.2

8 months ago

0.4.4

12 months ago

0.2.6

12 months ago

0.8.3

7 months ago

0.6.5

8 months ago

0.4.7

12 months ago

0.2.9

12 months ago

0.8.2

8 months ago

0.6.4

8 months ago

0.4.6

12 months ago

0.2.8

12 months ago

0.4.1

12 months ago

0.2.3

12 months ago

0.4.0

12 months ago

0.2.2

1 year ago

0.6.1

8 months ago

0.4.3

12 months ago

0.2.5

12 months ago

0.6.0

9 months ago

0.4.2

12 months ago

0.2.4

12 months ago

0.1.3

2 years ago

0.1.0

2 years ago

0.1.1

2 years ago

0.0.2

2 years ago

0.0.1

2 years ago