diff --git a/field/lib/_content.scss b/field/lib/_content.scss index 8ca2470fce..500571e09b 100644 --- a/field/lib/_content.scss +++ b/field/lib/_content.scss @@ -56,58 +56,42 @@ $_enter-delay: $_label-duration - $_visible-duration; // Content elements provided to the field (such as ) may use // `currentColor` to inherit this property. color: var(--_content-color); + } - .no-label &, - .focused &, - .populated & { - opacity: 1; - transition-delay: $_enter-delay; - } + .no-label .content, + .focused .content, + .populated .content { + opacity: 1; + transition-delay: $_enter-delay; } - .disabled { - &.no-label, - &.focused, - &.populated { - .content { - opacity: var(--_disabled-content-opacity); - } - } + .disabled.no-label .content, + .disabled.focused .content, + .disabled.populated .content { + opacity: var(--_disabled-content-opacity); } - :hover { - .content { - color: var(--_hover-content-color); - } + :hover .content { + color: var(--_hover-content-color); } - .focused { - .content { - color: var(--_focus-content-color); - } + .focused .content { + color: var(--_focus-content-color); } - .disabled { - .content { - color: var(--_disabled-content-color); - } + .disabled .content { + color: var(--_disabled-content-color); } - .error:not(.disabled) { - .content { - color: var(--_error-content-color); - } + .error .content { + color: var(--_error-content-color); + } - &:hover { - .content { - color: var(--_error-hover-content-color); - } - } + .error:hover .content { + color: var(--_error-hover-content-color); + } - &.focused { - .content { - color: var(--_error-focus-content-color); - } - } + .error.focused .content { + color: var(--_error-focus-content-color); } } diff --git a/field/lib/_filled-field.scss b/field/lib/_filled-field.scss index d007f1fe99..acf3ddcc00 100644 --- a/field/lib/_filled-field.scss +++ b/field/lib/_filled-field.scss @@ -76,7 +76,7 @@ $_animation-duration: 150ms; } } - .label--floating { + .label.floating { position: absolute; top: 0; } @@ -88,10 +88,10 @@ $_animation-duration: 150ms; width: 100%; visibility: hidden; z-index: -1; + } - .field:not(.disabled):hover & { - visibility: visible; - } + .field:not(.disabled):hover .state-layer { + visibility: visible; } .active-indicator { @@ -126,49 +126,34 @@ $_animation-duration: 150ms; transition: animation.standard(opacity, $_animation-duration), transform 0s ease $_animation-duration; } - - .focused & { - &::after { - opacity: 1; - transform: scaleX(1); - transition: animation.standard(transform, $_animation-duration); - } - } } - .field:not(.with-start) { - .start { - padding-inline-start: var(--_container-padding-horizontal); - } + .focused .active-indicator::after { + opacity: 1; + transform: scaleX(1); + transition: animation.standard(transform, $_animation-duration); } - .field:not(.with-end) { - .end { - padding-inline-end: var(--_container-padding-horizontal); - } + .field:not(.with-start) .start { + padding-inline-start: var(--_container-padding-horizontal); } - .field:not(.no-label) { - .container { - padding-bottom: var(--_with-label-container-padding-vertical); - padding-top: var(--_with-label-container-padding-vertical); - } + .field:not(.with-end) .end { + padding-inline-end: var(--_container-padding-horizontal); + } - .middle { - padding-top: var(--_label-text-populated-line-height); - } + .field:not(.no-label) .container { + padding-bottom: var(--_with-label-container-padding-vertical); + padding-top: var(--_with-label-container-padding-vertical); } - :hover { - .active-indicator::before { - border-bottom-color: var(--_hover-active-indicator-color); - border-bottom-width: var(--_hover-active-indicator-height); - } + .field:not(.no-label) .middle { + padding-top: var(--_label-text-populated-line-height); + } - .state-layer { - background: var(--_hover-state-layer-color); - opacity: var(--_hover-state-layer-opacity); - } + :hover .active-indicator::before { + border-bottom-color: var(--_hover-active-indicator-color); + border-bottom-width: var(--_hover-active-indicator-height); } // Focus is on a separate element and does not need a focus selector @@ -177,38 +162,37 @@ $_animation-duration: 150ms; border-bottom-width: var(--_focus-active-indicator-height); } - .disabled { - .active-indicator::before { - border-bottom-color: var(--_disabled-active-indicator-color); - border-bottom-width: var(--_disabled-active-indicator-height); - opacity: var(--_disabled-active-indicator-opacity); - } + :hover .state-layer { + background: var(--_hover-state-layer-color); + opacity: var(--_hover-state-layer-opacity); + } - .container::before { - background: var(--_disabled-container-color); - opacity: var(--_disabled-container-opacity); - } + .disabled .active-indicator::before { + border-bottom-color: var(--_disabled-active-indicator-color); + border-bottom-width: var(--_disabled-active-indicator-height); + opacity: var(--_disabled-active-indicator-opacity); } - .error:not(.disabled) { - .active-indicator::before { - border-bottom-color: var(--_error-active-indicator-color); - } + .disabled .container::before { + background: var(--_disabled-container-color); + opacity: var(--_disabled-container-opacity); + } + + .error .active-indicator::before { + border-bottom-color: var(--_error-active-indicator-color); + } - &:hover { - .active-indicator::before { - border-bottom-color: var(--_error-hover-active-indicator-color); - } + .error:hover .active-indicator::before { + border-bottom-color: var(--_error-hover-active-indicator-color); + } - .state-layer { - background: var(--_error-hover-state-layer-color); - opacity: var(--_error-hover-state-layer-opacity); - } - } + .error:hover .state-layer { + background: var(--_error-hover-state-layer-color); + opacity: var(--_error-hover-state-layer-opacity); + } - // Focus is on a separate element and does not need a focus selector - .active-indicator::after { - border-bottom-color: var(--_error-focus-active-indicator-color); - } + // Focus is on a separate element and does not need a focus selector + .error .active-indicator::after { + border-bottom-color: var(--_error-focus-active-indicator-color); } } diff --git a/field/lib/_label.scss b/field/lib/_label.scss index 0519d8b215..f7d9e269eb 100644 --- a/field/lib/_label.scss +++ b/field/lib/_label.scss @@ -35,7 +35,7 @@ ); } - .label--resting { + .label.resting { position: absolute; top: 50%; transform: translateY(-50%); @@ -50,7 +50,7 @@ ); } - .label--floating { + .label.floating { @include typography.theme-styles( ( size: var(--_label-text-populated-size), @@ -59,53 +59,39 @@ ); } - .label--hidden { + .label.hidden { opacity: 0; } - .no-label { - .label { - display: none; - } + .no-label .label { + display: none; } - :hover { - .label { - color: var(--_hover-label-text-color); - } + :hover .label { + color: var(--_hover-label-text-color); } - .focused { - .label { - color: var(--_focus-label-text-color); - } + .focused .label { + color: var(--_focus-label-text-color); } - .disabled { - .label { - color: var(--_disabled-label-text-color); + .disabled .label { + color: var(--_disabled-label-text-color); + } - &:not(.label--hidden) { - opacity: var(--_disabled-label-text-opacity); - } - } + .disabled .label:not(.hidden) { + opacity: var(--_disabled-label-text-opacity); } - .error:not(.disabled) { - .label { - color: var(--_error-label-text-color); - } + .error .label { + color: var(--_error-label-text-color); + } - &:hover { - .label { - color: var(--_error-hover-label-text-color); - } - } + .error:hover .label { + color: var(--_error-hover-label-text-color); + } - &.focused { - .label { - color: var(--_error-focus-label-text-color); - } - } + .error.focused .label { + color: var(--_error-focus-label-text-color); } } diff --git a/field/lib/_outlined-field.scss b/field/lib/_outlined-field.scss index cbdcc5565c..f433eacc88 100644 --- a/field/lib/_outlined-field.scss +++ b/field/lib/_outlined-field.scss @@ -87,12 +87,11 @@ $_animation-duration: 150ms; opacity: 0; transition: animation.standard(opacity, $_animation-duration); } + } - .focused & { - &::after { - opacity: 1; - } - } + .focused .outline-start::after, + .focused .outline-end::after { + opacity: 1; } .outline-start { @@ -132,10 +131,10 @@ $_animation-duration: 150ms; max-width: calc(100% - 2 * var(--_container-padding-horizontal)); padding: 0 var(--_outline-label-padding); position: relative; + } - .no-label & { - display: none; - } + .no-label .outline-notch { + display: none; } .outline-panel-inactive, @@ -165,26 +164,28 @@ $_animation-duration: 150ms; left: 50%; transform-origin: top right; } + } - .populated &, - .focused & { - &::before, - &::after { - transform: scaleX(0); - } + .populated .outline-panel-inactive, + .populated .outline-panel-active, + .focused .outline-panel-inactive, + .focused .outline-panel-active { + &::before, + &::after { + transform: scaleX(0); } } .outline-panel-active { opacity: 0; transition: animation.standard(opacity, $_animation-duration); + } - .focused & { - opacity: 1; - } + .focused .outline-panel-active { + opacity: 1; } - .label--floating { + .label.floating { // Center the label within the outline stroke transform: translateY(calc(-100% + var(--_label-text-padding-bottom))); } @@ -210,10 +211,8 @@ $_animation-duration: 150ms; ); } - .field:not(.with-end) { - .end { - padding-inline-end: max(var(--_container-padding-horizontal), $shape-end); - } + .field:not(.with-end) .end { + padding-inline-end: max(var(--_container-padding-horizontal), $shape-end); } .outline-start::before, @@ -226,26 +225,22 @@ $_animation-duration: 150ms; // States - :hover { - .outline { - border-color: var(--_hover-outline-color); - color: var(--_hover-outline-color); // Needed for Firefox HCM - } + :hover .outline { + border-color: var(--_hover-outline-color); + color: var(--_hover-outline-color); // Needed for Firefox HCM + } - .outline-start::before, - .outline-end::before, - .outline-panel-inactive, - .outline-panel-inactive::before, - .outline-panel-inactive::after { - border-width: var(--_hover-outline-width); - } + :hover .outline-start::before, + :hover .outline-end::before, + :hover .outline-panel-inactive, + :hover .outline-panel-inactive::before, + :hover .outline-panel-inactive::after { + border-width: var(--_hover-outline-width); } - .focused { - .outline { - border-color: var(--_focus-outline-color); - color: var(--_focus-outline-color); // Needed for Firefox HCM - } + .focused .outline { + border-color: var(--_focus-outline-color); + color: var(--_focus-outline-color); // Needed for Firefox HCM } .outline-start::after, @@ -256,47 +251,39 @@ $_animation-duration: 150ms; border-width: var(--_focus-outline-width); } - .disabled { - .outline { - border-color: var(--_disabled-outline-color); - color: var(--_disabled-outline-color); // Needed for Firefox HCM - } + .disabled .outline { + border-color: var(--_disabled-outline-color); + color: var(--_disabled-outline-color); // Needed for Firefox HCM + } - .outline-start, - .outline-end, - .outline-panel-inactive { - opacity: var(--_disabled-outline-opacity); - } + .disabled .outline-start, + .disabled .outline-end, + .disabled .outline-panel-inactive { + opacity: var(--_disabled-outline-opacity); + } - .outline-start::before, - .outline-end::before, - .outline-panel-inactive, - .outline-panel-inactive::before, - .outline-panel-inactive::after { - border-width: var(--_disabled-outline-width); - } + .disabled .outline-start::before, + .disabled .outline-end::before, + .disabled .outline-panel-inactive, + .disabled .outline-panel-inactive::before, + .disabled .outline-panel-inactive::after { + border-width: var(--_disabled-outline-width); } - .error:not(.disabled) { - .outline { - border-color: var(--_error-outline-color); - color: var(--_error-outline-color); // Needed for Firefox HCM - } + .error .outline { + border-color: var(--_error-outline-color); + color: var(--_error-outline-color); // Needed for Firefox HCM + } - &:hover { - .outline { - border-color: var(--_error-hover-outline-color); - // Needed for Firefox HCM - color: var(--_error-hover-outline-color); - } - } + .error:hover .outline { + border-color: var(--_error-hover-outline-color); + // Needed for Firefox HCM + color: var(--_error-hover-outline-color); + } - &.focused { - .outline { - border-color: var(--_error-focus-outline-color); - // Needed for Firefox HCM - color: var(--_error-focus-outline-color); - } - } + .error.focused .outline { + border-color: var(--_error-focus-outline-color); + // Needed for Firefox HCM + color: var(--_error-focus-outline-color); } } diff --git a/field/lib/_shared.scss b/field/lib/_shared.scss index fe88221f5a..36946ba5ec 100644 --- a/field/lib/_shared.scss +++ b/field/lib/_shared.scss @@ -49,16 +49,12 @@ min-width: 48px; } - .with-start { - .start { - margin-inline-end: 4px; - } + .with-start .start { + margin-inline-end: 4px; } - .with-end { - .end { - margin-inline-start: 4px; - } + .with-end .end { + margin-inline-start: 4px; } @include content.styles; diff --git a/field/lib/_supporting-text.scss b/field/lib/_supporting-text.scss index 24989d1aa9..9858348412 100644 --- a/field/lib/_supporting-text.scss +++ b/field/lib/_supporting-text.scss @@ -29,54 +29,41 @@ .supporting-text-end { // Can't be an inline display element () for padding-top to work. display: flex; + } + .supporting-text-start ::slotted(:not(:empty)), + .supporting-text-end ::slotted(:not(:empty)) { // Add padding to slotted elements instead of the wrappers so that it does not // show when the supporting text is empty. - ::slotted(:not(:empty)) { - padding-top: var(--_supporting-text-padding-top); - } + padding-top: var(--_supporting-text-padding-top); } - .supporting-text-end { - ::slotted(:not(:empty)) { - padding-inline-start: var(--_supporting-text-padding); - } + .supporting-text-end ::slotted(:not(:empty)) { + padding-inline-start: var(--_supporting-text-padding); } - :hover { - .supporting-text { - color: var(--_hover-supporting-text-color); - } + :hover .supporting-text { + color: var(--_hover-supporting-text-color); } - .focus { - .supporting-text { - color: var(--_focus-supporting-text-color); - } + .focus .supporting-text { + color: var(--_focus-supporting-text-color); } - .disabled { - .supporting-text { - color: var(--_disabled-supporting-text-color); - opacity: var(--_disabled-supporting-text-opacity); - } + .disabled .supporting-text { + color: var(--_disabled-supporting-text-color); + opacity: var(--_disabled-supporting-text-opacity); } - .error:not(.disabled) { - .supporting-text { - color: var(--_error-supporting-text-color); - } + .error .supporting-text { + color: var(--_error-supporting-text-color); + } - &:hover { - .supporting-text { - color: var(--_error-hover-supporting-text-color); - } - } + .error:hover .supporting-text { + color: var(--_error-hover-supporting-text-color); + } - &.focus { - .supporting-text { - color: var(--_error-focus-supporting-text-color); - } - } + .error.focus .supporting-text { + color: var(--_error-focus-supporting-text-color); } } diff --git a/field/lib/field.ts b/field/lib/field.ts index 304a80752f..1ba333d833 100644 --- a/field/lib/field.ts +++ b/field/lib/field.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import {html, LitElement, PropertyValues, TemplateResult} from 'lit'; +import {html, LitElement, PropertyValues} from 'lit'; import {property, queryAsync, state} from 'lit/decorators.js'; import {classMap} from 'lit/directives/class-map.js'; @@ -33,9 +33,9 @@ export class Field extends LitElement { @state() private isAnimating = false; private readonly labelAnimationSignal = createAnimationSignal(); - @queryAsync('.label--floating') + @queryAsync('.label.floating') private readonly floatingLabelEl!: Promise; - @queryAsync('.label--resting') + @queryAsync('.label.resting') private readonly restingLabelEl!: Promise; protected override update(props: PropertyValues) { @@ -56,10 +56,10 @@ export class Field extends LitElement { super.update(props); } - protected override render(): TemplateResult { + protected override render() { const classes = { 'disabled': this.disabled, - 'error': this.error, + 'error': this.error && !this.disabled, 'focused': this.focused, 'with-start': this.hasStart, 'with-end': this.hasEnd, @@ -124,9 +124,9 @@ export class Field extends LitElement { } const classes = { - 'label--hidden': !visible, - 'label--floating': isFloating, - 'label--resting': !isFloating, + 'hidden': !visible, + 'floating': isFloating, + 'resting': !isFloating, }; let labelText = this.label ?? '';