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

Replace better-color-tools with culori #61

Merged
merged 1 commit into from
Jul 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/nine-brooms-nail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@cobalt-ui/plugin-css': patch
'@cobalt-ui/core': patch
'@cobalt-ui/cli': patch
---

Replace better-color-tools with culori for faster, more accurate color operations
2 changes: 1 addition & 1 deletion docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"@cobalt-ui/core": "workspace:*",
"@cobalt-ui/plugin-css": "workspace:*",
"@cobalt-ui/plugin-sass": "workspace:*",
"astro": "^2.9.3",
"astro": "^2.9.4",
"npm-run-all": "^4.1.5",
"sass": "^1.64.1",
"shiki": "^0.14.3",
Expand Down
2 changes: 1 addition & 1 deletion docs/src/pages/docs/tokens/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ const tokenDef = {
<tr>
<td><code>$value</code></td>
<td><code>string</code></td>
<td>Though the spec limits valid colors to hex, Cobalt allows any valid CSS color, including OKLAB and OKLCH (parsed by <a href="https://github.com/drwpow/better-color-tools" target="_blank">better-color-tools</a>)</td>
<td>Though the spec limits valid colors to hex, Cobalt allows any color (parsed by <a href="https://culorijs.org/" target="_blank">culori</a>, a fast and accurate color library)</td>
</tr>
</tbody>
</table>
Expand Down
2 changes: 1 addition & 1 deletion examples/salesforce/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"@cobalt-ui/plugin-js": "workspace:*",
"@cobalt-ui/plugin-sass": "workspace:*",
"@salesforce-ux/design-system": "^2.21.3",
"better-color-tools": "^0.12.3",
"culori": "^3.2.0",
"postcss": "^8.4.26"
}
}
5 changes: 3 additions & 2 deletions examples/salesforce/scripts/update.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import color from 'better-color-tools';
import themeOne from '@salesforce-ux/design-system/design-tokens/dist/theme-one-salesforce.common.js';
import {formatHex, useMode, modeRgb} from 'culori/fn';
import fs from 'node:fs';
import {URL} from 'node:url';

Expand All @@ -9,6 +9,7 @@ const schema = JSON.parse(fs.readFileSync(tokensPath));
// color
const palette = Object.entries(themeOne).filter(([k]) => k.startsWith('palette'));
palette.sort((a, b) => a[0].localeCompare(b[0], 'en-us', {numeric: true}));
const rgb = useMode(modeRgb);
for (const [colorName, value] of palette) {
schema.tokens.palette[
colorName
Expand All @@ -18,7 +19,7 @@ for (const [colorName, value] of palette) {
.toLocaleLowerCase()
] = {
type: 'color',
value: color.from(value).hex,
value: formatHex(rgb(value)),
};
}

Expand Down
7 changes: 4 additions & 3 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,18 @@
"dependencies": {
"@cobalt-ui/core": "^1.3.0",
"@cobalt-ui/utils": "^1.1.1",
"better-color-tools": "^0.12.3",
"@types/culori": "^2.0.0",
"chokidar": "^3.5.3",
"culori": "^3.2.0",
"dotenv": "^16.3.1",
"js-yaml": "^4.1.0",
"piscina": "^3.2.0",
"svgo": "^3.0.2",
"yargs-parser": "^21.1.1"
},
"devDependencies": {
"@types/node": "^20.4.2",
"execa": "^7.1.1",
"@types/node": "^20.4.5",
"execa": "^7.2.0",
"figma-api": "^1.11.0",
"npm-run-all": "^4.1.5",
"vitest": "^0.33.0"
Expand Down
7 changes: 4 additions & 3 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@
},
"dependencies": {
"@cobalt-ui/utils": "^1.1.1",
"better-color-tools": "^0.12.3"
"@types/culori": "^2.0.0",
"culori": "^3.2.0"
},
"devDependencies": {
"@types/node": "^20.4.2",
"esbuild": "^0.18.12",
"@types/node": "^20.4.5",
"esbuild": "^0.18.17",
"npm-run-all": "^4.1.5",
"vitest": "^0.33.0"
}
Expand Down
16 changes: 7 additions & 9 deletions packages/core/src/parse/tokens/color.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import color from 'better-color-tools';
import {formatHex, formatHex8, parse} from 'culori';
import type {ParsedColorToken} from '../../token.js';

export interface ParseColorOptions {
Expand All @@ -17,15 +17,13 @@ export interface ParseColorOptions {
*/
export function normalizeColorValue(value: unknown, options: ParseColorOptions): ParsedColorToken['$value'] {
if (!value) throw new Error('missing value');
if (typeof value === 'string' || typeof value === 'number') {
try {
if (options.convertToHex === false && typeof value === 'string') {
return value;
}
return color.from(value).hex;
} catch (err) {
throw new Error(`invalid color "${value}"`);
if (typeof value === 'string') {
if (options.convertToHex === false) {
return value;
}
const parsed = parse(value);
if (!parsed) throw new Error(`invalid color "${value}"`);
return typeof parsed.alpha === 'number' && parsed.alpha < 1 ? formatHex8(parsed) : formatHex(parsed);
}
throw new Error(`expected string, received ${typeof value}`);
}
1 change: 0 additions & 1 deletion packages/core/test/tokens-studio.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ describe('Spacing', () => {

describe('Color', () => {
test('CSS color', () => {
// note: better-color-tools will parse any CSS-valid color so we don’t need to be exhaustive here
const json = {
global: {
color: {
Expand Down
7 changes: 4 additions & 3 deletions packages/plugin-css/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,16 @@
},
"dependencies": {
"@cobalt-ui/utils": "^1.1.1",
"better-color-tools": "^0.12.3",
"@types/culori": "^2.0.0",
"@types/mime": "^3.0.1",
"culori": "^3.2.0",
"mime": "^3.0.0",
"svgo": "^3.0.2"
},
"devDependencies": {
"@cobalt-ui/cli": "^1.3.0",
"@cobalt-ui/core": "^1.3.0",
"@types/mime": "^2.0.3",
"@types/node": "^20.4.2",
"@types/node": "^20.4.5",
"npm-run-all": "^4.1.5",
"vitest": "^0.33.0"
}
Expand Down
9 changes: 7 additions & 2 deletions packages/plugin-css/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import type {
Plugin,
ResolvedConfig,
} from '@cobalt-ui/core';
import color from 'better-color-tools';
import {converter, formatCss} from 'culori';
import {indent, isAlias, kebabinate, FG_YELLOW, RESET} from '@cobalt-ui/utils';
import {encode, formatFontNames} from './util.js';

Expand All @@ -44,6 +44,9 @@ export interface Options {
p3?: boolean;
}

/** ⚠️ Important! We do NOT want to parse as P3. We want to parse as sRGB, then expand 1:1 to P3. @see https://webkit.org/blog/10042/wide-gamut-color-in-css-with-display-p3/ */
const rgb = converter('rgb');

export default function pluginCSS(options?: Options): Plugin {
let config: ResolvedConfig;
let filename = options?.filename || './tokens.css';
Expand All @@ -70,7 +73,9 @@ export default function pluginCSS(options?: Options): Plugin {
if (!matches || !matches.length) continue;
let newVal = line;
for (const c of matches) {
newVal = newVal.replace(c, color.from(c).p3);
const parsed = rgb(c);
if (!parsed) throw new Error(`invalid color "${c}"`);
newVal = newVal.replace(c, formatCss({...parsed, mode: 'p3'}));
}
output.push(newVal);
}
Expand Down
10 changes: 5 additions & 5 deletions packages/plugin-css/test/border/want.css
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,17 @@

@supports (color: color(display-p3 1 1 1)) {
:root {
--ds-color-gray: color(display-p3 0.329412 0.278431 0.254902);
--ds-border: 1px solid color(display-p3 0.05098 0.011765 0);
--ds-color-gray: color(display-p3 0.32941176470588235 0.2784313725490196 0.2549019607843137);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

🤔 I guess all the rounding I was doing was slowing my library down for no good reason

--ds-border: 1px solid color(display-p3 0.050980392156862744 0.011764705882352941 0);
}

[data-color-theme="light"] {
--ds-color-gray: color(display-p3 0.329412 0.278431 0.254902);
--ds-border: 1px solid color(display-p3 0.05098 0.011765 0);
--ds-color-gray: color(display-p3 0.32941176470588235 0.2784313725490196 0.2549019607843137);
--ds-border: 1px solid color(display-p3 0.050980392156862744 0.011764705882352941 0);
}

[data-color-theme="dark"] {
--ds-color-gray: color(display-p3 0.733333 0.713725 0.701961);
--ds-color-gray: color(display-p3 0.7333333333333333 0.7137254901960784 0.7019607843137254);
--ds-border: 1px solid color(display-p3 1 1 1);
}
}
18 changes: 9 additions & 9 deletions packages/plugin-css/test/color/want.css
Original file line number Diff line number Diff line change
Expand Up @@ -47,35 +47,35 @@

@supports (color: color(display-p3 1 1 1)) {
:root {
--ds-color-blue: color(display-p3 0.129412 0.545098 1);
--ds-gradient: color(display-p3 0.129412 0.545098 1) 0%, color(display-p3 0.909804 0.352941 0.678431) 100%;
--ds-color-blue: color(display-p3 0.12941176470588237 0.5450980392156862 1);
--ds-gradient: color(display-p3 0.12941176470588237 0.5450980392156862 1) 0%, color(display-p3 0.9098039215686274 0.35294117647058826 0.6784313725490196) 100%;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

FWIW I’m glad I maintained my own color science library for a bit. If no other reason than to be sure the colors were accurate. With thousands of ways to do things in culori, it’s so easy to produce the wrong colors when upconverting to P3, and it would take a while to realize it.

}

[data-color-theme="light"] {
--ds-color-blue: color(display-p3 0.129412 0.545098 1);
--ds-color-blue: color(display-p3 0.12941176470588237 0.5450980392156862 1);
}

[data-color-theme="dark"] {
--ds-color-blue: color(display-p3 0.219608 0.545098 0.992157);
--ds-color-blue: color(display-p3 0.2196078431372549 0.5450980392156862 0.9921568627450981);
}

[data-color-theme="light-colorblind"] {
--ds-color-blue: color(display-p3 0.129412 0.545098 1);
--ds-color-blue: color(display-p3 0.12941176470588237 0.5450980392156862 1);
}

[data-color-theme="light-high-contrast"] {
--ds-color-blue: color(display-p3 0.066667 0.407843 0.890196);
--ds-color-blue: color(display-p3 0.06666666666666667 0.40784313725490196 0.8901960784313725);
}

[data-color-theme="dark-dimmed"] {
--ds-color-blue: color(display-p3 0.254902 0.517647 0.894118);
--ds-color-blue: color(display-p3 0.2549019607843137 0.5176470588235295 0.8941176470588236);
}

[data-color-theme="high-contrast"] {
--ds-color-blue: color(display-p3 0.25098 0.619608 1);
--ds-color-blue: color(display-p3 0.25098039215686274 0.6196078431372549 1);
}

[data-color-theme="dark-colorblind"] {
--ds-color-blue: color(display-p3 0.219608 0.545098 0.992157);
--ds-color-blue: color(display-p3 0.2196078431372549 0.5450980392156862 0.9921568627450981);
}
}
2 changes: 1 addition & 1 deletion packages/plugin-js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"devDependencies": {
"@cobalt-ui/cli": "^1.3.0",
"@cobalt-ui/core": "^1.3.0",
"fast-glob": "^3.3.0",
"fast-glob": "^3.3.1",
"npm-run-all": "^4.1.5",
"vitest": "^0.33.0"
}
Expand Down
6 changes: 3 additions & 3 deletions packages/plugin-sass/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,16 @@
"@cobalt-ui/cli": "^1.3.0"
},
"dependencies": {
"@cobalt-ui/utils": "^1.1.1",
"@cobalt-ui/utils": "^1.1.0",
"@types/mime": "^3.0.1",
"mime": "^3.0.0",
"svgo": "^3.0.2"
},
"devDependencies": {
"@cobalt-ui/cli": "^1.3.0",
"@cobalt-ui/core": "^1.3.0",
"@cobalt-ui/plugin-css": "^1.3.0",
"@types/mime": "^3.0.1",
"@types/node": "^20.4.2",
"@types/node": "^20.4.5",
"npm-run-all": "^4.1.5",
"vitest": "^0.33.0"
}
Expand Down
4 changes: 2 additions & 2 deletions packages/plugin-sass/test/plugin-css/tokens.css
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@

@supports (color: color(display-p3 1 1 1)) {
:root {
--ds-border-std: 1px solid color(display-p3 0.05098 0.011765 0);
--ds-border-std: 1px solid color(display-p3 0.050980392156862744 0.011764705882352941 0);
--ds-color-green: color(display-p3 0 1 0);
--ds-gradient-g-b: color(display-p3 0 1 0) 0%, color(display-p3 0 0 1) 100%;
--ds-shadow: 0 4px 8px 0 color(display-p3 0 0 0/0.10196);
--ds-shadow: 0 4px 8px 0 color(display-p3 0 0 0 / 0.10196078431372549);
}
}
2 changes: 1 addition & 1 deletion packages/utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@
"dev": "tsc -w"
},
"devDependencies": {
"@types/node": "^20.4.2"
"@types/node": "^20.4.5"
}
}
Loading