diff --git a/src/components/radio-button/radio-button/radio-button.e2e.ts b/src/components/radio-button/radio-button/radio-button.e2e.ts
index ed85e79385..6a7e47b9e6 100644
--- a/src/components/radio-button/radio-button/radio-button.e2e.ts
+++ b/src/components/radio-button/radio-button/radio-button.e2e.ts
@@ -9,72 +9,186 @@ import { SbbRadioButtonElement } from './radio-button.js';
describe(`sbb-radio-button`, () => {
let element: SbbRadioButtonElement;
- beforeEach(async () => {
- element = await fixture(html`Value label`);
- });
+ describe('general', () => {
+ beforeEach(async () => {
+ element = await fixture(html`Value label`);
+ });
+
+ it('renders', async () => {
+ assert.instanceOf(element, SbbRadioButtonElement);
+ });
+
+ it('should have corresponding aria values set', async () => {
+ expect(element).to.have.attribute('aria-checked', 'false');
+ expect(element).to.have.attribute('aria-required', 'false');
+ expect(element).not.to.have.attribute('aria-disabled');
+ });
+
+ it('should update aria values', async () => {
+ element.checked = true;
+ element.required = true;
+ element.disabled = true;
+
+ await waitForLitRender(element);
- it('renders', async () => {
- assert.instanceOf(element, SbbRadioButtonElement);
- });
+ expect(element).to.have.attribute('aria-checked', 'true');
+ expect(element).to.have.attribute('aria-required', 'true');
+ expect(element).to.have.attribute('aria-disabled', 'true');
+ });
- it('should not render accessibility label about containing state', async () => {
- element = element.shadowRoot!.querySelector('.sbb-screen-reader-only:not(input)')!;
- expect(element).not.to.be.ok;
- });
+ it('should not render accessibility label about containing state', async () => {
+ element = element.shadowRoot!.querySelector('.sbb-screen-reader-only:not(input)')!;
+ expect(element).not.to.be.ok;
+ });
- it('selects radio on click', async () => {
- const stateChange = new EventSpy(SbbRadioButtonElement.events.stateChange);
+ it('selects radio on click', async () => {
+ const stateChange = new EventSpy(SbbRadioButtonElement.events.stateChange);
- element.click();
- await waitForLitRender(element);
+ element.click();
+ await waitForLitRender(element);
- expect(element).to.have.attribute('checked');
- await waitForCondition(() => stateChange.events.length === 1);
- expect(stateChange.count).to.be.equal(1);
- });
+ expect(element).to.have.attribute('checked');
+ await waitForCondition(() => stateChange.events.length === 1);
+ expect(stateChange.count).to.be.equal(1);
+ });
- it('does not deselect radio if already checked', async () => {
- const stateChange = new EventSpy(SbbRadioButtonElement.events.stateChange);
+ it('does not deselect radio if already checked', async () => {
+ const stateChange = new EventSpy(SbbRadioButtonElement.events.stateChange);
- element.click();
- await waitForLitRender(element);
- expect(element).to.have.attribute('checked');
- await waitForCondition(() => stateChange.events.length === 1);
- expect(stateChange.count).to.be.equal(1);
+ element.click();
+ await waitForLitRender(element);
+ expect(element).to.have.attribute('checked');
+ await waitForCondition(() => stateChange.events.length === 1);
+ expect(stateChange.count).to.be.equal(1);
- element.click();
- await waitForLitRender(element);
- expect(element).to.have.attribute('checked');
- await waitForCondition(() => stateChange.events.length === 1);
- expect(stateChange.count).to.be.equal(1);
- });
+ element.click();
+ await waitForLitRender(element);
+ expect(element).to.have.attribute('checked');
+ await waitForCondition(() => stateChange.events.length === 1);
+ expect(stateChange.count).to.be.equal(1);
+ });
- it('allows empty selection', async () => {
- const stateChange = new EventSpy(SbbRadioButtonElement.events.stateChange);
-
- element.allowEmptySelection = true;
- element.click();
- await waitForLitRender(element);
- expect(element).to.have.attribute('checked');
- await waitForCondition(() => stateChange.events.length === 1);
- expect(stateChange.count).to.be.equal(1);
-
- element.click();
- await waitForLitRender(element);
- expect(element).not.to.have.attribute('checked');
- await waitForCondition(() => stateChange.events.length === 2);
- expect(stateChange.count).to.be.equal(2);
- });
+ it('allows empty selection', async () => {
+ const stateChange = new EventSpy(SbbRadioButtonElement.events.stateChange);
+
+ element.allowEmptySelection = true;
+ element.click();
+ await waitForLitRender(element);
+ expect(element).to.have.attribute('checked');
+ await waitForCondition(() => stateChange.events.length === 1);
+ expect(stateChange.count).to.be.equal(1);
+
+ element.click();
+ await waitForLitRender(element);
+ expect(element).not.to.have.attribute('checked');
+ await waitForCondition(() => stateChange.events.length === 2);
+ expect(stateChange.count).to.be.equal(2);
+ });
+
+ it('should convert falsy checked to false', async () => {
+ element.checked = true;
+ (element.checked as any) = undefined;
+
+ await waitForLitRender(element);
+
+ expect(element.checked).to.equal(false);
+ expect(element).to.have.attribute('aria-checked', 'false');
+ });
+
+ it('should convert truthy checked to true', async () => {
+ element.checked = true;
+ (element.checked as any) = 2;
+
+ await waitForLitRender(element);
+
+ expect(element.checked).to.equal(true);
+ expect(element).to.have.attribute('aria-checked', 'true');
+ });
+
+ it('should convert falsy disabled to false', async () => {
+ element.disabled = true;
+ (element.disabled as any) = undefined;
+
+ await waitForLitRender(element);
+
+ expect(element.disabled).to.equal(false);
+ expect(element).not.to.have.attribute('aria-disabled');
+ });
+
+ it('should convert truthy disabled to true', async () => {
+ element.disabled = true;
+ (element.disabled as any) = 2;
+
+ await waitForLitRender(element);
+
+ expect(element.disabled).to.equal(true);
+ expect(element).to.have.attribute('aria-disabled', 'true');
+ });
+
+ it('should convert falsy required to false', async () => {
+ element.required = true;
+ (element.required as any) = undefined;
+
+ await waitForLitRender(element);
+
+ expect(element.required).to.equal(false);
+ expect(element).to.have.attribute('aria-required', 'false');
+ });
+
+ it('should convert truthy required to true', async () => {
+ element.required = true;
+ (element.required as any) = 2;
+
+ await waitForLitRender(element);
+
+ expect(element.required).to.equal(true);
+ expect(element).to.have.attribute('aria-required', 'true');
+ });
+
+ it('should convert falsy allowEmptySelection to false', async () => {
+ element.allowEmptySelection = true;
+ (element.allowEmptySelection as any) = undefined;
+
+ await waitForLitRender(element);
+
+ expect(element.allowEmptySelection).to.equal(false);
+ });
+
+ it('should convert truthy allowEmptySelection to true', async () => {
+ element.allowEmptySelection = true;
+ (element.allowEmptySelection as any) = 2;
+
+ await waitForLitRender(element);
- it('should convert falsy checked to false', async () => {
- element.checked = true;
- (element.checked as any) = undefined;
- expect(element.checked).to.equal(false);
+ expect(element.allowEmptySelection).to.equal(true);
+ });
});
- it('should convert truthy checked to true', async () => {
- element.checked = true;
- (element.checked as any) = 2;
- expect(element.checked).to.equal(true);
+ describe('with initial attributes', () => {
+ beforeEach(async () => {
+ element = await fixture(
+ html`
+ Value label
+ `,
+ );
+ });
+
+ it('should have corresponding aria values set', async () => {
+ expect(element).to.have.attribute('aria-checked', 'true');
+ expect(element).to.have.attribute('aria-required', 'true');
+ expect(element).to.have.attribute('aria-disabled', 'true');
+ });
+
+ it('should update aria values', async () => {
+ element.checked = false;
+ element.required = false;
+ element.disabled = false;
+
+ await waitForLitRender(element);
+
+ expect(element).to.have.attribute('aria-checked', 'false');
+ expect(element).to.have.attribute('aria-required', 'false');
+ expect(element).not.to.have.attribute('aria-disabled');
+ });
});
});
diff --git a/src/components/radio-button/radio-button/radio-button.ts b/src/components/radio-button/radio-button/radio-button.ts
index 5636d200c0..77b91b739a 100644
--- a/src/components/radio-button/radio-button/radio-button.ts
+++ b/src/components/radio-button/radio-button/radio-button.ts
@@ -52,7 +52,7 @@ export class SbbRadioButtonElement extends SbbUpdateSchedulerMixin(LitElement) {
*/
@property({ attribute: 'allow-empty-selection', type: Boolean })
public set allowEmptySelection(value: boolean) {
- this._allowEmptySelection = value;
+ this._allowEmptySelection = Boolean(value);
}
public get allowEmptySelection(): boolean {
return this._allowEmptySelection || (this.group?.allowEmptySelection ?? false);
@@ -69,7 +69,7 @@ export class SbbRadioButtonElement extends SbbUpdateSchedulerMixin(LitElement) {
*/
@property({ reflect: true, type: Boolean })
public set disabled(value: boolean) {
- this._disabled = value;
+ this._disabled = Boolean(value);
}
public get disabled(): boolean {
return this._disabled || (this.group?.disabled ?? false);
@@ -81,7 +81,7 @@ export class SbbRadioButtonElement extends SbbUpdateSchedulerMixin(LitElement) {
*/
@property({ reflect: true, type: Boolean })
public set required(value: boolean) {
- this._required = value;
+ this._required = Boolean(value);
}
public get required(): boolean {
return this._required || (this.group?.required ?? false);
@@ -158,22 +158,6 @@ export class SbbRadioButtonElement extends SbbUpdateSchedulerMixin(LitElement) {
SbbRadioButtonElement.events.radioButtonLoaded,
{ bubbles: true },
);
-
- private _handleCheckedChange(currentValue: boolean, previousValue: boolean): void {
- if (currentValue !== previousValue) {
- this.setAttribute('aria-checked', `${currentValue}`);
- this._stateChange.emit({ type: 'checked', checked: currentValue });
- this.isSelectionPanelInput && this._updateExpandedLabel();
- }
- }
-
- private _handleDisabledChange(currentValue: boolean, previousValue: boolean): void {
- if (currentValue !== previousValue) {
- setOrRemoveAttribute(this, 'aria-disabled', currentValue ? 'true' : null);
- this._stateChange.emit({ type: 'disabled', disabled: currentValue });
- }
- }
-
private _handleClick(event: Event): void {
event.preventDefault();
this.select();
@@ -221,10 +205,17 @@ export class SbbRadioButtonElement extends SbbUpdateSchedulerMixin(LitElement) {
super.willUpdate(changedProperties);
if (changedProperties.has('checked')) {
- this._handleCheckedChange(this.checked, changedProperties.get('checked')!);
+ this.setAttribute('aria-checked', `${this.checked}`);
+ if (this.checked !== changedProperties.get('checked')!) {
+ this._stateChange.emit({ type: 'checked', checked: this.checked });
+ this.isSelectionPanelInput && this._updateExpandedLabel();
+ }
}
if (changedProperties.has('disabled')) {
- this._handleDisabledChange(this.disabled, changedProperties.get('disabled')!);
+ setOrRemoveAttribute(this, 'aria-disabled', this.disabled ? 'true' : null);
+ if (this.disabled !== changedProperties.get('disabled')!) {
+ this._stateChange.emit({ type: 'disabled', disabled: this.disabled });
+ }
}
if (changedProperties.has('required')) {
this.setAttribute('aria-required', `${this.required}`);