ng-devui
Version:
DevUI components based on Angular
585 lines (577 loc) • 33.4 kB
JavaScript
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