@function mdc-textfield-transition($property) { @return #{$property} 180ms $mdc-animation-fast-out-slow-in-timing-function; } // postcss-bem-linter: define textfield .mdc-textfield { @include mdc-typography-base; // We use only a subset of the MDC typography values here as changing things such as line-height // affects how the labels are transformed. @each $prop in (font-size, letter-spacing) { #{$prop}: map-get(map-get($mdc-typography-styles, subheading2), $prop); } display: inline-block; margin-bottom: 8px; will-change: opacity, transform, color; &__input { @include mdc-theme-prop(color, text-primary-on-light); padding: 0 0 8px; border: none; background: none; font-size: inherit; appearance: none; &::placeholder { @include mdc-theme-prop(color, text-hint-on-light); transition: mdc-textfield-transition(color); opacity: 1; } &:focus { outline: none; &::placeholder { @include mdc-theme-prop(color, text-secondary-on-light); } } // Remove red outline on firefox &:invalid { box-shadow: none; } @include mdc-theme-dark { color: white; &::placeholder { @include mdc-theme-prop(color, text-hint-on-dark); } &:focus::placeholder { @include mdc-theme-prop(color, text-secondary-on-dark); } } } &__label { @include mdc-theme-prop(color, text-hint-on-light); position: absolute; bottom: 8px; left: 0; transform-origin: left top; transition: mdc-textfield-transition(transform), mdc-textfield-transition(color); cursor: text; // stylelint-disable plugin/selector-bem-pattern @include mdc-rtl(".mdc-textfield") { right: 0; left: auto; transform-origin: right top; } // stylelint-enable plugin/selector-bem-pattern @include mdc-theme-dark(".mdc-textfield") { @include mdc-theme-prop(color, text-hint-on-dark); } &--float-above { transform: translateY(-100%) scale(.75, .75); cursor: auto; } } } // Move label when textfield gets autofilled in Chrome .mdc-textfield__input { // stylelint-disable plugin/selector-bem-pattern &:-webkit-autofill + .mdc-textfield__label { transform: translateY(-100%) scale(.75, .75); cursor: auto; } // stylelint-enable plugin/selector-bem-pattern } .mdc-textfield--upgraded:not(.mdc-textfield--fullwidth) { display: inline-flex; position: relative; box-sizing: border-box; align-items: flex-end; margin-top: 16px; &:not(.mdc-textfield--multiline) { height: 48px; &::after { position: absolute; bottom: 0; left: 0; width: 100%; height: 1px; transform: translateY(50%) scaleY(1); transform-origin: center bottom; transition: mdc-textfield-transition(background-color), mdc-textfield-transition(transform); background-color: $mdc-textfield-divider-on-light; content: ""; @include mdc-theme-dark(".mdc-textfield") { background-color: $mdc-textfield-divider-on-dark; } } } .mdc-textfield__label { pointer-events: none; } } .mdc-textfield--focused { @mixin mdc-textfield-after-styles { @include mdc-theme-prop(background-color, primary); transform: translateY(100%) scaleY(2); transition: mdc-textfield-transition(transform); } @mixin mdc-textfield-label-styles { @include mdc-theme-prop(color, primary); } &.mdc-textfield--upgraded:not(.mdc-textfield--fullwidth):not(.mdc-textfield--multiline)::after { @include mdc-textfield-after-styles; @include mdc-theme-dark(".mdc-textfield", true) { @include mdc-textfield-after-styles; } } .mdc-textfield__label { @include mdc-textfield-label-styles; @include mdc-theme-dark(".mdc-textfield") { @include mdc-textfield-label-styles; } } } .mdc-textfield--dense { margin-top: 12px; margin-bottom: 4px; font-size: .813rem; .mdc-textfield__label--float-above { // NOTE: This is an eyeball'd approximation of what's in the mocks. transform: translateY(calc(-100% - 2px)) scale(.923, .923); } } .mdc-textfield--invalid { &:not(.mdc-textfield--focused) { &::after { background-color: $mdc-textfield-error-on-light; } .mdc-textfield__label { color: $mdc-textfield-error-on-light; } } @include mdc-theme-dark(".mdc-textfield", true) { &:not(.mdc-textfield--focused) { &::after { background-color: $mdc-textfield-error-on-dark; } .mdc-textfield__label { color: $mdc-textfield-error-on-dark; } } } } .mdc-textfield--disabled { &::after { display: none; } // Account for offset by border .mdc-textfield__input { padding-bottom: 7px; } border-bottom: 1px dotted $mdc-textfield-disabled-border-on-light; @include mdc-theme-dark(".mdc-textfield", true) { border-bottom: 1px dotted $mdc-textfield-disabled-border-on-dark; } // stylelint-disable plugin/selector-bem-pattern .mdc-textfield__input, .mdc-textfield__label, & + .mdc-textfield-helptext { @include mdc-theme-prop(color, text-disabled-on-light); } // stylelint-enable plugin/selector-bem-pattern .mdc-textfield__input, .mdc-textfield__label { @include mdc-theme-dark(".mdc-textfield") { @include mdc-theme-prop(color, text-disabled-on-dark); } } @include mdc-theme-dark(".mdc-textfield", true) { // stylelint-disable plugin/selector-bem-pattern + .mdc-textfield-helptext { @include mdc-theme-prop(colr, text-disabled-on-dark); } // stylelint-enable plugin/selector-bem-pattern } .mdc-textfield__label { bottom: 7px; cursor: default; } } .mdc-textfield__input:required + .mdc-textfield__label::after { margin-left: 1px; content: "*"; .mdc-textfield--focused & { color: $mdc-textfield-error-on-light; } @include mdc-theme-dark(".mdc-textfield") { .mdc-textfield--focused & { color: $mdc-textfield-error-on-dark; } } } .mdc-textfield--multiline { $padding-inset: 4px; $label-offset-y: $padding-inset + 2; $label-offset-x: $padding-inset; display: flex; height: initial; transition: none; &::after { content: initial; } // stylelint-disable plugin/selector-bem-pattern .mdc-textfield__input { padding: $padding-inset; transition: mdc-textfield-transition(border-color); border: 1px solid $mdc-textfield-divider-on-light; border-radius: 2px; @include mdc-theme-dark(".mdc-textfield") { border-color: $mdc-textfield-divider-on-dark; } &:focus { @include mdc-theme-prop(border-color, primary); } &:invalid:not(:focus) { border-color: $mdc-textfield-error-on-light; } @include mdc-theme-dark(".mdc-textfield") { &:invalid:not(:focus) { border-color: $mdc-textfield-error-on-dark; } } } .mdc-textfield__label { top: $label-offset-y; bottom: initial; left: $label-offset-x; @include mdc-rtl(".mdc-textfield--multiline") { right: $label-offset-x; left: auto; } &--float-above { // Translate above the top of the input, and compensate for the amount of offset needed // to position the label within the bounds of the inset padding. // Note that the scale factor is an eyeball'd approximation of what's shown in the mocks. transform: translateY(calc(-100% - #{$label-offset-y})) scale(.923, .923); } } &.mdc-textfield--disabled { border-bottom: none; .mdc-textfield__input { border: 1px dotted $mdc-textfield-disabled-border-on-light; @include mdc-theme-dark(".mdc-textfield") { border-color: $mdc-textfield-disabled-border-on-dark; } } } // stylelint-enable plugin/selector-bem-pattern } .mdc-textfield--fullwidth { display: block; width: 100%; box-sizing: border-box; margin: 0; border: none; border-bottom: 1px solid $mdc-textfield-divider-on-light; outline: none; // stylelint-disable plugin/selector-bem-pattern &:not(.mdc-textfield--multiline) { height: 56px; } &.mdc-textfield--multiline { padding: 20px 0 0; } &.mdc-textfield--dense { &:not(.mdc-textfield--multiline) { height: 48px; } &.mdc-textfield--multiline { padding: 16px 0 0; } } &.mdc-textfield--disabled { &, &.mdc-textfield--multiline { border-bottom: 1px dotted $mdc-textfield-divider-on-light; } } @include mdc-theme-dark { border-bottom: 1px solid $mdc-textfield-divider-on-dark; &.mdc-textfield--disabled { &, &.mdc-textfield--multiline { border-bottom: 1px dotted $mdc-textfield-divider-on-dark; } } } // stylelint-enable plugin/selector-bem-pattern .mdc-textfield__input { width: 100%; height: 100%; padding: 0; resize: none; // Use !important here to override all other border treatments border: none !important; } } // Graceful degredation for css-only inputs .mdc-textfield { &:not(.mdc-textfield--upgraded):not(.mdc-textfield--multiline) .mdc-textfield__input { transition: mdc-textfield-transition(border-bottom-color); border-bottom: 1px solid $mdc-textfield-divider-on-light; } &:not(.mdc-textfield--upgraded) .mdc-textfield__input { &:focus { @include mdc-theme-prop(border-color, primary); } &:disabled { @include mdc-theme-prop(color, text-disabled-on-light); border-style: dotted; border-color: $mdc-textfield-disabled-border-on-light; } &:invalid:not(:focus) { border-color: $mdc-textfield-error-on-light; } } @include mdc-theme-dark { &:not(.mdc-textfield--upgraded) .mdc-textfield__input { &:not(:focus) { border-color: rgba(white, .12); } &:disabled { @include mdc-theme-prop(color, text-disabled-on-dark); border-color: $mdc-textfield-disabled-border-on-dark; } &:invalid:not(:focus) { border-color: $mdc-textfield-error-on-dark; } } } } // postcss-bem-linter: end // postcss-bem-linter: define textfield-helptext .mdc-textfield-helptext { @include mdc-theme-prop(color, text-hint-on-light); margin: 0; transition: mdc-textfield-transition(opacity); font-size: .75rem; opacity: 0; will-change: opacity; @include mdc-theme-dark { @include mdc-theme-prop(color, text-hint-on-dark); } // stylelint-disable plugin/selector-bem-pattern .mdc-textfield + & { margin-bottom: 8px; } .mdc-textfield--dense + & { margin-bottom: 4px; } .mdc-textfield--focused + &:not(#{&}--validation-msg) { opacity: 1; } // stylelint-enable plugin/selector-bem-pattern } .mdc-textfield-helptext--persistent { transition: none; opacity: 1; will-change: initial; } // postcss-bem-linter: end .mdc-textfield--invalid { + .mdc-textfield-helptext--validation-msg { color: $mdc-textfield-error-on-light; opacity: 1; } @include mdc-theme-dark(".mdc-textfield", true) { + .mdc-textfield-helptext--validation-msg { color: $mdc-textfield-error-on-dark; } } } // mdc-form-field tweaks to align text field label correctly // stylelint-disable selector-no-type .mdc-form-field > .mdc-textfield + label { align-self: flex-start; } // stylelint-enable selector-no-type