diff --git a/packages/main/cypress/specs/Input.cy.tsx b/packages/main/cypress/specs/Input.cy.tsx index 4081a16b5e9f..bf58ae6318fa 100644 --- a/packages/main/cypress/specs/Input.cy.tsx +++ b/packages/main/cypress/specs/Input.cy.tsx @@ -1284,6 +1284,13 @@ describe("Change event behavior when selecting the same suggestion item", () => }); describe("Accessibility", () => { + it("tests autofocus attribute", () => { + cy.mount(); + + cy.get("[ui5-input]") + .should("be.focused"); + }); + it("tests accessibleDescription property", () => { cy.mount(); diff --git a/packages/main/src/Input.ts b/packages/main/src/Input.ts index 08da1a4eaa1b..ec0c0f13297b 100644 --- a/packages/main/src/Input.ts +++ b/packages/main/src/Input.ts @@ -214,6 +214,7 @@ type InputSuggestionScrollEventDetail = { ValueStateMessageCss, SuggestionsCss, ], + shadowRootOptions: { delegatesFocus: true }, }) /** @@ -720,6 +721,9 @@ class Input extends UI5Element implements SuggestionComponent, IFormInputElement ResizeHandler.register(this, this._handleResizeBound); registerUI5Element(this, this._updateAssociatedLabelsTexts.bind(this)); this._enableComposition(); + if (this.hasAttribute("autofocus")) { + this.focus(); + } } onExitDOM() { diff --git a/packages/main/src/Popup.ts b/packages/main/src/Popup.ts index fda670bdff31..6f9cd2d51364 100644 --- a/packages/main/src/Popup.ts +++ b/packages/main/src/Popup.ts @@ -504,13 +504,18 @@ abstract class Popup extends UI5Element { * @returns Promise that resolves when the focus is applied */ async applyFocus(): Promise { - // do nothing if the standard HTML autofocus is used - if (this.querySelector("[autofocus]")) { + await this._waitForDomRef(); + + const elementWithAutoFocus = this.querySelector("[autofocus]"); + if (elementWithAutoFocus) { + // If the "autofocus" is set on UI5Element, focus it manually. + if ("isUI5Element" in elementWithAutoFocus) { + (elementWithAutoFocus as UI5Element).focus(); + } + // Otherwise, the browser will focus it automatically. return; } - await this._waitForDomRef(); - if (this.getRootNode() === this) { return; } diff --git a/packages/main/src/TextArea.ts b/packages/main/src/TextArea.ts index c879b7aa0be2..3892c82b1bcc 100644 --- a/packages/main/src/TextArea.ts +++ b/packages/main/src/TextArea.ts @@ -83,6 +83,7 @@ type TextAreaInputEventDetail = { ], renderer: jsxRenderer, template: TextAreaTemplate, + shadowRootOptions: { delegatesFocus: true }, }) /** * Fired when the text has changed and the focus leaves the component. @@ -377,6 +378,9 @@ class TextArea extends UI5Element implements IFormInputElement { onEnterDOM() { ResizeHandler.register(this, this._fnOnResize); + if (this.hasAttribute("autofocus")) { + this.focus(); + } } onExitDOM() { diff --git a/packages/main/test/pages/Dialog.html b/packages/main/test/pages/Dialog.html index 119577f212e3..ba919341096e 100644 --- a/packages/main/test/pages/Dialog.html +++ b/packages/main/test/pages/Dialog.html @@ -103,6 +103,7 @@
Close
+ diff --git a/packages/main/test/pages/Input.html b/packages/main/test/pages/Input.html index 4e18da99c108..46219d4562c2 100644 --- a/packages/main/test/pages/Input.html +++ b/packages/main/test/pages/Input.html @@ -22,6 +22,9 @@

Input with suggestions: type 'a'

Event [selectionChange] :: N/A
+

Input with autofocus

+ +

Input in Cozy

diff --git a/packages/main/test/pages/Popover.html b/packages/main/test/pages/Popover.html index dbf1b8fec06c..d87c066cdcd0 100644 --- a/packages/main/test/pages/Popover.html +++ b/packages/main/test/pages/Popover.html @@ -96,6 +96,13 @@ Close with Attribute + Open with Attribute + + Close with Method + Close with Attribute + + +

@@ -666,6 +673,9 @@

Popover in ShadowRoot, Opener set as ID in window.document

btnOpenWithAttr.addEventListener("click", function () { popoverAttr.setAttribute("open", ""); }); + btnOpenWithAttr2.addEventListener("click", function () { + popoverAttr2.setAttribute("open", ""); + }); btnCloseWithMethod.addEventListener("click", function () { popoverAttr.open = false;