mirror of
https://codeberg.org/Sevichecc/Seigwai.git
synced 2025-04-30 07:49:30 +08:00
Add Url input menu
This commit is contained in:
parent
d2f26c1f64
commit
e34e051f41
5 changed files with 147 additions and 48 deletions
|
@ -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",
|
||||
|
|
|
@ -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'}
|
||||
|
|
|
@ -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>
|
|
@ -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>I’m 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>
|
||||
|
|
|
@ -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;
|
||||
}
|
Loading…
Reference in a new issue