Package Exports
- @cobalt-ui/plugin-css
- @cobalt-ui/plugin-css/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@cobalt-ui/plugin-css) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
@cobalt-ui/plugin-css
Generate CSS output for Cobalt from design tokens.
Automatically generates 🌈 P3 colors for more vibrant colors on displays that support it.
Setup
npm i -D @cobalt-ui/plugin-css
// tokens.config.mjs
import css from '@cobalt-ui/plugin-css';
export default {
plugins: [
css({
/** set the filename inside outDir */
filename: './tokens.css',
/** create selector wrappers around modes */
modeSelectors: {
// …
},
/** embed file tokens? */
embedFiles: false,
/** handle specific token types */
transform: {
color: (value, token) => {
return value;
},
},
/** don’t like the name of CSS variables? change ’em! */
transformVariableNames(name, group) {
return `--${name.replace(/[._]/g, '-')}`;
},
}),
],
};
Usage
Running npx co build
with the plugin set up will generate a tokens/tokens.css
file. Simply inspect that, and import where desired and use the CSS Custom Properties as desired (docs).
Config
Embed Files
Say you have file
tokens in your tokens.json
:
{
"icon": {
"alert": {
"type": "file",
"value": "./icon/alert.svg"
}
}
}
By default, consuming those will simply print values as-is:
.icon-alert {
background-image: var(--icon-alert);
}
/* Becomes … */
.icon-alert {
background-image: url('./icon/alert.svg');
}
In some scenarios this is preferable, but in others, this may result in too many requests and may result in degraded performance. You can set embedFiles: true
to generate the following instead:
.icon-alert {
background-image: var(--icon-alert);
}
/* Becomes … */
.icon-alert {
background-image: url('image/svg+xml;utf8,<svg …></svg>');
}
Mode Selectors
Example
To generate CSS for Modes, add a modeSelectors: {}
object to your config, and specify mode: [selector1, selector2, …]
.
For example, if your color.base
group has light
and dark
modes, and you want to alter the CSS variables based on a body attribute:
// tokens.config.mjs
import css from '@cobalt-ui/plugin-css';
export default [
plugins: [
css({
modeSelectors: {
'color.base#light': ['body[data-color-mode="light"]'],
'color.base#dark': ['body[data-color-mode="dark"]'],
},
}),
],
]
This will generate the following CSS:
/* default theme set by tokens.json (same as "light") */
:root {
--color-blue: #0969da;
--color-green: #2da44e;
--color-red: #cf222e;
/* … */
}
/* light theme colors */
body[data-color-mode='light'] {
--color-blue: #0969da;
--color-green: #2da44e;
--color-red: #cf222e;
/* … */
}
/* dark theme colors */
body[data-color-mode='dark'] {
--color-blue: #1f6feb;
--color-green: #2ea043;
--color-red: #da3633;
/* … */
}
But more than just classes can be used (that’s why it’s called modeSelectors
and not modeClasses
)! You could also generate CSS if your type.size
group had desktop
and mobile
sizes:
// tokens.config.mjs
import css from '@cobalt-ui/plugin-css';
export default {
plugins: [
css({
modeSelectors: {
'type.size#desktop': ['@media (min-width: 600px)'],
},
}),
],
};
That will generate the following:
/* default size (in this case, mobile) */
:root {
--type-size: 16px;
}
/* desktop size */
@media (min-width: 600px) {
:root {
--type-size: 18px;
}
}
Syntax
The #
character designates the mode. You must have a #
somewhere in the selector.
#light
: match any token that has alight
modecolor#light
: deeply match any token inside thecolor
group, that has alight
modecolor.base#light
: deeply match any token inside thecolor.base
group with alight
mode, but ignore any other tokens insidecolor
Further Reading
To learn about modes, read the documentation
Transform
Inside plugin options, you can specify transforms per-type:
export default {
plugins: [
pluginCSS({
transform: {
color: (value, token) => {
return value;
},
dimension: (value, token) => {
return value;
},
font: (value, token) => {
return value;
},
duration: (value, token) => {
return value;
},
'cubic-bezier': (value, token) => {
return value;
},
file: (value, token) => {
return value;
},
url: (value, token) => {
return value;
},
shadow: (value, token) => {
return value;
},
gradient: (value, token) => {
return value;
},
typography: (value, token) => {
return value;
},
transition: (value, token) => {
return value;
},
},
}),
],
};
⚠️ Whenever you override a transformer for a token type, it’s now up to you to handle everything! You may also need the help of utilities like better-color-tools
Custom tokens
If you have your own custom token type, e.g. my-custom-type
, you can add more keys to transform
to handle it, like so:
export default {
plugins: [
pluginCSS({
transform: {
'my-custom-type': (value, token) => {
return String(value);
},
},
}),
],
};