* Moves the focus inside the focus trap. When autoFocus is not set to 'dialog', if focus * cannot be moved then focus will go to the dialog container.
(options?: FocusOptions)
| 252 | * cannot be moved then focus will go to the dialog container. |
| 253 | */ |
| 254 | protected _trapFocus(options?: FocusOptions) { |
| 255 | if (this._isDestroyed) { |
| 256 | return; |
| 257 | } |
| 258 | |
| 259 | // If were to attempt to focus immediately, then the content of the dialog would not yet be |
| 260 | // ready in instances where change detection has to run first. To deal with this, we simply |
| 261 | // wait until after the next render. |
| 262 | afterNextRender( |
| 263 | () => { |
| 264 | const element = this._elementRef.nativeElement; |
| 265 | switch (this._config.autoFocus) { |
| 266 | case false: |
| 267 | case 'dialog': |
| 268 | // Ensure that focus is on the dialog container. It's possible that a different |
| 269 | // component tried to move focus while the open animation was running. See: |
| 270 | // https://github.com/angular/components/issues/16215. Note that we only want to do this |
| 271 | // if the focus isn't inside the dialog already, because it's possible that the consumer |
| 272 | // turned off `autoFocus` in order to move focus themselves. |
| 273 | if (!this._containsFocus()) { |
| 274 | element.focus(options); |
| 275 | } |
| 276 | break; |
| 277 | case true: |
| 278 | case 'first-tabbable': |
| 279 | const focusedSuccessfully = this._focusTrap?.focusInitialElement(options); |
| 280 | // If we weren't able to find a focusable element in the dialog, then focus the dialog |
| 281 | // container instead. |
| 282 | if (!focusedSuccessfully) { |
| 283 | this._focusDialogContainer(options); |
| 284 | } |
| 285 | break; |
| 286 | case 'first-heading': |
| 287 | this._focusByCssSelector('h1, h2, h3, h4, h5, h6, [role="heading"]', options); |
| 288 | break; |
| 289 | default: |
| 290 | this._focusByCssSelector(this._config.autoFocus!, options); |
| 291 | break; |
| 292 | } |
| 293 | (this._focusTrapped as Subject<void>).next(); |
| 294 | }, |
| 295 | {injector: this._injector}, |
| 296 | ); |
| 297 | } |
| 298 | |
| 299 | /** Restores focus to the element that was focused before the dialog opened. */ |
| 300 | private _restoreFocus() { |
no test coverage detected