Add Url input menu

This commit is contained in:
Seviche CC 2023-03-29 16:50:53 +08:00
parent d2f26c1f64
commit e34e051f41
Signed by: SevicheCC
GPG key ID: C577000000000000
5 changed files with 147 additions and 48 deletions

View file

@ -16,6 +16,7 @@
"@prosemirror-adapter/vue": "^0.2.3",
"@tiptap/extension-bubble-menu": "2.0.0-beta.220",
"@tiptap/extension-character-count": "2.0.0-beta.220",
"@tiptap/extension-link": "2.0.0-beta.220",
"@tiptap/extension-typography": "2.0.0-beta.220",
"@tiptap/pm": "2.0.0-beta.220",
"@tiptap/starter-kit": "2.0.0-beta.220",

View file

@ -16,6 +16,9 @@ dependencies:
'@tiptap/extension-character-count':
specifier: 2.0.0-beta.220
version: 2.0.0-beta.220(@tiptap/core@2.0.0-beta.220)(@tiptap/pm@2.0.0-beta.220)
'@tiptap/extension-link':
specifier: 2.0.0-beta.220
version: 2.0.0-beta.220(@tiptap/core@2.0.0-beta.220)(@tiptap/pm@2.0.0-beta.220)
'@tiptap/extension-typography':
specifier: 2.0.0-beta.220
version: 2.0.0-beta.220(@tiptap/core@2.0.0-beta.220)
@ -780,6 +783,17 @@ packages:
'@tiptap/core': 2.0.0-beta.220(@tiptap/pm@2.0.0-beta.220)
dev: false
/@tiptap/extension-link@2.0.0-beta.220(@tiptap/core@2.0.0-beta.220)(@tiptap/pm@2.0.0-beta.220):
resolution: {integrity: sha512-vjEA8cE37ZZVVgPHSpttw3kbJoClb+ya/BVukDtJ1h6C7mIR1rqzNxTgpbnXJuA8xww0JOjpa5dpzEgcs294fA==}
peerDependencies:
'@tiptap/core': ^2.0.0-beta.209
'@tiptap/pm': ^2.0.0-beta.209
dependencies:
'@tiptap/core': 2.0.0-beta.220(@tiptap/pm@2.0.0-beta.220)
'@tiptap/pm': 2.0.0-beta.220(@tiptap/core@2.0.0-beta.220)
linkifyjs: 4.1.1
dev: false
/@tiptap/extension-list-item@2.0.0-beta.220(@tiptap/core@2.0.0-beta.220):
resolution: {integrity: sha512-+O0ivwxPP2l/m9PAowb2ytDT/cM5kwu0s1W5MUsHPIqf+M6ahnl4ESjhWZfDHUzvjqPq6MTbqoQLHbB1KS/N7w==}
peerDependencies:
@ -2870,6 +2884,10 @@ packages:
uc.micro: 1.0.6
dev: false
/linkifyjs@4.1.1:
resolution: {integrity: sha512-zFN/CTVmbcVef+WaDXT63dNzzkfRBKT1j464NJQkV7iSgJU0sLBus9W0HBwnXK13/hf168pbrx/V/bjEHOXNHA==}
dev: false
/local-pkg@0.4.3:
resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==}
engines: {node: '>=14'}

View file

@ -1,59 +1,110 @@
<script setup lang="ts">
import type { Editor
} from '@tiptap/vue-3';
import type { Editor } from '@tiptap/vue-3'
import { BubbleMenu } from '@tiptap/vue-3'
import { nextTick, ref } from 'vue'
const { editor } = defineProps<{ editor: Editor }>()
const url = ref('')
const showUrlInput = ref(false)
const placeholder = ref('Add Link to text')
const inputUrl = ref<HTMLInputElement | null>(null)
const openLinkInput = () => {
showUrlInput.value = true
nextTick(() => inputUrl.value?.focus())
}
const setLink = () => {
const previousUrl = editor.getAttributes('link').href
if (previousUrl)
placeholder.value = previousUrl
// cancelled
if (url.value === null)
return
if (url.value === '') {
editor.chain().focus().extendMarkRange('link').unsetAllMarks().run()
return
}
editor
.chain()
.focus()
.extendMarkRange('link')
.setLink({ href: url.value })
.run()
return (showUrlInput.value = false)
}
</script>
<template>
<BubbleMenu
:editor="editor"
:tippy-options="{ duration: 100 }"
:tippy-options="{ duration: 50 }"
class="flex text-gray-700 bg-white grass rounded-md p-[2px] shadow-xl border-slate-100 border"
>
<button
class="menu-btn"
placement="bold"
@click="editor.chain().focus().toggleBold().run()"
<div v-show="!showUrlInput">
<button
class="menu-btn"
:class="{ 'btn-active': editor.isActive('bold') }"
@click="editor.chain().focus().toggleBold().run()"
>
<span class="i-tabler-bold" />
</button>
<button
class="menu-btn"
:class="{ 'btn-active': editor.isActive('italic') }"
@click="editor.chain().focus().toggleItalic().run()"
>
<span class="i-tabler-italic" />
</button>
<button
class="menu-btn"
:class="{ 'btn-active': editor.isActive('strike') }"
@click="editor.chain().focus().toggleStrike().run()"
>
<span class="i-tabler-strikethrough" />
</button>
<button
class="menu-btn"
:class="{ 'btn-active': editor.isActive('code') }"
@click="editor.chain().focus().toggleCode().run()"
>
<span class="i-tabler-code" />
</button>
<button
class="menu-btn"
:class="{ 'btn-active': editor.isActive('quote') }"
@click="editor.chain().focus().toggleBlockquote().run()"
>
<span class="i-tabler-quote" />
</button>
<button
:class="{ 'btn-active': editor.isActive('link') }"
class="menu-btn"
@click="openLinkInput"
>
<span class="i-tabler-link" />
</button>
</div>
<div
v-show="showUrlInput"
class="input-group input-group-sm border-slate-300 border-1"
>
<span class="i-tabler-bold" />
</button>
<button
class="menu-btn"
@click="editor.chain().focus().toggleItalic().run()"
>
<span class="i-tabler-italic" />
</button>
<button
class="menu-btn"
@click="editor.chain().focus().toggleStrike().run()"
>
<span class="i-tabler-strikethrough" />
</button>
<button
class="menu-btn"
@click="editor.chain().focus().toggleCode().run()"
>
<span class="i-tabler-code" />
</button>
<button
class="menu-btn"
@click="editor.chain().focus().toggleBlockquote().run()"
>
<span class="i-tabler-quote" />
</button>
<input
ref="inputUrl"
v-model.trim="url"
class="input input-sm focus:outline-none"
:placeholder="placeholder"
@blur="showUrlInput = false"
>
<button class="btn btn-sm btn-square" @click="setLink">
<span class="i-tabler-link p-2" />
</button>
</div>
</BubbleMenu>
</template>
<style lang="pcss">
.menu-btn {
@apply btn btn-ghost btn-sm hover:bg-slate-200 rounded-md p-2;
}
.menu-btn > span {
@apply w-4;
}
</style>

View file

@ -2,19 +2,24 @@
import { EditorContent, useEditor } from '@tiptap/vue-3'
import StarterKit from '@tiptap/starter-kit'
import Typography from '@tiptap/extension-typography'
import Link from '@tiptap/extension-link'
import BubbleMenu from './BubbleMenu.vue'
const editor = useEditor({
content: '<p>Im running Tiptap with Vue.js. 🎉</p>',
extensions: [StarterKit, Typography],
extensions: [
StarterKit,
Typography,
Link.configure({
openOnClick: false,
}),
],
editable: true,
autofocus: true,
})
</script>
<template>
<BubbleMenu
v-if="editor"
:editor="editor" />
<BubbleMenu v-if="editor" :editor="editor" />
<EditorContent :editor="editor" />
</template>

View file

@ -9,3 +9,27 @@
.editor {
@apply mx-auto;
}
.btn-ghost {
@apply hover:bg-slate-200;
}
.btn-active{
@apply bg-slate-200;
}
.menu-btn {
@apply btn btn-ghost btn-sm rounded-md p-2;
}
.menu-btn > span {
@apply w-4;
}
.menu-btn.btn-active {
@apply bg-slate-200;
}
.input-group{
@apply h-4;
}