Skip to content
Draft
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
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 25 additions & 10 deletions src/formats/jsonFigma.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import type {RgbaFloat} from '../transformers/utilities/isRgbaFloat.js'
import {isRgbaFloat} from '../transformers/utilities/isRgbaFloat.js'
import {getReferences, sortByReference} from 'style-dictionary/utils'

// Type for dimension value in new W3C object format
type DimensionValue = {value: number; unit: string}

const isReference = (string: string): boolean => /^\{([^\\]*)\}$/g.test(string)

const getReference = (dictionary: Dictionary, refString: string, platform: PlatformConfig) => {
Expand All @@ -32,19 +35,31 @@ const getFigmaType = (type: string): string => {

const shadowToVariables = (
name: string,
values: Omit<ShadowTokenValue, 'color'> & {color: string | RgbaFloat},
values: Omit<ShadowTokenValue, 'color' | 'offsetX' | 'offsetY' | 'blur' | 'spread'> & {
color: string | RgbaFloat
offsetX: DimensionValue
offsetY: DimensionValue
blur: DimensionValue
spread: DimensionValue
},
token: TransformedToken,
) => {
// floatValue
const floatValue = (property: 'offsetX' | 'offsetY' | 'blur' | 'spread') => ({
name: `${name}/${property}`,
value: parseInt(values[property].replace('px', '')),
type: 'FLOAT',
scopes: ['EFFECT_FLOAT'],
mode,
collection,
group,
})
const floatValue = (property: 'offsetX' | 'offsetY' | 'blur' | 'spread') => {
const dimValue = values[property]
// New object format like {value: 1, unit: "px"}
const numValue = dimValue.value

return {
name: `${name}/${property}`,
value: numValue,
type: 'FLOAT',
scopes: ['EFFECT_FLOAT'],
mode,
collection,
group,
}
}

const {attributes} = token
const {mode, collection, group} = attributes || {}
Expand Down
2 changes: 1 addition & 1 deletion src/platforms/styleLint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const styleLint: PlatformInitializer = (outputFile, prefix, buildPath, op
transforms: [
'name/pathToKebabCase',
'color/hex',
'dimension/remPxArray',
'dimension/pixel',
'shadow/css',
'border/css',
'typography/css',
Expand Down
3 changes: 3 additions & 0 deletions src/primerStyleDictionary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
colorToRgbaFloat,
cubicBezierToCss,
dimensionToRem,
dimensionToPixel,
dimensionToPixelUnitless,
durationToCss,
figmaAttributes,
Expand Down Expand Up @@ -123,6 +124,8 @@ PrimerStyleDictionary.registerTransform(floatToPixelUnitless)

PrimerStyleDictionary.registerTransform(dimensionToRem)

PrimerStyleDictionary.registerTransform(dimensionToPixel)

PrimerStyleDictionary.registerTransform(dimensionToRemPxArray)

PrimerStyleDictionary.registerTransform(dimensionToPixelUnitless)
Expand Down
2 changes: 1 addition & 1 deletion src/schemas/borderTokenSchema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {borderToken, borderValue} from './borderToken.js'
const validBorderValue = {
color: '#333',
style: 'solid',
width: '1px',
width: {value: 1, unit: 'px'},
}

describe('Schema: borderValue', () => {
Expand Down
9 changes: 6 additions & 3 deletions src/schemas/dimensionTokenSchema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import {dimensionToken} from './dimensionToken.js'

describe('Schema: dimensionToken', () => {
const validToken = {
$value: '1px',
$value: {value: 1, unit: 'px'},
$type: 'dimension',
$description: 'a dimension token',
}

it('passes on valid values', () => {
expect(dimensionToken.safeParse(validToken).success).toStrictEqual(true)
expect(dimensionToken.safeParse({...validToken, $value: '1em'}).success).toStrictEqual(true)
expect(dimensionToken.safeParse({...validToken, $value: '1rem'}).success).toStrictEqual(true)
expect(dimensionToken.safeParse({...validToken, $value: {value: 1, unit: 'em'}}).success).toStrictEqual(true)
expect(dimensionToken.safeParse({...validToken, $value: {value: 1, unit: 'rem'}}).success).toStrictEqual(true)
})

it('fails on invalid type', () => {
Expand All @@ -19,10 +19,13 @@ describe('Schema: dimensionToken', () => {

it('fails on invalid value', () => {
expect(dimensionToken.safeParse({...validToken, $value: 'wrong'}).success).toStrictEqual(false)
expect(dimensionToken.safeParse({...validToken, $value: '1px'}).success).toStrictEqual(false)
expect(dimensionToken.safeParse({...validToken, $value: '1%'}).success).toStrictEqual(false)
expect(dimensionToken.safeParse({...validToken, $value: undefined}).success).toStrictEqual(false)
expect(dimensionToken.safeParse({...validToken, $value: ''}).success).toStrictEqual(false)
expect(dimensionToken.safeParse({...validToken, $value: false}).success).toStrictEqual(false)
expect(dimensionToken.safeParse({...validToken, $value: 1}).success).toStrictEqual(false)
expect(dimensionToken.safeParse({...validToken, $value: {value: 1, unit: '%'}}).success).toStrictEqual(false)
expect(dimensionToken.safeParse({...validToken, $value: {value: 'wrong', unit: 'px'}}).success).toStrictEqual(false)
})
})
18 changes: 4 additions & 14 deletions src/schemas/dimensionValue.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
import {z} from 'zod'
import {schemaErrorMessage} from '../utilities/index.js'

export const dimensionValue = z.union([
z.string().refine(
dim => /(^-?[0-9]+(px|rem)$|^-?[0-9]+\.?[0-9]*em$)/.test(dim),
val => ({
message: schemaErrorMessage(
`Invalid dimension: "${val}"`,
`Dimension must be a string with a unit (px, rem or em) or 0`,
),
}),
),
z.literal('0'),
z.literal(0),
])
export const dimensionValue = z.object({
value: z.number(),
unit: z.enum(['px', 'rem', 'em']),
})
26 changes: 18 additions & 8 deletions src/schemas/dimensionValueSchema.test.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,31 @@
import {dimensionValue} from './dimensionValue.js'

describe('Schema: dimensionValue', () => {
it('passes on valid values', () => {
expect(dimensionValue.safeParse('1px').success).toStrictEqual(true)
expect(dimensionValue.safeParse('-1px').success).toStrictEqual(true)
expect(dimensionValue.safeParse('1em').success).toStrictEqual(true)
expect(dimensionValue.safeParse('1rem').success).toStrictEqual(true)
expect(dimensionValue.safeParse('0').success).toStrictEqual(true)
expect(dimensionValue.safeParse(0).success).toStrictEqual(true)
it('passes on valid object values', () => {
expect(dimensionValue.safeParse({value: 1, unit: 'px'}).success).toStrictEqual(true)
expect(dimensionValue.safeParse({value: -1, unit: 'px'}).success).toStrictEqual(true)
expect(dimensionValue.safeParse({value: 16, unit: 'rem'}).success).toStrictEqual(true)
expect(dimensionValue.safeParse({value: 1.5, unit: 'em'}).success).toStrictEqual(true)
expect(dimensionValue.safeParse({value: 0, unit: 'px'}).success).toStrictEqual(true)
})

it('fails on invalid value', () => {
it('fails on invalid object values', () => {
expect(dimensionValue.safeParse({value: 1, unit: '%'}).success).toStrictEqual(false)
expect(dimensionValue.safeParse({value: 'small', unit: 'px'}).success).toStrictEqual(false)
expect(dimensionValue.safeParse({value: 1}).success).toStrictEqual(false)
expect(dimensionValue.safeParse({unit: 'px'}).success).toStrictEqual(false)
expect(dimensionValue.safeParse({}).success).toStrictEqual(false)
})

it('fails on invalid values', () => {
expect(dimensionValue.safeParse('1px').success).toStrictEqual(false)
expect(dimensionValue.safeParse('1%').success).toStrictEqual(false)
expect(dimensionValue.safeParse(1).success).toStrictEqual(false)
expect(dimensionValue.safeParse('small').success).toStrictEqual(false)
expect(dimensionValue.safeParse('').success).toStrictEqual(false)
expect(dimensionValue.safeParse(false).success).toStrictEqual(false)
expect(dimensionValue.safeParse(undefined).success).toStrictEqual(false)
expect(dimensionValue.safeParse('0').success).toStrictEqual(false)
expect(dimensionValue.safeParse(0).success).toStrictEqual(false)
})
})
18 changes: 12 additions & 6 deletions src/schemas/shadowTokenSchema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import {shadowValue, shadowToken} from './shadowToken.js'
const tokenValue = {
color: '#000000',
alpha: 0.5,
offsetX: '4px',
offsetY: '4px',
blur: '2px',
spread: '2px',
offsetX: {value: 4, unit: 'px'},
offsetY: {value: 4, unit: 'px'},
blur: {value: 2, unit: 'px'},
spread: {value: 2, unit: 'px'},
inset: false,
}

Expand All @@ -15,8 +15,14 @@ describe('Schema: shadowValue', () => {
expect(shadowValue.safeParse(tokenValue).success).toStrictEqual(true)
// without inset
expect(
shadowValue.safeParse({color: '#000000', alpha: 0.5, offsetX: '4px', offsetY: '4px', blur: '2px', spread: '2px'})
.success,
shadowValue.safeParse({
color: '#000000',
alpha: 0.5,
offsetX: {value: 4, unit: 'px'},
offsetY: {value: 4, unit: 'px'},
blur: {value: 2, unit: 'px'},
spread: {value: 2, unit: 'px'},
}).success,
).toStrictEqual(true)
})

Expand Down
10 changes: 6 additions & 4 deletions src/schemas/typographyTokenSchema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import {typographyToken, typographyValue} from './typographyToken.js'

describe('Schema: typographyToken', () => {
const validValue = {
fontSize: '16px',
lineHeight: '24px',
fontSize: {value: 16, unit: 'px'},
lineHeight: {value: 24, unit: 'px'},
fontWeight: 600,
fontFamily: 'Helvetica',
}
Expand Down Expand Up @@ -31,14 +31,16 @@ describe('Schema: typographyToken', () => {
})

it('it fails on invalid fontSize values', () => {
expect(typographyValue.safeParse({...validValue, fontSize: '100%'}).success).toStrictEqual(false)
expect(typographyValue.safeParse({...validValue, fontSize: {value: 100, unit: '%'}}).success).toStrictEqual(false)
expect(typographyValue.safeParse({...validValue, fontSize: '16px'}).success).toStrictEqual(false)
expect(typographyValue.safeParse({...validValue, fontSize: '100'}).success).toStrictEqual(false)
expect(typographyValue.safeParse({...validValue, fontSize: ''}).success).toStrictEqual(false)
expect(typographyValue.safeParse({...validValue, fontSize: 10}).success).toStrictEqual(false)
})

it('it fails on invalid lineHeight values', () => {
expect(typographyValue.safeParse({...validValue, lineHeight: '100%'}).success).toStrictEqual(false)
expect(typographyValue.safeParse({...validValue, lineHeight: {value: 100, unit: '%'}}).success).toStrictEqual(false)
expect(typographyValue.safeParse({...validValue, lineHeight: '24px'}).success).toStrictEqual(false)
expect(typographyValue.safeParse({...validValue, lineHeight: '100'}).success).toStrictEqual(false)
expect(typographyValue.safeParse({...validValue, lineHeight: ''}).success).toStrictEqual(false)
expect(typographyValue.safeParse({...validValue, lineHeight: 10}).success).toStrictEqual(false)
Expand Down
Loading