Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: 🔥 Remove autogenerated typography classes #2429

Merged
merged 14 commits into from
Sep 19, 2024
310 changes: 248 additions & 62 deletions apps/storefront/tokens/altinn/dark.ts

Large diffs are not rendered by default.

310 changes: 248 additions & 62 deletions apps/storefront/tokens/altinn/light.ts

Large diffs are not rendered by default.

310 changes: 248 additions & 62 deletions apps/storefront/tokens/digdir/dark.ts

Large diffs are not rendered by default.

310 changes: 248 additions & 62 deletions apps/storefront/tokens/digdir/light.ts

Large diffs are not rendered by default.

310 changes: 248 additions & 62 deletions apps/storefront/tokens/portal/dark.ts

Large diffs are not rendered by default.

310 changes: 248 additions & 62 deletions apps/storefront/tokens/portal/light.ts

Large diffs are not rendered by default.

310 changes: 248 additions & 62 deletions apps/storefront/tokens/uutilsynet/dark.ts

Large diffs are not rendered by default.

310 changes: 248 additions & 62 deletions apps/storefront/tokens/uutilsynet/light.ts

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/cli/src/tokens/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export async function buildTokens(options: Options): Promise<void> {

const colorModeConfigs = getConfigs(configs.colorModeVariables, outPath, tokensDir, colormodeThemes);
const semanticConfigs = getConfigs(configs.semanticVariables, outPath, tokensDir, semanticThemes);
const typographyConfigs = getConfigs(configs.typographyCSS, outPath, tokensDir, typographyThemes);
const typographyConfigs = getConfigs(configs.typographyVariables, outPath, tokensDir, typographyThemes);
const storefrontConfigs = getConfigs(configs.typescriptTokens, storefrontOutDir, tokensDir, colormodeThemes);

if (typographyConfigs.length > 0) {
Expand Down
25 changes: 18 additions & 7 deletions packages/cli/src/tokens/build/configs.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { register } from '@tokens-studio/sd-transforms';
import { expandTypesMap, register } from '@tokens-studio/sd-transforms';
import type { ThemeObject } from '@tokens-studio/types';
import * as R from 'ramda';
import StyleDictionary from 'style-dictionary';
Expand All @@ -7,7 +7,7 @@ import { outputReferencesFilter } from 'style-dictionary/utils';

import * as formats from './formats/css.js';
import { jsTokens } from './formats/js-tokens.js';
import { nameKebab, sizeRem, typographyShorthand } from './transformers.js';
import { nameKebab, sizeRem, typographyName } from './transformers.js';
import { permutateThemes as permutateThemes_ } from './utils/permutateThemes.js';
import type { PermutatedThemes } from './utils/permutateThemes.js';
import { pathStartsWithOneOf, typeEquals } from './utils/utils.js';
Expand All @@ -25,7 +25,7 @@ const fileHeader = () => [`These files are generated from design tokens defind u

StyleDictionary.registerTransform(sizeRem);
StyleDictionary.registerTransform(nameKebab);
StyleDictionary.registerTransform(typographyShorthand);
StyleDictionary.registerTransform(typographyName);

StyleDictionary.registerFormat(jsTokens);
StyleDictionary.registerFormat(formats.colormode);
Expand All @@ -38,7 +38,7 @@ const dsTransformers = [
'ts/size/px',
sizeRem.name,
'ts/typography/fontWeight',
typographyShorthand.name,
typographyName.name,
'ts/color/modifiers',
'ts/color/css/hexrgba',
'ts/size/lineheight',
Expand Down Expand Up @@ -149,7 +149,7 @@ export const semanticVariables: GetConfig = ({ outPath, theme }) => {
format: formats.semantic.name,
filter: (token) =>
(!token.isSource || isCalculatedToken(token)) &&
!typeEquals(['color', 'fontWeight', 'fontFamily'], token),
!typeEquals(['color', 'fontWeight', 'fontFamily', 'typography'], token),
},
],
options: {
Expand Down Expand Up @@ -200,14 +200,18 @@ export const typescriptTokens: GetConfig = ({ mode = 'unknown', outPath, theme }
};
};

export const typographyCSS: GetConfig = ({ outPath, theme, typography }) => {
export const typographyVariables: GetConfig = ({ outPath, theme, typography }) => {
const selector = `${typography === 'primary' ? ':root, ' : ''}[data-ds-typography="${typography}"]`;
const layer = `ds.theme.typography.${typography}`;

return {
usesDtcg: true,
log: { verbosity: 'silent' },
preprocessors: ['tokens-studio'],
expand: {
include: ['typography'],
typesMap: { ...expandTypesMap, typography: { ...expandTypesMap.typography, letterSpacing: 'dimension' } },
},
platforms: {
css: {
prefix,
Expand All @@ -216,7 +220,14 @@ export const typographyCSS: GetConfig = ({ outPath, theme, typography }) => {
layer,
buildPath: `${outPath}/${theme}/`,
basePxFontSize,
transforms: [nameKebab.name, 'ts/size/px', sizeRem.name, 'ts/size/lineheight', 'ts/typography/fontWeight'],
transforms: [
nameKebab.name,
'ts/size/px',
sizeRem.name,
'ts/size/lineheight',
'ts/typography/fontWeight',
typographyName.name,
],
files: [
{
destination: `typography/${typography}.css`,
Expand Down
126 changes: 17 additions & 109 deletions packages/cli/src/tokens/build/formats/css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ export const colormode: Format = {
usesDtcg,
});

const colorSchemeProperty = mode_ === 'dark' || mode_ === 'light' ? `color-scheme: ${mode_};\n` : '';
const colorSchemeProperty = mode_ === 'dark' || mode_ === 'light' ? `\n color-scheme: ${mode_};\n` : '';

const content = `{\n${allTokens.map(format).join('\n')}\n${colorSchemeProperty}}\n`;
const formattedTokens = dictionary.allTokens.map(format).join('\n');
const content = `{\n${formattedTokens}\n${colorSchemeProperty}}\n`;
const autoSelectorContent = ['light', 'dark'].includes(mode_) ? prefersColorScheme(mode_, content) : '';
const body = R.isNotNil(layer)
? `@layer ${layer} {\n${selector} ${content} ${autoSelectorContent}\n}\n`
Expand All @@ -48,7 +49,6 @@ const calculatedVariable = R.pipe(R.split(/:(.*?);/g), (split) => `${split[0]}:
export const semantic: Format = {
name: 'ds/css-semantic',
format: async ({ dictionary, file, options, platform }) => {
const { allTokens } = dictionary;
const { outputReferences, usesDtcg } = options;
const { selector, isCalculatedToken, layer } = platform;

Expand All @@ -61,7 +61,7 @@ export const semantic: Format = {
usesDtcg,
});

const formatTokens = R.map((token: TransformedToken) => {
const formattedTokens = R.map((token: TransformedToken) => {
const originalValue = getValue<string>(token.original);

if (
Expand All @@ -75,50 +75,19 @@ export const semantic: Format = {
}

return format(token);
});
}, dictionary.allTokens);

const formattedVariables = formatTokens(allTokens);
const content = `{\n${formattedVariables.join('\n')}\n}\n`;
const content = `{\n${formattedTokens.join('\n')}\n}\n`;
const body = R.isNotNil(layer) ? `@layer ${layer} {\n${selector} ${content}\n}\n` : `${selector} ${content}\n`;

return header + body;
},
};

type Typgraphy = {
fontWeight: string;
fontSize: string;
lineHeight: number;
fontFamily: string;
};

type ProcessedTokens = { variables: string[]; classes: string[] };

const sortByType = R.sortBy<TransformedToken>((token) => token?.$type === 'typography');
const getVariableName = R.pipe<string[], string[], string, string, string, string>(
R.split(':'),
R.head,
R.defaultTo(''),
R.trim,
(name) => `var(${name})`,
);

const bemify = R.pipe(
(path: string[]) => {
const filteredPath = path.filter((p) => p !== 'typography');
const withPrefix = R.concat([prefix], R.remove(0, 0, filteredPath));
const [rest, last] = R.splitAt(-1, withPrefix);

const className = `${rest.join('-')}--${R.head(last)}`;
return className;
},
R.trim,
R.toLower,
);

const classSelector = R.pipe(R.prop('path'), bemify);
const sortTypographyLast = R.sortWith<TransformedToken>([
R.ascend((token) => (typeEquals('typography')(token) ? 1 : 0)),
// Predicate to filter tokens with .path array that includes both typography and fontFamily
const typographyFontFamilyPredicate = R.allPass([
R.pathSatisfies(R.includes('typography'), ['path']),
R.pathSatisfies(R.includes('fontFamily'), ['path']),
]);

export const typography: Format = {
Expand All @@ -136,74 +105,13 @@ export const typography: Format = {
usesDtcg,
});

const sortedTokens = sortTypographyLast(dictionary.allTokens);

const formattedTokens = R.pipe(
sortByType,
R.reduce<TransformedToken, ProcessedTokens>(
(acc, token) => {
if (typeEquals('fontweight', token)) {
const className = `
.${classSelector(token)} {
font-weight: ${getValue<string>(token)};
}`;

return Object.assign(acc, {
variables: [...acc.variables, format(token)],
classes: [...acc.classes, className],
});
}

if (typeEquals('lineheight', token)) {
const className = `
.${classSelector(token)} {
line-height: ${getValue<string>(token)};
}`;

return Object.assign(acc, {
variables: [...acc.variables, format(token)],
classes: [...acc.classes, className],
});
}

if (typeEquals('typography', token)) {
let references: TransformedToken[] = [];
try {
references = getReferences(getValue<Typgraphy>(token.original), dictionary.tokens);
} catch (error) {
console.error('Error getting references', error);
throw new Error(JSON.stringify(token, null, 2));
}
const fontweight = R.find<TransformedToken>(typeEquals(['fontweight']))(references);
const lineheight = R.find<TransformedToken>(typeEquals(['lineheight']))(references);
const fontsize = R.find<TransformedToken>(typeEquals(['fontsize']))(references);
const letterSpacing = R.find<TransformedToken>(typeEquals(['dimension']))(references);

const fontSizeVar = fontsize ? getVariableName(format(fontsize)) : null;
const fontWeightVar = fontweight ? getVariableName(format(fontweight)) : null;
const lineheightVar = lineheight ? getVariableName(format(lineheight)) : null;
const letterSpacingVar = letterSpacing ? getVariableName(format(letterSpacing)) : null;

const className = `
.${classSelector(token)} {
${fontSizeVar ? `font-size: ${fontSizeVar};` : ''}
${lineheightVar ? `line-height: ${lineheightVar};` : ''}
${fontWeightVar ? `font-weight: ${fontWeightVar};` : ''}
${letterSpacingVar ? `letter-spacing: ${letterSpacingVar};` : ''}
}`;

return Object.assign(acc, { classes: [className, ...acc.classes] });
}

return Object.assign(acc, { variables: [...acc.variables, format(token)] });
},
{ variables: [], classes: [] },
),
)(sortedTokens);

const classes = formattedTokens.classes.join('\n');
const variables = formattedTokens.variables.join('\n');
const content = selector ? `${selector} {\n${variables}\n${classes}\n}` : classes;
console.log('dictionary.allTokens', dictionary.allTokens);

const filteredTokens = R.reject(typographyFontFamilyPredicate, dictionary.allTokens);

const formattedTokens = R.pipe(R.map(format), R.join('\n'))(filteredTokens);

const content = selector ? `${selector} {\n${formattedTokens}\n}` : formattedTokens;
const body = R.isNotNil(layer) ? `@layer ${layer} {\n${content}\n}` : content;

return header + body;
Expand Down
19 changes: 6 additions & 13 deletions packages/cli/src/tokens/build/transformers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,13 @@ export const nameKebab: Transform = {
},
};

type Typgraphy = {
fontWeight: string;
fontSize: string;
lineHeight: number;
fontFamily: string;
};

export const typographyShorthand: Transform = {
name: 'typography/shorthand',
type: 'value',
export const typographyName: Transform = {
name: 'name/typography',
type: 'name',
transitive: true,
filter: (token) => typeEquals('typography', token),
// expanded tokens have different type so we match on path instead
filter: (token) => pathStartsWithOneOf(['typography'], token),
transform: (token) => {
const typography = getValue<Typgraphy>(token);
return `${typography.fontWeight} ${typography.fontSize}/${typography.lineHeight} '${typography.fontFamily}'`;
return token.name.replace('-typography', '');
},
};
Loading
Loading