@opentiny/vue-renderless
Version:
An enterprise-class UI component library, support both Vue.js 2 and Vue.js 3, as well as PC and mobile.
298 lines (297 loc) • 6.63 kB
JavaScript
import {
__spreadProps,
__spreadValues
} from "../chunk-G2ADBYYC.js";
import {
Active,
closeTablePanel,
eventClick,
eventImg,
handleChange,
setLink,
shouldShow,
tableChoose,
tableMouseMove,
toggleTablePanel
} from "./index";
const api = [
"state",
"setLink",
"handleChange",
"tableMouseMove",
"tableChoose",
"toggleTablePanel",
"closeTablePanel",
"shouldShow",
"eventImg",
"eventClick",
"Active"
];
const renderless = (props, { computed, onBeforeUnmount, reactive, watch }, { vm, emit }, {
Editor,
StarterKit,
Table,
TableCell,
TableHeader,
TableRow,
Color,
TextStyle,
Image,
Highlight,
Link,
Underline,
Subscript,
Superscript,
TaskItem,
TaskList,
TextAlign,
Paragraph,
mergeAttributes,
CodeBlockLowlight,
lowlight,
VueNodeViewRenderer,
Placeholder,
codeHighlight
}) => {
let defaultToolBar = [
"bold",
"italic",
"underline",
"strike",
"quote",
"code",
"codeBlock",
"unorderedlist",
"orderedlist",
"taskList",
"subscript",
"superscript",
"undo",
"redo",
"left",
"center",
"right",
"formatClear",
"link",
"h-box",
//
"font-size",
//
"line-height",
//
"highlight",
"color",
//
"backgroundColor",
//
"unlink",
//
"img",
//
"table"
//
];
const CustomImage = Image.extend({
addAttributes() {
var _a;
return __spreadProps(__spreadValues({}, (_a = this.parent) == null ? void 0 : _a.call(this)), {
type: {
default: "img"
}
});
},
renderHTML({ node, HTMLAttributes }) {
if (node.attrs.type === "video") {
return ["div", { class: "img-button" }, ["video", mergeAttributes({ controls: true }, HTMLAttributes)]];
} else {
return ["div", { class: "img-button" }, ["img", HTMLAttributes]];
}
}
});
const CustomParagraph = Paragraph.extend({
addOptions() {
return {
levels: [1, 1.5, 2, 2.5, 3]
};
},
addAttributes() {
return {
level: {
default: 1.5
}
};
},
renderHTML({ node, HTMLAttributes }) {
const hasLevel = this.options.levels.includes(node.attrs.level);
const level = hasLevel ? node.attrs.level : this.options.levels[0];
return ["p", mergeAttributes({ style: `line-height: ${level}` }, HTMLAttributes), 0];
},
addCommands() {
return {
setP: (attributes) => ({ commands }) => {
return commands.setNode(this.name, attributes);
}
};
}
});
const CustomSize = Paragraph.extend({
addOptions() {
return {
size: [12, 14, 16, 18, 20, 24, 30]
};
},
addAttributes() {
return {
size: {
default: 14
}
};
},
renderHTML({ node, HTMLAttributes }) {
const hasSize = this.options.size.includes(node.attrs.size);
const size = hasSize ? node.attrs.size : this.options.size[2];
return ["p", mergeAttributes({ style: `font-size: ${size}px` }, HTMLAttributes), 0];
},
addCommands() {
return {
setSize: (attributes) => ({ commands }) => {
return commands.setNode(this.name, attributes);
}
};
}
});
const CustomBackgroundColor = Highlight.extend({
addAttributes() {
return {
bgColor: {
default: null,
renderHTML: (attributes) => {
if (!attributes.bgColor) {
return {};
}
return {
style: `background: ${attributes.bgColor}`
};
}
}
};
},
addCommands() {
return {
setBackColor: (attributes) => ({ commands }) => {
return commands.setMark(this.name, attributes);
}
};
}
});
const defaultOptions = {
extensions: [
StarterKit == null ? void 0 : StarterKit.configure({
// 开启多人协作功能要关闭默认的history模式
history: true
}),
Table.configure({
resizable: true
}),
TableCell,
TableHeader,
TableRow,
Color,
TextStyle,
CustomImage,
Highlight,
Link,
Underline,
Subscript,
Superscript,
TaskList,
TaskItem.configure({
nested: true
}),
TextAlign.configure({
types: ["heading", "paragraph"]
}),
CustomParagraph,
CustomSize,
CustomBackgroundColor,
CodeBlockLowlight.extend({
addNodeView() {
return VueNodeViewRenderer(codeHighlight);
}
}).configure({ lowlight }),
Placeholder.configure({
placeholder: props.placeholder
})
],
content: props.modelValue,
autofocus: true,
editable: true,
injectCSS: false,
// 事件
onBeforeCreate({ editor }) {
emit("beforeCreate", { editor });
},
onCreate({ editor }) {
emit("create", { editor });
},
onUpdate({ editor }) {
const html = editor.getHTML();
emit("update", { editor });
emit("update:modelValue", html);
},
onFocus({ editor, event }) {
emit("focus", { editor, event });
},
onBlur({ editor, event }) {
emit("blur", { editor, event });
},
onSelectionUpdate({ editor }) {
emit("selectionUpdate", { editor });
},
onTransaction({ editor, transaction }) {
emit("transaction", { editor, transaction });
},
onDestroy() {
emit("destroy");
}
};
let options = __spreadValues(__spreadValues({}, defaultOptions), props.options);
options.extensions = [.../* @__PURE__ */ new Set([...defaultOptions.extensions, ...props.options.extensions || []])];
const state = reactive({
editor: new Editor(options),
toolbar: computed(() => props.customToolBar.length ? props.customToolBar : defaultToolBar),
// table 变量
isShowTable: false,
flagX: 0,
flagY: 0
});
const api2 = {
state,
setLink: setLink(state.editor),
handleChange: handleChange(state.editor),
// table处理函数
tableMouseMove: tableMouseMove(state, vm),
toggleTablePanel: toggleTablePanel(state),
closeTablePanel: closeTablePanel(state),
tableChoose: tableChoose(state, vm),
// bubble 菜单
shouldShow,
eventImg,
eventClick,
Active
};
onBeforeUnmount(() => {
state.editor.destroy();
});
watch(
() => props.modelValue,
(value) => {
state.editor.commands.setContent(value);
}
);
return api2;
};
export {
api,
renderless
};