diff --git a/style-dictionary/core/color-palette.ts b/style-dictionary/core/color-palette.ts index ab95af3dea..045e5e55a9 100644 --- a/style-dictionary/core/color-palette.ts +++ b/style-dictionary/core/color-palette.ts @@ -26,6 +26,26 @@ const paletteTokens: StyleDictionary.ColorPaletteDictionary = { colorGrey950: '#0f141a', colorGrey1000: '#06080a', + colorNeutralGrey50: '#fcfcfc', + colorNeutralGrey100: '#f9f9f9', + colorNeutralGrey150: '#f8f8f8', + colorNeutralGrey200: '#f5f5f5', + colorNeutralGrey250: '#ededed', + colorNeutralGrey300: '#e1e1e1', + colorNeutralGrey350: '#c9c9c9', + colorNeutralGrey400: '#b7b7b7', + colorNeutralGrey450: '#a9a9a9', + colorNeutralGrey500: '#909090', + colorNeutralGrey600: '#6b6b6b', + colorNeutralGrey650: '#494949', + colorNeutralGrey700: '#3b3b3b', + colorNeutralGrey750: '#2d2d2d', + colorNeutralGrey800: '#242424', + colorNeutralGrey850: '#1e1e1e', + colorNeutralGrey900: '#1a1a1a', + colorNeutralGrey950: '#151515', + colorNeutralGrey1000: '#080808', + colorLime50: '#f7ffeb', colorLime100: '#ebffcc', colorLime200: '#d1ff8a', diff --git a/style-dictionary/one-theme/borders.ts b/style-dictionary/one-theme/borders.ts new file mode 100644 index 0000000000..6be1033a2e --- /dev/null +++ b/style-dictionary/one-theme/borders.ts @@ -0,0 +1,37 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +import { StyleDictionary } from '../utils/interfaces.js'; + +export const tokens: StyleDictionary.BordersDictionary = { + // ── Border widths ───────────────────────────────────────────────────────── + borderWidthButton: '1px', + borderWidthToken: '1px', + borderWidthAlert: '0px', + borderItemWidth: '1px', + borderWidthAlertInlineStart: '2px', + borderWidthItemSelected: '1px', + borderWidthCardSelected: '1px', + + // ── Icon stroke widths ──────────────────────────────────────────────────── + borderWidthIconSmall: '1.5px', + borderWidthIconNormal: '1.5px', + borderWidthIconMedium: '1.75px', + borderWidthIconBig: '2px', + borderWidthIconLarge: '2.5px', + + // ── Border radii ────────────────────────────────────────────────────────── + borderRadiusAlert: '2px', + borderRadiusBadge: '16px', + borderRadiusButton: '2px', + borderRadiusContainer: '4px', + borderRadiusDropdown: '2px', + borderRadiusDropzone: '4px', + borderRadiusFlashbar: '2px', + borderRadiusItem: '2px', + borderRadiusInput: '2px', + borderRadiusPopover: '4px', + borderRadiusTabsFocusRing: '4px', + borderRadiusToken: '2px', + borderRadiusTutorialPanelItem: '4px', + borderRadiusStatusIndicator: '2px', +}; diff --git a/style-dictionary/one-theme/color-palette.ts b/style-dictionary/one-theme/color-palette.ts new file mode 100644 index 0000000000..d0a21cb50b --- /dev/null +++ b/style-dictionary/one-theme/color-palette.ts @@ -0,0 +1,161 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +import pick from 'lodash/pick.js'; + +import { ReferenceTokens } from '@cloudscape-design/theming-build'; + +import { paletteTokens as brand } from '../core/color-palette.js'; +import { expandColorDictionary, expandReferenceTokens } from '../utils/index.js'; +import { StyleDictionary } from '../utils/interfaces.js'; + +/** + * @deprecated These color palette tokens are deprecated and may be removed in a future version. + * Use semantic reference tokens instead: + * - colorNeutralGrey* → colorNeutral* + * - colorIndigo* → colorPrimary* or colorInfo* + * - colorRed* → colorError* + * - colorGreen* → colorSuccess* + * - colorYellow* → colorWarning* + * + * Reference tokens provide better semantic meaning and consistency across themes. + */ +const tokens: StyleDictionary.ColorPaletteDictionary = { + ...pick(brand, [ + 'colorNeutralGrey50', + 'colorNeutralGrey100', + 'colorNeutralGrey150', + 'colorNeutralGrey200', + 'colorNeutralGrey250', + 'colorNeutralGrey300', + 'colorNeutralGrey350', + 'colorNeutralGrey400', + 'colorNeutralGrey450', + 'colorNeutralGrey500', + 'colorNeutralGrey600', + 'colorNeutralGrey650', + 'colorNeutralGrey700', + 'colorNeutralGrey750', + 'colorNeutralGrey800', + 'colorNeutralGrey850', + 'colorNeutralGrey900', + 'colorNeutralGrey950', + 'colorNeutralGrey1000', + 'colorIndigo50', + 'colorIndigo100', + 'colorIndigo200', + 'colorIndigo300', + 'colorIndigo400', + 'colorIndigo500', + 'colorIndigo600', + 'colorIndigo700', + 'colorIndigo800', + 'colorIndigo900', + 'colorIndigo1000', + 'colorGreen50', + 'colorGreen200', + 'colorGreen500', + 'colorGreen600', + 'colorGreen700', + 'colorGreen900', + 'colorGreen1000', + 'colorRed50', + 'colorRed400', + 'colorRed600', + 'colorRed900', + 'colorRed1000', + 'colorYellow50', + 'colorYellow300', + 'colorYellow400', + 'colorYellow500', + 'colorYellow800', + 'colorYellow900', + 'colorYellow1000', + 'colorPurple400', + 'colorPurple700', + 'colorAmber400', + 'colorAmber500', + 'colorAwsSquidInk', + 'colorTransparent', + 'colorBlack', + 'colorWhite', + ]), +}; + +// Reference tokens for visual-refresh theme +const referenceTokens: ReferenceTokens = { + color: { + primary: { + 50: brand.colorIndigo50, + 100: brand.colorIndigo100, + 200: brand.colorIndigo200, + 300: brand.colorIndigo300, + 400: brand.colorIndigo400, + 500: brand.colorIndigo500, + 600: brand.colorIndigo600, // a11y + 700: brand.colorIndigo700, + 800: brand.colorIndigo800, + 900: brand.colorIndigo900, + 1000: brand.colorIndigo1000, + }, + neutral: { + 50: brand.colorNeutralGrey50, + 100: brand.colorNeutralGrey100, + 150: brand.colorNeutralGrey150, + 200: brand.colorNeutralGrey200, + 250: brand.colorNeutralGrey250, + 300: brand.colorNeutralGrey300, + 350: brand.colorNeutralGrey350, + 400: brand.colorNeutralGrey400, + 450: brand.colorNeutralGrey450, + 500: brand.colorNeutralGrey500, // a11y + 600: brand.colorNeutralGrey600, + 650: brand.colorNeutralGrey650, + 700: brand.colorNeutralGrey700, + 750: brand.colorNeutralGrey750, + 800: brand.colorNeutralGrey800, + 850: brand.colorNeutralGrey850, + 900: brand.colorNeutralGrey900, + 950: brand.colorNeutralGrey950, + 1000: brand.colorNeutralGrey1000, + }, + error: { + 50: brand.colorRed50, + 300: brand.colorRed300, + 400: brand.colorRed400, + 600: brand.colorRed600, + 900: brand.colorRed900, + 1000: brand.colorRed1000, + }, + success: { + 50: brand.colorGreen50, + 200: brand.colorGreen200, + 500: brand.colorGreen500, + 600: brand.colorGreen600, + 700: brand.colorGreen700, + 1000: brand.colorGreen1000, + }, + warning: { + 50: brand.colorYellow50, + 300: brand.colorYellow300, + 400: brand.colorYellow400, + 500: brand.colorYellow500, + 800: brand.colorYellow800, + 900: brand.colorYellow900, + 1000: brand.colorYellow1000, + }, + info: { + 50: brand.colorIndigo50, + 300: brand.colorIndigo300, + 400: brand.colorIndigo400, + 600: brand.colorIndigo600, + 1000: brand.colorIndigo1000, + }, + }, +}; + +const expandedTokens: StyleDictionary.ExpandedColorScopeDictionary = expandColorDictionary(tokens); +const expandedReferenceTokens: ReferenceTokens = expandReferenceTokens(referenceTokens); + +export const mode: StyleDictionary.ModeIdentifier = 'color'; +export { expandedTokens as tokens }; +export { expandedReferenceTokens as referenceTokens }; diff --git a/style-dictionary/one-theme/colors.ts b/style-dictionary/one-theme/colors.ts index 5db5671793..9ec6084e38 100644 --- a/style-dictionary/one-theme/colors.ts +++ b/style-dictionary/one-theme/colors.ts @@ -3,9 +3,114 @@ import { expandColorDictionary } from '../utils/index.js'; import { StyleDictionary } from '../utils/interfaces.js'; -// Anything not listed here falls back to the visual-refresh value via ThemeBuilder.addTokens in ./index.ts. +// One Theme color overrides on top of the visual-refresh baseline. +// Tokens not listed here fall back to the visual-refresh value via ThemeBuilder.addTokens in ./index.ts. const tokens: StyleDictionary.ColorsDictionary = { - colorBackgroundButtonPrimaryDefault: '{colorBlack}', + // ── Body text ───────────────────────────────────────────────────────────── + colorTextBodyDefault: { light: '{colorNeutralGrey950}', dark: '{colorNeutralGrey350}' }, + colorTextBodySecondary: { light: '{colorNeutralGrey600}', dark: '{colorNeutralGrey450}' }, + + // ── Container / layout ──────────────────────────────────────────────────── + colorBackgroundLayoutMain: { light: '{colorWhite}', dark: '{colorNeutralGrey950}' }, + colorBackgroundContainerHeader: { light: '{colorWhite}', dark: '{colorNeutralGrey950}' }, + colorBackgroundContainerContent: { light: '{colorWhite}', dark: '{colorNeutralGrey950}' }, + colorBorderDividerDefault: { light: '{colorNeutralGrey350}', dark: '{colorNeutralGrey750}' }, + colorBorderDividerSecondary: { light: '{colorNeutralGrey250}', dark: '{colorNeutralGrey800}' }, + colorBorderLayout: { light: '{colorNeutralGrey350}', dark: '{colorNeutralGrey750}' }, + + // ── Normal button ───────────────────────────────────────────────────────── + colorBorderButtonNormalDefault: { light: '{colorNeutralGrey650}', dark: '{colorNeutralGrey700}' }, + colorBorderButtonNormalHover: { light: '{colorNeutralGrey650}', dark: '{colorNeutralGrey650}' }, + colorBorderButtonNormalActive: { light: '{colorNeutralGrey650}', dark: '{colorNeutralGrey600}' }, + colorBackgroundButtonNormalDefault: { light: '{colorWhite}', dark: '{colorNeutralGrey850}' }, + colorBackgroundButtonNormalHover: { light: '{colorNeutralGrey150}', dark: '{colorNeutralGrey800}' }, + colorBackgroundButtonNormalActive: { light: '{colorNeutralGrey250}', dark: '{colorNeutralGrey850}' }, + colorTextButtonNormalDefault: { light: '{colorNeutralGrey700}', dark: '{colorNeutralGrey350}' }, + colorTextButtonNormalHover: { light: '{colorNeutralGrey700}', dark: '{colorNeutralGrey250}' }, + colorTextButtonNormalActive: { light: '{colorNeutralGrey700}', dark: '{colorNeutralGrey300}' }, + + // ── Primary button ──────────────────────────────────────────────────────── + colorBackgroundButtonPrimaryDefault: { light: '{colorNeutralGrey800}', dark: '{colorNeutralGrey300}' }, + colorBackgroundButtonPrimaryHover: { light: '{colorNeutralGrey700}', dark: '{colorNeutralGrey200}' }, + colorBackgroundButtonPrimaryActive: { light: '{colorNeutralGrey800}', dark: '{colorNeutralGrey300}' }, + colorTextButtonPrimaryDefault: { light: '{colorNeutralGrey50}', dark: '{colorNeutralGrey950}' }, + colorTextButtonPrimaryHover: { light: '{colorNeutralGrey50}', dark: '{colorNeutralGrey950}' }, + colorTextButtonPrimaryActive: { light: '{colorNeutralGrey50}', dark: '{colorNeutralGrey950}' }, + + // ── Link button ─────────────────────────────────────────────────────────── + colorBackgroundButtonLinkDefault: { light: '{colorNeutralGrey150}', dark: '{colorNeutralGrey750}' }, + colorBackgroundButtonLinkHover: { light: '{colorNeutralGrey250}', dark: '{colorNeutralGrey650}' }, + colorBackgroundButtonLinkActive: { light: '{colorNeutralGrey250}', dark: '{colorNeutralGrey900}' }, + colorTextLinkButtonNormalDefault: { light: '{colorIndigo600}', dark: '{colorIndigo500}' }, + + // ── Toggle button ───────────────────────────────────────────────────────── + colorBackgroundToggleButtonNormalPressed: { light: '{colorWhite}', dark: '{colorNeutralGrey850}' }, + colorBorderToggleButtonNormalPressed: { light: '{colorIndigo600}', dark: '{colorIndigo500}' }, + colorTextToggleButtonNormalPressed: { light: '{colorNeutralGrey900}', dark: '{colorWhite}' }, + + // ── Input / form ────────────────────────────────────────────────────────── + colorBackgroundInputDefault: { light: '{colorWhite}', dark: '{colorNeutralGrey950}' }, + colorBackgroundInputDisabled: { light: '{colorNeutralGrey250}', dark: '{colorNeutralGrey800}' }, + colorBorderInputDefault: { light: '{colorNeutralGrey400}', dark: '{colorNeutralGrey600}' }, + colorTextFormLabel: { light: '{colorNeutralGrey600}', dark: '{colorNeutralGrey300}' }, + colorTextFormSecondary: { light: '{colorNeutralGrey600}', dark: '{colorNeutralGrey500}' }, + colorTextLabel: { light: '{colorNeutralGrey600}', dark: '{colorNeutralGrey500}' }, + colorTextKeyValuePairsValue: { light: '{colorNeutralGrey600}', dark: '{colorNeutralGrey300}' }, + + // ── Controls ────────────────────────────────────────────────────────────── + colorBackgroundControlChecked: { light: '{colorIndigo600}', dark: '{colorIndigo500}' }, + + // ── Links ───────────────────────────────────────────────────────────────── + colorTextLinkDefault: { light: '{colorNeutralGrey950}', dark: '{colorNeutralGrey350}' }, + colorTextLinkHover: { light: '{colorNeutralGrey650}', dark: '{colorNeutralGrey200}' }, + colorTextLinkSecondaryDefault: { light: '{colorNeutralGrey600}', dark: '{colorNeutralGrey450}' }, + colorTextLinkInfoDefault: { light: '{colorIndigo600}', dark: '{colorIndigo400}' }, + colorTextLinkInfoHover: { light: '{colorIndigo800}', dark: '{colorIndigo300}' }, + colorTextAccent: { light: '{colorIndigo600}', dark: '{colorIndigo500}' }, + colorTextLinkDecorationDefault: { light: '{colorNeutralGrey650}', dark: '{colorNeutralGrey600}' }, + + // ── Selection / focus ───────────────────────────────────────────────────── + colorBorderItemFocused: { light: '{colorIndigo600}', dark: '{colorIndigo500}' }, + colorBorderItemSelected: { light: '{colorIndigo600}', dark: '{colorIndigo500}' }, + colorBackgroundItemSelected: { light: '{colorNeutralGrey150}', dark: '{colorNeutralGrey1000}' }, + colorBackgroundLayoutToggleSelectedDefault: { light: '{colorNeutralGrey800}', dark: '{colorNeutralGrey100}' }, + colorBackgroundLayoutToggleSelectedHover: { light: '{colorNeutralGrey800}', dark: '{colorNeutralGrey100}' }, + colorBackgroundLayoutToggleSelectedActive: { light: '{colorNeutralGrey800}', dark: '{colorNeutralGrey100}' }, + + // ── Segmented control ───────────────────────────────────────────────────── + colorBackgroundSegmentActive: { light: '{colorNeutralGrey800}', dark: '{colorNeutralGrey300}' }, + colorBackgroundSegmentDefault: { light: 'transparent', dark: 'transparent' }, + + // ── Slider / progress ───────────────────────────────────────────────────── + colorBackgroundSliderRangeDefault: { light: '{colorIndigo600}', dark: '{colorIndigo500}' }, + colorBackgroundSliderHandleDefault: { light: '{colorIndigo600}', dark: '{colorIndigo500}' }, + colorBackgroundProgressBarValueDefault: { light: '{colorIndigo600}', dark: '{colorIndigo500}' }, + + // ── Notifications ───────────────────────────────────────────────────────── + colorBackgroundNotificationGreen: { light: '{colorSuccess700}', dark: '{colorSuccess700}' }, + colorBackgroundNotificationBlue: { light: '{colorIndigo800}', dark: '{colorIndigo800}' }, + colorTextNotificationDefault: { light: '{colorWhite}', dark: '{colorWhite}' }, + + // ── Status text ─────────────────────────────────────────────────────────── + colorTextStatusInfo: { light: '{colorIndigo600}', dark: '{colorIndigo300}' }, + colorTextStatusSuccess: { light: '{colorSuccess600}', dark: '{colorSuccess200}' }, + colorTextStatusWarning: { light: '{colorWarning800}', dark: '{colorWarning300}' }, + colorTextStatusError: { light: '{colorError600}', dark: '{colorError300}' }, + colorTextStatusInactive: { light: '{colorNeutralGrey650}', dark: '{colorNeutralGrey450}' }, + + // ── Dropdown filter match ───────────────────────────────────────────────── + colorTextDropdownItemFilterMatch: { light: '{colorIndigo600}', dark: '{colorIndigo500}' }, + colorBackgroundDropdownItemFilterMatch: { light: '{colorNeutralGrey200}', dark: '{colorNeutralGrey1000}' }, + + // ── Status indicator backgrounds (alpha values — no palette token available) ── + colorBackgroundStatusIndicatorInfo: { light: '#5c7fff10', dark: '#5c7fff20' }, + colorBackgroundStatusIndicatorWarning: { light: '#fbd33210', dark: '#fbd33220' }, + colorBackgroundStatusIndicatorSuccess: { light: '#2bb53410', dark: '#2bb53420' }, + colorBackgroundStatusIndicatorError: { light: '#ff7a7a10', dark: '#ff7a7a20' }, + colorBackgroundStatusIndicatorNeutral: { light: '{colorNeutralGrey250}', dark: '{colorNeutralGrey800}' }, + + // ── Breadcrumb ──────────────────────────────────────────────────────────── + colorTextBreadcrumbCurrent: { light: '{colorNeutralGrey600}', dark: '{colorNeutralGrey500}' }, }; const expandedTokens: StyleDictionary.ExpandedColorScopeDictionary = expandColorDictionary(tokens); diff --git a/style-dictionary/one-theme/contexts/alert.ts b/style-dictionary/one-theme/contexts/alert.ts new file mode 100644 index 0000000000..02df7bc41f --- /dev/null +++ b/style-dictionary/one-theme/contexts/alert.ts @@ -0,0 +1,22 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +import merge from 'lodash/merge.js'; + +import { expandColorDictionary } from '../../utils/index.js'; +import { StyleDictionary } from '../../utils/interfaces.js'; + +const tokens: StyleDictionary.ColorsDictionary = { + colorBackgroundStatusInfo: { light: '#5c7fff20', dark: '#161a2d' }, + colorBackgroundStatusWarning: { light: '#fbd33220', dark: '#fbd33210' }, + colorBackgroundStatusError: { light: '#ff7a7a10', dark: '#ff7a7a10' }, + colorBackgroundStatusSuccess: { light: '#7ae50020', dark: '#2bb53410' }, + colorTextStatusInfo: { light: '#0033cc', dark: '#7598ff' }, + colorBorderStatusInfo: { light: '#0033cc', dark: '#7598ff' }, + colorTextStatusSuccess: { light: '#00802f', dark: '#aeffa8' }, + colorBorderStatusSuccess: { light: '#00802f', dark: '#aeffa8' }, + colorBackgroundButtonNormalDefault: { light: 'transparent', dark: 'transparent' }, +}; + +const expandedTokens: StyleDictionary.ExpandedColorScopeDictionary = expandColorDictionary(merge({}, tokens)); + +export { expandedTokens as tokens }; diff --git a/style-dictionary/one-theme/contexts/app-layout-toolbar.ts b/style-dictionary/one-theme/contexts/app-layout-toolbar.ts new file mode 100644 index 0000000000..ca8eeadecc --- /dev/null +++ b/style-dictionary/one-theme/contexts/app-layout-toolbar.ts @@ -0,0 +1,14 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +import merge from 'lodash/merge.js'; + +import { expandColorDictionary } from '../../utils/index.js'; +import { StyleDictionary } from '../../utils/interfaces.js'; + +const tokens: StyleDictionary.ColorsDictionary = { + colorBackgroundLayoutMain: { light: '{colorNeutralGrey50}', dark: '{colorNeutralGrey1000}' }, +}; + +const expandedTokens: StyleDictionary.ExpandedColorScopeDictionary = expandColorDictionary(merge({}, tokens)); + +export { expandedTokens as tokens }; diff --git a/style-dictionary/one-theme/contexts/flashbar.ts b/style-dictionary/one-theme/contexts/flashbar.ts new file mode 100644 index 0000000000..96ce1cfcfa --- /dev/null +++ b/style-dictionary/one-theme/contexts/flashbar.ts @@ -0,0 +1,16 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +import merge from 'lodash/merge.js'; + +import { expandColorDictionary } from '../../utils/index.js'; +import { StyleDictionary } from '../../utils/interfaces.js'; + +const tokens: StyleDictionary.ColorsDictionary = { + colorBackgroundNotificationGreen: { light: '#006b48', dark: '#006b48' }, + colorBackgroundNotificationBlue: { light: '#0033cc', dark: '#0033cc' }, + colorTextNotificationDefault: { light: '#ffffff', dark: '#ffffff' }, +}; + +const expandedTokens: StyleDictionary.ExpandedColorScopeDictionary = expandColorDictionary(merge({}, tokens)); + +export { expandedTokens as tokens }; diff --git a/style-dictionary/one-theme/contexts/header.ts b/style-dictionary/one-theme/contexts/header.ts new file mode 100644 index 0000000000..47901f1e39 --- /dev/null +++ b/style-dictionary/one-theme/contexts/header.ts @@ -0,0 +1,31 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +import merge from 'lodash/merge.js'; + +import { expandColorDictionary } from '../../utils/index.js'; +import { StyleDictionary } from '../../utils/interfaces.js'; + +// The header context always renders on a dark background regardless of color mode. +// All values are mode-invariant (single string = same in light and dark). +const tokens: StyleDictionary.ColorsDictionary = { + colorBorderButtonNormalDefault: '#e1e1e1', + colorBorderButtonNormalHover: '#f9f9f9', + colorBorderButtonNormalActive: '#f9f9f9', + colorBackgroundButtonNormalHover: '#242424', + colorBackgroundButtonNormalActive: '#1a1a1a', + colorTextButtonNormalDefault: '#e1e1e1', + colorTextButtonNormalHover: '#f9f9f9', + colorTextButtonNormalActive: '#f9f9f9', + colorBackgroundButtonPrimaryDefault: '#f9f9f9', + colorBackgroundButtonPrimaryHover: '#ffffff', + colorBackgroundButtonPrimaryActive: '#f9f9f9', + colorTextButtonPrimaryDefault: '#1a1a1a', + colorTextButtonPrimaryHover: '#1a1a1a', + colorTextButtonPrimaryActive: '#1a1a1a', + colorTextLinkDefault: '#c9c9c9', +}; + +const expandedTokens: StyleDictionary.ExpandedColorScopeDictionary = expandColorDictionary(merge({}, tokens)); + +export const mode: StyleDictionary.ModeIdentifier = 'color'; +export { expandedTokens as tokens }; diff --git a/style-dictionary/one-theme/contexts/top-navigation.ts b/style-dictionary/one-theme/contexts/top-navigation.ts new file mode 100644 index 0000000000..30a9005716 --- /dev/null +++ b/style-dictionary/one-theme/contexts/top-navigation.ts @@ -0,0 +1,38 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +import merge from 'lodash/merge.js'; + +import { expandColorDictionary } from '../../utils/index.js'; +import { StyleDictionary } from '../../utils/interfaces.js'; + +const tokens: StyleDictionary.ColorsDictionary = { + colorBackgroundContainerContent: { light: '#ffffff', dark: '#151515' }, + colorBorderDividerDefault: { light: '#c9c9c9', dark: '#494949' }, + colorTextTopNavigationTitle: { light: '#242424', dark: '#f5f5f5' }, + colorTextInteractiveDefault: { light: '#242424', dark: '#f5f5f5' }, + colorTextInteractiveHover: { light: '#295eff', dark: '#5c7fff' }, + colorTextInteractiveActive: { light: '#080808', dark: '#f9f9f9' }, + colorTextAccent: { light: '#080808', dark: '#f9f9f9' }, + colorTextDropdownItemDefault: { light: '#080808', dark: '#f9f9f9' }, + colorTextDropdownItemHighlighted: { light: '#080808', dark: '#f9f9f9' }, + colorTextGroupLabel: { light: '#494949', dark: '#c9c9c9' }, + colorBackgroundDropdownItemDefault: { light: '#ffffff', dark: '#242424' }, + colorBackgroundDropdownItemHover: { light: '#f5f5f5', dark: '#1a1a1a' }, + colorBorderDropdownContainer: { light: '#b7b7b7', dark: '#6b6b6b' }, + colorTextBodyDefault: { light: '#080808', dark: '#f9f9f9' }, + colorBackgroundInputDefault: { light: '#ffffff', dark: '#242424' }, + colorBorderInputDefault: { light: '#b7b7b7', dark: '#6b6b6b' }, + colorTextInputPlaceholder: { light: '#6b6b6b', dark: '#909090' }, + colorBorderDropdownItemDefault: { light: '#e1e1e1', dark: '#494949' }, + colorTextDropdownItemSecondary: { light: '#494949', dark: '#c9c9c9' }, + colorItemSelected: { light: '#080808', dark: '#f9f9f9' }, + colorBackgroundDropdownItemSelected: { light: '#f8f8f8', dark: '#080808' }, + colorBorderItemSelected: { light: '#080808', dark: '#f9f9f9' }, + colorTextButtonInlineIconDefault: { light: '#242424', dark: '#f9f9f9' }, + colorTextButtonInlineIconHover: { light: '#242424', dark: '#f9f9f9' }, +}; + +const expandedTokens: StyleDictionary.ExpandedColorScopeDictionary = expandColorDictionary(merge({}, tokens)); + +export const mode: StyleDictionary.ModeIdentifier = 'color'; +export { expandedTokens as tokens }; diff --git a/style-dictionary/one-theme/index.ts b/style-dictionary/one-theme/index.ts index 71a56acf2e..37e8a0fb5a 100644 --- a/style-dictionary/one-theme/index.ts +++ b/style-dictionary/one-theme/index.ts @@ -2,6 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 import { ThemeBuilder } from '@cloudscape-design/theming-build'; +import { + createAlertContext, + createAppLayoutToolbarContext, + createFlashbarContext, + createHeaderContext, + createTopNavigationContext, +} from '../utils/contexts.js'; import { StyleDictionary } from '../utils/interfaces.js'; import { createColorMode, createDensityMode, createMotionMode } from '../utils/modes.js'; import { buildVisualRefresh } from '../visual-refresh/index.js'; @@ -13,14 +20,21 @@ const modes = [ ]; // One Theme starts from the full visual-refresh token set and layers overrides on top. -const overrides: Array = [await import('./colors.js')]; +const overrides = [ + await import('./color-palette.js'), + await import('./colors.js'), + await import('./typography.js'), + await import('./borders.js'), + await import('./spacing.js'), + await import('./sizes.js'), +] as Array; const builder = new ThemeBuilder('one-theme', '.awsui-one-theme', modes); // Layer 1: visual refresh baseline (full token set + contexts). await buildVisualRefresh(builder); -// Layer 2: One Theme overrides. +// Layer 2: One Theme token overrides. overrides.forEach(({ tokens, mode: modeId, referenceTokens }) => { const mode = modes.find(m => m.id === modeId); if (referenceTokens) { @@ -29,5 +43,12 @@ overrides.forEach(({ tokens, mode: modeId, referenceTokens }) => { builder.addTokens(tokens, mode); }); +// Layer 3: One Theme context overrides (replace the VR contexts added in layer 1). +builder.addContext(createAppLayoutToolbarContext((await import('./contexts/app-layout-toolbar.js')).tokens)); +builder.addContext(createTopNavigationContext((await import('./contexts/top-navigation.js')).tokens)); +builder.addContext(createHeaderContext((await import('./contexts/header.js')).tokens)); +builder.addContext(createFlashbarContext((await import('./contexts/flashbar.js')).tokens)); +builder.addContext(createAlertContext((await import('./contexts/alert.js')).tokens)); + const theme = builder.build(); export default theme; diff --git a/style-dictionary/one-theme/sizes.ts b/style-dictionary/one-theme/sizes.ts new file mode 100644 index 0000000000..9a3af6053c --- /dev/null +++ b/style-dictionary/one-theme/sizes.ts @@ -0,0 +1,13 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +import { expandDensityDictionary } from '../utils/index.js'; +import { StyleDictionary } from '../utils/interfaces.js'; + +const tokens: StyleDictionary.SizesDictionary = { + sizeVerticalInput: { comfortable: '30px', compact: '26px' }, +}; + +const expandedTokens: StyleDictionary.ExpandedDensityScopeDictionary = expandDensityDictionary(tokens); + +export { expandedTokens as tokens }; +export const mode: StyleDictionary.ModeIdentifier = 'density'; diff --git a/style-dictionary/one-theme/spacing.ts b/style-dictionary/one-theme/spacing.ts new file mode 100644 index 0000000000..935677937e --- /dev/null +++ b/style-dictionary/one-theme/spacing.ts @@ -0,0 +1,18 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +import { expandDensityDictionary } from '../utils/index.js'; +import { StyleDictionary } from '../utils/interfaces.js'; + +const tokens: StyleDictionary.SpacingDictionary = { + spaceAlertVertical: '8px', + spaceButtonHorizontal: '12px', + spaceTabsVertical: '2px', + spaceTokenVertical: '2px', + spaceFieldVertical: { comfortable: '4px', compact: '2px' }, + spaceStatusIndicatorPaddingHorizontal: '4px', +}; + +const expandedTokens: StyleDictionary.ExpandedDensityScopeDictionary = expandDensityDictionary(tokens); + +export { expandedTokens as tokens }; +export const mode: StyleDictionary.ModeIdentifier = 'density'; diff --git a/style-dictionary/one-theme/typography.ts b/style-dictionary/one-theme/typography.ts new file mode 100644 index 0000000000..fcf3e1ef98 --- /dev/null +++ b/style-dictionary/one-theme/typography.ts @@ -0,0 +1,50 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +import { StyleDictionary } from '../utils/interfaces.js'; + +export const tokens: StyleDictionary.TypographyDictionary = { + fontFamilyBase: "'Ember Modern Text UI', 'Amazon Ember', Roboto, Arial, sans-serif", + + // ── Headings ────────────────────────────────────────────────────────────── + fontSizeHeadingXl: '24px', + lineHeightHeadingXl: '30px', + fontWeightHeadingXl: '700', + + fontSizeHeadingL: '20px', + lineHeightHeadingL: '24px', + fontWeightHeadingL: '700', + + fontSizeHeadingM: '18px', + lineHeightHeadingM: '22px', + fontWeightHeadingM: '700', + + fontSizeHeadingS: '16px', + lineHeightHeadingS: '20px', + fontWeightHeadingS: '700', + + fontSizeHeadingXs: '14px', + lineHeightHeadingXs: '20px', + fontWeightHeadingXs: '700', + + // ── Interactive elements ────────────────────────────────────────────────── + fontWeightButton: '700', + fontWeightTabs: '700', + fontSizeTabs: '14px', + + // ── Alerts / flashbars ──────────────────────────────────────────────────── + fontWeightAlertHeader: '700', + fontWeightFlashbarHeader: '700', + + // ── Form labels ─────────────────────────────────────────────────────────── + fontSizeFormLabel: '14px', + lineHeightFormLabel: '20px', + fontWeightFormLabel: '700', + + // ── Key-value pairs ─────────────────────────────────────────────────────── + fontSizeKeyValuePairsLabel: '14px', + lineHeightKeyValuePairsLabel: '20px', + fontWeightKeyValuePairsLabel: '700', + + // ── Breadcrumb ──────────────────────────────────────────────────────────── + fontWeightBreadcrumbCurrent: '400', +}; diff --git a/style-dictionary/utils/token-names.ts b/style-dictionary/utils/token-names.ts index 4b68611181..e56c85f444 100644 --- a/style-dictionary/utils/token-names.ts +++ b/style-dictionary/utils/token-names.ts @@ -112,6 +112,25 @@ export type ColorPaletteTokenName = | 'colorGrey900' | 'colorGrey950' | 'colorGrey1000' + | 'colorNeutralGrey50' + | 'colorNeutralGrey100' + | 'colorNeutralGrey150' + | 'colorNeutralGrey200' + | 'colorNeutralGrey250' + | 'colorNeutralGrey300' + | 'colorNeutralGrey350' + | 'colorNeutralGrey400' + | 'colorNeutralGrey450' + | 'colorNeutralGrey500' + | 'colorNeutralGrey600' + | 'colorNeutralGrey650' + | 'colorNeutralGrey700' + | 'colorNeutralGrey750' + | 'colorNeutralGrey800' + | 'colorNeutralGrey850' + | 'colorNeutralGrey900' + | 'colorNeutralGrey950' + | 'colorNeutralGrey1000' | 'colorLime50' | 'colorLime100' | 'colorLime200'