From 3a2d2d499e864a4c217f7fd47dee0a630722348e Mon Sep 17 00:00:00 2001 From: Maximilian Schoell Date: Thu, 6 Aug 2026 11:48:32 +0200 Subject: [PATCH 1/9] refactor: decouple flash and alert styling from shared tokens --- .../__snapshots__/themes.test.ts.snap | 120 ++++++++++++++++++ src/alert/styles.scss | 17 +-- src/flashbar/flash.tsx | 4 + src/flashbar/styles.scss | 8 +- src/progress-bar/internal.tsx | 6 +- src/progress-bar/styles.scss | 20 +++ style-dictionary/utils/token-names.ts | 15 +++ style-dictionary/visual-refresh/colors.ts | 15 +++ .../visual-refresh/metadata/colors.ts | 75 +++++++++++ 9 files changed, 267 insertions(+), 13 deletions(-) diff --git a/src/__integ__/__snapshots__/themes.test.ts.snap b/src/__integ__/__snapshots__/themes.test.ts.snap index 362ad66114..8dd021c016 100644 --- a/src/__integ__/__snapshots__/themes.test.ts.snap +++ b/src/__integ__/__snapshots__/themes.test.ts.snap @@ -84,6 +84,10 @@ exports[`CSS Custom Properties match previous snapshot for mode "compact" 1`] = "color-background-action-card-default": "#ffffff", "color-background-action-card-disabled": "#eaeded", "color-background-action-card-hover": "#f1faff", + "color-background-alert-error": "#fdf3f1", + "color-background-alert-info": "#f1faff", + "color-background-alert-success": "#f2f8f0", + "color-background-alert-warning": "#fffef0", "color-background-avatar-default": "#545b64", "color-background-avatar-gen-ai": "radial-gradient(circle farthest-corner at top right, #b8e7ff 0%, #0099ff 25%, #5c7fff 40% , #8575ff 60%, #962eff 80%)", "color-background-backdrop": "rgba(242, 243, 243, 0.9)", @@ -174,7 +178,9 @@ exports[`CSS Custom Properties match previous snapshot for mode "compact" 1`] = "color-background-notification-yellow": "#ffe347", "color-background-popover": "#ffffff", "color-background-progress-bar-default": "#eaeded", + "color-background-progress-bar-flash": "#eaeded", "color-background-progress-bar-value-default": "#0073bb", + "color-background-progress-bar-value-flash": "#0073bb", "color-background-segment-active": "#0073bb", "color-background-segment-default": "#ffffff", "color-background-segment-disabled": "#ffffff", @@ -570,6 +576,11 @@ exports[`CSS Custom Properties match previous snapshot for mode "compact" 1`] = "color-success-950": "#003311", "color-text-accent": "#0073bb", "color-text-action-card-disabled": "#879596", + "color-text-alert-default": "#16191f", + "color-text-alert-icon-error": "#d13212", + "color-text-alert-icon-info": "#0073bb", + "color-text-alert-icon-success": "#1d8102", + "color-text-alert-icon-warning": "#906806", "color-text-avatar": "#ffffff", "color-text-badge-blue": "#fafafa", "color-text-badge-green": "#fafafa", @@ -632,6 +643,10 @@ exports[`CSS Custom Properties match previous snapshot for mode "compact" 1`] = "color-text-expandable-section-default": "#545b64", "color-text-expandable-section-hover": "#16191f", "color-text-expandable-section-navigation-icon-default": "#879596", + "color-text-flashbar-icon-error": "#d13212", + "color-text-flashbar-icon-info": "#0073bb", + "color-text-flashbar-icon-success": "#1d8102", + "color-text-flashbar-icon-warning": "#906806", "color-text-form-default": "#16191f", "color-text-form-label": "#16191f", "color-text-form-secondary": "#687078", @@ -1067,6 +1082,10 @@ exports[`CSS Custom Properties match previous snapshot for mode "dark" 1`] = ` "color-background-action-card-default": "#1a2029", "color-background-action-card-disabled": "#21252c", "color-background-action-card-hover": "#21252c", + "color-background-alert-error": "#270a11", + "color-background-alert-info": "#12293b", + "color-background-alert-success": "#172211", + "color-background-alert-warning": "#191100", "color-background-avatar-default": "#545b64", "color-background-avatar-gen-ai": "radial-gradient(circle farthest-corner at top right, #b8e7ff 0%, #0099ff 25%, #5c7fff 40% , #8575ff 60%, #962eff 80%)", "color-background-backdrop": "rgba(22, 25, 31, 0.8)", @@ -1157,7 +1176,9 @@ exports[`CSS Custom Properties match previous snapshot for mode "dark" 1`] = ` "color-background-notification-yellow": "#ffe347", "color-background-popover": "#21252c", "color-background-progress-bar-default": "#414750", + "color-background-progress-bar-flash": "#414750", "color-background-progress-bar-value-default": "#00a1c9", + "color-background-progress-bar-value-flash": "#00a1c9", "color-background-segment-active": "#00a1c9", "color-background-segment-default": "#2a2e33", "color-background-segment-disabled": "#2a2e33", @@ -1553,6 +1574,11 @@ exports[`CSS Custom Properties match previous snapshot for mode "dark" 1`] = ` "color-success-950": "#003311", "color-text-accent": "#44b9d6", "color-text-action-card-disabled": "#879596", + "color-text-alert-default": "#d5dbdb", + "color-text-alert-icon-error": "#ff5d64", + "color-text-alert-icon-info": "#44b9d6", + "color-text-alert-icon-success": "#6aaf35", + "color-text-alert-icon-warning": "#fbd332", "color-text-avatar": "#ffffff", "color-text-badge-blue": "#fafafa", "color-text-badge-green": "#fafafa", @@ -1615,6 +1641,10 @@ exports[`CSS Custom Properties match previous snapshot for mode "dark" 1`] = ` "color-text-expandable-section-default": "#d5dbdb", "color-text-expandable-section-hover": "#fafafa", "color-text-expandable-section-navigation-icon-default": "#95a5a6", + "color-text-flashbar-icon-error": "#ff5d64", + "color-text-flashbar-icon-info": "#44b9d6", + "color-text-flashbar-icon-success": "#6aaf35", + "color-text-flashbar-icon-warning": "#fbd332", "color-text-form-default": "#d5dbdb", "color-text-form-label": "#d5dbdb", "color-text-form-secondary": "#95a5a6", @@ -2050,6 +2080,10 @@ exports[`CSS Custom Properties match previous snapshot for mode "light" 1`] = ` "color-background-action-card-default": "#ffffff", "color-background-action-card-disabled": "#eaeded", "color-background-action-card-hover": "#f1faff", + "color-background-alert-error": "#fdf3f1", + "color-background-alert-info": "#f1faff", + "color-background-alert-success": "#f2f8f0", + "color-background-alert-warning": "#fffef0", "color-background-avatar-default": "#545b64", "color-background-avatar-gen-ai": "radial-gradient(circle farthest-corner at top right, #b8e7ff 0%, #0099ff 25%, #5c7fff 40% , #8575ff 60%, #962eff 80%)", "color-background-backdrop": "rgba(242, 243, 243, 0.9)", @@ -2140,7 +2174,9 @@ exports[`CSS Custom Properties match previous snapshot for mode "light" 1`] = ` "color-background-notification-yellow": "#ffe347", "color-background-popover": "#ffffff", "color-background-progress-bar-default": "#eaeded", + "color-background-progress-bar-flash": "#eaeded", "color-background-progress-bar-value-default": "#0073bb", + "color-background-progress-bar-value-flash": "#0073bb", "color-background-segment-active": "#0073bb", "color-background-segment-default": "#ffffff", "color-background-segment-disabled": "#ffffff", @@ -2536,6 +2572,11 @@ exports[`CSS Custom Properties match previous snapshot for mode "light" 1`] = ` "color-success-950": "#003311", "color-text-accent": "#0073bb", "color-text-action-card-disabled": "#879596", + "color-text-alert-default": "#16191f", + "color-text-alert-icon-error": "#d13212", + "color-text-alert-icon-info": "#0073bb", + "color-text-alert-icon-success": "#1d8102", + "color-text-alert-icon-warning": "#906806", "color-text-avatar": "#ffffff", "color-text-badge-blue": "#fafafa", "color-text-badge-green": "#fafafa", @@ -2598,6 +2639,10 @@ exports[`CSS Custom Properties match previous snapshot for mode "light" 1`] = ` "color-text-expandable-section-default": "#545b64", "color-text-expandable-section-hover": "#16191f", "color-text-expandable-section-navigation-icon-default": "#879596", + "color-text-flashbar-icon-error": "#d13212", + "color-text-flashbar-icon-info": "#0073bb", + "color-text-flashbar-icon-success": "#1d8102", + "color-text-flashbar-icon-warning": "#906806", "color-text-form-default": "#16191f", "color-text-form-label": "#16191f", "color-text-form-secondary": "#687078", @@ -3033,6 +3078,10 @@ exports[`CSS Custom Properties match previous snapshot for mode "reduced-motion" "color-background-action-card-default": "#ffffff", "color-background-action-card-disabled": "#eaeded", "color-background-action-card-hover": "#f1faff", + "color-background-alert-error": "#fdf3f1", + "color-background-alert-info": "#f1faff", + "color-background-alert-success": "#f2f8f0", + "color-background-alert-warning": "#fffef0", "color-background-avatar-default": "#545b64", "color-background-avatar-gen-ai": "radial-gradient(circle farthest-corner at top right, #b8e7ff 0%, #0099ff 25%, #5c7fff 40% , #8575ff 60%, #962eff 80%)", "color-background-backdrop": "rgba(242, 243, 243, 0.9)", @@ -3123,7 +3172,9 @@ exports[`CSS Custom Properties match previous snapshot for mode "reduced-motion" "color-background-notification-yellow": "#ffe347", "color-background-popover": "#ffffff", "color-background-progress-bar-default": "#eaeded", + "color-background-progress-bar-flash": "#eaeded", "color-background-progress-bar-value-default": "#0073bb", + "color-background-progress-bar-value-flash": "#0073bb", "color-background-segment-active": "#0073bb", "color-background-segment-default": "#ffffff", "color-background-segment-disabled": "#ffffff", @@ -3519,6 +3570,11 @@ exports[`CSS Custom Properties match previous snapshot for mode "reduced-motion" "color-success-950": "#003311", "color-text-accent": "#0073bb", "color-text-action-card-disabled": "#879596", + "color-text-alert-default": "#16191f", + "color-text-alert-icon-error": "#d13212", + "color-text-alert-icon-info": "#0073bb", + "color-text-alert-icon-success": "#1d8102", + "color-text-alert-icon-warning": "#906806", "color-text-avatar": "#ffffff", "color-text-badge-blue": "#fafafa", "color-text-badge-green": "#fafafa", @@ -3581,6 +3637,10 @@ exports[`CSS Custom Properties match previous snapshot for mode "reduced-motion" "color-text-expandable-section-default": "#545b64", "color-text-expandable-section-hover": "#16191f", "color-text-expandable-section-navigation-icon-default": "#879596", + "color-text-flashbar-icon-error": "#d13212", + "color-text-flashbar-icon-info": "#0073bb", + "color-text-flashbar-icon-success": "#1d8102", + "color-text-flashbar-icon-warning": "#906806", "color-text-form-default": "#16191f", "color-text-form-label": "#16191f", "color-text-form-secondary": "#687078", @@ -4016,6 +4076,10 @@ exports[`CSS Custom Properties match previous snapshot for mode "visual-refresh" "color-background-action-card-default": "#ffffff", "color-background-action-card-disabled": "#ffffff", "color-background-action-card-hover": "#f0fbff", + "color-background-alert-error": "#fff5f5", + "color-background-alert-info": "#f0fbff", + "color-background-alert-success": "#effff1", + "color-background-alert-warning": "#fffef0", "color-background-avatar-default": "#424650", "color-background-avatar-gen-ai": "radial-gradient(circle farthest-corner at top right, #b8e7ff 0%, #0099ff 25%, #5c7fff 40% , #8575ff 60%, #962eff 80%)", "color-background-backdrop": "rgba(35, 43, 55, 0.7)", @@ -4106,7 +4170,9 @@ exports[`CSS Custom Properties match previous snapshot for mode "visual-refresh" "color-background-notification-yellow": "#ffe347", "color-background-popover": "#ffffff", "color-background-progress-bar-default": "#ebebf0", + "color-background-progress-bar-flash": "#ebebf0", "color-background-progress-bar-value-default": "#006ce0", + "color-background-progress-bar-value-flash": "#006ce0", "color-background-segment-active": "#006ce0", "color-background-segment-default": "#ffffff", "color-background-segment-disabled": "#ffffff", @@ -4502,6 +4568,11 @@ exports[`CSS Custom Properties match previous snapshot for mode "visual-refresh" "color-success-950": "#003311", "color-text-accent": "#006ce0", "color-text-action-card-disabled": "#8c8c94", + "color-text-alert-default": "#0f141a", + "color-text-alert-icon-error": "#db0000", + "color-text-alert-icon-info": "#006ce0", + "color-text-alert-icon-success": "#00802f", + "color-text-alert-icon-warning": "#855900", "color-text-avatar": "#ffffff", "color-text-badge-blue": "#f9f9fa", "color-text-badge-green": "#f9f9fa", @@ -4564,6 +4635,10 @@ exports[`CSS Custom Properties match previous snapshot for mode "visual-refresh" "color-text-expandable-section-default": "#0f141a", "color-text-expandable-section-hover": "#006ce0", "color-text-expandable-section-navigation-icon-default": "#424650", + "color-text-flashbar-icon-error": "#db0000", + "color-text-flashbar-icon-info": "#006ce0", + "color-text-flashbar-icon-success": "#00802f", + "color-text-flashbar-icon-warning": "#855900", "color-text-form-default": "#0f141a", "color-text-form-label": "#0f141a", "color-text-form-secondary": "#656871", @@ -4999,6 +5074,10 @@ exports[`CSS Custom Properties match previous snapshot for mode "visual-refresh- "color-background-action-card-default": "#ffffff", "color-background-action-card-disabled": "#ffffff", "color-background-action-card-hover": "#f0fbff", + "color-background-alert-error": "#fff5f5", + "color-background-alert-info": "#f0fbff", + "color-background-alert-success": "#effff1", + "color-background-alert-warning": "#fffef0", "color-background-avatar-default": "#424650", "color-background-avatar-gen-ai": "radial-gradient(circle farthest-corner at top right, #b8e7ff 0%, #0099ff 25%, #5c7fff 40% , #8575ff 60%, #962eff 80%)", "color-background-backdrop": "rgba(35, 43, 55, 0.7)", @@ -5089,7 +5168,9 @@ exports[`CSS Custom Properties match previous snapshot for mode "visual-refresh- "color-background-notification-yellow": "#ffe347", "color-background-popover": "#ffffff", "color-background-progress-bar-default": "#ebebf0", + "color-background-progress-bar-flash": "#ebebf0", "color-background-progress-bar-value-default": "#006ce0", + "color-background-progress-bar-value-flash": "#006ce0", "color-background-segment-active": "#006ce0", "color-background-segment-default": "#ffffff", "color-background-segment-disabled": "#ffffff", @@ -5485,6 +5566,11 @@ exports[`CSS Custom Properties match previous snapshot for mode "visual-refresh- "color-success-950": "#003311", "color-text-accent": "#006ce0", "color-text-action-card-disabled": "#8c8c94", + "color-text-alert-default": "#0f141a", + "color-text-alert-icon-error": "#db0000", + "color-text-alert-icon-info": "#006ce0", + "color-text-alert-icon-success": "#00802f", + "color-text-alert-icon-warning": "#855900", "color-text-avatar": "#ffffff", "color-text-badge-blue": "#f9f9fa", "color-text-badge-green": "#f9f9fa", @@ -5547,6 +5633,10 @@ exports[`CSS Custom Properties match previous snapshot for mode "visual-refresh- "color-text-expandable-section-default": "#0f141a", "color-text-expandable-section-hover": "#006ce0", "color-text-expandable-section-navigation-icon-default": "#424650", + "color-text-flashbar-icon-error": "#db0000", + "color-text-flashbar-icon-info": "#006ce0", + "color-text-flashbar-icon-success": "#00802f", + "color-text-flashbar-icon-warning": "#855900", "color-text-form-default": "#0f141a", "color-text-form-label": "#0f141a", "color-text-form-secondary": "#656871", @@ -5982,6 +6072,10 @@ exports[`CSS Custom Properties match previous snapshot for mode "visual-refresh- "color-background-action-card-default": "#161d26", "color-background-action-card-disabled": "#161d26", "color-background-action-card-hover": "#1b232d", + "color-background-alert-error": "#1f0000", + "color-background-alert-info": "#001129", + "color-background-alert-success": "#001401", + "color-background-alert-warning": "#191100", "color-background-avatar-default": "#424650", "color-background-avatar-gen-ai": "radial-gradient(circle farthest-corner at top right, #b8e7ff 0%, #0099ff 25%, #5c7fff 40% , #8575ff 60%, #962eff 80%)", "color-background-backdrop": "rgba(15, 20, 26, 0.7)", @@ -6072,7 +6166,9 @@ exports[`CSS Custom Properties match previous snapshot for mode "visual-refresh- "color-background-notification-yellow": "#ffe347", "color-background-popover": "#1b232d", "color-background-progress-bar-default": "#333843", + "color-background-progress-bar-flash": "#333843", "color-background-progress-bar-value-default": "#42b4ff", + "color-background-progress-bar-value-flash": "#42b4ff", "color-background-segment-active": "#42b4ff", "color-background-segment-default": "#0f141a", "color-background-segment-disabled": "#0f141a", @@ -6468,6 +6564,11 @@ exports[`CSS Custom Properties match previous snapshot for mode "visual-refresh- "color-success-950": "#003311", "color-text-accent": "#42b4ff", "color-text-action-card-disabled": "#8c8c94", + "color-text-alert-default": "#c6c6cd", + "color-text-alert-icon-error": "#ff7a7a", + "color-text-alert-icon-info": "#42b4ff", + "color-text-alert-icon-success": "#2bb534", + "color-text-alert-icon-warning": "#fbd332", "color-text-avatar": "#ffffff", "color-text-badge-blue": "#f9f9fa", "color-text-badge-green": "#f9f9fa", @@ -6530,6 +6631,10 @@ exports[`CSS Custom Properties match previous snapshot for mode "visual-refresh- "color-text-expandable-section-default": "#dedee3", "color-text-expandable-section-hover": "#42b4ff", "color-text-expandable-section-navigation-icon-default": "#dedee3", + "color-text-flashbar-icon-error": "#ff7a7a", + "color-text-flashbar-icon-info": "#42b4ff", + "color-text-flashbar-icon-success": "#2bb534", + "color-text-flashbar-icon-warning": "#fbd332", "color-text-form-default": "#dedee3", "color-text-form-label": "#dedee3", "color-text-form-secondary": "#a4a4ad", @@ -6965,6 +7070,10 @@ exports[`CSS Custom Properties match previous snapshot for mode "visual-refresh- "color-background-action-card-default": "#161d26", "color-background-action-card-disabled": "#161d26", "color-background-action-card-hover": "#1b232d", + "color-background-alert-error": "#1f0000", + "color-background-alert-info": "#001129", + "color-background-alert-success": "#001401", + "color-background-alert-warning": "#191100", "color-background-avatar-default": "#424650", "color-background-avatar-gen-ai": "radial-gradient(circle farthest-corner at top right, #b8e7ff 0%, #0099ff 25%, #5c7fff 40% , #8575ff 60%, #962eff 80%)", "color-background-backdrop": "rgba(15, 20, 26, 0.7)", @@ -7055,7 +7164,9 @@ exports[`CSS Custom Properties match previous snapshot for mode "visual-refresh- "color-background-notification-yellow": "#ffe347", "color-background-popover": "#1b232d", "color-background-progress-bar-default": "#333843", + "color-background-progress-bar-flash": "#333843", "color-background-progress-bar-value-default": "#42b4ff", + "color-background-progress-bar-value-flash": "#42b4ff", "color-background-segment-active": "#42b4ff", "color-background-segment-default": "#161d26", "color-background-segment-disabled": "#161d26", @@ -7451,6 +7562,11 @@ exports[`CSS Custom Properties match previous snapshot for mode "visual-refresh- "color-success-950": "#003311", "color-text-accent": "#42b4ff", "color-text-action-card-disabled": "#8c8c94", + "color-text-alert-default": "#c6c6cd", + "color-text-alert-icon-error": "#ff7a7a", + "color-text-alert-icon-info": "#42b4ff", + "color-text-alert-icon-success": "#2bb534", + "color-text-alert-icon-warning": "#fbd332", "color-text-avatar": "#ffffff", "color-text-badge-blue": "#f9f9fa", "color-text-badge-green": "#f9f9fa", @@ -7513,6 +7629,10 @@ exports[`CSS Custom Properties match previous snapshot for mode "visual-refresh- "color-text-expandable-section-default": "#dedee3", "color-text-expandable-section-hover": "#42b4ff", "color-text-expandable-section-navigation-icon-default": "#dedee3", + "color-text-flashbar-icon-error": "#ff7a7a", + "color-text-flashbar-icon-info": "#42b4ff", + "color-text-flashbar-icon-success": "#2bb534", + "color-text-flashbar-icon-warning": "#fbd332", "color-text-form-default": "#dedee3", "color-text-form-label": "#dedee3", "color-text-form-secondary": "#a4a4ad", diff --git a/src/alert/styles.scss b/src/alert/styles.scss index c0c7d11f99..0cb3e3bc5f 100644 --- a/src/alert/styles.scss +++ b/src/alert/styles.scss @@ -24,6 +24,7 @@ .alert { @include styles.styles-reset; + color: awsui.$color-text-alert-default; position: relative; display: flex; flex-direction: row; @@ -144,17 +145,17 @@ $_border-colors: ( ); $_background-colors: ( - 'error': awsui.$color-background-status-error, - 'warning': awsui.$color-background-status-warning, - 'success': awsui.$color-background-status-success, - 'info': awsui.$color-background-status-info, + 'error': awsui.$color-background-alert-error, + 'warning': awsui.$color-background-alert-warning, + 'success': awsui.$color-background-alert-success, + 'info': awsui.$color-background-alert-info, ); $_text-colors: ( - 'error': awsui.$color-text-status-error, - 'warning': awsui.$color-text-status-warning, - 'success': awsui.$color-text-status-success, - 'info': awsui.$color-text-status-info, + 'error': awsui.$color-text-alert-icon-error, + 'warning': awsui.$color-text-alert-icon-warning, + 'success': awsui.$color-text-alert-icon-success, + 'info': awsui.$color-text-alert-icon-info, ); @each $type in map.keys($_text-colors) { diff --git a/src/flashbar/flash.tsx b/src/flashbar/flash.tsx index 867a3a57b4..c97eb43cc9 100644 --- a/src/flashbar/flash.tsx +++ b/src/flashbar/flash.tsx @@ -224,6 +224,10 @@ export const Flash = React.forwardRef( [styles.exiting]: transitionState === 'exiting', [styles.exited]: transitionState === 'exited', }, + // The separate flashbar-warning context exists for VR, where warning + // flashes have a light background and dark text. One Theme does not + // need this context. We don't want to add a isOneTheme check here so + // we still set the flashbar-warning context for One Theme. getVisualContextClassname(type === 'warning' && !loading ? 'flashbar-warning' : 'flashbar'), initialHidden && styles['initial-hidden'] )} diff --git a/src/flashbar/styles.scss b/src/flashbar/styles.scss index 4f21d78443..788854ea25 100644 --- a/src/flashbar/styles.scss +++ b/src/flashbar/styles.scss @@ -151,7 +151,7 @@ border-inline-start-color: awsui.$color-border-status-success; > .flash-body > .flash-focus-container > .flash-icon { - color: awsui.$color-text-status-success; + color: awsui.$color-text-flashbar-icon-success; } } @@ -160,7 +160,7 @@ border-inline-start-color: awsui.$color-border-status-error; > .flash-body > .flash-focus-container > .flash-icon { - color: awsui.$color-text-status-error; + color: awsui.$color-text-flashbar-icon-error; } } @@ -170,7 +170,7 @@ border-inline-start-color: awsui.$color-border-status-info; > .flash-body > .flash-focus-container > .flash-icon { - color: awsui.$color-text-status-info; + color: awsui.$color-text-flashbar-icon-info; } } @@ -180,6 +180,6 @@ border-inline-start-color: awsui.$color-border-status-warning; > .flash-body > .flash-focus-container > .flash-icon { - color: awsui.$color-text-status-warning; + color: awsui.$color-text-flashbar-icon-warning; } } diff --git a/src/progress-bar/internal.tsx b/src/progress-bar/internal.tsx index c8c0cec3d4..f8a0c785a8 100644 --- a/src/progress-bar/internal.tsx +++ b/src/progress-bar/internal.tsx @@ -39,7 +39,11 @@ export const Progress = ({ value, isInFlash, ariaLabel, ariaLabelledby, ariaDesc return (
= MAX_VALUE && styles.complete)} + className={clsx( + styles.progress, + progressValue >= MAX_VALUE && styles.complete, + isInFlash && styles['progress-flash'] + )} max={MAX_VALUE} value={progressValue} aria-label={ariaLabel} diff --git a/src/progress-bar/styles.scss b/src/progress-bar/styles.scss index bbb99c06ae..49bd3e65c1 100644 --- a/src/progress-bar/styles.scss +++ b/src/progress-bar/styles.scss @@ -129,6 +129,26 @@ $progress-value-background-color: var( @include general-progress-bar-style; background-color: $progress-value-background-color; } + + &.progress-flash { + background-color: var(#{custom-props.$progressBarBackgroundColor}, awsui.$color-background-progress-bar-flash); + + &::-webkit-progress-bar { + background-color: var(#{custom-props.$progressBarBackgroundColor}, awsui.$color-background-progress-bar-flash); + } + &::-webkit-progress-value { + background-color: var( + #{custom-props.$progressValueBackgroundColor}, + awsui.$color-background-progress-bar-value-flash + ); + } + &::-moz-progress-bar { + background-color: var( + #{custom-props.$progressValueBackgroundColor}, + awsui.$color-background-progress-bar-value-flash + ); + } + } } .additional-info { diff --git a/style-dictionary/utils/token-names.ts b/style-dictionary/utils/token-names.ts index a8f47b0c37..783230ac94 100644 --- a/style-dictionary/utils/token-names.ts +++ b/style-dictionary/utils/token-names.ts @@ -626,6 +626,8 @@ export type ColorsTokenName = | 'colorBackgroundVisualAccentAmber' | 'colorBackgroundPopover' | 'colorBackgroundProgressBarValueDefault' + | 'colorBackgroundProgressBarValueFlash' + | 'colorBackgroundProgressBarFlash' | 'colorBackgroundProgressBarDefault' | 'colorBackgroundSegmentActive' | 'colorBackgroundSegmentDefault' @@ -648,6 +650,10 @@ export type ColorsTokenName = | 'colorBackgroundSliderRangeErrorActive' | 'colorBackgroundSliderRangeWarningDefault' | 'colorBackgroundSliderRangeWarningActive' + | 'colorBackgroundAlertError' + | 'colorBackgroundAlertInfo' + | 'colorBackgroundAlertSuccess' + | 'colorBackgroundAlertWarning' | 'colorBackgroundStatusError' | 'colorBackgroundStatusInfo' | 'colorBackgroundDialog' @@ -814,6 +820,10 @@ export type ColorsTokenName = | 'colorTextExpandableSectionDefault' | 'colorTextExpandableSectionHover' | 'colorTextExpandableSectionNavigationIconDefault' + | 'colorTextFlashbarIconError' + | 'colorTextFlashbarIconInfo' + | 'colorTextFlashbarIconSuccess' + | 'colorTextFlashbarIconWarning' | 'colorBorderExpandableSectionDefault' | 'colorTextFormDefault' | 'colorTextFormLabel' @@ -860,6 +870,11 @@ export type ColorsTokenName = | 'colorTextLinkInfoHover' | 'colorTextLinkInvertedHover' | 'colorTextNotificationDefault' + | 'colorTextAlertDefault' + | 'colorTextAlertIconError' + | 'colorTextAlertIconInfo' + | 'colorTextAlertIconSuccess' + | 'colorTextAlertIconWarning' | 'colorTextNotificationStackBar' | 'colorTextNotificationYellow' | 'colorTextPaginationPageNumberActiveDisabled' diff --git a/style-dictionary/visual-refresh/colors.ts b/style-dictionary/visual-refresh/colors.ts index 6407e35c88..ccf6ea225f 100644 --- a/style-dictionary/visual-refresh/colors.ts +++ b/style-dictionary/visual-refresh/colors.ts @@ -96,6 +96,8 @@ const tokens: StyleDictionary.ColorsDictionary = { colorBackgroundNotificationStackBarHover: '{colorNeutral650}', colorBackgroundPopover: { light: '{colorWhite}', dark: '{colorNeutral800}' }, colorBackgroundProgressBarValueDefault: { light: '{colorPrimary600}', dark: '{colorPrimary400}' }, + colorBackgroundProgressBarValueFlash: '{colorBackgroundProgressBarValueDefault}', + colorBackgroundProgressBarFlash: '{colorBackgroundProgressBarDefault}', colorBackgroundProgressBarDefault: { light: '{colorNeutral250}', dark: '{colorNeutral700}' }, colorBackgroundSegmentActive: { light: '{colorPrimary600}', dark: '{colorPrimary400}' }, colorBackgroundSegmentDefault: '{colorBackgroundButtonNormalDefault}', @@ -118,6 +120,10 @@ const tokens: StyleDictionary.ColorsDictionary = { colorBackgroundSliderRangeWarningActive: '{colorTextStatusWarning}', colorBackgroundStatusError: { light: '{colorError50}', dark: '{colorError1000}' }, colorBackgroundStatusInfo: { light: '{colorInfo50}', dark: '{colorInfo1000}' }, + colorBackgroundAlertError: '{colorBackgroundStatusError}', + colorBackgroundAlertInfo: '{colorBackgroundStatusInfo}', + colorBackgroundAlertSuccess: '{colorBackgroundStatusSuccess}', + colorBackgroundAlertWarning: '{colorBackgroundStatusWarning}', colorBackgroundDialog: '{colorBackgroundStatusInfo}', colorBackgroundStatusSuccess: { light: '{colorSuccess50}', dark: '{colorSuccess1000}' }, colorBackgroundStatusWarning: { light: '{colorWarning50}', dark: '{colorWarning1000}' }, @@ -318,6 +324,7 @@ const tokens: StyleDictionary.ColorsDictionary = { colorTextLinkButtonUnderline: 'transparent', colorTextLinkButtonUnderlineHover: 'transparent', colorTextNotificationDefault: '{colorNeutral100}', + colorTextAlertDefault: '{colorTextBodyDefault}', colorTextNotificationStackBar: '{colorWhite}', colorTextNotificationYellow: '{colorNeutral950}', colorTextPaginationPageNumberActiveDisabled: '{colorTextInteractiveDisabled}', @@ -326,6 +333,14 @@ const tokens: StyleDictionary.ColorsDictionary = { colorTextSegmentDefault: { light: '{colorNeutral650}', dark: '{colorNeutral300}' }, colorTextSegmentHover: '{colorTextButtonNormalHover}', colorTextSmall: { light: '{colorNeutral600}', dark: '{colorNeutral450}' }, + colorTextFlashbarIconError: '{colorTextStatusError}', + colorTextFlashbarIconInfo: '{colorTextStatusInfo}', + colorTextFlashbarIconSuccess: '{colorTextStatusSuccess}', + colorTextFlashbarIconWarning: '{colorTextStatusWarning}', + colorTextAlertIconError: '{colorTextStatusError}', + colorTextAlertIconInfo: '{colorTextStatusInfo}', + colorTextAlertIconSuccess: '{colorTextStatusSuccess}', + colorTextAlertIconWarning: '{colorTextStatusWarning}', colorTextStatusError: { light: '{colorError600}', dark: '{colorError400}' }, colorTextStatusInactive: { light: '{colorNeutral600}', dark: '{colorNeutral450}' }, colorTextStatusInfo: { light: '{colorInfo600}', dark: '{colorInfo400}' }, diff --git a/style-dictionary/visual-refresh/metadata/colors.ts b/style-dictionary/visual-refresh/metadata/colors.ts index d4c924a4b2..e26eb817f5 100644 --- a/style-dictionary/visual-refresh/metadata/colors.ts +++ b/style-dictionary/visual-refresh/metadata/colors.ts @@ -261,6 +261,26 @@ const metadata: StyleDictionary.MetadataIndex = { public: true, themeable: true, }, + colorBackgroundAlertError: { + description: 'The background color of error alerts.', + public: false, + themeable: false, + }, + colorBackgroundAlertInfo: { + description: 'The background color of info alerts.', + public: false, + themeable: false, + }, + colorBackgroundAlertSuccess: { + description: 'The background color of success alerts.', + public: false, + themeable: false, + }, + colorBackgroundAlertWarning: { + description: 'The background color of warning alerts.', + public: false, + themeable: false, + }, colorBackgroundFlashbarError: { description: 'The background color of error flash messages.', public: true, @@ -431,6 +451,16 @@ const metadata: StyleDictionary.MetadataIndex = { public: true, themeable: true, }, + colorBackgroundProgressBarValueFlash: { + description: 'The background color of the progress bar value inside flash messages.', + public: false, + themeable: false, + }, + colorBackgroundProgressBarFlash: { + description: 'The background color of the progress bar track inside flash messages.', + public: false, + themeable: false, + }, colorBackgroundProgressBarDefault: { description: 'The default background color of the progress bar.', public: true, @@ -1018,6 +1048,26 @@ const metadata: StyleDictionary.MetadataIndex = { public: true, themeable: true, }, + colorTextFlashbarIconError: { + description: 'The icon color inside error flash messages.', + public: false, + themeable: false, + }, + colorTextFlashbarIconInfo: { + description: 'The icon color inside info and in-progress flash messages.', + public: false, + themeable: false, + }, + colorTextFlashbarIconSuccess: { + description: 'The icon color inside success flash messages.', + public: false, + themeable: false, + }, + colorTextFlashbarIconWarning: { + description: 'The icon color inside warning flash messages.', + public: false, + themeable: false, + }, colorTextFormDefault: { description: 'The default color of form field labels and values. For example: the label in form fields, checkboxes, radio buttons, toggles, and the value in inputs and text areas.', @@ -1198,6 +1248,31 @@ const metadata: StyleDictionary.MetadataIndex = { public: true, themeable: true, }, + colorTextAlertDefault: { + description: 'Default text color inside alerts.', + public: false, + themeable: false, + }, + colorTextAlertIconError: { + description: 'The icon color inside error alerts.', + public: false, + themeable: false, + }, + colorTextAlertIconInfo: { + description: 'The icon color inside info alerts.', + public: false, + themeable: false, + }, + colorTextAlertIconSuccess: { + description: 'The icon color inside success alerts.', + public: false, + themeable: false, + }, + colorTextAlertIconWarning: { + description: 'The icon color inside warning alerts.', + public: false, + themeable: false, + }, colorTextNotificationYellow: { description: 'The text and foreground color used on warning flash messages (yellow notification surface).', public: true, From 6d1c02b503d796238d129ca666b8183bf85fe1ca Mon Sep 17 00:00:00 2001 From: Maximilian Schoell Date: Thu, 6 Aug 2026 13:37:37 +0200 Subject: [PATCH 2/9] refactor: remove notification contexts from one theme --- .../content-header-notifications.page.tsx | 29 +++++++++ .../notifications-permutations.tsx | 59 ++++++++++++++++++ .../top-navigation-notifications.page.tsx | 29 +++++++++ style-dictionary/classic/index.ts | 14 ++++- style-dictionary/one-theme/colors.ts | 21 ++++++- style-dictionary/one-theme/contexts/alert.ts | 52 ---------------- .../one-theme/contexts/flashbar-warning.ts | 61 ------------------- .../one-theme/contexts/flashbar.ts | 60 ------------------ .../contexts/notification-controls.ts | 30 +++++++++ .../one-theme/contexts/top-navigation.ts | 4 +- style-dictionary/one-theme/index.ts | 12 ++-- style-dictionary/utils/contexts.ts | 11 ++++ style-dictionary/visual-refresh/index.ts | 18 ++++-- 13 files changed, 211 insertions(+), 189 deletions(-) create mode 100644 pages/visual-contexts/content-header-notifications.page.tsx create mode 100644 pages/visual-contexts/notifications-permutations.tsx create mode 100644 pages/visual-contexts/top-navigation-notifications.page.tsx delete mode 100644 style-dictionary/one-theme/contexts/alert.ts delete mode 100644 style-dictionary/one-theme/contexts/flashbar-warning.ts delete mode 100644 style-dictionary/one-theme/contexts/flashbar.ts create mode 100644 style-dictionary/one-theme/contexts/notification-controls.ts diff --git a/pages/visual-contexts/content-header-notifications.page.tsx b/pages/visual-contexts/content-header-notifications.page.tsx new file mode 100644 index 0000000000..6a3212a0a1 --- /dev/null +++ b/pages/visual-contexts/content-header-notifications.page.tsx @@ -0,0 +1,29 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +import React from 'react'; + +import Box from '~components/box'; +import VisualContext from '~components/internal/components/visual-context'; +import SpaceBetween from '~components/space-between'; + +import PermutationsView from '../utils/permutations-view'; +import ScreenshotArea from '../utils/screenshot-area'; +import { alertPermutations, flashbarPermutations, renderAlert, renderFlashbar } from './notifications-permutations'; + +import styles from './styles.scss'; + +export default function ContentHeaderNotificationsPermutations() { + return ( + + + + + Notifications in content-header visual context + + + + + + + ); +} diff --git a/pages/visual-contexts/notifications-permutations.tsx b/pages/visual-contexts/notifications-permutations.tsx new file mode 100644 index 0000000000..559148879d --- /dev/null +++ b/pages/visual-contexts/notifications-permutations.tsx @@ -0,0 +1,59 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +import React from 'react'; + +import Alert, { AlertProps } from '~components/alert'; +import Button from '~components/button'; +import Flashbar, { FlashbarProps } from '~components/flashbar'; +import Link from '~components/link'; + +import createPermutations from '../utils/permutations'; + +const noop = () => void 0; + +const types = ['info', 'success', 'warning', 'error'] as const; + +/* eslint-disable react/jsx-key */ +export const flashbarPermutations = createPermutations([ + { + type: [...types], + header: ['Flash header'], + content: [ + + Flash message with a{' '} + + link + + , + ], + action: [], + dismissible: [true], + dismissLabel: ['Dismiss'], + onDismiss: [noop], + }, +]); + +export const alertPermutations = createPermutations([ + { + type: [...types], + header: ['Alert header'], + children: [ + + Alert message with a link + , + ], + action: [], + dismissible: [true], + dismissAriaLabel: ['Dismiss'], + onDismiss: [noop], + }, +]); +/* eslint-enable react/jsx-key */ + +export function renderFlashbar(permutation: FlashbarProps.MessageDefinition) { + return ; +} + +export function renderAlert(permutation: AlertProps) { + return ; +} diff --git a/pages/visual-contexts/top-navigation-notifications.page.tsx b/pages/visual-contexts/top-navigation-notifications.page.tsx new file mode 100644 index 0000000000..cac2c00614 --- /dev/null +++ b/pages/visual-contexts/top-navigation-notifications.page.tsx @@ -0,0 +1,29 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +import React from 'react'; + +import Box from '~components/box'; +import VisualContext from '~components/internal/components/visual-context'; +import SpaceBetween from '~components/space-between'; + +import PermutationsView from '../utils/permutations-view'; +import ScreenshotArea from '../utils/screenshot-area'; +import { alertPermutations, flashbarPermutations, renderAlert, renderFlashbar } from './notifications-permutations'; + +import styles from './styles.scss'; + +export default function TopNavigationNotificationsPermutations() { + return ( + + + + + Notifications in top-navigation visual context + + + + + + + ); +} diff --git a/style-dictionary/classic/index.ts b/style-dictionary/classic/index.ts index e572b59768..d4c5e387c6 100644 --- a/style-dictionary/classic/index.ts +++ b/style-dictionary/classic/index.ts @@ -9,6 +9,7 @@ import { createFlashbarContext, createFlashbarWarningContext, createTopNavigationContext, + excludeOneTheme, } from '../utils/contexts.js'; import { StyleDictionary } from '../utils/interfaces.js'; import { createColorMode, createDensityMode, createMotionMode } from '../utils/modes.js'; @@ -43,13 +44,20 @@ export async function buildClassicOpenSource(builder: ThemeBuilder) { builder.addContext(createCompactTableContext((await import('./contexts/compact-table.js')).tokens)); builder.addContext(createTopNavigationContext((await import('./contexts/top-navigation.js')).tokens)); - builder.addContext(createFlashbarContext((await import('./contexts/flashbar.js')).tokens)); - builder.addContext(createFlashbarWarningContext((await import('./contexts/flashbar-warning.js')).tokens)); - builder.addContext(createAlertContext((await import('./contexts/alert.js')).tokens)); builder.addContext( createAppLayoutToolsDrawerTriggerContext((await import('./contexts/tools-drawer-trigger.js')).tokens) ); + // One theme styles notifications through base tokens and defines no flashbar + // or alert contexts. For packages bundling both themes, we scope out one + // theme so contexts don't override one theme colors. + const notificationContexts = [ + createFlashbarContext((await import('./contexts/flashbar.js')).tokens), + createFlashbarWarningContext((await import('./contexts/flashbar-warning.js')).tokens), + createAlertContext((await import('./contexts/alert.js')).tokens), + ]; + notificationContexts.forEach(context => builder.addContext(excludeOneTheme(context))); + return builder.build(); } diff --git a/style-dictionary/one-theme/colors.ts b/style-dictionary/one-theme/colors.ts index 209f41c5f7..039e563ff3 100644 --- a/style-dictionary/one-theme/colors.ts +++ b/style-dictionary/one-theme/colors.ts @@ -129,6 +129,8 @@ const tokens: StyleDictionary.ColorsDictionary = { colorBackgroundSliderRangeDefault: { light: '{colorPrimary600}', dark: '{colorPrimary500}' }, colorBackgroundSliderHandleDefault: { light: '{colorPrimary600}', dark: '{colorPrimary500}' }, colorBackgroundProgressBarValueDefault: { light: '{colorPrimary600}', dark: '{colorPrimary500}' }, + colorBackgroundProgressBarValueFlash: '{colorTextNotificationDefault}', + colorBackgroundProgressBarFlash: { light: '{colorGreyOpaque10}', dark: '{colorGreyOpaque25}' }, // ── Badge ───────────────────────────────────────────────────────── colorBackgroundBadgeGreen: { light: '{colorSuccess100}', dark: 'rgba(43, 181, 52, 0.2)' }, @@ -136,18 +138,31 @@ const tokens: StyleDictionary.ColorsDictionary = { colorBackgroundBadgeRed: { light: '{colorError100}', dark: 'rgba(255, 61, 61, 0.2)' }, colorBackgroundBadgeYellow: { light: '{colorWarning100}', dark: 'rgba(251, 211, 50, 0.2)' }, colorBackgroundBadgeGrey: { light: '{colorNeutral250}', dark: '{colorNeutral700}' }, - colorTextNotificationDefault: { light: '{colorNeutral100}', dark: '{colorNeutral100}' }, + colorTextNotificationDefault: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, + colorTextNotificationYellow: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, + colorTextLinkInvertedHover: { light: '{colorNeutral950}', dark: '{colorWhite}' }, + colorTextInteractiveInvertedDefault: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, + colorTextInteractiveInvertedHover: { light: '{colorNeutral950}', dark: '{colorWhite}' }, colorTextBadgeGreen: { light: '{colorSuccess600}', dark: '{colorSuccess200}' }, colorTextBadgeBlue: { light: '{colorInfo600}', dark: '{colorInfo300}' }, colorTextBadgeRed: { light: '{colorError700}', dark: '{colorError400}' }, colorTextBadgeGrey: { light: '{colorNeutral850}', dark: '{colorNeutral300}' }, - // ── Flashbar (one-theme: subtle alert-style backgrounds) ─────────────────── + // Flashbar colorBackgroundFlashbarError: { light: '#fceded', dark: '#460303' }, colorBackgroundFlashbarInfo: { light: '#eaeffc', dark: '#08144f' }, colorBackgroundFlashbarSuccess: { light: '#e9fce7', dark: '#03220d' }, colorBackgroundFlashbarWarning: { light: '#fcfadb', dark: '#372603' }, + colorTextFlashbarIconInfo: { light: '{colorInfo600}', dark: '{colorInfo400}' }, + colorTextFlashbarIconSuccess: { light: '{colorSuccess600}', dark: '{colorSuccess500}' }, + + // Alert + colorBackgroundAlertError: { light: '#fceded', dark: '#460303' }, + colorBackgroundAlertInfo: { light: '#eaeffc', dark: '#08144f' }, + colorBackgroundAlertSuccess: { light: '#e9fce7', dark: '#03220d' }, + colorBackgroundAlertWarning: { light: '#fcfadb', dark: '#372603' }, + colorTextAlertDefault: '{colorTextNotificationDefault}', // ── Status border ─────────────────────────────────────────────────────────── colorBorderStatusError: { light: '{colorError600}', dark: '{colorError400}' }, @@ -156,6 +171,8 @@ const tokens: StyleDictionary.ColorsDictionary = { colorBorderStatusWarning: { light: '{colorWarning900}', dark: '{colorWarning300}' }, // ── Status text ─────────────────────────────────────────────────────────── + colorTextAlertIconInfo: { light: '{colorInfo600}', dark: '{colorInfo400}' }, + colorTextAlertIconSuccess: { light: '{colorSuccess600}', dark: '{colorSuccess500}' }, colorTextStatusInfo: { light: '{colorInfo600}', dark: '{colorInfo300}' }, colorTextStatusSuccess: { light: '{colorSuccess600}', dark: '{colorSuccess200}' }, colorTextStatusWarning: { light: '{colorWarning900}', dark: '{colorWarning300}' }, diff --git a/style-dictionary/one-theme/contexts/alert.ts b/style-dictionary/one-theme/contexts/alert.ts deleted file mode 100644 index 37b05da0e6..0000000000 --- a/style-dictionary/one-theme/contexts/alert.ts +++ /dev/null @@ -1,52 +0,0 @@ -// 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 = { - // Status backgrounds - colorBackgroundStatusError: { light: '#fceded', dark: '#460303' }, - colorBackgroundStatusInfo: { light: '#eaeffc', dark: '#08144f' }, - colorBackgroundStatusSuccess: { light: '#e9fce7', dark: '#03220d' }, - colorBackgroundStatusWarning: { light: '#fcfadb', dark: '#372603' }, - - // Status text and borders - colorTextStatusInfo: { light: '{colorInfo600}', dark: '{colorInfo400}' }, - colorBorderStatusInfo: { light: '{colorInfo600}', dark: '{colorInfo400}' }, - colorTextStatusSuccess: { light: '{colorSuccess600}', dark: '{colorSuccess500}' }, - colorBorderStatusSuccess: { light: '{colorSuccess600}', dark: '{colorSuccess500}' }, - - // Buttons - colorTextButtonNormalDefault: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, - colorTextButtonNormalHover: { light: '{colorNeutral950}', dark: '{colorWhite}' }, - colorTextButtonNormalActive: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, - colorBorderButtonNormalDefault: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, - colorBorderButtonNormalHover: { light: '{colorNeutral950}', dark: '{colorWhite}' }, - colorBorderButtonNormalActive: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, - colorBackgroundButtonNormalDefault: { light: 'transparent', dark: 'transparent' }, - colorBackgroundButtonNormalHover: 'rgba(0, 0, 0, 0.05)', - colorBackgroundButtonNormalActive: 'rgba(0, 0, 0, 0.1)', - - // Link - colorTextLinkDefault: { light: '{colorNeutral900}', dark: '{colorNeutral50}' }, - colorTextLinkHover: { light: '{colorNeutral950}', dark: '{colorWhite}' }, - - // Dividers - colorBorderDividerDefault: { light: '{colorNeutral350}', dark: '{colorNeutral600}' }, - - // Alert text - colorTextBodyDefault: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, - - // Expandable section - colorTextExpandableSectionHover: { light: '{colorNeutral950}', dark: '{colorWhite}' }, - colorBorderExpandableSectionDefault: { light: '{colorNeutral600}', dark: '{colorNeutral500}' }, - - // Focus ring - colorBorderItemFocused: { light: '{colorNeutral800}', dark: '{colorWhite}' }, -}; - -const expandedTokens: StyleDictionary.ExpandedColorScopeDictionary = expandColorDictionary(merge({}, tokens)); - -export { expandedTokens as tokens }; diff --git a/style-dictionary/one-theme/contexts/flashbar-warning.ts b/style-dictionary/one-theme/contexts/flashbar-warning.ts deleted file mode 100644 index 51e476a1da..0000000000 --- a/style-dictionary/one-theme/contexts/flashbar-warning.ts +++ /dev/null @@ -1,61 +0,0 @@ -// 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 = { - // Status backgrounds - colorBackgroundStatusInfo: { light: '{colorInfo100}', dark: '{colorInfo950}' }, - colorBackgroundStatusWarning: { light: '{colorWarning100}', dark: '{colorWarning950}' }, - colorBackgroundStatusError: { light: '{colorError100}', dark: '{colorError950}' }, - colorBackgroundStatusSuccess: { light: '{colorSuccess100}', dark: '{colorSuccess950}' }, - - // Status text and borders - colorTextStatusInfo: { light: '{colorInfo600}', dark: '{colorInfo400}' }, - colorBorderStatusInfo: { light: '{colorInfo600}', dark: '{colorInfo400}' }, - colorTextStatusSuccess: { light: '{colorSuccess600}', dark: '{colorSuccess500}' }, - colorBorderStatusSuccess: { light: '{colorSuccess600}', dark: '{colorSuccess500}' }, - - // Buttons - colorTextButtonNormalDefault: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, - colorTextButtonNormalHover: { light: '{colorNeutral950}', dark: '{colorWhite}' }, - colorTextButtonNormalActive: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, - colorBorderButtonNormalDefault: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, - colorBorderButtonNormalHover: { light: '{colorNeutral950}', dark: '{colorWhite}' }, - colorBorderButtonNormalActive: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, - colorBackgroundButtonNormalDefault: { light: 'transparent', dark: 'transparent' }, - colorBackgroundButtonNormalHover: 'rgba(0, 0, 0, 0.05)', - colorBackgroundButtonNormalActive: 'rgba(0, 0, 0, 0.1)', - - // Link - colorTextLinkInvertedHover: { light: '{colorNeutral950}', dark: '{colorWhite}' }, - - // Dismiss button - colorTextInteractiveInvertedDefault: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, - colorTextInteractiveInvertedHover: { light: '{colorNeutral950}', dark: '{colorWhite}' }, - - // Dividers - colorBorderDividerDefault: { light: '{colorNeutral350}', dark: '{colorNeutral600}' }, - - // Notification text - colorTextNotificationYellow: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, - colorTextNotificationDefault: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, - colorTextHeadingSecondary: { light: '{colorNeutral750}', dark: '{colorNeutral300}' }, - - // Expandable section - colorTextExpandableSectionHover: { light: '{colorNeutral950}', dark: '{colorWhite}' }, - colorBorderExpandableSectionDefault: { light: '{colorNeutral600}', dark: '{colorNeutral500}' }, - - // Progress bar - colorBackgroundProgressBarValueDefault: { light: '{colorNeutral800}', dark: '{colorWhite}' }, - colorBackgroundProgressBarDefault: { light: '{colorGreyOpaque10}', dark: '{colorGreyOpaque25}' }, - - // Focus ring - colorBorderItemFocused: { light: '{colorNeutral800}', dark: '{colorWhite}' }, -}; - -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 deleted file mode 100644 index 9b279fa4ff..0000000000 --- a/style-dictionary/one-theme/contexts/flashbar.ts +++ /dev/null @@ -1,60 +0,0 @@ -// 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 = { - // Status backgrounds - colorBackgroundStatusInfo: { light: '{colorInfo100}', dark: '{colorInfo950}' }, - colorBackgroundStatusWarning: { light: '{colorWarning100}', dark: '{colorWarning950}' }, - colorBackgroundStatusError: { light: '{colorError100}', dark: '{colorError950}' }, - colorBackgroundStatusSuccess: { light: '{colorSuccess100}', dark: '{colorSuccess950}' }, - - // Status text and borders - colorTextStatusInfo: { light: '{colorInfo600}', dark: '{colorInfo400}' }, - colorBorderStatusInfo: { light: '{colorInfo600}', dark: '{colorInfo400}' }, - colorTextStatusSuccess: { light: '{colorSuccess600}', dark: '{colorSuccess500}' }, - colorBorderStatusSuccess: { light: '{colorSuccess600}', dark: '{colorSuccess500}' }, - - // Buttons - colorTextButtonNormalDefault: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, - colorTextButtonNormalHover: { light: '{colorNeutral950}', dark: '{colorWhite}' }, - colorTextButtonNormalActive: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, - colorBorderButtonNormalDefault: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, - colorBorderButtonNormalHover: { light: '{colorNeutral950}', dark: '{colorWhite}' }, - colorBorderButtonNormalActive: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, - colorBackgroundButtonNormalDefault: { light: 'transparent', dark: 'transparent' }, - colorBackgroundButtonNormalHover: 'rgba(0, 0, 0, 0.05)', - colorBackgroundButtonNormalActive: 'rgba(0, 0, 0, 0.1)', - - // Link - colorTextLinkInvertedHover: { light: '{colorNeutral950}', dark: '{colorWhite}' }, - - // Dismiss button - colorTextInteractiveInvertedDefault: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, - colorTextInteractiveInvertedHover: { light: '{colorNeutral950}', dark: '{colorWhite}' }, - - // Dividers - colorBorderDividerDefault: { light: '{colorNeutral350}', dark: '{colorNeutral600}' }, - - // Notification text - colorTextNotificationDefault: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, - colorTextHeadingSecondary: { light: '{colorNeutral750}', dark: '{colorNeutral300}' }, - - // Expandable section - colorTextExpandableSectionHover: { light: '{colorNeutral950}', dark: '{colorWhite}' }, - colorBorderExpandableSectionDefault: { light: '{colorNeutral600}', dark: '{colorNeutral500}' }, - - // Progress bar - colorBackgroundProgressBarValueDefault: { light: '{colorNeutral800}', dark: '{colorWhite}' }, - colorBackgroundProgressBarDefault: { light: '{colorGreyOpaque10}', dark: '{colorGreyOpaque25}' }, - - // Focus ring - colorBorderItemFocused: { light: '{colorNeutral800}', dark: '{colorWhite}' }, -}; - -const expandedTokens: StyleDictionary.ExpandedColorScopeDictionary = expandColorDictionary(merge({}, tokens)); - -export { expandedTokens as tokens }; diff --git a/style-dictionary/one-theme/contexts/notification-controls.ts b/style-dictionary/one-theme/contexts/notification-controls.ts new file mode 100644 index 0000000000..d382a6cbf2 --- /dev/null +++ b/style-dictionary/one-theme/contexts/notification-controls.ts @@ -0,0 +1,30 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +import { expandColorDictionary } from '../../utils/index.js'; +import { StyleDictionary } from '../../utils/interfaces.js'; + +/** + * Interactive controls inside flash messages and alerts follow the notification + * text treatment. Values are references only: the referenced base tokens resolve + * per mode and are pinned dark by the surface contexts (header, top navigation), + * so no combined contexts are needed. + */ +const tokens: StyleDictionary.ColorsDictionary = { + colorTextButtonNormalDefault: '{colorTextInteractiveInvertedDefault}', + colorTextButtonNormalHover: '{colorTextInteractiveInvertedHover}', + colorTextButtonNormalActive: '{colorTextInteractiveInvertedDefault}', + colorBorderButtonNormalDefault: '{colorTextInteractiveInvertedDefault}', + colorBorderButtonNormalHover: '{colorTextInteractiveInvertedHover}', + colorBorderButtonNormalActive: '{colorTextInteractiveInvertedDefault}', + colorBackgroundButtonNormalDefault: 'transparent', + colorBackgroundButtonNormalHover: 'rgba(0, 0, 0, 0.05)', + colorBackgroundButtonNormalActive: 'rgba(0, 0, 0, 0.1)', + colorBorderItemFocused: { + light: '{colorTextInteractiveInvertedDefault}', + dark: '{colorTextInteractiveInvertedHover}', + }, +}; + +const expandedTokens: StyleDictionary.ExpandedColorScopeDictionary = expandColorDictionary(tokens); + +export { expandedTokens as tokens }; diff --git a/style-dictionary/one-theme/contexts/top-navigation.ts b/style-dictionary/one-theme/contexts/top-navigation.ts index 29d4eb5dbb..e3b6c7f6aa 100644 --- a/style-dictionary/one-theme/contexts/top-navigation.ts +++ b/style-dictionary/one-theme/contexts/top-navigation.ts @@ -6,6 +6,7 @@ import { expandColorDictionary, pickState } from '../../utils/index.js'; import { StyleDictionary } from '../../utils/interfaces.js'; import { tokens as vrParentTokens } from '../../visual-refresh/colors.js'; import { tokens as oneThemeParentTokens } from '../colors.js'; +import { tokens as parentShadowsTokens } from '../shadows.js'; const tokens: StyleDictionary.ColorsDictionary = { colorBackgroundContainerContent: '{colorNeutral950}', @@ -27,9 +28,10 @@ const tokens: StyleDictionary.ColorsDictionary = { const vrDarkValues = pickState(vrParentTokens, 'dark'); const oneThemeDarkValues = pickState(oneThemeParentTokens, 'dark'); +const darkShadowsValues = pickState(parentShadowsTokens, 'dark'); const expandedTokens: StyleDictionary.ExpandedColorScopeDictionary = expandColorDictionary( - merge({}, vrDarkValues, oneThemeDarkValues, tokens) + merge({}, vrDarkValues, oneThemeDarkValues, darkShadowsValues, tokens) ); export const mode: StyleDictionary.ModeIdentifier = 'color'; diff --git a/style-dictionary/one-theme/index.ts b/style-dictionary/one-theme/index.ts index 3799038475..53ecc9dbd1 100644 --- a/style-dictionary/one-theme/index.ts +++ b/style-dictionary/one-theme/index.ts @@ -8,7 +8,6 @@ import { createCompactTableContext, createFlashbarContext, createFlashbarWarningContext, - createHeaderAlertContext, createHeaderContext, createTopNavigationContext, } from '../utils/contexts.js'; @@ -45,13 +44,16 @@ tokenCategories.forEach(({ tokens, mode: modeId, referenceTokens }) => { }); builder.addContext(createCompactTableContext((await import('../visual-refresh/contexts/compact-table.js')).tokens)); -builder.addContext(createHeaderAlertContext((await import('../visual-refresh/contexts/header-alert.js')).tokens)); 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(createFlashbarWarningContext((await import('./contexts/flashbar-warning.js')).tokens)); -builder.addContext(createAlertContext((await import('./contexts/alert.js')).tokens)); + +// Notification design lives in base tokens; these contexts only carry references +// so interactive controls inside notifications follow the notification treatment. +const notificationControlTokens = (await import('./contexts/notification-controls.js')).tokens; +builder.addContext(createFlashbarContext(notificationControlTokens)); +builder.addContext(createFlashbarWarningContext(notificationControlTokens)); +builder.addContext(createAlertContext(notificationControlTokens)); const theme = builder.build(); export default theme; diff --git a/style-dictionary/utils/contexts.ts b/style-dictionary/utils/contexts.ts index 5cdb143be2..de9b4b3c84 100644 --- a/style-dictionary/utils/contexts.ts +++ b/style-dictionary/utils/contexts.ts @@ -2,6 +2,17 @@ // SPDX-License-Identifier: Apache-2.0 import { GlobalValue, ModeValue, TokenCategory } from '@cloudscape-design/theming-build'; +const oneThemeGuard = ':where(:not(.awsui-one-theme):not(.awsui-one-theme *))'; + +/** + * Global (body) themes' context rules would otherwise also match context elements in + * one theme, which styles notifications through base tokens without these contexts. + */ +export const excludeOneTheme = (context: T): T => ({ + ...context, + selector: `${context.selector}${oneThemeGuard}`, +}); + export const createTopNavigationContext = (tokens: TokenCategory) => { return { id: 'top-navigation', diff --git a/style-dictionary/visual-refresh/index.ts b/style-dictionary/visual-refresh/index.ts index f838dd584d..7214e8f318 100644 --- a/style-dictionary/visual-refresh/index.ts +++ b/style-dictionary/visual-refresh/index.ts @@ -11,6 +11,7 @@ import { createHeaderAlertContext, createHeaderContext, createTopNavigationContext, + excludeOneTheme, } from '../utils/contexts.js'; import { StyleDictionary } from '../utils/interfaces.js'; import { createColorMode, createDensityMode, createMotionMode } from '../utils/modes.js'; @@ -43,16 +44,23 @@ export async function buildVisualRefresh(builder: ThemeBuilder) { builder.addTokens(tokens, mode); }); - // Add contexts for component-specific overrides + // Add contexts for component-specific overrides. builder.addContext(createCompactTableContext((await import('./contexts/compact-table.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(createFlashbarWarningContext((await import('./contexts/flashbar-warning.js')).tokens)); - builder.addContext(createAlertContext((await import('./contexts/alert.js')).tokens)); - builder.addContext(createHeaderAlertContext((await import('./contexts/header-alert.js')).tokens)); builder.addContext(createAppLayoutToolbarContext((await import('./contexts/app-layout-toolbar.js')).tokens)); + // One theme styles notifications through base tokens and defines no flashbar + // or alert contexts. For packages bundling both themes, we scope out one + // theme so contexts don't override one theme colors. + const notificationContexts = [ + createFlashbarContext((await import('./contexts/flashbar.js')).tokens), + createFlashbarWarningContext((await import('./contexts/flashbar-warning.js')).tokens), + createAlertContext((await import('./contexts/alert.js')).tokens), + createHeaderAlertContext((await import('./contexts/header-alert.js')).tokens), + ]; + notificationContexts.forEach(context => builder.addContext(excludeOneTheme(context))); + return builder.build(); } From 29c99acce98f03383f60f16dce78d88623b55ebf Mon Sep 17 00:00:00 2001 From: Maximilian Schoell Date: Thu, 6 Aug 2026 17:34:40 +0200 Subject: [PATCH 3/9] refactor: restore embedded content styling in one theme notifications --- style-dictionary/one-theme/colors.ts | 1 + style-dictionary/one-theme/contexts/notification-controls.ts | 2 ++ style-dictionary/utils/token-names.ts | 1 + style-dictionary/visual-refresh/metadata/colors.ts | 5 +++++ 4 files changed, 9 insertions(+) diff --git a/style-dictionary/one-theme/colors.ts b/style-dictionary/one-theme/colors.ts index 039e563ff3..dd347857b6 100644 --- a/style-dictionary/one-theme/colors.ts +++ b/style-dictionary/one-theme/colors.ts @@ -139,6 +139,7 @@ const tokens: StyleDictionary.ColorsDictionary = { colorBackgroundBadgeYellow: { light: '{colorWarning100}', dark: 'rgba(251, 211, 50, 0.2)' }, colorBackgroundBadgeGrey: { light: '{colorNeutral250}', dark: '{colorNeutral700}' }, colorTextNotificationDefault: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, + colorBorderDividerNotification: { light: '{colorNeutral350}', dark: '{colorNeutral600}' }, colorTextNotificationYellow: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, colorTextLinkInvertedHover: { light: '{colorNeutral950}', dark: '{colorWhite}' }, colorTextInteractiveInvertedDefault: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, diff --git a/style-dictionary/one-theme/contexts/notification-controls.ts b/style-dictionary/one-theme/contexts/notification-controls.ts index d382a6cbf2..1781482cbc 100644 --- a/style-dictionary/one-theme/contexts/notification-controls.ts +++ b/style-dictionary/one-theme/contexts/notification-controls.ts @@ -19,6 +19,8 @@ const tokens: StyleDictionary.ColorsDictionary = { colorBackgroundButtonNormalDefault: 'transparent', colorBackgroundButtonNormalHover: 'rgba(0, 0, 0, 0.05)', colorBackgroundButtonNormalActive: 'rgba(0, 0, 0, 0.1)', + colorTextBodyDefault: '{colorTextNotificationDefault}', + colorBorderDividerDefault: '{colorBorderDividerNotification}', colorBorderItemFocused: { light: '{colorTextInteractiveInvertedDefault}', dark: '{colorTextInteractiveInvertedHover}', diff --git a/style-dictionary/utils/token-names.ts b/style-dictionary/utils/token-names.ts index 783230ac94..a850169745 100644 --- a/style-dictionary/utils/token-names.ts +++ b/style-dictionary/utils/token-names.ts @@ -704,6 +704,7 @@ export type ColorsTokenName = | 'colorBorderControlDisabled' | 'colorBorderDividerActive' | 'colorBorderDividerDefault' + | 'colorBorderDividerNotification' | 'colorBorderDividerSecondary' | 'colorBorderDividerTableGroup' | 'colorBorderDividerPanelBottom' diff --git a/style-dictionary/visual-refresh/metadata/colors.ts b/style-dictionary/visual-refresh/metadata/colors.ts index e26eb817f5..04fe3324d0 100644 --- a/style-dictionary/visual-refresh/metadata/colors.ts +++ b/style-dictionary/visual-refresh/metadata/colors.ts @@ -723,6 +723,11 @@ const metadata: StyleDictionary.MetadataIndex = { public: true, themeable: true, }, + colorBorderDividerNotification: { + description: 'The border color for dividers inside flash messages and alerts.', + public: false, + themeable: false, + }, colorBorderDividerSecondary: { description: 'The border color for row dividers. For example: row dividers for table and collection preferences.', public: true, From aac72e15445029570edbf0447ccbb599ee017783 Mon Sep 17 00:00:00 2001 From: Maximilian Schoell Date: Thu, 6 Aug 2026 17:52:21 +0200 Subject: [PATCH 4/9] Revert "refactor: restore embedded content styling in one theme notifications" This reverts commit 2e6da888f6cba6c9fdb2958b1bed08b83fe4b966. --- style-dictionary/one-theme/colors.ts | 1 - style-dictionary/one-theme/contexts/notification-controls.ts | 2 -- style-dictionary/utils/token-names.ts | 1 - style-dictionary/visual-refresh/metadata/colors.ts | 5 ----- 4 files changed, 9 deletions(-) diff --git a/style-dictionary/one-theme/colors.ts b/style-dictionary/one-theme/colors.ts index dd347857b6..039e563ff3 100644 --- a/style-dictionary/one-theme/colors.ts +++ b/style-dictionary/one-theme/colors.ts @@ -139,7 +139,6 @@ const tokens: StyleDictionary.ColorsDictionary = { colorBackgroundBadgeYellow: { light: '{colorWarning100}', dark: 'rgba(251, 211, 50, 0.2)' }, colorBackgroundBadgeGrey: { light: '{colorNeutral250}', dark: '{colorNeutral700}' }, colorTextNotificationDefault: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, - colorBorderDividerNotification: { light: '{colorNeutral350}', dark: '{colorNeutral600}' }, colorTextNotificationYellow: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, colorTextLinkInvertedHover: { light: '{colorNeutral950}', dark: '{colorWhite}' }, colorTextInteractiveInvertedDefault: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, diff --git a/style-dictionary/one-theme/contexts/notification-controls.ts b/style-dictionary/one-theme/contexts/notification-controls.ts index 1781482cbc..d382a6cbf2 100644 --- a/style-dictionary/one-theme/contexts/notification-controls.ts +++ b/style-dictionary/one-theme/contexts/notification-controls.ts @@ -19,8 +19,6 @@ const tokens: StyleDictionary.ColorsDictionary = { colorBackgroundButtonNormalDefault: 'transparent', colorBackgroundButtonNormalHover: 'rgba(0, 0, 0, 0.05)', colorBackgroundButtonNormalActive: 'rgba(0, 0, 0, 0.1)', - colorTextBodyDefault: '{colorTextNotificationDefault}', - colorBorderDividerDefault: '{colorBorderDividerNotification}', colorBorderItemFocused: { light: '{colorTextInteractiveInvertedDefault}', dark: '{colorTextInteractiveInvertedHover}', diff --git a/style-dictionary/utils/token-names.ts b/style-dictionary/utils/token-names.ts index a850169745..783230ac94 100644 --- a/style-dictionary/utils/token-names.ts +++ b/style-dictionary/utils/token-names.ts @@ -704,7 +704,6 @@ export type ColorsTokenName = | 'colorBorderControlDisabled' | 'colorBorderDividerActive' | 'colorBorderDividerDefault' - | 'colorBorderDividerNotification' | 'colorBorderDividerSecondary' | 'colorBorderDividerTableGroup' | 'colorBorderDividerPanelBottom' diff --git a/style-dictionary/visual-refresh/metadata/colors.ts b/style-dictionary/visual-refresh/metadata/colors.ts index 04fe3324d0..e26eb817f5 100644 --- a/style-dictionary/visual-refresh/metadata/colors.ts +++ b/style-dictionary/visual-refresh/metadata/colors.ts @@ -723,11 +723,6 @@ const metadata: StyleDictionary.MetadataIndex = { public: true, themeable: true, }, - colorBorderDividerNotification: { - description: 'The border color for dividers inside flash messages and alerts.', - public: false, - themeable: false, - }, colorBorderDividerSecondary: { description: 'The border color for row dividers. For example: row dividers for table and collection preferences.', public: true, From d5f2cb015171cd73f193ba55b5ed75d236c6c288 Mon Sep 17 00:00:00 2001 From: Maximilian Schoell Date: Thu, 6 Aug 2026 18:02:11 +0200 Subject: [PATCH 5/9] fix: notification border colors in one theme dark mode --- style-dictionary/one-theme/color-palette.ts | 1 + style-dictionary/one-theme/colors.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/style-dictionary/one-theme/color-palette.ts b/style-dictionary/one-theme/color-palette.ts index 329b8b558e..719f6aa0c5 100644 --- a/style-dictionary/one-theme/color-palette.ts +++ b/style-dictionary/one-theme/color-palette.ts @@ -127,6 +127,7 @@ const referenceTokens: ReferenceTokens = { 100: brand.colorRed100, 300: brand.colorRed300, 400: brand.colorRed400, + 500: brand.colorRed500, 600: brand.colorRed600, 700: brand.colorRed700, 800: brand.colorRed800, diff --git a/style-dictionary/one-theme/colors.ts b/style-dictionary/one-theme/colors.ts index 039e563ff3..5aac6ab024 100644 --- a/style-dictionary/one-theme/colors.ts +++ b/style-dictionary/one-theme/colors.ts @@ -165,7 +165,7 @@ const tokens: StyleDictionary.ColorsDictionary = { colorTextAlertDefault: '{colorTextNotificationDefault}', // ── Status border ─────────────────────────────────────────────────────────── - colorBorderStatusError: { light: '{colorError600}', dark: '{colorError400}' }, + colorBorderStatusError: { light: '{colorError600}', dark: '{colorError500}' }, colorBorderStatusInfo: { light: '{colorInfo600}', dark: '{colorInfo400}' }, colorBorderStatusSuccess: { light: '{colorSuccess600}', dark: '{colorSuccess300}' }, colorBorderStatusWarning: { light: '{colorWarning900}', dark: '{colorWarning300}' }, From ce1d1474a0aef9ff0a1c2b79f08193d4c7d22d49 Mon Sep 17 00:00:00 2001 From: Maximilian Schoell Date: Fri, 7 Aug 2026 14:15:41 +0000 Subject: [PATCH 6/9] feat: add notification embedded-content tokens --- .../notifications-permutations.tsx | 36 ++++++++++++------- pages/visual-contexts/notifications.page.tsx | 24 +++++++++++++ style-dictionary/one-theme/colors.ts | 3 ++ .../contexts/notification-controls.ts | 16 ++++++--- style-dictionary/utils/token-names.ts | 3 ++ style-dictionary/visual-refresh/colors.ts | 3 ++ .../visual-refresh/metadata/colors.ts | 15 ++++++++ 7 files changed, 83 insertions(+), 17 deletions(-) create mode 100644 pages/visual-contexts/notifications.page.tsx diff --git a/pages/visual-contexts/notifications-permutations.tsx b/pages/visual-contexts/notifications-permutations.tsx index 559148879d..28ca3beedd 100644 --- a/pages/visual-contexts/notifications-permutations.tsx +++ b/pages/visual-contexts/notifications-permutations.tsx @@ -3,9 +3,12 @@ import React from 'react'; import Alert, { AlertProps } from '~components/alert'; +import Box from '~components/box'; import Button from '~components/button'; +import Divider from '~components/divider'; import Flashbar, { FlashbarProps } from '~components/flashbar'; import Link from '~components/link'; +import SpaceBetween from '~components/space-between'; import createPermutations from '../utils/permutations'; @@ -13,19 +16,30 @@ const noop = () => void 0; const types = ['info', 'success', 'warning', 'error'] as const; +// Embedded content is rendered by other components, which read the shared body text, +// link and divider tokens rather than inheriting from the notification. +function EmbeddedContent({ linkColor }: { linkColor?: 'inverted' }) { + return ( + + + Message with a{' '} + + link + {' '} + and inline code. + + + Body text below a divider. + + ); +} + /* eslint-disable react/jsx-key */ export const flashbarPermutations = createPermutations([ { type: [...types], header: ['Flash header'], - content: [ - - Flash message with a{' '} - - link - - , - ], + content: [], action: [], dismissible: [true], dismissLabel: ['Dismiss'], @@ -37,11 +51,7 @@ export const alertPermutations = createPermutations([ { type: [...types], header: ['Alert header'], - children: [ - - Alert message with a link - , - ], + children: [], action: [], dismissible: [true], dismissAriaLabel: ['Dismiss'], diff --git a/pages/visual-contexts/notifications.page.tsx b/pages/visual-contexts/notifications.page.tsx new file mode 100644 index 0000000000..376368604c --- /dev/null +++ b/pages/visual-contexts/notifications.page.tsx @@ -0,0 +1,24 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +import React from 'react'; + +import Box from '~components/box'; +import SpaceBetween from '~components/space-between'; + +import PermutationsView from '../utils/permutations-view'; +import ScreenshotArea from '../utils/screenshot-area'; +import { alertPermutations, flashbarPermutations, renderAlert, renderFlashbar } from './notifications-permutations'; + +export default function NotificationsPermutations() { + return ( + + + + Notifications on the page surface + + + + + + ); +} diff --git a/style-dictionary/one-theme/colors.ts b/style-dictionary/one-theme/colors.ts index 5aac6ab024..6090f23370 100644 --- a/style-dictionary/one-theme/colors.ts +++ b/style-dictionary/one-theme/colors.ts @@ -140,6 +140,9 @@ const tokens: StyleDictionary.ColorsDictionary = { colorBackgroundBadgeGrey: { light: '{colorNeutral250}', dark: '{colorNeutral700}' }, colorTextNotificationDefault: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, colorTextNotificationYellow: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, + colorTextNotificationLinkDefault: { light: '{colorNeutral900}', dark: '{colorNeutral50}' }, + colorTextNotificationLinkHover: { light: '{colorNeutral950}', dark: '{colorWhite}' }, + colorBorderDividerNotification: { light: '{colorNeutral350}', dark: '{colorNeutral600}' }, colorTextLinkInvertedHover: { light: '{colorNeutral950}', dark: '{colorWhite}' }, colorTextInteractiveInvertedDefault: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, colorTextInteractiveInvertedHover: { light: '{colorNeutral950}', dark: '{colorWhite}' }, diff --git a/style-dictionary/one-theme/contexts/notification-controls.ts b/style-dictionary/one-theme/contexts/notification-controls.ts index d382a6cbf2..1f78794a96 100644 --- a/style-dictionary/one-theme/contexts/notification-controls.ts +++ b/style-dictionary/one-theme/contexts/notification-controls.ts @@ -4,12 +4,20 @@ import { expandColorDictionary } from '../../utils/index.js'; import { StyleDictionary } from '../../utils/interfaces.js'; /** - * Interactive controls inside flash messages and alerts follow the notification - * text treatment. Values are references only: the referenced base tokens resolve - * per mode and are pinned dark by the surface contexts (header, top navigation), - * so no combined contexts are needed. + * Interactive controls and embedded content inside flash messages and alerts follow + * the notification text treatment. Values are references only: the referenced base + * tokens resolve per mode and are pinned dark by the surface contexts (header, top + * navigation), so no combined contexts are needed. + * + * Embedded content (text, links, dividers) has to be redirected here rather than in + * the alert and flashbar stylesheets, because it is rendered by other components + * which read the shared tokens directly. */ const tokens: StyleDictionary.ColorsDictionary = { + colorTextBodyDefault: '{colorTextNotificationDefault}', + colorTextLinkDefault: '{colorTextNotificationLinkDefault}', + colorTextLinkHover: '{colorTextNotificationLinkHover}', + colorBorderDividerDefault: '{colorBorderDividerNotification}', colorTextButtonNormalDefault: '{colorTextInteractiveInvertedDefault}', colorTextButtonNormalHover: '{colorTextInteractiveInvertedHover}', colorTextButtonNormalActive: '{colorTextInteractiveInvertedDefault}', diff --git a/style-dictionary/utils/token-names.ts b/style-dictionary/utils/token-names.ts index 783230ac94..43b4914f6c 100644 --- a/style-dictionary/utils/token-names.ts +++ b/style-dictionary/utils/token-names.ts @@ -704,6 +704,7 @@ export type ColorsTokenName = | 'colorBorderControlDisabled' | 'colorBorderDividerActive' | 'colorBorderDividerDefault' + | 'colorBorderDividerNotification' | 'colorBorderDividerSecondary' | 'colorBorderDividerTableGroup' | 'colorBorderDividerPanelBottom' @@ -870,6 +871,8 @@ export type ColorsTokenName = | 'colorTextLinkInfoHover' | 'colorTextLinkInvertedHover' | 'colorTextNotificationDefault' + | 'colorTextNotificationLinkDefault' + | 'colorTextNotificationLinkHover' | 'colorTextAlertDefault' | 'colorTextAlertIconError' | 'colorTextAlertIconInfo' diff --git a/style-dictionary/visual-refresh/colors.ts b/style-dictionary/visual-refresh/colors.ts index ccf6ea225f..1fb3e82898 100644 --- a/style-dictionary/visual-refresh/colors.ts +++ b/style-dictionary/visual-refresh/colors.ts @@ -183,6 +183,7 @@ const tokens: StyleDictionary.ColorsDictionary = { colorBorderControlDisabled: '{colorBackgroundControlDisabled}', colorBorderDividerActive: { light: '{colorNeutral950}', dark: '{colorNeutral100}' }, colorBorderDividerDefault: { light: '{colorNeutral350}', dark: '{colorNeutral650}' }, + colorBorderDividerNotification: '{colorBorderDividerDefault}', colorBorderDividerPanelBottom: '{colorBorderDividerDefault}', colorBorderDividerPanelSide: '{colorBorderDividerDefault}', colorBorderDividerSecondary: { light: '{colorNeutral250}', dark: '{colorNeutral750}' }, @@ -325,6 +326,8 @@ const tokens: StyleDictionary.ColorsDictionary = { colorTextLinkButtonUnderlineHover: 'transparent', colorTextNotificationDefault: '{colorNeutral100}', colorTextAlertDefault: '{colorTextBodyDefault}', + colorTextNotificationLinkDefault: '{colorTextLinkDefault}', + colorTextNotificationLinkHover: '{colorTextLinkHover}', colorTextNotificationStackBar: '{colorWhite}', colorTextNotificationYellow: '{colorNeutral950}', colorTextPaginationPageNumberActiveDisabled: '{colorTextInteractiveDisabled}', diff --git a/style-dictionary/visual-refresh/metadata/colors.ts b/style-dictionary/visual-refresh/metadata/colors.ts index e26eb817f5..f83509d2b0 100644 --- a/style-dictionary/visual-refresh/metadata/colors.ts +++ b/style-dictionary/visual-refresh/metadata/colors.ts @@ -723,6 +723,11 @@ const metadata: StyleDictionary.MetadataIndex = { public: true, themeable: true, }, + colorBorderDividerNotification: { + description: 'The border color for dividers inside flash messages and alerts.', + public: false, + themeable: false, + }, colorBorderDividerSecondary: { description: 'The border color for row dividers. For example: row dividers for table and collection preferences.', public: true, @@ -1273,6 +1278,16 @@ const metadata: StyleDictionary.MetadataIndex = { public: false, themeable: false, }, + colorTextNotificationLinkDefault: { + description: 'The default text color of links inside flash messages and alerts.', + public: false, + themeable: false, + }, + colorTextNotificationLinkHover: { + description: 'The text color of hovered links inside flash messages and alerts.', + public: false, + themeable: false, + }, colorTextNotificationYellow: { description: 'The text and foreground color used on warning flash messages (yellow notification surface).', public: true, From e583229914191ee1e874f20e350b20cacf757903 Mon Sep 17 00:00:00 2001 From: Maximilian Schoell Date: Mon, 10 Aug 2026 09:38:39 +0200 Subject: [PATCH 7/9] chore: update comment --- .../one-theme/contexts/notification-controls.ts | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/style-dictionary/one-theme/contexts/notification-controls.ts b/style-dictionary/one-theme/contexts/notification-controls.ts index 1f78794a96..1400b2c63e 100644 --- a/style-dictionary/one-theme/contexts/notification-controls.ts +++ b/style-dictionary/one-theme/contexts/notification-controls.ts @@ -4,14 +4,8 @@ import { expandColorDictionary } from '../../utils/index.js'; import { StyleDictionary } from '../../utils/interfaces.js'; /** - * Interactive controls and embedded content inside flash messages and alerts follow - * the notification text treatment. Values are references only: the referenced base - * tokens resolve per mode and are pinned dark by the surface contexts (header, top - * navigation), so no combined contexts are needed. - * - * Embedded content (text, links, dividers) has to be redirected here rather than in - * the alert and flashbar stylesheets, because it is rendered by other components - * which read the shared tokens directly. + * Token overrides for interactive content paced within Notifications such as + * Buttons, Tables, etc. */ const tokens: StyleDictionary.ColorsDictionary = { colorTextBodyDefault: '{colorTextNotificationDefault}', From be8d13d8480470c00beb5570e7e5d5f501a4979c Mon Sep 17 00:00:00 2001 From: Maximilian Schoell Date: Mon, 10 Aug 2026 09:39:19 +0200 Subject: [PATCH 8/9] chore: remove alert from top-nav context --- pages/visual-contexts/top-navigation-notifications.page.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pages/visual-contexts/top-navigation-notifications.page.tsx b/pages/visual-contexts/top-navigation-notifications.page.tsx index cac2c00614..6349bf8058 100644 --- a/pages/visual-contexts/top-navigation-notifications.page.tsx +++ b/pages/visual-contexts/top-navigation-notifications.page.tsx @@ -8,7 +8,7 @@ import SpaceBetween from '~components/space-between'; import PermutationsView from '../utils/permutations-view'; import ScreenshotArea from '../utils/screenshot-area'; -import { alertPermutations, flashbarPermutations, renderAlert, renderFlashbar } from './notifications-permutations'; +import { flashbarPermutations, renderFlashbar } from './notifications-permutations'; import styles from './styles.scss'; @@ -20,7 +20,6 @@ export default function TopNavigationNotificationsPermutations() { Notifications in top-navigation visual context - From 80507504833256b480e0dbec0a32faf5cd3d488a Mon Sep 17 00:00:00 2001 From: Maximilian Schoell Date: Mon, 10 Aug 2026 16:51:54 +0200 Subject: [PATCH 9/9] fix: split inverted link color off colorTextNotificationDefault --- src/__integ__/__snapshots__/themes.test.ts.snap | 8 ++++++++ src/link/styles.scss | 4 ++-- style-dictionary/one-theme/colors.ts | 3 ++- .../one-theme/contexts/notification-controls.ts | 2 ++ style-dictionary/utils/token-names.ts | 1 + style-dictionary/visual-refresh/colors.ts | 1 + style-dictionary/visual-refresh/metadata/colors.ts | 6 ++++++ 7 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/__integ__/__snapshots__/themes.test.ts.snap b/src/__integ__/__snapshots__/themes.test.ts.snap index 8dd021c016..9d56128051 100644 --- a/src/__integ__/__snapshots__/themes.test.ts.snap +++ b/src/__integ__/__snapshots__/themes.test.ts.snap @@ -685,6 +685,7 @@ exports[`CSS Custom Properties match previous snapshot for mode "compact" 1`] = "color-text-link-hover": "#0a4a74", "color-text-link-info-default": "#0073bb", "color-text-link-info-hover": "#0a4a74", + "color-text-link-inverted-default": "#fafafa", "color-text-link-inverted-hover": "#fafafa", "color-text-link-secondary-default": "#0073bb", "color-text-link-secondary-hover": "#0a4a74", @@ -1683,6 +1684,7 @@ exports[`CSS Custom Properties match previous snapshot for mode "dark" 1`] = ` "color-text-link-hover": "#99cbe4", "color-text-link-info-default": "#44b9d6", "color-text-link-info-hover": "#99cbe4", + "color-text-link-inverted-default": "#fafafa", "color-text-link-inverted-hover": "#fafafa", "color-text-link-secondary-default": "#44b9d6", "color-text-link-secondary-hover": "#99cbe4", @@ -2681,6 +2683,7 @@ exports[`CSS Custom Properties match previous snapshot for mode "light" 1`] = ` "color-text-link-hover": "#0a4a74", "color-text-link-info-default": "#0073bb", "color-text-link-info-hover": "#0a4a74", + "color-text-link-inverted-default": "#fafafa", "color-text-link-inverted-hover": "#fafafa", "color-text-link-secondary-default": "#0073bb", "color-text-link-secondary-hover": "#0a4a74", @@ -3679,6 +3682,7 @@ exports[`CSS Custom Properties match previous snapshot for mode "reduced-motion" "color-text-link-hover": "#0a4a74", "color-text-link-info-default": "#0073bb", "color-text-link-info-hover": "#0a4a74", + "color-text-link-inverted-default": "#fafafa", "color-text-link-inverted-hover": "#fafafa", "color-text-link-secondary-default": "#0073bb", "color-text-link-secondary-hover": "#0a4a74", @@ -4677,6 +4681,7 @@ exports[`CSS Custom Properties match previous snapshot for mode "visual-refresh" "color-text-link-hover": "#002b66", "color-text-link-info-default": "#006ce0", "color-text-link-info-hover": "#002b66", + "color-text-link-inverted-default": "#f9f9fa", "color-text-link-inverted-hover": "#ffffff", "color-text-link-secondary-default": "#006ce0", "color-text-link-secondary-hover": "#002b66", @@ -5675,6 +5680,7 @@ exports[`CSS Custom Properties match previous snapshot for mode "visual-refresh- "color-text-link-hover": "#002b66", "color-text-link-info-default": "#006ce0", "color-text-link-info-hover": "#002b66", + "color-text-link-inverted-default": "#f9f9fa", "color-text-link-inverted-hover": "#ffffff", "color-text-link-secondary-default": "#006ce0", "color-text-link-secondary-hover": "#002b66", @@ -6673,6 +6679,7 @@ exports[`CSS Custom Properties match previous snapshot for mode "visual-refresh- "color-text-link-hover": "#75cfff", "color-text-link-info-default": "#42b4ff", "color-text-link-info-hover": "#75cfff", + "color-text-link-inverted-default": "#f9f9fa", "color-text-link-inverted-hover": "#ffffff", "color-text-link-secondary-default": "#42b4ff", "color-text-link-secondary-hover": "#75cfff", @@ -7671,6 +7678,7 @@ exports[`CSS Custom Properties match previous snapshot for mode "visual-refresh- "color-text-link-hover": "#75cfff", "color-text-link-info-default": "#42b4ff", "color-text-link-info-hover": "#75cfff", + "color-text-link-inverted-default": "#f9f9fa", "color-text-link-inverted-hover": "#ffffff", "color-text-link-secondary-default": "#42b4ff", "color-text-link-secondary-hover": "#75cfff", diff --git a/src/link/styles.scss b/src/link/styles.scss index ca2b162bfc..b87bfe5514 100644 --- a/src/link/styles.scss +++ b/src/link/styles.scss @@ -47,7 +47,7 @@ letter-spacing: normal; } &.color-inverted { - color: awsui.$color-text-notification-default; + color: awsui.$color-text-link-inverted-default; text-decoration-color: currentColor; &:hover { color: awsui.$color-text-link-inverted-hover; @@ -57,7 +57,7 @@ } &.color-inverted { - color: awsui.$color-text-notification-default; + color: awsui.$color-text-link-inverted-default; &:not(.button) { text-decoration-line: underline; text-decoration-color: currentColor; diff --git a/style-dictionary/one-theme/colors.ts b/style-dictionary/one-theme/colors.ts index 6090f23370..b3d64b7bf8 100644 --- a/style-dictionary/one-theme/colors.ts +++ b/style-dictionary/one-theme/colors.ts @@ -143,7 +143,8 @@ const tokens: StyleDictionary.ColorsDictionary = { colorTextNotificationLinkDefault: { light: '{colorNeutral900}', dark: '{colorNeutral50}' }, colorTextNotificationLinkHover: { light: '{colorNeutral950}', dark: '{colorWhite}' }, colorBorderDividerNotification: { light: '{colorNeutral350}', dark: '{colorNeutral600}' }, - colorTextLinkInvertedHover: { light: '{colorNeutral950}', dark: '{colorWhite}' }, + colorTextLinkInvertedDefault: '{colorNeutral100}', + colorTextLinkInvertedHover: '{colorWhite}', colorTextInteractiveInvertedDefault: { light: '{colorNeutral800}', dark: '{colorNeutral100}' }, colorTextInteractiveInvertedHover: { light: '{colorNeutral950}', dark: '{colorWhite}' }, diff --git a/style-dictionary/one-theme/contexts/notification-controls.ts b/style-dictionary/one-theme/contexts/notification-controls.ts index 1400b2c63e..e3cff6dec3 100644 --- a/style-dictionary/one-theme/contexts/notification-controls.ts +++ b/style-dictionary/one-theme/contexts/notification-controls.ts @@ -11,6 +11,8 @@ const tokens: StyleDictionary.ColorsDictionary = { colorTextBodyDefault: '{colorTextNotificationDefault}', colorTextLinkDefault: '{colorTextNotificationLinkDefault}', colorTextLinkHover: '{colorTextNotificationLinkHover}', + colorTextLinkInvertedDefault: '{colorTextNotificationDefault}', + colorTextLinkInvertedHover: '{colorTextNotificationLinkHover}', colorBorderDividerDefault: '{colorBorderDividerNotification}', colorTextButtonNormalDefault: '{colorTextInteractiveInvertedDefault}', colorTextButtonNormalHover: '{colorTextInteractiveInvertedHover}', diff --git a/style-dictionary/utils/token-names.ts b/style-dictionary/utils/token-names.ts index 43b4914f6c..7124406bde 100644 --- a/style-dictionary/utils/token-names.ts +++ b/style-dictionary/utils/token-names.ts @@ -869,6 +869,7 @@ export type ColorsTokenName = | 'colorTextLinkSecondaryHover' | 'colorTextLinkInfoDefault' | 'colorTextLinkInfoHover' + | 'colorTextLinkInvertedDefault' | 'colorTextLinkInvertedHover' | 'colorTextNotificationDefault' | 'colorTextNotificationLinkDefault' diff --git a/style-dictionary/visual-refresh/colors.ts b/style-dictionary/visual-refresh/colors.ts index 1fb3e82898..d4f7297c28 100644 --- a/style-dictionary/visual-refresh/colors.ts +++ b/style-dictionary/visual-refresh/colors.ts @@ -321,6 +321,7 @@ const tokens: StyleDictionary.ColorsDictionary = { colorTextLinkSecondaryHover: '{colorTextLinkHover}', colorTextLinkInfoDefault: '{colorTextLinkDefault}', colorTextLinkInfoHover: '{colorTextLinkHover}', + colorTextLinkInvertedDefault: '{colorTextNotificationDefault}', colorTextLinkInvertedHover: '{colorWhite}', colorTextLinkButtonUnderline: 'transparent', colorTextLinkButtonUnderlineHover: 'transparent', diff --git a/style-dictionary/visual-refresh/metadata/colors.ts b/style-dictionary/visual-refresh/metadata/colors.ts index f83509d2b0..a4dfb22b1e 100644 --- a/style-dictionary/visual-refresh/metadata/colors.ts +++ b/style-dictionary/visual-refresh/metadata/colors.ts @@ -1248,6 +1248,12 @@ const metadata: StyleDictionary.MetadataIndex = { public: true, themeable: true, }, + colorTextLinkInvertedDefault: { + description: + 'The default text color of links rendered on an inverted (dark) surface. For example: a link inside a flashbar.', + public: false, + themeable: false, + }, colorTextNotificationDefault: { description: 'Default text color for notifications. For example: the text on badges and flashes.', public: true,