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 ?? '';