Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: set has-value attribute on radio-button click #2862

Merged
merged 4 commits into from
Oct 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions packages/radio-group/src/vaadin-radio-group.js
Original file line number Diff line number Diff line change
Expand Up @@ -357,10 +357,6 @@ class RadioGroup extends FieldMixin(FocusMixin(DisabledMixin(KeyboardMixin(DirMi
return;
}

if (this.__selectedRadioButton && this.__selectedRadioButton.value === newValue) {
Copy link
Contributor Author

@vursen vursen Oct 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The check above doesn't make much sense and it is exactly what causes the regression:

1. Consideration

When the user selects a radio-button, the __valueObserver callback is invoked before the previously selected radio-button gets unchecked:

__selectRadioButton(radioButton) {
if (radioButton) {
this.value = radioButton.value;
} else {
this.value = '';
}
this.__radioButtons.forEach((button) => {
button.checked = button === radioButton;
});

...so it might happen that the __selectedRadioButton getter returns the previously selected radio-button instead of a new one that results in the has-value attribute inconsistency.

2. Consideration

However, even if the __valueObserver were invoked after the previously selected radio-button was unchecked, the check above wouldn't be correct: the has-value attribute would be set only when changing the value attribute but not when selecting a radio-button. Note, __selectedRadioButton would be always equal to the most recently selected radio-button = that has been just selected.

return;
}

const newSelectedRadioButton = this.__radioButtons.find((radioButton) => {
return radioButton.value === newValue;
});
Expand Down
42 changes: 31 additions & 11 deletions packages/radio-group/test/radio-group.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -267,17 +267,6 @@ describe('radio-group', () => {
expect(buttons[1].checked).to.be.false;
});

it('should not have has-value attribute by default', () => {
expect(group.hasAttribute('has-value')).to.be.false;
});

it('should toggle has-value attribute on value change', () => {
group.value = '2';
expect(group.hasAttribute('has-value')).to.be.true;
group.value = '';
expect(group.hasAttribute('has-value')).to.be.false;
});

it('should dispatch value-changed event when value changes', () => {
const spy = sinon.spy();
group.addEventListener('value-changed', spy);
Expand All @@ -302,6 +291,37 @@ describe('radio-group', () => {
});
});

describe('has-value attribute', () => {
beforeEach(async () => {
group = fixtureSync(`
<vaadin-radio-group>
<vaadin-radio-button value="1" label="Button 1"></vaadin-radio-button>
<vaadin-radio-button value="2" label="Button 2"></vaadin-radio-button>
</vaadin-radio-group>
`);
await nextFrame();
buttons = [...group.querySelectorAll('vaadin-radio-button')];
});

it('should not have has-value attribute by default', () => {
expect(group.hasAttribute('has-value')).to.be.false;
});

it('should set has-value on radio button click', () => {
buttons[0].click();
expect(group.hasAttribute('has-value')).to.be.true;
buttons[1].click();
expect(group.hasAttribute('has-value')).to.be.true;
});

it('should toggle has-value attribute on value change', () => {
group.value = '2';
expect(group.hasAttribute('has-value')).to.be.true;
group.value = '';
expect(group.hasAttribute('has-value')).to.be.false;
});
});

describe('change event', () => {
let spy;

Expand Down