From b21bbf4a8741483f2f92de7419d4fe4f18dec9a0 Mon Sep 17 00:00:00 2001 From: Alexander Schwarzmann Date: Wed, 22 May 2024 13:45:32 +0200 Subject: [PATCH 1/4] chore(ui-kit): expose only design tokens in usage --- packages/ui-kit/package.json | 1 + .../ui-kit/scripts/parse-design-tokens.mts | 48 ++++++++++++++----- .../ui-kit/scripts/validate-design-tokens.mts | 5 ++ .../src/components/Button/Button.module.scss | 4 +- .../components/Counter/Counter.module.scss | 6 +-- .../ErrorFallback/ErrorFallback.module.scss | 5 +- .../src/components/Input/Input.module.scss | 8 ++-- .../Leaderboard/Leaderboard.module.scss | 9 ++-- .../src/components/Loader/Loader.module.scss | 5 +- .../components/PieChart/PieChart.module.scss | 7 +-- .../Select/Option/Option.module.scss | 2 +- .../src/components/Select/Select.module.scss | 6 +-- .../TimeRangePicker.module.scss | 8 ++-- .../Typography/Typography.module.scss | 10 ++-- packages/ui-kit/src/themes/_common.scss | 4 +- packages/ui-kit/src/themes/_darkTheme.scss | 4 +- packages/ui-kit/src/themes/_lightTheme.scss | 4 +- 17 files changed, 86 insertions(+), 50 deletions(-) diff --git a/packages/ui-kit/package.json b/packages/ui-kit/package.json index 568806c9..d7191b47 100644 --- a/packages/ui-kit/package.json +++ b/packages/ui-kit/package.json @@ -15,6 +15,7 @@ "design-tokens:sync": "yarn design-tokens:clean && tsc -p ./scripts/tsconfig.json && yarn design-tokens:parse && yarn design-tokens:validate", "design-tokens:clean": "rm -rf ./scripts/dist && rm -rf ./src/generated && rm -rf ./src/themes/generated", "design-tokens:parse": "node ./scripts/dist/parse-design-tokens.mjs", + "design-tokens:parse-in-use": "rm -rf ./scripts/dist && tsc -p ./scripts/tsconfig.json && node ./scripts/dist/parse-design-tokens.mjs --mode=in-use", "design-tokens:validate": "node ./scripts/dist/validate-design-tokens.mjs" }, "publishConfig": { diff --git a/packages/ui-kit/scripts/parse-design-tokens.mts b/packages/ui-kit/scripts/parse-design-tokens.mts index e2d96341..cf526192 100644 --- a/packages/ui-kit/scripts/parse-design-tokens.mts +++ b/packages/ui-kit/scripts/parse-design-tokens.mts @@ -2,6 +2,7 @@ import fs, { promises as fsPromises } from 'fs' import path from 'path' import slugify from 'slugify' import ora from 'ora' +// import { getCSSVariables } from './validate-design-tokens.mjs' const GENERATED_WARNING = 'This file is generated automatically by scripts/parse-design-tokens.js. Do not edit manually.' @@ -60,6 +61,14 @@ type TypographyClassProps = { props: { prop: string; value: string }[] } +export const getArgValue = (argName: string) => { + const index = process.argv.findIndex((arg) => arg.startsWith(`--${argName}=`)) + if (index === -1) { + return null + } + return process.argv[index].split('=')[1] +} + // Slugify string with strict mode export const slugifyStr = (str: string): string => slugify(str.replaceAll('/', '-'), { lower: true, strict: true }) @@ -157,7 +166,13 @@ export const getThemeTokens = ({ ) const main = async () => { - const spinner = ora({ text: 'Parsing design variables and tokens...', color: 'yellow' }).start() + const mode = getArgValue('mode') + const inInUseMode = mode === 'in-use' + + const spinner = ora({ + text: `Parsing design variables and tokens${inInUseMode ? ' (ONLY IN USE)' : ''}...`, + color: 'yellow' + }).start() try { const variablesJSON = await getJSONFromFile() @@ -167,8 +182,8 @@ const main = async () => { throw new Error('Failed to parse variables.json') } - const variables: TokenDataProps[] = [] - const tokens: TokenDataProps[] = [] + let variables: TokenDataProps[] = [] + let tokens: TokenDataProps[] = [] // Parse variables variablesJSON.collections @@ -239,6 +254,20 @@ const main = async () => { const themes = variablesJSON.collections.find(({ name }) => name === '1. Color Modes')?.modes + // if (inInUseMode) { + // const currentVariablesList = getCSSVariables('./src', 'current') + // console.log('========', currentVariablesList.length) + + // console.log('Before variables: ', variables.length) + // console.log('Before tokens: ', tokens.length) + + // variables = variables.filter((variable) => currentVariablesList.includes(variable.cssName)) + // tokens = tokens.filter((token) => currentVariablesList.includes(token.cssName)) + + // console.log('After variables: ', variables.length) + // console.log('After tokens: ', tokens.length) + // } + // Parse theme tokens const lightTheme = getThemeTokens({ name: 'light', themes, variables, tokens }) const darkTheme = getThemeTokens({ name: 'dark', themes, variables, tokens }) @@ -248,7 +277,7 @@ const main = async () => { '_variables.scss', [ `// ${GENERATED_WARNING}\n`, - '.variables {', + '%variables {', variables.map(({ cssName, value }) => ` ${cssName}: ${value};`).join('\n'), '}' ].join('\n') @@ -260,15 +289,14 @@ const main = async () => { [ `// ${GENERATED_WARNING}\n`, "@use './variables';\n", - '.tokens {', - ' @extend .variables;\n', + '%tokens {', + ' @extend %variables;\n', tokens.map(({ cssName, value }) => ` ${cssName}: ${value};`).join('\n'), '}\n', typographyClasses .map((typographyClass) => [ - `.${typographyClass.className} {`, - ' @extend .variables;\n', + `%${typographyClass.className} {`, typographyClass.props.map(({ prop, value }) => ` ${prop}: ${value};`).join('\n'), '}\n' ].join('\n') @@ -287,9 +315,7 @@ const main = async () => { `_${name}.scss`, [ `// ${GENERATED_WARNING}\n`, - "@use './tokens';\n", - `.${name} {`, - ' @extend .tokens;\n', + `%${name} {`, theme?.map(({ cssName, value }) => ` ${cssName}: ${value};`).join('\n'), '}' ].join('\n') diff --git a/packages/ui-kit/scripts/validate-design-tokens.mts b/packages/ui-kit/scripts/validate-design-tokens.mts index 6d2ebb40..31d02aeb 100644 --- a/packages/ui-kit/scripts/validate-design-tokens.mts +++ b/packages/ui-kit/scripts/validate-design-tokens.mts @@ -23,11 +23,13 @@ export const getAllFiles = ({ dirPath, type, arrayOfFiles = [] }: GetAllFilesPro if (fs.statSync(fullPath).isDirectory()) { const options: GetAllFilesProps = { dirPath: fullPath, type, arrayOfFiles } if (type === 'current' && file !== 'themes') { + // console.log(file) arrayOfFiles = getAllFiles(options) } else if (type === 'new' && file === 'generated') { arrayOfFiles = getAllFiles(options) } } else if (file.endsWith('.css') || (type === 'new' && file.endsWith('.scss'))) { + // console.log(fullPath, file.endsWith('.css'), type === 'new' && file.endsWith('.scss')) arrayOfFiles.push(fullPath) } }) @@ -45,6 +47,7 @@ export const extractCSSVariables = (file: string): string[] => { // Get a list of propel's CSS variables from all CSS files in the given directory export const getCSSVariables = (dirPath: string, type: 'current' | 'new'): string[] => { const files = getAllFiles({ dirPath, type }) + // console.log(files) const allVariables = new Set() files.forEach((file) => { @@ -75,6 +78,8 @@ export const validateDesignTokens = (spinner: Ora): void => { let validationFailed = false const currentVariablesList = getCSSVariables('./src', 'current') + spinner.succeed(`Tokens in use: ${currentVariablesList.length}`) + spinner.succeed(JSON.stringify(currentVariablesList, null, 2)) const newVariablesList = getCSSVariables('./src/themes', 'new') currentVariablesList.forEach((variable) => { diff --git a/packages/ui-kit/src/components/Button/Button.module.scss b/packages/ui-kit/src/components/Button/Button.module.scss index 2910e7e8..d20fd3d7 100644 --- a/packages/ui-kit/src/components/Button/Button.module.scss +++ b/packages/ui-kit/src/components/Button/Button.module.scss @@ -1,7 +1,7 @@ @use '../../themes/generated/tokens'; .rootButton { - @extend .textMdRegular; + @extend %textMdRegular; padding: var(--propel-spacing-lg) var(--propel-spacing-4xl); gap: var(--propel-spacing-lg); @@ -71,7 +71,7 @@ } &.small { - @extend .textSmSemibold; + @extend %textSmSemibold; padding: var(--propel-spacing-md) var(--propel-spacing-4xl); diff --git a/packages/ui-kit/src/components/Counter/Counter.module.scss b/packages/ui-kit/src/components/Counter/Counter.module.scss index aad5b6c5..13b17a0e 100644 --- a/packages/ui-kit/src/components/Counter/Counter.module.scss +++ b/packages/ui-kit/src/components/Counter/Counter.module.scss @@ -1,7 +1,7 @@ -@use '../../themes/common'; +@use '../../themes/generated/tokens'; .rootCounter { - @extend .displayLgBold; + @extend %displayLgBold; color: var(--propel-text-primary); white-space: nowrap; transition: opacity 0.2s ease-in-out; @@ -13,6 +13,6 @@ } .loader { - @extend .displayLgBold; + @extend %displayLgBold; color: var(--propel-text-secondary); } diff --git a/packages/ui-kit/src/components/ErrorFallback/ErrorFallback.module.scss b/packages/ui-kit/src/components/ErrorFallback/ErrorFallback.module.scss index c3787a22..6e8a9681 100644 --- a/packages/ui-kit/src/components/ErrorFallback/ErrorFallback.module.scss +++ b/packages/ui-kit/src/components/ErrorFallback/ErrorFallback.module.scss @@ -1,7 +1,8 @@ -@use '../../themes/common'; +// @use '../../themes/common'; +@use '../../themes/generated/tokens'; .rootErrorFallback { - @extend .textMdRegular; + @extend %textMdRegular; color: var(--propel-text-secondary); max-width: 263px; height: var(--propel-component-height); diff --git a/packages/ui-kit/src/components/Input/Input.module.scss b/packages/ui-kit/src/components/Input/Input.module.scss index 3068cff1..e57ffcff 100644 --- a/packages/ui-kit/src/components/Input/Input.module.scss +++ b/packages/ui-kit/src/components/Input/Input.module.scss @@ -1,7 +1,7 @@ @use '../../themes/generated/tokens'; .rootInput { - @extend .textMdRegular; + @extend %textMdRegular; padding: var(--propel-spacing-lg) var(--propel-spacing-xl); gap: var(--propel-spacing-lg); @@ -21,7 +21,7 @@ transition: border-color var(--propel-transition-ease-time) ease, box-shadow var(--propel-transition-ease-time) ease; & input { - @extend .textMdRegular; + @extend %textMdRegular; border: none; padding: 0; @@ -67,12 +67,12 @@ } .small { - @extend .textSmRegular; + @extend %textSmRegular; padding: var(--propel-spacing-md) var(--propel-spacing-lg); gap: var(--propel-spacing-md); & input { - @extend .textSmRegular; + @extend %textSmRegular; } } diff --git a/packages/ui-kit/src/components/Leaderboard/Leaderboard.module.scss b/packages/ui-kit/src/components/Leaderboard/Leaderboard.module.scss index c97b2256..16dad810 100644 --- a/packages/ui-kit/src/components/Leaderboard/Leaderboard.module.scss +++ b/packages/ui-kit/src/components/Leaderboard/Leaderboard.module.scss @@ -1,7 +1,8 @@ -@use '../../themes/common'; +// @use '../../themes/common'; +@use '../../themes/generated/tokens'; .rootLeaderboard { - @extend .textXxsRegular; + @extend %textXxsRegular; color: var(--propel-text-secondary); overflow: auto; padding: 0; @@ -68,11 +69,11 @@ text-align: left; padding: var(--propel-spacing-md) var(--propel-spacing-md) var(--propel-spacing-md) 0; color: var(--propel-text-secondary); - @extend .textXsRegular; + @extend %textXsRegular; } td { - @extend .textXsRegular; + @extend %textXsRegular; color: var(--propel-text-secondary); border-bottom: 1px solid var(--propel-border-primary); } diff --git a/packages/ui-kit/src/components/Loader/Loader.module.scss b/packages/ui-kit/src/components/Loader/Loader.module.scss index fceacf32..bdd27256 100644 --- a/packages/ui-kit/src/components/Loader/Loader.module.scss +++ b/packages/ui-kit/src/components/Loader/Loader.module.scss @@ -1,7 +1,8 @@ -@use '../../themes/common'; +// @use '../../themes/common'; +@use '../../themes/generated/tokens'; .rootLoader { - @extend .textMdRegular; + @extend %textMdRegular; color: var(--propel-text-secondary); overflow: auto; width: 100%; diff --git a/packages/ui-kit/src/components/PieChart/PieChart.module.scss b/packages/ui-kit/src/components/PieChart/PieChart.module.scss index 76e462f1..ad76be16 100644 --- a/packages/ui-kit/src/components/PieChart/PieChart.module.scss +++ b/packages/ui-kit/src/components/PieChart/PieChart.module.scss @@ -1,7 +1,8 @@ -@use '../../themes/common'; +// @use '../../themes/common'; +@use '../../themes/generated/tokens'; .rootPieChart { - @extend .textXxsRegular; + @extend %textXxsRegular; color: var(--propel-text-primary); overflow: auto; padding: 0; @@ -35,7 +36,7 @@ } .pieChartList { - @extend .textXsRegular; + @extend %textXsRegular; color: var(--propel-text-secondary); margin-top: var(--propel-spacing-xl); diff --git a/packages/ui-kit/src/components/Select/Option/Option.module.scss b/packages/ui-kit/src/components/Select/Option/Option.module.scss index fcbf2921..14ceb179 100644 --- a/packages/ui-kit/src/components/Select/Option/Option.module.scss +++ b/packages/ui-kit/src/components/Select/Option/Option.module.scss @@ -1,7 +1,7 @@ @use '../../../themes/generated/tokens'; .rootOption { - @extend .textMdRegular; + @extend %textMdRegular; padding: var(--propel-spacing-xl) var(--propel-spacing-4xl); margin: 0; diff --git a/packages/ui-kit/src/components/Select/Select.module.scss b/packages/ui-kit/src/components/Select/Select.module.scss index a8c7db80..5441fc63 100644 --- a/packages/ui-kit/src/components/Select/Select.module.scss +++ b/packages/ui-kit/src/components/Select/Select.module.scss @@ -1,10 +1,10 @@ @use '../../themes/generated/tokens'; .rootButton { - @extend .textMdRegular; + @extend %textMdRegular; &.small { - @extend .textSmRegular; + @extend %textSmRegular; } } @@ -35,7 +35,7 @@ .small { ul { li { - @extend .textSmRegular; + @extend %textSmRegular; padding: var(--propel-spacing-md) var(--propel-spacing-xl); gap: var(--propel-spacing-xxs); diff --git a/packages/ui-kit/src/components/TimeRangePicker/TimeRangePicker.module.scss b/packages/ui-kit/src/components/TimeRangePicker/TimeRangePicker.module.scss index eca78df5..30ab4155 100644 --- a/packages/ui-kit/src/components/TimeRangePicker/TimeRangePicker.module.scss +++ b/packages/ui-kit/src/components/TimeRangePicker/TimeRangePicker.module.scss @@ -79,7 +79,7 @@ } .caption_label { - @extend .textSmRegular; + @extend %textSmRegular; position: absolute; left: 0; @@ -92,11 +92,11 @@ } .head_cell { - @extend .textSmRegular; + @extend %textSmRegular; } .cell { - @extend .textSmRegular; + @extend %textSmRegular; } .nav { @@ -118,7 +118,7 @@ } .button { - @extend .textSmRegular; + @extend %textSmRegular; padding: 10px var(--propel-spacing-md); border-width: 1px; diff --git a/packages/ui-kit/src/components/Typography/Typography.module.scss b/packages/ui-kit/src/components/Typography/Typography.module.scss index fb5ca21b..15de2d5a 100644 --- a/packages/ui-kit/src/components/Typography/Typography.module.scss +++ b/packages/ui-kit/src/components/Typography/Typography.module.scss @@ -7,23 +7,23 @@ // Add new variant when needed. Check themes/generated/_tokens.scss for available variants. .textMdRegular { - @extend .textMdRegular; + @extend %textMdRegular; } .textMdSemibold { - @extend .textMdSemibold; + @extend %textMdSemibold; } .textXsRegular { - @extend .textXsRegular; + @extend %textXsRegular; } .textXxsRegular { - @extend .textXxsRegular; + @extend %textXxsRegular; } .textSmRegular { - @extend .textSmRegular; + @extend %textSmRegular; } .block { diff --git a/packages/ui-kit/src/themes/_common.scss b/packages/ui-kit/src/themes/_common.scss index 45914cc9..6eaa805a 100644 --- a/packages/ui-kit/src/themes/_common.scss +++ b/packages/ui-kit/src/themes/_common.scss @@ -1,6 +1,6 @@ @use './generated/tokens'; -.commonTokens { +%commonTokens { --propel-component-height: 300px; --propel-transition-ease-time: 300ms; @@ -64,5 +64,5 @@ --propel-color-blue50: #eff8ff; --propel-color-blue25: #f5faff; - @extend .tokens; + @extend %tokens; } diff --git a/packages/ui-kit/src/themes/_darkTheme.scss b/packages/ui-kit/src/themes/_darkTheme.scss index a6c2c8ef..06ba9ed1 100644 --- a/packages/ui-kit/src/themes/_darkTheme.scss +++ b/packages/ui-kit/src/themes/_darkTheme.scss @@ -5,7 +5,7 @@ @use './generated/darkTheme'; .darkTheme { - @extend .commonTokens; + @extend %commonTokens; --propel-color-primary: #2e90fa; --propel-color-secondary: rgba(46, 144, 250, 0.35); @@ -18,5 +18,5 @@ --propel-color-loader: #2d2d2d; --propel-color-loader-animation: #00000020; - @extend .darkTheme; + @extend %darkTheme; } diff --git a/packages/ui-kit/src/themes/_lightTheme.scss b/packages/ui-kit/src/themes/_lightTheme.scss index fbda3983..05c004be 100644 --- a/packages/ui-kit/src/themes/_lightTheme.scss +++ b/packages/ui-kit/src/themes/_lightTheme.scss @@ -5,7 +5,7 @@ @use './generated/lightTheme'; .lightTheme { - @extend .commonTokens; + @extend %commonTokens; --propel-color-primary: #2e90fa; --propel-color-secondary: #cdd5df; @@ -18,5 +18,5 @@ --propel-color-loader: #e9e9e9; --propel-color-loader-animation: #ffffff20; - @extend .lightTheme; + @extend %lightTheme; } From 16e0de533a1fc678de423550368a7efc8697cd32 Mon Sep 17 00:00:00 2001 From: Alexander Schwarzmann Date: Wed, 22 May 2024 16:19:24 +0200 Subject: [PATCH 2/4] chore(ui-kit): updates --- .../documentation/ui-kit/Theming.mdx | 25 ++------ packages/ui-kit/package.json | 5 +- .../parse.mts} | 63 +++++++------------ .../shared.mts} | 60 +++++------------- .../ui-kit/scripts/design-tokens/validate.mts | 40 ++++++++++++ packages/ui-kit/scripts/tsconfig.json | 1 + packages/ui-kit/src/themes/_darkTheme.scss | 1 - packages/ui-kit/src/themes/_lightTheme.scss | 1 - packages/ui-kit/src/themes/themes.module.scss | 2 - 9 files changed, 87 insertions(+), 111 deletions(-) rename packages/ui-kit/scripts/{parse-design-tokens.mts => design-tokens/parse.mts} (84%) rename packages/ui-kit/scripts/{validate-design-tokens.mts => design-tokens/shared.mts} (62%) create mode 100644 packages/ui-kit/scripts/design-tokens/validate.mts diff --git a/app/storybook/documentation/ui-kit/Theming.mdx b/app/storybook/documentation/ui-kit/Theming.mdx index eb3b2a5f..3798aad3 100644 --- a/app/storybook/documentation/ui-kit/Theming.mdx +++ b/app/storybook/documentation/ui-kit/Theming.mdx @@ -3,10 +3,7 @@ import LinkTo from '@storybook/addon-links/react' import { prettier } from '../../src/utils' import { SourceCode } from '../../.storybook/blocks/SourceCode' import * as ThemeProviderStories from '../../../../packages/ui-kit/src/components/ThemeProvider/ThemeProvider.stories' -import rawThemesScss from '!!raw-loader!../../../../packages/ui-kit/src/themes/themes.module.scss' -import rawCommonScss from '!!raw-loader!../../../../packages/ui-kit/src/themes/generated/_tokens.scss' -import rawLightThemeScss from '!!raw-loader!../../../../packages/ui-kit/src/themes/generated/_lightTheme.scss' -import rawDarkThemeScss from '!!raw-loader!../../../../packages/ui-kit/src/themes/generated/_darkTheme.scss' +import rawThemesScss from '!!raw-loader!../../../../packages/ui-kit/src/generated/themes/themes.module.css' @@ -41,25 +38,13 @@ Further details are available in the -The `common.scss` file contains the **common** theme configuration, defining a series of CSS custom properties that are -shared by both the light and dark themes. - - - -The `lightTheme.scss` file sets up the **light theme** for the UI Kit, defining a series of CSS custom properties -specific to this theme. - - - -The `darkTheme.scss` file sets up the **dark theme** for the UI Kit, defining a series of CSS custom properties specific -to this theme. - - - ### Customizing the Theme The `ThemeProvider` component allows theme customization through its `theme` prop. diff --git a/packages/ui-kit/package.json b/packages/ui-kit/package.json index d7191b47..8fb28336 100644 --- a/packages/ui-kit/package.json +++ b/packages/ui-kit/package.json @@ -14,9 +14,8 @@ "test:coverage": "jest --ci --coverage --json --outputFile=coverage/coverage.json", "design-tokens:sync": "yarn design-tokens:clean && tsc -p ./scripts/tsconfig.json && yarn design-tokens:parse && yarn design-tokens:validate", "design-tokens:clean": "rm -rf ./scripts/dist && rm -rf ./src/generated && rm -rf ./src/themes/generated", - "design-tokens:parse": "node ./scripts/dist/parse-design-tokens.mjs", - "design-tokens:parse-in-use": "rm -rf ./scripts/dist && tsc -p ./scripts/tsconfig.json && node ./scripts/dist/parse-design-tokens.mjs --mode=in-use", - "design-tokens:validate": "node ./scripts/dist/validate-design-tokens.mjs" + "design-tokens:parse": "node ./scripts/dist/design-tokens/parse.mjs", + "design-tokens:validate": "node ./scripts/dist/design-tokens/validate.mjs" }, "publishConfig": { "access": "public", diff --git a/packages/ui-kit/scripts/parse-design-tokens.mts b/packages/ui-kit/scripts/design-tokens/parse.mts similarity index 84% rename from packages/ui-kit/scripts/parse-design-tokens.mts rename to packages/ui-kit/scripts/design-tokens/parse.mts index cf526192..5000ddb8 100644 --- a/packages/ui-kit/scripts/parse-design-tokens.mts +++ b/packages/ui-kit/scripts/design-tokens/parse.mts @@ -1,8 +1,9 @@ import fs, { promises as fsPromises } from 'fs' -import path from 'path' -import slugify from 'slugify' import ora from 'ora' -// import { getCSSVariables } from './validate-design-tokens.mjs' +import path from 'path' +import { buildSASSFiles, camelCaseToKebabCase, getCSSVariables, kebabCaseToCamelCase, slugifyStr } from './shared.mjs' + +const env = process.env.NODE_ENV || 'development' const GENERATED_WARNING = 'This file is generated automatically by scripts/parse-design-tokens.js. Do not edit manually.' @@ -61,28 +62,6 @@ type TypographyClassProps = { props: { prop: string; value: string }[] } -export const getArgValue = (argName: string) => { - const index = process.argv.findIndex((arg) => arg.startsWith(`--${argName}=`)) - if (index === -1) { - return null - } - return process.argv[index].split('=')[1] -} - -// Slugify string with strict mode -export const slugifyStr = (str: string): string => slugify(str.replaceAll('/', '-'), { lower: true, strict: true }) - -// Convert kebab-case to camelCase -export const kebabCaseToCamelCase = (kebabStr: string): string => - kebabStr - .split('-') - .map((word, index) => (index === 0 ? word : word[0].toUpperCase() + word.slice(1))) - .join('') - -// Convert camelCase to kebab-case -export const camelCaseToKebabCase = (camelStr: string): string => - camelStr.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase() - // Parse Figma variable value export const parseValue = (variable: VariableProps): string => { const { type, value } = variable @@ -165,12 +144,11 @@ export const getThemeTokens = ({ ) ) -const main = async () => { - const mode = getArgValue('mode') - const inInUseMode = mode === 'in-use' +const main = async (isProdEnv = false) => { + let succeedMessage = 'Parse design variables and tokens' const spinner = ora({ - text: `Parsing design variables and tokens${inInUseMode ? ' (ONLY IN USE)' : ''}...`, + text: `Parsing design variables and tokens...`, color: 'yellow' }).start() @@ -254,19 +232,20 @@ const main = async () => { const themes = variablesJSON.collections.find(({ name }) => name === '1. Color Modes')?.modes - // if (inInUseMode) { - // const currentVariablesList = getCSSVariables('./src', 'current') - // console.log('========', currentVariablesList.length) + if (isProdEnv) { + await buildSASSFiles(spinner) - // console.log('Before variables: ', variables.length) - // console.log('Before tokens: ', tokens.length) + const currentVariablesList = getCSSVariables('./src', 'current') + const statsBefore = { + variables: variables.length, + tokens: tokens.length + } - // variables = variables.filter((variable) => currentVariablesList.includes(variable.cssName)) - // tokens = tokens.filter((token) => currentVariablesList.includes(token.cssName)) + variables = variables.filter((variable) => currentVariablesList.includes(variable.cssName)) + tokens = tokens.filter((token) => currentVariablesList.includes(token.cssName)) - // console.log('After variables: ', variables.length) - // console.log('After tokens: ', tokens.length) - // } + succeedMessage = `Filter out all design variables (${variables.length} from ${statsBefore.variables}) and tokens (${tokens.length} from ${statsBefore.tokens}) not in use` + } // Parse theme tokens const lightTheme = getThemeTokens({ name: 'light', themes, variables, tokens }) @@ -364,7 +343,7 @@ const main = async () => { ].join('\n') ) - spinner.succeed('Parse design variables and tokens') + spinner.succeed(succeedMessage) } catch (err) { console.error(err) spinner.fail('Failed to parse design variables and tokens') @@ -372,3 +351,7 @@ const main = async () => { } main() + +if (env === 'production') { + main(true) +} diff --git a/packages/ui-kit/scripts/validate-design-tokens.mts b/packages/ui-kit/scripts/design-tokens/shared.mts similarity index 62% rename from packages/ui-kit/scripts/validate-design-tokens.mts rename to packages/ui-kit/scripts/design-tokens/shared.mts index 31d02aeb..9739319e 100644 --- a/packages/ui-kit/scripts/validate-design-tokens.mts +++ b/packages/ui-kit/scripts/design-tokens/shared.mts @@ -1,10 +1,23 @@ +import { exec } from 'child_process' import fs from 'fs' +import { Ora } from 'ora' import path from 'path' -import ora, { Ora } from 'ora' -import { exec } from 'child_process' +import slugify from 'slugify' import { promisify } from 'util' -const FAILED_MESSAGE = 'Design tokens validation failed' +// Slugify string with strict mode +export const slugifyStr = (str: string): string => slugify(str.replaceAll('/', '-'), { lower: true, strict: true }) + +// Convert kebab-case to camelCase +export const kebabCaseToCamelCase = (kebabStr: string): string => + kebabStr + .split('-') + .map((word, index) => (index === 0 ? word : word[0].toUpperCase() + word.slice(1))) + .join('') + +// Convert camelCase to kebab-case +export const camelCaseToKebabCase = (camelStr: string): string => + camelStr.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase() const execAsync = promisify(exec) @@ -23,13 +36,11 @@ export const getAllFiles = ({ dirPath, type, arrayOfFiles = [] }: GetAllFilesPro if (fs.statSync(fullPath).isDirectory()) { const options: GetAllFilesProps = { dirPath: fullPath, type, arrayOfFiles } if (type === 'current' && file !== 'themes') { - // console.log(file) arrayOfFiles = getAllFiles(options) } else if (type === 'new' && file === 'generated') { arrayOfFiles = getAllFiles(options) } } else if (file.endsWith('.css') || (type === 'new' && file.endsWith('.scss'))) { - // console.log(fullPath, file.endsWith('.css'), type === 'new' && file.endsWith('.scss')) arrayOfFiles.push(fullPath) } }) @@ -47,7 +58,6 @@ export const extractCSSVariables = (file: string): string[] => { // Get a list of propel's CSS variables from all CSS files in the given directory export const getCSSVariables = (dirPath: string, type: 'current' | 'new'): string[] => { const files = getAllFiles({ dirPath, type }) - // console.log(files) const allVariables = new Set() files.forEach((file) => { @@ -71,41 +81,3 @@ export const buildSASSFiles = async (spinner: Ora): Promise => { throw error } } - -// Compare current and new CSS variables, and log any missing variables -export const validateDesignTokens = (spinner: Ora): void => { - spinner.start('Validating design tokens...') - let validationFailed = false - - const currentVariablesList = getCSSVariables('./src', 'current') - spinner.succeed(`Tokens in use: ${currentVariablesList.length}`) - spinner.succeed(JSON.stringify(currentVariablesList, null, 2)) - const newVariablesList = getCSSVariables('./src/themes', 'new') - - currentVariablesList.forEach((variable) => { - if (!newVariablesList.includes(variable)) { - spinner.warn(`Design token '${variable}' is not defined`) - validationFailed = true - } - }) - - if (validationFailed) { - throw new Error(FAILED_MESSAGE) - } - - spinner.succeed('Validate design tokens') -} - -async function main() { - const spinner = ora({ text: 'Building SASS files...', color: 'yellow' }).start() - - try { - await buildSASSFiles(spinner) - validateDesignTokens(spinner) - } catch (error) { - spinner.fail(FAILED_MESSAGE) - console.error(error) - } -} - -main() diff --git a/packages/ui-kit/scripts/design-tokens/validate.mts b/packages/ui-kit/scripts/design-tokens/validate.mts new file mode 100644 index 00000000..cf5b0464 --- /dev/null +++ b/packages/ui-kit/scripts/design-tokens/validate.mts @@ -0,0 +1,40 @@ +import ora, { Ora } from 'ora' +import { getCSSVariables, buildSASSFiles } from './shared.mjs' + +const FAILED_MESSAGE = 'Design tokens validation failed' + +// Compare current and new CSS variables, and log any missing variables +export const validateDesignTokens = (spinner: Ora): void => { + spinner.start('Validating design tokens...') + let validationFailed = false + + const currentVariablesList = getCSSVariables('./src', 'current') + const newVariablesList = getCSSVariables('./src/themes', 'new') + + currentVariablesList.forEach((variable) => { + if (!newVariablesList.includes(variable)) { + spinner.warn(`Design token '${variable}' is not defined`) + validationFailed = true + } + }) + + if (validationFailed) { + throw new Error(FAILED_MESSAGE) + } + + spinner.succeed('Validate design tokens') +} + +async function main() { + const spinner = ora({ text: 'Building SASS files...', color: 'yellow' }).start() + + try { + await buildSASSFiles(spinner) + validateDesignTokens(spinner) + } catch (error) { + spinner.fail(FAILED_MESSAGE) + console.error(error) + } +} + +main() diff --git a/packages/ui-kit/scripts/tsconfig.json b/packages/ui-kit/scripts/tsconfig.json index 22405983..96c6d49b 100644 --- a/packages/ui-kit/scripts/tsconfig.json +++ b/packages/ui-kit/scripts/tsconfig.json @@ -5,6 +5,7 @@ "target": "ESNext", "strict": true, "outDir": "dist", + "rootDir": ".", "lib": ["ESNext", "DOM"] }, "include": ["./**/*.mts"], diff --git a/packages/ui-kit/src/themes/_darkTheme.scss b/packages/ui-kit/src/themes/_darkTheme.scss index 06ba9ed1..a0c9ab4a 100644 --- a/packages/ui-kit/src/themes/_darkTheme.scss +++ b/packages/ui-kit/src/themes/_darkTheme.scss @@ -1,4 +1,3 @@ -/** darkTheme.scss */ // @deprecated - all tokens in this file are deprecated in favor of the generated tokens and should be removed in the future @use './common'; diff --git a/packages/ui-kit/src/themes/_lightTheme.scss b/packages/ui-kit/src/themes/_lightTheme.scss index 05c004be..36b9763e 100644 --- a/packages/ui-kit/src/themes/_lightTheme.scss +++ b/packages/ui-kit/src/themes/_lightTheme.scss @@ -1,4 +1,3 @@ -/** lightTheme.scss */ // @deprecated - all tokens in this file are deprecated in favor of the generated tokens and should be removed in the future @use './common'; diff --git a/packages/ui-kit/src/themes/themes.module.scss b/packages/ui-kit/src/themes/themes.module.scss index 8a2f86a3..2d510d80 100644 --- a/packages/ui-kit/src/themes/themes.module.scss +++ b/packages/ui-kit/src/themes/themes.module.scss @@ -1,4 +1,2 @@ -/** themes.module.scss */ - @use './lightTheme'; @use './darkTheme'; From e721c35aff4906d323b2d1a6dce2640742c994d9 Mon Sep 17 00:00:00 2001 From: Alexander Schwarzmann Date: Wed, 22 May 2024 16:20:41 +0200 Subject: [PATCH 3/4] chore(cicd): add changeset --- .changeset/light-pandas-perform.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/light-pandas-perform.md diff --git a/.changeset/light-pandas-perform.md b/.changeset/light-pandas-perform.md new file mode 100644 index 00000000..8571efc9 --- /dev/null +++ b/.changeset/light-pandas-perform.md @@ -0,0 +1,5 @@ +--- +'@propeldata/ui-kit': minor +--- + +Filter out all design variables and tokens not in use From 5a9fa59f159bc6f7aed7d9c72c5c358594b3ef9d Mon Sep 17 00:00:00 2001 From: Alexander Schwarzmann Date: Thu, 23 May 2024 11:21:10 +0200 Subject: [PATCH 4/4] chore(ui-kit): fixes for design token parser filter --- packages/ui-kit/scripts/design-tokens/parse.mts | 10 ++++++---- .../src/components/PieChart/PieChart.module.scss | 12 ++++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/packages/ui-kit/scripts/design-tokens/parse.mts b/packages/ui-kit/scripts/design-tokens/parse.mts index 5000ddb8..95396878 100644 --- a/packages/ui-kit/scripts/design-tokens/parse.mts +++ b/packages/ui-kit/scripts/design-tokens/parse.mts @@ -232,6 +232,10 @@ const main = async (isProdEnv = false) => { const themes = variablesJSON.collections.find(({ name }) => name === '1. Color Modes')?.modes + // Parse theme tokens + let lightTheme = getThemeTokens({ name: 'light', themes, variables, tokens }) + let darkTheme = getThemeTokens({ name: 'dark', themes, variables, tokens }) + if (isProdEnv) { await buildSASSFiles(spinner) @@ -243,14 +247,12 @@ const main = async (isProdEnv = false) => { variables = variables.filter((variable) => currentVariablesList.includes(variable.cssName)) tokens = tokens.filter((token) => currentVariablesList.includes(token.cssName)) + lightTheme = lightTheme?.filter((token) => currentVariablesList.includes(token.cssName)) + darkTheme = darkTheme?.filter((token) => currentVariablesList.includes(token.cssName)) succeedMessage = `Filter out all design variables (${variables.length} from ${statsBefore.variables}) and tokens (${tokens.length} from ${statsBefore.tokens}) not in use` } - // Parse theme tokens - const lightTheme = getThemeTokens({ name: 'light', themes, variables, tokens }) - const darkTheme = getThemeTokens({ name: 'dark', themes, variables, tokens }) - // Generate _variables.scss writeToFileSync( '_variables.scss', diff --git a/packages/ui-kit/src/components/PieChart/PieChart.module.scss b/packages/ui-kit/src/components/PieChart/PieChart.module.scss index ad76be16..c0ca5954 100644 --- a/packages/ui-kit/src/components/PieChart/PieChart.module.scss +++ b/packages/ui-kit/src/components/PieChart/PieChart.module.scss @@ -7,6 +7,18 @@ overflow: auto; padding: 0; + --pie-bg-25: var(--propel-brand-25); + --pie-bg-50: var(--propel-brand-50); + --pie-bg-100: var(--propel-brand-100); + --pie-bg-200: var(--propel-brand-200); + --pie-bg-300: var(--propel-brand-300); + --pie-bg-400: var(--propel-brand-400); + --pie-bg-500: var(--propel-brand-500); + --pie-bg-600: var(--propel-brand-600); + --pie-bg-700: var(--propel-brand-700); + --pie-bg-900: var(--propel-brand-900); + --pie-bg-empty: var(--propel-background-brand-primary); + canvas { height: var(--propel-component-height); }