Skip to content

Commit

Permalink
fix(web): Fix type and breakpoints tokens (#124)
Browse files Browse the repository at this point in the history
This PR fixes system type and breakpoints tokens.

[category:Web Tokens]

Release Note:
Type tokens have been fixed to refer to system font tokens instead of base. Breakpoints tokens have been fixed to have px value instead of rem.

Co-authored-by: Raisa Primerova <[email protected]>
  • Loading branch information
RayRedGoose and Raisa Primerova authored Oct 7, 2024
1 parent 8e81145 commit 0cab56d
Show file tree
Hide file tree
Showing 12 changed files with 136 additions and 85 deletions.
13 changes: 4 additions & 9 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
plugins: [
'@typescript-eslint',
],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'prettier',
],
plugins: ['@typescript-eslint'],
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
rules: {
"@typescript-eslint/no-explicit-any": "off"
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/ban-ts-ignore': 'off',
},
};
1 change: 1 addition & 0 deletions packages/canvas-tokens/_refs.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions packages/canvas-tokens/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ StyleDictionary.registerTransformGroup({
'name/cti/kebab',
'value/flatten-border',
'value/shadow/flat-sys',
'value/breakpoints/px',
'value/hex-to-rgba',
'value/wrapped-font-family',
'value/math',
Expand Down
96 changes: 48 additions & 48 deletions packages/canvas-tokens/tokens/web/sys.json
Original file line number Diff line number Diff line change
Expand Up @@ -1047,30 +1047,30 @@
"subtext": {
"small": {
"value": {
"fontFamily": "{font-family.50}",
"fontWeight": "{font-weight.400}",
"lineHeight": "{line-height.50}",
"fontSize": "{font-size.25}",
"fontFamily": "{font-family.default}",
"fontWeight": "{font-weight.normal}",
"lineHeight": "{line-height.subtext.small}",
"fontSize": "{font-size.subtext.small}",
"letterSpacing": "{letter-spacing.50}"
},
"type": "typography"
},
"medium": {
"value": {
"fontFamily": "{font-family.50}",
"fontWeight": "{font-weight.400}",
"lineHeight": "{line-height.50}",
"fontSize": "{font-size.50}",
"fontFamily": "{font-family.default}",
"fontWeight": "{font-weight.normal}",
"lineHeight": "{line-height.subtext.medium}",
"fontSize": "{font-size.subtext.medium}",
"letterSpacing": "{letter-spacing.100}"
},
"type": "typography"
},
"large": {
"value": {
"fontFamily": "{font-family.50}",
"fontWeight": "{font-weight.400}",
"lineHeight": "{line-height.100}",
"fontSize": "{font-size.75}",
"fontFamily": "{font-family.default}",
"fontWeight": "{font-weight.normal}",
"lineHeight": "{line-height.subtext.large}",
"fontSize": "{font-size.subtext.large}",
"letterSpacing": "{letter-spacing.150}"
},
"type": "typography"
Expand All @@ -1079,87 +1079,87 @@
"body": {
"small": {
"value": {
"fontFamily": "{font-family.50}",
"fontWeight": "{font-weight.400}",
"lineHeight": "{line-height.150}",
"fontSize": "{font-size.100}",
"fontFamily": "{font-family.default}",
"fontWeight": "{font-weight.normal}",
"lineHeight": "{line-height.body.small}",
"fontSize": "{font-size.body.small}",
"letterSpacing": "{letter-spacing.200}"
},
"type": "typography"
},
"medium": {
"value": {
"fontFamily": "{font-family.50}",
"fontWeight": "{font-weight.400}",
"lineHeight": "{line-height.200}",
"fontSize": "{font-size.125}"
"fontFamily": "{font-family.default}",
"fontWeight": "{font-weight.normal}",
"lineHeight": "{line-height.body.medium}",
"fontSize": "{font-size.body.medium}"
},
"type": "typography"
},
"large": {
"value": {
"fontFamily": "{font-family.50}",
"fontWeight": "{font-weight.400}",
"lineHeight": "{line-height.200}",
"fontSize": "{font-size.150}"
"fontFamily": "{font-family.default}",
"fontWeight": "{font-weight.normal}",
"lineHeight": "{line-height.body.large}",
"fontSize": "{font-size.body.large}"
},
"type": "typography"
}
},
"heading": {
"small": {
"value": {
"fontFamily": "{font-family.50}",
"fontWeight": "{font-weight.700}",
"lineHeight": "{line-height.250}",
"fontSize": "{font-size.200}"
"fontFamily": "{font-family.default}",
"fontWeight": "{font-weight.bold}",
"lineHeight": "{line-height.heading.small}",
"fontSize": "{font-size.heading.small}"
},
"type": "typography"
},
"medium": {
"value": {
"fontFamily": "{font-family.50}",
"fontWeight": "{font-weight.700}",
"lineHeight": "{line-height.300}",
"fontSize": "{font-size.250}"
"fontFamily": "{font-family.default}",
"fontWeight": "{font-weight.bold}",
"lineHeight": "{line-height.heading.medium}",
"fontSize": "{font-size.heading.medium}"
},
"type": "typography"
},
"large": {
"value": {
"fontFamily": "{font-family.50}",
"fontWeight": "{font-weight.700}",
"lineHeight": "{line-height.350}",
"fontSize": "{font-size.300}"
"fontFamily": "{font-family.default}",
"fontWeight": "{font-weight.bold}",
"lineHeight": "{line-height.heading.large}",
"fontSize": "{font-size.heading.large}"
},
"type": "typography"
}
},
"title": {
"small": {
"value": {
"fontFamily": "{font-family.50}",
"fontWeight": "{font-weight.700}",
"lineHeight": "{line-height.400}",
"fontSize": "{font-size.400}"
"fontFamily": "{font-family.default}",
"fontWeight": "{font-weight.bold}",
"lineHeight": "{line-height.title.small}",
"fontSize": "{font-size.title.small}"
},
"type": "typography"
},
"medium": {
"value": {
"fontFamily": "{font-family.50}",
"fontWeight": "{font-weight.700}",
"lineHeight": "{line-height.500}",
"fontSize": "{font-size.500}"
"fontFamily": "{font-family.default}",
"fontWeight": "{font-weight.bold}",
"lineHeight": "{line-height.title.medium}",
"fontSize": "{font-size.title.medium}"
},
"type": "typography"
},
"large": {
"value": {
"fontFamily": "{font-family.50}",
"fontWeight": "{font-weight.700}",
"lineHeight": "{line-height.600}",
"fontSize": "{font-size.600}"
"fontFamily": "{font-family.default}",
"fontWeight": "{font-weight.bold}",
"lineHeight": "{line-height.title.large}",
"fontSize": "{font-size.title.large}"
},
"type": "typography"
}
Expand Down
5 changes: 5 additions & 0 deletions packages/canvas-tokens/utils/filters/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ export const isBaseOpacity: Matcher = token => {
return level === 'base' && category === 'opacity' && parseFloat(token.value) > 1;
};

export const isBreakpoints: Matcher = token => {
const [level, category] = token.path;
return level === 'sys' && category === 'breakpoints';
};

export const filterCodeTokens: Matcher = token => {
const excludedTokens = ['level', 'shadow', 'typescale'];
return !excludedTokens.includes(token.path[1]);
Expand Down
33 changes: 5 additions & 28 deletions packages/canvas-tokens/utils/tokenStudioParser.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {kebabCase} from 'case-anything';
import {DesignToken} from 'style-dictionary/types/DesignToken';
import refsList from '../_refs.json';

export function resolveRef(ref: string, resolver: (full: string, ref: string) => string) {
// comment explaining what this RegExp does.
Expand Down Expand Up @@ -31,34 +32,10 @@ export const tokenStudioParser = ({contents}: any) => {
return parsed;
};

const levelRefs = {
base: [
'palette',
'opacity',
'font-size',
'line-height',
'typescale',
'font-family',
'font-weight',
'letter-spacing',
'shadow',
'level',
'extended',
'unit',
],
brand: ['primary', 'alert', 'error', 'success', 'neutral', 'common', 'gradient'],
sys: ['color', 'breakpoints', 'depth', 'shape', 'space', 'type'],
};

const getLevel = (ref: string): string => {
const [key] = ref.split('.');

return Object.keys(levelRefs).reduce((acc: string, item: string) => {
if (levelRefs[item as 'base' | 'brand' | 'sys'].includes(key)) {
return item;
}
return acc;
}, '');
const getLevel = (ref: string): string | void => {
return Object.keys(refsList).find((key: string) =>
(refsList as any)[key].some((item: string) => item.startsWith(ref))
);
};

const replaceDescriptionByComment = (token: DesignToken) => {
Expand Down
10 changes: 10 additions & 0 deletions packages/canvas-tokens/utils/transformers/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {Transform} from 'style-dictionary';
import * as math from 'mathjs';
import * as filter from '../filters';
import {flatShadow} from './flatShadow';
import {flatRGBAColor} from './flatRGBAColor';
Expand Down Expand Up @@ -47,6 +48,15 @@ export const transforms: Record<string, Transform> = {
matcher: filter.isBaseOpacity,
transformer: ({value}) => `${value / 100}`,
},
'value/breakpoints/px': {
type: 'value',
transitive: true,
matcher: filter.isBreakpoints,
transformer: ({value}) => {
const expr = value.replace('0.25rem', '4');
return `${math.evaluate(expr)}px`;
},
},
// transform function that changes a value to its CSS var name
'value/variables': {
type: 'value',
Expand Down
48 changes: 48 additions & 0 deletions scripts/utils/generateRefs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import fs from 'fs';
import {decodeJSONBufferString} from './parse-utils';
import path from 'path';

type Transform = (
tokens: Record<string, any>,
parsed?: any,
level?: string
) => Record<string, string[]>;

const transformToRefs: Transform = (tokens, parsed = {}, level = '') => {
const keys = Object.keys(tokens);

keys.forEach(key => {
const isHighestLevel = /base|brand|sys/.test(key);
if (isHighestLevel) {
parsed[key] = [];
}

if (keys.includes('value')) {
parsed?.push(level);
return parsed;
}

transformToRefs(
tokens[key],
isHighestLevel ? parsed[key] : parsed,
isHighestLevel ? '' : level ? `${level}.${key}` : key
);
});

return parsed;
};

export const generateRefs = async (file: any) => {
const refsFileName = path.resolve(__dirname, '../../packages/canvas-tokens/_refs.json');

await fs.readFile(refsFileName, async (err, data) => {
const tokens = transformToRefs(file);

if (err || !data) {
fs.writeFileSync(refsFileName, JSON.stringify(tokens));
} else {
const content = decodeJSONBufferString(data as any);
fs.writeFileSync(refsFileName, JSON.stringify({...content, ...tokens}));
}
});
};
3 changes: 3 additions & 0 deletions scripts/utils/sync-base-config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {tokensStudioRepoParams, canvasTokensRepoParams} from './api-client';
import {ContentFile, getFileContent, updateFileContent} from './file-content';
import {generateRefs} from './generateRefs';
import {decodeJSONBufferString, encodeJSONToString} from './parse-utils';

// Format the config object into the shape expected by the consumer
Expand Down Expand Up @@ -45,6 +46,8 @@ export async function syncBaseConfig() {
// Re-encode the formatted JSON object to a Buffer string
const encodedConfig = encodeJSONToString(formattedConfig);

generateRefs(formattedConfig);

// Sync Canvas Tokens config file with the updated config
updateFileContent({
owner: canvasTokensRepoParams.owner,
Expand Down
3 changes: 3 additions & 0 deletions scripts/utils/sync-brand-config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {tokensStudioRepoParams, canvasTokensRepoParams} from './api-client';
import {ContentFile, getFileContent, updateFileContent} from './file-content';
import {generateRefs} from './generateRefs';
import {decodeJSONBufferString, encodeJSONToString} from './parse-utils';

// Format the config object into the shape expected by the consumer
Expand Down Expand Up @@ -45,6 +46,8 @@ export async function syncBrandConfig() {
// Re-encode the formatted JSON object to a Buffer string
const encodedConfig = encodeJSONToString(formattedConfig);

generateRefs(formattedConfig);

// Sync Canvas Tokens config file with the updated config
updateFileContent({
owner: canvasTokensRepoParams.owner,
Expand Down
3 changes: 3 additions & 0 deletions scripts/utils/sync-sys-config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {tokensStudioRepoParams, canvasTokensRepoParams} from './api-client';
import {ContentFile, getFileContent, updateFileContent} from './file-content';
import {generateRefs} from './generateRefs';
import {decodeJSONBufferString, encodeJSONToString} from './parse-utils';

/**
Expand Down Expand Up @@ -80,6 +81,8 @@ export async function syncSystemConfig() {
// Re-encode the formatted JSON object to a Buffer string
const encodedConfig = encodeJSONToString(formattedConfig);

generateRefs(formattedConfig);

// Fetch system token config from canvas-tokens repo
const canvasSystemTokensConfig = (await getFileContent({
owner: canvasTokensRepoParams.owner,
Expand Down
5 changes: 5 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@
"module": "commonjs",
"jsx": "react",
"esModuleInterop": true,
"resolveJsonModule": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"composite": true
},
"include": [
// ...other includes
"packages/**/*.json"
],
"ts-node": {
"compilerOptions": {
"module": "commonjs"
Expand Down

0 comments on commit 0cab56d

Please sign in to comment.