From 10cf2ad588b541bed15ed96d985cf8de76a93a92 Mon Sep 17 00:00:00 2001 From: Maximilian Schoell Date: Wed, 17 Jun 2026 12:21:53 +0200 Subject: [PATCH 1/3] refactor: replace INCLUDE_ONE_THEME with INCLUDED_THEMES --- build-tools/tasks/generate-environment.js | 17 +++++++++---- build-tools/utils/themes.js | 29 +++++++++++++++++++---- pages/app/components/theme-switcher.tsx | 4 ++-- src/internal/environment.d.ts | 2 ++ 4 files changed, 41 insertions(+), 11 deletions(-) diff --git a/build-tools/tasks/generate-environment.js b/build-tools/tasks/generate-environment.js index f43ecd1b4a..57c5062c8c 100644 --- a/build-tools/tasks/generate-environment.js +++ b/build-tools/tasks/generate-environment.js @@ -6,7 +6,16 @@ const themes = require('../utils/themes'); const workspace = require('../utils/workspace'); const ALWAYS_VISUAL_REFRESH = process.env.ALWAYS_VISUAL_REFRESH === 'true'; -const INCLUDE_ONE_THEME = process.env.INCLUDE_ONE_THEME === 'true'; + +function tsType(value) { + if (Array.isArray(value)) { + return 'string[]'; + } + if (typeof value === 'boolean') { + return 'boolean'; + } + return 'string'; +} function writeEnvironmentFile(theme) { const filepath = 'internal/environment'; @@ -17,7 +26,7 @@ function writeEnvironmentFile(theme) { THEME: theme.name, SYSTEM: 'core', ALWAYS_VISUAL_REFRESH: !!theme.alwaysVisualRefresh || ALWAYS_VISUAL_REFRESH, - INCLUDE_ONE_THEME: INCLUDE_ONE_THEME, + INCLUDED_THEMES: theme.includedThemes ?? [], }; const basePath = path.join(theme.outputPath, filepath); @@ -32,8 +41,8 @@ function writeEnvironmentFile(theme) { ); writeFile( `${basePath}.d.ts`, - Object.keys(values) - .map(key => `export const ${key}: string;`) + Object.entries(values) + .map(([key, value]) => `export const ${key}: ${tsType(value)};`) .join('\n') ); } diff --git a/build-tools/utils/themes.js b/build-tools/utils/themes.js index 6564bf32d4..86bb338798 100644 --- a/build-tools/utils/themes.js +++ b/build-tools/utils/themes.js @@ -3,7 +3,28 @@ const path = require('path'); const workspace = require('./workspace'); -const INCLUDE_ONE_THEME = process.env.INCLUDE_ONE_THEME === 'true'; +// Registry of secondary themes that can be layered on top of the primary theme as opt-in overrides. +// To add a new theme, register its id and style-dictionary entry path here, then include it via the +// THEMES env var. +const SECONDARY_THEMES = { + 'visual-refresh': './visual-refresh-secondary/index.js', + 'one-theme': './one-theme/index.js', +}; + +// THEMES is a comma-separated list of secondary themes to compile into the build, e.g. +// `THEMES=visual-refresh,one-theme`. Defaults to `visual-refresh`. +const includedThemes = (process.env.THEMES ?? 'visual-refresh') + .split(',') + .map(name => name.trim()) + .filter(Boolean); + +includedThemes.forEach(name => { + if (!SECONDARY_THEMES[name]) { + throw new Error( + `Unknown theme "${name}" in THEMES env var. Available themes: ${Object.keys(SECONDARY_THEMES).join(', ')}.` + ); + } +}); const themes = [ // This is the default Cloudscape theme, which is best used with Visual Refresh enabled (by default) @@ -15,10 +36,8 @@ const themes = [ designTokensPackageJson: { name: '@cloudscape-design/design-tokens' }, outputPath: path.join(workspace.targetPath, 'components'), primaryThemePath: './classic/index.js', - secondaryThemePaths: [ - './visual-refresh-secondary/index.js', - ...(INCLUDE_ONE_THEME ? ['./one-theme/index.js'] : []), - ], + includedThemes, + secondaryThemePaths: includedThemes.map(name => SECONDARY_THEMES[name]), }, ]; diff --git a/pages/app/components/theme-switcher.tsx b/pages/app/components/theme-switcher.tsx index 26ade0902b..1c4ec7fcd9 100644 --- a/pages/app/components/theme-switcher.tsx +++ b/pages/app/components/theme-switcher.tsx @@ -4,7 +4,7 @@ import React, { useContext } from 'react'; import { Density, Mode } from '@cloudscape-design/global-styles'; -import { ALWAYS_VISUAL_REFRESH, INCLUDE_ONE_THEME } from '~components/internal/environment'; +import { ALWAYS_VISUAL_REFRESH, INCLUDED_THEMES } from '~components/internal/environment'; import SpaceBetween from '~components/space-between'; import AppContext from '../app-context'; @@ -39,7 +39,7 @@ export default function ThemeSwitcher() { Visual refresh - {INCLUDE_ONE_THEME && ( + {INCLUDED_THEMES.includes('one-theme') && (