Created
November 5, 2021 21:53
-
-
Save slavafomin/d6d92d1dacae927ab19f2745f93a4abc to your computer and use it in GitHub Desktop.
Angular 11+ autofocus directive
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* This smart directive accepts boolean value as an input and focuses the | |
* element based on the evaluated boolean expression. | |
* | |
* Also, the directive could be applied to the input/button/select/a elements | |
* directly or to any parent element as well. It will search the DOM for the first | |
* suitable element to focus automatically. | |
*/ | |
import { AfterViewInit, Directive, ElementRef, Input, NgModule } from '@angular/core'; | |
const focusableElements = [ | |
'input', | |
'select', | |
'button', | |
'a', | |
]; | |
@Directive({ | |
selector: '[autofocus]', | |
}) | |
export class AutofocusDirective implements AfterViewInit { | |
@Input() | |
public set autofocus(shouldFocus: boolean) { | |
this.shouldFocus = shouldFocus; | |
this.checkFocus(); | |
} | |
private shouldFocus = true; | |
constructor( | |
private readonly elementRef: ElementRef | |
) { | |
} | |
public ngAfterViewInit() { | |
this.checkFocus(); | |
} | |
private checkFocus() { | |
if (!this.shouldFocus) { | |
return; | |
} | |
const hostElement = ( | |
<HTMLElement> | |
this.elementRef.nativeElement | |
); | |
if (!hostElement) { | |
return; | |
} | |
if (focusableElements.includes( | |
hostElement.tagName.toLowerCase()) | |
) { | |
hostElement.focus?.(); | |
} else if (hostElement?.querySelector) { | |
for (const tagName of focusableElements) { | |
const childElement = ( | |
<HTMLInputElement> | |
hostElement.querySelector(tagName) | |
); | |
if (childElement) { | |
childElement?.focus?.(); | |
break; | |
} | |
} | |
} | |
} | |
} | |
@NgModule({ | |
declarations: [ | |
AutofocusDirective, | |
], | |
exports: [ | |
AutofocusDirective, | |
], | |
}) | |
export class AutofocusModule { | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment