JSPM

tailwind-hue-theme

0.1.3
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 19
  • Score
    100M100P100Q77218F
  • License MIT

Tailwind CSS v4 plugin for dynamic OKLCH hue theming with an optional HuePicker widget

Package Exports

  • tailwind-hue-theme
  • tailwind-hue-theme/widget

Readme

tailwind-hue-theme

A Tailwind CSS v4 plugin that makes your entire color palette shift dynamically based on a single --brand-h CSS variable. Ship light, bring your own color wheel.

Includes an optional HuePicker widget — a floating circular color wheel for live hue selection with drag support, preset swatches, and localStorage persistence.


Features

  • Single variable control — update --brand-h (0–360) and your entire palette shifts: backgrounds, borders, text, and accents.
  • OKLCH color space — perceptually uniform, wide-gamut colors that look great at any hue.
  • Slate + Indigo + Cyan scales all respond to --brand-h. Slate uses low chroma so dark backgrounds stay dark; indigo follows the hue directly; cyan is offset by +40°.
  • Optional HuePicker widget — drag the circular color wheel, click a preset, or call setHue() from code.
  • localStorage persistence — selected hue survives page reloads.
  • Zero runtime dependencies — ships CJS + ESM + .d.ts.

Installation

npm install tailwind-hue-theme

Tailwind v4 plugin

Add to your CSS:

@import "tailwindcss";
@plugin "tailwind-hue-theme";

That's it. The plugin injects --brand-h: 250 (indigo) into :root and remaps --color-slate-*, --color-indigo-*, and --color-cyan-* to OKLCH values that track --brand-h at runtime.

Switch the palette live from JavaScript:

// Drop-in anywhere — no framework required
document.documentElement.style.setProperty('--brand-h', '155') // Emerald
document.documentElement.style.setProperty('--brand-h', '10')  // Rose
document.documentElement.style.setProperty('--brand-h', '250') // Indigo (default)

Override the default hue in CSS without JavaScript:

@plugin "tailwind-hue-theme";
:root { --brand-h: 155; }

JS config API (Tailwind v4 / v3)

// tailwind.config.js
import { createHuePlugin } from 'tailwind-hue-theme'

export default {
  plugins: [
    createHuePlugin({ defaultHue: 155, secondaryOffset: 50 }),
  ],
}

createHuePlugin(options?)

Option Type Default Description
defaultHue number 250 Starting hue (0–360). Written to --brand-h.
secondaryOffset number 40 Degrees added to --brand-h for the cyan scale.

buildTokens(options?)

Returns the raw Record<string, string> of CSS custom properties so you can inspect or test the generated values programmatically.


HuePicker widget

import { HuePicker } from 'tailwind-hue-theme/widget'

const picker = new HuePicker()
// → Floating color wheel appears in the bottom-right corner.

Options

Option Type Default Description
defaultHue number 250 Initial hue (0–360) if no persisted value exists.
cssVariable string '--brand-h' CSS custom property updated on <html>.
storageKey string 'tailwind-hue-theme' localStorage key for persistence.
container HTMLElement document.body Element the widget is appended to.
onChange (hue: number) => void Called every time the hue changes.
presets HuePreset[] 6 built-in Preset swatches. Pass [] to disable.

Methods

Method Description
getHue(): number Returns the current hue (0–360).
setHue(n: number) Programmatically set hue. Normalises values outside 0–360.
destroy() Removes all DOM nodes and the injected <style> tag.

Preset format

interface HuePreset {
  label: string   // Shown in aria-label and title
  hue: number     // 0–360
}

Built-in presets

Name Hue
Indigo 250
Teal 195
Purple 295
Rose 10
Amber 75
Emerald 155

Custom presets

import { HuePicker } from 'tailwind-hue-theme/widget'

new HuePicker({
  presets: [
    { label: 'Sky',  hue: 220 },
    { label: 'Pink', hue: 330 },
  ],
})

Programmatic use (no floating UI)

import { HuePicker } from 'tailwind-hue-theme/widget'

const picker = new HuePicker({
  presets: [],      // no swatches
  container: document.getElementById('my-container')!,
  onChange: (hue) => console.log('hue →', hue),
})

// Drive the palette from your own UI:
document.getElementById('my-slider')!.addEventListener('input', (e) => {
  picker.setHue(Number((e.target as HTMLInputElement).value))
})

Color scales

Scale Chroma range Hue expression
slate 0.004–0.036 var(--brand-h)
indigo 0.03–0.18 var(--brand-h)
cyan 0.03–0.18 calc(var(--brand-h) + <secondaryOffset>)

The slate scale uses intentionally low chroma so that dark backgrounds (slate-900, slate-950) remain visually dark at any hue — they just gain a subtle tint.


TypeScript

All exports are fully typed. The package ships .d.ts files alongside CJS and ESM bundles.

import { createHuePlugin, buildTokens, type HuePluginOptions } from 'tailwind-hue-theme'
import { HuePicker, DEFAULT_PRESETS, getWidgetCSS, type HuePickerOptions, type HuePreset } from 'tailwind-hue-theme/widget'

License

MIT — see LICENSE.


Created by Peter Benoit