-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Style dictionary shadow build (#370)
* shadows with with referenced color to support color modes Co-authored-by: Rez <[email protected]>
- Loading branch information
1 parent
f631e4c
commit e619ca9
Showing
20 changed files
with
1,002 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import {getMockToken} from '~/src/test-utilities' | ||
import {isShadow} from './isShadow' | ||
|
||
describe('Filter: isShadow', () => { | ||
it('returns true if $type property is `shadow`', () => { | ||
expect(isShadow(getMockToken({$type: 'shadow'}))).toStrictEqual(true) | ||
}) | ||
|
||
it('returns false if $type property is not `shadow`', () => { | ||
expect(isShadow(getMockToken({$type: 'pumpkin'}))).toStrictEqual(false) | ||
}) | ||
|
||
it('returns false if $type property is falsy', () => { | ||
expect(isShadow(getMockToken({$type: false}))).toStrictEqual(false) | ||
expect(isShadow(getMockToken({$type: undefined}))).toStrictEqual(false) | ||
expect(isShadow(getMockToken({$type: null}))).toStrictEqual(false) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import StyleDictionary from 'style-dictionary' | ||
|
||
/** | ||
* @description Checks if token is of $type `shadow` | ||
* @param arguments [StyleDictionary.TransformedToken](https://github.com/amzn/style-dictionary/blob/main/types/TransformedToken.d.ts) | ||
* @returns boolean | ||
*/ | ||
export const isShadow = (token: StyleDictionary.TransformedToken): boolean => { | ||
return token.$type === 'shadow' | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
import {getMockToken} from '~/src/test-utilities' | ||
import {shadowToCss} from './shadowToCss' | ||
|
||
describe('Transformer: shadowToCss', () => { | ||
it('transforms `shadow` token to css shadow string', () => { | ||
const input = [ | ||
getMockToken({ | ||
value: { | ||
color: '#000000', | ||
offsetX: '0px', | ||
offsetY: '2px', | ||
blur: '1px', | ||
spread: '0' | ||
} | ||
}) | ||
] | ||
const expectedOutput = ['0px 2px 1px 0 #000000'] | ||
expect(input.map(item => shadowToCss.transformer(item))).toStrictEqual(expectedOutput) | ||
}) | ||
|
||
it('transforms inset `shadow` token to css shadow string', () => { | ||
const input = [ | ||
getMockToken({ | ||
value: { | ||
color: '#000000', | ||
offsetX: '0px', | ||
offsetY: '2px', | ||
blur: '1px', | ||
spread: '0px', | ||
inset: true | ||
} | ||
}), | ||
getMockToken({ | ||
value: { | ||
color: '#000000', | ||
offsetX: '0px', | ||
offsetY: '2px', | ||
blur: '1px', | ||
spread: '0px', | ||
inset: false | ||
} | ||
}) | ||
] | ||
const expectedOutput = ['inset 0px 2px 1px 0px #000000', '0px 2px 1px 0px #000000'] | ||
expect(input.map(item => shadowToCss.transformer(item))).toStrictEqual(expectedOutput) | ||
}) | ||
|
||
it('throws an error when required values are missing', () => { | ||
// missing blur | ||
expect(() => | ||
shadowToCss.transformer( | ||
getMockToken({ | ||
value: { | ||
color: '#000000', | ||
offsetX: '2px', | ||
offsetY: '2px', | ||
blur: '1px' | ||
} | ||
}) | ||
) | ||
).toThrowError() | ||
|
||
// missing spread | ||
expect(() => | ||
shadowToCss.transformer( | ||
getMockToken({ | ||
value: { | ||
color: '#000000', | ||
offsetX: '2px', | ||
offsetY: '2px', | ||
blur: '1px' | ||
} | ||
}) | ||
) | ||
).toThrowError() | ||
|
||
// missing offsets | ||
expect(() => | ||
shadowToCss.transformer( | ||
getMockToken({ | ||
value: { | ||
color: '#000000', | ||
offsetX: '2px', | ||
spread: '0px', | ||
blur: '1px' | ||
} | ||
}) | ||
) | ||
).toThrowError() | ||
|
||
expect(() => | ||
shadowToCss.transformer( | ||
getMockToken({ | ||
value: { | ||
color: '#000000', | ||
offsetY: '2px', | ||
spread: '0px', | ||
blur: '1px' | ||
} | ||
}) | ||
) | ||
).toThrowError() | ||
// missing color | ||
expect(() => | ||
shadowToCss.transformer( | ||
getMockToken({ | ||
value: { | ||
offsetX: '0px', | ||
offsetY: '2px', | ||
spread: '0px', | ||
blur: '1px' | ||
} | ||
}) | ||
) | ||
).toThrowError() | ||
}) | ||
|
||
it('transforms `shadow` token alpha value to css shadow string', () => { | ||
const input = [ | ||
getMockToken({ | ||
value: { | ||
color: '#000000', | ||
offsetX: '0px', | ||
offsetY: '2px', | ||
blur: '1px', | ||
spread: '0', | ||
alpha: 0.5 | ||
} | ||
}), | ||
getMockToken({ | ||
value: { | ||
color: '#22222266', | ||
offsetX: '0px', | ||
offsetY: '2px', | ||
blur: '1px', | ||
spread: '0', | ||
alpha: 0.5 | ||
} | ||
}) | ||
] | ||
const expectedOutput = ['0px 2px 1px 0 #00000080', '0px 2px 1px 0 #22222280'] | ||
expect(input.map(item => shadowToCss.transformer(item))).toStrictEqual(expectedOutput) | ||
}) | ||
|
||
it('transforms multi-layer `shadow` token to css shadow string', () => { | ||
const input = getMockToken({ | ||
value: [ | ||
{ | ||
color: '#000000', | ||
offsetX: '0px', | ||
offsetY: '2px', | ||
blur: '1px', | ||
spread: '0', | ||
alpha: 0.5 | ||
}, | ||
{ | ||
color: '#22222266', | ||
offsetX: '0px', | ||
offsetY: '8px', | ||
blur: '16px', | ||
spread: '0', | ||
alpha: 0.2 | ||
} | ||
] | ||
}) | ||
|
||
const expectedOutput = '0px 2px 1px 0 #00000080, 0px 8px 16px 0 #22222233' | ||
expect(shadowToCss.transformer(input)).toStrictEqual(expectedOutput) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import {toHex} from 'color2k' | ||
import StyleDictionary from 'style-dictionary' | ||
import {ShadowTokenValue} from '../../types/ShadowTokenValue' | ||
import {isShadow} from '../filters/isShadow' | ||
import {alpha} from '../utilities' | ||
|
||
/** | ||
* checks if all required properties exist on shadow token | ||
* @param object - ShadowTokenValue | ||
* @returns void or throws error | ||
*/ | ||
const checkForShadowTokenProperties = (shadow: ShadowTokenValue) => { | ||
const requiredShadowProperties = ['color', 'offsetX', 'offsetY', 'blur', 'spread'] | ||
for (const prop of requiredShadowProperties) { | ||
if (prop in shadow === false) { | ||
throw new Error(`Missing propery: ${prop} on shadow token ${JSON.stringify(shadow)}`) | ||
} | ||
} | ||
} | ||
/** | ||
* @description converts w3c shadow tokens in css shadow string | ||
* @type value transformer — [StyleDictionary.ValueTransform](https://github.com/amzn/style-dictionary/blob/main/types/Transform.d.ts) | ||
* @matcher matches all tokens of $type `shadow` | ||
* @transformer returns css shadow `string` | ||
*/ | ||
export const shadowToCss: StyleDictionary.Transform = { | ||
type: `value`, | ||
transitive: true, | ||
matcher: isShadow, | ||
transformer: ({value}: {value: ShadowTokenValue | ShadowTokenValue[]}) => { | ||
// turn value into array | ||
const shadowValues = !Array.isArray(value) ? [value] : value | ||
return shadowValues | ||
.map((shadow: ShadowTokenValue) => { | ||
// if value === string it was probably already transformed | ||
if (typeof shadow === 'string') return shadow | ||
|
||
checkForShadowTokenProperties(shadow) | ||
/*css box shadow: inset? | offset-x | offset-y | blur-radius | spread-radius | color */ | ||
return `${shadow.inset === true ? 'inset ' : ''}${shadow.offsetX} ${shadow.offsetY} ${shadow.blur} ${ | ||
shadow.spread | ||
} ${toHex(alpha(shadow.color, shadow.alpha || 1))}` | ||
}) | ||
.join(', ') | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
/** | ||
* @description a css shadow | ||
* @format inset? | offset-x | offset-y | blur-radius? | spread-radius? | color? | ||
*/ | ||
type Shadow = string |
Oops, something went wrong.