From 953d578c660796d66fe0b72b3a2c31ac19a1e298 Mon Sep 17 00:00:00 2001 From: "Nichols, Kieran" Date: Wed, 6 Dec 2023 16:51:26 -0500 Subject: [PATCH 1/2] feat(theme): introduce new `*-container-minimum` theme colors, and additional cleanup of various files --- src/dev/pages/icon-button/icon-button.ejs | 2 +- src/dev/pages/theme/theme.scss | 4 ++++ src/dev/pages/theme/theme.ts | 11 ++++++++++- src/lib/circular-progress/circular-progress.scss | 6 +++++- src/lib/core/base/base-adapter.ts | 5 +++++ src/lib/core/styles/tokens/_token-utils.scss | 6 +++--- src/lib/core/styles/tokens/theme/_token-utils.scss | 4 ++++ src/lib/core/styles/tokens/theme/_tokens.surface.scss | 3 +++ .../core/styles/tokens/theme/_tokens.utilities.scss | 3 ++- src/lib/menu/menu.ts | 4 +--- src/lib/state-layer/state-layer-foundation.ts | 5 ++++- 11 files changed, 42 insertions(+), 11 deletions(-) diff --git a/src/dev/pages/icon-button/icon-button.ejs b/src/dev/pages/icon-button/icon-button.ejs index a07b30de0..ba63c853e 100644 --- a/src/dev/pages/icon-button/icon-button.ejs +++ b/src/dev/pages/icon-button/icon-button.ejs @@ -89,7 +89,7 @@ - + diff --git a/src/dev/pages/theme/theme.scss b/src/dev/pages/theme/theme.scss index e040a6a57..e7fb35372 100644 --- a/src/dev/pages/theme/theme.scss +++ b/src/dev/pages/theme/theme.scss @@ -1,3 +1,7 @@ +.content .card { + max-width: 1075px; +} + .swatches { display: flex; flex-direction: column; diff --git a/src/dev/pages/theme/theme.ts b/src/dev/pages/theme/theme.ts index dba071f04..ef8623838 100644 --- a/src/dev/pages/theme/theme.ts +++ b/src/dev/pages/theme/theme.ts @@ -25,6 +25,7 @@ const SWATCH_GROUPS: ISwatchGroup[] = [ { swatches: [ { text: 'Surface container', background: 'surface-container', foreground: 'on-surface-container' }, + { text: 'Surface container (minimum)', background: 'surface-container-minimum', foreground: 'on-surface' }, { text: 'Surface container (low)', background: 'surface-container-low', foreground: 'on-surface' }, { text: 'Surface container (medium)', background: 'surface-container-medium', foreground: 'on-surface' }, { text: 'Surface container (high)', background: 'surface-container-high', foreground: 'on-surface-container-high' } @@ -40,6 +41,7 @@ const SWATCH_GROUPS: ISwatchGroup[] = [ header: 'Key colors', swatches: [ { text: 'Primary', background: 'primary', foreground: 'on-primary' }, + { text: 'Primary container (minimum)', background: 'primary-container-minimum', foreground: 'on-primary-container-minimum' }, { text: 'Primary container (low)', background: 'primary-container-low', foreground: 'on-primary-container-low' }, { text: 'Primary container', background: 'primary-container', foreground: 'on-primary-container' }, { text: 'Primary container (high)', background: 'primary-container-high', foreground: 'on-primary-container-high' } @@ -48,6 +50,7 @@ const SWATCH_GROUPS: ISwatchGroup[] = [ { swatches: [ { text: 'Secondary', background: 'secondary', foreground: 'on-secondary' }, + { text: 'Secondary container (minimum)', background: 'secondary-container-minimum', foreground: 'on-secondary-container-minimum' }, { text: 'Secondary container (low)', background: 'secondary-container-low', foreground: 'on-secondary-container-low'}, { text: 'Secondary container', background: 'secondary-container', foreground: 'on-secondary-container' }, { text: 'Secondary container (high)', background: 'secondary-container-high', foreground: 'on-secondary-container-high' } @@ -56,6 +59,7 @@ const SWATCH_GROUPS: ISwatchGroup[] = [ { swatches: [ { text: 'Tertiary', background: 'tertiary', foreground: 'on-tertiary' }, + { text: 'Tertiary container (minimum)', background: 'tertiary-container-minimum', foreground: 'on-tertiary-container-minimum' }, { text: 'Tertiary container (low)', background: 'tertiary-container-low', foreground: 'on-tertiary-container-low' }, { text: 'Tertiary container', background: 'tertiary-container', foreground: 'on-tertiary-container' }, { text: 'Tertiary container (high)', background: 'tertiary-container-high', foreground: 'on-tertiary-container-high' } @@ -65,6 +69,7 @@ const SWATCH_GROUPS: ISwatchGroup[] = [ header: 'Status', swatches: [ { text: 'Success', background: 'success', foreground: 'on-success' }, + { text: 'Success container (minimum)', background: 'success-container-minimum', foreground: 'on-success-container-minimum' }, { text: 'Success container (low)', background: 'success-container-low', foreground: 'on-success-container-low' }, { text: 'Success container', background: 'success-container', foreground: 'on-success-container' }, { text: 'Success container (high)', background: 'success-container-high', foreground: 'on-success-container-high' } @@ -73,6 +78,7 @@ const SWATCH_GROUPS: ISwatchGroup[] = [ { swatches: [ { text: 'Error ', background: 'error', foreground: 'on-error' }, + { text: 'Error container (minimum)', background: 'error-container-minimum', foreground: 'on-error-container-minimum' }, { text: 'Error container (low)', background: 'error-container-low', foreground: 'on-error-container-low' }, { text: 'Error container', background: 'error-container', foreground: 'on-error-container' }, { text: 'Error container (high)', background: 'error-container-high', foreground: 'on-error-container-high' } @@ -81,6 +87,7 @@ const SWATCH_GROUPS: ISwatchGroup[] = [ { swatches: [ { text: 'Warning', background: 'warning', foreground: 'on-warning' }, + { text: 'Warning container (minimum)', background: 'warning-container-minimum', foreground: 'on-warning-container-minimum' }, { text: 'Warning container (low)', background: 'warning-container-low', foreground: 'on-warning-container-low' }, { text: 'Warning container', background: 'warning-container', foreground: 'on-warning-container' }, { text: 'Warning container (high)', background: 'warning-container-high', foreground: 'on-warning-container-high' } @@ -89,6 +96,7 @@ const SWATCH_GROUPS: ISwatchGroup[] = [ { swatches: [ { text: 'Info', background: 'info', foreground: 'on-info' }, + { text: 'Info container (minimum)', background: 'info-container-minimum', foreground: 'on-info-container-minimum' }, { text: 'Info container (low)', background: 'info-container-low', foreground: 'on-info-container-low' }, { text: 'Info container', background: 'info-container', foreground: 'on-info-container' }, { text: 'Info container (high)', background: 'info-container-high', foreground: 'on-info-container-high' } @@ -106,7 +114,8 @@ const SWATCH_GROUPS: ISwatchGroup[] = [ { header: 'Utilities', swatches: [ - { text: 'Outline', background: 'outline', foreground: 'text-high' } + { text: 'Outline', background: 'outline', foreground: 'text-high' }, + { text: 'Outline (high)', background: 'outline-high', foreground: 'text-high-inverse' } ] } ]; diff --git a/src/lib/circular-progress/circular-progress.scss b/src/lib/circular-progress/circular-progress.scss index a96e3e392..fde735998 100644 --- a/src/lib/circular-progress/circular-progress.scss +++ b/src/lib/circular-progress/circular-progress.scss @@ -121,7 +121,11 @@ svg { @include theme(warning); @include theme(info); -:host([track]) { +// +// Track +// + +:host(:is([track],[determinate])) { .forge-circular-progress { @include override(track-color, track-fill-color); } diff --git a/src/lib/core/base/base-adapter.ts b/src/lib/core/base/base-adapter.ts index 8c905e228..30a8a8d27 100644 --- a/src/lib/core/base/base-adapter.ts +++ b/src/lib/core/base/base-adapter.ts @@ -22,6 +22,7 @@ export interface IBaseAdapter { setBodyAttribute(name: string, value: string): void; removeBodyAttribute(name: string): void; focusHost(options?: FocusOptions): void; + clickHost(): void; } export class BaseAdapter implements IBaseAdapter { @@ -127,6 +128,10 @@ export class BaseAdapter implements IBaseAdapter { HTMLElement.prototype.focus.call(this._component, options); } + public clickHost(): void { + HTMLElement.prototype.click.call(this._component); + } + public get isConnected(): boolean { return this._component.isConnected; } diff --git a/src/lib/core/styles/tokens/_token-utils.scss b/src/lib/core/styles/tokens/_token-utils.scss index 842d10c00..c73184fb7 100644 --- a/src/lib/core/styles/tokens/_token-utils.scss +++ b/src/lib/core/styles/tokens/_token-utils.scss @@ -86,11 +86,11 @@ @mixin tokens($module, $tokens, $includes: null, $excludes: null) { @if ($includes) { // We are including only specific tokens - @each $token in $includes { - @if (not map.has-key($tokens, $token)) { + @each $token-name in $includes { + @if (not map.has-key($tokens, $token-name)) { @error 'Invalid include token "#{$token}" for module "#{$module}"'; } - #{declare($module, $token)}: #{map.get($tokens, $token)}; + #{declare($module, $token-name)}: #{map.get($tokens, $token-name)}; } } @else { // We are including all tokens, but first we need to check if any excluded tokens were provided diff --git a/src/lib/core/styles/tokens/theme/_token-utils.scss b/src/lib/core/styles/tokens/theme/_token-utils.scss index 9af367dff..745852668 100644 --- a/src/lib/core/styles/tokens/theme/_token-utils.scss +++ b/src/lib/core/styles/tokens/theme/_token-utils.scss @@ -18,6 +18,7 @@ $surface-tone: color-utils.tone($surface); // The container colors are the provided color mixed with the surface color at lower emphasis levels + $container-minimum: theme-utils.hexify($color, $surface, color-emphasis.value(if($surface-tone == 'light', minimum, lowest))); $container-low: theme-utils.hexify($color, $surface, color-emphasis.value(if($surface-tone == 'light', lower, low))); $container: theme-utils.hexify($color, $surface, color-emphasis.value(if($surface-tone == 'light', low, medium-low))); $container-high: theme-utils.hexify($color, $surface, color-emphasis.value(if($surface-tone == 'light', medium-low, medium))); @@ -28,16 +29,19 @@ // The on-container colors are the contrast color for the provided color mixed with the // container color at a lower emphasis to let the contrast color bleed through for // increased contrast against the lower emphasis container color + $on-container-minimum: theme-utils.hexify($color, theme-utils.contrast($container-minimum), color-emphasis.value(medium)); $on-container-low: theme-utils.hexify($color, theme-utils.contrast($container-low), color-emphasis.value(medium)); $on-container: theme-utils.hexify($color, theme-utils.contrast($container), color-emphasis.value(medium)); $on-container-high: theme-utils.contrast($container-high); @return ( #{$name}: $color, + #{$name}-container-minimum: $container-minimum, #{$name}-container-low: $container-low, #{$name}-container: $container, #{$name}-container-high: $container-high, on-#{$name}: $on-color, + on-#{$name}-container-minimum: $on-container-minimum, on-#{$name}-container-low: $on-container-low, on-#{$name}-container: $on-container, on-#{$name}-container-high: $on-container-high diff --git a/src/lib/core/styles/tokens/theme/_tokens.surface.scss b/src/lib/core/styles/tokens/theme/_tokens.surface.scss index c25e7e94f..b05b59d8b 100644 --- a/src/lib/core/styles/tokens/theme/_tokens.surface.scss +++ b/src/lib/core/styles/tokens/theme/_tokens.surface.scss @@ -18,6 +18,7 @@ $surface-inverse: theme-utils.hexify($on-surface, $surface, color-emphasis.value(inverse)); $surface-container: theme-utils.hexify($on-surface, $surface, color-emphasis.value(lower)); + $surface-container-minimum: theme-utils.hexify($on-surface, $surface, color-emphasis.value(minimum)); $surface-container-low: theme-utils.hexify($on-surface, $surface, color-emphasis.value(lowest)); $surface-container-medium: theme-utils.hexify($on-surface, $surface, color-emphasis.value(if($surface-tone == 'light', low, medium-low))); $surface-container-high: theme-utils.hexify($on-surface, $surface, color-emphasis.value(if($surface-tone == 'light', medium-low, medium))); @@ -26,6 +27,7 @@ surface: $surface, surface-inverse: $surface-inverse, surface-container: $surface-container, + surface-container-minimum: $surface-container-minimum, surface-container-low: $surface-container-low, surface-container-medium: $surface-container-medium, surface-container-high: $surface-container-high, @@ -35,6 +37,7 @@ on-surface: $on-surface, on-surface-inverse: theme-utils.contrast($surface-inverse), on-surface-container: theme-utils.contrast($surface-container), + on-surface-container-minimum: theme-utils.contrast($surface-container-minimum), on-surface-container-low: theme-utils.contrast($surface-container-low), on-surface-container-medium: theme-utils.contrast($surface-container-medium), on-surface-container-high: theme-utils.contrast($surface-container-high) diff --git a/src/lib/core/styles/tokens/theme/_tokens.utilities.scss b/src/lib/core/styles/tokens/theme/_tokens.utilities.scss index d79ecc906..a837a83bf 100644 --- a/src/lib/core/styles/tokens/theme/_tokens.utilities.scss +++ b/src/lib/core/styles/tokens/theme/_tokens.utilities.scss @@ -14,7 +14,8 @@ $on-surface: map.get($surface-theme, on-surface); @return ( - outline: theme-utils.hexify($on-surface, $surface, color-emphasis.value(lower)) + outline: theme-utils.hexify($on-surface, $surface, color-emphasis.value(lower)), + outline-high: theme-utils.hexify($on-surface, $surface, color-emphasis.value(medium)) ); } diff --git a/src/lib/menu/menu.ts b/src/lib/menu/menu.ts index 479bf419e..af52f0e0b 100644 --- a/src/lib/menu/menu.ts +++ b/src/lib/menu/menu.ts @@ -52,9 +52,7 @@ declare global { name: MENU_CONSTANTS.elementName, dependencies: [ PopupComponent, - ListComponent, - CircularProgressComponent, - LinearProgressComponent + ListComponent ] }) export class MenuComponent extends ListDropdownAware implements IMenuComponent { diff --git a/src/lib/state-layer/state-layer-foundation.ts b/src/lib/state-layer/state-layer-foundation.ts index d3f7a9097..0bf574ef5 100644 --- a/src/lib/state-layer/state-layer-foundation.ts +++ b/src/lib/state-layer/state-layer-foundation.ts @@ -42,6 +42,10 @@ export class StateLayerFoundation implements IStateLayerFoundation { public initialize(): void { this._adapter.trySetTarget(this._target); + // Clicks could be triggered programmatically so we need to listen for them regardless + // of deferred initialization status + this._adapter.addTargetListener('click', this._clickListener); + // We defer initialization until the first pointerenter event is received. // // This is a performance optimization to avoid attaching many listeners to the target element @@ -77,7 +81,6 @@ export class StateLayerFoundation implements IStateLayerFoundation { this._adapter.addTargetListener('pointerdown', this._pointerDownListener); this._adapter.addTargetListener('pointerup', this._pointerUpListener); this._adapter.addTargetListener('pointercancel', this._pointerCancelListener); - this._adapter.addTargetListener('click', this._clickListener); this._adapter.addTargetListener('contextmenu', this._contextmenuListener); this._attached = true; } From 80a62bf74266744f38c1f863d51ada040a6708e3 Mon Sep 17 00:00:00 2001 From: "Nichols, Kieran" Date: Wed, 6 Dec 2023 19:47:01 -0500 Subject: [PATCH 2/2] fix(state-layer): ensure all listeners are always remove from the previous target element regardless of attached state --- src/lib/state-layer/state-layer-foundation.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/lib/state-layer/state-layer-foundation.ts b/src/lib/state-layer/state-layer-foundation.ts index 0bf574ef5..4a1e0254e 100644 --- a/src/lib/state-layer/state-layer-foundation.ts +++ b/src/lib/state-layer/state-layer-foundation.ts @@ -249,10 +249,10 @@ export class StateLayerFoundation implements IStateLayerFoundation { } public set targetElement(el: HTMLElement | null) { // Always remove the listeners from the previous target element - if (this._attached) { - this._removeListeners(); - } else { - // If unattached destroy the defer listener to recreate on the new target element + this._removeListeners(); + + // If unattached destroy the defer listener to recreate on the new target element + if (!this._attached) { this._adapter.destroy(); this._deferred = false; } @@ -273,9 +273,10 @@ export class StateLayerFoundation implements IStateLayerFoundation { this._target = value; if (this._adapter.isConnected) { - if (this._attached) { - this._removeListeners(); - } else { + // Always remove the listeners from the previous target element + this._removeListeners(); + + if (!this._attached) { this._adapter.destroy(); this._deferred = false; }