@openedx/paragon 23.15.1 → 23.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -94,7 +94,8 @@ const COMMANDS = {
94
94
  {
95
95
  name: '-t, --themes',
96
96
  description: `Specify themes to include in the token build.
97
- Can be provided as a comma-separated list (e.g., "light,dark") or multiple arguments (e.g., "-t light -t dark").`,
97
+ Can be provided as a comma-separated list (e.g., "light,dark") or multiple arguments (e.g., "-t light -t dark").
98
+ Cannot be used with --all-themes`,
98
99
  defaultValue: 'light',
99
100
  },
100
101
  {
@@ -107,6 +108,16 @@ const COMMANDS = {
107
108
  description: 'Enable verbose logging.',
108
109
  defaultValue: false,
109
110
  },
111
+ {
112
+ name: '--base-paragon-theme',
113
+ 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".',
114
+ defaultValue: 'Same as theme',
115
+ },
116
+ {
117
+ name: '--all-themes',
118
+ description: 'Build tokens for all themes in the source directory. Cannot be used with --themes.',
119
+ defaultValue: false,
120
+ },
110
121
  ],
111
122
  },
112
123
  'replace-variables': {
@@ -267,6 +278,10 @@ const COMMANDS = {
267
278
  } catch (error) {
268
279
  // eslint-disable-next-line no-console
269
280
  console.error(chalk.red.bold('An error occurred:', error));
281
+ if (error instanceof Error) {
282
+ // eslint-disable-next-line no-console
283
+ console.error(chalk.red(error.stack));
284
+ }
270
285
  sendTrackInfo('openedx.paragon.cli-command.used', { command, status: 'error', errorMsg: error.message });
271
286
  process.exit(1);
272
287
  }
@@ -1,3 +1,4 @@
1
+ const fs = require('fs');
1
2
  const path = require('path');
2
3
  const minimist = require('minimist');
3
4
  const {
@@ -13,17 +14,22 @@ const { createIndexCssFile } = require('../tokens/utils');
13
14
  * @param {string[]} commandArgs - Command line arguments for building tokens.
14
15
  * @param {string} [commandArgs.build-dir='./build/'] - The directory where the build output will be placed.
15
16
  * @param {string} [commandArgs.source] - The source directory containing JSON token files.
17
+ * @param {string} [commandArgs.base-paragon-theme] - The base theme to use from Paragon if named differently than
18
+ * the theme.
16
19
  * @param {boolean} [commandArgs.source-tokens-only=false] - Indicates whether to include only source tokens.
17
20
  * @param {string|string[]} [commandArgs.themes=['light']] - The themes (variants) for which to build tokens.
21
+ * @param {boolean} [commandArgs.all-themes] - Indicated whether to process all themes.
18
22
  */
19
23
  async function buildTokensCommand(commandArgs) {
20
24
  const defaultParams = {
21
- themes: ['light'],
25
+ themes: null,
26
+ 'base-paragon-theme': null,
22
27
  'build-dir': './build/',
23
28
  'source-tokens-only': false,
24
29
  'output-references': true,
25
30
  'exclude-core': false,
26
31
  verbose: false,
32
+ 'all-themes': false,
27
33
  };
28
34
 
29
35
  const alias = {
@@ -39,19 +45,36 @@ async function buildTokensCommand(commandArgs) {
39
45
  'output-references': outputReferences,
40
46
  themes,
41
47
  verbose,
48
+ 'base-paragon-theme': baseParagonTheme,
49
+ 'all-themes': allThemes,
42
50
  'exclude-core': excludeCore,
43
51
  } = minimist(
44
52
  commandArgs,
45
53
  {
46
54
  alias,
47
55
  default: defaultParams,
48
- boolean: ['source-tokens-only', 'output-references', 'exclude-core', 'verbose'],
56
+ boolean: ['source-tokens-only', 'output-references', 'exclude-core', 'verbose', 'all-themes'],
49
57
  },
50
58
  );
51
59
 
52
- const parsedThemes = Array.isArray(themes) ? themes : themes.split(',').map(t => t.trim());
60
+ if (themes !== null && allThemes) {
61
+ throw Error('Cannot specify themes with `--themes` when using `--all-themes`.');
62
+ }
63
+ let themesToProcess = null;
64
+
65
+ if (allThemes) {
66
+ const tokensPath = tokensSource || path.resolve(__dirname, '../tokens/src');
67
+ themesToProcess = fs
68
+ .readdirSync(`${tokensPath}/themes/`, { withFileTypes: true })
69
+ .filter(entry => entry.isDirectory())
70
+ .map(entry => entry.name);
71
+ } else if (Array.isArray(themes)) {
72
+ themesToProcess = themes;
73
+ } else {
74
+ themesToProcess = (themes || 'light').split(',').map(t => t.trim());
75
+ }
53
76
 
54
- const StyleDictionary = await initializeStyleDictionary({ themes: parsedThemes });
77
+ const StyleDictionary = await initializeStyleDictionary({ themes: themesToProcess });
55
78
 
56
79
  const coreConfig = {
57
80
  include: [
@@ -100,12 +123,12 @@ async function buildTokensCommand(commandArgs) {
100
123
  },
101
124
  };
102
125
 
103
- const getStyleDictionaryConfig = (themeVariant) => ({
126
+ const getStyleDictionaryConfig = (themeVariant, baseThemeVariant) => ({
104
127
  ...coreConfig,
105
128
  include: [
106
129
  ...coreConfig.include,
107
- path.resolve(__dirname, `../tokens/src/themes/${themeVariant}/**/*.json`),
108
- path.resolve(__dirname, `../tokens/src/themes/${themeVariant}/**/*.toml`),
130
+ path.resolve(__dirname, `../tokens/src/themes/${baseThemeVariant}/**/*.json`),
131
+ path.resolve(__dirname, `../tokens/src/themes/${baseThemeVariant}/**/*.toml`),
109
132
  ],
110
133
  source: tokensSource
111
134
  ? [
@@ -159,10 +182,10 @@ async function buildTokensCommand(commandArgs) {
159
182
  }
160
183
 
161
184
  // Add theme variants
162
- for (const themeVariant of parsedThemes) {
163
- const config = getStyleDictionaryConfig(themeVariant);
185
+ themesToProcess.forEach(themeVariant => {
186
+ const config = getStyleDictionaryConfig(themeVariant, baseParagonTheme || themeVariant);
164
187
  configs.push({ config, themeVariant });
165
- }
188
+ });
166
189
 
167
190
  // Build tokens for each configuration
168
191
  await Promise.all(configs.map(async ({ config, themeVariant }) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openedx/paragon",
3
- "version": "23.15.1",
3
+ "version": "23.16.0",
4
4
  "description": "Accessible, responsive UI component library based on Bootstrap.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",