UNPKG

8.22 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// stylelint-disable selector-class-pattern --
24// Selector '.mdc-*' should only be used in this project.
25
26@use '@material/rtl/rtl';
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 @include rtl.ignore-next-line();
49 left: 0;
50 @include rtl.ignore-next-line();
51 -webkit-transform-origin: left top;
52 @include rtl.ignore-next-line();
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.rtl {
67 @include rtl.ignore-next-line();
68 right: 0;
69 @include rtl.ignore-next-line();
70 left: auto;
71 @include rtl.ignore-next-line();
72 -webkit-transform-origin: right top;
73 @include rtl.ignore-next-line();
74 transform-origin: right top;
75 @include rtl.ignore-next-line();
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.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 @include rtl.ignore-next-line();
144 transform: translateX(calc(0 - #{$positionX}))
145 translateY(-#{$positionY}) scale(#{$scale});
146 }
147
148 33% {
149 animation-timing-function: cubic-bezier(0.5, 0, 0.701732, 0.495819);
150 @include rtl.ignore-next-line();
151 transform: translateX(calc(4% - #{$positionX}))
152 translateY(-#{$positionY}) scale(#{$scale});
153 }
154
155 66% {
156 animation-timing-function: cubic-bezier(
157 0.302435,
158 0.381352,
159 0.55,
160 0.956352
161 );
162 @include rtl.ignore-next-line();
163 transform: translateX(calc(-4% - #{$positionX}))
164 translateY(-#{$positionY}) scale(#{$scale});
165 }
166
167 100% {
168 @include rtl.ignore-next-line();
169 transform: translateX(calc(0 - #{$positionX}))
170 translateY(-#{$positionY}) scale(#{$scale});
171 }
172 }
173 }
174}
175
176@mixin float-position(
177 $positionY,
178 $positionX: 0%,
179 $scale: variables.$float-scale,
180 $query: feature-targeting.all()
181) {
182 $feat-structure: feature-targeting.create-target($query, structure);
183
184 .mdc-floating-label--float-above {
185 @include feature-targeting.targets($feat-structure) {
186 @if $positionX > 0 or $positionX < 0 {
187 @include rtl.ignore-next-line();
188 transform: translateY(-1 * $positionY)
189 translateX(-1 * $positionX)
190 scale($scale);
191
192 @include rtl.rtl {
193 @include rtl.ignore-next-line();
194 transform: translateY(-1 * $positionY) translateX($positionX)
195 scale($scale);
196 }
197 } @else {
198 transform: translateY(-1 * $positionY) scale($scale);
199 }
200 }
201 }
202}
203
204@mixin shake-animation($modifier, $query: feature-targeting.all()) {
205 $feat-animation: feature-targeting.create-target($query, animation);
206
207 .mdc-floating-label--shake {
208 @include feature-targeting.targets($feat-animation) {
209 animation: mdc-floating-label-shake-float-above-#{$modifier} 250ms 1;
210 }
211 }
212}
213
214@mixin max-width($max-width, $query: feature-targeting.all()) {
215 $feat-structure: feature-targeting.create-target($query, structure);
216
217 @include feature-targeting.targets($feat-structure) {
218 max-width: $max-width;
219 }
220}
221
222///
223/// Sets the CSS transition for the floating animation.
224///
225/// @param {Number} $duration-ms - Duration (in ms) of the animation.
226/// @param {String} $timing-function - Optionally overrides the default animation timing function.
227///
228@mixin float-transition(
229 $duration-ms,
230 $timing-function: animation-variables.$standard-curve-timing-function,
231 $query: feature-targeting.all()
232) {
233 $feat-animation: feature-targeting.create-target($query, animation);
234
235 @include feature-targeting.targets($feat-animation) {
236 transition: color $duration-ms $timing-function,
237 transform $duration-ms $timing-function;
238 }
239}
240
241@mixin _required-content($query: feature-targeting.all()) {
242 $feat-structure: feature-targeting.create-target($query, structure);
243
244 @include feature-targeting.targets($feat-structure) {
245 @include rtl.ignore-next-line();
246 margin-left: 1px;
247 @include rtl.ignore-next-line();
248 margin-right: 0px;
249 content: '*';
250 }
251}
252
253// Need to specify LTR/RTL manually since rtl mixins will add ::after[dir=rtl]
254// selector and that breaks some browsers
255@mixin _required-content-rtl($query: feature-targeting.all()) {
256 $feat-structure: feature-targeting.create-target($query, structure);
257
258 @include feature-targeting.targets($feat-structure) {
259 @include rtl.ignore-next-line();
260 margin-left: 0;
261 @include rtl.ignore-next-line();
262 margin-right: 1px;
263 }
264}