Skip to content
Open
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
2 changes: 1 addition & 1 deletion .github/workflows/import-design-tokens.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
run: yarn install --immutable --immutable-cache

- name: Generate skins from design tokens
run: cd packages/generate-design-tokens && yarn && node index.js
run: cd packages/generate-design-tokens && yarn && node index.ts

- name: Prettier
run: yarn prettier src/skins --write
Expand Down
6 changes: 6 additions & 0 deletions css/blau.css

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

testing the generation by using mistica-design master locally

Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/**
* @generated
* This file was automatically generated by the generate-design-tokens script.
* Do not edit it by hand: your changes will be overwritten the next time the script runs.
*/

[data-mistica-skin='blau'] {
/* Palette colors */
--mistica-blau-white: #ffffff;
Expand Down
1,490 changes: 1,490 additions & 0 deletions css/community/cyber.css

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions css/esimflag.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/**
* @generated
* This file was automatically generated by the generate-design-tokens script.
* Do not edit it by hand: your changes will be overwritten the next time the script runs.
*/

[data-mistica-skin='esimflag'] {
/* Palette colors */
--mistica-esimflag-white: #ffffff;
Expand Down
6 changes: 6 additions & 0 deletions css/mistica-common.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/**
* @generated
* This file was automatically generated by the generate-design-tokens script.
* Do not edit it by hand: your changes will be overwritten the next time the script runs.
*/

/* Default text color */
[data-mistica-skin] {
color: var(--mistica-color-textPrimary);
Expand Down
6 changes: 6 additions & 0 deletions css/movistar.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/**
* @generated
* This file was automatically generated by the generate-design-tokens script.
* Do not edit it by hand: your changes will be overwritten the next time the script runs.
*/

[data-mistica-skin='movistar'] {
/* Palette colors */
--mistica-movistar-white: #ffffff;
Expand Down
6 changes: 6 additions & 0 deletions css/o2.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/**
* @generated
* This file was automatically generated by the generate-design-tokens script.
* Do not edit it by hand: your changes will be overwritten the next time the script runs.
*/

[data-mistica-skin='o2'] {
/* Palette colors */
--mistica-o2-white: #ffffff;
Expand Down
6 changes: 6 additions & 0 deletions css/telefonica.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/**
* @generated
* This file was automatically generated by the generate-design-tokens script.
* Do not edit it by hand: your changes will be overwritten the next time the script runs.
*/

[data-mistica-skin='telefonica'] {
/* Palette colors */
--mistica-telefonica-white: #ffffff;
Expand Down
6 changes: 6 additions & 0 deletions css/vivo-evolution.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/**
* @generated
* This file was automatically generated by the generate-design-tokens script.
* Do not edit it by hand: your changes will be overwritten the next time the script runs.
*/

[data-mistica-skin='vivo-evolution'] {
/* Palette colors */
--mistica-vivo-evolution-vivoNeutral0: #ffffff;
Expand Down
6 changes: 6 additions & 0 deletions css/vivo.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/**
* @generated
* This file was automatically generated by the generate-design-tokens script.
* Do not edit it by hand: your changes will be overwritten the next time the script runs.
*/

[data-mistica-skin='vivo'] {
/* Palette colors */
--mistica-vivo-white: #ffffff;
Expand Down
23 changes: 20 additions & 3 deletions packages/generate-design-tokens/README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
# generate-design-tokens

Script to generate mistica skins (in src/skins folder) from design tokens imported from mistica-design repo.
Script to generate mistica skins from design tokens imported from the mistica-design repo.

Run:
## Generated Files

- **Main skins** → `src/skins/` and `css/`
- **Community skins** → `src/community/skins/` and `css/community/`

The script discovers community skin tokens in the `tokens/community/` folder of the mistica-design repository
and generates corresponding TypeScript and CSS files.

## Run

The script is written in TypeScript and runs directly on Node (>= 24), which strips the types at runtime, so
no build step is required:

```bash
node index.ts
```

Type-check the package with:

```bash
node index.js
yarn typecheck
```

This script is used by the import-design-tokens GitHub workflow.
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import fs from 'fs';
import path from 'path';
import * as fs from 'node:fs';
import * as path from 'node:path';

const pxToRem = (px) => `${(px / 16).toFixed(3)}rem`;
import type {ColorDescription, DesignTokens, GradientDescription, RadiusDescription} from './token-types.ts';

const fromHexToRgb = (hexColor) => {
const pxToRem = (px: number): string => `${(px / 16).toFixed(3)}rem`;

const fromHexToRgb = (hexColor: string): [number, number, number] => {
if (!hexColor.startsWith('#')) {
throw Error(`Bad hex color, ${hexColor}`);
}
Expand All @@ -24,7 +26,7 @@ const fromHexToRgb = (hexColor) => {
throw Error(`Bad hex color, ${hexColor}`);
};

export const buildRadius = (radiusDescription) => {
export const buildRadius = (radiusDescription: RadiusDescription): string => {
if (radiusDescription.value.endsWith('%')) {
return radiusDescription.value;
}
Expand All @@ -42,45 +44,44 @@ export const buildRadius = (radiusDescription) => {
};

const prefix = 'mistica-';
const colorSchemeSelector = (colorScheme) => `[data-${prefix}color-scheme="${colorScheme}"]`;
const buildVarName = (propertyName, name) => `--${prefix}${propertyName}-${name}`;
const buildColorVarName = (colorName) => buildVarName('color', colorName);
const buildBorderRadiusVarName = (radiusName) => buildVarName('border-radius', radiusName);
const buildFontSizeVarName = (textPreset) => buildVarName('font-size', textPreset);
const buildLineHeightVarName = (textPreset) => buildVarName('line-height', textPreset);
const buildFontWeightVarName = (textPreset) => buildVarName('font-weight', textPreset);
const colorSchemeSelector = (colorScheme: string): string => `[data-${prefix}color-scheme="${colorScheme}"]`;
const buildVarName = (propertyName: string, name: string): string => `--${prefix}${propertyName}-${name}`;
const buildColorVarName = (colorName: string): string => buildVarName('color', colorName);
const buildBorderRadiusVarName = (radiusName: string): string => buildVarName('border-radius', radiusName);
const buildFontSizeVarName = (textPreset: string): string => buildVarName('font-size', textPreset);
const buildLineHeightVarName = (textPreset: string): string => buildVarName('line-height', textPreset);
const buildFontWeightVarName = (textPreset: string): string => buildVarName('font-weight', textPreset);
const tabletMediaQuery = '@media (min-width: 768px)';
const desktopMediaQuery = '@media (min-width: 1024px)';
const largeDesktopMediaQuery = '@media (min-width: 1512px)';

export const generateSkinCssSrc = (skinName, DESIGN_TOKENS_FOLDER) => {
type TextPreset = {
size?: {mobile: number; desktop: number};
lineHeight?: {mobile: number; desktop: number};
weight?: 'light' | 'regular' | 'medium' | 'bold';
};

export const generateSkinCssSrc = (skinName: string, DESIGN_TOKENS_FOLDER: string): string => {
const designTokensFile = fs.readFileSync(path.join(DESIGN_TOKENS_FOLDER, `${skinName}.json`), 'utf8');
const designTokens = JSON.parse(designTokensFile);
const designTokens: DesignTokens = JSON.parse(designTokensFile);

const skinSelector = `[data-${prefix}skin='${skinName}']`;
const palettePrefix = prefix + `${skinName}-`;
const buildPaletteColorVarName = (colorName) => `--${palettePrefix}${colorName}`;
const buildRawPaletteColorVarName = (colorName) => `--${palettePrefix}raw-${colorName}`;

const usedPaleteColors = new Set();
const usedRawPaletteColors = new Set();

/**
* @param {{angle: number, colors: Array<{
* value: string,
* stop: number, // value from 0 to 1
* }>}} gradientDescription
* @returns {string}
*/
const buildCssGradient = (gradientDescription) => {
const buildPaletteColorVarName = (colorName: string): string => `--${palettePrefix}${colorName}`;
const buildRawPaletteColorVarName = (colorName: string): string => `--${palettePrefix}raw-${colorName}`;

const usedPaleteColors = new Set<string>();
const usedRawPaletteColors = new Set<string>();

const buildCssGradient = (gradientDescription: GradientDescription): string => {
const stops = gradientDescription.colors.map((color) => {
// eslint-disable-next-line no-use-before-define
// eslint-disable-next-line @typescript-eslint/no-use-before-define
return `${buildCssColor(color)} ${color.stop * 100}%`;
});
return `linear-gradient(${gradientDescription.angle}deg, ${stops.join(', ')})`;
};

const buildCssColor = (colorDescription) => {
const buildCssColor = (colorDescription: ColorDescription): string => {
if (colorDescription.type === 'linear-gradient') {
return buildCssGradient(colorDescription.value);
}
Expand Down Expand Up @@ -146,7 +147,7 @@ export const generateSkinCssSrc = (skinName, DESIGN_TOKENS_FOLDER) => {
)
.join('\n');

const textPresets = {
const textPresets: Record<string, TextPreset> = {
1: {
size: {mobile: 12, desktop: 14},
lineHeight: {mobile: 16, desktop: 20},
Expand Down Expand Up @@ -193,13 +194,15 @@ export const generateSkinCssSrc = (skinName, DESIGN_TOKENS_FOLDER) => {
},
};
Object.entries(designTokens.text).forEach(([textAttribute, textAttributeConfig]) => {
Object.entries(textAttributeConfig).forEach(([presetName, {value}]) => {
presetName = presetName.startsWith('text') ? presetName.replace('text', '') : presetName;
Object.entries(textAttributeConfig).forEach(([rawPresetName, {value}]) => {
const presetName = rawPresetName.startsWith('text')
? rawPresetName.replace('text', '')
: rawPresetName;

textPresets[presetName] = {
...(textPresets[presetName] ?? {}),
[textAttribute]: value,
};
} as TextPreset;
});
});

Expand Down Expand Up @@ -263,7 +266,7 @@ ${skinSelector}${colorSchemeSelector('dark')} {
${skinSelector} {
${darkModeColors}
}

${skinSelector}${colorSchemeSelector('light')} {
${forceLightModeColors}
}
Expand All @@ -278,9 +281,9 @@ ${desktopMediaQuery} {
`;
};

export const generateCommonCssSrc = (DESIGN_TOKENS_FOLDER) => {
export const generateCommonCssSrc = (DESIGN_TOKENS_FOLDER: string): string => {
const designTokensFile = fs.readFileSync(path.join(DESIGN_TOKENS_FOLDER, `movistar.json`), 'utf8');
const designTokens = JSON.parse(designTokensFile);
const designTokens: DesignTokens = JSON.parse(designTokensFile);

const textPresets = new Set([
'text1',
Expand Down
Loading
Loading