update(mention): remove static fun
This commit is contained in:
parent
5243387a10
commit
688bdb3dde
|
@ -16,7 +16,7 @@ type Config = Array<{
|
|||
items: Array<Omit<CollapseItemProps, 'engine'> | string>;
|
||||
}>;
|
||||
export interface ToolbarOptions extends PluginOptions {
|
||||
config: Config;
|
||||
config?: Config;
|
||||
popup?: {
|
||||
items: GroupItemProps[];
|
||||
};
|
||||
|
|
|
@ -20,7 +20,7 @@ type Config = Array<{
|
|||
items: Array<Omit<CollapseItemProps, 'engine'> | string>;
|
||||
}>;
|
||||
export interface ToolbarOptions extends PluginOptions {
|
||||
config: Config;
|
||||
config?: Config;
|
||||
popup?: {
|
||||
items: GroupItemProps[];
|
||||
};
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
unescape,
|
||||
escape,
|
||||
} from '@aomao/engine';
|
||||
import { MentionItem } from '../types';
|
||||
import { MentionItem, MentionOptions } from '../types';
|
||||
|
||||
export type Options = {
|
||||
onCancel?: () => void;
|
||||
|
@ -34,35 +34,24 @@ class CollapseComponent implements CollapseComponentInterface {
|
|||
private readonly SCOPE_NAME = 'data-mention-component';
|
||||
#position?: Position;
|
||||
#scrollbar?: Scrollbar;
|
||||
static renderItem?: (
|
||||
item: MentionItem,
|
||||
root: NodeInterface,
|
||||
) => string | NodeInterface | void;
|
||||
|
||||
static renderEmpty: (root: NodeInterface) => string | NodeInterface | void =
|
||||
renderEmpty: (root: NodeInterface) => string | NodeInterface | void =
|
||||
() => {
|
||||
return `<div class="data-mention-item"><span class="data-mention-item-text">Empty Data</span></div>`;
|
||||
};
|
||||
|
||||
static renderLoading?: (
|
||||
root: NodeInterface,
|
||||
) => string | NodeInterface | void;
|
||||
|
||||
static render?: (
|
||||
root: NodeInterface,
|
||||
data: MentionItem[],
|
||||
bindItem: (
|
||||
node: NodeInterface,
|
||||
data: { [key: string]: string },
|
||||
) => NodeInterface,
|
||||
) => Promise<string | NodeInterface | void>;
|
||||
|
||||
constructor(engine: EngineInterface, options: Options) {
|
||||
this.otpions = options;
|
||||
this.engine = engine;
|
||||
this.#position = new Position(this.engine);
|
||||
}
|
||||
|
||||
getPluginOptions = () => {
|
||||
const mentionOptions =
|
||||
this.engine.plugin.findPlugin<MentionOptions>('mention');
|
||||
return mentionOptions?.options;
|
||||
};
|
||||
|
||||
handlePreventDefault = (event: Event) => {
|
||||
// Card已被删除
|
||||
if (this.root?.closest('body').length !== 0) {
|
||||
|
@ -231,21 +220,23 @@ class CollapseComponent implements CollapseComponentInterface {
|
|||
|
||||
let body = this.getBody();
|
||||
let result = null;
|
||||
|
||||
const options = this.getPluginOptions();
|
||||
if (typeof data === 'boolean' && data === true) {
|
||||
result = CollapseComponent.renderLoading
|
||||
? CollapseComponent.renderLoading(this.root)
|
||||
result = options?.onLoading
|
||||
? options.onLoading(this.root)
|
||||
: this.engine.trigger('mention:loading', this.root);
|
||||
body = this.getBody();
|
||||
if (result) body?.append(result);
|
||||
} else if (data.filter((item) => !!item.key).length === 0) {
|
||||
const result =
|
||||
this.engine.trigger('mention:empty', this.root) ||
|
||||
CollapseComponent.renderEmpty(this.root);
|
||||
(options?.onEmpty
|
||||
? options?.onEmpty(this.root)
|
||||
: this.renderEmpty(this.root));
|
||||
body = this.getBody();
|
||||
if (result) body?.append(result);
|
||||
} else if (
|
||||
CollapseComponent.render ||
|
||||
options?.onRender ||
|
||||
(result = this.engine.trigger(
|
||||
'mention:render',
|
||||
this.root,
|
||||
|
@ -253,8 +244,8 @@ class CollapseComponent implements CollapseComponentInterface {
|
|||
this.bindItem,
|
||||
))
|
||||
) {
|
||||
(CollapseComponent.render
|
||||
? CollapseComponent.render(this.root, data, this.bindItem)
|
||||
(options?.onRender
|
||||
? options.onRender(this.root, data, this.bindItem)
|
||||
: result
|
||||
).then((content: any) => {
|
||||
const body = this.getBody();
|
||||
|
@ -276,8 +267,8 @@ class CollapseComponent implements CollapseComponentInterface {
|
|||
);
|
||||
const result = triggerResult
|
||||
? triggerResult
|
||||
: CollapseComponent.renderItem
|
||||
? CollapseComponent.renderItem(data, this.root!)
|
||||
: options?.renderItem
|
||||
? options.renderItem(data, this.root!)
|
||||
: this.renderTemplate(data);
|
||||
if (!result) return;
|
||||
|
||||
|
|
|
@ -9,14 +9,14 @@ import {
|
|||
Position,
|
||||
DATA_ELEMENT,
|
||||
UI,
|
||||
CardInterface,
|
||||
SelectStyleType,
|
||||
CardValue,
|
||||
AjaxInterface,
|
||||
} from '@aomao/engine';
|
||||
import CollapseComponent, { CollapseComponentInterface } from './collapse';
|
||||
import { MentionItem } from '../types';
|
||||
import './index.css';
|
||||
1;
|
||||
import { MentionOptions } from '../types';
|
||||
export interface MentionValue extends CardValue {
|
||||
key?: string;
|
||||
name?: string;
|
||||
|
@ -32,6 +32,7 @@ class Mention<T extends MentionValue = MentionValue> extends Card<T> {
|
|||
#showTimeout?: NodeJS.Timeout;
|
||||
#hideTimeout?: NodeJS.Timeout;
|
||||
#enterLayout?: NodeInterface;
|
||||
#request?: AjaxInterface;
|
||||
|
||||
static get cardName() {
|
||||
return 'mention';
|
||||
|
@ -49,88 +50,41 @@ class Mention<T extends MentionValue = MentionValue> extends Card<T> {
|
|||
return SelectStyleType.NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认数据
|
||||
*/
|
||||
static defaultData?: Array<MentionItem>;
|
||||
getPluginOptions = () => {
|
||||
const mentionOptions =
|
||||
this.editor.plugin.findPlugin<MentionOptions>('mention');
|
||||
return mentionOptions?.options;
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询
|
||||
* @param keyword 关键字
|
||||
* @returns
|
||||
*/
|
||||
static search(keyword: string) {
|
||||
return new Promise<Array<MentionItem>>((resolve) => {
|
||||
resolve([]);
|
||||
search = (keyword: string): Promise<MentionItem[]> => {
|
||||
const options = this.getPluginOptions();
|
||||
if (options && options.onSearch) return options.onSearch(keyword);
|
||||
const reuslt = this.editor.trigger('mention:search', keyword);
|
||||
if (reuslt !== undefined) return reuslt;
|
||||
const { request } = this.editor;
|
||||
return new Promise((resolve) => {
|
||||
if (options?.action) {
|
||||
const { type, contentType, parse } = options;
|
||||
this.#request?.abort();
|
||||
this.#request = request.ajax({
|
||||
url: options.action,
|
||||
contentType: contentType || '',
|
||||
type: type === undefined ? 'json' : type,
|
||||
data: {
|
||||
keyword,
|
||||
},
|
||||
success: (response: any) => {
|
||||
const { result, data } = parse
|
||||
? parse(response)
|
||||
: response;
|
||||
if (!result) return;
|
||||
resolve(data);
|
||||
},
|
||||
method: 'GET',
|
||||
});
|
||||
} else resolve([]);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 单击
|
||||
* @param key
|
||||
* @param name
|
||||
*/
|
||||
static itemClick?: (
|
||||
node: NodeInterface,
|
||||
data: { [key: string]: any },
|
||||
) => void;
|
||||
|
||||
/**
|
||||
* 鼠标移入
|
||||
* @param node
|
||||
* @param key
|
||||
* @param name
|
||||
*/
|
||||
static mouseEnter?: (
|
||||
node: NodeInterface,
|
||||
data: { [key: string]: any },
|
||||
) => void;
|
||||
|
||||
/**
|
||||
* 自定义渲染列表
|
||||
* @param root 根节点
|
||||
*/
|
||||
static set render(
|
||||
fun: (
|
||||
root: NodeInterface,
|
||||
data: MentionItem[],
|
||||
bindItem: (
|
||||
node: NodeInterface,
|
||||
data: { [key: string]: any },
|
||||
) => NodeInterface,
|
||||
) => Promise<string | NodeInterface | void>,
|
||||
) {
|
||||
CollapseComponent.render = fun;
|
||||
}
|
||||
|
||||
static onSelect?: (data: {
|
||||
[key: string]: any;
|
||||
}) => void | { [key: string]: any };
|
||||
|
||||
static onInsert?: (card: CardInterface) => void;
|
||||
|
||||
/**
|
||||
* 自定义渲染列表项
|
||||
* @param item 数据项
|
||||
*/
|
||||
static set renderItem(
|
||||
fun: (
|
||||
item: MentionItem,
|
||||
root: NodeInterface,
|
||||
) => string | NodeInterface | void,
|
||||
) {
|
||||
CollapseComponent.renderItem = fun;
|
||||
}
|
||||
|
||||
static renderLoading?: (
|
||||
root: NodeInterface,
|
||||
) => string | NodeInterface | void;
|
||||
|
||||
static set renderEmpty(
|
||||
fun: (root: NodeInterface) => string | NodeInterface | void,
|
||||
) {
|
||||
CollapseComponent.renderEmpty = fun;
|
||||
}
|
||||
};
|
||||
|
||||
init() {
|
||||
if (!this.#position) this.#position = new Position(this.editor);
|
||||
|
@ -139,6 +93,7 @@ class Mention<T extends MentionValue = MentionValue> extends Card<T> {
|
|||
}
|
||||
super.init();
|
||||
if (this.component) return;
|
||||
const options = this.getPluginOptions();
|
||||
this.component = new CollapseComponent(this.editor, {
|
||||
onCancel: () => {
|
||||
this.changeToText();
|
||||
|
@ -147,8 +102,8 @@ class Mention<T extends MentionValue = MentionValue> extends Card<T> {
|
|||
let newValue =
|
||||
this.editor.trigger('mention:select', data) || {};
|
||||
delete newValue['id'];
|
||||
if (Mention.onSelect) {
|
||||
newValue = Mention.onSelect(data) || {};
|
||||
if (options?.onSelect) {
|
||||
newValue = options.onSelect(data) || {};
|
||||
delete newValue['id'];
|
||||
}
|
||||
const { card } = this.editor;
|
||||
|
@ -164,7 +119,7 @@ class Mention<T extends MentionValue = MentionValue> extends Card<T> {
|
|||
});
|
||||
card.removeNode(this);
|
||||
this.editor.trigger('mention:insert', component);
|
||||
if (Mention.onInsert) Mention.onInsert(component);
|
||||
if (options?.onInsert) options.onInsert(component);
|
||||
card.focus(component, false);
|
||||
},
|
||||
});
|
||||
|
@ -215,17 +170,20 @@ class Mention<T extends MentionValue = MentionValue> extends Card<T> {
|
|||
const keyword = content.substr(1);
|
||||
// 搜索关键词为空
|
||||
const defaultData =
|
||||
this.editor.trigger('mention:default') || Mention.defaultData;
|
||||
this.editor.trigger<MentionItem[]>('mention:default') ||
|
||||
this.getPluginOptions()?.defaultData;
|
||||
if (keyword === '' && defaultData) {
|
||||
this.component?.render(this.root, defaultData);
|
||||
return;
|
||||
}
|
||||
// if (Mention.renderLoading) {
|
||||
CollapseComponent.renderLoading = Mention.renderLoading;
|
||||
|
||||
this.component?.render(this.root, true);
|
||||
CollapseComponent.renderLoading = undefined;
|
||||
// }
|
||||
Mention.search(keyword).then((data) => {
|
||||
|
||||
const reuslt = this.editor.trigger('mention:search', keyword);
|
||||
if (reuslt !== undefined) {
|
||||
reuslt;
|
||||
}
|
||||
this.search(keyword).then((data) => {
|
||||
this.component?.render(this.root, data);
|
||||
});
|
||||
}
|
||||
|
@ -244,7 +202,8 @@ class Mention<T extends MentionValue = MentionValue> extends Card<T> {
|
|||
};
|
||||
|
||||
showEnter = () => {
|
||||
if (!this.#container || !Mention.mouseEnter) return;
|
||||
const options = this.getPluginOptions();
|
||||
if (!this.#container || !options?.mouseEnter) return;
|
||||
const value = this.getValue();
|
||||
if (!value?.name) return;
|
||||
const { id, key, name, ...info } = value;
|
||||
|
@ -265,7 +224,7 @@ class Mention<T extends MentionValue = MentionValue> extends Card<T> {
|
|||
name: unescape(name),
|
||||
...info,
|
||||
});
|
||||
Mention.mouseEnter!(this.#enterLayout, {
|
||||
options?.mouseEnter!(this.#enterLayout, {
|
||||
key: unescape(key || ''),
|
||||
name: unescape(name),
|
||||
...info,
|
||||
|
@ -340,8 +299,8 @@ class Mention<T extends MentionValue = MentionValue> extends Card<T> {
|
|||
name: unescape(name),
|
||||
...info,
|
||||
});
|
||||
if (Mention.itemClick)
|
||||
Mention.itemClick(this.#container, {
|
||||
if (options?.itemClick)
|
||||
options?.itemClick(this.#container, {
|
||||
key: unescape(key || ''),
|
||||
name: unescape(name),
|
||||
...info,
|
||||
|
@ -366,6 +325,7 @@ class Mention<T extends MentionValue = MentionValue> extends Card<T> {
|
|||
}
|
||||
const language = this.editor.language.get('mention');
|
||||
let timeout: NodeJS.Timeout | undefined = undefined;
|
||||
const options = this.getPluginOptions();
|
||||
// 没有值的情况下,弹出下拉框编辑模式
|
||||
if (!this.#container) {
|
||||
this.#container = $(
|
||||
|
@ -413,12 +373,12 @@ class Mention<T extends MentionValue = MentionValue> extends Card<T> {
|
|||
this.component?.render(
|
||||
this.root,
|
||||
this.editor.trigger('mention:default') ||
|
||||
Mention.defaultData ||
|
||||
options?.defaultData ||
|
||||
[],
|
||||
);
|
||||
if (
|
||||
!(Mention.defaultData
|
||||
? Mention.defaultData
|
||||
!(options?.defaultData
|
||||
? options?.defaultData
|
||||
: this.editor.trigger('mention:default'))
|
||||
) {
|
||||
setTimeout(() => {
|
||||
|
|
|
@ -19,121 +19,16 @@ import {
|
|||
} from '@aomao/engine';
|
||||
import MentionComponent, { MentionValue } from './component';
|
||||
import locales from './locales';
|
||||
import { MentionItem } from './types';
|
||||
|
||||
export interface MentionOptions extends PluginOptions {
|
||||
defaultData?: Array<MentionItem>;
|
||||
onSearch?: (keyword: string) => Promise<Array<MentionItem>>;
|
||||
onSelect?: (data: {
|
||||
[key: string]: string;
|
||||
}) => void | { [key: string]: string };
|
||||
onInsert?: (card: CardInterface) => void;
|
||||
onClick?: (node: NodeInterface, data: { [key: string]: string }) => void;
|
||||
onMouseEnter?: (
|
||||
node: NodeInterface,
|
||||
data: { [key: string]: string },
|
||||
) => void;
|
||||
onRender?: (
|
||||
root: NodeInterface,
|
||||
data: MentionItem[],
|
||||
bindItem: (
|
||||
node: NodeInterface,
|
||||
data: { [key: string]: string },
|
||||
) => NodeInterface,
|
||||
) => Promise<string | NodeInterface | void>;
|
||||
onRenderItem?: (
|
||||
item: MentionItem,
|
||||
root: NodeInterface,
|
||||
) => string | NodeInterface | void;
|
||||
onLoading?: (root: NodeInterface) => string | NodeInterface | void;
|
||||
onEmpty?: (root: NodeInterface) => string | NodeInterface | void;
|
||||
spaceTrigger?: boolean;
|
||||
/**
|
||||
* 查询地址
|
||||
*/
|
||||
action?: string;
|
||||
/**
|
||||
* 数据返回类型,默认 json
|
||||
*/
|
||||
type?: '*' | 'json' | 'xml' | 'html' | 'text' | 'js';
|
||||
/**
|
||||
* 额外携带数据上传
|
||||
*/
|
||||
data?: {};
|
||||
/**
|
||||
* 请求类型,默认 multipart/form-data;
|
||||
*/
|
||||
contentType?: string;
|
||||
/**
|
||||
* 解析上传后的Respone,返回 result:是否成功,data:成功:文件地址,失败:错误信息
|
||||
*/
|
||||
parse?: (response: any) => {
|
||||
result: boolean;
|
||||
data: Array<MentionItem>;
|
||||
};
|
||||
}
|
||||
import { MentionOptions } from './types';
|
||||
|
||||
class MentionPlugin<
|
||||
T extends MentionOptions = MentionOptions,
|
||||
> extends Plugin<T> {
|
||||
#request?: AjaxInterface;
|
||||
static get pluginName() {
|
||||
return 'mention';
|
||||
}
|
||||
|
||||
init() {
|
||||
const {
|
||||
defaultData,
|
||||
onSearch,
|
||||
onSelect,
|
||||
onInsert,
|
||||
onClick,
|
||||
onMouseEnter,
|
||||
onRender,
|
||||
onRenderItem,
|
||||
onLoading,
|
||||
onEmpty,
|
||||
action,
|
||||
contentType,
|
||||
type,
|
||||
parse,
|
||||
} = this.options;
|
||||
const { request } = this.editor;
|
||||
if (defaultData) MentionComponent.defaultData = defaultData;
|
||||
if (onClick) MentionComponent.itemClick = onClick;
|
||||
if (onMouseEnter) MentionComponent.mouseEnter = onMouseEnter;
|
||||
if (onRender) MentionComponent.render = onRender;
|
||||
if (onRenderItem) MentionComponent.renderItem = onRenderItem;
|
||||
if (onLoading) MentionComponent.renderLoading = onLoading;
|
||||
if (onEmpty) MentionComponent.renderEmpty = onEmpty;
|
||||
if (onSelect) MentionComponent.onSelect = onSelect;
|
||||
if (onInsert) MentionComponent.onInsert = onInsert;
|
||||
MentionComponent.search = (keyword: string) => {
|
||||
if (onSearch) return onSearch(keyword);
|
||||
const reuslt = this.editor.trigger('mention:search', keyword);
|
||||
if (reuslt !== undefined) return reuslt;
|
||||
return new Promise((resolve) => {
|
||||
if (action) {
|
||||
this.#request?.abort();
|
||||
this.#request = request.ajax({
|
||||
url: action,
|
||||
contentType: contentType || '',
|
||||
type: type === undefined ? 'json' : type,
|
||||
data: {
|
||||
keyword,
|
||||
},
|
||||
success: (response: any) => {
|
||||
const { result, data } = parse
|
||||
? parse(response)
|
||||
: response;
|
||||
if (!result) return;
|
||||
resolve(data);
|
||||
},
|
||||
method: 'GET',
|
||||
});
|
||||
} else resolve([]);
|
||||
});
|
||||
};
|
||||
if (isEngine(this.editor)) {
|
||||
this.editor.on('keydown:at', (event) => this.onAt(event));
|
||||
this.editor.on('parse:value', (node) => this.paserValue(node));
|
||||
|
|
|
@ -1 +1,54 @@
|
|||
import { CardInterface, NodeInterface, PluginOptions } from '@aomao/engine';
|
||||
|
||||
export type MentionItem = { key?: string; name: string; avatar?: string };
|
||||
export interface MentionOptions extends PluginOptions {
|
||||
defaultData?: Array<MentionItem>;
|
||||
onSearch?: (keyword: string) => Promise<Array<MentionItem>>;
|
||||
onSelect?: (data: {
|
||||
[key: string]: string;
|
||||
}) => void | { [key: string]: string };
|
||||
onInsert?: (card: CardInterface) => void;
|
||||
onClick?: (node: NodeInterface, data: { [key: string]: string }) => void;
|
||||
onMouseEnter?: (
|
||||
node: NodeInterface,
|
||||
data: { [key: string]: string },
|
||||
) => void;
|
||||
onRender?: (
|
||||
root: NodeInterface,
|
||||
data: MentionItem[],
|
||||
bindItem: (
|
||||
node: NodeInterface,
|
||||
data: { [key: string]: string },
|
||||
) => NodeInterface,
|
||||
) => Promise<string | NodeInterface | void>;
|
||||
onRenderItem?: (
|
||||
item: MentionItem,
|
||||
root: NodeInterface,
|
||||
) => string | NodeInterface | void;
|
||||
onLoading?: (root: NodeInterface) => string | NodeInterface | void;
|
||||
onEmpty?: (root: NodeInterface) => string | NodeInterface | void;
|
||||
spaceTrigger?: boolean;
|
||||
/**
|
||||
* 查询地址
|
||||
*/
|
||||
action?: string;
|
||||
/**
|
||||
* 数据返回类型,默认 json
|
||||
*/
|
||||
type?: '*' | 'json' | 'xml' | 'html' | 'text' | 'js';
|
||||
/**
|
||||
* 额外携带数据上传
|
||||
*/
|
||||
data?: {};
|
||||
/**
|
||||
* 请求类型,默认 multipart/form-data;
|
||||
*/
|
||||
contentType?: string;
|
||||
/**
|
||||
* 解析上传后的Respone,返回 result:是否成功,data:成功:文件地址,失败:错误信息
|
||||
*/
|
||||
parse?: (response: any) => {
|
||||
result: boolean;
|
||||
data: Array<MentionItem>;
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue