@@ -28,13 +28,6 @@ function pxToRem(px: string | number) {
2828 return val + 'rem'
2929}
3030
31- function getHSLFromColor ( color ) {
32- const h = ( ( color . get ( 'hsl.h' ) || 0 ) * 1 ) . toFixed ( 2 )
33- const s = ( color . get ( 'hsl.s' ) * 100 ) . toFixed ( 2 )
34- const l = ( color . get ( 'hsl.l' ) * 100 ) . toFixed ( 2 )
35- return { h, s, l }
36- }
37-
3831function getColorTokenValue ( variant , styles ) {
3932 if ( variant . styles ?. fill ) {
4033 const style = styles [ variant . styles . fill ]
@@ -56,8 +49,9 @@ function getColorTokenValue(variant, styles) {
5649 const { r, g, b, a } = variant . fills [ 0 ]
5750 const color = chroma ( { r, g, b, a } )
5851
59- const { h, s, l } = getHSLFromColor ( color )
60- return `hsl(${ h } deg ${ s } % ${ l } %${ a === 1 ? '' : ' / ' + a } )`
52+ return `hsl(${ color . get ( 'hsl.h' ) } deg ${ color . get ( 'hsl.s' ) * 100 } % ${
53+ color . get ( 'hsl.l' ) * 100
54+ } %${ a === 1 ? '' : ' / ' + a } )`
6155 }
6256}
6357
@@ -145,18 +139,6 @@ function parseShadows(items) {
145139function parseColors ( items , styles : { name : string ; description : string } [ ] ) {
146140 const colors = { }
147141
148- function getKeyFromIndex ( index ) {
149- if ( index === 0 ) return '010'
150- if ( index === 1 ) return '050'
151- return index - 1 + '00'
152- }
153-
154- function getIndexFromKey ( colorKey ) {
155- if ( colorKey === '010' ) return 0
156- if ( colorKey === '050' ) return 1
157- return ( parseInt ( colorKey ) || 0 ) / 100
158- }
159-
160142 for ( const item of items ) {
161143 if ( item . name . startsWith ( '_' ) ) {
162144 continue
@@ -186,19 +168,20 @@ function parseColors(items, styles: { name: string; description: string }[]) {
186168 colorShortName = baseColorName . replace ( / [ a - z ] / g, '' ) . toLowerCase ( )
187169 }
188170
189- const defaultIndex = getIndexFromKey ( name . match ( / \d + / g) ?. at ( 0 ) )
190171 const r = parseFloat ( ( item . fills [ 0 ] . color . r * 255 ) . toFixed ( 2 ) )
191172 const g = parseFloat ( ( item . fills [ 0 ] . color . g * 255 ) . toFixed ( 2 ) )
192173 const b = parseFloat ( ( item . fills [ 0 ] . color . b * 255 ) . toFixed ( 2 ) )
193174
194- const color = chroma ( { r, g, b } )
195- const { h , s , l } = getHSLFromColor ( color )
196- const totalSteps = 11
197- const totalStepsToLight = defaultIndex + 1
198- const totalStepsToDark = totalSteps - ( defaultIndex + 1 )
175+ const defaultColor = chroma ( { r, g, b } )
176+ const hslH = defaultColor . get ( 'hsl.h' ) || 0
177+ const hslS = defaultColor . get ( 'hsl.s' )
178+ const hslL = defaultColor . get ( 'hsl.l' )
179+ const oklchH = defaultColor . get ( 'oklch.h' ) || 0
199180
200181 if ( isWhite ) {
201- colors [ colorShortName ] = `hsl(${ h } deg ${ s } % ${ l } %)`
182+ colors [ colorShortName ] = `hsl(${ hslH . toFixed ( 2 ) } deg ${ (
183+ hslS * 100
184+ ) . toFixed ( 2 ) } % ${ ( hslL * 100 ) . toFixed ( 2 ) } %)`
202185 const whiteGradients = [
203186 {
204187 modifier : 'alpha-highest' ,
@@ -224,67 +207,81 @@ function parseColors(items, styles: { name: string; description: string }[]) {
224207 for ( const gradient of whiteGradients ) {
225208 colors [
226209 `${ colorShortName } -${ gradient . modifier } `
227- ] = `hsl(${ h } deg ${ s } % ${ l } % / ${ gradient . alpha } )`
210+ ] = `hsl(${ hslH . toFixed ( 2 ) } deg ${ ( hslS * 100 ) . toFixed ( 2 ) } % ${ (
211+ hslL * 100
212+ ) . toFixed ( 2 ) } % / ${ gradient . alpha } )`
228213 }
229214 continue
230215 }
231216
232- // default
233- colors [
234- `${ colorShortName } -${ getKeyFromIndex ( defaultIndex + 1 ) } /default`
235- ] = `hsl(${ h } deg ${ s } % ${ l } %)`
236-
237- // to light
238- const colorLightest = chroma ( { r, g, b } )
239- . set ( 'hsl.h' , color . get ( 'hsl.h' ) - 15 )
240- . set ( 'hsl.l' , 0.9825 )
241- . set ( 'hsl.s' , isNeutral ? 0 : 1 )
242- const colorLight = chroma ( { r, g, b } )
243- . set ( 'hsl.h' , color . get ( 'hsl.h' ) - 10 )
244- . set ( 'hsl.l' , 0.9425 )
245- . set ( 'hsl.s' , isNeutral ? 0 : 1 )
246- const colorsToLightest = [
247- colorLightest ,
248- ...chroma
249- . scale ( [ colorLight , color ] )
250- . correctLightness ( )
251- . colors ( totalStepsToLight ) ,
217+ const scale = [
218+ { key : '010' , chroma : isNeutral ? 0.002 : 0.02 , lightness : 0.98 } ,
219+ { key : '050' , chroma : isNeutral ? 0.005 : 0.04 , lightness : 0.96 } ,
220+ { key : '100' , chroma : isNeutral ? 0.005 : 0.07 , lightness : 0.91 } ,
221+ { key : '200' , chroma : isNeutral ? 0.01 : 0.14 , lightness : 0.8 } ,
222+ { key : '300' , chroma : isNeutral ? 0.01 : 0.15 , lightness : 0.74 } ,
223+ { key : '400' , chroma : isNeutral ? 0.01 : 0.14 , lightness : 0.64 } ,
224+ { key : '500' , chroma : isNeutral ? 0.005 : 0.13 , lightness : 0.55 } ,
225+ { key : '600' , chroma : isNeutral ? 0.01 : 0.11 , lightness : 0.5 } ,
226+ { key : '700' , chroma : isNeutral ? 0.015 : 0.1 , lightness : 0.4 } ,
227+ { key : '800' , chroma : isNeutral ? 0.02 : 0.08 , lightness : 0.35 } ,
228+ { key : '900' , chroma : 0.06 , lightness : 0.24 } ,
252229 ]
253- colorsToLightest . forEach ( ( color , step ) => {
254- if ( step === defaultIndex + 1 ) return
255- const { h, s, l } = getHSLFromColor ( chroma ( color ) )
256- colors [
257- `${ colorShortName } -${ getKeyFromIndex ( step ) } `
258- ] = `hsl(${ h } deg ${ s } % ${ l } %)`
230+
231+ scale . forEach ( ( setting ) => {
232+ const color = chroma . oklch ( setting . lightness , setting . chroma , oklchH )
233+ colors [ `${ colorShortName } -${ setting . key } ` ] = `hsl(${ color
234+ . get ( 'hsl.h' )
235+ . toFixed ( 2 ) } deg ${ ( color . get ( 'hsl.s' ) * 100 ) . toFixed ( 2 ) } % ${ (
236+ color . get ( 'hsl.l' ) * 100
237+ ) . toFixed ( 2 ) } %)`
259238 } )
260239
261- // to dark
262- const colorDark = chroma ( { r, g, b } )
263- . set ( 'hsl.h' , color . get ( 'hsl.h' ) + 10 )
264- . luminance ( 0.015 )
265- chroma
266- . scale ( [ color , colorDark ] )
267- . mode ( 'lab' )
268- . correctLightness ( )
269- . colors ( totalStepsToDark )
270- . forEach ( ( color , i ) => {
271- if ( i === 0 ) return
272- const index = defaultIndex + 1 + i
273- const { h, s, l } = getHSLFromColor ( chroma ( color ) )
274- colors [ `${ colorShortName } -${ getKeyFromIndex ( index ) } ` ] = `hsl(${
275- h || 0
276- } deg ${ s } % ${ l } %)`
277- colors [ `${ colorShortName } -${ getKeyFromIndex ( index ) } ` ] = `hsl(${
278- h || 0
279- } deg ${ s } % ${ l } %)`
280- } )
240+ // Find color in scale with smallest distance to the default color
241+ // and replace it with the default color.
242+ const defaultKey = scale . reduce ( ( key , setting ) => {
243+ const settingColor = chroma . oklch (
244+ setting . lightness ,
245+ setting . chroma ,
246+ oklchH
247+ )
248+ if ( ! key ) {
249+ return setting . key
250+ }
251+ const keyColorSetting = scale . find ( ( setting ) => setting . key === key )
252+ const keyColor = chroma . oklch (
253+ keyColorSetting . lightness ,
254+ keyColorSetting . chroma ,
255+ oklchH
256+ )
257+ const distanceToSettingColor = chroma . deltaE (
258+ settingColor . hex ( ) ,
259+ defaultColor . hex ( )
260+ )
261+ const distanceToKeyColor = chroma . deltaE (
262+ keyColor . hex ( ) ,
263+ defaultColor . hex ( )
264+ )
265+ if ( distanceToSettingColor < distanceToKeyColor ) {
266+ return setting . key
267+ }
268+ return key
269+ } , '' )
270+ colors [ `${ colorShortName } -${ defaultKey } ` ] = `hsl(${ hslH . toFixed ( 2 ) } deg ${ (
271+ hslS * 100
272+ ) . toFixed ( 2 ) } % ${ ( hslL * 100 ) . toFixed ( 2 ) } %)`
273+ colors [ `${ colorShortName } -${ defaultKey } /default` ] = `hsl(${ hslH . toFixed (
274+ 2
275+ ) } deg ${ ( hslS * 100 ) . toFixed ( 2 ) } % ${ ( hslL * 100 ) . toFixed ( 2 ) } %)`
281276
282277 // TODO check if it is wiser to pick a color from the middle of the range
283278 // alpha
284- colors [ `${ colorShortName } -alpha-low` ] = `hsl(${ h } deg ${ s } % ${ l } % / 0.2)`
285- colors [
286- `${ colorShortName } -alpha-lowest`
287- ] = `hsl(${ h } deg ${ s } % ${ l } % / 0.1)`
279+ colors [ `${ colorShortName } -alpha-low` ] = `hsl(${ hslH . toFixed ( 2 ) } deg ${ (
280+ hslS * 100
281+ ) . toFixed ( 2 ) } % ${ ( hslL * 100 ) . toFixed ( 2 ) } % / 0.2)`
282+ colors [ `${ colorShortName } -alpha-lowest` ] = `hsl(${ hslH . toFixed ( 2 ) } deg ${ (
283+ hslS * 100
284+ ) . toFixed ( 2 ) } % ${ ( hslL * 100 ) . toFixed ( 2 ) } % / 0.1)`
288285 }
289286 }
290287
@@ -337,6 +334,8 @@ function parseSpacings(items) {
337334function invertColors ( colors ) {
338335 const inverted = JSON . parse (
339336 JSON . stringify ( colors )
337+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
338+ // @ts -ignore
340339 . replaceAll ( / ( - \d \d \d ) / g, '$1_' )
341340 . replaceAll ( '900_' , '010' )
342341 . replaceAll ( '800_' , '050' )
0 commit comments