Skip to content
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
5 changes: 5 additions & 0 deletions .changeset/chatty-beers-divide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@solid-design-system/docs': patch
---

Fixed `sd-radio-group` default story markup.
5 changes: 5 additions & 0 deletions .changeset/swift-snails-own.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@solid-design-system/components': patch
---

Improved `sd-radio-group` robustness when no radios are present, preventing errors and logging a helpful warning instead.
14 changes: 14 additions & 0 deletions packages/components/src/components/radio-group/radio-group.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,20 @@ describe('<sd-radio-group>', () => {
});
});

describe('when there are no radios', () => {
it('should warn but not throw error', async () => {
const radioGroup = await fixture<SdRadioGroup>(html` <sd-radio-group></sd-radio-group> `);
const warningLog = sinon.stub(console, 'warn');

radioGroup.focus();
await radioGroup.updateComplete;

expect(warningLog.calledOnceWith('No radios found in the radio group.')).to.be.true;

warningLog.restore();
});
});

describe('when resetting a form', () => {
it('should reset the element to its initial value', async () => {
const form = await fixture<HTMLFormElement>(html`
Expand Down
29 changes: 27 additions & 2 deletions packages/components/src/components/radio-group/radio-group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,22 @@ export default class SdRadioGroup extends SolidElement implements SolidFormContr
}

private getAllRadios() {
return [...this.querySelectorAll<SdRadio | SdRadioButton>('sd-radio, sd-radio-button')];
const radios = [...this.querySelectorAll<SdRadio | SdRadioButton>('sd-radio, sd-radio-button')];

if (radios.length === 0) {
console.warn('No radios found in the radio group.');
}

return radios;
}

private handleRadioClick(event: MouseEvent) {
const target = (event.target as HTMLElement).closest<SdRadio | SdRadioButton>('sd-radio, sd-radio-button')!;
const radios = this.getAllRadios();
const oldValue = this.value;
const radios = this.getAllRadios();
if (radios.length === 0) {
return;
}

if (target.disabled) {
return;
Expand All @@ -168,6 +177,10 @@ export default class SdRadioGroup extends SolidElement implements SolidFormContr
}

const radios = this.getAllRadios().filter(radio => !radio.disabled);
if (radios.length === 0) {
return;
}

const checkedRadio = radios.find(radio => radio.checked) ?? radios[0];
const incr = event.key === ' ' ? 0 : ['ArrowUp', 'ArrowLeft'].includes(event.key) ? -1 : 1;
const oldValue = this.value;
Expand Down Expand Up @@ -210,6 +223,10 @@ export default class SdRadioGroup extends SolidElement implements SolidFormContr
/** Move focus to the checked radio (or the first one if none are checked) */
focus() {
const radios = this.getAllRadios();
if (radios.length === 0) {
return;
}

const checked = radios.find(radio => radio.checked);
const radioToFocus = checked || radios[0];

Expand All @@ -226,6 +243,10 @@ export default class SdRadioGroup extends SolidElement implements SolidFormContr

private async syncRadioElements() {
const radios = this.getAllRadios();
if (radios.length === 0) {
this.hasButtonGroup = false;
return;
}

await Promise.all(
// Sync the checked state and size
Expand Down Expand Up @@ -286,6 +307,10 @@ export default class SdRadioGroup extends SolidElement implements SolidFormContr

private updateCheckedRadio() {
const radios = this.getAllRadios();
if (radios.length === 0) {
return;
}

radios.forEach(radio => (radio.checked = radio.value === this.value));
this.formControlController.setValidity(this.validity.valid);
}
Expand Down
12 changes: 6 additions & 6 deletions packages/docs/src/stories/components/radio-group.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ export default {
{
type: 'slot',
name: 'default',
value: `<sd-radio-group name="large-radio-group" size="lg" value="1" label="Group label">
<sd-radio value="1">Radio 1</sd-radio>
<sd-radio value="2">Radio 2</sd-radio>
<sd-radio value="3">Radio 3</sd-radio>
</sd-radio-group>`
value: `<sd-radio value="1">Radio 1</sd-radio>
<sd-radio value="2">Radio 2</sd-radio>
<sd-radio value="3">Radio 3</sd-radio>`
},
{ type: 'attribute', name: 'name', value: 'radio-group' },
{ type: 'attribute', name: 'value', value: '1' }
{ type: 'attribute', name: 'value', value: '1' },
{ type: 'attribute', name: 'label', value: 'Group label' },
{ type: 'attribute', name: 'size', value: 'lg' }
]),
argTypes
};
Expand Down
Loading