Vue
v-model:document via update:document.
vue
<script setup>
import { onMounted, onBeforeUnmount, ref } from "vue";
import { mountVanillaEditor } from "velo-text";
const props = defineProps({
document: { type: Object, required: true },
theme: { type: String, default: "light-neutral" },
editable: { type: Boolean, default: true },
resolveAssetUrl: { type: Function, default: undefined },
getVariableCatalog: { type: Function, default: undefined },
getTemplateData: { type: Function, default: undefined },
});
const emit = defineEmits(["update:document"]);
const el = ref(null);
let editor;
onMounted(() => {
editor = mountVanillaEditor(el.value, {
document: props.document,
theme: props.theme,
editable: props.editable,
resolveAssetUrl: props.resolveAssetUrl,
getVariableCatalog: props.getVariableCatalog,
getTemplateData: props.getTemplateData,
onChange: (doc) => emit("update:document", doc),
});
});
onBeforeUnmount(() => editor?.destroy());
defineExpose({
insertVariable: (path, format, fallback) => editor?.commands.insertVariable(path, format, fallback),
getDocument: () => editor?.getDocument(),
commands: () => editor?.commands,
});
</script>
<template>
<div ref="el" class="pde-editor"></div>
</template>vue
<script setup>
import { ref } from "vue";
import { createDocument, createIdGenerator, exportDocument } from "velo-text";
import PortableEditor from "./PortableEditor.vue";
const MIME = {
pdf: "application/pdf",
odt: "application/vnd.oasis.opendocument.text",
docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
};
function sampleDoc() {
const g = createIdGenerator("vue");
const doc = createDocument({ idGenerator: g, clock: { nowIso: () => new Date().toISOString() } });
doc.root.children.push({
type: "paragraph",
id: g.next(),
children: [
{ type: "text", id: g.next(), text: "Hello " },
{ type: "variable", id: g.next(), path: "name", source: "{{name}}", valueType: "string" },
],
});
return doc;
}
const editor = ref(null);
const document = ref(sampleDoc());
const status = ref("ready");
async function doExport(format) {
const live = editor.value?.getDocument() ?? document.value;
const chunks = [];
await exportDocument({
document: live,
data: { name: "Ada" },
format,
sink: { write(c) { chunks.push(c); }, close() {} },
options: { strict: false },
});
const a = window.document.createElement("a");
a.href = URL.createObjectURL(new Blob(chunks, { type: MIME[format] }));
a.download = `vue.${format}`;
a.click();
status.value = `exported ${format}`;
}
</script>
<template>
<div data-pde-theme="light-neutral">
<p>{{ status }}</p>
<button type="button" @click="editor?.insertVariable('name')">Insert variable</button>
<button type="button" @click="doExport('pdf')">PDF</button>
<button type="button" @click="doExport('odt')">ODT</button>
<button type="button" @click="doExport('docx')">DOCX</button>
<PortableEditor ref="editor" v-model:document="document" theme="light-neutral" />
</div>
</template>