Git Product home page Git Product logo

Comments (10)

jlaswell avatar jlaswell commented on May 16, 2024 2

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.

madeleineostoja avatar madeleineostoja commented on May 16, 2024 1

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.

madeleineostoja avatar madeleineostoja commented on May 16, 2024 1

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.

madeleineostoja avatar madeleineostoja commented on May 16, 2024

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.

crhallberg avatar crhallberg commented on May 16, 2024

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.

madeleineostoja avatar madeleineostoja commented on May 16, 2024

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.

jlaswell avatar jlaswell commented on May 16, 2024

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.

madeleineostoja avatar madeleineostoja commented on May 16, 2024

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.

madeleineostoja avatar madeleineostoja commented on May 16, 2024

Up to date example config in #47

(Flattened module config, removed merge utility)

from pollen.

madeleineostoja avatar madeleineostoja commented on May 16, 2024

Thanks for the suggestion!! Makes Pollen a much more useful and powerful tool :)

from pollen.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.