diff --git a/packages/main/cypress/specs/Switch.cy.tsx b/packages/main/cypress/specs/Switch.cy.tsx index c443fb451ab1..32e496679978 100644 --- a/packages/main/cypress/specs/Switch.cy.tsx +++ b/packages/main/cypress/specs/Switch.cy.tsx @@ -38,6 +38,66 @@ describe("General events interactions", () => { cy.get("@switch") .should("not.have.attr", "checked"); }); + + it("Should toggle checked state when SPACE is pressed", () => { + cy.mount(Click me); + + cy.get("[ui5-switch]") + .as("switch"); + + cy.get("@switch") + .shadow() + .find(".ui5-switch-root") + .focus() + .should("be.focused") + .realPress("Space"); + + cy.get("@changed") + .should("have.been.calledOnce"); + + cy.get("@switch") + .should("have.attr", "checked"); + }); + + it("Should not toggle checked state on SPACE + Shift are pressed", () => { + cy.mount(Click me); + + cy.get("[ui5-switch]") + .as("switch"); + + cy.get("@switch") + .shadow() + .find(".ui5-switch-root") + .focus() + .should("be.focused") + .realPress(["Space", "Shift"]); + + cy.get("@changed") + .should("not.have.been.called"); + + cy.get("@switch") + .should("not.have.attr", "checked"); + }); + + it("Should not toggle checked state on SPACE + Escape are pressed", () => { + cy.mount(Click me); + + cy.get("[ui5-switch]") + .as("switch"); + + cy.get("@switch") + .shadow() + .find(".ui5-switch-root") + .focus() + .should("be.focused") + .realPress(["Space", "Escape"]); + + cy.get("@changed") + .should("not.have.been.called"); + + cy.get("@switch") + .should("not.have.attr", "checked"); + }); }); describe("General accesibility attributes", () => { @@ -165,4 +225,5 @@ describe("General interactions in form", () => { cy.get("#requiredTestSwitch:invalid").should("not.exist", "Checked required Switch should not have :invalid CSS class"); }); -}); \ No newline at end of file + +}); diff --git a/packages/main/src/Switch.ts b/packages/main/src/Switch.ts index fdd5f1a75c20..cf444137aea5 100644 --- a/packages/main/src/Switch.ts +++ b/packages/main/src/Switch.ts @@ -4,7 +4,9 @@ import property from "@ui5/webcomponents-base/dist/decorators/property.js"; import event from "@ui5/webcomponents-base/dist/decorators/event-strict.js"; import jsxRenderer from "@ui5/webcomponents-base/dist/renderer/JsxRenderer.js"; import type { IFormInputElement } from "@ui5/webcomponents-base/dist/features/InputElementsFormSupport.js"; -import { isSpace, isEnter } from "@ui5/webcomponents-base/dist/Keys.js"; +import { + isSpace, isEnter, isShift, isEscape, +} from "@ui5/webcomponents-base/dist/Keys.js"; import i18n from "@ui5/webcomponents-base/dist/decorators/i18n.js"; import type I18nBundle from "@ui5/webcomponents-base/dist/i18nBundle.js"; import { getEffectiveAriaLabelText } from "@ui5/webcomponents-base/dist/util/AccessibilityTextsHelper.js"; @@ -77,6 +79,7 @@ class Switch extends UI5Element implements IFormInputElement { change: void "value-changed": void } + /** * Defines the component design. * @@ -195,6 +198,9 @@ class Switch extends UI5Element implements IFormInputElement { @property() value = ""; + @property({ type: Boolean, noAttribute: true }) + _cancelAction = false; + @i18n("@ui5/webcomponents") static i18nBundle: I18nBundle; @@ -227,6 +233,7 @@ class Switch extends UI5Element implements IFormInputElement { } _onkeydown(e: KeyboardEvent) { + this._cancelAction = isShift(e) || isEscape(e); if (isSpace(e)) { e.preventDefault(); } @@ -237,7 +244,7 @@ class Switch extends UI5Element implements IFormInputElement { } _onkeyup(e: KeyboardEvent) { - if (isSpace(e)) { + if (isSpace(e) && !this._cancelAction) { this._onclick(); } }