1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 | @use 'sass:map';
|
27 | @use '@material/density/functions' as density-functions;
|
28 | @use '@material/feature-targeting/feature-targeting';
|
29 | @use '@material/theme/theme';
|
30 | @use '@material/theme/keys';
|
31 | @use '@material/density/variables' as density-variables;
|
32 | @use '@material/theme/theme-color';
|
33 | @use '@material/ripple/ripple-theme';
|
34 |
|
35 | $ripple-size: 40px !default;
|
36 | $icon-size: 20px !default;
|
37 | $transition-duration: 120ms !default;
|
38 | $ripple-opacity: 0.14 !default;
|
39 | $baseline-theme-color: secondary !default;
|
40 | $unchecked-color: rgba(theme-color.prop-value(on-surface), 0.54) !default;
|
41 | $disabled-circle-color: rgba(theme-color.prop-value(on-surface), 0.38) !default;
|
42 |
|
43 | $minimum-size: 28px !default;
|
44 | $maximum-size: $ripple-size !default;
|
45 | $density-scale: density-variables.$default-scale !default;
|
46 | $density-config: (
|
47 | size: (
|
48 | minimum: $minimum-size,
|
49 | default: $ripple-size,
|
50 | maximum: $maximum-size,
|
51 | ),
|
52 | ) !default;
|
53 |
|
54 | $ripple-target: '.mdc-radio__ripple';
|
55 | $unselected-ripple-target: '.mdc-radio__native-control:enabled:not(:checked) ~ #{$ripple-target}';
|
56 | $custom-property-prefix: 'radio';
|
57 |
|
58 |
|
59 | $light-theme: (
|
60 | disabled-selected-icon-color: theme-color.$on-surface,
|
61 | disabled-selected-icon-opacity: 0.38,
|
62 | disabled-unselected-icon-color: theme-color.$on-surface,
|
63 | disabled-unselected-icon-opacity: 0.38,
|
64 | selected-focus-icon-color: theme-color.$primary,
|
65 | selected-focus-state-layer-color: theme-color.$primary,
|
66 | selected-focus-state-layer-opacity: 0.12,
|
67 | selected-hover-icon-color: theme-color.$primary,
|
68 | selected-hover-state-layer-color: theme-color.$primary,
|
69 | selected-hover-state-layer-opacity: 0.04,
|
70 | selected-icon-color: theme-color.$primary,
|
71 | selected-pressed-icon-color: theme-color.$primary,
|
72 | selected-pressed-state-layer-color: theme-color.$primary,
|
73 | selected-pressed-state-layer-opacity: 0.1,
|
74 | state-layer-size: $ripple-size,
|
75 | unselected-focus-icon-color: theme-color.$on-surface,
|
76 | unselected-focus-state-layer-color: theme-color.$on-surface,
|
77 | unselected-focus-state-layer-opacity: 0.12,
|
78 | unselected-hover-icon-color: theme-color.$on-surface,
|
79 | unselected-hover-state-layer-color: theme-color.$on-surface,
|
80 | unselected-hover-state-layer-opacity: 0.04,
|
81 | unselected-icon-color: theme-color.$on-surface,
|
82 | unselected-pressed-icon-color: theme-color.$on-surface,
|
83 | unselected-pressed-state-layer-color: theme-color.$on-surface,
|
84 | unselected-pressed-state-layer-opacity: 0.1,
|
85 | );
|
86 |
|
87 | @mixin theme($theme) {
|
88 | @include theme.validate-theme($light-theme, $theme);
|
89 | @include keys.declare-custom-properties(
|
90 | $theme,
|
91 | $prefix: $custom-property-prefix
|
92 | );
|
93 | }
|
94 |
|
95 | @mixin theme-styles($theme) {
|
96 | @include theme.validate-theme-keys($light-theme, $theme);
|
97 |
|
98 | $theme: keys.create-theme-properties(
|
99 | $theme,
|
100 | $prefix: $custom-property-prefix
|
101 | );
|
102 |
|
103 | @include _disabled-selected-icon-color(
|
104 | map.get($theme, disabled-selected-icon-color)
|
105 | );
|
106 | @include _disabled-selected-icon-opacity(
|
107 | map.get($theme, disabled-selected-icon-opacity)
|
108 | );
|
109 | @include _disabled-unselected-icon-color(
|
110 | map.get($theme, disabled-unselected-icon-color)
|
111 | );
|
112 | @include _disabled-unselected-icon-opacity(
|
113 | map.get($theme, disabled-unselected-icon-opacity)
|
114 | );
|
115 |
|
116 |
|
117 | @include ripple-theme.focus() {
|
118 | @include _selected-icon-color(map.get($theme, selected-focus-icon-color));
|
119 | @include _selected-state-layer-color(
|
120 | map.get($theme, selected-focus-state-layer-color)
|
121 | );
|
122 | @include _selected-focus-state-layer-opacity(
|
123 | map.get($theme, selected-focus-state-layer-opacity)
|
124 | );
|
125 | }
|
126 | @include ripple-theme.hover() {
|
127 | @include _selected-icon-color(map.get($theme, selected-hover-icon-color));
|
128 | @include _selected-state-layer-color(
|
129 | map.get($theme, selected-hover-state-layer-color)
|
130 | );
|
131 | @include _selected-hover-state-layer-opacity(
|
132 | map.get($theme, selected-hover-state-layer-opacity)
|
133 | );
|
134 | }
|
135 | @include _selected-icon-color(map.get($theme, selected-icon-color));
|
136 | @include ripple-theme.active() {
|
137 | @include _selected-icon-color(map.get($theme, selected-pressed-icon-color));
|
138 | @include _selected-state-layer-color(
|
139 | map.get($theme, selected-pressed-state-layer-color)
|
140 | );
|
141 | @include _selected-pressed-state-layer-opacity(
|
142 | map.get($theme, selected-pressed-state-layer-opacity)
|
143 | );
|
144 | }
|
145 |
|
146 |
|
147 | @include ripple-theme.focus() {
|
148 | @include _unselected-icon-color(
|
149 | map.get($theme, unselected-focus-icon-color)
|
150 | );
|
151 | @include _unselected-state-layer-color(
|
152 | map.get($theme, unselected-focus-state-layer-color)
|
153 | );
|
154 | @include _unselected-focus-state-layer-opacity(
|
155 | map.get($theme, unselected-focus-state-layer-opacity)
|
156 | );
|
157 | }
|
158 | @include ripple-theme.hover() {
|
159 | @include _unselected-icon-color(
|
160 | map.get($theme, unselected-hover-icon-color)
|
161 | );
|
162 | @include _unselected-state-layer-color(
|
163 | map.get($theme, unselected-hover-state-layer-color)
|
164 | );
|
165 | @include _unselected-hover-state-layer-opacity(
|
166 | map.get($theme, unselected-hover-state-layer-opacity)
|
167 | );
|
168 | }
|
169 | @include _unselected-icon-color(map.get($theme, unselected-icon-color));
|
170 | @include ripple-theme.active() {
|
171 | @include _unselected-icon-color(
|
172 | map.get($theme, unselected-pressed-icon-color)
|
173 | );
|
174 | @include _unselected-state-layer-color(
|
175 | map.get($theme, unselected-pressed-state-layer-color)
|
176 | );
|
177 | @include _unselected-pressed-state-layer-opacity(
|
178 | map.get($theme, unselected-pressed-state-layer-opacity)
|
179 | );
|
180 | }
|
181 |
|
182 | @include ripple-size(map.get($theme, state-layer-size));
|
183 |
|
184 | @include touch-target(
|
185 | $size: map.get($theme, state-layer-size),
|
186 | $ripple-size: map.get($theme, state-layer-size)
|
187 | );
|
188 | }
|
189 |
|
190 | @mixin _disabled-selected-icon-color($color) {
|
191 | @include disabled-checked-stroke-color($color);
|
192 | @include disabled-ink-color($color);
|
193 | }
|
194 |
|
195 | @mixin _disabled-selected-icon-opacity($opacity) {
|
196 | @include _disabled-checked-stroke-opacity($opacity);
|
197 | @include _disabled-ink-opacity($opacity);
|
198 | }
|
199 |
|
200 | @mixin _disabled-unselected-icon-color($color) {
|
201 | @include disabled-unchecked-stroke-color($color);
|
202 | }
|
203 |
|
204 | @mixin _disabled-unselected-icon-opacity($opacity) {
|
205 | @include _disabled-unchecked-stroke-opacity($opacity);
|
206 | }
|
207 |
|
208 | @mixin _selected-icon-color($color) {
|
209 | @include checked-stroke-color($color);
|
210 | @include ink-color($color);
|
211 | }
|
212 |
|
213 | @mixin _selected-state-layer-color($color) {
|
214 | @include ripple-theme.states-base-color(
|
215 | $color: $color,
|
216 | $ripple-target: $ripple-target
|
217 | );
|
218 | }
|
219 |
|
220 | @mixin _selected-hover-state-layer-opacity($opacity) {
|
221 | @include ripple-theme.states-hover-opacity(
|
222 | $opacity: $opacity,
|
223 | $ripple-target: $ripple-target
|
224 | );
|
225 | }
|
226 |
|
227 | @mixin _selected-focus-state-layer-opacity($opacity) {
|
228 | @include ripple-theme.states-focus-opacity(
|
229 | $opacity: $opacity,
|
230 | $ripple-target: $ripple-target
|
231 | );
|
232 | }
|
233 |
|
234 | @mixin _selected-pressed-state-layer-opacity($opacity) {
|
235 | @include ripple-theme.states-press-opacity(
|
236 | $opacity: $opacity,
|
237 | $ripple-target: $ripple-target
|
238 | );
|
239 | }
|
240 |
|
241 | @mixin _unselected-icon-color($color) {
|
242 | @include unchecked-stroke-color($color);
|
243 | }
|
244 |
|
245 | @mixin _unselected-state-layer-color($color) {
|
246 | @include ripple-theme.states-base-color(
|
247 | $color: $color,
|
248 | $ripple-target: $unselected-ripple-target
|
249 | );
|
250 | }
|
251 |
|
252 | @mixin _unselected-hover-state-layer-opacity($opacity) {
|
253 | @include ripple-theme.states-hover-opacity(
|
254 | $opacity: $opacity,
|
255 | $ripple-target: $unselected-ripple-target
|
256 | );
|
257 | }
|
258 |
|
259 | @mixin _unselected-focus-state-layer-opacity($opacity) {
|
260 | @include ripple-theme.states-focus-opacity(
|
261 | $opacity: $opacity,
|
262 | $ripple-target: $unselected-ripple-target
|
263 | );
|
264 | }
|
265 |
|
266 | @mixin _unselected-pressed-state-layer-opacity($opacity) {
|
267 | @include ripple-theme.states-press-opacity(
|
268 | $opacity: $opacity,
|
269 | $ripple-target: $unselected-ripple-target
|
270 | );
|
271 | }
|
272 |
|
273 |
|
274 |
|
275 |
|
276 |
|
277 | @mixin unchecked-stroke-color($color, $query: feature-targeting.all()) {
|
278 | @include _if-enabled-unchecked {
|
279 | @include _stroke-color($color, $query: $query);
|
280 | }
|
281 | }
|
282 |
|
283 |
|
284 |
|
285 |
|
286 |
|
287 | @mixin checked-stroke-color($color, $query: feature-targeting.all()) {
|
288 | @include _if-enabled-checked {
|
289 | @include _stroke-color($color, $query: $query);
|
290 | }
|
291 | }
|
292 |
|
293 |
|
294 |
|
295 |
|
296 |
|
297 | @mixin ink-color($color, $query: feature-targeting.all()) {
|
298 | @include _if-enabled {
|
299 | @include _ink-color($color, $query: $query);
|
300 | }
|
301 | }
|
302 |
|
303 |
|
304 |
|
305 |
|
306 |
|
307 | @mixin disabled-unchecked-stroke-color(
|
308 | $color,
|
309 | $query: feature-targeting.all()
|
310 | ) {
|
311 | @include _if-disabled-unchecked {
|
312 | @include _stroke-color($color, $query: $query);
|
313 | }
|
314 | }
|
315 |
|
316 | @mixin _disabled-unchecked-stroke-opacity($opacity) {
|
317 | @include _if-disabled-unchecked {
|
318 | @include _stroke-opacity($opacity);
|
319 | }
|
320 | }
|
321 |
|
322 |
|
323 |
|
324 |
|
325 |
|
326 | @mixin disabled-checked-stroke-color($color, $query: feature-targeting.all()) {
|
327 | @include if-disabled-checked_ {
|
328 | @include _stroke-color($color, $query: $query);
|
329 | }
|
330 | }
|
331 |
|
332 | @mixin _disabled-checked-stroke-opacity($opacity) {
|
333 | @include if-disabled-checked_ {
|
334 | @include _stroke-opacity($opacity);
|
335 | }
|
336 | }
|
337 |
|
338 |
|
339 |
|
340 |
|
341 |
|
342 | @mixin disabled-ink-color($color, $query: feature-targeting.all()) {
|
343 | @include if-disabled_ {
|
344 | @include _ink-color($color, $query: $query);
|
345 | }
|
346 | }
|
347 |
|
348 | @mixin _disabled-ink-opacity($opacity) {
|
349 | @include if-disabled_ {
|
350 | @include _ink-opacity($opacity);
|
351 | }
|
352 | }
|
353 |
|
354 | @mixin focus-indicator-color($color, $query: feature-targeting.all()) {
|
355 | $feat-color: feature-targeting.create-target($query, color);
|
356 |
|
357 | .mdc-radio__background::before {
|
358 | @include feature-targeting.targets($feat-color) {
|
359 | @include theme.property(background-color, $color);
|
360 | }
|
361 | }
|
362 | }
|
363 |
|
364 |
|
365 |
|
366 |
|
367 |
|
368 |
|
369 |
|
370 |
|
371 | @mixin touch-target(
|
372 | $size: $ripple-size,
|
373 | $ripple-size: $ripple-size,
|
374 | $query: feature-targeting.all()
|
375 | ) {
|
376 | $feat-structure: feature-targeting.create-target($query, structure);
|
377 | $offset: 'calc((__ripple_size - __size) / 2)';
|
378 | $replace: (
|
379 | __ripple_size: $ripple-size,
|
380 | __size: $size,
|
381 | );
|
382 |
|
383 | .mdc-radio__native-control {
|
384 | @include feature-targeting.targets($feat-structure) {
|
385 | @include theme.property('top', $offset, $replace: $replace);
|
386 | @include theme.property('right', $offset, $replace: $replace);
|
387 | @include theme.property('left', $offset, $replace: $replace);
|
388 | @include theme.property('width', $size);
|
389 | @include theme.property('height', $size);
|
390 | }
|
391 | }
|
392 | }
|
393 |
|
394 |
|
395 |
|
396 |
|
397 |
|
398 |
|
399 |
|
400 | @mixin density($density-scale, $query: feature-targeting.all()) {
|
401 | $size: density-functions.prop-value(
|
402 | $density-config: $density-config,
|
403 | $density-scale: $density-scale,
|
404 | $property-name: size,
|
405 | );
|
406 |
|
407 | @include ripple-size($size, $query: $query);
|
408 |
|
409 | @include touch-target($size: $size, $ripple-size: $size, $query: $query);
|
410 |
|
411 | @if $density-scale != 0 {
|
412 | @include touch-target-reset_($query: $query);
|
413 | }
|
414 | }
|
415 |
|
416 |
|
417 |
|
418 |
|
419 |
|
420 |
|
421 | @mixin ripple-size($size, $query: feature-targeting.all()) {
|
422 | $feat-structure: feature-targeting.create-target($query, structure);
|
423 | $replace: (
|
424 | __size: $size,
|
425 | __icon_size: $icon-size,
|
426 | );
|
427 |
|
428 | @include feature-targeting.targets($feat-structure) {
|
429 | $padding: 'calc((__size - __icon_size) / 2)';
|
430 |
|
431 | @include theme.property('padding', $padding, $replace: $replace);
|
432 | }
|
433 |
|
434 | .mdc-radio__background::before {
|
435 | @include feature-targeting.targets($feat-structure) {
|
436 | $padding-offset: 'calc(-1 * (__size - __icon_size) / 2)';
|
437 |
|
438 | @include theme.property('top', $padding-offset, $replace: $replace);
|
439 | @include theme.property('left', $padding-offset, $replace: $replace);
|
440 | @include theme.property('width', $size);
|
441 | @include theme.property('height', $size);
|
442 | }
|
443 | }
|
444 | }
|
445 |
|
446 |
|
447 |
|
448 |
|
449 |
|
450 |
|
451 |
|
452 | @mixin touch-target-reset_($query: feature-targeting.all()) {
|
453 | $feat-structure: feature-targeting.create-target($query, structure);
|
454 |
|
455 | @include feature-targeting.targets($feat-structure) {
|
456 | margin: 0;
|
457 | }
|
458 | }
|
459 |
|
460 |
|
461 |
|
462 |
|
463 |
|
464 |
|
465 | @mixin _if-enabled {
|
466 | .mdc-radio__native-control:enabled + {
|
467 | @content;
|
468 | }
|
469 | }
|
470 |
|
471 |
|
472 |
|
473 |
|
474 |
|
475 |
|
476 | @mixin _if-enabled-unchecked {
|
477 | .mdc-radio__native-control:enabled:not(:checked) + {
|
478 | @content;
|
479 | }
|
480 | }
|
481 |
|
482 |
|
483 |
|
484 |
|
485 |
|
486 |
|
487 | @mixin _if-enabled-checked {
|
488 | .mdc-radio__native-control:enabled:checked + {
|
489 | @content;
|
490 | }
|
491 | }
|
492 |
|
493 |
|
494 |
|
495 |
|
496 |
|
497 |
|
498 | @mixin if-disabled_ {
|
499 | [aria-disabled='true'] .mdc-radio__native-control,
|
500 | .mdc-radio__native-control:disabled {
|
501 | + {
|
502 | @content;
|
503 | }
|
504 | }
|
505 | }
|
506 |
|
507 |
|
508 |
|
509 |
|
510 |
|
511 |
|
512 | @mixin _if-disabled-unchecked {
|
513 | [aria-disabled='true'] .mdc-radio__native-control,
|
514 | .mdc-radio__native-control:disabled {
|
515 | &:not(:checked) + {
|
516 | @content;
|
517 | }
|
518 | }
|
519 | }
|
520 |
|
521 |
|
522 |
|
523 |
|
524 |
|
525 |
|
526 | @mixin if-disabled-checked_ {
|
527 | [aria-disabled='true'] .mdc-radio__native-control,
|
528 | .mdc-radio__native-control:disabled {
|
529 | &:checked + {
|
530 | @content;
|
531 | }
|
532 | }
|
533 | }
|
534 |
|
535 |
|
536 |
|
537 |
|
538 |
|
539 |
|
540 | @mixin _ink-color($color, $query: feature-targeting.all()) {
|
541 | $feat-color: feature-targeting.create-target($query, color);
|
542 |
|
543 | .mdc-radio__background .mdc-radio__inner-circle {
|
544 | @include feature-targeting.targets($feat-color) {
|
545 | @include theme.property(border-color, $color);
|
546 | }
|
547 | }
|
548 | }
|
549 |
|
550 | @mixin _ink-opacity($opacity) {
|
551 | .mdc-radio__background .mdc-radio__inner-circle {
|
552 | @include theme.property(opacity, $opacity);
|
553 | }
|
554 | }
|
555 |
|
556 |
|
557 |
|
558 |
|
559 |
|
560 |
|
561 | @mixin _stroke-color($color, $query: feature-targeting.all()) {
|
562 | $feat-color: feature-targeting.create-target($query, color);
|
563 |
|
564 | .mdc-radio__background .mdc-radio__outer-circle {
|
565 | @include feature-targeting.targets($feat-color) {
|
566 | @include theme.property(border-color, $color);
|
567 | }
|
568 | }
|
569 | }
|
570 |
|
571 | @mixin _stroke-opacity($opacity) {
|
572 | .mdc-radio__background .mdc-radio__outer-circle {
|
573 | @include theme.property(opacity, $opacity);
|
574 | }
|
575 | }
|