Skip to content

Commit a060abc

Browse files
committed
refactor(radio-button): remove MDC dependency
1 parent e868bf7 commit a060abc

File tree

4 files changed

+72
-38
lines changed

4 files changed

+72
-38
lines changed

src/components/checkbox/checkbox.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@
3939

4040
.box {
4141
&:after {
42+
height: 0.125rem;
43+
width: 0.25rem;
44+
4245
.indeterminate & {
4346
opacity: 1;
4447
width: calc(var(--limel-boolean-input-box-size) - 0.5rem);
@@ -47,6 +50,8 @@
4750
}
4851

4952
.checkbox {
53+
--limel-boolean-input-box-border-radius: 0.25rem;
54+
5055
svg.check-mark {
5156
position: absolute;
5257
z-index: 1;
Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,48 @@
1-
@use '@material/radio';
2-
@use '@material/radio/styles';
3-
@use '@material/form-field';
1+
/**
2+
* :::important
3+
* The `RadioButtonTemplate` can be imported and used in the HTML of
4+
* other components, to render a non-functional and decorative radio button in
5+
* their UI. An example of this is the list component.
6+
* This means the content of `RadioButtonTemplate` will become a part of the
7+
* consumer's DOM structure.
8+
*
9+
* Additionally, the consumer components' also need to import the current `.scss`
10+
* file into their own styles file, for the radio button to be rendered correctly!
11+
* This means, if the styles in this file are not "specific" enough,
12+
* there is a risk that the consumer component's styles are affected by
13+
* our styles here.
14+
*
15+
* For instance if the consumer has a `<label>`,
16+
* it might unintentionally inherit styles from the radio button; unless we
17+
* make the such styles more specific here.
18+
*
19+
* Naturally, we cannot mitigate all sorts of potential styling problems.
20+
* The consumer component should be aware of this issue too.
21+
* But we can ensure that our styles here both make sense,
22+
* are readable, and are as specific as possible to avoid unintended side effects.
23+
* :::
24+
*/
425

5-
@include form-field.core-styles;
26+
@use '../../style/mixins';
627

7-
.mdc-form-field {
8-
display: flex;
28+
@forward '../../style/internal/boolean-input.scss';
929

10-
.mdc-radio {
11-
@include radio.ink-color(primary);
12-
}
30+
.radio-button {
31+
--limel-boolean-input-box-border-radius: var(
32+
--limel-boolean-input-box-size
33+
);
1334
}
1435

15-
.mdc-radio {
16-
.mdc-radio__native-control:enabled:not(:checked)
17-
+ .mdc-radio__background
18-
.mdc-radio__outer-circle {
19-
border-color: var(--mdc-checkbox-unchecked-color);
36+
.box {
37+
&:after {
38+
width: 100%;
39+
height: 100%;
40+
border-radius: 50%;
41+
42+
.boolean-input:has(input[type='radio']:checked) & {
43+
opacity: 1;
44+
transform: scale(0.6);
45+
box-shadow: var(--shadow-depth-8);
46+
}
2047
}
2148
}

src/components/list/radio-button/radio-button.template.tsx

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,30 +14,25 @@ export const RadioButtonTemplate: FunctionalComponent<
1414
return (
1515
<div class="mdc-form-field">
1616
<div
17-
class={`
18-
mdc-radio
19-
${props.disabled ? 'mdc-radio--disabled' : ''}
20-
`}
17+
class={{
18+
'boolean-input': true,
19+
'radio-button': true,
20+
checked: props.checked,
21+
disabled: props.disabled,
22+
}}
2123
>
2224
<input
23-
class="mdc-radio__native-control"
2425
type="radio"
2526
id={props.id}
2627
checked={props.checked}
2728
disabled={props.disabled}
2829
onChange={props.onChange}
2930
/>
30-
<div class="mdc-radio__background">
31-
<div class="mdc-radio__outer-circle" />
32-
<div class="mdc-radio__inner-circle" />
33-
</div>
31+
<div class="box" />
32+
<label class="boolean-input-label" htmlFor={props.id}>
33+
{props.label}
34+
</label>
3435
</div>
35-
<label
36-
class={`${props.disabled ? 'disabled' : ''}`}
37-
htmlFor={props.id}
38-
>
39-
{props.label}
40-
</label>
4136
</div>
4237
);
4338
};

src/style/internal/boolean-input.scss

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
); // helps align with other fields in the form, or within table rows
2222
width: 100%;
2323

24-
input[type='checkbox'] {
24+
input[type='checkbox'],
25+
input[type='radio'] {
2526
// Hide the native checkbox
2627
@include mixins.visually-hidden;
2728
-webkit-appearance: none;
@@ -97,7 +98,7 @@ label.boolean-input-label {
9798
height: var(--limel-boolean-input-box-size);
9899

99100
margin-right: var(--limel-boolean-input-gap-size);
100-
border-radius: 0.25rem;
101+
border-radius: var(--limel-boolean-input-box-border-radius);
101102
border: 0.125rem solid;
102103

103104
border-color: var(
@@ -110,7 +111,8 @@ label.boolean-input-label {
110111
);
111112

112113
.checked &,
113-
.boolean-input:has(input[type='checkbox']:checked) & {
114+
.boolean-input:has(input[type='checkbox']:checked) &,
115+
.boolean-input:has(input[type='radio']:checked) & {
114116
background-color: var(
115117
--lime-primary-color,
116118
var(--limel-theme-primary-color)
@@ -143,29 +145,34 @@ label.boolean-input-label {
143145
inset: -0.1875rem; // 3px
144146
border-radius: inherit;
145147

146-
.boolean-input:has(input[type='checkbox']:focus-visible) & {
148+
.boolean-input:has(input[type='checkbox']:focus-visible) &,
149+
.boolean-input:has(input[type='radio']:focus-visible) & {
147150
will-change: box-shadow;
148151

149152
box-shadow: var(--shadow-depth-8-focused);
150153
}
151154
}
152155

153156
&:after {
154-
// For indicating the indeterminate state
157+
// For indicating the indeterminate state in checkbox
158+
// For indicating the the checked state in radio
155159
transition:
156160
opacity 0.2s ease,
157-
width 0.4s ease;
161+
width 0.4s ease,
162+
box-shadow 0.6s cubic-bezier(0.68, -0.55, 0, 1.87),
163+
transform 0.6s cubic-bezier(0.68, -0.55, 0, 1.87);
158164
content: '';
159165
position: absolute;
160166
inset: 0;
161167
margin: auto;
162168

163-
height: 0.125rem;
164-
width: 0.25rem;
165-
166169
border-radius: 1rem;
167170
opacity: 0;
168171

169172
background-color: rgb(var(--color-white));
173+
174+
.boolean-input:not(.disabled):has(label.boolean-input-label:hover) & {
175+
will-change: opacity, box-shadow, transform, width;
176+
}
170177
}
171178
}

0 commit comments

Comments
 (0)