drwpow / cobalt-ui

Use W3C Design Token Community Group tokens in CI and code

Home Page:https://cobalt-ui.pages.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

CSS modes documentation is incorrect

mike-engel opened this issue · comments

The documentation for modeSelectors in the css plugin has multiple examples, some of which are failing. On the css plugin docs, modes do not include the # selector in the key, but on the modes guide they do. Looking at this commit from Jan 2022, the # is definitely required, so right now the css plugin docs are incorrect.

However, I'd really like to see the # requirement dropped, since we have modes defined at the semantic level rather than the color level (e.g. background-strong.light, background-strong.dark which alias to static colors). I'm not sure if you were planning on dropping the # requirement, or if there's a typo in the plugin docs.

Yes docs definitely need to be updated in areas to fix the inconsistencies.

Oh and you’re saying you aren’t using $extensions.mode at all? And you want to do something like:

  modeSelectors: {
    '*.light': ['@prefers (color-scheme: light)'],
    '*.dark': ['@prefers (color-scheme: dark)']
  }

?

Right now I'm just doing some tests with modes, but I am using $extensions.mode:

{
	"background": {
		"$type": "color",
		"$description": "Background colors. Backgrounds should always be an alias to a color token.",
		"default": {
			"$value": "{colors.gray.200}",
			"$extensions": {
				"mode": {
					"light": "{colors.gray.200}",
					"dark": "{colors.gray.900}"
				}
			}
		},
		"hover": {
			"$value": "{colors.gray.300}"
		},
		"disabled": {
			"$value": "{colors.gray.100}"
		},
		"weak": {
			"default": {
				"$value": "{colors.gray.100}"
			},
			"hover": {
				"$value": "{colors.gray.200}"
			}
		},
		"strong": {
			"default": {
				"$value": "{colors.gray.300}"
			},
			"hover": {
				"$value": "{colors.gray.500}"
			}
		}
	},
}

But we have many root-level tokens that could use modes as we're doing something along the lines of asana's design token strategy: background, selected, info, beta, warning, etc. If we continued on with the # selector, we'd have a lot of duplication which is do-able, but annoying. If we add even more themes beyond simple light/dark (high contrast, tritanopia, etc.) then it gets even more annoying to manage:

modeSelectors: {
  'background#light': ['body[data-theme="light"]'],
  'background#dark': ['body[data-theme="dark"]'],
  'selected#light': ['body[data-theme="light"]'],
  'selected#dark': ['body[data-theme="dark"]'],
  'info#light': ['body[data-theme="light"]'],
  'info#dark': ['body[data-theme="dark"]'],
  // so on and so forth...
}

So, in summary, yeah, something like *#light or just light would be preferred

Cool. Yeah might just need to add a simple micromatch support or something for this. I think that would be pretty trivial to do overall. The current restrictions aren’t intentional.

Thought about it a little bit more, and would there be an opportunity to have a friendlier API here?

Something like:

  modeSelectors: [
    {
      mode: 'light',
      tokens: ['color.*', 'shadow.*'], // (optional) micromatch to filter to certain tokens
      css: ['@media (prefers-color-scheme: light)', 'body[data-color-mode="light"]'],
    },
    
  ],

With the # symbol I was originally thinking it would become shorthand for selecting modes. But over time I just think it’s confusing. And I’m not trying to write a token DSL or anything 😄

This would be a breaking change, but it might help usability? Open to thoughts.

I think that looks much better and straightforward compared to what's there now and what we talked about earlier. I think selector is a better name than css for the key, but that's a very small nitpick 😛

This could also be done in a backwards compatible way, since you could easily transform existing modeSelectors into the new structure:

modeSelectors: {
  'background#light': ['body[data-theme="light"]'],
}

// Gets turned into this internally
modeSelectors: [
  {
    mode: 'light',
    tokens: ['background.*'],
    css: ['body[data-theme="light"]'],
  },
]

I'm not sure how much you care about backwards compat, but it would be a simple loop through the keys of the old modeSelectors object to turn it into an array of objects

Cool! Let’s go with this format, then. With the selector change you mentioned (that was just an oversight).

And as you pointed out, backwards compatibility is cheap here, so why not keep it and avoid a breaking change? But the docs can use the new format

Just released @cobalt-ui/plugin-css@1.4.0 which adds the API discussed. Please give it a try and let me know if you run into any weirdness 🙂

Thanks @drwpow! Finally got time for a quick test and everything looks great 🎉