UNPKG

md-editor-v3

Version:

Markdown editor for vue3, developed in jsx and typescript, dark theme、beautify content by prettier、render articles directly、paste or clip the picture and upload it...

331 lines (330 loc) 9.37 kB
import { createVNode, defineComponent, h, inject, ref, shallowRef, reactive, computed, watch, nextTick, onMounted, Teleport } from "vue"; import { p as prefix, g as globalConfig } from "./config.mjs"; import { g as getSlot } from "./vue-tsx.mjs"; import { k as keyMove } from "./dom.mjs"; import { Upload, Trash2, X, SquareSigma, ChartArea, ListTree, CodeXml, Eye, View, Expand, Shrink, Maximize2, Minimize2, SquareCode, Save, Forward, Reply, Table, Image, Link, Code, ListTodo, ListOrdered, List, Quote, Superscript, Subscript, Heading, Strikethrough, Italic, Underline, Bold } from "lucide-vue-next"; import { c as getZIndexIncrement } from "./index5.mjs"; const Github = () => createVNode("svg", { "xmlns": "http://www.w3.org/2000/svg", "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "class": "lucide lucide-github-icon" }, [createVNode("path", { "d": "M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4" }, null), createVNode("path", { "d": "M9 18c-4.51 2-5-2-7-2" }, null)]); const iconMaps = { bold: Bold, underline: Underline, italic: Italic, "strike-through": Strikethrough, title: Heading, sub: Subscript, sup: Superscript, quote: Quote, "unordered-list": List, "ordered-list": ListOrdered, task: ListTodo, "code-row": Code, code: SquareCode, link: Link, image: Image, table: Table, revoke: Reply, next: Forward, save: Save, prettier: SquareCode, minimize: Minimize2, maximize: Maximize2, "fullscreen-exit": Shrink, fullscreen: Expand, "preview-only": View, preview: Eye, "preview-html": CodeXml, catalog: ListTree, github: Github, mermaid: ChartArea, formula: SquareSigma, close: X, delete: Trash2, upload: Upload }; const Icon$1 = /* @__PURE__ */ defineComponent({ name: `${prefix}-icon-set`, props: { name: { type: String, default: "" } }, setup(props2) { return () => { return h(iconMaps[props2.name], { class: `${prefix}-icon` }); }; } }); const Icon = /* @__PURE__ */ defineComponent({ name: `${prefix}-icon`, props: { name: { type: String, default: "" } }, setup(props2) { const customIcon = inject("customIcon"); return () => { const item = customIcon.value[props2.name]; if (typeof item === "object") { return typeof item.component === "object" ? h(item.component, item.props) : createVNode("span", { "innerHTML": item.component }, null); } return createVNode(Icon$1, { "name": props2.name }, null); }; } }); const props = { title: { type: [String, Object], default: "" }, visible: { type: Boolean, default: false }, width: { type: String, default: "auto" }, height: { type: String, default: "auto" }, onClose: { type: Function }, showAdjust: { type: Boolean, default: false }, isFullscreen: { type: Boolean, default: false }, onAdjust: { type: Function, default: () => { } }, class: { type: String, default: void 0 }, style: { type: [Object, String], default: () => ({}) }, showMask: { type: Boolean, default: true } }; const MdModal = /* @__PURE__ */ defineComponent({ name: "MdModal", props, emits: ["onClose"], setup(props2, ctx) { const themeRef = inject("theme"); const rootRef = inject("rootRef"); const modalVisible = ref(props2.visible); const modalClass = ref([`${prefix}-modal`]); const modalRef = ref(); const modalHeaderRef = ref(); const bodyRef = ref(); const containerRef = shallowRef(); let keyMoveClear = () => { }; const state = reactive({ maskStyle: { zIndex: -1 }, modalStyle: { zIndex: -1 }, initPos: { left: "0px", top: "0px" }, historyPos: { left: "0px", top: "0px" } }); const innerSize = computed(() => { if (props2.isFullscreen) { return { width: "100%", height: "100%" }; } else { return { width: props2.width, height: props2.height }; } }); watch(() => props2.isFullscreen, (nVal) => { if (nVal) { keyMoveClear(); } else { nextTick(() => { keyMoveClear = keyMove(modalHeaderRef.value, (left, top) => { state.initPos.left = left + "px"; state.initPos.top = top + "px"; }); }); } }); watch(() => props2.visible, (nVal) => { if (nVal) { state.maskStyle.zIndex = globalConfig.editorConfig.zIndex + getZIndexIncrement(); state.modalStyle.zIndex = globalConfig.editorConfig.zIndex + getZIndexIncrement(); modalClass.value.push("zoom-in"); modalVisible.value = nVal; nextTick(() => { const halfWidth = modalRef.value.offsetWidth / 2; const halfHeight = modalRef.value.offsetHeight / 2; const halfClientWidth = document.documentElement.clientWidth / 2; const halfClientHeight = document.documentElement.clientHeight / 2; state.initPos.left = halfClientWidth - halfWidth + "px"; state.initPos.top = halfClientHeight - halfHeight + "px"; if (!props2.isFullscreen) { keyMoveClear = keyMove(modalHeaderRef.value, (left, top) => { state.initPos.left = left + "px"; state.initPos.top = top + "px"; }); } }); setTimeout(() => { modalClass.value = modalClass.value.filter((item) => item !== "zoom-in"); }, 140); } else { modalClass.value.push("zoom-out"); keyMoveClear(); setTimeout(() => { modalClass.value = modalClass.value.filter((item) => item !== "zoom-out"); modalVisible.value = nVal; }, 130); } }); const internalStyle = computed(() => ({ display: modalVisible.value ? "block" : "none" })); const combinedStyle = computed(() => { if (typeof props2.style === "string") { return [props2.style, internalStyle.value].join("; "); } else if (props2.style instanceof Object) { return { ...internalStyle.value, ...props2.style }; } else { return internalStyle.value; } }); onMounted(() => { var _a; const rootNode = (_a = rootRef.value) == null ? void 0 : _a.getRootNode(); bodyRef.value = rootNode instanceof Document ? document.body : rootNode; }); return () => { const slotDefault = getSlot({ ctx }); const slotTitle = getSlot({ props: props2, ctx }, "title"); return bodyRef.value ? createVNode(Teleport, { "to": bodyRef.value }, { default: () => [createVNode("div", { "ref": containerRef, "class": `${prefix}-modal-container`, "data-theme": themeRef.value }, [createVNode("div", { "class": props2.class, "style": combinedStyle.value }, [props2.showMask && createVNode("div", { "class": `${prefix}-modal-mask`, "style": state.maskStyle, "onClick": () => { var _a; (_a = props2.onClose) == null ? void 0 : _a.call(props2); ctx.emit("onClose"); } }, null), createVNode("div", { "class": modalClass.value, "style": { ...state.modalStyle, ...state.initPos, ...innerSize.value }, "ref": modalRef }, [createVNode("div", { "class": `${prefix}-modal-header`, "ref": modalHeaderRef }, [slotTitle || ""]), createVNode("div", { "class": `${prefix}-modal-body` }, [slotDefault]), createVNode("div", { "class": `${prefix}-modal-func` }, [props2.showAdjust && createVNode("div", { "class": `${prefix}-modal-adjust`, "onClick": (e) => { e.stopPropagation(); if (!props2.isFullscreen) { state.historyPos = state.initPos; state.initPos = { left: "0", top: "0" }; } else { state.initPos = state.historyPos; } props2.onAdjust(!props2.isFullscreen); } }, [createVNode(Icon, { "name": props2.isFullscreen ? "minimize" : "maximize" }, null)]), createVNode("div", { "class": `${prefix}-modal-close`, "onClick": (e) => { var _a; e.stopPropagation(); (_a = props2.onClose) == null ? void 0 : _a.call(props2); ctx.emit("onClose"); } }, [createVNode(Icon, { "name": "close" }, null)])])])])])] }) : ""; }; } }); MdModal.install = (app) => { app.component(MdModal.name, MdModal); return app; }; export { Icon as I, MdModal as M };