I want to write a custom class, that would apply set of styles, but I want to be able to use it together with a color for the theme. It will probably easier to explain it by example.
So for example if we want to set background to a certain color we would add class like this:
<div class="bg-red">
And instead of background I would like to have my own custom
class, that would apply new set of styles, but which I can still use together with a color:
<div class="custom-red">
So I started experimenting with Tailwind plugins and components. I wrote plugin like this:
function ({ matchComponents, theme }) {
const getStyles = (color) => {
return {
position: 'relative',
'&::before': {
backgroundColor: color
// ...
}
};
};
matchComponents({
testbg: (value) => getStyles(value)
}, {
values: theme('colors')
});
}
And it almost worked. I mean it is working for simple color like red
. But my color pallet is more complex and nested.
theme: {
colors: {
primary: {
DEFAULT: '#....'
5: '#....'
10: '#....'
50: '#....'
},
secondary: {
5: '#....'
10: '#....'
},
red: '#....'
}
}
And sadly it didn't generate all color possibilities. It just took the "shallow" keys of the colors and generated classes like custom-primary
, custom-secondary
, custom-red
. But there is no custom-primary-5
for example.
So is there a straightforward way of doing it? I guess I could manually parse colors from theme and recursively go through the object and create separate component for each. But this seems like a completely weird thing to do, as the stuff I'm trying to do seems like a really basic use case for a tool like Tailwind.
Tailwind provides a flattenColorPalette()
function that helps you flatten the object structure into a flat dictionary. This should then work with any level of color value nesting.
const plugin = require("tailwindcss/plugin");
const { default: flattenColorPalette } = require("tailwindcss/lib/util/flattenColorPalette");
module.exports = {
…
plugins: [
plugin(function ({ matchComponents, theme }) {
const getStyles = (color) => {
// …
};
matchComponents({
testbg: (value) => getStyles(value)
}, {
values: flattenColorPalette(theme('colors')),
});
}),
],
}