sass-references/angular-material/material/form-field/_mdc-text-field-structure.scss

619 lines
17 KiB
SCSS
Raw Normal View History

2024-12-06 10:42:08 +08:00
@use '@angular/cdk';
@use '../core/style/vendor-prefixes';
@use '../core/tokens/token-utils';
@use '../core/tokens/m2/mdc/filled-text-field' as tokens-mdc-filled-text-field;
@use '../core/tokens/m2/mdc/outlined-text-field' as tokens-mdc-outlined-text-field;
// Includes the structural styles for the form field inherited from MDC.
@mixin private-text-field-structure {
$filled-slots: (
tokens-mdc-filled-text-field.$prefix,
tokens-mdc-filled-text-field.get-token-slots()
);
$outlined-slots: (
tokens-mdc-outlined-text-field.$prefix,
tokens-mdc-outlined-text-field.get-token-slots()
);
.mdc-text-field {
display: inline-flex;
align-items: baseline;
padding: 0 16px;
position: relative;
box-sizing: border-box;
overflow: hidden;
will-change: opacity, transform, color;
// TODO(crisbeto): The filled form field overrides these while the outlined doesn't.
// The correct thing to do would be to remove them from here and have the one based on the
// token in the outlined appearance. We keep them as is for now to avoid screenshot diffs.
border-top-left-radius: 4px;
border-top-right-radius: 4px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
.mdc-text-field__input {
width: 100%;
min-width: 0;
border: none;
border-radius: 0;
background: none;
padding: 0;
-moz-appearance: none;
-webkit-appearance: none;
// TODO(crisbeto): this height gets overwritten eventually, but there are some internal
// tests that depend on this being here in weird ways so we're keeping it around for now.
height: 28px;
// Note that while this style and the `-ms-clear` are identical, we can't combine
// them because if one of them isn't supported, it'll invalidate the whole rule.
&::-webkit-calendar-picker-indicator {
display: none;
}
&::-ms-clear {
display: none;
}
&:focus {
outline: none;
}
&:invalid {
box-shadow: none;
}
@include vendor-prefixes.input-placeholder {
opacity: 0;
}
.mdc-text-field--no-label &,
.mdc-text-field--focused & {
@include vendor-prefixes.input-placeholder {
opacity: 1;
}
}
.mdc-text-field--disabled:not(.mdc-text-field--no-label) &.mat-mdc-input-disabled-interactive {
@include vendor-prefixes.input-placeholder {
opacity: 0;
}
}
.mdc-text-field--outlined &,
.mdc-text-field--filled.mdc-text-field--no-label & {
height: 100%;
}
.mdc-text-field--outlined & {
display: flex;
border: none !important;
background-color: transparent;
}
.mdc-text-field--disabled & {
pointer-events: auto;
}
@include token-utils.use-tokens($filled-slots...) {
@include _input-tokens('.mdc-text-field--filled');
}
@include token-utils.use-tokens($outlined-slots...) {
@include _input-tokens('.mdc-text-field--outlined');
}
@include cdk.high-contrast {
.mdc-text-field--disabled & {
background-color: Window;
}
}
}
.mdc-text-field--filled {
height: 56px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
@include token-utils.use-tokens($filled-slots...) {
@include token-utils.create-token-slot(border-top-left-radius, container-shape);
@include token-utils.create-token-slot(border-top-right-radius, container-shape);
&:not(.mdc-text-field--disabled) {
@include token-utils.create-token-slot(background-color, container-color);
}
&.mdc-text-field--disabled {
@include token-utils.create-token-slot(background-color, disabled-container-color);
}
}
}
.mdc-text-field--outlined {
height: 56px;
overflow: visible;
@include token-utils.use-tokens($outlined-slots...) {
$shape-var: token-utils.get-token-variable(container-shape);
padding-right: max(16px, #{$shape-var});
padding-left: max(16px, calc(#{$shape-var} + 4px));
[dir='rtl'] & {
padding-right: max(16px, calc(#{$shape-var} + 4px));
padding-left: max(16px, #{$shape-var});
}
}
}
.mdc-floating-label {
position: absolute;
left: 0;
transform-origin: left top;
line-height: 1.15rem;
text-align: left;
text-overflow: ellipsis;
white-space: nowrap;
cursor: text;
overflow: hidden;
will-change: transform;
[dir='rtl'] & {
right: 0;
left: auto;
transform-origin: right top;
text-align: right;
}
.mdc-text-field & {
top: 50%;
transform: translateY(-50%);
pointer-events: none;
}
.mdc-notched-outline & {
display: inline-block;
position: relative;
max-width: 100%;
}
.mdc-text-field--outlined & {
left: 4px;
right: auto;
}
[dir='rtl'] .mdc-text-field--outlined & {
left: auto;
right: 4px;
}
.mdc-text-field--filled & {
left: 16px;
right: auto;
}
[dir='rtl'] .mdc-text-field--filled & {
left: auto;
right: 16px;
}
.mdc-text-field--disabled & {
cursor: default;
@include cdk.high-contrast {
z-index: 1;
}
}
.mdc-text-field--filled.mdc-text-field--no-label & {
display: none;
}
@include token-utils.use-tokens($filled-slots...) {
@include _floating-label-tokens('.mdc-text-field--filled');
}
@include token-utils.use-tokens($outlined-slots...) {
@include _floating-label-tokens('.mdc-text-field--outlined');
}
}
.mdc-floating-label--float-above {
cursor: auto;
transform: translateY(-106%) scale(0.75);
.mdc-text-field--filled & {
transform: translateY(-106%) scale(0.75);
}
.mdc-text-field--outlined & {
transform: translateY(-37.25px) scale(1);
font-size: 0.75rem;
}
.mdc-notched-outline & {
text-overflow: clip;
}
.mdc-notched-outline--upgraded & {
max-width: 133.3333333333%;
}
.mdc-text-field--outlined.mdc-notched-outline--upgraded &,
.mdc-text-field--outlined .mdc-notched-outline--upgraded & {
transform: translateY(-34.75px) scale(0.75);
}
.mdc-text-field--outlined.mdc-notched-outline--upgraded &,
.mdc-text-field--outlined .mdc-notched-outline--upgraded & {
font-size: 1rem;
}
}
.mdc-floating-label--required {
&:not(.mdc-floating-label--hide-required-marker)::after {
margin-left: 1px;
margin-right: 0;
content: '*';
[dir='rtl'] & {
margin-left: 0;
margin-right: 1px;
}
}
}
.mdc-notched-outline {
display: flex;
position: absolute;
top: 0;
right: 0;
left: 0;
box-sizing: border-box;
width: 100%;
max-width: 100%;
height: 100%;
text-align: left;
pointer-events: none;
[dir='rtl'] & {
text-align: right;
}
.mdc-text-field--outlined & {
z-index: 1;
}
}
.mat-mdc-notch-piece {
box-sizing: border-box;
height: 100%;
pointer-events: none;
border-top: 1px solid;
border-bottom: 1px solid;
.mdc-text-field--focused & {
border-width: 2px;
}
@include token-utils.use-tokens($outlined-slots...) {
// Moved out into variables because the selectors we inherited were too long.
$enabled-selector: '.mdc-text-field--outlined:not(.mdc-text-field--disabled)';
$hover-selector: ':not(.mdc-text-field--focused):hover';
#{$enabled-selector} & {
@include token-utils.create-token-slot(border-color, outline-color);
@include token-utils.create-token-slot(border-width, outline-width);
}
#{$enabled-selector}#{$hover-selector} & {
@include token-utils.create-token-slot(border-color, hover-outline-color);
}
#{$enabled-selector}.mdc-text-field--focused & {
@include token-utils.create-token-slot(border-color, focus-outline-color);
}
.mdc-text-field--outlined.mdc-text-field--disabled & {
@include token-utils.create-token-slot(border-color, disabled-outline-color);
}
#{$enabled-selector}.mdc-text-field--invalid & {
@include token-utils.create-token-slot(border-color, error-outline-color);
}
#{$enabled-selector}.mdc-text-field--invalid#{$hover-selector} .mdc-notched-outline & {
@include token-utils.create-token-slot(border-color, error-hover-outline-color);
}
#{$enabled-selector}.mdc-text-field--invalid.mdc-text-field--focused & {
@include token-utils.create-token-slot(border-color, error-focus-outline-color);
}
#{$enabled-selector}.mdc-text-field--focused .mdc-notched-outline & {
@include token-utils.create-token-slot(border-width, focus-outline-width);
}
}
}
.mdc-notched-outline__leading {
border-left: 1px solid;
border-right: none;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
@include token-utils.use-tokens($outlined-slots...) {
@include token-utils.create-token-slot(border-top-left-radius, container-shape);
@include token-utils.create-token-slot(border-bottom-left-radius, container-shape);
.mdc-text-field--outlined .mdc-notched-outline & {
$shape-var: token-utils.get-token-variable(container-shape);
width: max(12px, #{$shape-var});
}
}
[dir='rtl'] & {
border-left: none;
border-right: 1px solid;
border-bottom-left-radius: 0;
border-top-left-radius: 0;
@include token-utils.use-tokens($outlined-slots...) {
@include token-utils.create-token-slot(border-top-right-radius, container-shape);
@include token-utils.create-token-slot(border-bottom-right-radius, container-shape);
}
}
}
.mdc-notched-outline__trailing {
flex-grow: 1;
border-left: none;
border-right: 1px solid;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
@include token-utils.use-tokens($outlined-slots...) {
@include token-utils.create-token-slot(border-top-right-radius, container-shape);
@include token-utils.create-token-slot(border-bottom-right-radius, container-shape);
}
[dir='rtl'] & {
border-left: 1px solid;
border-right: none;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
@include token-utils.use-tokens($outlined-slots...) {
@include token-utils.create-token-slot(border-top-left-radius, container-shape);
@include token-utils.create-token-slot(border-bottom-left-radius, container-shape);
}
}
}
.mdc-notched-outline__notch {
flex: 0 0 auto;
width: auto;
@include token-utils.use-tokens($outlined-slots...) {
.mdc-text-field--outlined .mdc-notched-outline & {
$shape-var: token-utils.get-token-variable(container-shape);
max-width: min(
var(--mat-form-field-notch-max-width, 100%),
calc(100% - max(12px, #{$shape-var}) * 2)
);
}
}
.mdc-text-field--outlined .mdc-notched-outline--notched & {
padding-top: 1px;
}
.mdc-text-field--focused.mdc-text-field--outlined .mdc-notched-outline--notched & {
padding-top: 2px;
}
.mdc-notched-outline--notched & {
padding-left: 0;
padding-right: 8px;
border-top: none;
--mat-form-field-notch-max-width: 100%;
}
[dir='rtl'] .mdc-notched-outline--notched & {
padding-left: 8px;
padding-right: 0;
}
.mdc-notched-outline--no-label & {
display: none;
}
}
.mdc-line-ripple {
&::before,
&::after {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
border-bottom-style: solid;
content: '';
}
&::before {
z-index: 1;
@include token-utils.use-tokens($filled-slots...) {
$enabled-field: '.mdc-text-field--filled:not(.mdc-text-field--disabled)';
@include token-utils.create-token-slot(border-bottom-width, active-indicator-height);
#{$enabled-field} & {
@include token-utils.create-token-slot(border-bottom-color, active-indicator-color);
}
#{$enabled-field}:not(.mdc-text-field--focused):hover & {
@include token-utils.create-token-slot(border-bottom-color, hover-active-indicator-color);
}
.mdc-text-field--filled.mdc-text-field--disabled & {
@include token-utils.create-token-slot(
border-bottom-color,
disabled-active-indicator-color
);
}
#{$enabled-field}.mdc-text-field--invalid & {
@include token-utils.create-token-slot(border-bottom-color, error-active-indicator-color);
}
#{$enabled-field}.mdc-text-field--invalid:not(.mdc-text-field--focused):hover & {
@include token-utils.create-token-slot(
border-bottom-color,
error-hover-active-indicator-color
);
}
}
}
&::after {
transform: scaleX(0);
opacity: 0;
z-index: 2;
@include token-utils.use-tokens($filled-slots...) {
.mdc-text-field--filled & {
@include token-utils.create-token-slot(
border-bottom-width,
focus-active-indicator-height
);
}
.mdc-text-field--filled:not(.mdc-text-field--disabled) & {
@include token-utils.create-token-slot(border-bottom-color, focus-active-indicator-color);
}
.mdc-text-field--filled.mdc-text-field--invalid:not(.mdc-text-field--disabled) & {
@include token-utils.create-token-slot(
border-bottom-color,
error-focus-active-indicator-color
);
}
}
}
}
.mdc-line-ripple--active::after {
transform: scaleX(1);
opacity: 1;
}
.mdc-line-ripple--deactivating::after {
opacity: 0;
}
.mdc-text-field--disabled {
pointer-events: none;
}
}
// Includes the tokens for the floating label for a specific form field variant.
@mixin _floating-label-tokens($selector) {
$enabled-field: '#{$selector}:not(.mdc-text-field--disabled)';
#{$enabled-field} & {
@include token-utils.create-token-slot(color, label-text-color);
}
#{$enabled-field}.mdc-text-field--focused & {
@include token-utils.create-token-slot(color, focus-label-text-color);
}
#{$enabled-field}:not(.mdc-text-field--focused):hover & {
@include token-utils.create-token-slot(color, hover-label-text-color);
}
#{$selector}.mdc-text-field--disabled & {
@include token-utils.create-token-slot(color, disabled-label-text-color);
}
#{$enabled-field}.mdc-text-field--invalid & {
@include token-utils.create-token-slot(color, error-label-text-color);
}
#{$enabled-field}.mdc-text-field--invalid.mdc-text-field--focused & {
@include token-utils.create-token-slot(color, error-focus-label-text-color);
}
#{$enabled-field}.mdc-text-field--invalid:not(.mdc-text-field--disabled):hover & {
@include token-utils.create-token-slot(color, error-hover-label-text-color);
}
#{$selector} & {
@include token-utils.create-token-slot(font-family, label-text-font);
@include token-utils.create-token-slot(font-size, label-text-size);
@include token-utils.create-token-slot(font-weight, label-text-weight);
@include token-utils.create-token-slot(letter-spacing, label-text-tracking);
}
}
// Includes the tokens for the input for a specific form field variant.
@mixin _input-tokens($selector) {
#{$selector}:not(.mdc-text-field--disabled) & {
@include token-utils.create-token-slot(color, input-text-color);
@include token-utils.create-token-slot(caret-color, caret-color);
@include vendor-prefixes.input-placeholder {
@include token-utils.create-token-slot(color, input-text-placeholder-color);
}
}
#{$selector}.mdc-text-field--invalid:not(.mdc-text-field--disabled) & {
@include token-utils.create-token-slot(caret-color, error-caret-color);
}
#{$selector}.mdc-text-field--disabled & {
@include token-utils.create-token-slot(color, disabled-input-text-color);
}
}
// Includes the animation styles for the form field inherited from MDC.
@mixin private-text-field-animations {
$timing-curve: cubic-bezier(0.4, 0, 0.2, 1);
.mdc-floating-label {
transition:
transform 150ms $timing-curve,
color 150ms $timing-curve;
}
.mdc-text-field__input {
transition: opacity 150ms $timing-curve;
@include vendor-prefixes.input-placeholder {
transition: opacity 67ms $timing-curve;
}
}
&.mdc-text-field--no-label,
&.mdc-text-field--focused {
.mdc-text-field__input {
@include vendor-prefixes.input-placeholder {
transition-delay: 40ms;
transition-duration: 110ms;
}
}
}
.mdc-text-field--filled:not(.mdc-ripple-upgraded):focus .mdc-text-field__ripple::before {
transition-duration: 75ms;
}
.mdc-line-ripple::after {
transition:
transform 180ms $timing-curve,
opacity 180ms $timing-curve;
}
}