UNPKG

7.78 kBSCSSView Raw
1//
2// Copyright 2018 Google Inc.
3//
4// Permission is hereby granted, free of charge, to any person obtaining a copy
5// of this software and associated documentation files (the "Software"), to deal
6// in the Software without restriction, including without limitation the rights
7// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8// copies of the Software, and to permit persons to whom the Software is
9// furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20// THE SOFTWARE.
21//
22
23// Selector '.mdc-*' should only be used in this project.
24// stylelint-disable selector-class-pattern
25
26@use '@material/rtl/mixins' as rtl-mixins;
27@use '@material/theme/theme-color';
28@use '@material/theme/theme';
29@use '@material/feature-targeting/feature-targeting';
30@use '@material/animation/variables' as animation-variables;
31@use '@material/typography/typography';
32@use './variables';
33
34@mixin core-styles($query: feature-targeting.all()) {
35 $feat-structure: feature-targeting.create-target($query, structure);
36 $feat-animation: feature-targeting.create-target($query, animation);
37
38 // postcss-bem-linter: define floating-label
39 .mdc-floating-label {
40 @include typography.typography(
41 subtitle1,
42 $exclude-props: (line-height),
43 $query: $query
44 );
45
46 @include feature-targeting.targets($feat-structure) {
47 position: absolute;
48 /* @noflip */
49 left: 0;
50 /* @noflip */
51 -webkit-transform-origin: left top;
52 /* @noflip */
53 transform-origin: left top;
54 line-height: 1.15rem;
55 text-align: left;
56 text-overflow: ellipsis;
57 white-space: nowrap;
58 cursor: text;
59 overflow: hidden;
60
61 /* @alternate */
62 // Force the label into its own layer to prevent visible layer promotion adjustments
63 // when the ripple is activated behind it.
64 will-change: transform;
65
66 @include rtl-mixins.rtl {
67 /* @noflip */
68 right: 0;
69 /* @noflip */
70 left: auto;
71 /* @noflip */
72 -webkit-transform-origin: right top;
73 /* @noflip */
74 transform-origin: right top;
75 /* @noflip */
76 text-align: right;
77 }
78 }
79
80 @include feature-targeting.targets($feat-animation) {
81 transition: transform variables.$transition-duration
82 animation-variables.$standard-curve-timing-function,
83 color variables.$transition-duration
84 animation-variables.$standard-curve-timing-function;
85 }
86 }
87
88 .mdc-floating-label--float-above {
89 @include feature-targeting.targets($feat-structure) {
90 cursor: auto;
91 }
92 }
93
94 .mdc-floating-label--required {
95 &::after {
96 @include _required-content($query);
97 }
98
99 @include rtl-mixins.rtl {
100 &::after {
101 @include _required-content-rtl($query);
102 }
103 }
104 }
105
106 @at-root {
107 @include float-position(variables.$position-y, $query: $query);
108 @include shake-animation(standard, $query: $query);
109 }
110
111 @include shake-keyframes(standard, variables.$position-y, $query: $query);
112}
113
114@mixin ink-color($color, $query: feature-targeting.all()) {
115 $feat-color: feature-targeting.create-target($query, color);
116
117 @include feature-targeting.targets($feat-color) {
118 @include theme.property(color, $color);
119 }
120}
121
122// Used for textarea in case of scrolling
123@mixin fill-color($color, $query: feature-targeting.all()) {
124 $feat-color: feature-targeting.create-target($query, color);
125
126 @include feature-targeting.targets($feat-color) {
127 @include theme.property(background-color, $color);
128 }
129}
130
131@mixin shake-keyframes(
132 $modifier,
133 $positionY,
134 $positionX: 0%,
135 $scale: variables.$float-scale,
136 $query: feature-targeting.all()
137) {
138 $feat-animation: feature-targeting.create-target($query, animation);
139
140 @include feature-targeting.targets($feat-animation) {
141 @keyframes mdc-floating-label-shake-float-above-#{$modifier} {
142 0% {
143 transform: translateX(calc(0 - #{$positionX}))
144 translateY(-#{$positionY}) scale(#{$scale});
145 }
146
147 33% {
148 animation-timing-function: cubic-bezier(0.5, 0, 0.701732, 0.495819);
149 transform: translateX(calc(4% - #{$positionX}))
150 translateY(-#{$positionY}) scale(#{$scale});
151 }
152
153 66% {
154 animation-timing-function: cubic-bezier(
155 0.302435,
156 0.381352,
157 0.55,
158 0.956352
159 );
160 transform: translateX(calc(-4% - #{$positionX}))
161 translateY(-#{$positionY}) scale(#{$scale});
162 }
163
164 100% {
165 transform: translateX(calc(0 - #{$positionX}))
166 translateY(-#{$positionY}) scale(#{$scale});
167 }
168 }
169 }
170}
171
172@mixin float-position(
173 $positionY,
174 $positionX: 0%,
175 $scale: variables.$float-scale,
176 $query: feature-targeting.all()
177) {
178 $feat-structure: feature-targeting.create-target($query, structure);
179
180 .mdc-floating-label--float-above {
181 @include feature-targeting.targets($feat-structure) {
182 @if $positionX > 0 or $positionX < 0 {
183 transform: translateY(-1 * $positionY)
184 translateX(-1 * $positionX)
185 scale($scale);
186
187 @include rtl-mixins.rtl {
188 transform: translateY(-1 * $positionY) translateX($positionX)
189 scale($scale);
190 }
191 } @else {
192 transform: translateY(-1 * $positionY) scale($scale);
193 }
194 }
195 }
196}
197
198@mixin shake-animation($modifier, $query: feature-targeting.all()) {
199 $feat-animation: feature-targeting.create-target($query, animation);
200
201 .mdc-floating-label--shake {
202 @include feature-targeting.targets($feat-animation) {
203 animation: mdc-floating-label-shake-float-above-#{$modifier} 250ms 1;
204 }
205 }
206}
207
208@mixin max-width($max-width, $query: feature-targeting.all()) {
209 $feat-structure: feature-targeting.create-target($query, structure);
210
211 @include feature-targeting.targets($feat-structure) {
212 max-width: $max-width;
213 }
214}
215
216///
217/// Sets the CSS transition for the floating animation.
218///
219/// @param {Number} $duration-ms - Duration (in ms) of the animation.
220/// @param {String} $timing-function - Optionally overrides the default animation timing function.
221///
222@mixin float-transition(
223 $duration-ms,
224 $timing-function: animation-variables.$standard-curve-timing-function,
225 $query: feature-targeting.all()
226) {
227 $feat-animation: feature-targeting.create-target($query, animation);
228
229 @include feature-targeting.targets($feat-animation) {
230 transition: color $duration-ms $timing-function,
231 transform $duration-ms $timing-function;
232 }
233}
234
235@mixin _required-content($query: feature-targeting.all()) {
236 $feat-structure: feature-targeting.create-target($query, structure);
237
238 @include feature-targeting.targets($feat-structure) {
239 /* @noflip */
240 margin-left: 1px;
241 /* @noflip */
242 margin-right: 0px;
243 content: '*';
244 }
245}
246
247// Need to specify LTR/RTL manually since rtl mixins will add ::after[dir=rtl]
248// selector and that breaks some browsers
249@mixin _required-content-rtl($query: feature-targeting.all()) {
250 $feat-structure: feature-targeting.create-target($query, structure);
251
252 @include feature-targeting.targets($feat-structure) {
253 /* @noflip */
254 margin-left: 0;
255 /* @noflip */
256 margin-right: 1px;
257 }
258}