From c57141063b40c481065d38249cb01f6e0a5b568d Mon Sep 17 00:00:00 2001 From: Andrei Zhaleznichenka Date: Fri, 29 May 2026 06:58:45 +0200 Subject: [PATCH] wip --- build-tools/tasks/generate-environment.js | 6 +- build-tools/tasks/styles.js | 3 +- build-tools/tasks/themeable-source.js | 2 +- build-tools/utils/themes.js | 56 +++++++++++-- .../with-table-and-sticky-offset.page.tsx | 2 +- pages/app/app-context.tsx | 6 -- pages/app/components/theme-switcher.tsx | 37 --------- pages/app/index.tsx | 11 +-- pages/theming/integration.page.tsx | 2 +- pages/webpack.config.cjs | 5 +- style-dictionary/core-open-source/borders.ts | 33 ++++++++ style-dictionary/core-open-source/colors.ts | 82 +++++++++++++++++++ .../core-open-source/contexts/alert.ts | 19 +++++ .../core-open-source/contexts/flashbar.ts | 14 ++++ .../core-open-source/contexts/header.ts | 27 ++++++ .../contexts/top-navigation.ts | 37 +++++++++ style-dictionary/core-open-source/index.ts | 51 ++++++++++++ style-dictionary/core-open-source/sizes.ts | 13 +++ style-dictionary/core-open-source/spacing.ts | 17 ++++ .../core-open-source/typography.ts | 31 +++++++ style-dictionary/core/color-palette.ts | 2 - style-dictionary/core/index.ts | 13 ++- style-dictionary/utils/token-names.ts | 2 + style-dictionary/visual-refresh/colors.ts | 2 + 24 files changed, 395 insertions(+), 78 deletions(-) create mode 100644 style-dictionary/core-open-source/borders.ts create mode 100644 style-dictionary/core-open-source/colors.ts create mode 100644 style-dictionary/core-open-source/contexts/alert.ts create mode 100644 style-dictionary/core-open-source/contexts/flashbar.ts create mode 100644 style-dictionary/core-open-source/contexts/header.ts create mode 100644 style-dictionary/core-open-source/contexts/top-navigation.ts create mode 100644 style-dictionary/core-open-source/index.ts create mode 100644 style-dictionary/core-open-source/sizes.ts create mode 100644 style-dictionary/core-open-source/spacing.ts create mode 100644 style-dictionary/core-open-source/typography.ts diff --git a/build-tools/tasks/generate-environment.js b/build-tools/tasks/generate-environment.js index f43ecd1b4a..481fd6def8 100644 --- a/build-tools/tasks/generate-environment.js +++ b/build-tools/tasks/generate-environment.js @@ -5,9 +5,6 @@ const { writeFile } = require('../utils/files'); 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 writeEnvironmentFile(theme) { const filepath = 'internal/environment'; const values = { @@ -16,8 +13,7 @@ function writeEnvironmentFile(theme) { GIT_SHA: workspace.gitCommitVersion, THEME: theme.name, SYSTEM: 'core', - ALWAYS_VISUAL_REFRESH: !!theme.alwaysVisualRefresh || ALWAYS_VISUAL_REFRESH, - INCLUDE_ONE_THEME: INCLUDE_ONE_THEME, + ALWAYS_VISUAL_REFRESH: !!theme.alwaysVisualRefresh, }; const basePath = path.join(theme.outputPath, filepath); diff --git a/build-tools/tasks/styles.js b/build-tools/tasks/styles.js index 50aa943278..4249e4a891 100644 --- a/build-tools/tasks/styles.js +++ b/build-tools/tasks/styles.js @@ -46,8 +46,9 @@ function stylesTask(theme) { theme.secondaryThemePaths?.map(async path => (await import(join(styleDictionaryRoot, path))).default) ?? [] ); + const metadataPath = theme.metadataPath || join(theme.primaryThemePath, '../metadata.js'); // eslint-disable-next-line no-unsanitized/method - const { default: metadata } = await import(join(styleDictionaryRoot, theme.primaryThemePath, '../metadata.js')); + const { default: metadata } = await import(join(styleDictionaryRoot, metadataPath)); const exposed = []; const themeable = []; const variablesMap = {}; diff --git a/build-tools/tasks/themeable-source.js b/build-tools/tasks/themeable-source.js index 67d85fa7b4..7c11ff2f58 100644 --- a/build-tools/tasks/themeable-source.js +++ b/build-tools/tasks/themeable-source.js @@ -17,7 +17,7 @@ const componentsTemplateDir = 'internal/template'; const designTokensTemplateDir = 'internal/template-tokens'; const stylesDir = 'internal/scss'; -const theme = themes.find(theme => theme.name === 'default'); +const theme = themes[0]; const themeable = { name: 'components-themeable', sourceDir: theme.outputPath, diff --git a/build-tools/utils/themes.js b/build-tools/utils/themes.js index 6564bf32d4..304c1d56f6 100644 --- a/build-tools/utils/themes.js +++ b/build-tools/utils/themes.js @@ -3,10 +3,9 @@ const path = require('path'); const workspace = require('./workspace'); -const INCLUDE_ONE_THEME = process.env.INCLUDE_ONE_THEME === 'true'; +const THEME = process.env.THEME || 'default'; -const themes = [ - // This is the default Cloudscape theme, which is best used with Visual Refresh enabled (by default) +const allThemes = [ { name: 'default', packageJson: { name: '@cloudscape-design/components' }, @@ -14,12 +13,55 @@ const themes = [ designTokensDir: 'design-tokens', designTokensPackageJson: { name: '@cloudscape-design/design-tokens' }, outputPath: path.join(workspace.targetPath, 'components'), + primaryThemePath: './core-open-source/index.js', + secondaryThemePaths: [], + metadataPath: './visual-refresh/metadata.js', + alwaysVisualRefresh: true, + }, + { + name: 'visual-refresh', + packageJson: { name: '@cloudscape-design/components' }, + designTokensOutput: 'index', + designTokensDir: 'design-tokens', + designTokensPackageJson: { name: '@cloudscape-design/design-tokens' }, + outputPath: path.join(workspace.targetPath, 'components'), + primaryThemePath: './visual-refresh/index.js', + secondaryThemePaths: [], + metadataPath: './visual-refresh/metadata.js', + alwaysVisualRefresh: true, + }, + { + name: 'classic', + packageJson: { name: '@cloudscape-design/components' }, + designTokensOutput: 'index', + designTokensDir: 'design-tokens', + 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'] : []), - ], + secondaryThemePaths: [], + metadataPath: './classic/metadata.js', + alwaysVisualRefresh: false, + }, + { + name: 'one-theme', + packageJson: { name: '@cloudscape-design/components' }, + designTokensOutput: 'index', + designTokensDir: 'design-tokens', + designTokensPackageJson: { name: '@cloudscape-design/design-tokens' }, + outputPath: path.join(workspace.targetPath, 'components'), + primaryThemePath: './one-theme/index.js', + secondaryThemePaths: [], + metadataPath: './visual-refresh/metadata.js', + alwaysVisualRefresh: true, }, ]; +// Build only the selected theme (default: 'default' which is core-open-source) +const themes = allThemes.filter(t => t.name === THEME); + +if (themes.length === 0) { + const available = allThemes.map(t => t.name).join(', '); + throw new Error(`Unknown theme "${THEME}". Available themes: ${available}`); +} + module.exports = themes; diff --git a/pages/app-layout/with-table-and-sticky-offset.page.tsx b/pages/app-layout/with-table-and-sticky-offset.page.tsx index e2964798ef..85d18c0a1f 100644 --- a/pages/app-layout/with-table-and-sticky-offset.page.tsx +++ b/pages/app-layout/with-table-and-sticky-offset.page.tsx @@ -29,7 +29,7 @@ export default function () { header={
Sticky Scrollbar Example
} // manually set vertical offset to test this feature - stickyHeaderVerticalOffset={urlParams.visualRefresh ? 57 : 45} + stickyHeaderVerticalOffset={57} stickyHeader={true} variant="full-page" columnDefinitions={columnsConfig} diff --git a/pages/app/app-context.tsx b/pages/app/app-context.tsx index 4807fdf5fe..3d1d374767 100644 --- a/pages/app/app-context.tsx +++ b/pages/app/app-context.tsx @@ -6,13 +6,9 @@ import mapValues from 'lodash/mapValues'; import { Density, Mode } from '@cloudscape-design/global-styles'; -import { THEME } from '~components/internal/environment'; - interface AppUrlParams { density: Density; direction: 'ltr' | 'rtl'; - visualRefresh: boolean; - oneTheme: boolean; motionDisabled: boolean; appLayoutWidget: boolean; mode?: Mode; @@ -32,8 +28,6 @@ const appContextDefaults: AppContextType = { urlParams: { density: Density.Comfortable, direction: 'ltr', - visualRefresh: THEME === 'default', - oneTheme: false, motionDisabled: false, appLayoutWidget: false, }, diff --git a/pages/app/components/theme-switcher.tsx b/pages/app/components/theme-switcher.tsx index 26ade0902b..7a3962f612 100644 --- a/pages/app/components/theme-switcher.tsx +++ b/pages/app/components/theme-switcher.tsx @@ -4,7 +4,6 @@ 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 SpaceBetween from '~components/space-between'; import AppContext from '../app-context'; @@ -12,44 +11,8 @@ import AppContext from '../app-context'; export default function ThemeSwitcher() { const { mode, urlParams, setUrlParams, setMode } = useContext(AppContext); - function activateTheme(theme: 'visualRefresh' | 'oneTheme' | 'classic') { - setUrlParams({ - visualRefresh: theme === 'visualRefresh', - oneTheme: theme === 'oneTheme', - }); - window.location.reload(); - } - - const vrSwitchProps: React.InputHTMLAttributes = { - id: 'visual-refresh-toggle', - type: 'checkbox', - }; - - if (ALWAYS_VISUAL_REFRESH) { - vrSwitchProps.checked = true; - vrSwitchProps.readOnly = true; - } else { - vrSwitchProps.checked = urlParams.visualRefresh && !urlParams.oneTheme; - vrSwitchProps.onChange = event => activateTheme(event.target.checked ? 'visualRefresh' : 'classic'); - } - return ( - - {INCLUDE_ONE_THEME && ( - - )}