Skip to content

Commit 199534d

Browse files
authored
feat(radio): Add density mixin to radio (material-components#5118)
BREAKING CHANGE: In Checkbox, Renamed sass variables `$mdc-radio-touch-area` => `$mdc-radio-ripple-size` & `$mdc-radio-ui-size` => `$mdc-radio-icon-size` to be consistent with checkbox. Also, removed `$mdc-radio-ui-pct` sass variable.
1 parent 8765899 commit 199534d

File tree

11 files changed

+357
-36
lines changed

11 files changed

+357
-36
lines changed

packages/mdc-density/_variables.scss

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,4 @@ $mdc-density-minimum-scale: minimum !default;
2525
$mdc-density-maximum-scale: maximum !default;
2626
$mdc-density-supported-scales: (default, minimum, maximum) !default;
2727
$mdc-density-supported-properties: (height, size) !default;
28-
$mdc-density-default-scale: default !default;
28+
$mdc-density-default-scale: 0 !default;

packages/mdc-radio/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@ Mixin | Description
131131
`mdc-radio-checked-stroke-color($color)` | Sets the stroke color of a checked radio button
132132
`mdc-radio-ink-color($color)` | Sets the ink color of a radio button
133133
`mdc-radio-focus-indicator-color($color)` | Sets the color of the focus indicator
134+
`mdc-radio-touch-target($size, $ripple-size)` | Sets radio touch target size which can be more than the ripple size. Param `$ripple-size` is required for custom ripple size, defaults to `$mdc-radio-ripple-size`.
135+
`mdc-radio-ripple-size($size)` | Sets custom ripple size of radio.
136+
`mdc-radio-density($density-scale)` | Sets density scale for radio. Supported density scale values are `-3`, `-2`, `-1` and `0` (default).
134137

135138
#### Caveat: Edge and CSS Custom Properties
136139

packages/mdc-radio/_mixins.scss

+82-21
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
//
2222

2323
@import "@material/animation/functions";
24+
@import "@material/density/functions";
2425
@import "@material/feature-targeting/functions";
2526
@import "@material/feature-targeting/mixins";
2627
@import "@material/ripple/mixins";
@@ -48,22 +49,20 @@ $mdc-radio-ripple-target: ".mdc-radio__ripple";
4849
$feat-color: mdc-feature-create-target($query, color);
4950
$feat-structure: mdc-feature-create-target($query, structure);
5051

51-
@include mdc-radio-touch-target($size: $mdc-radio-touch-area, $query: $query);
52-
5352
.mdc-radio {
5453
@include mdc-radio-unchecked-stroke-color($mdc-radio-unchecked-color, $query);
5554
@include mdc-radio-checked-stroke-color($mdc-radio-baseline-theme-color, $query);
5655
@include mdc-radio-ink-color($mdc-radio-baseline-theme-color, $query);
5756
@include mdc-radio-focus-indicator-color($mdc-radio-baseline-theme-color, $query);
57+
@include mdc-radio-density($mdc-radio-density-scale, $query);
5858

5959
@include mdc-feature-targets($feat-structure) {
6060
display: inline-block;
6161
position: relative;
6262
flex: 0 0 auto;
63-
box-sizing: border-box;
64-
width: $mdc-radio-touch-area;
65-
height: $mdc-radio-touch-area;
66-
padding: ($mdc-radio-touch-area - $mdc-radio-ui-size) / 2;
63+
box-sizing: content-box;
64+
width: $mdc-radio-icon-size;
65+
height: $mdc-radio-icon-size;
6766
cursor: pointer;
6867
/* @alternate */
6968
will-change: opacity, transform, border-color, color;
@@ -73,20 +72,15 @@ $mdc-radio-ripple-target: ".mdc-radio__ripple";
7372
&__background {
7473
@include mdc-feature-targets($feat-structure) {
7574
display: inline-block;
76-
position: absolute;
77-
left: ($mdc-radio-touch-area - $mdc-radio-ui-size) / 2;
75+
position: relative;
7876
box-sizing: border-box;
79-
width: $mdc-radio-ui-pct;
80-
height: $mdc-radio-ui-pct;
77+
width: $mdc-radio-icon-size;
78+
height: $mdc-radio-icon-size;
8179
}
8280

8381
&::before {
8482
@include mdc-feature-targets($feat-structure) {
8583
position: absolute;
86-
top: 0;
87-
left: 0;
88-
width: 100%;
89-
height: 100%;
9084
transform: scale(0, 0);
9185
border-radius: 50%;
9286
opacity: 0;
@@ -142,8 +136,6 @@ $mdc-radio-ripple-target: ".mdc-radio__ripple";
142136
&__native-control {
143137
@include mdc-feature-targets($feat-structure) {
144138
position: absolute;
145-
width: 100%;
146-
height: 100%;
147139
margin: 0;
148140
padding: 0;
149141
opacity: 0;
@@ -154,8 +146,8 @@ $mdc-radio-ripple-target: ".mdc-radio__ripple";
154146

155147
&--touch {
156148
@include mdc-touch-target-component(
157-
$component-height: $mdc-radio-touch-area,
158-
$component-width: $mdc-radio-touch-area,
149+
$component-height: $mdc-radio-ripple-size,
150+
$component-width: $mdc-radio-ripple-size,
159151
$query: $query);
160152
@include mdc-radio-touch-target($size: $mdc-touch-target-height, $query: $query);
161153
}
@@ -233,7 +225,7 @@ $mdc-radio-ripple-target: ".mdc-radio__ripple";
233225
.mdc-radio__native-control:focus {
234226
+ .mdc-radio__background::before {
235227
@include mdc-feature-targets($feat-structure) {
236-
transform: scale(2, 2);
228+
transform: scale(1);
237229
opacity: map-get($mdc-ripple-dark-ink-opacities, focus);
238230
}
239231

@@ -318,9 +310,19 @@ $mdc-radio-ripple-target: ".mdc-radio__ripple";
318310
}
319311
}
320312

321-
@mixin mdc-radio-touch-target($size: $mdc-radio-touch-area, $query: mdc-feature-all()) {
313+
///
314+
/// Sets radio touch target size which can be more than the ripple size. Param `$ripple-size` is required for custom
315+
/// ripple size.
316+
///
317+
/// @param {Number} $size Size of touch target (Native input) in `px`.
318+
/// @param {Number} $ripple-size Size of ripple in `px`. Required only for custom ripple size.
319+
///
320+
@mixin mdc-radio-touch-target(
321+
$size: $mdc-radio-ripple-size,
322+
$ripple-size: $mdc-radio-ripple-size,
323+
$query: mdc-feature-all()) {
322324
$feat-structure: mdc-feature-create-target($query, structure);
323-
$offset: ($mdc-radio-touch-area - $size) / 2;
325+
$offset: ($ripple-size - $size) / 2;
324326

325327
.mdc-radio__native-control {
326328
@include mdc-feature-targets($feat-structure) {
@@ -332,3 +334,62 @@ $mdc-radio-ripple-target: ".mdc-radio__ripple";
332334
}
333335
}
334336
}
337+
338+
///
339+
/// Sets density scale for radio.
340+
///
341+
/// @param {Number | String} $density-scale - Density scale value for component. Supported density scale values
342+
/// `-3`, `-2`, `-1`, `0`.
343+
///
344+
@mixin mdc-radio-density($density-scale, $query: mdc-feature-all()) {
345+
$size: mdc-density-prop-value(
346+
$density-config: $mdc-radio-density-config,
347+
$density-scale: $density-scale,
348+
$property-name: size,
349+
);
350+
351+
@include mdc-radio-ripple-size($size, $query: $query);
352+
// Sets touch target size same as ripple size.
353+
@include mdc-radio-touch-target($size: $size, $ripple-size: $size, $query: $query);
354+
355+
@if $density-scale != 0 {
356+
@include mdc-radio-touch-target-reset_($query: $query);
357+
}
358+
}
359+
360+
///
361+
/// Sets radio ripple size.
362+
///
363+
/// @param {Number} $size - Ripple size in `px`.
364+
///
365+
@mixin mdc-radio-ripple-size($size, $query: mdc-feature-all()) {
366+
$feat-structure: mdc-feature-create-target($query, structure);
367+
$padding: ($size - $mdc-radio-icon-size) / 2;
368+
369+
@include mdc-feature-targets($feat-structure) {
370+
padding: $padding;
371+
}
372+
373+
.mdc-radio__background::before {
374+
@include mdc-feature-targets($feat-structure) {
375+
top: -$padding;
376+
left: -$padding;
377+
width: $size;
378+
height: $size;
379+
}
380+
}
381+
}
382+
383+
///
384+
/// Resets touch target-related styles. This is called from the density mixin to
385+
/// automatically remove the increased touch target, since dense components
386+
/// don't have the same default a11y requirements.
387+
/// @access private
388+
///
389+
@mixin mdc-radio-touch-target-reset_($query: mdc-feature-all()) {
390+
$feat-structure: mdc-feature-create-target($query, structure);
391+
392+
@include mdc-feature-targets($feat-structure) {
393+
margin: 0;
394+
}
395+
}

packages/mdc-radio/_variables.scss

+14-3
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,24 @@
2020
// THE SOFTWARE.
2121
//
2222

23+
@import "@material/density/variables";
2324
@import "@material/theme/variables";
2425

25-
$mdc-radio-touch-area: 40px !default;
26-
$mdc-radio-ui-size: 20px !default;
27-
$mdc-radio-ui-pct: percentage($mdc-radio-ui-size / $mdc-radio-touch-area) !default;
26+
$mdc-radio-ripple-size: 40px !default;
27+
$mdc-radio-icon-size: 20px !default;
2828
$mdc-radio-transition-duration: 120ms !default;
2929
$mdc-radio-ripple-opacity: .14 !default;
3030
$mdc-radio-baseline-theme-color: secondary !default;
3131
$mdc-radio-unchecked-color: rgba(mdc-theme-prop-value(on-surface), .54) !default;
3232
$mdc-radio-circle-color: rgba(mdc-theme-prop-value(on-surface), .26) !default;
33+
34+
$mdc-radio-minimum-size: 28px !default;
35+
$mdc-radio-maximum-size: $mdc-radio-ripple-size !default;
36+
$mdc-radio-density-scale: $mdc-density-default-scale !default;
37+
$mdc-radio-density-config: (
38+
size: (
39+
minimum: $mdc-radio-minimum-size,
40+
default: $mdc-radio-ripple-size,
41+
maximum: $mdc-radio-maximum-size,
42+
),
43+
) !default;

packages/mdc-radio/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"dependencies": {
2121
"@material/animation": "^3.1.0",
2222
"@material/base": "^3.1.0",
23+
"@material/density": "^0.0.0",
2324
"@material/dom": "^3.1.0",
2425
"@material/feature-targeting": "^3.1.0",
2526
"@material/ripple": "^3.2.0",

test/screenshot/golden.json

+24-8
Original file line numberDiff line numberDiff line change
@@ -903,20 +903,36 @@
903903
"desktop_windows_ie@11": "https://storage.googleapis.com/mdc-web-screenshot-tests/travis/2019/01/18/07_50_32_667/spec/mdc-menu/issues/4025.html.windows_ie_11.png"
904904
}
905905
},
906+
"spec/mdc-radio/classes/baseline-touch-target.html": {
907+
"public_url": "https://storage.googleapis.com/mdc-web-screenshot-tests/travis/2019/09/27/01_14_23_992/spec/mdc-radio/classes/baseline-touch-target.html?utm_source=golden_json",
908+
"screenshots": {
909+
"desktop_windows_chrome@latest": "https://storage.googleapis.com/mdc-web-screenshot-tests/travis/2019/09/27/01_14_23_992/spec/mdc-radio/classes/baseline-touch-target.html.windows_chrome_76.png",
910+
"desktop_windows_firefox@latest": "https://storage.googleapis.com/mdc-web-screenshot-tests/travis/2019/09/27/01_14_23_992/spec/mdc-radio/classes/baseline-touch-target.html.windows_firefox_69.png",
911+
"desktop_windows_ie@11": "https://storage.googleapis.com/mdc-web-screenshot-tests/travis/2019/09/27/01_14_23_992/spec/mdc-radio/classes/baseline-touch-target.html.windows_ie_11.png"
912+
}
913+
},
906914
"spec/mdc-radio/classes/baseline.html": {
907-
"public_url": "https://storage.googleapis.com/mdc-web-screenshot-tests/travis/2019/05/03/18_19_22_511/spec/mdc-radio/classes/baseline.html?utm_source=golden_json",
915+
"public_url": "https://storage.googleapis.com/mdc-web-screenshot-tests/travis/2019/09/20/22_06_30_583/spec/mdc-radio/classes/baseline.html?utm_source=golden_json",
916+
"screenshots": {
917+
"desktop_windows_chrome@latest": "https://storage.googleapis.com/mdc-web-screenshot-tests/travis/2019/09/20/22_06_30_583/spec/mdc-radio/classes/baseline.html.windows_chrome_76.png",
918+
"desktop_windows_firefox@latest": "https://storage.googleapis.com/mdc-web-screenshot-tests/travis/2019/09/20/22_06_30_583/spec/mdc-radio/classes/baseline.html.windows_firefox_69.png",
919+
"desktop_windows_ie@11": "https://storage.googleapis.com/mdc-web-screenshot-tests/travis/2019/09/20/22_06_30_583/spec/mdc-radio/classes/baseline.html.windows_ie_11.png"
920+
}
921+
},
922+
"spec/mdc-radio/mixins/density.html": {
923+
"public_url": "https://storage.googleapis.com/mdc-web-screenshot-tests/travis/2019/09/27/01_14_23_992/spec/mdc-radio/mixins/density.html?utm_source=golden_json",
908924
"screenshots": {
909-
"desktop_windows_chrome@latest": "https://storage.googleapis.com/mdc-web-screenshot-tests/travis/2019/05/03/18_19_22_511/spec/mdc-radio/classes/baseline.html.windows_chrome_74.png",
910-
"desktop_windows_firefox@latest": "https://storage.googleapis.com/mdc-web-screenshot-tests/travis/2018/09/10/17_42_51_602/spec/mdc-radio/classes/baseline.html.windows_firefox_62.png",
911-
"desktop_windows_ie@11": "https://storage.googleapis.com/mdc-web-screenshot-tests/advorak/2018/09/03/23_44_52_047/spec/mdc-radio/classes/baseline.html.windows_ie_11.png"
925+
"desktop_windows_chrome@latest": "https://storage.googleapis.com/mdc-web-screenshot-tests/travis/2019/09/27/01_14_23_992/spec/mdc-radio/mixins/density.html.windows_chrome_76.png",
926+
"desktop_windows_firefox@latest": "https://storage.googleapis.com/mdc-web-screenshot-tests/travis/2019/09/27/01_14_23_992/spec/mdc-radio/mixins/density.html.windows_firefox_69.png",
927+
"desktop_windows_ie@11": "https://storage.googleapis.com/mdc-web-screenshot-tests/travis/2019/09/27/01_14_23_992/spec/mdc-radio/mixins/density.html.windows_ie_11.png"
912928
}
913929
},
914930
"spec/mdc-radio/mixins/mixins.html": {
915-
"public_url": "https://storage.googleapis.com/mdc-web-screenshot-tests/travis/2019/05/03/18_19_22_511/spec/mdc-radio/mixins/mixins.html?utm_source=golden_json",
931+
"public_url": "https://storage.googleapis.com/mdc-web-screenshot-tests/travis/2019/09/20/22_06_30_583/spec/mdc-radio/mixins/mixins.html?utm_source=golden_json",
916932
"screenshots": {
917-
"desktop_windows_chrome@latest": "https://storage.googleapis.com/mdc-web-screenshot-tests/travis/2019/05/03/18_19_22_511/spec/mdc-radio/mixins/mixins.html.windows_chrome_74.png",
918-
"desktop_windows_firefox@latest": "https://storage.googleapis.com/mdc-web-screenshot-tests/travis/2018/09/10/17_42_51_602/spec/mdc-radio/mixins/mixins.html.windows_firefox_62.png",
919-
"desktop_windows_ie@11": "https://storage.googleapis.com/mdc-web-screenshot-tests/advorak/2018/09/03/23_44_52_047/spec/mdc-radio/mixins/mixins.html.windows_ie_11.png"
933+
"desktop_windows_chrome@latest": "https://storage.googleapis.com/mdc-web-screenshot-tests/travis/2019/09/20/22_06_30_583/spec/mdc-radio/mixins/mixins.html.windows_chrome_76.png",
934+
"desktop_windows_firefox@latest": "https://storage.googleapis.com/mdc-web-screenshot-tests/travis/2019/09/20/22_06_30_583/spec/mdc-radio/mixins/mixins.html.windows_firefox_69.png",
935+
"desktop_windows_ie@11": "https://storage.googleapis.com/mdc-web-screenshot-tests/travis/2019/09/20/22_06_30_583/spec/mdc-radio/mixins/mixins.html.windows_ie_11.png"
920936
}
921937
},
922938
"spec/mdc-rtl/variables/include.html": {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
<!DOCTYPE html>
2+
<!--
3+
Copyright 2019 Google Inc.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.
22+
-->
23+
<html lang="en">
24+
<head>
25+
<meta charset="utf-8">
26+
<title>Radio With Touch Target - MDC Web Screenshot Test</title>
27+
<meta name="viewport" content="width=device-width, initial-scale=1">
28+
<link rel="stylesheet" href="../../../out/mdc.radio.css">
29+
<link rel="stylesheet" href="../../../out/spec/fixture.css">
30+
<link rel="stylesheet" href="../../../out/spec/mdc-radio/fixture.css">
31+
32+
<!-- Global site tag (gtag.js) - Google Analytics -->
33+
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-118996389-2"></script>
34+
<script>
35+
window.dataLayer = window.dataLayer || [];
36+
function gtag(){dataLayer.push(arguments);}
37+
gtag('js', new Date());
38+
gtag('config', 'UA-118996389-2');
39+
</script>
40+
</head>
41+
42+
<body class="test-container">
43+
<main class="test-viewport test-viewport--mobile">
44+
<div class="test-layout">
45+
<div class="test-cell test-cell--light test-cell--radio">
46+
<div class="mdc-radio mdc-radio--touch">
47+
<input class="mdc-radio__native-control" type="radio" name="enabled-radio-group"
48+
id="test-radio-1" data-autofocus>
49+
<div class="mdc-radio__background">
50+
<div class="mdc-radio__outer-circle"></div>
51+
<div class="mdc-radio__inner-circle"></div>
52+
</div>
53+
<div class="mdc-radio__ripple"></div>
54+
</div>
55+
<label class="test-radio-label" for="test-radio-1">1</label>
56+
</div>
57+
58+
<div class="test-cell test-cell--light test-cell--radio">
59+
<div class="mdc-radio mdc-radio--touch">
60+
<input class="mdc-radio__native-control" type="radio" name="enabled-radio-group" checked
61+
id="test-radio-2">
62+
<div class="mdc-radio__background">
63+
<div class="mdc-radio__outer-circle"></div>
64+
<div class="mdc-radio__inner-circle"></div>
65+
</div>
66+
<div class="mdc-radio__ripple"></div>
67+
</div>
68+
<label class="test-radio-label" for="test-radio-2">2</label>
69+
</div>
70+
71+
<div class="test-cell test-cell--light test-cell--radio">
72+
<div class="mdc-radio mdc-radio--touch mdc-radio--disabled">
73+
<input class="mdc-radio__native-control" type="radio" name="disabled-radio-group" disabled
74+
id="test-radio-3">
75+
<div class="mdc-radio__background">
76+
<div class="mdc-radio__outer-circle"></div>
77+
<div class="mdc-radio__inner-circle"></div>
78+
</div>
79+
<div class="mdc-radio__ripple"></div>
80+
</div>
81+
<label class="test-radio-label" for="test-radio-3">3</label>
82+
</div>
83+
84+
<div class="test-cell test-cell--light test-cell--radio">
85+
<div class="mdc-radio mdc-radio--touch mdc-radio--disabled">
86+
<input class="mdc-radio__native-control" type="radio" name="disabled-radio-group" disabled checked
87+
id="test-radio-4">
88+
<div class="mdc-radio__background">
89+
<div class="mdc-radio__outer-circle"></div>
90+
<div class="mdc-radio__inner-circle"></div>
91+
</div>
92+
<div class="mdc-radio__ripple"></div>
93+
</div>
94+
<label class="test-radio-label" for="test-radio-4">4</label>
95+
</div>
96+
</div>
97+
</main>
98+
99+
<!-- Automatically provides/replaces `Promise` if missing or broken. -->
100+
<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.js"></script>
101+
<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.js"></script>
102+
<script src="https://cdnjs.cloudflare.com/ajax/libs/fontfaceobserver/2.0.13/fontfaceobserver.standalone.js"></script>
103+
<script src="../../../out/material-components-web.js"></script>
104+
<script src="../../../out/spec/fixture.js"></script>
105+
<script src="../../../out/spec/mdc-radio/fixture.js"></script>
106+
</body>
107+
</html>

test/screenshot/spec/mdc-radio/fixture.js

+8
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,13 @@
2222
*/
2323

2424
window.mdc.testFixture.fontsLoaded.then(() => {
25+
[].slice.call(document.querySelectorAll('.mdc-radio')).forEach((el) => {
26+
mdc.radio.MDCRadio.attachTo(el);
27+
const autoFocusEl = el.querySelector('input[data-autofocus]');
28+
if (autoFocusEl) {
29+
autoFocusEl.focus();
30+
}
31+
});
32+
2533
window.mdc.testFixture.notifyDomReady();
2634
});

0 commit comments

Comments
 (0)