1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 | @use 'sass:list';
|
24 | @use 'sass:map';
|
25 | @use 'sass:math';
|
26 | @use 'sass:meta';
|
27 | @use '@material/feature-targeting/feature-targeting';
|
28 | @use '@material/rtl/rtl';
|
29 | @use '@material/theme/custom-properties';
|
30 | @use '@material/theme/css';
|
31 | @use '@material/theme/keys';
|
32 | @use '@material/theme/theme';
|
33 |
|
34 |
|
35 | $small-component-radius: 4px !default;
|
36 | $medium-component-radius: 4px !default;
|
37 | $large-component-radius: 0 !default;
|
38 |
|
39 | @include keys.set-values(
|
40 | (
|
41 | small: $small-component-radius,
|
42 | medium: $medium-component-radius,
|
43 | large: $large-component-radius,
|
44 | ),
|
45 | $options: (custom-property-prefix: shape)
|
46 | );
|
47 |
|
48 |
|
49 |
|
50 | $category-keywords: (
|
51 | small: keys.create-custom-property(small),
|
52 | medium: keys.create-custom-property(medium),
|
53 | large: keys.create-custom-property(large),
|
54 | ) !default;
|
55 |
|
56 | @function is-shape-key($radius) {
|
57 | @return map.has-key($category-keywords, $radius);
|
58 | }
|
59 |
|
60 | @function get-shape-keys() {
|
61 | @return map.keys($category-keywords);
|
62 | }
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 | @function flip-radius($radius) {
|
73 | @if meta.type-of($radius) == 'list' {
|
74 | @if list.length($radius) > 4 {
|
75 | @error "Invalid radius: '#{$radius}' is more than 4 values";
|
76 | }
|
77 | }
|
78 |
|
79 | @if list.length($radius) == 4 {
|
80 | @return list.nth($radius, 2) list.nth($radius, 1) list.nth($radius, 4)
|
81 | list.nth($radius, 3);
|
82 | } @else if list.length($radius) == 3 {
|
83 | @return list.nth($radius, 2) list.nth($radius, 1) list.nth($radius, 2)
|
84 | list.nth($radius, 3);
|
85 | } @else if list.length($radius) == 2 {
|
86 | @return list.nth($radius, 2) list.nth($radius, 1);
|
87 | } @else {
|
88 | @return $radius;
|
89 | }
|
90 | }
|
91 |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 |
|
98 |
|
99 |
|
100 |
|
101 |
|
102 |
|
103 |
|
104 |
|
105 |
|
106 |
|
107 |
|
108 |
|
109 |
|
110 |
|
111 |
|
112 |
|
113 |
|
114 |
|
115 |
|
116 |
|
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 | @function resolve-radius($radius, $component-height: null) {
|
128 | @if $radius == null {
|
129 | @return null;
|
130 | }
|
131 |
|
132 | @if meta.type-of($radius) == 'list' {
|
133 |
|
134 | @if list.length($radius) > 4 or list.length($radius) < 1 {
|
135 | @error "mdc-shape: Invalid radius: #{$radius}. Radius must be between 1 and 4 values.";
|
136 | }
|
137 |
|
138 | $radii: ();
|
139 | @each $corner in $radius {
|
140 | $radii: list.append(
|
141 | $radii,
|
142 | resolve-radius($corner, $component-height: $component-height)
|
143 | );
|
144 | }
|
145 |
|
146 | @return $radii;
|
147 | }
|
148 |
|
149 | @if is-shape-key($radius) {
|
150 |
|
151 | @return resolve-radius(
|
152 | keys.create-custom-property($radius),
|
153 | $component-height: $component-height
|
154 | );
|
155 | } @else if custom-properties.is-custom-prop($radius) {
|
156 |
|
157 | $fallback: resolve-radius(
|
158 | custom-properties.get-fallback($radius, $shallow: true),
|
159 | $component-height: $component-height
|
160 | );
|
161 | @return custom-properties.set-fallback($radius, $fallback, $shallow: true);
|
162 | } @else if meta.type-of($radius) == 'map' {
|
163 |
|
164 | $family: map.get($radius, family);
|
165 | @if custom-properties.is-custom-prop($family) {
|
166 |
|
167 | $family: custom-properties.get-fallback($family);
|
168 | }
|
169 |
|
170 | @if $family != 'rounded' {
|
171 | @error 'mdc-shape: Invalid shape family: "#{$family}". Only "rounded" is supported.';
|
172 | }
|
173 |
|
174 | @return resolve-radius(
|
175 | map.get($radius, radius),
|
176 | $component-height: $component-height
|
177 | );
|
178 | } @else {
|
179 |
|
180 | @if meta.type-of($radius) != 'number' {
|
181 | @error "mdc-shape: Invalid radius: #{$radius}. Must be a number.";
|
182 | }
|
183 |
|
184 | $radius-unit: math.unit($radius);
|
185 | $component-height-type: meta.type-of($component-height);
|
186 | @if $radius-unit == '%' and $component-height-type == 'number' {
|
187 | $radius: _resolve-radius-percentage($radius, $component-height);
|
188 | }
|
189 |
|
190 | @return $radius;
|
191 | }
|
192 | }
|
193 |
|
194 |
|
195 |
|
196 |
|
197 |
|
198 |
|
199 |
|
200 |
|
201 |
|
202 |
|
203 |
|
204 | @function mask-radius($radius, $masked-corners) {
|
205 | @if meta.type-of($radius) == 'list' {
|
206 | @if list.length($radius) > 4 {
|
207 | @error "Invalid radius: '#{$radius}' is more than 4 values";
|
208 | }
|
209 | }
|
210 |
|
211 | @if list.length($masked-corners) != 4 {
|
212 | @error "Expected masked-corners of length 4 but got '#{list.length($masked-corners)}'.";
|
213 | }
|
214 |
|
215 | $radius: unpack-radius($radius);
|
216 |
|
217 | @return if(list.nth($masked-corners, 1) == 1, list.nth($radius, 1), 0)
|
218 | if(list.nth($masked-corners, 2) == 1, list.nth($radius, 2), 0)
|
219 | if(list.nth($masked-corners, 3) == 1, list.nth($radius, 3), 0)
|
220 | if(list.nth($masked-corners, 4) == 1, list.nth($radius, 4), 0);
|
221 | }
|
222 |
|
223 |
|
224 |
|
225 |
|
226 |
|
227 |
|
228 |
|
229 |
|
230 |
|
231 |
|
232 |
|
233 |
|
234 |
|
235 | @function unpack-radius($radius) {
|
236 | @return css.unpack-value($radius);
|
237 | }
|
238 |
|
239 |
|
240 |
|
241 |
|
242 |
|
243 |
|
244 | @function _resolve-radius-percentage($percentage, $component-height) {
|
245 |
|
246 | $percentage: math.div($percentage, $percentage * 0 + 1);
|
247 | @return $component-height * math.div($percentage, 100);
|
248 | }
|
249 |
|
250 | @mixin radius(
|
251 | $radius,
|
252 | $rtl-reflexive: false,
|
253 | $component-height: null,
|
254 | $query: feature-targeting.all()
|
255 | ) {
|
256 | $feat-structure: feature-targeting.create-target($query, structure);
|
257 |
|
258 | @include feature-targeting.targets($feat-structure) {
|
259 | $has-multiple-corners: meta.type-of($radius) == 'list' and
|
260 | list.length($radius) > 1;
|
261 |
|
262 | $needs-flip: $rtl-reflexive and $has-multiple-corners;
|
263 | $radius: resolve-radius($radius, $component-height: $component-height);
|
264 | @if not $has-multiple-corners {
|
265 | @include theme.property(border-radius, $radius);
|
266 | } @else {
|
267 | $gss: (
|
268 | noflip: $needs-flip,
|
269 | );
|
270 | $radii: unpack-radius($radius);
|
271 | @include theme.property(
|
272 | border-top-left-radius,
|
273 | list.nth($radii, 1),
|
274 | $gss: $gss
|
275 | );
|
276 | @include theme.property(
|
277 | border-top-right-radius,
|
278 | list.nth($radii, 2),
|
279 | $gss: $gss
|
280 | );
|
281 | @include theme.property(
|
282 | border-bottom-right-radius,
|
283 | list.nth($radii, 3),
|
284 | $gss: $gss
|
285 | );
|
286 | @include theme.property(
|
287 | border-bottom-left-radius,
|
288 | list.nth($radii, 4),
|
289 | $gss: $gss
|
290 | );
|
291 | }
|
292 |
|
293 | @if ($needs-flip) {
|
294 | @include rtl.rtl {
|
295 |
|
296 | $gss: (
|
297 | noflip: true,
|
298 | );
|
299 | $radii: flip-radius(unpack-radius($radius));
|
300 | @include theme.property(
|
301 | border-top-left-radius,
|
302 | list.nth($radii, 1),
|
303 | $gss: $gss
|
304 | );
|
305 | @include theme.property(
|
306 | border-top-right-radius,
|
307 | list.nth($radii, 2),
|
308 | $gss: $gss
|
309 | );
|
310 | @include theme.property(
|
311 | border-bottom-right-radius,
|
312 | list.nth($radii, 3),
|
313 | $gss: $gss
|
314 | );
|
315 | @include theme.property(
|
316 | border-bottom-left-radius,
|
317 | list.nth($radii, 4),
|
318 | $gss: $gss
|
319 | );
|
320 | }
|
321 | }
|
322 | }
|
323 | }
|