ng-devui
Version:
DevUI components based on Angular
761 lines (751 loc) • 38.2 kB
JavaScript
import * as i0 from '@angular/core';
import { Directive, Input, HostBinding, Injectable, Inject, EventEmitter, Optional, SkipSelf, ContentChildren, forwardRef, Output, Host, HostListener, Component, ViewEncapsulation, ViewChild, NgModule } from '@angular/core';
import * as i3 from '@angular/animations';
import { style, animate } from '@angular/animations';
import { DOCUMENT, CommonModule } from '@angular/common';
import * as i2 from 'ng-devui/utils';
import { addClassToOrigin, removeClassFromOrigin, formWithDropDown, WithConfig, AnimationCurves, AnimationDuration, AppendToBodyDirectionsConfig, fadeInOut } from 'ng-devui/utils';
import * as i2$1 from 'ng-devui/window-ref';
import { WindowRefModule } from 'ng-devui/window-ref';
import { ReplaySubject, merge, fromEvent } from 'rxjs';
import { debounceTime, mapTo, delay, filter, tap } from 'rxjs/operators';
import { __decorate, __metadata } from 'tslib';
import * as i2$2 from '@angular/cdk/overlay';
import { CdkOverlayOrigin, CdkConnectedOverlay, OverlayModule } from '@angular/cdk/overlay';
class DropDownMenuItemDirective {
constructor(el, render) {
this.el = el;
this.render = render;
this.disabled = false;
this.itemClass = true;
}
ngOnChanges(changes) {
if (changes.disabled) {
if (this.disabled) {
this.render.setStyle(this.el.nativeElement, 'pointer-events', 'none');
}
else {
this.render.removeStyle(this.el.nativeElement, 'pointer-events');
}
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DropDownMenuItemDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: DropDownMenuItemDirective, selector: "[dDropDownMenuItem]", inputs: { disabled: "disabled" }, host: { properties: { "class.devui-dropdown-item": "this.itemClass" } }, exportAs: ["d-dropdown-menu-item"], usesOnChanges: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DropDownMenuItemDirective, decorators: [{
type: Directive,
args: [{
selector: '[dDropDownMenuItem]',
exportAs: 'd-dropdown-menu-item',
}]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { disabled: [{
type: Input
}], itemClass: [{
type: HostBinding,
args: ['class.devui-dropdown-item']
}] } });
class DropDownService {
constructor(doc) {
this.doc = doc;
this.documentClickTimeOut = null;
this.closeDropdownBind = this.closeDropdown.bind(this);
this.document = this.doc;
}
open(dropdownScope) {
if (!this.openScope) {
// 延时绑定document事件,防止事件冒泡导致立即触发
this.documentClickTimeOut = setTimeout(() => {
this.document.addEventListener('click', this.closeDropdownBind);
});
}
this.openScope = dropdownScope;
}
close(dropdownScope) {
if (this.openScope !== dropdownScope) {
return;
}
this.openScope = null;
clearTimeout(this.documentClickTimeOut);
this.document.removeEventListener('click', this.closeDropdownBind);
}
closeDropdown(event) {
if (event && this.openScope?.menuEl) {
const menuEl = this.openScope.menuEl.nativeElement;
const target = event.target;
const className = target && typeof target.className === 'string' ? target.className : '';
const rules = [
className.indexOf('disabled') > -1,
/input|textarea/i.test(target.tagName) && menuEl.contains(target),
this.openScope.closeScope === 'none',
menuEl.contains(target) && this.openScope.closeScope === 'blank',
this.openScope.dropdownChildren.some((children) => children.toggleEl.nativeElement.contains(target)),
];
if (!rules.includes(true)) {
this.openScope.isOpen = false;
}
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DropDownService, deps: [{ token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DropDownService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DropDownService, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: undefined, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }] });
class DropDownDirective {
/**
* 控制是否打开dropdown,绑定一个devui-dropdown-open class
*/
set isOpen(value) {
this._isOpen = !!value;
if (this.disabled) {
return;
}
if (this.isOpen) {
this.visibleSubject.next(true);
this.focusToggleElement();
this.dropdownService.open(this);
addClassToOrigin(this.toggleEl);
setTimeout(() => {
this.startAnimation = true;
this.cdr.detectChanges();
});
}
else {
this.startAnimation = false;
this.visibleSubject.next(false);
this.dropdownService.close(this);
removeClassFromOrigin(this.toggleEl);
}
this.toggleEvent.emit(this.isOpen);
}
get isOpen() {
return this._isOpen;
}
set appendToBody(bool) {
this._appendToBody = bool === true;
this.updateCdkConnectedOverlayOrigin();
}
get appendToBody() {
return this._appendToBody;
}
set dropDownMenu(dropdownMenu) {
// init drop down menu
this.menuEl = dropdownMenu.el;
}
set dropDownToggle(dropdownToggle) {
// init toggle element
this.toggleEl = dropdownToggle.el;
this.updateCdkConnectedOverlayOrigin();
}
constructor(dropdownService, cdr, el, devConfigService, parentDropdown, doc) {
this.dropdownService = dropdownService;
this.cdr = cdr;
this.el = el;
this.devConfigService = devConfigService;
this.parentDropdown = parentDropdown;
this.doc = doc;
this.mouseenterFlag = false;
this.startAnimation = false;
this.addClass = true;
this.disabled = false;
this.showAnimation = true;
/**
* dropdown触发方式
*/
this.trigger = 'click';
/**
* 关闭区域,默认点击菜单链接也会关闭,blank点击其他空白区域才关闭
*/
this.closeScope = 'all';
this.closeOnMouseLeaveMenu = false;
this.autofocusToggleElement = true;
this.toggleEvent = new EventEmitter();
this.visibleSubject = new ReplaySubject(1);
this._isOpen = false;
this.document = this.doc;
}
ngOnChanges(changes) {
if (Object.prototype.hasOwnProperty.call(changes, 'trigger')) {
this.handleHoverSubscriptionIfTriggerIsHover();
}
}
ngOnDestroy() {
this.dropdownService.close(this);
this.unsubscribeHoverAction();
}
ngAfterContentInit() {
this.handleHoverSubscriptionIfTriggerIsHover();
}
toggle() {
this.isOpen = !this.isOpen;
return this.isOpen;
}
focusToggleElement() {
if (this.toggleEl && this.autofocusToggleElement) {
this.toggleEl.nativeElement.focus();
}
}
updateCdkConnectedOverlayOrigin() {
if (this.toggleEl && this.appendToBody === true) {
this.cdkConnectedOverlayOrigin = new CdkOverlayOrigin(formWithDropDown(this.toggleEl) || this.toggleEl.nativeElement);
}
else {
this.cdkConnectedOverlayOrigin = undefined;
}
}
subscribeHoverAction(observable) {
if (!this.hoverSubscription) {
this.hoverSubscription = observable.pipe(debounceTime(50)).subscribe((isOpen) => {
if (this.mouseenterFlag) {
this.mouseenterFlag = false;
return;
}
if (!this.disabled && this.isOpen !== isOpen) {
this.isOpen = isOpen;
}
});
}
}
unsubscribeHoverAction() {
if (this.hoverSubscription) {
this.hoverSubscription.unsubscribe();
this.hoverSubscription = null;
}
}
handleHoverSubscriptionIfTriggerIsHover() {
if (this.trigger === 'hover') {
const states = merge(fromEvent(this.el.nativeElement, 'mouseenter').pipe(mapTo(true)), fromEvent(this.el.nativeElement, 'mouseleave').pipe(delay(200), filter((event) => {
if (this.isOpen && this.appendToBody === true) {
// 冒泡模拟的relatedTarget, 和作用于dropdown本身event.relatedTarget
// menu(子) -> toggle(父) 冒泡模拟的用于离开菜单的时候判断不判断overlay的div层,即只判断menuEl.nativeElement
// toggle(父) -> menu(子) 离开元素本身的需要判断是否落入了overlay的div层,即只判断menuEl.nativeElement.parentElement
const relatedTarget = event.relatedTarget || (event.originEvent && event.originEvent.relatedTarget);
return !(this.menuEl?.nativeElement && relatedTarget &&
(this.menuEl?.nativeElement.parentElement?.contains(event.relatedTarget)
|| this.menuEl?.nativeElement.parentElement?.parentElement?.contains(event.relatedTarget) // 套了两层div增加判断
|| this.menuEl?.nativeElement.contains(relatedTarget)
|| this.dropdownChildren.some(children => children !== this
// appendToBody的时候可能会没有实例化不在document上需要做判断有没有parentElement
&& (children.menuEl?.nativeElement.parentElement?.contains(event.relatedTarget)
|| children.menuEl?.nativeElement.contains(relatedTarget)))));
}
else {
return true;
}
}), tap((event) => {
if (this.parentDropdown) {
this.simulateEventDispatch(event, this.parentDropdown.el.nativeElement);
}
}), mapTo(false)));
this.subscribeHoverAction(states);
}
else {
this.unsubscribeHoverAction();
}
}
simulateEventDispatch($event, target) {
const event = this.document.createEvent('MouseEvents');
event.initEvent($event.type, true, true);
event.originEvent = $event.originEvent || $event;
if (!target) {
target = this.el.nativeElement;
}
target.dispatchEvent(event);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DropDownDirective, deps: [{ token: DropDownService }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i2.DevConfigService }, { token: DropDownDirective, optional: true, skipSelf: true }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: DropDownDirective, selector: "[dDropDown]", inputs: { isOpen: "isOpen", disabled: "disabled", showAnimation: "showAnimation", trigger: "trigger", closeScope: "closeScope", closeOnMouseLeaveMenu: "closeOnMouseLeaveMenu", autofocusToggleElement: "autofocusToggleElement" }, outputs: { toggleEvent: "toggleEvent" }, host: { properties: { "class.devui-dropdown-open": "this.isOpen", "class.devui-dropdown": "this.addClass", "class.devui-dropdown-animation": "this.showAnimation" } }, providers: [DropDownService], queries: [{ propertyName: "dropdownChildren", predicate: i0.forwardRef(() => DropDownDirective), descendants: true }], exportAs: ["d-dropdown"], usesOnChanges: true, ngImport: i0 }); }
}
__decorate([
WithConfig(),
__metadata("design:type", Object)
], DropDownDirective.prototype, "showAnimation", void 0);
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DropDownDirective, decorators: [{
type: Directive,
args: [{
selector: '[dDropDown]',
exportAs: 'd-dropdown',
providers: [DropDownService],
}]
}], ctorParameters: () => [{ type: DropDownService }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i2.DevConfigService }, { type: DropDownDirective, decorators: [{
type: Optional
}, {
type: SkipSelf
}] }, { type: undefined, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }], propDecorators: { dropdownChildren: [{
type: ContentChildren,
args: [forwardRef(() => DropDownDirective), { descendants: true }]
}], isOpen: [{
type: HostBinding,
args: ['class.devui-dropdown-open']
}, {
type: Input
}], addClass: [{
type: HostBinding,
args: ['class.devui-dropdown']
}], disabled: [{
type: Input
}], showAnimation: [{
type: HostBinding,
args: ['class.devui-dropdown-animation']
}, {
type: Input
}], trigger: [{
type: Input
}], closeScope: [{
type: Input
}], closeOnMouseLeaveMenu: [{
type: Input
}], autofocusToggleElement: [{
type: Input
}], toggleEvent: [{
type: Output
}] } });
class DropDownMenuDirective {
constructor(dropdown, el, render, windowRef, builder, doc) {
this.dropdown = dropdown;
this.el = el;
this.render = render;
this.windowRef = windowRef;
this.builder = builder;
this.doc = doc;
this.display = 'none';
this.tabIndex = -1;
this.addClass = true;
this.currentValue = false;
this.hide = (event) => {
this.dropdown.toggle();
};
this.keydownEscapeEvent$ = fromEvent(this.doc.body, 'keydown').pipe(
// chrome 为 Escape , ie 11为Esc
filter(event => event.key === 'Escape' || event.key === 'Esc'));
}
ngOnInit() {
this.dropdown.dropDownMenu = this;
this.subscription = this.dropdown.visibleSubject.subscribe(value => {
if (value !== this.currentValue) {
this.currentValue = value;
if (this.keydownEscapeSub) {
this.keydownEscapeSub.unsubscribe();
}
if (value) {
this.keydownEscapeSub = this.keydownEscapeEvent$.subscribe(event => {
if (event.defaultPrevented) {
return;
}
this.hide(event);
});
}
if (this.dropdown.appendToBody) {
this.render.setStyle(this.el.nativeElement, 'display', 'block'); // 立马生效不等host binding绑定
this.display = 'block';
return;
}
if (this.player) { // 此处保留一个防止点击过快
this.player.finish();
}
if (this.dropdown.showAnimation) {
const direction = this.calcPopDirection(value);
const metadata = value ? this.fadeIn(direction) : this.fadeOut(direction);
const factory = this.builder.build(metadata);
this.player = factory.create(this.el.nativeElement);
const player = this.player;
this.player.onDone(() => {
if (!value) {
this.render.setStyle(this.el.nativeElement, 'display', 'none');
this.display = 'none';
}
player.destroy();
if (this.player === player) {
this.player = undefined;
}
});
this.player.onStart(() => {
if (value) {
this.render.setStyle(this.el.nativeElement, 'display', 'block');
this.display = 'block';
}
});
this.player.play();
}
else {
this.render.setStyle(this.el.nativeElement, 'display', value ? 'block' : 'none');
this.display = value ? 'block' : 'none';
}
}
});
}
ngOnDestroy() {
if (this.keydownEscapeSub) {
this.keydownEscapeSub.unsubscribe();
}
if (this.subscription) {
this.subscription.unsubscribe();
}
}
calcPopDirection(value) {
const dropdownMenuElement = this.el.nativeElement;
const elementHeight = dropdownMenuElement.offsetHeight;
const bottomDistance = this.windowRef.innerHeight - this.dropdown.el.nativeElement.getBoundingClientRect().bottom;
const isBottomEnough = bottomDistance >= elementHeight;
if (!value) {
return this.popDirectionCache;
}
else {
if (!isBottomEnough) {
this.render.setStyle(dropdownMenuElement, 'bottom', '100%');
this.render.setStyle(dropdownMenuElement, 'top', 'auto');
this.popDirectionCache = 'top';
return 'top';
}
else {
this.render.removeStyle(dropdownMenuElement, 'bottom');
this.render.removeStyle(dropdownMenuElement, 'top');
this.popDirectionCache = 'bottom';
return 'bottom';
}
}
}
mouseEnter(event) {
this.dropdown.mouseenterFlag = true;
}
mouseLeave(event) {
event.stopPropagation();
this.dropdown.mouseenterFlag = false;
if ((this.dropdown.appendToBody && this.dropdown.trigger === 'hover')
|| (this.dropdown.trigger === 'click' && this.dropdown.closeOnMouseLeaveMenu)) {
if (this.dropdown.toggleEl?.nativeElement.contains(event.relatedTarget)
|| this.dropdown.dropdownChildren.some(children => children.menuEl !== this.el
&& children.menuEl?.nativeElement.parentElement?.contains(event.relatedTarget))) {
return;
}
else {
if (this.dropdown.trigger === 'hover') {
this.dropdown.simulateEventDispatch(event);
}
else {
const relatedTarget = event.originEvent?.relatedTarget;
if (relatedTarget && (this.dropdown.toggleEl?.nativeElement.contains(relatedTarget)
|| this.dropdown.dropdownChildren.some(children => children.menuEl?.nativeElement.contains(relatedTarget)))) {
return;
}
this.dropdown.isOpen = false;
}
}
}
return false;
}
fadeIn(direction) {
switch (direction) {
case 'top':
return [
style({ transform: 'scaleY(0.8) translateY(4px)', opacity: 0.8, transformOrigin: '0% 100%' }),
animate(`200ms ${AnimationCurves.EASE_IN}`, style({ transform: 'scaleY(0.9999) translateY(0)', opacity: 1, transformOrigin: '0% 100%' })),
];
case 'bottom':
default:
return [
style({ transform: 'scaleY(0.8) translateY(-4px)', opacity: 0.8, transformOrigin: '0% 0%' }),
animate(`200ms ${AnimationCurves.EASE_OUT}`, style({ transform: 'scaleY(0.9999) translateY(0)', opacity: 1, transformOrigin: '0% 0%' })),
];
}
}
fadeOut(direction) {
switch (direction) {
case 'top':
return [
style({ transform: 'scaleY(0.9999) translateY(0)', opacity: 1, transformOrigin: '0% 100%' }),
animate(`${AnimationDuration.BASE} ${AnimationCurves.EASE_IN}`, style({ transform: 'scaleY(0.8) translateY(4px)', opacity: 0.8, transformOrigin: '0% 100%' }))
];
case 'bottom':
default:
return [
style({ transform: 'scaleY(0.9999) translateY(0)', opacity: 1, transformOrigin: '0% 0%' }),
animate(`${AnimationDuration.BASE} ${AnimationCurves.EASE_IN}`, style({ transform: 'scaleY(0.8) translateY(-4px)', opacity: 0.8, transformOrigin: '0% 0%' }))
];
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DropDownMenuDirective, deps: [{ token: DropDownDirective, host: true }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i2$1.WindowRef }, { token: i3.AnimationBuilder }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: DropDownMenuDirective, selector: "[dDropDownMenu]", host: { listeners: { "mouseenter": "mouseEnter($event)", "mouseleave": "mouseLeave($event)" }, properties: { "style.display": "this.display", "attr.tabIndex": "this.tabIndex", "class.devui-dropdown-menu": "this.addClass" } }, exportAs: ["d-dropdown-menu"], ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DropDownMenuDirective, decorators: [{
type: Directive,
args: [{
selector: '[dDropDownMenu]',
exportAs: 'd-dropdown-menu',
}]
}], ctorParameters: () => [{ type: DropDownDirective, decorators: [{
type: Host
}] }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i2$1.WindowRef }, { type: i3.AnimationBuilder }, { type: undefined, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }], propDecorators: { display: [{
type: HostBinding,
args: ['style.display']
}], tabIndex: [{
type: HostBinding,
args: ['attr.tabIndex']
}], addClass: [{
type: HostBinding,
args: ['class.devui-dropdown-menu']
}], mouseEnter: [{
type: HostListener,
args: ['mouseenter', ['$event']]
}], mouseLeave: [{
type: HostListener,
args: ['mouseleave', ['$event']]
}] } });
class DropDownToggleDirective {
get tabIndex() {
return this.disabled ? null : 0;
}
get attrDisabled() {
return this.disabled ? 'disabled' : null;
}
get disabled() {
return this.dropdown && this.dropdown.disabled;
}
constructor(dropdown, el) {
this.dropdown = dropdown;
this.el = el;
this.addClass = true;
this.toggleOnFocus = false;
this.autoFocus = false;
this.isMouseEvent = false;
}
ngOnInit() {
this.dropdown.dropDownToggle = this;
}
ngAfterViewInit() {
if (this.autoFocus) {
setTimeout(() => {
this.el.nativeElement.focus();
}, 0);
}
}
toggleDropdown(event) {
if (!this.disabled && this.dropdown.trigger !== 'manually') {
this.dropdown.toggle();
}
return false;
}
// mousedown mouseup解决focus与click冲突问题
setMouseEventTrue(event) {
this.isMouseEvent = true;
}
setMouseEventFalse(event) {
this.isMouseEvent = false;
}
toggleOnFocusFn(event) {
if (this.toggleOnFocus && !this.disabled && !this.dropdown.isOpen && !this.isMouseEvent) {
this.dropdown.toggle();
}
}
toggle(event) {
if (this.disabled || this.dropdown.trigger === 'manually' || event.defaultPrevented) {
return;
}
this.dropdown.toggle();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DropDownToggleDirective, deps: [{ token: DropDownDirective, host: true }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: DropDownToggleDirective, selector: "[dDropDownToggle]", inputs: { toggleOnFocus: "toggleOnFocus", autoFocus: "autoFocus" }, host: { listeners: { "click": "toggleDropdown($event)", "mousedown": "setMouseEventTrue($event)", "mouseup": "setMouseEventFalse($event)", "focus": "toggleOnFocusFn($event)", "keydown.enter": "toggle($event)" }, properties: { "attr.tabIndex": "this.tabIndex", "attr.disabled": "this.attrDisabled", "class.devui-dropdown-toggle": "this.addClass" } }, exportAs: ["d-dropdown-toggle"], ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DropDownToggleDirective, decorators: [{
type: Directive,
args: [{
selector: '[dDropDownToggle]',
exportAs: 'd-dropdown-toggle',
}]
}], ctorParameters: () => [{ type: DropDownDirective, decorators: [{
type: Host
}] }, { type: i0.ElementRef }], propDecorators: { tabIndex: [{
type: HostBinding,
args: ['attr.tabIndex']
}], attrDisabled: [{
type: HostBinding,
args: ['attr.disabled']
}], addClass: [{
type: HostBinding,
args: ['class.devui-dropdown-toggle']
}], toggleOnFocus: [{
type: Input
}], autoFocus: [{
type: Input
}], toggleDropdown: [{
type: HostListener,
args: ['click', ['$event']]
}], setMouseEventTrue: [{
type: HostListener,
args: ['mousedown', ['$event']]
}], setMouseEventFalse: [{
type: HostListener,
args: ['mouseup', ['$event']]
}], toggleOnFocusFn: [{
type: HostListener,
args: ['focus', ['$event']]
}], toggle: [{
type: HostListener,
args: ['keydown.enter', ['$event']]
}] } });
class DropDownAppendToBodyComponent {
constructor(dropDown, scrollStrategyOption, devConfigService) {
this.dropDown = dropDown;
this.scrollStrategyOption = scrollStrategyOption;
this.devConfigService = devConfigService;
this.appendToBodyDirections = ['rightDown', 'leftDown', 'rightUp', 'leftUp'];
this.menuPosition = 'bottom';
this.dropDown.appendToBody = true;
this.scrollStrategy = this.scrollStrategyOption.reposition();
}
ngOnChanges(changes) {
const { alignOrigin, appendToBodyDirections, appendToBodyScrollStrategy } = changes;
const globalScrollStrategy = this.devConfigService.getConfigForApi('appendToBodyScrollStrategy');
if (appendToBodyDirections) {
this.setPositions();
}
if (alignOrigin) {
this.setOrigin();
}
if (this.appendToBodyScrollStrategy && (appendToBodyScrollStrategy || globalScrollStrategy)) {
const func = this.scrollStrategyOption[this.appendToBodyScrollStrategy];
this.scrollStrategy = func();
}
}
ngOnInit() {
this.setPositions();
this.setOrigin();
}
setOrigin() {
if (this.alignOrigin) {
this.origin = new CdkOverlayOrigin(this.alignOrigin);
}
else {
this.origin = undefined;
}
}
setPositions() {
if (this.appendToBodyDirections && this.appendToBodyDirections.length > 0) {
this.positions = this.appendToBodyDirections
.map((position) => {
if (typeof position === 'string') {
return AppendToBodyDirectionsConfig[position];
}
else {
return position;
}
})
.filter((position) => position !== undefined);
}
else {
this.positions = undefined;
}
}
reposition() {
if (this.overlay && this.overlay.overlayRef) {
setTimeout(() => {
this.setPositions();
this.overlay.overlayRef.updatePosition();
}, 0);
}
}
onPositionChange(position) {
switch (position.connectionPair.overlayY) {
case 'top':
case 'center':
this.menuPosition = 'bottom';
break;
case 'bottom':
this.menuPosition = 'top';
break;
default:
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DropDownAppendToBodyComponent, deps: [{ token: DropDownDirective, host: true }, { token: i2$2.ScrollStrategyOptions }, { token: i2.DevConfigService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DropDownAppendToBodyComponent, selector: "[dDropDown][appendToBody]", inputs: { alignOrigin: "alignOrigin", appendToBodyDirections: "appendToBodyDirections", appendToBodyScrollStrategy: "appendToBodyScrollStrategy" }, viewQueries: [{ propertyName: "dropDownWrapper", first: true, predicate: ["dropDownWrapper"], descendants: true }, { propertyName: "overlay", first: true, predicate: CdkConnectedOverlay, descendants: true, static: true }], exportAs: ["d-dropdown-append-to-body"], usesOnChanges: true, ngImport: i0, template: `
<ng-content></ng-content>
<ng-template
cdk-connected-overlay
[cdkConnectedOverlayOrigin]="origin || dropDown.cdkConnectedOverlayOrigin"
[cdkConnectedOverlayOpen]="dropDown.isOpen"
[cdkConnectedOverlayPositions]="positions"
[cdkConnectedOverlayScrollStrategy]="scrollStrategy"
(backdropClick)="dropDown.isOpen = false"
(detach)="dropDown.isOpen && (dropDown.isOpen = false)"
(positionChange)="onPositionChange($event)"
>
<div []="dropDown.startAnimation ? menuPosition : 'void'" #dropDownWrapper [@.disabled]="!dropDown.showAnimation">
<ng-content select="[dDropDownMenu]"></ng-content>
</div>
</ng-template>
`, isInline: true, styles: [".cdk-overlay-pane>div>.devui-dropdown-menu{position:relative;top:0;left:0;border:none}.devui-dropdown span.icon-chevron-down{display:inline-block;vertical-align:text-top}.devui-dropdown span.icon-chevron-down2{display:inline-block;vertical-align:middle}.devui-dropdown-animation span.icon-chevron-down,.devui-dropdown-animation span.icon-chevron-down-2{transition:transform var(--devui-animation-duration-slow, .3s) var(--devui-animation-ease-in-out-smooth, cubic-bezier(.645, .045, .355, 1))}.devui-dropdown.open span.icon-chevron-down,.devui-dropdown.open span.icon-chevron-down-2{transform:rotate(180deg)}\n"], dependencies: [{ kind: "directive", type: i2$2.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }], animations: [fadeInOut], encapsulation: i0.ViewEncapsulation.None }); }
}
__decorate([
WithConfig(),
__metadata("design:type", String)
], DropDownAppendToBodyComponent.prototype, "appendToBodyScrollStrategy", void 0);
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DropDownAppendToBodyComponent, decorators: [{
type: Component,
args: [{ selector: '[dDropDown][appendToBody]', exportAs: 'd-dropdown-append-to-body', template: `
<ng-content></ng-content>
<ng-template
cdk-connected-overlay
[cdkConnectedOverlayOrigin]="origin || dropDown.cdkConnectedOverlayOrigin"
[cdkConnectedOverlayOpen]="dropDown.isOpen"
[cdkConnectedOverlayPositions]="positions"
[cdkConnectedOverlayScrollStrategy]="scrollStrategy"
(backdropClick)="dropDown.isOpen = false"
(detach)="dropDown.isOpen && (dropDown.isOpen = false)"
(positionChange)="onPositionChange($event)"
>
<div []="dropDown.startAnimation ? menuPosition : 'void'" #dropDownWrapper [@.disabled]="!dropDown.showAnimation">
<ng-content select="[dDropDownMenu]"></ng-content>
</div>
</ng-template>
`, encapsulation: ViewEncapsulation.None, animations: [fadeInOut], preserveWhitespaces: false, styles: [".cdk-overlay-pane>div>.devui-dropdown-menu{position:relative;top:0;left:0;border:none}.devui-dropdown span.icon-chevron-down{display:inline-block;vertical-align:text-top}.devui-dropdown span.icon-chevron-down2{display:inline-block;vertical-align:middle}.devui-dropdown-animation span.icon-chevron-down,.devui-dropdown-animation span.icon-chevron-down-2{transition:transform var(--devui-animation-duration-slow, .3s) var(--devui-animation-ease-in-out-smooth, cubic-bezier(.645, .045, .355, 1))}.devui-dropdown.open span.icon-chevron-down,.devui-dropdown.open span.icon-chevron-down-2{transform:rotate(180deg)}\n"] }]
}], ctorParameters: () => [{ type: DropDownDirective, decorators: [{
type: Host
}] }, { type: i2$2.ScrollStrategyOptions }, { type: i2.DevConfigService }], propDecorators: { dropDownWrapper: [{
type: ViewChild,
args: ['dropDownWrapper']
}], overlay: [{
type: ViewChild,
args: [CdkConnectedOverlay, { static: true }]
}], alignOrigin: [{
type: Input
}], appendToBodyDirections: [{
type: Input
}], appendToBodyScrollStrategy: [{
type: Input
}] } });
class DropDownModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DropDownModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: DropDownModule, declarations: [DropDownDirective,
DropDownMenuItemDirective,
DropDownMenuDirective,
DropDownToggleDirective,
DropDownAppendToBodyComponent], imports: [CommonModule, OverlayModule, WindowRefModule], exports: [DropDownDirective, DropDownMenuItemDirective, DropDownMenuDirective, DropDownToggleDirective, DropDownAppendToBodyComponent] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DropDownModule, imports: [CommonModule, OverlayModule, WindowRefModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DropDownModule, decorators: [{
type: NgModule,
args: [{
imports: [CommonModule, OverlayModule, WindowRefModule],
exports: [DropDownDirective, DropDownMenuItemDirective, DropDownMenuDirective, DropDownToggleDirective, DropDownAppendToBodyComponent],
declarations: [
DropDownDirective,
DropDownMenuItemDirective,
DropDownMenuDirective,
DropDownToggleDirective,
DropDownAppendToBodyComponent,
],
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { DropDownAppendToBodyComponent, DropDownDirective, DropDownMenuDirective, DropDownMenuItemDirective, DropDownModule, DropDownService, DropDownToggleDirective };
//# sourceMappingURL=ng-devui-dropdown.mjs.map