tinted-theming / home

Style systems and smart build tooling for crafting high fidelity color schemes and easily using them in all your favorite apps.
MIT License
252 stars 12 forks source link

Proposal: Variables #61

Open joshgoebel opened 2 years ago

joshgoebel commented 2 years ago

Reference #11. Essentially the user should be able to pick their own user-defined semantic names - and those would be variables:

$nord0: #2E3440
$polar_night_dark: $nord0
$aurura_red: #BF616A

diff_added: $aurura_red
base09: $aurura_red

Here $aurura_red is a variable denoted by the $... in my Node codebase this is just a variation of semantic names, there isn't really anything special about $red... though I do think it makes sense to use $ for variables for visual clues and so you can tell them apart from semantic tag names. (And avoid name collisions)

The base17 schema spec explains the rational briefly: https://github.com/base16-project/base17/blob/main/schema_spec.md#variable-slots Like everywhere else you have named variables, they are user convenience that makes building more complex schemes easier.

joshgoebel commented 2 years ago

I'm pulling over my comments from the current builder spec PR - and fleshing them out a bit more. I feel like i'm getting some pushback on variables - which I find very confusing and frustrating. They are a KEY low-level feature that makes authoring with the additional scopes/slots supported by Base17 a real pleasure - and to me the entire system feels honestly quite crippled without them.

Lets take a simple example from the spec:

    mappings:
      diff_added: base0B
      error: base0F
      punctuation: base04

What is the scheme author trying to express? Remember that now that we have semantics:

So:

IE: Those 3 lines tell us almost nothing about the intentions of the schema author, and what they were trying to accomplish. Perhaps base04 has a bit more signal (even if I'd disagree), but the others are still anyone's guess.


Meanwhile, compare to someone constructing a schema using variables:

    mappings:
      diff_added: "$hue_green"
      diff_removed: "$hue_red"
      error: "$ansi.brightRed"
      punctuation: "$slightly_faded_text"

At a single glance it's immediately obvious the exact intentions of the author.

This has HUGE implications for theme maintenance over time when the original authors drop off. And allows for some consistent practices to build up around theme authoring that we can help encourage here in the central repo - to make all themes easily to understand and maintain across time. Themes that document NOT just a palette, but a clear intention of how those colors are using semantically across the theme... including in ways the spec itself might not even support yet.

joshgoebel commented 2 years ago

It's also obvious at least to me that someone building a slightly more complex scheme would likely start with named variables... why? For the very same reason variables were added to CSS and variables exist in ALL of the CSS pre-processor systems - they make it much easier to design and implement theming - avoid duplication - and think in your own terms.

...such as in my own skittles example:

name: "Skittles (dark)"
author: "Josh Goebel"
description: "Looks as good as it tastes."

variables: # skittles
  $lemon: "#D7CA04"
  $orange: "#EE641C"
  $grape: "#6D5473"
  $raspberry: "#05538B"
  $strawberry: "#9A1518"
  $green_apple: "#28B109"
  $pineapple_passion: "#0098CB"
  $stawberry_starfruit: "#DD7EB2"

I'm starting out defining my accent colors by name... and then I would use these later to fill in BOTH the palette and semantics:

mappings:
  diff_inserted: $green_apple
  diff_deleted: $strawberry

palette: # bg/fg/ui
  # accents
  base08: $strawberry
  base09: $orange
  base0A: $lemon
  base0B: $green_apple
  base0C: $pineapple_passion
  base0D: $raspberry
  base0E: $strawberry_starfruit
  base0F: $grape

The entire time I'm designing I'm thinking in terms of my variables/hues/etc... NOT baseXX.... Having to first point variables to baseXX and then define everything in terms of baseXX makes it MUCH harder to at a glance see what I'm trying to accomplish. I don't see what is gained by this extra and unnecessary layer of indirection and so far I can't recall hearing any argument in favor of the utility of this... only some pushbacks about the complexity - which AFAIK I've already demonstrated is quite manageable.

joshgoebel commented 2 years ago

The whole idea of a variable/constant is that I only have to change things in a single place - this eases maintenance and reduces mistakes (most developers should agree here, just look for any named constant vs "magic numbers" discussion)... if I update the green_apple color, I should need to only change a single line/variable... I should not also need to remember to update the baseXX table because (for some strange reason) it can't simply reference the same variable that I can use freely everywhere else. Even from a user experience perspective this seems very strange to me.

So far the only argument [I think] I've heard for this omission is this allows easier copy and pasting. To me that sounds like an edge case, but I also think that could be solved various ways:

And that's just off the top of my head.