Skip to content

Commit

Permalink
Feat(exporter-tokens): Export only Theme tokens collection
Browse files Browse the repository at this point in the history
- Filter out primitives from the generated tokens and leave only color theme tokens

- solves #DS-1543
  • Loading branch information
pavelklibani committed Nov 11, 2024
1 parent d691cc5 commit 3f224f1
Show file tree
Hide file tree
Showing 6 changed files with 213 additions and 41 deletions.
70 changes: 35 additions & 35 deletions exporters/tokens/generated/exporter.cjs

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions exporters/tokens/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ export const JS_INDENTATION = ' ';
export const SCSS_DIRECTORY = 'scss';
export const SCSS_INDENTATION = ' ';
export const THEMES_DIRECTORY = 'themes';
export const TOKEN_COLLECTION_NAME = 'Theme tokens';
export const TOKEN_PROPERTY_NAME = 'Collection';
export const TYPOGRAPHY_KEY = 'styles';
20 changes: 14 additions & 6 deletions exporters/tokens/src/generators/fileGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { TokenGroup, Token, Supernova, TokenTheme } from '@supernovaio/sdk-exporters';
import { generateFileContent } from './contentGenerator';
import { Supernova, Token, TokenGroup, TokenTheme } from '@supernovaio/sdk-exporters';
import { commonThemedFilesData, FileData, nonThemedFilesData, themedFilesData } from '../config/fileConfig';
import { toCamelCase } from '../helpers/stringHelper';
import { indentAndFormat } from '../formatters/stylesFormatter';
import { GLOBAL_DIRECTORY, JS_DIRECTORY, SCSS_DIRECTORY, THEMES_DIRECTORY } from '../constants';
import { indentAndFormat } from '../formatters/stylesFormatter';
import { filterColorCollections } from '../helpers/colorHelper';
import { toCamelCase } from '../helpers/stringHelper';
import { generateFileContent } from './contentGenerator';

export const generateFiles = (
tokens: Array<Token>,
Expand Down Expand Up @@ -79,6 +80,7 @@ export const generateOutputFilesByThemes = async (
sdk: Supernova,
): Promise<{ path: string; fileName: string; content: string }[]> => {
const outputFiles: { path: string; fileName: string; content: string }[] = [];
const filteredColorCollections = filterColorCollections(tokens);

// Generate global files for non-themed tokens
const globalFiles = generateFiles(tokens, mappedTokens, tokenGroups, nonThemedFilesData);
Expand Down Expand Up @@ -121,7 +123,7 @@ export const generateOutputFilesByThemes = async (
// Compute themed tokens for all themes in parallel
const allThemes = await Promise.all(
themes.map(async (theme) => {
const themedTokens = sdk.tokens.computeTokensByApplyingThemes(tokens, tokens, [theme]);
const themedTokens = sdk.tokens.computeTokensByApplyingThemes(tokens, filteredColorCollections, [theme]);

return { themedTokens, theme };
}),
Expand Down Expand Up @@ -161,7 +163,13 @@ export const generateOutputFilesByThemes = async (
const rootThemesFileContent = generateThemesRootFile(themes);
const rootTsThemesFileContent = generateThemesRootFile(themes, true);
const rootScssThemesFile = `@forward 'color-tokens';\n`;
const colorTokensFile = generateFiles(tokens, mappedTokens, tokenGroups, commonThemedFilesData, false);
const colorTokensFile = generateFiles(
filteredColorCollections,
mappedTokens,
tokenGroups,
commonThemedFilesData,
false,
);
outputFiles.push({ path: `./${SCSS_DIRECTORY}/`, fileName: '@themes.scss', content: rootThemesFileContent });
outputFiles.push({
path: `./${JS_DIRECTORY}/${THEMES_DIRECTORY}`,
Expand Down
10 changes: 10 additions & 0 deletions exporters/tokens/src/helpers/__tests__/colorHelper.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { exampleCollectionTokens, expectedCollectionValue } from '../../../tests/fixtures/exampleCollectionTokens';
import { examplePrefixToken } from '../../../tests/fixtures/examplePrefixToken';
import {
canHexBeShortened,
filterColorCollections,
findAllHexColorsInStringAndNormalize,
normalizeColor,
removeAlphaChannel,
Expand Down Expand Up @@ -105,4 +107,12 @@ describe('colorHelper', () => {
});
},
);

describe('filterColorCollections', () => {
it('should filter color collections', () => {
const tokens = Array.from(exampleCollectionTokens.values());

expect(filterColorCollections(tokens)).toStrictEqual(expectedCollectionValue);
});
});
});
25 changes: 25 additions & 0 deletions exporters/tokens/src/helpers/colorHelper.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { Token, TokenType } from '@supernovaio/sdk-exporters';
import { TOKEN_COLLECTION_NAME, TOKEN_PROPERTY_NAME } from '../constants';

const HEX_COLOR_REGEX = /#([A-Fa-f0-9]{6,8})\b/g;
const LONG_HEX_WITH_ALPHA_LENGTH = 8;
const SHORT_HEX_WITH_ALPHA_LENGTH = 4;
Expand Down Expand Up @@ -73,3 +76,25 @@ export const transformColorsToVariables = (

return transformedValue;
};

export const filterColorCollections = (tokens: Token[]) => {
return tokens.filter((item) => {
// Include all tokens that are not of tokenType "Color"
if (item.tokenType !== TokenType.color) {
return true;
}

// Proceed with filtering for "Color" tokenType
const collectionProperty = item.properties.find((prop) => prop.name === TOKEN_PROPERTY_NAME);
if (!collectionProperty) {
return false;
}

const themeTokenOption = collectionProperty.options?.find((option) => option.name === TOKEN_COLLECTION_NAME);
if (!themeTokenOption) {
return false;
}

return item.propertyValues?.Collection === themeTokenOption.id;
});
};
127 changes: 127 additions & 0 deletions exporters/tokens/tests/fixtures/exampleCollectionTokens.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import { ColorToken, StringToken, Token, TokenType } from '@supernovaio/sdk-exporters';

export const exampleCollectionTokens = new Map<string, Token>();
exampleCollectionTokens.set('colorCollectionRef1', {
id: 'colorCollectionRef1',
name: 'Theme Color',
tokenType: TokenType.color,
properties: [
{
name: 'Collection',
options: [
{
id: 'theme-tokens-id',
name: 'Theme tokens',
},
{
id: 'primitives-id',
name: 'Primitives',
},
{
id: 'global-tokens-id',
name: 'Global tokens',
},
],
},
],
propertyValues: { Collection: 'theme-tokens-id' },
} as unknown as ColorToken);

exampleCollectionTokens.set('colorCollectionRef2', {
id: 'colorCollectionRef2',
name: 'Primitive Color',
tokenType: TokenType.color,
properties: [
{
name: 'Collection',
options: [
{
id: 'theme-tokens-id',
name: 'Theme tokens',
},
{
id: 'primitives-id',
name: 'Primitives',
},
{
id: 'global-tokens-id',
name: 'Global tokens',
},
],
},
],
propertyValues: { Collection: 'primitives-id' },
} as unknown as ColorToken);

exampleCollectionTokens.set('colorCollectionRef3', {
id: 'colorCollectionRef3',
name: 'Global Color',
tokenType: TokenType.color,
properties: [
{
name: 'Collection',
options: [
{
id: 'theme-tokens-id',
name: 'Theme tokens',
},
{
id: 'primitives-id',
name: 'Primitives',
},
{
id: 'global-tokens-id',
name: 'Global tokens',
},
],
},
],
propertyValues: { Collection: 'global-tokens-id' },
} as unknown as ColorToken);

exampleCollectionTokens.set('stringRef', {
id: 'stringRef',
name: 'Columns',
tokenType: TokenType.string,
parentGroupId: '2',
origin: {
name: 'Grid/Columns',
},
value: 'value',
} as unknown as StringToken);

export const expectedCollectionValue = [
{
id: 'colorCollectionRef1',
name: 'Theme Color',
properties: [
{
name: 'Collection',
options: [
{
id: 'theme-tokens-id',
name: 'Theme tokens',
},
{
id: 'primitives-id',
name: 'Primitives',
},
{
id: 'global-tokens-id',
name: 'Global tokens',
},
],
},
],
propertyValues: { Collection: 'theme-tokens-id' },
tokenType: 'Color',
},
{
id: 'stringRef',
name: 'Columns',
origin: { name: 'Grid/Columns' },
parentGroupId: '2',
tokenType: 'String',
value: 'value',
},
];

0 comments on commit 3f224f1

Please sign in to comment.