refactor editor
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<t-popconfirm
|
||||
v-model:visible="visible"
|
||||
trigger="click"
|
||||
:confirm-btn="{ content: '插入', theme: 'primary' }"
|
||||
:cancel-btn="{ content: '取消', theme: 'default' }"
|
||||
placement="bottom"
|
||||
@visible-change="onVisibleChange"
|
||||
@confirm="onConfirm"
|
||||
>
|
||||
<template #icon><span></span></template>
|
||||
<template #content>
|
||||
<div class="link-form">
|
||||
<t-input v-model="linkForm.href" placeholder="请输入链接地址" />
|
||||
<t-input v-model="linkForm.text" placeholder="请输入显示文本,可留空" />
|
||||
<t-checkbox v-model="linkForm.syncToHref">显示文本同步为链接</t-checkbox>
|
||||
</div>
|
||||
</template>
|
||||
<t-button v-popup="'插入链接'" variant="outline" :theme="active ? 'primary' : 'default'">
|
||||
<t-icon name="link-1" />
|
||||
</t-button>
|
||||
</t-popconfirm>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { TiptapEditorInstance } from "timi-web/editor";
|
||||
|
||||
defineOptions({
|
||||
name: "TiptapLinkButton"
|
||||
});
|
||||
|
||||
const props = defineProps<{
|
||||
editor?: TiptapEditorInstance;
|
||||
active: boolean;
|
||||
}>();
|
||||
|
||||
const visible = ref(false);
|
||||
const linkForm = reactive({
|
||||
href: "",
|
||||
text: "",
|
||||
syncToHref: false
|
||||
});
|
||||
|
||||
function onVisibleChange(nextVisible: boolean) {
|
||||
if (!nextVisible || !props.editor) {
|
||||
return;
|
||||
}
|
||||
const previousUrl = (props.editor.getAttributes("link").href as string) || "";
|
||||
const selectedText = props.editor.state.doc.textBetween(
|
||||
props.editor.state.selection.from,
|
||||
props.editor.state.selection.to,
|
||||
""
|
||||
);
|
||||
linkForm.href = previousUrl || "https://";
|
||||
linkForm.text = selectedText || "";
|
||||
linkForm.syncToHref = false;
|
||||
}
|
||||
|
||||
function onConfirm() {
|
||||
if (!props.editor) {
|
||||
return;
|
||||
}
|
||||
const href = linkForm.href.trim();
|
||||
if (!href) {
|
||||
props.editor.chain().focus().unsetLink().run();
|
||||
visible.value = false;
|
||||
return;
|
||||
}
|
||||
const text = linkForm.syncToHref ? href : linkForm.text.trim();
|
||||
if (text) {
|
||||
props.editor
|
||||
.chain()
|
||||
.focus()
|
||||
.insertContent({
|
||||
type: "text",
|
||||
text,
|
||||
marks: [{ type: "link", attrs: { href } }]
|
||||
})
|
||||
.run();
|
||||
visible.value = false;
|
||||
return;
|
||||
}
|
||||
props.editor.chain().focus().extendMarkRange("link").setLink({ href }).run();
|
||||
visible.value = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.link-form {
|
||||
gap: .75rem;
|
||||
width: 20rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user