Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
37 changes: 16 additions & 21 deletions packages/theme/bin/generate-primitive-tokens/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
parse,
to,
serialize,
OKLCH,
sRGB,
type PlainColorObject,
} from 'colorjs.io/fn';
Expand All @@ -30,28 +29,24 @@ const __dirname = path.dirname( __filename );
const colorJsonPath = path.join( __dirname, '../../tokens/color.json' );

const transformColorStringToDTCGValue = ( color: string ) => {
if ( /oklch|p3/.test( color ) ) {
let parsed: PlainColorObject;
try {
parsed = to( parse( color ), OKLCH );
} catch {
return color;
}

const coords = parsed.coords;
return {
colorSpace: 'oklch',
components: [
Math.floor( 10000 * coords[ 0 ] ) / 10000, // l
coords[ 1 ], // c
isNaN( coords[ 2 ] ) ? 0 : coords[ 2 ], // h
],
...( parsed.alpha < 1 ? { alpha: parsed.alpha } : undefined ),
hex: serialize( to( parsed, sRGB ), { format: 'hex' } ),
};
let parsed: PlainColorObject;
try {
parsed = to( parse( color ), sRGB );
} catch {
return color;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Not introduced in this PR, but it's not obvious to me what kinds of cases would error on the parse but is still safe to silently return with the original value.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

That's a good point, maybe we should avoid catching this, so that it actually disrupts the build for the unexpected input.


return color;
// 3 decimal places is the minimum precision for lossless hex serialization.
// With 3 decimal places rounding to the nearest 0.001, the maximum rounding
// error is 0.0005. With 256 possible hex values, 0.0005 × 256 = 0.128,
// guaranteeing the rounded value stays within 0.5 of the original value.
const round = ( n: number ) => Math.round( n * 1000 ) / 1000;
return {
colorSpace: 'srgb',
components: parsed.coords.map( round ),
...( parsed.alpha < 1 ? { alpha: parsed.alpha } : undefined ),
hex: serialize( parsed, { format: 'hex' } ),
};
};

// Main function
Expand Down
Loading
Loading