Skip to content

Commit a62b09c

Browse files
authoredApr 1, 2025
fix: ensure input in checkbox and radio-button has opacity: 0 (#8882)
1 parent 2dc0597 commit a62b09c

8 files changed

+84
-4
lines changed
 

‎packages/checkbox/src/vaadin-checkbox-mixin.d.ts

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type { FocusMixinClass } from '@vaadin/a11y-base/src/focus-mixin.js';
1111
import type { KeyboardMixinClass } from '@vaadin/a11y-base/src/keyboard-mixin.js';
1212
import type { ControllerMixinClass } from '@vaadin/component-base/src/controller-mixin.js';
1313
import type { DelegateStateMixinClass } from '@vaadin/component-base/src/delegate-state-mixin.js';
14+
import type { SlotStylesMixinClass } from '@vaadin/component-base/src/slot-styles-mixin.js';
1415
import type { CheckedMixinClass } from '@vaadin/field-base/src/checked-mixin.js';
1516
import type { FieldMixinClass } from '@vaadin/field-base/src/field-mixin.js';
1617
import type { InputMixinClass } from '@vaadin/field-base/src/input-mixin.js';
@@ -34,6 +35,7 @@ export declare function CheckboxMixin<T extends Constructor<HTMLElement>>(
3435
Constructor<InputMixinClass> &
3536
Constructor<KeyboardMixinClass> &
3637
Constructor<LabelMixinClass> &
38+
Constructor<SlotStylesMixinClass> &
3739
Constructor<ValidateMixinClass> &
3840
T;
3941

‎packages/checkbox/src/vaadin-checkbox-mixin.js

+20-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
import { ActiveMixin } from '@vaadin/a11y-base/src/active-mixin.js';
77
import { DelegateFocusMixin } from '@vaadin/a11y-base/src/delegate-focus-mixin.js';
8+
import { SlotStylesMixin } from '@vaadin/component-base/src/slot-styles-mixin.js';
89
import { CheckedMixin } from '@vaadin/field-base/src/checked-mixin.js';
910
import { FieldMixin } from '@vaadin/field-base/src/field-mixin.js';
1011
import { InputController } from '@vaadin/field-base/src/input-controller.js';
@@ -18,9 +19,12 @@ import { LabelledInputController } from '@vaadin/field-base/src/labelled-input-c
1819
* @mixes CheckedMixin
1920
* @mixes DelegateFocusMixin
2021
* @mixes FieldMixin
22+
* @mixes SlotStylesMixin
2123
*/
2224
export const CheckboxMixin = (superclass) =>
23-
class CheckboxMixinClass extends FieldMixin(CheckedMixin(DelegateFocusMixin(ActiveMixin(superclass)))) {
25+
class CheckboxMixinClass extends SlotStylesMixin(
26+
FieldMixin(CheckedMixin(DelegateFocusMixin(ActiveMixin(superclass)))),
27+
) {
2428
static get properties() {
2529
return {
2630
/**
@@ -93,6 +97,21 @@ export const CheckboxMixin = (superclass) =>
9397
this.tabindex = 0;
9498
}
9599

100+
/** @protected */
101+
get slotStyles() {
102+
const tag = this.localName;
103+
104+
// Needed to override `opacity: 1` set on `input` by Tailwind CSS.
105+
// See https://github.com/vaadin/web-components/issues/8881
106+
return [
107+
`
108+
${tag} > input[slot='input'] {
109+
opacity: 0;
110+
}
111+
`,
112+
];
113+
}
114+
96115
/** @protected */
97116
ready() {
98117
super.ready();

‎packages/checkbox/src/vaadin-checkbox-styles.js

-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ export const checkboxStyles = css`
6262
6363
/* visually hidden */
6464
::slotted(input) {
65-
opacity: 0;
6665
cursor: inherit;
6766
margin: 0;
6867
align-self: stretch;

‎packages/checkbox/test/checkbox.test.js

+20
Original file line numberDiff line numberDiff line change
@@ -292,4 +292,24 @@ describe('checkbox', () => {
292292
expect(input.indeterminate).to.be.false;
293293
});
294294
});
295+
296+
describe('opacity', () => {
297+
beforeEach(async () => {
298+
checkbox = fixtureSync(`<vaadin-checkbox></vaadin-checkbox>`);
299+
await nextRender();
300+
input = checkbox.inputElement;
301+
});
302+
303+
it('should apply opacity: 0 on the slotted input', () => {
304+
// Emulate CSS normalize styles like used by Tailwind
305+
fixtureSync(`
306+
<style>
307+
input {
308+
opacity: 1;
309+
}
310+
</script>
311+
`);
312+
expect(getComputedStyle(input).opacity).to.equal('0');
313+
});
314+
});
295315
});

‎packages/radio-group/src/vaadin-radio-button-mixin.d.ts

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import type { DisabledMixinClass } from '@vaadin/a11y-base/src/disabled-mixin.js
1010
import type { FocusMixinClass } from '@vaadin/a11y-base/src/focus-mixin.js';
1111
import type { KeyboardMixinClass } from '@vaadin/a11y-base/src/keyboard-mixin.js';
1212
import type { DelegateStateMixinClass } from '@vaadin/component-base/src/delegate-state-mixin.js';
13+
import type { SlotStylesMixinClass } from '@vaadin/component-base/src/slot-styles-mixin.js';
1314
import type { CheckedMixinClass } from '@vaadin/field-base/src/checked-mixin.js';
1415
import type { InputMixinClass } from '@vaadin/field-base/src/input-mixin.js';
1516
import type { LabelMixinClass } from '@vaadin/field-base/src/label-mixin.js';
@@ -40,6 +41,7 @@ export declare function RadioButtonMixin<T extends Constructor<HTMLElement>>(
4041
Constructor<KeyboardMixinClass> &
4142
Constructor<LabelMixinClass> &
4243
Constructor<RadioButtonMixinClass> &
44+
Constructor<SlotStylesMixinClass> &
4345
T;
4446

4547
export declare class RadioButtonMixinClass {

‎packages/radio-group/src/vaadin-radio-button-mixin.js

+20-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
import { ActiveMixin } from '@vaadin/a11y-base/src/active-mixin.js';
77
import { DelegateFocusMixin } from '@vaadin/a11y-base/src/delegate-focus-mixin.js';
8+
import { SlotStylesMixin } from '@vaadin/component-base/src/slot-styles-mixin.js';
89
import { CheckedMixin } from '@vaadin/field-base/src/checked-mixin.js';
910
import { InputController } from '@vaadin/field-base/src/input-controller.js';
1011
import { LabelMixin } from '@vaadin/field-base/src/label-mixin.js';
@@ -18,9 +19,12 @@ import { LabelledInputController } from '@vaadin/field-base/src/labelled-input-c
1819
* @mixes CheckedMixin
1920
* @mixes DelegateFocusMixin
2021
* @mixes LabelMixin
22+
* @mixes SlotStylesMixin
2123
*/
2224
export const RadioButtonMixin = (superclass) =>
23-
class RadioButtonMixinClass extends LabelMixin(CheckedMixin(DelegateFocusMixin(ActiveMixin(superclass)))) {
25+
class RadioButtonMixinClass extends SlotStylesMixin(
26+
LabelMixin(CheckedMixin(DelegateFocusMixin(ActiveMixin(superclass)))),
27+
) {
2428
static get properties() {
2529
return {
2630
/**
@@ -54,6 +58,21 @@ export const RadioButtonMixin = (superclass) =>
5458
this.tabindex = 0;
5559
}
5660

61+
/** @protected */
62+
get slotStyles() {
63+
const tag = this.localName;
64+
65+
// Needed to override `opacity: 1` set on `input` by Tailwind CSS.
66+
// See https://github.com/vaadin/web-components/issues/8881
67+
return [
68+
`
69+
${tag} > input[slot='input'] {
70+
opacity: 0;
71+
}
72+
`,
73+
];
74+
}
75+
5776
/** @protected */
5877
ready() {
5978
super.ready();

‎packages/radio-group/src/vaadin-radio-button-styles.js

-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ export const radioButtonStyles = css`
5252
5353
/* visually hidden */
5454
::slotted(input) {
55-
opacity: 0;
5655
cursor: inherit;
5756
margin: 0;
5857
align-self: stretch;

‎packages/radio-group/test/radio-button.test.js

+20
Original file line numberDiff line numberDiff line change
@@ -272,4 +272,24 @@ describe('radio-button', () => {
272272
expect(spy).to.be.not.called;
273273
});
274274
});
275+
276+
describe('opacity', () => {
277+
beforeEach(async () => {
278+
radio = fixtureSync('<vaadin-radio-button></vaadin-radio-button>');
279+
await nextRender();
280+
input = radio.inputElement;
281+
});
282+
283+
it('should apply opacity: 0 on the slotted input', () => {
284+
// Emulate CSS normalize styles like used by Tailwind
285+
fixtureSync(`
286+
<style>
287+
input {
288+
opacity: 1;
289+
}
290+
</script>
291+
`);
292+
expect(getComputedStyle(input).opacity).to.equal('0');
293+
});
294+
});
275295
});

0 commit comments

Comments
 (0)