@dialpad/dialtone-vue
Version:
Vue component library for Dialpad's design system Dialtone
108 lines (107 loc) • 3.23 kB
JavaScript
import { VueRenderer } from "@tiptap/vue-2";
import { emojisIndexed } from "@dialpad/dialtone-emojis";
import SuggestionList from "../suggestion/SuggestionList.vue.js";
import EmojiSuggestion from "./EmojiSuggestion.vue.js";
import tippy from "tippy.js";
import hideOnEsc from "../tippy_plugins/hide_on_esc.js";
const suggestionLimit = 20;
const suggestionOptions = {
items: ({ query }) => {
if (query.length < 2) {
return [];
}
const emojiList = Object.values(emojisIndexed);
query = query.toLowerCase();
const filteredEmoji = emojiList.filter(
(item) => [
item.name,
item.shortname.replaceAll(":", ""),
...item.keywords
].some((text) => text.startsWith(query))
).splice(0, suggestionLimit);
return filteredEmoji.map((item) => ({ code: item.shortname }));
},
command: ({ editor, range, props }) => {
var _a, _b;
const nodeAfter = editor.view.state.selection.$to.nodeAfter;
const overrideSpace = (_a = nodeAfter == null ? void 0 : nodeAfter.text) == null ? void 0 : _a.startsWith(" ");
if (overrideSpace) {
range.to += 1;
}
editor.chain().focus().insertContentAt(range, [
{
type: "emoji",
attrs: props
}
]).run();
(_b = window.getSelection()) == null ? void 0 : _b.collapseToEnd();
},
render: () => {
let component;
let popup;
let popupIsOpen = false;
return {
onStart: (props) => {
component = new VueRenderer(SuggestionList, {
parent: void 0,
propsData: {
itemComponent: EmojiSuggestion,
itemType: "emoji",
...props
},
editor: props.editor
});
if (!props.clientRect) {
return;
}
popup = tippy("body", {
getReferenceClientRect: props.clientRect,
appendTo: () => document.body,
content: component.element,
showOnCreate: false,
onShow: () => {
popupIsOpen = true;
},
onHidden: () => {
popupIsOpen = false;
},
interactive: true,
trigger: "manual",
placement: "top-start",
zIndex: 650,
plugins: [hideOnEsc]
});
if (props.items.length > 0) {
popup == null ? void 0 : popup[0].show();
}
},
onUpdate(props) {
component == null ? void 0 : component.updateProps(props);
if (props.items.length > 0) {
popup == null ? void 0 : popup[0].show();
} else {
popup == null ? void 0 : popup[0].hide();
}
popup == null ? void 0 : popup[0].setProps({
getReferenceClientRect: props.clientRect
});
},
onKeyDown(props) {
var _a;
if (popupIsOpen) {
return (_a = component == null ? void 0 : component.ref) == null ? void 0 : _a.onKeyDown(props);
}
},
onExit() {
popup == null ? void 0 : popup[0].destroy();
popup = null;
component == null ? void 0 : component.destroy();
component = null;
}
};
}
};
export {
suggestionOptions as default
};
//# sourceMappingURL=suggestion.js.map