Comments (10)
Commenting on a closed issue to say thanks and this looks awesome! Circling back to this over the next week to try it out! 🎉
from pollen.
I’ve been thinking about this too. It could be interesting to have all of pollen’s CSS variables generated with a build tool, so a user can import the built CSS directly as they do now, or generate their own set by extending defaults.
Sort of the same as tailwind’s config file, except it’d be a discrete build that outputs a file to consume however you like. Then you could also define the rest of your design system programmatically there as well (like adding new utilities to tailwind), which could be quite powerful.
And I agree that addons like colour and typesets in particular would benefit a lot from this. In my own work I find the default colour palette of limited use since every project has it’s own palette, and you can’t avoid typesets being pretty opinionated and therefore also of limited general use (which is why I haven’t published them yet, and am leaning towards leaving them out).
It’d be a pretty big chunk of work for a limited use-case (overriding with plain CSS variables is usually fine unless you’re doing a big overhaul), but happy to discuss ideas and hash out a possible API!
from pollen.
Well as long as it's sync you could run any logic you need to generate key:value
data and then return that in the config function. I'm not sure it'd be worth having things like scales in the pollen defaults, it'd be easy enough to do that with userland logic/math. That would be how Pollen's existing size
scale for example would be generated.
Example:
module.exports = function(pollen, merge) {
const scale = [...Array(10).keys()]
.reduce((obj, cur) => ({ ...obj, [cur]: cur * 2 }), {});
return {
typography: merge(pollen.typography, { scale })
}
}
In my mind the provided default config should just literally be a bag of all the key:value
pairs used by default, so it's easy to understand and extend, and doesn't need documentation beyond what we already have / what is generated. This is the same way Tailwind's config works (except they use a special extend
key rather than explicitly merging defaults) and that seems to be easily understood.
Finally I think if this was to be implemented it should definitely be a part of Pollen core, since I don't know how you'd reconcile addons + core modules other than changing the methodology to enabling them in config vs. consuming extra prebuilt CSS files.
from pollen.
Thinking more about this I think it could be a very cool idea, turning Pollen into a design system generator with defaults rather than just a collection of CSS files. My only concern is introducing complexity, since one of the big benefits of Pollen is its simplicity, with no config file or buildstep. So I'd definitely want a bit of community feedback before committing to anything. Would obviously be a fairly large breaking change and mean a v4 release.
With that said, how's this for a very rough back-of-the-napkin sketch of a potential API?
Potential Build API
Use default core variables
Nothing changes
import 'pollen-css/pollen.css`;
Generate default core variables
Empty config file with pollen builder
pollen.config.js
module.exports = function() {
return {}
}
Run pollen cli, defaults to outputting ./pollen.css
$ pollen
Enable addons
No more prebuilt addon CSS files, enable each family in them in config and build a custom pollen.css
bundle by passing true
to the top level config options
pollen.config.js
module.exports = function() {
return {
// Core (true by default)
typography: true,
layout: true,
ui: true,
// Addons (false by default)
colors: true,
grid: true
}
}
Output to custom dir
$ pollen -o src/styles/_pollen.css
Change value of defaults
Passing an object to a config option overwrites all defaults, use the provided pollen
object and merge
utility (just deep-merge
passed through) in the config function extend defaults. Slightly verbose but feels less magical than extending by default or tailwind's odd extend
key.
pollen.config.js
module.exports = function(pollen: PollenDefaults, merge) {
return {
typography: merge(pollen.typography, {
line: {
md: 1.6
}
})
}
}
Extend defaults
Add a new key to a config option to create a new variable in that family.
Here's an example of not using merge
as well, if that introduces unnecessary API surface.
pollen.config.js
module.exports = function(pollen: PollenDefaults) {
return {
typography: {
...pollen.typography,
line: {
..pollen.typography.line,
xxs: 1.1
}
}
}
}
Generates --line-xxs: 1.1
Add new custom output
Add config objects to a custom
key, where each object is a new family and its keys are [family]-[key]
items
pollen.config.js
module.exports = function(pollen: PollenDefaults) {
return {
colors: true,
custom: {
gradient: {
grey: `linear-gradient(var(--color-grey-300), var(--color-grey-500))`,
blue: `linear-gradient(var(--color-blue-300), var(--color-blue-500))`
}
}
}
Generates a new family of variables, up to the user to ensure any dependencies they use are enabled in config
--gradient-grey: linear-gradient(var(--color-grey-300), var(--color-grey-500));
--gradient-blue: linear-gradient(var(--color-blue-300), var(--color-blue-500));
Thoughts
Not sure about the top-level keys (typography
, etc), the main benefit is quicker config, ie: enabling/disabling a whole addon or core module at once. The alternative is to have every family at the top level of config. This would make it a lot more transparent (no need for custom
config object, every key is a family), but way more verbose.
Eg:
module.exports = function() {
return {
// Core modules
scale: true,
font: true,
line: true,
letter: true,
prose: true,
size: true,
width: true,
radius: true,
elevation: true,
blur: true,
easing: true,
layer: true,
// Addons
color: true,
gridPage: true,
grid: true,
// Custom
gradient: {...}
}
Passing merge
in the config function is fairly useless, could just document using deep-merge
directly, but it could make things easier to adopt. Spreading objects and nested objects manually is annoying without a tool like that.
from pollen.
As long as the default css remains useful and reasonably small, I think this level of control would be very useful. I wonder if we can tie this into purgeCSS somehow to automatically disable addons.
from pollen.
What benefit would purgeCSS give? Under this proposal you’d just pass false to the addons in config to exclude them from the generated bundle.
And yep it’s an ongoing goal for the default core modules to remain under 1kb so they’re a no brainer to throw in without optimisation or pruning needed
from pollen.
Thanks for being open to this idea.
It’d be a pretty big chunk of work for a limited use-case (overriding with plain CSS variables is usually fine unless you’re doing a big overhaul)
We're that limited use case. 🙃 Sounds like there's a desire to keep this simple and easily consumable, which I wanted to mention. I don't want to bring an idea that ruins the first line of the getting started page. I'd be open to the build process living as a separate repo to actually build heybokeh/pollen, but if the build process lives alongside here too, I'd still +1 that.
From there, I like the ideas for the ability to merge, extend, and add custom variables. I think there may be potential around a concept of ratios as well. That may be outside the scope of desired support here too.
.text {
font-size: var(--scale-0); /* 16px */
line-height: var(--scale-3); /* 24px */
&--secondary {
font-size: var(--scale-00); /* 14px */
line-height: var(--scale-2); /* 20px */
}
}
.header {
/**
* I need 32px/40px. :(
*
* --scale-4: 1.875rem or 30px
* --scale-5: 2.25rem or 36px
* --scale-6: 3rem; /* 48px */
*/
font-size: var(--size-8);
line-height: var(--size-10);
}
Instead of having to define every size/scale in the pollen.config.js file, some sort of scaling/ratio would be valuable.
module.exports = function(pollen: PollenDefaults, merge) {
return {
typography: merge(pollen.typography, {
scale: {
// linear scaling could be PollenDefaults.scale.linear
func: (val: number, rate: number) => PollenDefaults.scale.linear,
},
}
)};
}
and yields the following.
--scale-000: 0.5rem;
--scale-00: 0.75rem;
--scale-0: 1rem;
--scale-1: 1.25rem;
--scale-2: 1.5rem;
/* ... */
from pollen.
Published under v3.2.0-beta.1
with zero breaking changes 🥳
npm i pollen-css@beta
I don't have time to write docs for this yet, and might not for a while, but the interface largely matches what I outlined in my first lengthy comment, with a small adjustment:
pollen.config.js
/** @type {import('pollen-css').Config} */
module.exports = (pollen, merge) => {
return {
output: 'pollen.css' // default value,
modules: {
// Config API outlined previously
}
}
}
$ pollen
Currently I'm generating the old prebuilt addon files with pollen build configs so there's no breaking changes, but I'd like to hard deprecate them at some point in favour of config only. And assuming this new generative approach feels good and we stick with it, I want to release as a minor version so we have leeway to change the config API at some point without another major version breaking change.
from pollen.
Up to date example config in #47
(Flattened module config, removed merge utility)
from pollen.
Thanks for the suggestion!! Makes Pollen a much more useful and powerful tool :)
from pollen.
Related Issues (20)
- Colors: colorful (warm/cold) greys HOT 2
- Support shadow DOM HOT 7
- Feature: Add ability to export json file of tokens HOT 4
- Support for wider color gamuts HOT 5
- RFC: Support for queries HOT 1
- Rename elevation to shadow(?) HOT 1
- Add and configure unit tests HOT 2
- Document & release JSON output
- Add git hooks to run tests
- Automatically resolve `.cjs` config HOT 1
- Use rem for layout units HOT 3
- Fluid sizes HOT 13
- Custom colors not in exported JSON HOT 2
- Writing output-file to a file in a directory gives error HOT 1
- Proper easing library
- Aspect ratios
- system-ui in --font-sans font stack HOT 2
- postcss and postcss-jit-props integration HOT 1
- Not an issue, but information about this project HOT 1
- Stale link to Bokeh on doc site landing page HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pollen.