diff --git a/button/lib/_elevation.scss b/button/lib/_elevation.scss index 4c9e0629c5..a35597d1e6 100644 --- a/button/lib/_elevation.scss +++ b/button/lib/_elevation.scss @@ -11,11 +11,6 @@ // go/keep-sorted end @mixin styles() { - md-elevation { - inset: 0; - position: absolute; - } - .md3-button { @include elevation.theme( ( diff --git a/button/lib/_shared.scss b/button/lib/_shared.scss index 254bbf2ae0..dfcf7dfef6 100644 --- a/button/lib/_shared.scss +++ b/button/lib/_shared.scss @@ -131,6 +131,7 @@ .md3-button::after, .md3-button::before, md-elevation, + md-elevation-surface, .md3-button__ripple { z-index: -1; // Place behind content } diff --git a/button/lib/elevated-button.ts b/button/lib/elevated-button.ts index 49f967f417..9e4804a57b 100644 --- a/button/lib/elevated-button.ts +++ b/button/lib/elevated-button.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import '../../elevation/elevation.js'; +import '../../elevation/elevation-surface.js'; import {html, TemplateResult} from 'lit'; import {ClassInfo} from 'lit/directives/class-map.js'; @@ -23,6 +23,6 @@ export class ElevatedButton extends Button { } protected override renderElevation(): TemplateResult { - return html``; + return html``; } } diff --git a/button/lib/filled-button.ts b/button/lib/filled-button.ts index 22abb1b9aa..58f6e0048d 100644 --- a/button/lib/filled-button.ts +++ b/button/lib/filled-button.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import '../../elevation/elevation.js'; +import '../../elevation/elevation-surface.js'; import {html, TemplateResult} from 'lit'; import {ClassInfo} from 'lit/directives/class-map.js'; @@ -23,6 +23,6 @@ export class FilledButton extends Button { } protected override renderElevation(): TemplateResult { - return html``; + return html``; } } diff --git a/button/lib/tonal-button.ts b/button/lib/tonal-button.ts index 6b836ac823..f7503e5bdd 100644 --- a/button/lib/tonal-button.ts +++ b/button/lib/tonal-button.ts @@ -23,6 +23,6 @@ export class TonalButton extends Button { } protected override renderElevation(): TemplateResult { - return html``; + return html``; } } diff --git a/chips/lib/_shared.scss b/chips/lib/_shared.scss index 45dfed565f..82b26ad436 100644 --- a/chips/lib/_shared.scss +++ b/chips/lib/_shared.scss @@ -137,11 +137,6 @@ opacity: var(--_elevated-disabled-container-opacity); } - md-elevation { - inset: 0; - position: absolute; - } - md-focus-ring { @include focus-ring.theme( ( diff --git a/chips/lib/chip.ts b/chips/lib/chip.ts index 8999d9bddd..1437b615f8 100644 --- a/chips/lib/chip.ts +++ b/chips/lib/chip.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import '../../elevation/elevation.js'; +import '../../elevation/elevation-surface.js'; import '../../focus/focus-ring.js'; import '../../ripple/ripple.js'; @@ -49,7 +49,7 @@ export class Chip extends LitElement { @focus=${this.handleFocus} @pointerdown=${this.handlePointerDown} ${ripple(this.getRipple)}> - + ${when(this.showRipple, this.renderRipple)} diff --git a/dialog/lib/_dialog.scss b/dialog/lib/_dialog.scss index 271a28d9e6..24692b7213 100644 --- a/dialog/lib/_dialog.scss +++ b/dialog/lib/_dialog.scss @@ -115,11 +115,7 @@ padding-block-end: var(--_container-block-padding); } - md-elevation { - position: absolute; - inset: 0; - border-radius: inherit; - + md-elevation-surface { @include elevation.theme( ( level: var(--_container-elevation), diff --git a/dialog/lib/dialog.ts b/dialog/lib/dialog.ts index 5985648998..7acc5f7415 100644 --- a/dialog/lib/dialog.ts +++ b/dialog/lib/dialog.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import '../../elevation/elevation.js'; +import '../../elevation/elevation-surface.js'; import {html, LitElement, PropertyValues} from 'lit'; import {property, query, state} from 'lit/decorators.js'; @@ -275,7 +275,7 @@ export class Dialog extends LitElement { @pointermove=${this.handlePointerMove} @pointerup=${this.handleDragEnd} > - +
diff --git a/elevation/elevation-surface.ts b/elevation/elevation-surface.ts new file mode 100644 index 0000000000..feb6f02465 --- /dev/null +++ b/elevation/elevation-surface.ts @@ -0,0 +1,26 @@ +/** + * @license + * Copyright 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import {customElement} from 'lit/decorators.js'; + +import {styles} from './lib/elevation-styles.css.js'; +import {ElevationSurface} from './lib/elevation-surface.js'; +import {styles as surfaceStyles} from './lib/surface-styles.css.js'; + +declare global { + interface HTMLElementTagNameMap { + 'md-elevation-surface': MdElevationSurface; + } +} + +/** + * @deprecated An elevation component with a surface-tint. Will be removed + * once components are updated. + */ +@customElement('md-elevation-surface') +export class MdElevationSurface extends ElevationSurface { + static override styles = [styles, surfaceStyles]; +} diff --git a/elevation/lib/_elevation.scss b/elevation/lib/_elevation.scss index b23d2f926f..0db02d4418 100644 --- a/elevation/lib/_elevation.scss +++ b/elevation/lib/_elevation.scss @@ -9,17 +9,26 @@ // go/keep-sorted start @use '../../sass/theme'; @use '../../sass/var'; -@use './md-comp-elevation'; +@use '../../tokens'; // go/keep-sorted end @mixin theme($tokens) { - $tokens: theme.validate-theme(md-comp-elevation.values(), $tokens); + $tokens: theme.validate-theme( + map.merge( + tokens.md-comp-elevation-values(), + ( + // TODO(b/272526637): remove after surface is removed + 'surface-tint': null + ) + ), + $tokens + ); $tokens: theme.create-theme-vars($tokens, 'elevation'); @include theme.emit-theme-vars($tokens); } @mixin styles() { - $tokens: md-comp-elevation.values(); + $tokens: tokens.md-comp-elevation-values(); $tokens: theme.create-theme-vars($tokens, 'elevation'); :host { @@ -27,28 +36,27 @@ --_#{$token}: #{$value}; } - border-radius: inherit; display: flex; pointer-events: none; - position: relative; - } - - :host(:not([surface])) .surface, - :host(:not([shadow])) .shadow { - display: none; + transition-duration: var(--_duration); + transition-timing-function: var(--_easing); } - .surface, + :host, .shadow, .shadow::before, .shadow::after { border-radius: inherit; - content: ''; inset: 0; position: absolute; + } + + .shadow::before, + .shadow::after { + content: ''; + transition-duration: inherit; transition-property: box-shadow, opacity; - transition-duration: var(--_duration); - transition-timing-function: var(--_easing); + transition-timing-function: inherit; } // Key box shadows @@ -165,38 +173,4 @@ opacity: 0.15; box-shadow: 0px $y $blur $spread var(--_shadow-color); } - - .surface { - // Surface tint opacities: - // level0: opacity: 0; - // level1: opacity: 0.05; - // level2: opacity: 0.08; - // level3: opacity: 0.11; - // level4: opacity: 0.12; - // level5: opacity: 0.14; - - // Add a clamped value for each level to build the correct values. - // Sass will simplify nested calc()s. - - // 0 + 0 = 0 - // $level0-opacity: 0; // +0 is a no-op - // 0 + 0.05 = 0.05 - $level1-opacity: clamp(0, var(--_level), 0.05); - // 0.05 + 0.03 = 0.08 - $level2-opacity: clamp(0, var(--_level) - 1, 0.03); - // 0.08 + 0.03 = 0.11 - $level3-opacity: clamp(0, var(--_level) - 2, 0.03); - // (can't simplify levels 2-3 since the value is < 1) - // 0.11 + 0.01 = 0.12 - $level4-opacity: clamp(0, var(--_level) - 3, 0.01); - // 0.12 + 0.02 = 0.14 - $level5-opacity: clamp(0, var(--_level) - 4, 0.02); - $opacity: calc( - $level1-opacity + $level2-opacity + $level3-opacity + $level4-opacity + - $level5-opacity - ); - - background: var(--_surface-tint); - opacity: $opacity; - } } diff --git a/elevation/lib/_md-comp-elevation.scss b/elevation/lib/_md-comp-elevation.scss deleted file mode 100644 index 4f33f204f3..0000000000 --- a/elevation/lib/_md-comp-elevation.scss +++ /dev/null @@ -1,27 +0,0 @@ -// -// Copyright 2022 Google LLC -// SPDX-License-Identifier: Apache-2.0 -// - -// go/keep-sorted start -@use 'sass:map'; -// go/keep-sorted end -// go/keep-sorted start -@use '../../tokens'; -// go/keep-sorted end - -$_default-deps: ( - md-sys-color: tokens.md-sys-color-values-light(), - md-sys-elevation: tokens.md-sys-elevation-values(), - md-sys-motion: tokens.md-sys-motion-values(), -); - -@function values($deps: $_default-deps, $exclude-hardcoded-values: false) { - @return ( - duration: if($exclude-hardcoded-values, null, 0s), - easing: map.get($deps, md-sys-motion, easing-emphasized), - level: map.get($deps, md-sys-elevation, level0), - shadow-color: map.get($deps, md-sys-color, shadow), - surface-tint: map.get($deps, md-sys-color, surface-tint) - ); -} diff --git a/elevation/lib/_surface.scss b/elevation/lib/_surface.scss new file mode 100644 index 0000000000..fa8ed1aed3 --- /dev/null +++ b/elevation/lib/_surface.scss @@ -0,0 +1,47 @@ +// +// Copyright 2023 Google LLC +// SPDX-License-Identifier: Apache-2.0 +// + +/// @deprecated Remove once components are updated for tonal surfaces +@mixin styles() { + .surface { + // Surface tint opacities: + // level0: opacity: 0; + // level1: opacity: 0.05; + // level2: opacity: 0.08; + // level3: opacity: 0.11; + // level4: opacity: 0.12; + // level5: opacity: 0.14; + + // Add a clamped value for each level to build the correct values. + // Sass will simplify nested calc()s. + + // 0 + 0 = 0 + // $level0-opacity: 0; // +0 is a no-op + // 0 + 0.05 = 0.05 + $level1-opacity: clamp(0, var(--_level), 0.05); + // 0.05 + 0.03 = 0.08 + $level2-opacity: clamp(0, var(--_level) - 1, 0.03); + // 0.08 + 0.03 = 0.11 + $level3-opacity: clamp(0, var(--_level) - 2, 0.03); + // (can't simplify levels 2-3 since the value is < 1) + // 0.11 + 0.01 = 0.12 + $level4-opacity: clamp(0, var(--_level) - 3, 0.01); + // 0.12 + 0.02 = 0.14 + $level5-opacity: clamp(0, var(--_level) - 4, 0.02); + $opacity: calc( + $level1-opacity + $level2-opacity + $level3-opacity + $level4-opacity + + $level5-opacity + ); + + background: var( + --md-elevation-surface-tint, + var(--md-sys-color-surface-tint, #6750a4) + ); + border-radius: inherit; + inset: 0; + opacity: $opacity; + position: absolute; + } +} diff --git a/elevation/lib/elevation-surface.ts b/elevation/lib/elevation-surface.ts new file mode 100644 index 0000000000..dea7683182 --- /dev/null +++ b/elevation/lib/elevation-surface.ts @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import {html, nothing} from 'lit'; +import {property} from 'lit/decorators.js'; + +import {Elevation} from './elevation.js'; + +/** + * @deprecated An elevation component with a surface-tint. Will be removed + * once components are updated. + */ +export class ElevationSurface extends Elevation { + /** + * Whether or not the elevation level should display a shadow. + */ + @property({type: Boolean}) shadow = false; + + override render() { + return html` + + ${this.shadow ? super.render() : nothing} + `; + } +} diff --git a/elevation/lib/elevation.ts b/elevation/lib/elevation.ts index a91306e718..07974be97c 100644 --- a/elevation/lib/elevation.ts +++ b/elevation/lib/elevation.ts @@ -5,25 +5,12 @@ */ import {html, LitElement} from 'lit'; -import {property} from 'lit/decorators.js'; /** * A component for elevation. */ export class Elevation extends LitElement { - /** - * Whether or not the elevation level should display a shadow. - */ - @property({type: Boolean, reflect: true}) shadow = false; - /** - * Whether or not the elevation level should display a surface tint color. - */ - @property({type: Boolean, reflect: true}) surface = false; - override render() { - return html` - - - `; + return html``; } } diff --git a/elevation/lib/surface-styles.scss b/elevation/lib/surface-styles.scss new file mode 100644 index 0000000000..2489428638 --- /dev/null +++ b/elevation/lib/surface-styles.scss @@ -0,0 +1,10 @@ +// +// Copyright 2023 Google LLC +// SPDX-License-Identifier: Apache-2.0 +// + +// go/keep-sorted start +@use './surface'; +// go/keep-sorted end + +@include surface.styles; diff --git a/fab/lib/_shared.scss b/fab/lib/_shared.scss index 1df4b20614..193dcca457 100644 --- a/fab/lib/_shared.scss +++ b/fab/lib/_shared.scss @@ -136,9 +136,7 @@ } } - md-elevation { - inset: 0; - position: absolute; + md-elevation-surface { z-index: -1; // Place behind content } diff --git a/fab/lib/fab-shared.ts b/fab/lib/fab-shared.ts index d749c74598..04da9f242c 100644 --- a/fab/lib/fab-shared.ts +++ b/fab/lib/fab-shared.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import '../../elevation/elevation.js'; +import '../../elevation/elevation-surface.js'; import '../../focus/focus-ring.js'; import '../../ripple/ripple.js'; @@ -87,7 +87,7 @@ export abstract class FabShared extends LitElement { /** @soyTemplate */ protected renderElevation(): TemplateResult { - return html``; + return html``; } /** @soyTemplate */ diff --git a/menu/lib/_menu.scss b/menu/lib/_menu.scss index 52e7ea3593..5392fbfa3b 100644 --- a/menu/lib/_menu.scss +++ b/menu/lib/_menu.scss @@ -103,11 +103,6 @@ $_custom-property-prefix: 'menu'; max-height: inherit; } } - - md-elevation { - position: absolute; - inset: 0; - } } @function _resolve-tokens($tokens) { diff --git a/menu/lib/menu.ts b/menu/lib/menu.ts index 61c382d590..69b4de2d3d 100644 --- a/menu/lib/menu.ts +++ b/menu/lib/menu.ts @@ -8,7 +8,7 @@ // tslint:disable:no-new-decorators import '../../list/list.js'; import '../../focus/focus-ring.js'; -import '../../elevation/elevation.js'; +import '../../elevation/elevation-surface.js'; import {html, isServer, LitElement} from 'lit'; import {eventOptions, property, query, state} from 'lit/decorators.js'; @@ -297,7 +297,7 @@ export abstract class Menu extends LitElement { * Renders the elevation component. */ protected renderElevation() { - return html``; + return html``; } /** diff --git a/navigationbar/lib/_navigation-bar.scss b/navigationbar/lib/_navigation-bar.scss index f32189c637..a035634b67 100644 --- a/navigationbar/lib/_navigation-bar.scss +++ b/navigationbar/lib/_navigation-bar.scss @@ -57,9 +57,7 @@ } } - md-elevation { - inset: 0; - position: absolute; + md-elevation-surface { z-index: 0; } } diff --git a/navigationbar/lib/navigation-bar.ts b/navigationbar/lib/navigation-bar.ts index 71a8e746c7..f2b85a0806 100644 --- a/navigationbar/lib/navigation-bar.ts +++ b/navigationbar/lib/navigation-bar.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import '../../elevation/elevation.js'; +import '../../elevation/elevation-surface.js'; import {html, LitElement, PropertyValues, TemplateResult} from 'lit'; import {property, queryAssignedElements} from 'lit/decorators.js'; @@ -41,8 +41,8 @@ export class NavigationBar extends LitElement implements NavigationBarState { @keydown="${this.handleKeydown}" @navigation-tab-interaction="${this.handleNavigationTabInteraction}" @navigation-tab-rendered=${this.handleNavigationTabConnected} - >
`; } diff --git a/navigationdrawer/lib/_navigation-drawer.scss b/navigationdrawer/lib/_navigation-drawer.scss index 0e3112a70c..8b71f109a8 100644 --- a/navigationdrawer/lib/_navigation-drawer.scss +++ b/navigationdrawer/lib/_navigation-drawer.scss @@ -77,9 +77,6 @@ $_custom-property-prefix: 'navigation-drawer'; } md-elevation { - inset: 0; - position: absolute; - width: inherit; z-index: 0; } diff --git a/navigationdrawer/lib/navigation-drawer.ts b/navigationdrawer/lib/navigation-drawer.ts index 8f3235fbe8..7b47fbaf7a 100644 --- a/navigationdrawer/lib/navigation-drawer.ts +++ b/navigationdrawer/lib/navigation-drawer.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import '../../elevation/elevation.js'; +import '../../elevation/elevation-surface.js'; import {html, LitElement, PropertyValues, TemplateResult} from 'lit'; import {property} from 'lit/decorators.js'; @@ -56,7 +56,7 @@ export class NavigationDrawer extends LitElement { aria-modal="${this.ariaModal}" class="md3-navigation-drawer ${this.getRenderClasses()}" role="dialog"> - +
diff --git a/slider/lib/_slider.scss b/slider/lib/_slider.scss index ce3b0c68f8..c58a3bfc9c 100644 --- a/slider/lib/_slider.scss +++ b/slider/lib/_slider.scss @@ -9,7 +9,7 @@ @use 'sass:map'; // go/keep-sorted end // go/keep-sorted start -@use '../../elevation/lib/elevation'; +@use '../../elevation/elevation'; @use '../../focus/focus-ring'; @use '../../ripple/ripple'; @use '../../sass/color'; @@ -491,10 +491,4 @@ height: var(--_state-layer-size); width: var(--_state-layer-size); } - - // Elevation - md-elevation { - position: absolute; - inset: 0; - } } diff --git a/slider/lib/slider.ts b/slider/lib/slider.ts index d6e9bab7a2..d1fd14d7ef 100644 --- a/slider/lib/slider.ts +++ b/slider/lib/slider.ts @@ -414,7 +414,7 @@ export class Slider extends LitElement { })}"> -
+
${when(this.withLabel, () => this.renderLabel(label))}
diff --git a/tokens/_index.scss b/tokens/_index.scss index da627530dc..6fd1d5305a 100644 --- a/tokens/_index.scss +++ b/tokens/_index.scss @@ -20,6 +20,7 @@ @forward './md-comp-divider' as md-comp-divider-*; @forward './md-comp-elevated-button' as md-comp-elevated-button-*; @forward './md-comp-elevated-card' as md-comp-elevated-card-*; +@forward './md-comp-elevation' as md-comp-elevation-*; @forward './md-comp-extended-fab-branded' as md-comp-extended-fab-branded-*; @forward './md-comp-extended-fab-primary' as md-comp-extended-fab-primary-*; @forward './md-comp-extended-fab-secondary' as md-comp-extended-fab-secondary-*; diff --git a/tokens/_md-comp-elevation.scss b/tokens/_md-comp-elevation.scss new file mode 100644 index 0000000000..a0b5ee7790 --- /dev/null +++ b/tokens/_md-comp-elevation.scss @@ -0,0 +1,28 @@ +// +// Copyright 2022 Google LLC +// SPDX-License-Identifier: Apache-2.0 +// + +// go/keep-sorted start +@use 'sass:map'; +// go/keep-sorted end +// go/keep-sorted start +@use './md-sys-color'; +@use './md-sys-elevation'; +@use './md-sys-motion'; +// go/keep-sorted end + +$_default: ( + 'md-sys-color': md-sys-color.values-light(), + 'md-sys-elevation': md-sys-elevation.values(), + 'md-sys-motion': md-sys-motion.values(), +); + +@function values($deps: $_default, $exclude-hardcoded-values: false) { + @return ( + 'duration': if($exclude-hardcoded-values, null, 0s), + 'easing': map.get($deps, 'md-sys-motion', 'easing-emphasized'), + 'level': map.get($deps, 'md-sys-elevation', 'level0'), + 'shadow-color': map.get($deps, 'md-sys-color', 'shadow') + ); +}