From d8bc62a28995a35727ace9be1e7a91a7d583d163 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Se=CC=81rgio=20Fonseca?= Date: Tue, 3 Mar 2026 12:59:22 +0000 Subject: [PATCH 1/5] fix: handle empty radio group and throw warning --- .../src/components/radio-group/radio-group.ts | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/packages/components/src/components/radio-group/radio-group.ts b/packages/components/src/components/radio-group/radio-group.ts index 84b289b3eb..86ae5ba862 100644 --- a/packages/components/src/components/radio-group/radio-group.ts +++ b/packages/components/src/components/radio-group/radio-group.ts @@ -141,13 +141,22 @@ export default class SdRadioGroup extends SolidElement implements SolidFormContr } private getAllRadios() { - return [...this.querySelectorAll('sd-radio, sd-radio-button')]; + const radios = [...this.querySelectorAll('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('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; @@ -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; @@ -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]; @@ -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 @@ -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); } From 122e9630a1ee9dffce10de3b98e9c22a32b11cd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Se=CC=81rgio=20Fonseca?= Date: Tue, 3 Mar 2026 13:01:22 +0000 Subject: [PATCH 2/5] test: add empty group test --- .../src/components/radio-group/radio-group.test.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/components/src/components/radio-group/radio-group.test.ts b/packages/components/src/components/radio-group/radio-group.test.ts index e9aa5e8fb5..db19570b76 100644 --- a/packages/components/src/components/radio-group/radio-group.test.ts +++ b/packages/components/src/components/radio-group/radio-group.test.ts @@ -239,6 +239,20 @@ describe('', () => { }); }); +describe('when there are no radios', () => { + it('should warn but not throw error', async () => { + const radioGroup = await fixture(html` `); + 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(html` From 8290538bcba5bd88e736df04479581721fb892b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Se=CC=81rgio=20Fonseca?= Date: Tue, 3 Mar 2026 13:02:24 +0000 Subject: [PATCH 3/5] fix: default story incorrect markup --- .../docs/src/stories/components/radio-group.stories.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/docs/src/stories/components/radio-group.stories.ts b/packages/docs/src/stories/components/radio-group.stories.ts index b66a78fa7a..fb70755d8a 100644 --- a/packages/docs/src/stories/components/radio-group.stories.ts +++ b/packages/docs/src/stories/components/radio-group.stories.ts @@ -21,11 +21,9 @@ export default { { type: 'slot', name: 'default', - value: ` - Radio 1 - Radio 2 - Radio 3 - ` + value: `Radio 1 + Radio 2 + Radio 3` }, { type: 'attribute', name: 'name', value: 'radio-group' }, { type: 'attribute', name: 'value', value: '1' } From 41a2320f6534d0dc04a17ac7195f4a4e0e0fe59a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Se=CC=81rgio=20Fonseca?= Date: Tue, 3 Mar 2026 13:03:08 +0000 Subject: [PATCH 4/5] chore: add changesets --- .changeset/chatty-beers-divide.md | 5 +++++ .changeset/swift-snails-own.md | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 .changeset/chatty-beers-divide.md create mode 100644 .changeset/swift-snails-own.md diff --git a/.changeset/chatty-beers-divide.md b/.changeset/chatty-beers-divide.md new file mode 100644 index 0000000000..0284a8fc4b --- /dev/null +++ b/.changeset/chatty-beers-divide.md @@ -0,0 +1,5 @@ +--- +'@solid-design-system/docs': patch +--- + +Fixed `sd-radio-group` default story markup. diff --git a/.changeset/swift-snails-own.md b/.changeset/swift-snails-own.md new file mode 100644 index 0000000000..205b6eacd0 --- /dev/null +++ b/.changeset/swift-snails-own.md @@ -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. From 979bcaa34b0910c7633d8584b69d4302df320ef4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Se=CC=81rgio=20Fonseca?= Date: Tue, 3 Mar 2026 17:04:25 +0000 Subject: [PATCH 5/5] chore: add missing attributes --- .../docs/src/stories/components/radio-group.stories.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/docs/src/stories/components/radio-group.stories.ts b/packages/docs/src/stories/components/radio-group.stories.ts index fb70755d8a..a4c5a33fb8 100644 --- a/packages/docs/src/stories/components/radio-group.stories.ts +++ b/packages/docs/src/stories/components/radio-group.stories.ts @@ -22,11 +22,13 @@ export default { type: 'slot', name: 'default', value: `Radio 1 - Radio 2 - Radio 3` + Radio 2 + Radio 3` }, { 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 };