|
| 1 | +@import '../core/theming/palette'; |
| 2 | +@import '../core/theming/theming'; |
| 3 | +@import '../core/style/form-common'; |
| 4 | +@import '../core/typography/typography-utils'; |
| 5 | + |
| 6 | + |
| 7 | +@mixin mat-form-field-theme($theme) { |
| 8 | + $primary: map-get($theme, primary); |
| 9 | + $accent: map-get($theme, accent); |
| 10 | + $warn: map-get($theme, warn); |
| 11 | + $background: map-get($theme, background); |
| 12 | + $foreground: map-get($theme, foreground); |
| 13 | + $is-dark-theme: map-get($theme, is-dark); |
| 14 | + |
| 15 | + // Placeholder colors. Required is used for the `*` star shown in the placeholder. |
| 16 | + $form-field-placeholder-color: mat-color($foreground, secondary-text); |
| 17 | + $form-field-floating-placeholder-color: mat-color($primary); |
| 18 | + $form-field-required-placeholder-color: mat-color($accent); |
| 19 | + |
| 20 | + // Underline colors. |
| 21 | + $form-field-underline-color: mat-color($foreground, divider, if($is-dark-theme, 0.7, 0.42)); |
| 22 | + $form-field-underline-color-accent: mat-color($accent); |
| 23 | + $form-field-underline-color-warn: mat-color($warn); |
| 24 | + $form-field-underline-focused-color: mat-color($primary); |
| 25 | + |
| 26 | + .mat-form-field-placeholder { |
| 27 | + color: $form-field-placeholder-color; |
| 28 | + } |
| 29 | + |
| 30 | + .mat-hint { |
| 31 | + color: mat-color($foreground, secondary-text); |
| 32 | + } |
| 33 | + |
| 34 | + .mat-focused .mat-form-field-placeholder { |
| 35 | + color: $form-field-floating-placeholder-color; |
| 36 | + |
| 37 | + &.mat-accent { |
| 38 | + color: $form-field-underline-color-accent; |
| 39 | + } |
| 40 | + |
| 41 | + &.mat-warn { |
| 42 | + color: $form-field-underline-color-warn; |
| 43 | + } |
| 44 | + } |
| 45 | + |
| 46 | + .mat-form-field-autofill-float:-webkit-autofill + .mat-form-field-placeholder, |
| 47 | + .mat-focused .mat-form-field-placeholder.mat-form-field-float { |
| 48 | + .mat-form-field-required-marker { |
| 49 | + color: $form-field-required-placeholder-color; |
| 50 | + } |
| 51 | + } |
| 52 | + |
| 53 | + .mat-form-field-underline { |
| 54 | + background-color: $form-field-underline-color; |
| 55 | + |
| 56 | + &.mat-disabled { |
| 57 | + @include mat-control-disabled-underline($form-field-underline-color); |
| 58 | + } |
| 59 | + } |
| 60 | + |
| 61 | + .mat-form-field-ripple { |
| 62 | + background-color: $form-field-underline-focused-color; |
| 63 | + |
| 64 | + &.mat-accent { |
| 65 | + background-color: $form-field-underline-color-accent; |
| 66 | + } |
| 67 | + |
| 68 | + &.mat-warn { |
| 69 | + background-color: $form-field-underline-color-warn; |
| 70 | + } |
| 71 | + } |
| 72 | + |
| 73 | + // Styling for the error state of the form field. Note that while the same can be |
| 74 | + // achieved with the ng-* classes, we use this approach in order to ensure that the same |
| 75 | + // logic is used to style the error state and to show the error messages. |
| 76 | + .mat-form-field-invalid { |
| 77 | + .mat-form-field-placeholder { |
| 78 | + color: $form-field-underline-color-warn; |
| 79 | + |
| 80 | + &.mat-accent, |
| 81 | + &.mat-form-field-float .mat-form-field-required-marker { |
| 82 | + color: $form-field-underline-color-warn; |
| 83 | + } |
| 84 | + } |
| 85 | + |
| 86 | + .mat-form-field-ripple { |
| 87 | + background-color: $form-field-underline-color-warn; |
| 88 | + } |
| 89 | + } |
| 90 | + |
| 91 | + .mat-error { |
| 92 | + color: $form-field-underline-color-warn; |
| 93 | + } |
| 94 | +} |
| 95 | + |
| 96 | +// Applies a floating placeholder above the form field control itself. |
| 97 | +@mixin _mat-form-field-placeholder-floating($font-scale, $infix-padding, $infix-margin-top) { |
| 98 | + // We use perspective to fix the text blurriness as described here: |
| 99 | + // http://www.useragentman.com/blog/2014/05/04/fixing-typography-inside-of-2-d-css-transforms/ |
| 100 | + // This results in a small jitter after the label floats on Firefox, which the |
| 101 | + // translateZ fixes. |
| 102 | + transform: translateY(-$infix-margin-top - $infix-padding) scale($font-scale) perspective(100px) |
| 103 | + translateZ(0.001px); |
| 104 | + // The tricks above used to smooth out the animation on chrome and firefox actually make things |
| 105 | + // worse on IE, so we don't include them in the IE version. |
| 106 | + -ms-transform: translateY(-$infix-margin-top - $infix-padding) |
| 107 | + scale($font-scale); |
| 108 | + |
| 109 | + width: 100% / $font-scale; |
| 110 | +} |
| 111 | + |
| 112 | +@mixin mat-form-field-typography($config) { |
| 113 | + // The unit-less line-height from the font config. |
| 114 | + $line-height: mat-line-height($config, input); |
| 115 | + |
| 116 | + // The amount to scale the font for the floating label and subscript. |
| 117 | + $subscript-font-scale: 0.75; |
| 118 | + // The amount to scale the font for the prefix and suffix icons. |
| 119 | + $prefix-suffix-icon-font-scale: 1.5; |
| 120 | + |
| 121 | + // The amount of space between the top of the line and the top of the actual text |
| 122 | + // (as a fraction of the font-size). |
| 123 | + $line-spacing: ($line-height - 1) / 2; |
| 124 | + // The padding on the infix. Mocks show half of the text size, but seem to measure from the edge |
| 125 | + // of the text itself, not the edge of the line; therefore we subtract off the line spacing. |
| 126 | + $infix-padding: 0.5em - $line-spacing; |
| 127 | + // The margin applied to the form-field-infix to reserve space for the floating label. |
| 128 | + $infix-margin-top: 1em * $line-height * $subscript-font-scale; |
| 129 | + // Font size to use for the label and subscript text. |
| 130 | + $subscript-font-size: $subscript-font-scale * 100%; |
| 131 | + // Font size to use for the for the prefix and suffix icons. |
| 132 | + $prefix-suffix-icon-font-size: $prefix-suffix-icon-font-scale * 100%; |
| 133 | + // The space between the bottom of the .mat-form-field-flex area and the subscript wrapper. |
| 134 | + // Mocks show half of the text size, but this margin is applied to an element with the subscript |
| 135 | + // text font size, so we need to divide by the scale factor to make it half of the original text |
| 136 | + // size. We again need to subtract off the line spacing since the mocks measure to the edge of the |
| 137 | + // text, not the edge of the line. |
| 138 | + $subscript-margin-top: 0.5em / $subscript-font-scale - ($line-spacing * 2); |
| 139 | + // The padding applied to the form-field-wrapper to reserve space for the subscript, since it's |
| 140 | + // absolutely positioned. This is a combination of the subscript's margin and line-height, but we |
| 141 | + // need to multiply by the subscript font scale factor since the wrapper has a larger font size. |
| 142 | + $wrapper-padding-bottom: ($subscript-margin-top + $line-height) * $subscript-font-scale; |
| 143 | + |
| 144 | + .mat-form-field { |
| 145 | + font-family: mat-font-family($config); |
| 146 | + font-size: inherit; |
| 147 | + font-weight: mat-font-weight($config, input); |
| 148 | + line-height: mat-line-height($config, input); |
| 149 | + } |
| 150 | + |
| 151 | + .mat-form-field-wrapper { |
| 152 | + padding-bottom: $wrapper-padding-bottom; |
| 153 | + } |
| 154 | + |
| 155 | + .mat-form-field-prefix, |
| 156 | + .mat-form-field-suffix { |
| 157 | + // Allow icons in a prefix or suffix to adapt to the correct size. |
| 158 | + .mat-icon { |
| 159 | + font-size: $prefix-suffix-icon-font-size; |
| 160 | + line-height: $line-height; |
| 161 | + } |
| 162 | + |
| 163 | + // Allow icon buttons in a prefix or suffix to adapt to the correct size. |
| 164 | + .mat-icon-button { |
| 165 | + height: $prefix-suffix-icon-font-scale * 1em; |
| 166 | + width: $prefix-suffix-icon-font-scale * 1em; |
| 167 | + |
| 168 | + .mat-icon { |
| 169 | + height: $line-height * 1em; |
| 170 | + line-height: $line-height; |
| 171 | + } |
| 172 | + } |
| 173 | + } |
| 174 | + |
| 175 | + .mat-form-field-infix { |
| 176 | + padding: $infix-padding 0; |
| 177 | + // Throws off the baseline if we do it as a real margin, so we do it as a border instead. |
| 178 | + border-top: $infix-margin-top solid transparent; |
| 179 | + } |
| 180 | + |
| 181 | + .mat-form-field-autofill-float:-webkit-autofill + |
| 182 | + .mat-form-field-placeholder-wrapper .mat-form-field-float { |
| 183 | + @include _mat-form-field-placeholder-floating( |
| 184 | + $subscript-font-scale, $infix-padding, $infix-margin-top); |
| 185 | + } |
| 186 | + |
| 187 | + .mat-form-field-placeholder-wrapper { |
| 188 | + top: -$infix-margin-top; |
| 189 | + padding-top: $infix-margin-top; |
| 190 | + } |
| 191 | + |
| 192 | + .mat-form-field-placeholder { |
| 193 | + top: $infix-margin-top + $infix-padding; |
| 194 | + |
| 195 | + // Show the placeholder above the control when it's not empty, or focused. |
| 196 | + &.mat-form-field-float:not(.mat-form-field-empty), |
| 197 | + .mat-focused &.mat-form-field-float { |
| 198 | + @include _mat-form-field-placeholder-floating($subscript-font-scale, |
| 199 | + $infix-padding, $infix-margin-top); |
| 200 | + } |
| 201 | + } |
| 202 | + |
| 203 | + .mat-form-field-underline { |
| 204 | + // We want the underline to start at the end of the content box, not the padding box, |
| 205 | + // so we move it up by the padding amount. |
| 206 | + bottom: $wrapper-padding-bottom; |
| 207 | + } |
| 208 | + |
| 209 | + .mat-form-field-subscript-wrapper { |
| 210 | + font-size: $subscript-font-size; |
| 211 | + margin-top: $subscript-margin-top; |
| 212 | + |
| 213 | + // We want the subscript to start at the end of the content box, not the padding box, |
| 214 | + // so we move it up by the padding amount (adjusted for the smaller font size); |
| 215 | + top: calc(100% - #{$wrapper-padding-bottom / $subscript-font-scale}); |
| 216 | + } |
| 217 | +} |
0 commit comments