Skip to content

Commit c44c23f

Browse files
georgimkvilhan007
authored andcommitted
fix(ui5-dialog): fix text selection on chrome (#3532)
On Chrome, clicking on slotted elements (light DOM) in the dialog (shadow DOM) causes the focus to travel up the light DOM tree to reach the closes element that is focusable. Which ends to be the body element as document.activeElement. This is not the case for FF & Safari, where the focus travels up the slot, reaching the dialog root which is actually the closest focusable element. This change introduces a workaround to align the focus behaviour in Chrome with the other browsers. Related issue: WICG/webcomponents#773 Fixes #3466
1 parent 3e3edcc commit c44c23f

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

packages/main/src/Popup.hbs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
dir="{{effectiveDir}}"
99
@keydown={{_onkeydown}}
1010
@focusout={{_onfocusout}}
11+
@mouseup={{_onmouseup}}
12+
@mousedown={{_onmousedown}}
1113
>
1214

1315
<span class="first-fe" data-ui5-focus-trap tabindex="0" @focusin={{forwardToLast}}></span>

packages/main/src/Popup.js

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { renderFinished } from "@ui5/webcomponents-base/dist/Render.js";
22
import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js";
33
import { getRTL } from "@ui5/webcomponents-base/dist/config/RTL.js";
44
import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js";
5+
import { isChrome } from "@ui5/webcomponents-base/dist/Device.js";
56
import { getFirstFocusableElement, getLastFocusableElement } from "@ui5/webcomponents-base/dist/util/FocusableElements.js";
67
import createStyleInHead from "@ui5/webcomponents-base/dist/util/createStyleInHead.js";
78
import { isTabPrevious } from "@ui5/webcomponents-base/dist/Keys.js";
@@ -266,10 +267,30 @@ class Popup extends UI5Element {
266267
}
267268

268269
_onfocusout(e) {
269-
// relatedTarget is the element, which will get focus. If no such element exists, focus the root
270+
// relatedTarget is the element, which will get focus. If no such element exists, focus the root.
271+
// This happens after the mouse is released in order to not interrupt text selection.
270272
if (!e.relatedTarget) {
271-
this._root.tabIndex = -1;
272-
this._root.focus();
273+
this._shouldFocusRoot = true;
274+
}
275+
}
276+
277+
_onmousedown(e) {
278+
this._root.removeAttribute("tabindex");
279+
280+
if (this.shadowRoot.contains(e.target)) {
281+
this._shouldFocusRoot = true;
282+
} else {
283+
this._shouldFocusRoot = false;
284+
}
285+
}
286+
287+
_onmouseup() {
288+
this._root.tabIndex = -1;
289+
if (this._shouldFocusRoot) {
290+
if (isChrome()) {
291+
this._root.focus();
292+
}
293+
this._shouldFocusRoot = false;
273294
}
274295
}
275296

0 commit comments

Comments
 (0)