Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add colorFormat option to plugin-css and plugin-sass #113

Merged
merged 4 commits into from Sep 10, 2023
Merged

Conversation

drwpow
Copy link
Owner

@drwpow drwpow commented Sep 7, 2023

Changes

Adds colorFormat option to the CSS and Sass plugins, allowing users to transform colors to any colorspace on-the-fly. 🎨

Why not use the color.hex flag?

Why not just expand the core config to handle colorspace conversions—that way plugins don’t have to duplicate the work? I didn’t take that approach for the same reason there are disagreements on color formats in the spec—there’s not a universal color type that works for all platforms (web and native). For that reason, I believe plugins should convert between colorspaces, and not core.

For example, say you wanted to use the Oklab colorspace in web. No problem—just use the oklab() CSS function which is supported by all browsers. Now what if you wanted to use that value in a Swift app… uh-oh. If the Swift plugin got an oklab() string from core, now the Swift plugin has to do double work to not only parse and understand a CSS string; it still has to do the work of converting it to the P3 space anyway.

In other words, since there’s no true universal way to express color in every programming language, then color conversion must be at the plugin (language) level.

But why allow hex normalization in core at all, then?

Core still normalizes colors to hex for the same reason the W3C Design Token spec enforces hex—it’s the only universal format that exists. It’s not only trivial to convert between hexadecimal and any sRGB-based format in any language; it’s also natively-accepted in many languages as well as-is.

So Hex is a special case, basically, and everything else has to have language-level awareness to manage colors.

Alternative 2: Culori Objects

This library uses Culori to manage color. Why not just allow culori color objects in core?

{ mode: 'rgb', r: 0.1, g: 0.2, b: 1, alpha: 1 }

An object is even less portable than a hex string. Because whereas hex is usable as-is in many languages (i.e. you may not have to do anything), an object is usable in precisely zero languages. It would require every plugin to do the work of converting that into a useable colorspace which… would probably just be hex most of the time.

TL;DR

  • This PR adds the ability for the CSS and Sass plugins to transform colors into any colorspace
  • If other plugins want to transform colorspaces, they’ll have to do that work as Cobalt Core can’t take it on

How to Review

  • Tests should pass

@changeset-bot
Copy link

changeset-bot bot commented Sep 7, 2023

🦋 Changeset detected

Latest commit: 9b2a8cc

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@cobalt-ui/plugin-css Minor
@cobalt-ui/plugin-sass Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@cloudflare-pages
Copy link

cloudflare-pages bot commented Sep 7, 2023

Deploying with  Cloudflare Pages  Cloudflare Pages

Latest commit: 9b2a8cc
Status: ✅  Deploy successful!
Preview URL: https://a1709c7d.cobalt-ui.pages.dev
Branch Preview URL: https://color-format.cobalt-ui.pages.dev

View logs

@drwpow
Copy link
Owner Author

drwpow commented Sep 7, 2023

🤔 Hm this has actually uncovered some hidden complexity in the way transformations currently work in plugins. Not the API so much as the way the current plugins are written. Which is a good thing.

But will take a step back and rethink how this is handled first.

Edit: figured it out in #114. Luckily it was just a bug in how the CSS plugin worked; it didn’t require an API change from core or anything

@@ -206,106 +201,157 @@ ${cbClose}`
};
}

/** transform color */
export function transformColor(value: ParsedColorToken['$value']): string {
return String(value);
Copy link
Owner Author

@drwpow drwpow Sep 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Slightly-irrelevant to this PR, but also realized with the simplification in #114, we can now use the same transformers for both plugin-css and plugin-sass, reducing the overall bug surface area.

As far as “transformers” are concerned in plugin-css and plugin-sass, these ONLY deal with raw, normalized values. Resolving aliases is now done in the plugin core. That wasn’t possible before, again, because composite tokens have to deal with partial aliasing. But I saw the light and realized composite tokens just get transformed ad-hoc. This realization has now helped cleanup in both CSS and Sass plugins I’m happy with.

This isn’t really a fundamental API change or anything, but as others build plugins, figuring this stuff out and setting patterns makes it so others don’t have to wrestle with as much.

@drwpow drwpow changed the title Add colorFormat option Add colorFormat option to plugin-css and plugin-sass Sep 10, 2023
@drwpow drwpow merged commit cc078a7 into main Sep 10, 2023
8 checks passed
@drwpow drwpow deleted the color-format branch September 10, 2023 03:55
@github-actions github-actions bot mentioned this pull request Sep 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant