@blox/material
Version:
Material Components for Angular
102 lines • 12.3 kB
JavaScript
import { ContentChildren, Directive, ElementRef, forwardRef } from '@angular/core';
import { focusTrap } from '@material/dom';
import { AbstractMdcFocusTrap, AbstractMdcFocusInitial } from './abstract.mdc.focus-trap';
/**
* When placed on a child element of an <code>mdcFocusTrap</code>, the focus trap
* will try to move focus to this element when the focus trap is activated.
*/
export class MdcFocusInitialDirective extends AbstractMdcFocusInitial {
constructor(_elm) {
super();
this._elm = _elm;
/** @internal */ this.priority = 100;
}
}
MdcFocusInitialDirective.decorators = [
{ type: Directive, args: [{
selector: '[mdcFocusInitial]',
providers: [{ provide: AbstractMdcFocusInitial, useExisting: forwardRef(() => MdcFocusInitialDirective) }]
},] }
];
MdcFocusInitialDirective.ctorParameters = () => [
{ type: ElementRef }
];
let activeTrap = null;
/** @docs-private */
class FocusTrapHandleImpl {
constructor(_elm, focusElm, skipFocus) {
this._elm = _elm;
this._active = true;
this.trap = null;
if (activeTrap)
// Stacking focus tracks (i.e. changing to another focus trap, and returning
// to the previous on deactivation) is not supported:
throw new Error('An mdcFocusTrap is already active.');
this.trap = new focusTrap.FocusTrap(_elm.nativeElement, {
initialFocusEl: focusElm || undefined,
skipInitialFocus: skipFocus
});
this.trap.trapFocus();
activeTrap = this;
}
untrap() {
this._active = false;
if (activeTrap === this) {
activeTrap = null;
this.trap.releaseFocus();
}
}
get active() {
return this._active;
}
}
/**
* Directive for trapping the tab key focus within an element. To be used
* for e.g. modal dialogs, where focus must be constrained for an accesssible experience.
*
* This will only trap the keyboard focus (when using tab or shift+tab). It will not prevent the focus from moving
* out of the trapped region due to mouse interaction. You can use a background scrim element that overlays
* the window to achieve that. (Like `mdcDialog` does).
*
* Use `mdcFocusInitial` on a child element if a specific element needs to get
* focus upon activation of the trap. In the absense of an `mdcFocusInitial`,
* or when that element can't be focused, the focus trap will activate the first tabbable
* child element of the focus trap.
*/
export class MdcFocusTrapDirective extends AbstractMdcFocusTrap {
constructor(_elm) {
super();
this._elm = _elm;
this.trap = null;
}
ngOnDestroy() {
// if this element is destroyed, it must not leave the trap in activated state:
if (this.trap)
this.trap.untrap();
this.trap = null;
}
/** @docs-private */
trapFocus() {
var _a;
let focusInitial = null;
this._focusInitials.forEach(focus => focusInitial = (focusInitial == null || focusInitial.priority <= focus.priority) ? focus : focusInitial);
this.trap = new FocusTrapHandleImpl(this._elm, (_a = focusInitial) === null || _a === void 0 ? void 0 : _a._elm.nativeElement, false);
return this.trap;
}
}
MdcFocusTrapDirective.decorators = [
{ type: Directive, args: [{
selector: '[mdcFocusTrap],[mdcDialog],[mdcDrawer]',
providers: [{ provide: AbstractMdcFocusTrap, useExisting: forwardRef(() => MdcFocusTrapDirective) }]
},] }
];
MdcFocusTrapDirective.ctorParameters = () => [
{ type: ElementRef }
];
MdcFocusTrapDirective.propDecorators = {
_focusInitials: [{ type: ContentChildren, args: [AbstractMdcFocusInitial, { descendants: true },] }]
};
export const FOCUS_TRAP_DIRECTIVES = [
MdcFocusInitialDirective, MdcFocusTrapDirective
];
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWRjLmZvY3VzLXRyYXAuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvZm9jdXMtdHJhcC9tZGMuZm9jdXMtdHJhcC5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGVBQWUsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUErQixVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDaEgsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMxQyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsdUJBQXVCLEVBQW1CLE1BQU0sMkJBQTJCLENBQUM7QUFFM0c7OztHQUdHO0FBS0gsTUFBTSxPQUFPLHdCQUF5QixTQUFRLHVCQUF1QjtJQUdqRSxZQUFtQixJQUFnQjtRQUMvQixLQUFLLEVBQUUsQ0FBQztRQURPLFNBQUksR0FBSixJQUFJLENBQVk7UUFGbkMsZ0JBQWdCLENBQVUsYUFBUSxHQUFHLEdBQUcsQ0FBQztJQUl6QyxDQUFDOzs7WUFUSixTQUFTLFNBQUM7Z0JBQ1AsUUFBUSxFQUFFLG1CQUFtQjtnQkFDN0IsU0FBUyxFQUFFLENBQUMsRUFBQyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsV0FBVyxFQUFFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyx3QkFBd0IsQ0FBQyxFQUFFLENBQUM7YUFDNUc7OztZQVhvQyxVQUFVOztBQW9CL0MsSUFBSSxVQUFVLEdBQStCLElBQUksQ0FBQztBQUVsRCxvQkFBb0I7QUFDcEIsTUFBTSxtQkFBbUI7SUFJckIsWUFBbUIsSUFBZ0IsRUFBRSxRQUE0QixFQUFFLFNBQWtCO1FBQWxFLFNBQUksR0FBSixJQUFJLENBQVk7UUFIM0IsWUFBTyxHQUFHLElBQUksQ0FBQztRQUNmLFNBQUksR0FBK0IsSUFBSSxDQUFDO1FBRzVDLElBQUksVUFBVTtZQUNWLDRFQUE0RTtZQUM1RSxxREFBcUQ7WUFDckQsTUFBTSxJQUFJLEtBQUssQ0FBQyxvQ0FBb0MsQ0FBQyxDQUFDO1FBQzFELElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxTQUFTLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUU7WUFDcEQsY0FBYyxFQUFFLFFBQVEsSUFBSSxTQUFTO1lBQ3JDLGdCQUFnQixFQUFFLFNBQVM7U0FDOUIsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUN0QixVQUFVLEdBQUcsSUFBSSxDQUFDO0lBQ3RCLENBQUM7SUFFRCxNQUFNO1FBQ0YsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7UUFDckIsSUFBSSxVQUFVLEtBQUssSUFBSSxFQUFFO1lBQ3JCLFVBQVUsR0FBRyxJQUFJLENBQUM7WUFDbEIsSUFBSSxDQUFDLElBQUssQ0FBQyxZQUFZLEVBQUUsQ0FBQztTQUM3QjtJQUNMLENBQUM7SUFFRCxJQUFJLE1BQU07UUFDTixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUM7SUFDeEIsQ0FBQztDQUNKO0FBRUQ7Ozs7Ozs7Ozs7OztHQVlHO0FBS0gsTUFBTSxPQUFPLHFCQUFzQixTQUFRLG9CQUFvQjtJQUszRCxZQUFvQixJQUFnQjtRQUNoQyxLQUFLLEVBQUUsQ0FBQztRQURRLFNBQUksR0FBSixJQUFJLENBQVk7UUFGNUIsU0FBSSxHQUEyQixJQUFJLENBQUM7SUFJNUMsQ0FBQztJQUVELFdBQVc7UUFDUCwrRUFBK0U7UUFDL0UsSUFBSSxJQUFJLENBQUMsSUFBSTtZQUNULElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7SUFDckIsQ0FBQztJQUVELG9CQUFvQjtJQUNwQixTQUFTOztRQUNMLElBQUksWUFBWSxHQUFtQyxJQUFJLENBQUM7UUFDeEQsSUFBSSxDQUFDLGNBQWUsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxZQUFZLEdBQUcsQ0FBQyxZQUFZLElBQUksSUFBSSxJQUFJLFlBQVksQ0FBQyxRQUFTLElBQUksS0FBSyxDQUFDLFFBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ2pKLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxRQUFRLFlBQWEsMENBQUUsSUFBSSxDQUFDLGFBQWEsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUMvRixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDckIsQ0FBQzs7O1lBMUJKLFNBQVMsU0FBQztnQkFDUCxRQUFRLEVBQUUsd0NBQXdDO2dCQUNsRCxTQUFTLEVBQUUsQ0FBQyxFQUFDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLHFCQUFxQixDQUFDLEVBQUUsQ0FBQzthQUN0Rzs7O1lBckVvQyxVQUFVOzs7NkJBd0UxQyxlQUFlLFNBQUMsdUJBQXVCLEVBQUUsRUFBQyxXQUFXLEVBQUUsSUFBSSxFQUFDOztBQXVCakUsTUFBTSxDQUFDLE1BQU0scUJBQXFCLEdBQUc7SUFDakMsd0JBQXdCLEVBQUUscUJBQXFCO0NBQ2xELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb250ZW50Q2hpbGRyZW4sIERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgSW5wdXQsIE9uRGVzdHJveSwgUXVlcnlMaXN0LCBmb3J3YXJkUmVmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBmb2N1c1RyYXAgfSBmcm9tICdAbWF0ZXJpYWwvZG9tJztcbmltcG9ydCB7IEFic3RyYWN0TWRjRm9jdXNUcmFwLCBBYnN0cmFjdE1kY0ZvY3VzSW5pdGlhbCwgRm9jdXNUcmFwSGFuZGxlIH0gZnJvbSAnLi9hYnN0cmFjdC5tZGMuZm9jdXMtdHJhcCc7XG5cbi8qKlxuICogV2hlbiBwbGFjZWQgb24gYSBjaGlsZCBlbGVtZW50IG9mIGFuIDxjb2RlPm1kY0ZvY3VzVHJhcDwvY29kZT4sIHRoZSBmb2N1cyB0cmFwXG4gKiB3aWxsIHRyeSB0byBtb3ZlIGZvY3VzIHRvIHRoaXMgZWxlbWVudCB3aGVuIHRoZSBmb2N1cyB0cmFwIGlzIGFjdGl2YXRlZC5cbiAqL1xuQERpcmVjdGl2ZSh7XG4gICAgc2VsZWN0b3I6ICdbbWRjRm9jdXNJbml0aWFsXScsXG4gICAgcHJvdmlkZXJzOiBbe3Byb3ZpZGU6IEFic3RyYWN0TWRjRm9jdXNJbml0aWFsLCB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBNZGNGb2N1c0luaXRpYWxEaXJlY3RpdmUpIH1dXG59KVxuZXhwb3J0IGNsYXNzIE1kY0ZvY3VzSW5pdGlhbERpcmVjdGl2ZSBleHRlbmRzIEFic3RyYWN0TWRjRm9jdXNJbml0aWFsIHtcbiAgICAvKiogQGludGVybmFsICovIHJlYWRvbmx5IHByaW9yaXR5ID0gMTAwO1xuXG4gICAgY29uc3RydWN0b3IocHVibGljIF9lbG06IEVsZW1lbnRSZWYpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG59XG5cbmxldCBhY3RpdmVUcmFwOiBGb2N1c1RyYXBIYW5kbGVJbXBsIHwgbnVsbCA9IG51bGw7XG5cbi8qKiBAZG9jcy1wcml2YXRlICovXG5jbGFzcyBGb2N1c1RyYXBIYW5kbGVJbXBsIGltcGxlbWVudHMgRm9jdXNUcmFwSGFuZGxlIHtcbiAgICBwcml2YXRlIF9hY3RpdmUgPSB0cnVlO1xuICAgIHByaXZhdGUgdHJhcDogZm9jdXNUcmFwLkZvY3VzVHJhcCB8IG51bGwgPSBudWxsO1xuXG4gICAgY29uc3RydWN0b3IocHVibGljIF9lbG06IEVsZW1lbnRSZWYsIGZvY3VzRWxtOiBIVE1MRWxlbWVudCB8IG51bGwsIHNraXBGb2N1czogYm9vbGVhbikge1xuICAgICAgICBpZiAoYWN0aXZlVHJhcClcbiAgICAgICAgICAgIC8vIFN0YWNraW5nIGZvY3VzIHRyYWNrcyAoaS5lLiBjaGFuZ2luZyB0byBhbm90aGVyIGZvY3VzIHRyYXAsIGFuZCByZXR1cm5pbmdcbiAgICAgICAgICAgIC8vIHRvIHRoZSBwcmV2aW91cyBvbiBkZWFjdGl2YXRpb24pIGlzIG5vdCBzdXBwb3J0ZWQ6XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FuIG1kY0ZvY3VzVHJhcCBpcyBhbHJlYWR5IGFjdGl2ZS4nKTtcbiAgICAgICAgdGhpcy50cmFwID0gbmV3IGZvY3VzVHJhcC5Gb2N1c1RyYXAoX2VsbS5uYXRpdmVFbGVtZW50LCB7XG4gICAgICAgICAgICBpbml0aWFsRm9jdXNFbDogZm9jdXNFbG0gfHwgdW5kZWZpbmVkLFxuICAgICAgICAgICAgc2tpcEluaXRpYWxGb2N1czogc2tpcEZvY3VzXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnRyYXAudHJhcEZvY3VzKCk7XG4gICAgICAgIGFjdGl2ZVRyYXAgPSB0aGlzO1xuICAgIH1cblxuICAgIHVudHJhcCgpIHtcbiAgICAgICAgdGhpcy5fYWN0aXZlID0gZmFsc2U7XG4gICAgICAgIGlmIChhY3RpdmVUcmFwID09PSB0aGlzKSB7XG4gICAgICAgICAgICBhY3RpdmVUcmFwID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMudHJhcCEucmVsZWFzZUZvY3VzKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXQgYWN0aXZlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWN0aXZlO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEaXJlY3RpdmUgZm9yIHRyYXBwaW5nIHRoZSB0YWIga2V5IGZvY3VzIHdpdGhpbiBhbiBlbGVtZW50LiBUbyBiZSB1c2VkXG4gKiBmb3IgZS5nLiBtb2RhbCBkaWFsb2dzLCB3aGVyZSBmb2N1cyBtdXN0IGJlIGNvbnN0cmFpbmVkIGZvciBhbiBhY2Nlc3NzaWJsZSBleHBlcmllbmNlLlxuICogXG4gKiBUaGlzIHdpbGwgb25seSB0cmFwIHRoZSBrZXlib2FyZCBmb2N1cyAod2hlbiB1c2luZyB0YWIgb3Igc2hpZnQrdGFiKS4gSXQgd2lsbCBub3QgcHJldmVudCB0aGUgZm9jdXMgZnJvbSBtb3ZpbmdcbiAqIG91dCBvZiB0aGUgdHJhcHBlZCByZWdpb24gZHVlIHRvIG1vdXNlIGludGVyYWN0aW9uLiBZb3UgY2FuIHVzZSBhIGJhY2tncm91bmQgc2NyaW0gZWxlbWVudCB0aGF0IG92ZXJsYXlzXG4gKiB0aGUgd2luZG93IHRvIGFjaGlldmUgdGhhdC4gKExpa2UgYG1kY0RpYWxvZ2AgZG9lcykuXG4gKlxuICogVXNlIGBtZGNGb2N1c0luaXRpYWxgIG9uIGEgY2hpbGQgZWxlbWVudCBpZiBhIHNwZWNpZmljIGVsZW1lbnQgbmVlZHMgdG8gZ2V0XG4gKiBmb2N1cyB1cG9uIGFjdGl2YXRpb24gb2YgdGhlIHRyYXAuIEluIHRoZSBhYnNlbnNlIG9mIGFuIGBtZGNGb2N1c0luaXRpYWxgLFxuICogb3Igd2hlbiB0aGF0IGVsZW1lbnQgY2FuJ3QgYmUgZm9jdXNlZCwgdGhlIGZvY3VzIHRyYXAgd2lsbCBhY3RpdmF0ZSB0aGUgZmlyc3QgdGFiYmFibGVcbiAqIGNoaWxkIGVsZW1lbnQgb2YgdGhlIGZvY3VzIHRyYXAuXG4gKi9cbkBEaXJlY3RpdmUoe1xuICAgIHNlbGVjdG9yOiAnW21kY0ZvY3VzVHJhcF0sW21kY0RpYWxvZ10sW21kY0RyYXdlcl0nLFxuICAgIHByb3ZpZGVyczogW3twcm92aWRlOiBBYnN0cmFjdE1kY0ZvY3VzVHJhcCwgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gTWRjRm9jdXNUcmFwRGlyZWN0aXZlKSB9XVxufSlcbmV4cG9ydCBjbGFzcyBNZGNGb2N1c1RyYXBEaXJlY3RpdmUgZXh0ZW5kcyBBYnN0cmFjdE1kY0ZvY3VzVHJhcCBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIEBDb250ZW50Q2hpbGRyZW4oQWJzdHJhY3RNZGNGb2N1c0luaXRpYWwsIHtkZXNjZW5kYW50czogdHJ1ZX0pIF9mb2N1c0luaXRpYWxzPzogUXVlcnlMaXN0PEFic3RyYWN0TWRjRm9jdXNJbml0aWFsPjtcbiAgICBwcml2YXRlIHRyYXA6IEZvY3VzVHJhcEhhbmRsZSB8IG51bGwgPSBudWxsO1xuICAgIFxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgX2VsbTogRWxlbWVudFJlZikge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIG5nT25EZXN0cm95KCkge1xuICAgICAgICAvLyBpZiB0aGlzIGVsZW1lbnQgaXMgZGVzdHJveWVkLCBpdCBtdXN0IG5vdCBsZWF2ZSB0aGUgdHJhcCBpbiBhY3RpdmF0ZWQgc3RhdGU6XG4gICAgICAgIGlmICh0aGlzLnRyYXApXG4gICAgICAgICAgICB0aGlzLnRyYXAudW50cmFwKCk7XG4gICAgICAgIHRoaXMudHJhcCA9IG51bGw7XG4gICAgfVxuXG4gICAgLyoqIEBkb2NzLXByaXZhdGUgKi9cbiAgICB0cmFwRm9jdXMoKTogRm9jdXNUcmFwSGFuZGxlIHtcbiAgICAgICAgbGV0IGZvY3VzSW5pdGlhbDogQWJzdHJhY3RNZGNGb2N1c0luaXRpYWwgfCBudWxsID0gbnVsbDtcbiAgICAgICAgdGhpcy5fZm9jdXNJbml0aWFscyEuZm9yRWFjaChmb2N1cyA9PiBmb2N1c0luaXRpYWwgPSAoZm9jdXNJbml0aWFsID09IG51bGwgfHwgZm9jdXNJbml0aWFsLnByaW9yaXR5ISA8PSBmb2N1cy5wcmlvcml0eSEpID8gZm9jdXMgOiBmb2N1c0luaXRpYWwpO1xuICAgICAgICB0aGlzLnRyYXAgPSBuZXcgRm9jdXNUcmFwSGFuZGxlSW1wbCh0aGlzLl9lbG0sICg8YW55PmZvY3VzSW5pdGlhbCk/Ll9lbG0ubmF0aXZlRWxlbWVudCwgZmFsc2UpO1xuICAgICAgICByZXR1cm4gdGhpcy50cmFwO1xuICAgIH1cbn1cblxuZXhwb3J0IGNvbnN0IEZPQ1VTX1RSQVBfRElSRUNUSVZFUyA9IFtcbiAgICBNZGNGb2N1c0luaXRpYWxEaXJlY3RpdmUsIE1kY0ZvY3VzVHJhcERpcmVjdGl2ZVxuXTtcbiJdfQ==