()
| 218 | } |
| 219 | |
| 220 | const trapScopedFocus = () => { |
| 221 | /** |
| 222 | * If we are focusing the overlay, clear |
| 223 | * the last focused element so that hitting |
| 224 | * tab activates the first focusable element |
| 225 | * in the overlay wrapper. |
| 226 | */ |
| 227 | if (lastOverlay === target) { |
| 228 | lastOverlay.lastFocus = undefined; |
| 229 | /** |
| 230 | * Toasts can be presented from an overlay. |
| 231 | * However, focus should still be returned to |
| 232 | * the overlay when clicking a toast. Normally, |
| 233 | * focus would be returned to the last focusable |
| 234 | * descendant in the overlay which may not always be |
| 235 | * the button that the toast was presented from. In this case, |
| 236 | * the focus may be returned to an unexpected element. |
| 237 | * To account for this, we make sure to return focus to the |
| 238 | * last focused element in the overlay if focus is |
| 239 | * moved to the toast. |
| 240 | */ |
| 241 | } else if (target.tagName === 'ION-TOAST') { |
| 242 | focusElementInOverlay(lastOverlay.lastFocus, lastOverlay); |
| 243 | |
| 244 | /** |
| 245 | * Otherwise, we must be focusing an element |
| 246 | * inside of the overlay. The two possible options |
| 247 | * here are an input/button/etc or the ion-focus-trap |
| 248 | * element. The focus trap element is used to prevent |
| 249 | * the keyboard focus from leaving the overlay when |
| 250 | * using Tab or screen assistants. |
| 251 | */ |
| 252 | } else { |
| 253 | /** |
| 254 | * We do not want to focus the traps, so get the overlay |
| 255 | * wrapper element as the traps live outside of the wrapper. |
| 256 | */ |
| 257 | |
| 258 | const overlayRoot = getElementRoot(lastOverlay); |
| 259 | if (!overlayRoot.contains(target)) { |
| 260 | return; |
| 261 | } |
| 262 | |
| 263 | const overlayWrapper = overlayRoot.querySelector<HTMLElement>('.ion-overlay-wrapper'); |
| 264 | if (!overlayWrapper) { |
| 265 | return; |
| 266 | } |
| 267 | |
| 268 | /** |
| 269 | * If the target is inside the wrapper, let the browser |
| 270 | * focus as normal and keep a log of the last focused element. |
| 271 | * Additionally, if the backdrop was tapped we should not |
| 272 | * move focus back inside the wrapper as that could cause |
| 273 | * an interactive elements focus state to activate. |
| 274 | */ |
| 275 | if (overlayWrapper.contains(target) || target === overlayRoot.querySelector('ion-backdrop')) { |
| 276 | lastOverlay.lastFocus = target; |
| 277 | } else { |
no test coverage detected