lexical-vue
Version:
An extensible Vue 3 web text-editor based on Lexical.
95 lines (94 loc) • 4.02 kB
JavaScript
import { createBlock, createCommentVNode, defineComponent, guardReactiveProps, nextTick, normalizeProps, openBlock, ref, renderSlot, unref, useSlots, watch, watchEffect, withCtx } from "vue";
import { $getNodeByKey } from "lexical";
import { useLexicalComposer } from "./LexicalComposer.vine.js";
import { LexicalMenu, useMenuAnchorRef } from "./shared/LexicalMenu.vine.js";
const NodeMenuPlugin = (()=>{
const __vine = defineComponent({
name: 'NodeMenuPlugin',
props: {
options: {
required: true
},
nodeKey: {
required: true
},
anchorClassName: {},
commandPriority: {},
parent: {}
},
emits: [
'close',
'open',
'selectOption'
],
setup (__props, param) {
let { emit: __emit, expose: __expose } = param;
const emit = __emit;
__expose();
const props = __props;
useSlots();
const editor = useLexicalComposer();
const resolution = ref(null);
function setResolution(payload) {
resolution.value = payload;
}
const anchorElementRef = useMenuAnchorRef(resolution, setResolution, props.anchorClassName, props.parent);
function closeNodeMenu() {
setResolution(null);
if (null !== resolution.value) emit('close');
}
function openNodeMenu(res) {
setResolution(res);
if (null === resolution.value) emit('open', res);
}
function positionOrCloseMenu() {
if (props.nodeKey) editor.update(()=>{
const node = $getNodeByKey(props.nodeKey);
const domElement = editor.getElementByKey(props.nodeKey);
if (null != node && null != domElement) {
if (null == resolution.value) nextTick(()=>openNodeMenu({
getRect: ()=>domElement.getBoundingClientRect()
}));
}
});
else if (null == props.nodeKey && null != resolution.value) closeNodeMenu();
}
watch(()=>props.nodeKey, positionOrCloseMenu, {
immediate: true
});
watchEffect((onInvalidate)=>{
if (null != props.nodeKey) {
const unregister = editor.registerUpdateListener((param)=>{
let { dirtyElements } = param;
if (dirtyElements.get(props.nodeKey)) positionOrCloseMenu();
});
onInvalidate(unregister);
}
});
return (_ctx, _cache)=>null !== unref(anchorElementRef) && null !== resolution.value && null !== unref(editor) ? (openBlock(), createBlock(unref(LexicalMenu), {
key: 0,
resolution: resolution.value,
editor: unref(editor),
"anchor-element-ref": unref(anchorElementRef),
options: _ctx.options,
"command-priority": _ctx.commandPriority,
close: closeNodeMenu,
onSelectOption: _cache[0] || (_cache[0] = ($event)=>emit('selectOption', $event))
}, {
default: withCtx((slotProps)=>[
renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(slotProps)))
]),
_: 3
}, 8, [
"resolution",
"editor",
"anchor-element-ref",
"options",
"command-priority"
])) : createCommentVNode("", true);
}
});
__vine.__vue_vine = true;
return __vine;
})();
export { NodeMenuPlugin };