This is a postcss plugin that extracts colors from css styles into new css rules with changed selector, example:
.btn {
display: block;
padding: 1em;
font-size: 2em;
color: #000;
border: 3px solid #000;
}
.btn {
display: block;
padding: 1em;
font-size: 2em;
}
.default-theme .btn {
color: #000;
border: 3px solid #000;
}
Features of this plugin
- Extract all css colors
- Selectors wrapper (you can add prefixes to selectors to create multiple themes)
- Extract to external files via webpack assets
- Extract to external files via custom function
- Support and integration for [ungic-sass-theme] module
Get Started
Install npm install theme-colors-extractor
Demo
Use in your webpack project:
const { plugin } = require('./postcss-plugin.js');
let isProductionMode = env.production;
module: {
rules: [
{
test: /\.scss$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
url: false,
import: false,
},
},
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
require("postcss-rtl")(),
require("autoprefixer")()
plugin(
selector: {
before: true,
as: 'className',
value: 'default-theme',
replace: ['html', ':root', 'body', '[dir]'],
}
);
]
}
}
},
{
loader: "sass-loader",
options: {}
}
],
},
],
}
const { plugin, ungicSassThemeIntegrator } = require('./postcss-plugin.js');
let isProductionMode = env.production;
module: {
rules: [
{
test: /\.scss$/,
use: [
isProductionMode ? MiniCssExtractPlugin.loader : "style-loader",
{
loader: "css-loader",
options: {
url: false,
import: false,
},
},
{
loader: "postcss-loader",
options: {
postcssOptions: (loaderContext) => {
let plugins = [
require("postcss-rtl")(),
require("autoprefixer")()
]
if (isProductionMode) {
plugins.push(plugin({
loaderContext,
root: path.join(__dirname, 'app'),
extract: {
fileName: '[name]-theme'+ (env.inverse? '-inv' : '') + '-[suffix].css',
},
selector: {
before: true,
as: 'className',
value: env.inverse ? env.theme + '-inv' : env.theme,
replace: ['html', ':root', 'body', '[dir]'],
}
}))
}
return {
plugins
}
}
}
},
{
loader: "sass-loader",
options: {
implementation: require("sass"),
additionalData: ungicSassThemeIntegrator({
themeName: env.theme,
themeOptions: {
'inverse-mode': !!env.inverse
}
}),
sassOptions: {
outputStyle: "expanded",
sourceComments: true
},
},
}
],
},
],
}
Then add the following to the scripts section in the package.json
file:
...
"scripts": {
...
"build": "webpack --mode production --env production --env theme=default",
"build-inverse": "webpack --mode production --env production --env theme=default --env inverse"
},
Options
This option is used to extract colors, not required
-
Type: function
or object
-
as object:
- fileName - output file name, By default:
[name]-theme-[suffix].css
fileName - can contain two replaceable keys:
- [name] - source scss file name
- [suffix] - value from selector.value parameter of configuration
plugin({
extract: {
fileName: '[name]-theme'+ (env.inverse? '-inv' : '') + '-[suffix].css',
},
...
})
-
as function:
plugin({
extract: function({content, loaderContext}) {
}
...
})
saveProps
Remove colors in original scss files? By default, colors are removed from source files, not required
- Type:
boolean
- Default:
false
loaderContext
Webpack loaderContext
, required
for extract
option!
root
Root path of application, if not specified, loaderContext.rootContext
will be used
- Type:
string
- full path (for example: path.join(__dirname, 'app')
)
selector (required)
Customizing the Selector for Exported Style Rules
- Type:
object
- before
boolean
, - selector handling method
true
default - Add prefix to each selector (.theme-name .app)false
- Merge prefix with root of selector (.app.theme-name)
- as
string
- type of prefix
attribute
className
defaultid
tag
- value
string
- name of prefix, default: theme - replace
array
- what should be replaced with selector.value, default: ['html', ':root']