MCPcopy Create free account
hub / github.com/UI5/webcomponents / findFocusableElement

Function findFocusableElement

packages/base/src/util/FocusableElements.ts:50–123  ·  view source on GitHub ↗
(container: HTMLElement, forward: boolean, startFromContainer?: boolean)

Source from the content-addressed store, hash-verified

48};
49
50const findFocusableElement = async (container: HTMLElement, forward: boolean, startFromContainer?: boolean): FocusableElementPromise => {
51 let child: HTMLElement | undefined;
52 let assignedElements;
53 let currentIndex = -1;
54
55 if (container.shadowRoot) {
56 child = forward ? container.shadowRoot.firstElementChild as HTMLElement : container.shadowRoot.lastElementChild as HTMLElement;
57 } else if (container instanceof HTMLSlotElement && container.assignedNodes()) {
58 assignedElements = container.assignedElements();
59 currentIndex = forward ? 0 : assignedElements.length - 1;
60 child = assignedElements[currentIndex] as HTMLElement;
61 } else if (startFromContainer) {
62 child = container;
63 } else {
64 child = forward ? container.firstElementChild as HTMLElement : container.lastElementChild as HTMLElement;
65 }
66
67 let focusableDescendant;
68
69 /* eslint-disable no-await-in-loop */
70
71 while (child) {
72 const originalChild: HTMLElement | undefined = child;
73
74 if (!isElementHidden(originalChild) && !isUI5ElementWithNegativeTabIndex(originalChild)) {
75 if (instanceOfUI5Element(child)) {
76 // getDomRef is used because some components mark their focusable ref in an inner
77 // html but there might also be focusable targets outside of it
78 // as an example - TreeItemBase
79 // div - root of the component returned by getDomRef()
80 // li.ui5-li-tree - returned by getFocusDomRef() and may not be focusable (ItemNavigation manages tabindex)
81 // ul.subtree - may still contain focusable targets (sub nodes of the tree item)
82 await child._waitForDomRef();
83 child = child.getDomRef();
84 }
85
86 if (!child || isElementHidden(child)) {
87 return null;
88 }
89
90 if (child.nodeType === 1 && isElemFocusable(child) && !isFocusTrap(child)) {
91 if (isElementClickable(child)) {
92 return (child && typeof child.focus === "function") ? child : null;
93 }
94
95 focusableDescendant = await findFocusableElement(child, forward);
96
97 // check if it is a keyboard focusable scroll container
98 if (!isSafari() && !focusableDescendant && isScrollable(child)) {
99 return (child && typeof child.focus === "function") ? child : null;
100 }
101
102 if (focusableDescendant) {
103 return (focusableDescendant && typeof focusableDescendant.focus === "function") ? focusableDescendant : null;
104 }
105 }
106 }
107

Callers 2

getFirstFocusableElementFunction · 0.85
getLastFocusableElementFunction · 0.85

Calls 8

isElementHiddenFunction · 0.85
isElemFocusableFunction · 0.85
isFocusTrapFunction · 0.85
isElementClickableFunction · 0.85
isSafariFunction · 0.85
isScrollableFunction · 0.85
containsMethod · 0.80

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…