Skip to content

Commit

Permalink
BREAKING: add a parser function to add fontStyle to typography tokens…
Browse files Browse the repository at this point in the history
… based on the fontWeight value
  • Loading branch information
thomasmattheussen authored and jorenbroekema committed Jun 30, 2023
1 parent 3376e96 commit 0363efc
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/tiny-poets-doubt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tokens-studio/sd-transforms': minor
---

BREAKING: add parser that extracts "italic" from fontWeight and adds it as a separate property on Typography tokens object values.
53 changes: 53 additions & 0 deletions src/parsers/add-font-styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { DeepKeyTokenMap, SingleToken, TokenTypographyValue } from '@tokens-studio/types';
// @ts-expect-error no type exported for this function
import getReferences from 'style-dictionary/lib/utils/references/getReferences.js';
// @ts-expect-error no type exported for this function
import usesReference from 'style-dictionary/lib/utils/references/usesReference.js';

function recurse(
slice: DeepKeyTokenMap<false>,
boundGetRef: (ref: string) => Array<SingleToken<false>>,
) {
for (const key in slice) {
const token = slice[key];
const { type, value } = token;
if (type === 'typography') {
let fontWeight;

if (usesReference(value)) {
let ref = { value: value } as SingleToken<false>;
while (ref && ref.value && typeof ref.value === 'string' && usesReference(ref.value)) {
try {
ref = Object.fromEntries(
Object.entries(boundGetRef(ref.value)[0]).map(([k, v]) => [k, v]),
) as SingleToken<false>;
} catch (e) {
console.warn(`Warning: could not resolve reference ${ref.value}`);
return;
}
}
fontWeight = (ref.value as TokenTypographyValue).fontWeight;
(token as SingleToken<false>).value = ref.value;
} else if (typeof value === 'object') {
fontWeight = value.fontWeight;
}

// cast it to TokenTypographyValue now that we've resolved references all the way, we know it cannot be a string anymore.
const tokenValue = value as TokenTypographyValue;
if (fontWeight && fontWeight.toLowerCase().indexOf('italic') > -1) {
// @ts-expect-error fontStyle is not a property that exists on Typography Tokens, we just add it ourselves
tokenValue.fontStyle = 'italic';
tokenValue.fontWeight = tokenValue.fontWeight?.replace(/italic$/i, '').trim();
}
} else if (typeof token === 'object') {
recurse(token as unknown as DeepKeyTokenMap<false>, boundGetRef);
}
}
}

export function addFontStyles(dictionary: DeepKeyTokenMap<false>): DeepKeyTokenMap<false> {
const copy = { ...dictionary };
const boundGetRef = getReferences.bind({ properties: copy });
recurse(copy, boundGetRef);
return copy;
}
1 change: 1 addition & 0 deletions src/parsers/expand-composites.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const typeMaps = {
fontWeight: 'fontWeights',
lineHeight: 'lineHeights',
fontSize: 'fontSizes',
fontStyle: 'fontStyles',
},
};

Expand Down
4 changes: 3 additions & 1 deletion src/registerTransforms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { TransformOptions } from './TransformOptions.js';
import { expandComposites } from './parsers/expand-composites.js';
import { excludeParentKeys } from './parsers/exclude-parent-keys.js';
import { transformOpacity } from './transformOpacity.js';
import { addFontStyles } from './parsers/add-font-styles.js';

const isBrowser = typeof window === 'object';

Expand Down Expand Up @@ -59,7 +60,8 @@ export async function registerTransforms(sd: Core, transformOpts?: TransformOpti
parse: ({ filePath, contents }) => {
const obj = JSON.parse(contents);
const excluded = excludeParentKeys(obj, transformOpts);
const expanded = expandComposites(excluded, filePath, transformOpts);
const withFontStyles = addFontStyles(excluded);
const expanded = expandComposites(withFontStyles, filePath, transformOpts);
return expanded;
},
});
Expand Down
48 changes: 48 additions & 0 deletions test/spec/parsers/add-font-styles.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { expect } from '@esm-bundle/chai';
import { DeepKeyTokenMap } from '@tokens-studio/types';
import { addFontStyles } from '../../../src/parsers/add-font-styles.js';

const tokensInput = {
foo: {
value: {
fontFamily: 'Arial',
fontWeight: 'Bold Italic',
lineHeight: '1.25',
fontSize: '26',
},
type: 'typography',
},
ref: {
value: '{foo}',
type: 'typography',
},
};

const tokensOutput = {
foo: {
value: {
fontFamily: 'Arial',
fontWeight: 'Bold',
fontStyle: 'italic',
lineHeight: '1.25',
fontSize: '26',
},
type: 'typography',
},
ref: {
value: {
fontFamily: 'Arial',
fontWeight: 'Bold',
fontStyle: 'italic',
lineHeight: '1.25',
fontSize: '26',
},
type: 'typography',
},
};

describe('add font style', () => {
it.only(`should expand composition tokens by default`, () => {
expect(addFontStyles(tokensInput as DeepKeyTokenMap<false>)).to.eql(tokensOutput);
});
});

0 comments on commit 0363efc

Please sign in to comment.