mirror of https://github.com/openedx/paragon.git
feat: Better support for multiple themes (#2792)
* feat: Better support for multiple themes This change adds support for two CLI options to the build-tokens command. The first, --all-themes makes the build-tokens command process all themes in the source directory as opposed to specifying all the names via --theme. Secondly, --base-paragon-theme allows you to have multiple themes derived from the same common base. If specified, you can have a derived theme that still loads tokens from the light theme. For example, you can have a site theme called 'theme-one' and set the base theme to light so it will reuse the core light theme tokens and layer on changes from 'theme-one'. * fixup! feat: Better support for multiple themes * fixup! fixup! feat: Better support for multiple themes
This commit is contained in:
parent
04e52615ba
commit
b46e241866
|
|
@ -94,7 +94,8 @@ const COMMANDS = {
|
|||
{
|
||||
name: '-t, --themes',
|
||||
description: `Specify themes to include in the token build.
|
||||
Can be provided as a comma-separated list (e.g., "light,dark") or multiple arguments (e.g., "-t light -t dark").`,
|
||||
Can be provided as a comma-separated list (e.g., "light,dark") or multiple arguments (e.g., "-t light -t dark").
|
||||
Cannot be used with --all-themes`,
|
||||
defaultValue: 'light',
|
||||
},
|
||||
{
|
||||
|
|
@ -107,6 +108,16 @@ const COMMANDS = {
|
|||
description: 'Enable verbose logging.',
|
||||
defaultValue: false,
|
||||
},
|
||||
{
|
||||
name: '--base-paragon-theme',
|
||||
description: 'Specify the base theme to use in the token build. For example, to build the "high-contrast" theme on top of the light theme use "--theme high-contrast --base-paragon-theme light".',
|
||||
defaultValue: 'Same as theme',
|
||||
},
|
||||
{
|
||||
name: '--all-themes',
|
||||
description: 'Build tokens for all themes in the source directory. Cannot be used with --themes.',
|
||||
defaultValue: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
'replace-variables': {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const minimist = require('minimist');
|
||||
const {
|
||||
|
|
@ -13,17 +14,22 @@ const { createIndexCssFile } = require('../tokens/utils');
|
|||
* @param {string[]} commandArgs - Command line arguments for building tokens.
|
||||
* @param {string} [commandArgs.build-dir='./build/'] - The directory where the build output will be placed.
|
||||
* @param {string} [commandArgs.source] - The source directory containing JSON token files.
|
||||
* @param {string} [commandArgs.base-paragon-theme] - The base theme to use from Paragon if named differently than
|
||||
* the theme.
|
||||
* @param {boolean} [commandArgs.source-tokens-only=false] - Indicates whether to include only source tokens.
|
||||
* @param {string|string[]} [commandArgs.themes=['light']] - The themes (variants) for which to build tokens.
|
||||
* @param {boolean} [commandArgs.all-themes] - Indicated whether to process all themes.
|
||||
*/
|
||||
async function buildTokensCommand(commandArgs) {
|
||||
const defaultParams = {
|
||||
themes: ['light'],
|
||||
themes: null,
|
||||
'base-paragon-theme': null,
|
||||
'build-dir': './build/',
|
||||
'source-tokens-only': false,
|
||||
'output-references': true,
|
||||
'exclude-core': false,
|
||||
verbose: false,
|
||||
'all-themes': false,
|
||||
};
|
||||
|
||||
const alias = {
|
||||
|
|
@ -39,19 +45,36 @@ async function buildTokensCommand(commandArgs) {
|
|||
'output-references': outputReferences,
|
||||
themes,
|
||||
verbose,
|
||||
'base-paragon-theme': baseParagonTheme,
|
||||
'all-themes': allThemes,
|
||||
'exclude-core': excludeCore,
|
||||
} = minimist(
|
||||
commandArgs,
|
||||
{
|
||||
alias,
|
||||
default: defaultParams,
|
||||
boolean: ['source-tokens-only', 'output-references', 'exclude-core', 'verbose'],
|
||||
boolean: ['source-tokens-only', 'output-references', 'exclude-core', 'verbose', 'all-themes'],
|
||||
},
|
||||
);
|
||||
|
||||
const parsedThemes = Array.isArray(themes) ? themes : themes.split(',').map(t => t.trim());
|
||||
if (themes !== null && allThemes) {
|
||||
throw Error('Cannot specify themes with `--themes` when using `--all-themes`.');
|
||||
}
|
||||
let themesToProcess = null;
|
||||
|
||||
const StyleDictionary = await initializeStyleDictionary({ themes: parsedThemes });
|
||||
if (allThemes) {
|
||||
const tokensPath = tokensSource || path.resolve(__dirname, '../tokens/src');
|
||||
themesToProcess = fs
|
||||
.readdirSync(`${tokensPath}/themes/`, { withFileTypes: true })
|
||||
.filter(entry => entry.isDirectory())
|
||||
.map(entry => entry.name);
|
||||
} else if (Array.isArray(themes)) {
|
||||
themesToProcess = themes;
|
||||
} else {
|
||||
themesToProcess = (themes || 'light').split(',').map(t => t.trim());
|
||||
}
|
||||
|
||||
const StyleDictionary = await initializeStyleDictionary({ themes: themesToProcess });
|
||||
|
||||
const coreConfig = {
|
||||
include: [
|
||||
|
|
@ -100,12 +123,12 @@ async function buildTokensCommand(commandArgs) {
|
|||
},
|
||||
};
|
||||
|
||||
const getStyleDictionaryConfig = (themeVariant) => ({
|
||||
const getStyleDictionaryConfig = (themeVariant, baseThemeVariant) => ({
|
||||
...coreConfig,
|
||||
include: [
|
||||
...coreConfig.include,
|
||||
path.resolve(__dirname, `../tokens/src/themes/${themeVariant}/**/*.json`),
|
||||
path.resolve(__dirname, `../tokens/src/themes/${themeVariant}/**/*.toml`),
|
||||
path.resolve(__dirname, `../tokens/src/themes/${baseThemeVariant}/**/*.json`),
|
||||
path.resolve(__dirname, `../tokens/src/themes/${baseThemeVariant}/**/*.toml`),
|
||||
],
|
||||
source: tokensSource
|
||||
? [
|
||||
|
|
@ -159,10 +182,10 @@ async function buildTokensCommand(commandArgs) {
|
|||
}
|
||||
|
||||
// Add theme variants
|
||||
for (const themeVariant of parsedThemes) {
|
||||
const config = getStyleDictionaryConfig(themeVariant);
|
||||
themesToProcess.forEach(themeVariant => {
|
||||
const config = getStyleDictionaryConfig(themeVariant, baseParagonTheme || themeVariant);
|
||||
configs.push({ config, themeVariant });
|
||||
}
|
||||
});
|
||||
|
||||
// Build tokens for each configuration
|
||||
await Promise.all(configs.map(async ({ config, themeVariant }) => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue