diff --git a/.changeset/metal-cycles-tell.md b/.changeset/metal-cycles-tell.md new file mode 100644 index 000000000..7ee9de5e8 --- /dev/null +++ b/.changeset/metal-cycles-tell.md @@ -0,0 +1,5 @@ +--- +'@primer/primitives': patch +--- + +add cubicBezier transformer diff --git a/src/filters/isCubicBezier.test.ts b/src/filters/isCubicBezier.test.ts new file mode 100644 index 000000000..dd98db5d2 --- /dev/null +++ b/src/filters/isCubicBezier.test.ts @@ -0,0 +1,22 @@ +import {getMockToken} from '../test-utilities/index.js' +import {isCubicBezier} from './isCubicBezier.js' + +describe('Filter: isCubicBezier', () => { + it('returns true if $type property is `cubicBezier`', () => { + expect(isCubicBezier(getMockToken({$type: 'cubicBezier'}))).toStrictEqual(true) + }) + + it('returns false if $type property is not `cubicBezier`', () => { + expect(isCubicBezier(getMockToken({$type: 'pumpkin'}))).toStrictEqual(false) + }) + + it('returns false if $type property is missing', () => { + expect(isCubicBezier(getMockToken({alpha: 0.4}))).toStrictEqual(false) + }) + + it('returns false if $type property is falsy', () => { + expect(isCubicBezier(getMockToken({$type: false}))).toStrictEqual(false) + expect(isCubicBezier(getMockToken({$type: undefined}))).toStrictEqual(false) + expect(isCubicBezier(getMockToken({$type: null}))).toStrictEqual(false) + }) +}) diff --git a/src/filters/isCubicBezier.ts b/src/filters/isCubicBezier.ts new file mode 100644 index 000000000..e324f60ac --- /dev/null +++ b/src/filters/isCubicBezier.ts @@ -0,0 +1,11 @@ +import type {TransformedToken} from 'style-dictionary/types' + +/** + * @description Checks if token is of $type `cubicBezier` + * @param token [TransformedToken](https://github.com/amzn/style-dictionary/blob/main/types/TransformedToken.d.ts) + * @returns boolean + */ +export const isCubicBezier = (token: TransformedToken): boolean => { + const typeValue = token.$type ?? token.type + return typeValue === 'cubicBezier' +} diff --git a/src/transformers/cubicBezierToCss.test.ts b/src/transformers/cubicBezierToCss.test.ts new file mode 100644 index 000000000..0a812cf60 --- /dev/null +++ b/src/transformers/cubicBezierToCss.test.ts @@ -0,0 +1,48 @@ +import {getMockToken} from '../test-utilities/index.js' +import {cubicBezierToCss} from './cubicBezierToCss.js' + +describe('Transformer: cubicBezierToCss', () => { + it('transforms `cubicBezier` token to css cubicBezier function', () => { + const input = getMockToken({ + $value: [0, 0, 1, 1], + }) + + const expectedOutput = 'cubic-bezier(0,0,1,1)' + expect(cubicBezierToCss.transform(input, {}, {})).toStrictEqual(expectedOutput) + }) + + it('throws an error when required values are missing', () => { + // missing blur + expect(() => + cubicBezierToCss.transform( + getMockToken({ + $value: [0, 0, 1], + }), + {}, + {}, + ), + ).toThrowError() + + // missing spread + expect(() => + cubicBezierToCss.transform( + getMockToken({ + $value: [0, 0, 1, 1, 1, 1], + }), + {}, + {}, + ), + ).toThrowError() + + // missing offsets + expect(() => + cubicBezierToCss.transform( + getMockToken({ + $value: [0, 0, 1, '1'], + }), + {}, + {}, + ), + ).toThrowError() + }) +}) diff --git a/src/transformers/cubicBezierToCss.ts b/src/transformers/cubicBezierToCss.ts new file mode 100644 index 000000000..c80343168 --- /dev/null +++ b/src/transformers/cubicBezierToCss.ts @@ -0,0 +1,26 @@ +import type {PlatformConfig, Transform, TransformedToken} from 'style-dictionary/types' +import {isCubicBezier} from '../filters/isCubicBezier.js' + +/** + * @description converts cubicBezeir tokens array value to a css cubic-bezier + * @type value transformer — [StyleDictionary.ValueTransform](https://github.com/amzn/style-dictionary/blob/main/types/Transform.d.ts) + * @matcher matches all tokens of $type `duration` + * @transformer returns a css cubic-bezier function + */ +export const cubicBezierToCss: Transform = { + name: 'cubicBezeir/css', + type: 'value', + transitive: true, + filter: isCubicBezier, + transform: (token: TransformedToken, _config: PlatformConfig) => { + const value = token.$value ?? token.value + // throw value of more or less than 4 items in array + if (value.length !== 4 || value.some((item: unknown) => typeof item !== 'number')) { + throw new Error( + `Invalid cubicBezier token ${token.path.join('.')}, must be an array with 4 numbers, but got this instead: ${JSON.stringify(value)}`, + ) + } + // return value + return `cubic-bezier(${value.join(',')})` + }, +}