MCPcopy Index your code
hub / github.com/ionic-team/ionic-framework / trapShadowFocus

Function trapShadowFocus

core/src/utils/overlays.ts:312–367  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

310 }
311 };
312 const trapShadowFocus = () => {
313 /**
314 * If the target is inside the wrapper, let the browser
315 * focus as normal and keep a log of the last focused element.
316 */
317 if (lastOverlay.contains(target)) {
318 lastOverlay.lastFocus = target;
319 /**
320 * Toasts can be presented from an overlay.
321 * However, focus should still be returned to
322 * the overlay when clicking a toast. Normally,
323 * focus would be returned to the last focusable
324 * descendant in the overlay which may not always be
325 * the button that the toast was presented from. In this case,
326 * the focus may be returned to an unexpected element.
327 * To account for this, we make sure to return focus to the
328 * last focused element in the overlay if focus is
329 * moved to the toast.
330 */
331 } else if (target.tagName === 'ION-TOAST') {
332 focusElementInOverlay(lastOverlay.lastFocus, lastOverlay);
333 } else {
334 /**
335 * Otherwise, we are about to have focus
336 * go out of the overlay. We need to wrap
337 * the focus to either the first element
338 * or the last element.
339 */
340
341 /**
342 * Once we call `focusFirstDescendant` and focus the first
343 * descendant, another focus event will fire which will
344 * cause `lastOverlay.lastFocus` to be updated before
345 * we can run the code after that. We will cache the value
346 * here to avoid that.
347 */
348 const lastFocus = lastOverlay.lastFocus;
349
350 // Focus the first element in the overlay wrapper
351 focusFirstDescendant(lastOverlay);
352
353 /**
354 * If the cached last focused element is the
355 * same as the active element, then we need
356 * to wrap focus to the last descendant. This happens
357 * when the first descendant is focused, and the user
358 * presses Shift + Tab. The previous line will focus
359 * the same descendant again (the first one), causing
360 * last focus to equal the active element.
361 */
362 if (lastFocus === doc.activeElement) {
363 focusLastDescendant(lastOverlay);
364 }
365 lastOverlay.lastFocus = doc.activeElement as HTMLElement;
366 }
367 };
368
369 if (lastOverlay.shadowRoot) {

Callers 1

trapKeyboardFocusFunction · 0.85

Calls 3

focusFirstDescendantFunction · 0.90
focusLastDescendantFunction · 0.90
focusElementInOverlayFunction · 0.85

Tested by

no test coverage detected