vite-theme-color-replacer
v1.0.36
Published
A Vite plugin for dynamically changing theme colors at runtime
Maintainers
Readme
vite-theme-color-replacer
A Vite plugin for dynamically changing theme colors at runtime. This plugin extracts CSS rules containing specified colors and generates a separate CSS file that can be dynamically modified in the browser.
Features
- Extract CSS rules containing theme colors from your build output
- Generate a separate theme-colors CSS file
- Dynamically change colors at runtime without reloading
- Support for hex, rgb, and hsl color formats
- TypeScript support
- Works with Element UI and other UI frameworks
Installation
npm install vite-theme-color-replacer -DUsage
1. Configure in vite.config.ts
import { defineConfig } from 'vite'
import viteThemeColorReplacer from 'vite-theme-color-replacer'
import { getElementUISeries } from 'vite-theme-color-replacer/forElementUI'
export default defineConfig({
plugins: [
viteThemeColorReplacer({
// Colors to extract from CSS
matchColors: getElementUISeries('#409EFF'), // Element UI blue series
// Output file name (supports [contenthash])
fileName: 'css/theme-colors-[contenthash:8].css',
// Optional: External CSS files to process
externalCssFiles: ['./node_modules/element-plus/dist/index.css'],
// Optional: Inject CSS inline (no separate file download)
injectCss: false,
// Optional: Custom CSS processing
resolveCss: (css) => {
return css.replace(/#ccc/g, '#eee')
},
// Optional: Change selectors for higher specificity
changeSelector: (selector, util) => {
return util.changeEach(selector, '.my-app')
}
})
]
})2. Change colors at runtime
import { changer } from 'vite-theme-color-replacer/client'
import { getElementUISeries } from 'vite-theme-color-replacer/forElementUI'
// Change to a new theme color
async function changeTheme(newPrimaryColor: string) {
const newColors = getElementUISeries(newPrimaryColor)
await changer.changeColor({
newColors: newColors,
// Optional: specify where to append the style element
appendToEl: 'body',
// Optional: modify the CSS URL
changeUrl: (url) => `/${url}`
})
console.log('Theme changed successfully!')
}
// Example: Change to red theme
changeTheme('#f56c6c')Options
Plugin Options (build time)
| Option | Type | Description |
|--------|------|-------------|
| matchColors | string[] | Required. Colors to extract from CSS. Supports hex (#409EFF), rgb (64,158,255), and hsl formats. |
| fileName | string | Output CSS file name. Supports [contenthash] placeholder. Default: 'css/theme-colors-[contenthash:8].css' |
| externalCssFiles | string \| string[] | External CSS files to process (e.g., CDN CSS). |
| injectCss | boolean | Inject CSS inline into HTML, eliminating separate file download. Default: false |
| resolveCss | (css: string, arr: string[]) => string | Custom CSS post-processing function. |
| changeSelector | (selector: string, util: SelectorUtil) => string | Modify CSS selectors for higher specificity. |
| configVar | string | Custom variable name for config injection. Default: auto-generated. |
Runtime Options
| Option | Type | Description |
|--------|------|-------------|
| newColors | string[] | Required. New colors to apply (one-to-one with matchColors). |
| oldColors | string[] | Optional. Override default old colors. |
| appendToEl | string | CSS selector for style element placement. Default: 'body' |
| changeUrl | (url: string) => string | Modify CSS URL before fetching. Useful for non-hash routing. |
Element UI Integration
The plugin includes utilities for Element UI:
import {
getElementUISeries,
getElementUIThemeColors,
changeElementUISelector
} from 'vite-theme-color-replacer/forElementUI'
// Get all Element UI color variants (9 lighten levels + primary + 2 darken levels)
const colors = getElementUISeries('#409EFF')
// Get colors including RGB format
const allColors = getElementUIThemeColors('#409EFF')
// Change selectors for scoped styling
changeElementUISelector(selector, { suffix: '.my-app' })Color Utilities
import * as varyColor from 'vite-theme-color-replacer/client/varyColor'
// Lighten a color
const lighter = varyColor.lighten('#409EFF', 0.2) // 20% lighter
// Darken a color
const darker = varyColor.darken('#409EFF', 0.2) // 20% darker
// Mix two colors
const mixed = varyColor.mix('#fff', '#409EFF', 0.5)
// Convert to HSL
const hsl = varyColor.hexToHsl('#409EFF')How It Works
Build time: The plugin scans all CSS output, extracts rules containing
matchColors, and generates a separate CSS file.Runtime: When you call
changer.changeColor(), the client:- Fetches the theme-colors CSS file
- Replaces old colors with new colors
- Injects the modified CSS into a
<style>element
This approach is efficient because:
- Only color-related CSS is replaced (small file size)
- No page reload needed
- Works with any CSS framework
Comparison with webpack-theme-color-replacer
| Feature | webpack version | vite version | |---------|-----------------|--------------| | TypeScript | No | Yes | | Module format | CJS | ESM | | CSS extraction | From css-loader output | From native CSS files | | Config injection | DefinePlugin | HTML injection | | IE support | Yes (polyfill) | No |
License
MIT
