UNPKG

ng-devui

Version:

DevUI components based on Angular

585 lines (577 loc) 33.4 kB
import * as i0 from '@angular/core'; import { ElementRef, Component, ViewChildren, EventEmitter, Directive, Optional, Host, Self, Input, Output, HostBinding, HostListener, NgModule } from '@angular/core'; import * as i1 from '@angular/common'; import { CommonModule } from '@angular/common'; import * as i2 from 'ng-devui/loading'; import { LoadingModule } from 'ng-devui/loading'; import { __decorate, __metadata } from 'tslib'; import { ENTER, LEFT_ARROW, RIGHT_ARROW, TAB, ESCAPE, UP_ARROW, DOWN_ARROW } from '@angular/cdk/keycodes'; import * as i2$1 from '@angular/cdk/overlay'; import { ConnectionPositionPair, OverlayConfig } from '@angular/cdk/overlay'; import { ComponentPortal } from '@angular/cdk/portal'; import * as i1$1 from '@angular/forms'; import * as i3 from 'ng-devui/utils'; import { WithConfig } from 'ng-devui/utils'; import { Subject, fromEvent } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; class MentionComponent { constructor() { this.suggestions = []; this.activeIndex = -1; this.loading = false; this.value = ''; this.mentionNotFoundContent = ''; } get focusItemElement() { const itemArr = this.items?.toArray(); if (itemArr && itemArr[this.activeIndex]) { return itemArr[this.activeIndex].nativeElement; } return null; } selectSuggestion(suggestion) { if (this.trigger) { this.trigger.selectSuggestion(suggestion); } } scrollToFocusItem() { if (this.focusItemElement) { this.focusItemElement.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'nearest' }); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MentionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: MentionComponent, selector: "d-mention", viewQueries: [{ propertyName: "items", predicate: ["items"], descendants: true, read: ElementRef }], ngImport: i0, template: "<ul class=\"devui-mention-dropdown\" dLoading [showLoading]=\"loading\" [ngClass]=\"{ 'devui-mention-overlay-top': position === 'top' }\">\n <ng-template\n *ngIf=\"mentionHeaderTemplate\"\n [ngTemplateOutlet]=\"mentionHeaderTemplate\"\n [ngTemplateOutletContext]=\"{ activeIndex: activeIndex, loading: loading }\"\n ></ng-template>\n <li\n #items\n *ngFor=\"let suggestion of suggestions; let i = index\"\n class=\"devui-mention-dropdown-item\"\n [class.focus]=\"i === activeIndex\"\n (click)=\"selectSuggestion(suggestion)\"\n (mousedown)=\"$event.preventDefault()\"\n >\n <ng-container *ngIf=\"mentionItemTemplate; else defaultSuggestion\">\n <ng-container [ngTemplateOutlet]=\"mentionItemTemplate\" [ngTemplateOutletContext]=\"{ $implicit: suggestion }\"></ng-container>\n </ng-container>\n <ng-template #defaultSuggestion>{{ suggestion }}</ng-template>\n </li>\n <li class=\"devui-mention-dropdown-notfound devui-mention-dropdown-item\" *ngIf=\"suggestions.length === 0\">\n <span *ngIf=\"!loading\">{{ mentionNotFoundContent }}</span>\n </li>\n</ul>\n", styles: [".devui-font-size-base{font-size:var(--devui-font-size, 12px)}.devui-font-base{font-size:var(--devui-font-size, 12px);font-weight:var(--devui-font-content-weight, normal);line-height:var(--devui-line-height-base, 1.5)}.devui-font-size-modal-title{font-size:var(--devui-font-size-modal-title, 18px)}.devui-font-modal-title{font-size:var(--devui-font-size-modal-title, 18px);font-weight:var(--devui-font-title-weight, bold);line-height:var(--devui-line-height-base, 1.5)}.devui-font-size-page-title{font-size:var(--devui-font-size-page-title, 16px)}.devui-font-page-title{font-size:var(--devui-font-size-page-title, 16px);font-weight:var(--devui-font-title-weight, bold);line-height:var(--devui-line-height-base, 1.5)}.devui-font-size-secondary-title{font-size:var(--devui-font-size-card-title, 14px)}.devui-font-secondary-title{font-size:var(--devui-font-size-card-title, 14px);font-weight:var(--devui-font-title-weight, bold);line-height:var(--devui-line-height-base, 1.5)}.devui-mention-dropdown{position:absolute;color:var(--devui-text, #191919);z-index:var(--devui-z-index-dropdown, 1052);min-width:120px;max-height:250px;overflow-x:hidden;overflow-y:auto;border-radius:var(--devui-border-radius, 2px);background-color:var(--devui-connected-overlay-bg, #ffffff);box-shadow:var(--devui-shadow-length-base, 0 1px 6px 0) var(--devui-light-shadow, rgba(0, 0, 0, .08));margin-top:16px;box-sizing:border-box;outline:none}.devui-mention-dropdown.devui-mention-overlay-top{transform:translateY(-100%);margin-top:-8px}.devui-mention-dropdown .devui-mention-dropdown-notfound{min-height:34px;line-height:1.5;color:var(--devui-text, #191919);font-size:var(--devui-font-size, 12px);padding:8px 12px;border:0}.devui-mention-dropdown .devui-mention-dropdown-item{font-size:var(--devui-font-size, 12px);display:block;min-height:34px;line-height:1.5;width:100%;padding:8px 12px;clear:both;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;border:0;color:var(--devui-text, #191919);cursor:pointer}.devui-mention-dropdown .devui-mention-dropdown-item:hover{color:var(--devui-list-item-hover-text, #000000);background-color:var(--devui-list-item-hover-bg, #f2f2f3)}.devui-mention-dropdown .devui-mention-dropdown-item.focus{color:var(--devui-list-item-active-text, #000000);background-color:var(--devui-list-item-active-bg, #cedefd)}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.LoadingDirective, selector: "[dLoading]", inputs: ["backdrop", "message", "positionType", "showLoading", "view", "zIndex", "loading", "loadingStyle", "loadingTemplateRef"], exportAs: ["dLoading"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MentionComponent, decorators: [{ type: Component, args: [{ selector: 'd-mention', template: "<ul class=\"devui-mention-dropdown\" dLoading [showLoading]=\"loading\" [ngClass]=\"{ 'devui-mention-overlay-top': position === 'top' }\">\n <ng-template\n *ngIf=\"mentionHeaderTemplate\"\n [ngTemplateOutlet]=\"mentionHeaderTemplate\"\n [ngTemplateOutletContext]=\"{ activeIndex: activeIndex, loading: loading }\"\n ></ng-template>\n <li\n #items\n *ngFor=\"let suggestion of suggestions; let i = index\"\n class=\"devui-mention-dropdown-item\"\n [class.focus]=\"i === activeIndex\"\n (click)=\"selectSuggestion(suggestion)\"\n (mousedown)=\"$event.preventDefault()\"\n >\n <ng-container *ngIf=\"mentionItemTemplate; else defaultSuggestion\">\n <ng-container [ngTemplateOutlet]=\"mentionItemTemplate\" [ngTemplateOutletContext]=\"{ $implicit: suggestion }\"></ng-container>\n </ng-container>\n <ng-template #defaultSuggestion>{{ suggestion }}</ng-template>\n </li>\n <li class=\"devui-mention-dropdown-notfound devui-mention-dropdown-item\" *ngIf=\"suggestions.length === 0\">\n <span *ngIf=\"!loading\">{{ mentionNotFoundContent }}</span>\n </li>\n</ul>\n", styles: [".devui-font-size-base{font-size:var(--devui-font-size, 12px)}.devui-font-base{font-size:var(--devui-font-size, 12px);font-weight:var(--devui-font-content-weight, normal);line-height:var(--devui-line-height-base, 1.5)}.devui-font-size-modal-title{font-size:var(--devui-font-size-modal-title, 18px)}.devui-font-modal-title{font-size:var(--devui-font-size-modal-title, 18px);font-weight:var(--devui-font-title-weight, bold);line-height:var(--devui-line-height-base, 1.5)}.devui-font-size-page-title{font-size:var(--devui-font-size-page-title, 16px)}.devui-font-page-title{font-size:var(--devui-font-size-page-title, 16px);font-weight:var(--devui-font-title-weight, bold);line-height:var(--devui-line-height-base, 1.5)}.devui-font-size-secondary-title{font-size:var(--devui-font-size-card-title, 14px)}.devui-font-secondary-title{font-size:var(--devui-font-size-card-title, 14px);font-weight:var(--devui-font-title-weight, bold);line-height:var(--devui-line-height-base, 1.5)}.devui-mention-dropdown{position:absolute;color:var(--devui-text, #191919);z-index:var(--devui-z-index-dropdown, 1052);min-width:120px;max-height:250px;overflow-x:hidden;overflow-y:auto;border-radius:var(--devui-border-radius, 2px);background-color:var(--devui-connected-overlay-bg, #ffffff);box-shadow:var(--devui-shadow-length-base, 0 1px 6px 0) var(--devui-light-shadow, rgba(0, 0, 0, .08));margin-top:16px;box-sizing:border-box;outline:none}.devui-mention-dropdown.devui-mention-overlay-top{transform:translateY(-100%);margin-top:-8px}.devui-mention-dropdown .devui-mention-dropdown-notfound{min-height:34px;line-height:1.5;color:var(--devui-text, #191919);font-size:var(--devui-font-size, 12px);padding:8px 12px;border:0}.devui-mention-dropdown .devui-mention-dropdown-item{font-size:var(--devui-font-size, 12px);display:block;min-height:34px;line-height:1.5;width:100%;padding:8px 12px;clear:both;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;border:0;color:var(--devui-text, #191919);cursor:pointer}.devui-mention-dropdown .devui-mention-dropdown-item:hover{color:var(--devui-list-item-hover-text, #000000);background-color:var(--devui-list-item-hover-bg, #f2f2f3)}.devui-mention-dropdown .devui-mention-dropdown-item.focus{color:var(--devui-list-item-active-text, #000000);background-color:var(--devui-list-item-active-bg, #cedefd)}\n"] }] }], propDecorators: { items: [{ type: ViewChildren, args: ['items', { read: ElementRef }] }] } }); /** * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ const POSITION_MAP = { top: new ConnectionPositionPair({ originX: 'center', originY: 'top' }, { overlayX: 'center', overlayY: 'bottom' }), topCenter: new ConnectionPositionPair({ originX: 'center', originY: 'top' }, { overlayX: 'center', overlayY: 'bottom' }), topLeft: new ConnectionPositionPair({ originX: 'start', originY: 'top' }, { overlayX: 'start', overlayY: 'bottom' }), topRight: new ConnectionPositionPair({ originX: 'end', originY: 'top' }, { overlayX: 'end', overlayY: 'bottom' }), right: new ConnectionPositionPair({ originX: 'end', originY: 'center' }, { overlayX: 'start', overlayY: 'center' }), rightTop: new ConnectionPositionPair({ originX: 'end', originY: 'top' }, { overlayX: 'start', overlayY: 'top' }), rightBottom: new ConnectionPositionPair({ originX: 'end', originY: 'bottom' }, { overlayX: 'start', overlayY: 'bottom' }), bottom: new ConnectionPositionPair({ originX: 'center', originY: 'bottom' }, { overlayX: 'center', overlayY: 'top' }), bottomCenter: new ConnectionPositionPair({ originX: 'center', originY: 'bottom' }, { overlayX: 'center', overlayY: 'top' }), bottomLeft: new ConnectionPositionPair({ originX: 'start', originY: 'bottom' }, { overlayX: 'start', overlayY: 'top' }), bottomRight: new ConnectionPositionPair({ originX: 'end', originY: 'bottom' }, { overlayX: 'end', overlayY: 'top' }), left: new ConnectionPositionPair({ originX: 'start', originY: 'center' }, { overlayX: 'end', overlayY: 'center' }), leftTop: new ConnectionPositionPair({ originX: 'start', originY: 'top' }, { overlayX: 'end', overlayY: 'top' }), leftBottom: new ConnectionPositionPair({ originX: 'start', originY: 'bottom' }, { overlayX: 'end', overlayY: 'bottom' }) }; const DEFAULT_TOOLTIP_POSITIONS = [POSITION_MAP.top, POSITION_MAP.right, POSITION_MAP.bottom, POSITION_MAP.left]; const DEFAULT_CASCADER_POSITIONS = [POSITION_MAP.bottomLeft, POSITION_MAP.bottomRight, POSITION_MAP.topLeft, POSITION_MAP.topRight]; const DEFAULT_MENTION_TOP_POSITIONS = [ new ConnectionPositionPair({ originX: 'start', originY: 'bottom' }, { overlayX: 'start', overlayY: 'bottom' }), new ConnectionPositionPair({ originX: 'start', originY: 'bottom' }, { overlayX: 'end', overlayY: 'bottom' }) ]; const DEFAULT_MENTION_BOTTOM_POSITIONS = [ POSITION_MAP.bottomLeft, new ConnectionPositionPair({ originX: 'start', originY: 'bottom' }, { overlayX: 'end', overlayY: 'top' }) ]; function getPlacementName(position) { for (const placement in POSITION_MAP) { if (position.connectionPair.originX === POSITION_MAP[placement].originX && position.connectionPair.originY === POSITION_MAP[placement].originY && position.connectionPair.overlayX === POSITION_MAP[placement].overlayX && position.connectionPair.overlayY === POSITION_MAP[placement].overlayY) { return placement; } } return undefined; } const properties = [ 'direction', // RTL support 'boxSizing', 'width', // on Chrome and IE, exclude the scrollbar, so the mirror div wraps exactly as the textarea does 'height', 'overflowX', 'overflowY', 'borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth', 'borderStyle', 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft', 'fontStyle', 'fontVariant', 'fontWeight', 'fontStretch', 'fontSize', 'fontSizeAdjust', 'lineHeight', 'fontFamily', 'textAlign', 'textTransform', 'textIndent', 'textDecoration', 'letterSpacing', 'wordSpacing', 'tabSize', 'MozTabSize', ]; const isBrowser = typeof window !== 'undefined'; const isFirefox = isBrowser && window.mozInnerScreenX !== undefined; function _parseInt(value) { return parseInt(value, 10); } function getCaretCoordinates(element, position, options) { if (!isBrowser) { throw new Error('textarea-caret-position#getCaretCoordinates should only be called in a browser'); } // isDebugMode 调试模式,用来定位光标位置的 const isDebugMode = (options && options.isDebugMode) || false; if (isDebugMode) { const el = document.querySelector('#input-textarea-caret-position-mirror-div'); if (el) { el.parentNode.removeChild(el); } } const div = document.createElement('div'); div.id = 'input-textarea-caret-position-mirror-div'; document.body.appendChild(div); const style = div.style; const computed = window.getComputedStyle ? window.getComputedStyle(element) : element.currentStyle; const isInput = element.nodeName === 'INPUT'; style.whiteSpace = 'pre-wrap'; if (!isInput) { style.wordWrap = 'break-word'; } style.position = 'absolute'; if (!isDebugMode) { style.visibility = 'hidden'; } properties.forEach((prop) => { if (isInput && prop === 'lineHeight') { if (computed.boxSizing === 'border-box') { const height = _parseInt(computed.height); const outerHeight = _parseInt(computed.paddingTop) + _parseInt(computed.paddingBottom) + _parseInt(computed.borderTopWidth) + _parseInt(computed.borderBottomWidth); const targetHeight = outerHeight + _parseInt(computed.lineHeight); if (height > targetHeight) { style.lineHeight = height - outerHeight + 'px'; } else if (height === targetHeight) { style.lineHeight = computed.lineHeight; } else { style.lineHeight = '0'; } } else { style.lineHeight = computed.height; } } else { style[prop] = computed[prop]; } }); if (isFirefox) { if (element.scrollHeight > _parseInt(computed.height)) { style.overflowY = 'scroll'; } } else { style.overflow = 'hidden'; } div.textContent = element.value.substring(0, position); if (isInput) { div.textContent = div.textContent.replace(/\s/g, '\u00a0'); } const span = document.createElement('span'); span.textContent = element.value.substring(position) || '.'; div.appendChild(span); const coordinates = { top: span.offsetTop + _parseInt(computed.borderTopWidth), left: span.offsetLeft + _parseInt(computed.borderLeftWidth), height: _parseInt(computed.lineHeight), }; if (isDebugMode) { span.style.backgroundColor = '#aaa'; } else { document.body.removeChild(div); } return coordinates; } function getRegExp(prefix) { const prefixArray = Array.isArray(prefix) ? prefix : [prefix]; let prefixToken = prefixArray.join('').replace(/(\$|\^)/g, '\\$1'); if (prefixArray.length > 1) { prefixToken = `[${prefixToken}]`; } return new RegExp(`(\\s|^)(${prefixToken})[^\\s]*`, 'g'); } function getMentions(value, prefix = '@') { if (typeof value !== 'string') { return []; } const regex = getRegExp(prefix); const mentions = value.match(regex); return mentions !== null ? mentions.map((e) => e.trim()) : []; } class MentionDirective { get hasGlowStyle() { return this.showGlowStyle; } get nativeElement() { return this.el.nativeElement; } constructor(ngModelInstance, el, viewContainerRef, cdr, overlay, devConfigService) { this.ngModelInstance = ngModelInstance; this.el = el; this.viewContainerRef = viewContainerRef; this.cdr = cdr; this.overlay = overlay; this.devConfigService = devConfigService; this.mentionNotFoundContent = 'No suggestion matched'; this.mentionSuggestions = []; this.mentionLoading = false; this.mentionTrigger = ['@']; this.mentionSeparator = ' '; this.mentionSeparatorToggle = { prefix: false, suffix: false }; this.mentionPosition = 'bottom'; this.endWithCursorPos = false; this.mentionValueParse = (value) => value; this.mentionSelectItem = new EventEmitter(); this.mentionSearchChange = new EventEmitter(); this.mentionAfterMentionInit = new EventEmitter(); this.showGlowStyle = true; this.isOpen = false; this.activeIndex = -1; this.unsubscribe$ = new Subject(); this.defaultNotFoundText = ''; this.value = ''; this.previousValue = ''; this.overlayRef = null; this.filterSuggestions = []; } onKeyDown(event) { if (this.mentionRef) { const keyCode = event.keyCode; if (this.isOpen && keyCode === ENTER && this.activeIndex !== -1 && this.filterSuggestions.length) { this.selectSuggestion(this.filterSuggestions[this.activeIndex]); event.preventDefault(); } else if (keyCode === LEFT_ARROW || keyCode === RIGHT_ARROW) { if (keyCode === LEFT_ARROW) { this.cursorMentionStart = this.cursorMentionStart - 1; } else { this.cursorMentionStart = this.cursorMentionStart + 1; } event.stopPropagation(); setTimeout(() => { this.resetMention(); }); } else { if (this.isOpen && (keyCode === TAB || keyCode === ESCAPE)) { this.hideMention(); return; } if (this.isOpen && keyCode === UP_ARROW) { event.preventDefault(); event.stopPropagation(); this.setPreviousItemActive(); } if (this.isOpen && keyCode === DOWN_ARROW) { event.preventDefault(); event.stopPropagation(); this.setNextItemActive(); } } this.setMentionData(); } } onClick(e) { if (this.overlayRef && this.isOpen) { if (!this.nativeElement.contains(e.target)) { this.hideMention(); } } else if (this.nativeElement.contains(e.target)) { this.resetMention(); } } ngOnChanges(changes) { const { mentionSuggestions } = changes; if (mentionSuggestions && this.isOpen) { this.previousValue = null; this.activeIndex = -1; this.resetMention(false); } } ngOnInit() { this.mentionAfterMentionInit.emit(this); } ngAfterViewInit() { fromEvent(this.el.nativeElement, 'input') .pipe(debounceTime(300)) .subscribe(() => { this.resetMention(); }); } ngOnDestroy() { if (this.overlayRef) { this.overlayRef.dispose(); } } resetMention(emit = true) { this.checkMention(); if (!this.cursorMention) { this.hideMention(); return; } this.suggestionsFilter(this.cursorMention, emit); if (this.mentionSeparatorToggle.suffix || (this.filterSuggestions.length && !this.mentionSeparatorToggle.suffix)) { const activeIndex = this.filterSuggestions.indexOf(this.value); this.activeIndex = activeIndex >= 0 ? activeIndex : 0; this.showMention(); } else if (this.mentionLoading) { this.showMention(); } else { this.hideMention(); } } checkMention() { const value = this.nativeElement.value.replace(/[\r\n]/g, this.mentionSeparator) || ''; const selectionStart = this.nativeElement.selectionStart; let i = this.mentionTrigger.length; while (i >= 0) { const startPos = value.lastIndexOf(this.mentionTrigger[i], selectionStart); const resPos = value.indexOf(this.mentionSeparator, selectionStart) > -1 ? value.indexOf(this.mentionSeparator, selectionStart) : value.length; const endPos = this.endWithCursorPos ? selectionStart : resPos; const mention = value.substring(startPos, selectionStart); if ((this.mentionSeparatorToggle.prefix && startPos > 0 && value[startPos - 1] !== this.mentionSeparator) || startPos < 0 || mention.includes(this.mentionTrigger[i], 1) || (this.mentionSeparatorToggle.suffix && mention.includes(this.mentionSeparator))) { this.cursorMention = null; this.cursorMentionStart = -1; this.cursorMentionEnd = -1; this.cursorEnd = -1; this.value = ''; } else { this.cursorMention = mention[0]; this.cursorMentionStart = startPos; this.cursorMentionEnd = endPos; this.cursorEnd = selectionStart; this.value = mention.slice(1); return; } i--; } } hideMention() { if (this.overlayRef && this.overlayRef.hasAttached()) { this.overlayRef.detach(); this.cdr.markForCheck(); this.isOpen = false; } } showMention() { this.attachOverlay(); this.isOpen = true; this.cdr.markForCheck(); } attachOverlay() { if (!this.overlayRef) { this.portal = new ComponentPortal(MentionComponent, this.viewContainerRef); this.overlayRef = this.overlay.create(this.getOverlayConfig()); } if (this.overlayRef && !this.overlayRef.hasAttached()) { this.mentionRef = this.overlayRef.attach(this.portal); this.mentionRef.instance.mentionHeaderTemplate = this.mentionHeaderTemplate; this.mentionRef.instance.mentionItemTemplate = this.mentionItemTemplate; this.mentionRef.instance.mentionNotFoundContent = this.mentionNotFoundContent; } this.updatePositions(); } getOverlayConfig() { const target = this.el; return new OverlayConfig({ positionStrategy: this.getOverlayPosition(target), scrollStrategy: this.overlay.scrollStrategies.reposition(), disposeOnNavigation: true, }); } getOverlayPosition(target) { const positions = [ new ConnectionPositionPair({ originX: 'start', originY: 'bottom' }, { overlayX: 'start', overlayY: 'top' }), new ConnectionPositionPair({ originX: 'start', originY: 'top' }, { overlayX: 'start', overlayY: 'bottom' }), ]; this.positionStrategy = this.overlay .position() .flexibleConnectedTo(target) .withPositions(positions) .withFlexibleDimensions(false) .withPush(false); return this.positionStrategy; } updatePositions() { const coordinates = getCaretCoordinates(this.nativeElement, this.cursorEnd); const top = coordinates.top - this.nativeElement.getBoundingClientRect().height - this.nativeElement.scrollTop; const left = coordinates.left - this.nativeElement.scrollLeft; this.positionStrategy.withDefaultOffsetX(left).withDefaultOffsetY(top); this.positionStrategy.withPositions([...DEFAULT_MENTION_BOTTOM_POSITIONS]); this.positionStrategy.apply(); this.setMentionData(); } suggestionsFilter(value, emit) { if (this.previousValue === value && value !== this.cursorMention[0]) { return; } this.previousValue = value; if (emit) { this.mentionSearchChange.emit({ value: this.value, trigger: this.cursorMention, }); } const searchValue = this.value.toLowerCase(); this.filterSuggestions = this.mentionSuggestions.filter((suggestion) => this.mentionValueParse(suggestion).toLowerCase().includes(searchValue)); } setMentionData() { Object.assign(this.mentionRef.instance, { suggestions: this.filterSuggestions, activeIndex: this.activeIndex, loading: this.mentionLoading, trigger: this, position: this.mentionPosition, }); } selectSuggestion(suggestion) { const value = this.mentionValueParse(suggestion); this.insertMention({ mention: value, startPos: this.cursorMentionStart, endPos: this.cursorMentionEnd, }); this.mentionSelectItem.emit(suggestion); this.hideMention(); this.activeIndex = -1; } insertMention(mention) { const value = this.el.nativeElement.value; const insertValue = `${mention.mention.trim()}${this.mentionSeparatorToggle.suffix ? this.mentionSeparator : ''}`; const newValue = [value.slice(0, mention.startPos + 1), insertValue, value.slice(mention.endPos, value.length)].join(''); this.el.nativeElement.value = newValue; this.value = newValue; if (this.ngModelInstance) { this.ngModelInstance.control.setValue(newValue); } } setPreviousItemActive() { this.activeIndex = this.activeIndex - 1 < 0 ? this.filterSuggestions.length - 1 : this.activeIndex - 1; this.cdr.markForCheck(); setTimeout(() => { if (this.mentionRef) { this.mentionRef.instance.scrollToFocusItem(); } }); } setNextItemActive() { this.activeIndex = this.activeIndex + 1 <= this.filterSuggestions.length - 1 ? this.activeIndex + 1 : 0; this.cdr.markForCheck(); setTimeout(() => { if (this.mentionRef) { this.mentionRef.instance.scrollToFocusItem(); } }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MentionDirective, deps: [{ token: i1$1.NgModel, host: true, optional: true, self: true }, { token: i0.ElementRef }, { token: i0.ViewContainerRef }, { token: i0.ChangeDetectorRef }, { token: i2$1.Overlay }, { token: i3.DevConfigService }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: MentionDirective, selector: "[dMention]", inputs: { mentionNotFoundContent: "mentionNotFoundContent", mentionSuggestions: "mentionSuggestions", mentionLoading: "mentionLoading", mentionTrigger: "mentionTrigger", mentionSeparator: "mentionSeparator", mentionSeparatorToggle: "mentionSeparatorToggle", mentionPosition: "mentionPosition", mentionHeaderTemplate: "mentionHeaderTemplate", mentionItemTemplate: "mentionItemTemplate", endWithCursorPos: "endWithCursorPos", mentionValueParse: "mentionValueParse", showGlowStyle: "showGlowStyle" }, outputs: { mentionSelectItem: "mentionSelectItem", mentionSearchChange: "mentionSearchChange", mentionAfterMentionInit: "mentionAfterMentionInit" }, host: { listeners: { "keydown": "onKeyDown($event)", "document:click": "onClick($event)" }, properties: { "class.devui-glow-style": "this.hasGlowStyle" } }, exportAs: ["dMention"], usesOnChanges: true, ngImport: i0 }); } } __decorate([ WithConfig(), __metadata("design:type", Object) ], MentionDirective.prototype, "showGlowStyle", void 0); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MentionDirective, decorators: [{ type: Directive, args: [{ selector: '[dMention]', exportAs: 'dMention', }] }], ctorParameters: () => [{ type: i1$1.NgModel, decorators: [{ type: Optional }, { type: Host }, { type: Self }] }, { type: i0.ElementRef }, { type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }, { type: i2$1.Overlay }, { type: i3.DevConfigService }], propDecorators: { mentionNotFoundContent: [{ type: Input }], mentionSuggestions: [{ type: Input }], mentionLoading: [{ type: Input }], mentionTrigger: [{ type: Input }], mentionSeparator: [{ type: Input }], mentionSeparatorToggle: [{ type: Input }], mentionPosition: [{ type: Input }], mentionHeaderTemplate: [{ type: Input }], mentionItemTemplate: [{ type: Input }], endWithCursorPos: [{ type: Input }], mentionValueParse: [{ type: Input }], mentionSelectItem: [{ type: Output }], mentionSearchChange: [{ type: Output }], mentionAfterMentionInit: [{ type: Output }], showGlowStyle: [{ type: Input }], hasGlowStyle: [{ type: HostBinding, args: ['class.devui-glow-style'] }], onKeyDown: [{ type: HostListener, args: ['keydown', ['$event']] }], onClick: [{ type: HostListener, args: ['document:click', ['$event']] }] } }); class MentionModule { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MentionModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: MentionModule, declarations: [MentionComponent, MentionDirective], imports: [CommonModule, LoadingModule], exports: [MentionComponent, MentionDirective] }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MentionModule, imports: [CommonModule, LoadingModule] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MentionModule, decorators: [{ type: NgModule, args: [{ imports: [CommonModule, LoadingModule], declarations: [MentionComponent, MentionDirective], exports: [MentionComponent, MentionDirective], }] }] }); /** * Generated bundle index. Do not edit. */ export { DEFAULT_CASCADER_POSITIONS, DEFAULT_MENTION_BOTTOM_POSITIONS, DEFAULT_MENTION_TOP_POSITIONS, DEFAULT_TOOLTIP_POSITIONS, MentionComponent, MentionDirective, MentionModule, POSITION_MAP, getCaretCoordinates, getMentions, getPlacementName, getRegExp }; //# sourceMappingURL=ng-devui-mention.mjs.map