forked from Mirrors/elk
feat: basic integration with TipTap (#87)
This commit is contained in:
parent
019a36c9bb
commit
c2810fd5eb
14 changed files with 722 additions and 31 deletions
|
@ -14,6 +14,6 @@ const emojiObject = emojisArrayToObject(props.emojis || [])
|
||||||
|
|
||||||
export default () => h(
|
export default () => h(
|
||||||
'div',
|
'div',
|
||||||
{ class: 'rich-content' },
|
{ class: 'content-rich' },
|
||||||
contentToVNode(props.content, emojiObject),
|
contentToVNode(props.content, emojiObject),
|
||||||
)
|
)
|
||||||
|
|
|
@ -13,6 +13,6 @@ import { isPreviewHelpOpen, isPublishDialogOpen, isSigninDialogOpen, isUserSwitc
|
||||||
<HelpPreview />
|
<HelpPreview />
|
||||||
</ModalDialog>
|
</ModalDialog>
|
||||||
<ModalDialog v-model="isPublishDialogOpen">
|
<ModalDialog v-model="isPublishDialogOpen">
|
||||||
<PublishWidget draft-key="dialog" expanded min-w-180 p6 />
|
<PublishWidget draft-key="dialog" expanded min-w-180 />
|
||||||
</ModalDialog>
|
</ModalDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import type { CreateStatusParams, StatusVisibility } from 'masto'
|
import type { CreateStatusParams, StatusVisibility } from 'masto'
|
||||||
import { fileOpen } from 'browser-fs-access'
|
import { fileOpen } from 'browser-fs-access'
|
||||||
import { useDropZone } from '@vueuse/core'
|
import { useDropZone } from '@vueuse/core'
|
||||||
|
import { EditorContent } from '@tiptap/vue-3'
|
||||||
|
|
||||||
const {
|
const {
|
||||||
draftKey,
|
draftKey,
|
||||||
|
@ -15,10 +16,19 @@ const {
|
||||||
expanded?: boolean
|
expanded?: boolean
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const expanded = $ref(_expanded)
|
let isExpanded = $ref(_expanded)
|
||||||
let isSending = $ref(false)
|
let isSending = $ref(false)
|
||||||
let { draft } = $(useDraft(draftKey, inReplyToId))
|
let { draft } = $(useDraft(draftKey, inReplyToId))
|
||||||
|
|
||||||
|
const { editor } = useTiptap({
|
||||||
|
content: toRef(draft.params, 'status'),
|
||||||
|
placeholder,
|
||||||
|
autofocus: isExpanded,
|
||||||
|
onSubimit: publish,
|
||||||
|
onFocus() { isExpanded = true },
|
||||||
|
onPaste: handlePaste,
|
||||||
|
})
|
||||||
|
|
||||||
const status = $computed(() => {
|
const status = $computed(() => {
|
||||||
return {
|
return {
|
||||||
...draft.params,
|
...draft.params,
|
||||||
|
@ -87,11 +97,16 @@ function chooseVisibility(visibility: StatusVisibility) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function publish() {
|
async function publish() {
|
||||||
|
if (process.dev) {
|
||||||
|
alert(JSON.stringify(draft.params, null, 2))
|
||||||
|
return
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
isSending = true
|
isSending = true
|
||||||
if (!draft.editingStatus)
|
if (!draft.editingStatus)
|
||||||
await masto.statuses.create(status)
|
await masto.statuses.create(status)
|
||||||
else await masto.statuses.update(draft.editingStatus.id, status)
|
else
|
||||||
|
await masto.statuses.update(draft.editingStatus.id, status)
|
||||||
|
|
||||||
draft = getDefaultDraft({ inReplyToId })
|
draft = getDefaultDraft({ inReplyToId })
|
||||||
isPublishDialogOpen.value = false
|
isPublishDialogOpen.value = false
|
||||||
|
@ -111,6 +126,7 @@ async function onDrop(files: File[] | null) {
|
||||||
const { isOverDropZone } = useDropZone(dropZoneRef, onDrop)
|
const { isOverDropZone } = useDropZone(dropZoneRef, onDrop)
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
|
// Remove draft if it's empty
|
||||||
if (!draft.attachments.length && !draft.params.status) {
|
if (!draft.attachments.length && !draft.params.status) {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
delete currentUserDrafts.value[draftKey]
|
delete currentUserDrafts.value[draftKey]
|
||||||
|
@ -138,7 +154,7 @@ onUnmounted(() => {
|
||||||
<div
|
<div
|
||||||
ref="dropZoneRef"
|
ref="dropZoneRef"
|
||||||
flex flex-col gap-3 flex-1
|
flex flex-col gap-3 flex-1
|
||||||
border="2 dashed transparent" p-1
|
border="2 dashed transparent"
|
||||||
:class="[isSending ? 'pointer-events-none' : '', isOverDropZone ? '!border-primary' : '']"
|
:class="[isSending ? 'pointer-events-none' : '', isOverDropZone ? '!border-primary' : '']"
|
||||||
>
|
>
|
||||||
<div v-if="draft.params.sensitive">
|
<div v-if="draft.params.sensitive">
|
||||||
|
@ -151,22 +167,17 @@ onUnmounted(() => {
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<textarea
|
<EditorContent
|
||||||
v-model="draft.params.status"
|
:editor="editor"
|
||||||
:placeholder="placeholder"
|
:class="isExpanded ? 'min-h-120px' : ''"
|
||||||
h-80px
|
|
||||||
:class="expanded ? '!h-200px' : ''"
|
|
||||||
p2 border-rounded w-full bg-transparent
|
|
||||||
transition="height"
|
|
||||||
outline-none border="~ base"
|
|
||||||
@paste="handlePaste"
|
|
||||||
@focus="expanded = true"
|
|
||||||
@keydown.esc="expanded = false"
|
|
||||||
@keydown.ctrl.enter="publish"
|
|
||||||
@keydown.meta.enter="publish"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div flex="~ col gap-2" max-h-50vh overflow-auto>
|
<div v-if="isUploading" flex gap-1 items-center text-sm p1 text-primary>
|
||||||
|
<div i-ri:loader-2-fill animate-spin />
|
||||||
|
Uploading...
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="draft.attachments.length" flex="~ col gap-2" overflow-auto>
|
||||||
<PublishAttachment
|
<PublishAttachment
|
||||||
v-for="(att, idx) in draft.attachments" :key="att.id"
|
v-for="(att, idx) in draft.attachments" :key="att.id"
|
||||||
:attachment="att"
|
:attachment="att"
|
||||||
|
@ -174,18 +185,28 @@ onUnmounted(() => {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="isUploading" flex gap-2 justify-end items-center>
|
<div
|
||||||
<div op50 i-ri:loader-2-fill animate-spin text-2xl />
|
v-if="isExpanded" flex="~ gap-2" m="l--1" pt-2
|
||||||
Uploading...
|
border="t base"
|
||||||
</div>
|
>
|
||||||
|
|
||||||
<div flex="~ gap-2">
|
|
||||||
<CommonTooltip placement="bottom" content="Add images, a video or an audio file">
|
<CommonTooltip placement="bottom" content="Add images, a video or an audio file">
|
||||||
<button btn-action-icon @click="pickAttachments">
|
<button btn-action-icon @click="pickAttachments">
|
||||||
<div i-ri:upload-line />
|
<div i-ri:image-add-line />
|
||||||
</button>
|
</button>
|
||||||
</CommonTooltip>
|
</CommonTooltip>
|
||||||
|
|
||||||
|
<template v-if="editor">
|
||||||
|
<CommonTooltip placement="bottom" content="Toggle code block">
|
||||||
|
<button
|
||||||
|
btn-action-icon
|
||||||
|
:class="editor.isActive('codeBlock') ? 'op100' : 'op50'"
|
||||||
|
@click="editor?.chain().focus().toggleCodeBlock().run()"
|
||||||
|
>
|
||||||
|
<div i-ri:code-s-slash-line />
|
||||||
|
</button>
|
||||||
|
</CommonTooltip>
|
||||||
|
</template>
|
||||||
|
|
||||||
<div flex-auto />
|
<div flex-auto />
|
||||||
|
|
||||||
<CommonTooltip placement="bottom" content="Add content warning">
|
<CommonTooltip placement="bottom" content="Add content warning">
|
||||||
|
|
58
components/tiptap/TiptapMentionList.vue
Normal file
58
components/tiptap/TiptapMentionList.vue
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
const { items, command } = defineProps<{
|
||||||
|
items: any[]
|
||||||
|
command: Function
|
||||||
|
}>()
|
||||||
|
|
||||||
|
let selectedIndex = $ref(0)
|
||||||
|
|
||||||
|
watch(items, () => {
|
||||||
|
selectedIndex = 0
|
||||||
|
})
|
||||||
|
|
||||||
|
function onKeyDown(event: KeyboardEvent) {
|
||||||
|
if (event.key === 'ArrowUp') {
|
||||||
|
selectedIndex = ((selectedIndex + items.length) - 1) % items.length
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
else if (event.key === 'ArrowDown') {
|
||||||
|
selectedIndex = (selectedIndex + 1) % items.length
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
else if (event.key === 'Enter') {
|
||||||
|
selectItem(selectedIndex)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectItem(index: number) {
|
||||||
|
const item = items[index]
|
||||||
|
if (item)
|
||||||
|
command({ id: item })
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
onKeyDown,
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div relative bg-base text-base shadow border="~ base rounded" text-sm>
|
||||||
|
<template v-if="items.length">
|
||||||
|
<button
|
||||||
|
v-for="(item, index) in items"
|
||||||
|
:key="index"
|
||||||
|
:class="index === selectedIndex ? 'bg-active' : 'op50'"
|
||||||
|
block m0 w-full text-left px2 py1
|
||||||
|
@click="selectItem(index)"
|
||||||
|
>
|
||||||
|
{{ item }}asd
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
<div v-else block m0 w-full text-left px2 py1 italic op30>
|
||||||
|
No result
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
93
composables/tiptap.ts
Normal file
93
composables/tiptap.ts
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
import { Extension, useEditor } from '@tiptap/vue-3'
|
||||||
|
import Placeholder from '@tiptap/extension-placeholder'
|
||||||
|
import Document from '@tiptap/extension-document'
|
||||||
|
import Paragraph from '@tiptap/extension-paragraph'
|
||||||
|
import Text from '@tiptap/extension-text'
|
||||||
|
import Mention from '@tiptap/extension-mention'
|
||||||
|
import CodeBlock from '@tiptap/extension-code-block'
|
||||||
|
import CharacterCount from '@tiptap/extension-character-count'
|
||||||
|
import { Plugin } from 'prosemirror-state'
|
||||||
|
|
||||||
|
import type { Ref } from 'vue'
|
||||||
|
import { HashSuggestion, MentionSuggestion } from './tiptap/suggestion'
|
||||||
|
import { POST_CHARS_LIMIT } from '~/constants'
|
||||||
|
|
||||||
|
export interface UseTiptapOptions {
|
||||||
|
content: Ref<string | undefined>
|
||||||
|
placeholder: string
|
||||||
|
onSubimit: () => void
|
||||||
|
onFocus: () => void
|
||||||
|
onPaste: (event: ClipboardEvent) => void
|
||||||
|
autofocus: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useTiptap(options: UseTiptapOptions) {
|
||||||
|
const {
|
||||||
|
autofocus,
|
||||||
|
content,
|
||||||
|
placeholder,
|
||||||
|
} = options
|
||||||
|
|
||||||
|
const editor = useEditor({
|
||||||
|
content: content.value,
|
||||||
|
extensions: [
|
||||||
|
Document,
|
||||||
|
Paragraph,
|
||||||
|
Text,
|
||||||
|
Mention.configure({
|
||||||
|
suggestion: MentionSuggestion,
|
||||||
|
}),
|
||||||
|
Mention.configure({
|
||||||
|
suggestion: HashSuggestion,
|
||||||
|
}),
|
||||||
|
Placeholder.configure({
|
||||||
|
placeholder,
|
||||||
|
}),
|
||||||
|
CharacterCount.configure({
|
||||||
|
limit: POST_CHARS_LIMIT,
|
||||||
|
}),
|
||||||
|
CodeBlock,
|
||||||
|
Extension.create({
|
||||||
|
name: 'api',
|
||||||
|
addKeyboardShortcuts() {
|
||||||
|
return {
|
||||||
|
'Mod-Enter': () => {
|
||||||
|
options.onSubimit()
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onFocus() {
|
||||||
|
options.onFocus()
|
||||||
|
},
|
||||||
|
addProseMirrorPlugins() {
|
||||||
|
return [
|
||||||
|
new Plugin({
|
||||||
|
props: {
|
||||||
|
handleDOMEvents: {
|
||||||
|
paste(view, event) {
|
||||||
|
options.onPaste(event)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
onUpdate({ editor }) {
|
||||||
|
content.value = editor.getHTML()
|
||||||
|
},
|
||||||
|
editorProps: {
|
||||||
|
attributes: {
|
||||||
|
class: 'content-editor content-rich',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
autofocus,
|
||||||
|
editable: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
editor,
|
||||||
|
}
|
||||||
|
}
|
83
composables/tiptap/suggestion.ts
Normal file
83
composables/tiptap/suggestion.ts
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
import type { GetReferenceClientRect, Instance } from 'tippy.js'
|
||||||
|
import tippy from 'tippy.js'
|
||||||
|
import { VueRenderer } from '@tiptap/vue-3'
|
||||||
|
import type { SuggestionOptions } from '@tiptap/suggestion'
|
||||||
|
import { PluginKey } from 'prosemirror-state'
|
||||||
|
import TiptapMentionList from '~/components/tiptap/TiptapMentionList.vue'
|
||||||
|
|
||||||
|
export const MentionSuggestion: Partial<SuggestionOptions> = {
|
||||||
|
pluginKey: new PluginKey('mention'),
|
||||||
|
char: '@',
|
||||||
|
items({ query }) {
|
||||||
|
// TODO: query
|
||||||
|
return [
|
||||||
|
'TODO MENTION QUERY', 'Lea Thompson', 'Cyndi Lauper', 'Tom Cruise', 'Madonna', 'Jerry Hall', 'Joan Collins', 'Winona Ryder', 'Christina Applegate', 'Alyssa Milano', 'Molly Ringwald', 'Ally Sheedy', 'Debbie Harry', 'Olivia Newton-John', 'Elton John', 'Michael J. Fox', 'Axl Rose', 'Emilio Estevez', 'Ralph Macchio', 'Rob Lowe', 'Jennifer Grey', 'Mickey Rourke', 'John Cusack', 'Matthew Broderick', 'Justine Bateman', 'Lisa Bonet',
|
||||||
|
].filter(item => item.toLowerCase().startsWith(query.toLowerCase())).slice(0, 5)
|
||||||
|
},
|
||||||
|
render: createSuggestionRenderer(),
|
||||||
|
}
|
||||||
|
|
||||||
|
export const HashSuggestion: Partial<SuggestionOptions> = {
|
||||||
|
pluginKey: new PluginKey('hashtag'),
|
||||||
|
char: '#',
|
||||||
|
items({ query }) {
|
||||||
|
// TODO: query
|
||||||
|
return [
|
||||||
|
'TODO HASH QUERY',
|
||||||
|
].filter(item => item.toLowerCase().startsWith(query.toLowerCase())).slice(0, 5)
|
||||||
|
},
|
||||||
|
render: createSuggestionRenderer(),
|
||||||
|
}
|
||||||
|
|
||||||
|
function createSuggestionRenderer(): SuggestionOptions['render'] {
|
||||||
|
return () => {
|
||||||
|
let component: VueRenderer
|
||||||
|
let popup: Instance
|
||||||
|
|
||||||
|
return {
|
||||||
|
onStart: (props) => {
|
||||||
|
component = new VueRenderer(TiptapMentionList, {
|
||||||
|
props,
|
||||||
|
editor: props.editor,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!props.clientRect)
|
||||||
|
return
|
||||||
|
|
||||||
|
popup = tippy(document.body, {
|
||||||
|
getReferenceClientRect: props.clientRect as GetReferenceClientRect,
|
||||||
|
appendTo: () => document.body,
|
||||||
|
content: component.element,
|
||||||
|
showOnCreate: true,
|
||||||
|
interactive: true,
|
||||||
|
trigger: 'manual',
|
||||||
|
placement: 'bottom-start',
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
onUpdate(props) {
|
||||||
|
component.updateProps(props)
|
||||||
|
|
||||||
|
if (!props.clientRect)
|
||||||
|
return
|
||||||
|
|
||||||
|
popup?.setProps({
|
||||||
|
getReferenceClientRect: props.clientRect as GetReferenceClientRect,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
onKeyDown(props) {
|
||||||
|
if (props.event.key === 'Escape') {
|
||||||
|
popup?.hide()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return component?.ref?.onKeyDown(props.event)
|
||||||
|
},
|
||||||
|
|
||||||
|
onExit() {
|
||||||
|
popup?.destroy()
|
||||||
|
component?.destroy()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,8 @@ export const HOST_DOMAIN = process.dev
|
||||||
? 'http://localhost:3000'
|
? 'http://localhost:3000'
|
||||||
: 'https://elk.zone'
|
: 'https://elk.zone'
|
||||||
|
|
||||||
|
export const POST_CHARS_LIMIT = 500
|
||||||
|
|
||||||
export const DEFAULT_SERVER = 'mas.to'
|
export const DEFAULT_SERVER = 'mas.to'
|
||||||
|
|
||||||
export const STORAGE_KEY_DRAFTS = 'elk-drafts'
|
export const STORAGE_KEY_DRAFTS = 'elk-drafts'
|
||||||
|
|
|
@ -15,6 +15,7 @@ export default defineNuxtConfig({
|
||||||
'floating-vue/dist/style.css',
|
'floating-vue/dist/style.css',
|
||||||
'~/styles/vars.css',
|
'~/styles/vars.css',
|
||||||
'~/styles/global.css',
|
'~/styles/global.css',
|
||||||
|
'~/styles/tiptap.css',
|
||||||
'~/styles/dropdown.css',
|
'~/styles/dropdown.css',
|
||||||
],
|
],
|
||||||
alias: {
|
alias: {
|
||||||
|
|
10
package.json
10
package.json
|
@ -23,6 +23,15 @@
|
||||||
"@iconify-json/ri": "^1.1.4",
|
"@iconify-json/ri": "^1.1.4",
|
||||||
"@iconify-json/twemoji": "^1.1.6",
|
"@iconify-json/twemoji": "^1.1.6",
|
||||||
"@pinia/nuxt": "^0.4.5",
|
"@pinia/nuxt": "^0.4.5",
|
||||||
|
"@tiptap/extension-character-count": "2.0.0-beta.203",
|
||||||
|
"@tiptap/extension-code-block": "2.0.0-beta.203",
|
||||||
|
"@tiptap/extension-mention": "2.0.0-beta.203",
|
||||||
|
"@tiptap/extension-paragraph": "2.0.0-beta.203",
|
||||||
|
"@tiptap/extension-placeholder": "2.0.0-beta.203",
|
||||||
|
"@tiptap/extension-text": "2.0.0-beta.203",
|
||||||
|
"@tiptap/starter-kit": "2.0.0-beta.203",
|
||||||
|
"@tiptap/suggestion": "2.0.0-beta.203",
|
||||||
|
"@tiptap/vue-3": "2.0.0-beta.203",
|
||||||
"@types/fs-extra": "^9.0.13",
|
"@types/fs-extra": "^9.0.13",
|
||||||
"@types/js-yaml": "^4.0.5",
|
"@types/js-yaml": "^4.0.5",
|
||||||
"@types/prettier": "^2.7.1",
|
"@types/prettier": "^2.7.1",
|
||||||
|
@ -51,6 +60,7 @@
|
||||||
"sanitize-html": "^2.7.3",
|
"sanitize-html": "^2.7.3",
|
||||||
"shiki": "^0.11.1",
|
"shiki": "^0.11.1",
|
||||||
"theme-vitesse": "^0.6.0",
|
"theme-vitesse": "^0.6.0",
|
||||||
|
"tippy.js": "^6.3.7",
|
||||||
"typescript": "^4.9.3",
|
"typescript": "^4.9.3",
|
||||||
"ufo": "^1.0.0",
|
"ufo": "^1.0.0",
|
||||||
"unplugin-auto-import": "^0.11.5",
|
"unplugin-auto-import": "^0.11.5",
|
||||||
|
|
395
pnpm-lock.yaml
395
pnpm-lock.yaml
|
@ -8,6 +8,15 @@ specifiers:
|
||||||
'@iconify-json/ri': ^1.1.4
|
'@iconify-json/ri': ^1.1.4
|
||||||
'@iconify-json/twemoji': ^1.1.6
|
'@iconify-json/twemoji': ^1.1.6
|
||||||
'@pinia/nuxt': ^0.4.5
|
'@pinia/nuxt': ^0.4.5
|
||||||
|
'@tiptap/extension-character-count': 2.0.0-beta.203
|
||||||
|
'@tiptap/extension-code-block': 2.0.0-beta.203
|
||||||
|
'@tiptap/extension-mention': 2.0.0-beta.203
|
||||||
|
'@tiptap/extension-paragraph': 2.0.0-beta.203
|
||||||
|
'@tiptap/extension-placeholder': 2.0.0-beta.203
|
||||||
|
'@tiptap/extension-text': 2.0.0-beta.203
|
||||||
|
'@tiptap/starter-kit': 2.0.0-beta.203
|
||||||
|
'@tiptap/suggestion': 2.0.0-beta.203
|
||||||
|
'@tiptap/vue-3': 2.0.0-beta.203
|
||||||
'@types/fs-extra': ^9.0.13
|
'@types/fs-extra': ^9.0.13
|
||||||
'@types/js-yaml': ^4.0.5
|
'@types/js-yaml': ^4.0.5
|
||||||
'@types/prettier': ^2.7.1
|
'@types/prettier': ^2.7.1
|
||||||
|
@ -36,6 +45,7 @@ specifiers:
|
||||||
sanitize-html: ^2.7.3
|
sanitize-html: ^2.7.3
|
||||||
shiki: ^0.11.1
|
shiki: ^0.11.1
|
||||||
theme-vitesse: ^0.6.0
|
theme-vitesse: ^0.6.0
|
||||||
|
tippy.js: ^6.3.7
|
||||||
typescript: ^4.9.3
|
typescript: ^4.9.3
|
||||||
ufo: ^1.0.0
|
ufo: ^1.0.0
|
||||||
unplugin-auto-import: ^0.11.5
|
unplugin-auto-import: ^0.11.5
|
||||||
|
@ -49,6 +59,15 @@ devDependencies:
|
||||||
'@iconify-json/ri': 1.1.4
|
'@iconify-json/ri': 1.1.4
|
||||||
'@iconify-json/twemoji': 1.1.6
|
'@iconify-json/twemoji': 1.1.6
|
||||||
'@pinia/nuxt': 0.4.5_typescript@4.9.3
|
'@pinia/nuxt': 0.4.5_typescript@4.9.3
|
||||||
|
'@tiptap/extension-character-count': 2.0.0-beta.203
|
||||||
|
'@tiptap/extension-code-block': 2.0.0-beta.203
|
||||||
|
'@tiptap/extension-mention': 2.0.0-beta.203_66kmopqpbsmmkalw2shrvalvci
|
||||||
|
'@tiptap/extension-paragraph': 2.0.0-beta.203
|
||||||
|
'@tiptap/extension-placeholder': 2.0.0-beta.203
|
||||||
|
'@tiptap/extension-text': 2.0.0-beta.203
|
||||||
|
'@tiptap/starter-kit': 2.0.0-beta.203
|
||||||
|
'@tiptap/suggestion': 2.0.0-beta.203
|
||||||
|
'@tiptap/vue-3': 2.0.0-beta.203
|
||||||
'@types/fs-extra': 9.0.13
|
'@types/fs-extra': 9.0.13
|
||||||
'@types/js-yaml': 4.0.5
|
'@types/js-yaml': 4.0.5
|
||||||
'@types/prettier': 2.7.1
|
'@types/prettier': 2.7.1
|
||||||
|
@ -77,6 +96,7 @@ devDependencies:
|
||||||
sanitize-html: 2.7.3
|
sanitize-html: 2.7.3
|
||||||
shiki: 0.11.1
|
shiki: 0.11.1
|
||||||
theme-vitesse: 0.6.0
|
theme-vitesse: 0.6.0
|
||||||
|
tippy.js: 6.3.7
|
||||||
typescript: 4.9.3
|
typescript: 4.9.3
|
||||||
ufo: 1.0.0
|
ufo: 1.0.0
|
||||||
unplugin-auto-import: 0.11.5
|
unplugin-auto-import: 0.11.5
|
||||||
|
@ -926,6 +946,10 @@ packages:
|
||||||
resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==}
|
resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@popperjs/core/2.11.6:
|
||||||
|
resolution: {integrity: sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@rollup/plugin-alias/4.0.2_rollup@2.79.1:
|
/@rollup/plugin-alias/4.0.2_rollup@2.79.1:
|
||||||
resolution: {integrity: sha512-1hv7dBOZZwo3SEupxn4UA2N0EDThqSSS+wI1St1TNTBtOZvUchyIClyHcnDcjjrReTPZ47Faedrhblv4n+T5UQ==}
|
resolution: {integrity: sha512-1hv7dBOZZwo3SEupxn4UA2N0EDThqSSS+wI1St1TNTBtOZvUchyIClyHcnDcjjrReTPZ47Faedrhblv4n+T5UQ==}
|
||||||
engines: {node: '>=14.0.0'}
|
engines: {node: '>=14.0.0'}
|
||||||
|
@ -1066,6 +1090,283 @@ packages:
|
||||||
rollup: 2.79.1
|
rollup: 2.79.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/core/2.0.0-beta.203:
|
||||||
|
resolution: {integrity: sha512-iRkFv4jjRtI7b18quyO3C8rilD8T24S3KYrZ3idRRw+ifO0dTeuDsRKjlcDT815zJRYdz99s5/lGq2ES0vC2gA==}
|
||||||
|
dependencies:
|
||||||
|
prosemirror-commands: 1.3.1
|
||||||
|
prosemirror-keymap: 1.2.0
|
||||||
|
prosemirror-model: 1.18.3
|
||||||
|
prosemirror-schema-list: 1.2.2
|
||||||
|
prosemirror-state: 1.4.2
|
||||||
|
prosemirror-transform: 1.7.0
|
||||||
|
prosemirror-view: 1.29.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/extension-blockquote/2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4:
|
||||||
|
resolution: {integrity: sha512-e8jE9AZ5L21AO6exMxFWFgU0c0ygxWVcuYJRMiThNhj38NWCNoHGHDqXbOjh2kM9NoRnad9erFuilVgYRmXcTw==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.1
|
||||||
|
dependencies:
|
||||||
|
'@tiptap/core': 2.0.0-beta.203
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/extension-bold/2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4:
|
||||||
|
resolution: {integrity: sha512-MuhBt7O44hJZ/5N42wVSN/9YB0iXkFgRkltbXPaWDqrXQjbZh9NRXMbQw7pOuW+3gn4NmUP5cd6pe9qHII1MtA==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.193
|
||||||
|
dependencies:
|
||||||
|
'@tiptap/core': 2.0.0-beta.203
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/extension-bubble-menu/2.0.0-beta.203:
|
||||||
|
resolution: {integrity: sha512-5EdYWCi6SyKVpY6xPqD5S0u7Jz8CG/FjgnFng0FBBJ2dCvxbeVdwTWL/WwN3KmIkY8T91ScQtbJb0bruC+GIUw==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.193
|
||||||
|
dependencies:
|
||||||
|
prosemirror-state: 1.4.2
|
||||||
|
prosemirror-view: 1.29.1
|
||||||
|
tippy.js: 6.3.7
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/extension-bullet-list/2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4:
|
||||||
|
resolution: {integrity: sha512-u9uY4XL0y9cIwEsm8008fpMPGXr9IVxbbmRXGh19oRnBPS1C3vnxGmgThrXojYwEWkp+5NimoH/E6ljUbuNbBQ==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.193
|
||||||
|
dependencies:
|
||||||
|
'@tiptap/core': 2.0.0-beta.203
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/extension-character-count/2.0.0-beta.203:
|
||||||
|
resolution: {integrity: sha512-j/XzlqVXATzKqbStJyU2VlykIIjLraki8TK9vTTLagQB6lYTv/AJT6L/Y0Ei7yUSjKYOL6sL7/Rze8czqeykNw==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.193
|
||||||
|
dependencies:
|
||||||
|
prosemirror-model: 1.18.3
|
||||||
|
prosemirror-state: 1.4.2
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/extension-code-block/2.0.0-beta.203:
|
||||||
|
resolution: {integrity: sha512-wXN1POlJBA9NG0eTKRGoBQFX40+TQUvfYi3i1mDk47sNdtbITJIFR3WRkljqSWrFbKdLFKPADUaQ+k6f2KZm/w==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.193
|
||||||
|
dependencies:
|
||||||
|
prosemirror-state: 1.4.2
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/extension-code-block/2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4:
|
||||||
|
resolution: {integrity: sha512-wXN1POlJBA9NG0eTKRGoBQFX40+TQUvfYi3i1mDk47sNdtbITJIFR3WRkljqSWrFbKdLFKPADUaQ+k6f2KZm/w==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.193
|
||||||
|
dependencies:
|
||||||
|
'@tiptap/core': 2.0.0-beta.203
|
||||||
|
prosemirror-state: 1.4.2
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/extension-code/2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4:
|
||||||
|
resolution: {integrity: sha512-iYC26EI4V4aAh10dq6LuCbPgHHrNCURotn2jA90fOjFnCspIuAXdQsPPV6syCLIIUdjFT8t/dscijlhzMYzVOg==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.193
|
||||||
|
dependencies:
|
||||||
|
'@tiptap/core': 2.0.0-beta.203
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/extension-document/2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4:
|
||||||
|
resolution: {integrity: sha512-H0HyFvnlMl0dHujGO+/+xjmOgu3aTslWVNLT2hOxBvfCAwW4hLmxQVaaMr+75so68rr1ndTPGUnPtXlQHvtzbA==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.193
|
||||||
|
dependencies:
|
||||||
|
'@tiptap/core': 2.0.0-beta.203
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/extension-dropcursor/2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4:
|
||||||
|
resolution: {integrity: sha512-oR4WjZdNcxYeYuKDzugMgEZGH7c6uzkV6InewPpHSuKVcbzjF1HbS/EHgpBSRFvLRYJ+nrbJMzERLWn9ZS5njA==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.193
|
||||||
|
dependencies:
|
||||||
|
'@tiptap/core': 2.0.0-beta.203
|
||||||
|
prosemirror-dropcursor: 1.5.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/extension-floating-menu/2.0.0-beta.203:
|
||||||
|
resolution: {integrity: sha512-QiWXX9vmDTvP6jo/lwZpQ/7Sf2XCeD1RQQmWIC+cohfxdd606dMVvFhYt8OofjoWn+e4uxobEtfxkvA418zUkg==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.193
|
||||||
|
dependencies:
|
||||||
|
prosemirror-state: 1.4.2
|
||||||
|
prosemirror-view: 1.29.1
|
||||||
|
tippy.js: 6.3.7
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/extension-gapcursor/2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4:
|
||||||
|
resolution: {integrity: sha512-HwY2dwAyIBOy+V2+Dbyw59POtAxz7UER9R470SGabi9/M7rBhZYrzL0gs+V9OB4AH1OO5hib02l8Dcnq+KKF7A==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.193
|
||||||
|
dependencies:
|
||||||
|
'@tiptap/core': 2.0.0-beta.203
|
||||||
|
prosemirror-gapcursor: 1.3.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/extension-hard-break/2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4:
|
||||||
|
resolution: {integrity: sha512-FfMufoiIwzNTsTZkb6qaNpJbyh6dOYagnGzlDmjyvc6+wqdJWE4sxwVAcMO0j1tvCdkaozWeWSuJzYv4xZKMFA==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.193
|
||||||
|
dependencies:
|
||||||
|
'@tiptap/core': 2.0.0-beta.203
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/extension-heading/2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4:
|
||||||
|
resolution: {integrity: sha512-pjBQNwWya+eGffesgn/Fz+7xC+RoiRVNo5xjahZVSP2MVZwbvcq/UV+fIut1nu9WJgPfAPkYnBSXmbPp0SRB0g==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.193
|
||||||
|
dependencies:
|
||||||
|
'@tiptap/core': 2.0.0-beta.203
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/extension-history/2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4:
|
||||||
|
resolution: {integrity: sha512-3gaplasYTuHepP1gnP/p5qjN5Sz9QudXz3Vue+2j1XulTFDjoB83j4FSujnAPshw2hePXNxv1mdHeeJ219Odxw==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.193
|
||||||
|
dependencies:
|
||||||
|
'@tiptap/core': 2.0.0-beta.203
|
||||||
|
prosemirror-history: 1.3.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/extension-horizontal-rule/2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4:
|
||||||
|
resolution: {integrity: sha512-mvERa4IfFBPVG1he1b+urtQD8mk9nGzZif9yPMfcpDIW8ewJv/MUH/mEASxZbb7cqXOMAWZqp1rVpH/MLBgtfw==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.193
|
||||||
|
dependencies:
|
||||||
|
'@tiptap/core': 2.0.0-beta.203
|
||||||
|
prosemirror-state: 1.4.2
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/extension-italic/2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4:
|
||||||
|
resolution: {integrity: sha512-7X/Z6V2DnziNfHhIoCLHI+EKQoaz0nyjPvNvs7wfSno6LTYUz33bXBpPF7gNZPyBJK/F/znC2Mg2l6XzcI7c+g==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.193
|
||||||
|
dependencies:
|
||||||
|
'@tiptap/core': 2.0.0-beta.203
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/extension-list-item/2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4:
|
||||||
|
resolution: {integrity: sha512-hfVxILSkLGKH4AVkj1imyHu1hAJjV6gWPDm7zQDi9MtQEoxU3fH+5nLwedsrveDZZHguwjHc/B+JyGcljzVeeg==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.193
|
||||||
|
dependencies:
|
||||||
|
'@tiptap/core': 2.0.0-beta.203
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/extension-mention/2.0.0-beta.203_66kmopqpbsmmkalw2shrvalvci:
|
||||||
|
resolution: {integrity: sha512-GR29PExMNE0mnQ4r30fgi+6QStrtxErRomnxKWlMMCdb+pHEgKrk1rbcZeLMc+efoainDMzN4HkFSAWmdKTSDw==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.193
|
||||||
|
'@tiptap/suggestion': ^2.0.0-beta.193
|
||||||
|
dependencies:
|
||||||
|
'@tiptap/suggestion': 2.0.0-beta.203
|
||||||
|
prosemirror-model: 1.18.3
|
||||||
|
prosemirror-state: 1.4.2
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/extension-ordered-list/2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4:
|
||||||
|
resolution: {integrity: sha512-Dp+SzrJ4yrFheng8pAtow19/wviC2g4QcxT88ZVz4wjC6JTo0M6sOQg9slxvx+Q+VbqrmPdikbqTiE/Ef416ig==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.193
|
||||||
|
dependencies:
|
||||||
|
'@tiptap/core': 2.0.0-beta.203
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/extension-paragraph/2.0.0-beta.203:
|
||||||
|
resolution: {integrity: sha512-kqsW7KPl2orCEJiNjCRCY/p06TrTTiq2n2hxatFRbHwvpQC4Z71JgaRJ/28WCL61QVy9v2UwNmCT2NFxUvMLgg==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.193
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/extension-paragraph/2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4:
|
||||||
|
resolution: {integrity: sha512-kqsW7KPl2orCEJiNjCRCY/p06TrTTiq2n2hxatFRbHwvpQC4Z71JgaRJ/28WCL61QVy9v2UwNmCT2NFxUvMLgg==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.193
|
||||||
|
dependencies:
|
||||||
|
'@tiptap/core': 2.0.0-beta.203
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/extension-placeholder/2.0.0-beta.203:
|
||||||
|
resolution: {integrity: sha512-MMwCzCZdapY6+LIubo/c4KmdXM1NKc2sBu8ahWF97h9pfs7UGxYDtWoAAUQlV4IzFiC5OhpYHwhStOaD3LhWjw==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.193
|
||||||
|
dependencies:
|
||||||
|
prosemirror-model: 1.18.3
|
||||||
|
prosemirror-state: 1.4.2
|
||||||
|
prosemirror-view: 1.29.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/extension-strike/2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4:
|
||||||
|
resolution: {integrity: sha512-CxgaJybQs36AUn1PrXbiNbqliYkf4n7LM/NvqtkoXPLISvndqAEQGmx1hS0NdoqERoAIz2FTOBdoWrL0b60vFA==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.193
|
||||||
|
dependencies:
|
||||||
|
'@tiptap/core': 2.0.0-beta.203
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/extension-text/2.0.0-beta.203:
|
||||||
|
resolution: {integrity: sha512-hOAPb3C2nIFZNJaFCaWj72sgcXqxJNTazXcsiei9A/p0L4NAIVa0ySub7H3NxRvxY/hRLUniA6u3QTzMo7Xsug==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.193
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/extension-text/2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4:
|
||||||
|
resolution: {integrity: sha512-hOAPb3C2nIFZNJaFCaWj72sgcXqxJNTazXcsiei9A/p0L4NAIVa0ySub7H3NxRvxY/hRLUniA6u3QTzMo7Xsug==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.193
|
||||||
|
dependencies:
|
||||||
|
'@tiptap/core': 2.0.0-beta.203
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/starter-kit/2.0.0-beta.203:
|
||||||
|
resolution: {integrity: sha512-tKnQW1MA+9MijptQuIUlJYIeulMLhKRFbcR++UM/K1oRw6nlOyyvFz07prehIPwsjV0RsZg0TYYiuNTWOaEOAg==}
|
||||||
|
dependencies:
|
||||||
|
'@tiptap/core': 2.0.0-beta.203
|
||||||
|
'@tiptap/extension-blockquote': 2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4
|
||||||
|
'@tiptap/extension-bold': 2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4
|
||||||
|
'@tiptap/extension-bullet-list': 2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4
|
||||||
|
'@tiptap/extension-code': 2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4
|
||||||
|
'@tiptap/extension-code-block': 2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4
|
||||||
|
'@tiptap/extension-document': 2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4
|
||||||
|
'@tiptap/extension-dropcursor': 2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4
|
||||||
|
'@tiptap/extension-gapcursor': 2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4
|
||||||
|
'@tiptap/extension-hard-break': 2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4
|
||||||
|
'@tiptap/extension-heading': 2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4
|
||||||
|
'@tiptap/extension-history': 2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4
|
||||||
|
'@tiptap/extension-horizontal-rule': 2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4
|
||||||
|
'@tiptap/extension-italic': 2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4
|
||||||
|
'@tiptap/extension-list-item': 2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4
|
||||||
|
'@tiptap/extension-ordered-list': 2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4
|
||||||
|
'@tiptap/extension-paragraph': 2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4
|
||||||
|
'@tiptap/extension-strike': 2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4
|
||||||
|
'@tiptap/extension-text': 2.0.0-beta.203_ywil7uncaz323pl33xz5cqvwo4
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/suggestion/2.0.0-beta.203:
|
||||||
|
resolution: {integrity: sha512-Pqk8QgKB08Rinvpd0dQnWLr+SPwwlZF5NX/v3cGqZ18ZJvE3UahVJD+Suj6oTLsgMba5hsXbPAIdGMiy0Q9PUw==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.193
|
||||||
|
dependencies:
|
||||||
|
prosemirror-model: 1.18.3
|
||||||
|
prosemirror-state: 1.4.2
|
||||||
|
prosemirror-view: 1.29.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/vue-3/2.0.0-beta.203:
|
||||||
|
resolution: {integrity: sha512-JkRNyVJMnENZVYQRV6vvR6IO3UXq2sqwLbu3WeRKeTaqZtb1Tzt+80UA2vTELN+TB5PUGtaqs+MNrB94bdPGrA==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.193
|
||||||
|
vue: ^3.0.0
|
||||||
|
dependencies:
|
||||||
|
'@tiptap/extension-bubble-menu': 2.0.0-beta.203
|
||||||
|
'@tiptap/extension-floating-menu': 2.0.0-beta.203
|
||||||
|
prosemirror-state: 1.4.2
|
||||||
|
prosemirror-view: 1.29.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@trysound/sax/0.2.0:
|
/@trysound/sax/0.2.0:
|
||||||
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
|
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
|
||||||
engines: {node: '>=10.13.0'}
|
engines: {node: '>=10.13.0'}
|
||||||
|
@ -5424,6 +5725,10 @@ packages:
|
||||||
wcwidth: 1.0.1
|
wcwidth: 1.0.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/orderedmap/2.1.0:
|
||||||
|
resolution: {integrity: sha512-/pIFexOm6S70EPdznemIz3BQZoJ4VTFrhqzu0ACBqBgeLsLxq8e6Jim63ImIfwW/zAD1AlXpRMlOv3aghmo4dA==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/os-tmpdir/1.0.2:
|
/os-tmpdir/1.0.2:
|
||||||
resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==}
|
resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
@ -5997,6 +6302,82 @@ packages:
|
||||||
resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
|
resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/prosemirror-commands/1.3.1:
|
||||||
|
resolution: {integrity: sha512-XTporPgoECkOQACVw0JTe3RZGi+fls3/byqt+tXwGTkD7qLuB4KdVrJamDMJf4kfKga3uB8hZ+kUUyZ5oWpnfg==}
|
||||||
|
dependencies:
|
||||||
|
prosemirror-model: 1.18.3
|
||||||
|
prosemirror-state: 1.4.2
|
||||||
|
prosemirror-transform: 1.7.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/prosemirror-dropcursor/1.5.0:
|
||||||
|
resolution: {integrity: sha512-vy7i77ddKyXlu8kKBB3nlxLBnsWyKUmQIPB5x8RkYNh01QNp/qqGmdd5yZefJs0s3rtv5r7Izfu2qbtr+tYAMQ==}
|
||||||
|
dependencies:
|
||||||
|
prosemirror-state: 1.4.2
|
||||||
|
prosemirror-transform: 1.7.0
|
||||||
|
prosemirror-view: 1.29.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/prosemirror-gapcursor/1.3.1:
|
||||||
|
resolution: {integrity: sha512-GKTeE7ZoMsx5uVfc51/ouwMFPq0o8YrZ7Hx4jTF4EeGbXxBveUV8CGv46mSHuBBeXGmvu50guoV2kSnOeZZnUA==}
|
||||||
|
dependencies:
|
||||||
|
prosemirror-keymap: 1.2.0
|
||||||
|
prosemirror-model: 1.18.3
|
||||||
|
prosemirror-state: 1.4.2
|
||||||
|
prosemirror-view: 1.29.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/prosemirror-history/1.3.0:
|
||||||
|
resolution: {integrity: sha512-qo/9Wn4B/Bq89/YD+eNWFbAytu6dmIM85EhID+fz9Jcl9+DfGEo8TTSrRhP15+fFEoaPqpHSxlvSzSEbmlxlUA==}
|
||||||
|
dependencies:
|
||||||
|
prosemirror-state: 1.4.2
|
||||||
|
prosemirror-transform: 1.7.0
|
||||||
|
rope-sequence: 1.3.3
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/prosemirror-keymap/1.2.0:
|
||||||
|
resolution: {integrity: sha512-TdSfu+YyLDd54ufN/ZeD1VtBRYpgZnTPnnbY+4R08DDgs84KrIPEPbJL8t1Lm2dkljFx6xeBE26YWH3aIzkPKg==}
|
||||||
|
dependencies:
|
||||||
|
prosemirror-state: 1.4.2
|
||||||
|
w3c-keyname: 2.2.6
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/prosemirror-model/1.18.3:
|
||||||
|
resolution: {integrity: sha512-yUVejauEY3F1r7PDy4UJKEGeIU+KFc71JQl5sNvG66CLVdKXRjhWpBW6KMeduGsmGOsw85f6EGrs6QxIKOVILA==}
|
||||||
|
dependencies:
|
||||||
|
orderedmap: 2.1.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/prosemirror-schema-list/1.2.2:
|
||||||
|
resolution: {integrity: sha512-rd0pqSDp86p0MUMKG903g3I9VmElFkQpkZ2iOd3EOVg1vo5Cst51rAsoE+5IPy0LPXq64eGcCYlW1+JPNxOj2w==}
|
||||||
|
dependencies:
|
||||||
|
prosemirror-model: 1.18.3
|
||||||
|
prosemirror-state: 1.4.2
|
||||||
|
prosemirror-transform: 1.7.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/prosemirror-state/1.4.2:
|
||||||
|
resolution: {integrity: sha512-puuzLD2mz/oTdfgd8msFbe0A42j5eNudKAAPDB0+QJRw8cO1ygjLmhLrg9RvDpf87Dkd6D4t93qdef00KKNacQ==}
|
||||||
|
dependencies:
|
||||||
|
prosemirror-model: 1.18.3
|
||||||
|
prosemirror-transform: 1.7.0
|
||||||
|
prosemirror-view: 1.29.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/prosemirror-transform/1.7.0:
|
||||||
|
resolution: {integrity: sha512-O4T697Cqilw06Zvc3Wm+e237R6eZtJL/xGMliCi+Uo8VL6qHk6afz1qq0zNjT3eZMuYwnP8ZS0+YxX/tfcE9TQ==}
|
||||||
|
dependencies:
|
||||||
|
prosemirror-model: 1.18.3
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/prosemirror-view/1.29.1:
|
||||||
|
resolution: {integrity: sha512-OhujVZSDsh0l0PyHNdfaBj6DBkbhYaCfbaxmTeFrMKd/eWS+G6IC+OAbmR9IsLC8Se1HSbphMaXnsXjupHL3UQ==}
|
||||||
|
dependencies:
|
||||||
|
prosemirror-model: 1.18.3
|
||||||
|
prosemirror-state: 1.4.2
|
||||||
|
prosemirror-transform: 1.7.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
/protocols/2.0.1:
|
/protocols/2.0.1:
|
||||||
resolution: {integrity: sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==}
|
resolution: {integrity: sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==}
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -6236,6 +6617,10 @@ packages:
|
||||||
fsevents: 2.3.2
|
fsevents: 2.3.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/rope-sequence/1.3.3:
|
||||||
|
resolution: {integrity: sha512-85aZYCxweiD5J8yTEbw+E6A27zSnLPNDL0WfPdw3YYodq7WjnTKo0q4dtyQ2gz23iPT8Q9CUyJtAaUNcTxRf5Q==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/run-async/2.4.1:
|
/run-async/2.4.1:
|
||||||
resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==}
|
resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==}
|
||||||
engines: {node: '>=0.12.0'}
|
engines: {node: '>=0.12.0'}
|
||||||
|
@ -6732,6 +7117,12 @@ packages:
|
||||||
engines: {node: '>=14.0.0'}
|
engines: {node: '>=14.0.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/tippy.js/6.3.7:
|
||||||
|
resolution: {integrity: sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==}
|
||||||
|
dependencies:
|
||||||
|
'@popperjs/core': 2.11.6
|
||||||
|
dev: true
|
||||||
|
|
||||||
/tmp/0.0.33:
|
/tmp/0.0.33:
|
||||||
resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==}
|
resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==}
|
||||||
engines: {node: '>=0.6.0'}
|
engines: {node: '>=0.6.0'}
|
||||||
|
@ -7448,6 +7839,10 @@ packages:
|
||||||
'@vue/shared': 3.2.45
|
'@vue/shared': 3.2.45
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/w3c-keyname/2.2.6:
|
||||||
|
resolution: {integrity: sha512-f+fciywl1SJEniZHD6H+kUO8gOnwIr7f4ijKA6+ZvJFjeGi1r4PDLl53Ayud9O/rk64RqgoQine0feoeOU0kXg==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/wcwidth/1.0.1:
|
/wcwidth/1.0.1:
|
||||||
resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==}
|
resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
|
@ -24,11 +24,23 @@
|
||||||
background: #8886;
|
background: #8886;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::-moz-selection {
|
||||||
|
background: var(--c-bg-selection);
|
||||||
|
}
|
||||||
|
|
||||||
|
::selection {
|
||||||
|
background: var(--c-bg-selection);
|
||||||
|
}
|
||||||
|
|
||||||
/* Force vertical scrollbar to be always visible to avoid layout shift while loading the content */
|
/* Force vertical scrollbar to be always visible to avoid layout shift while loading the content */
|
||||||
html {
|
html {
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.zen .zen-hide {
|
||||||
|
--at-apply: op0 hover:op100 transition duration-600;
|
||||||
|
}
|
||||||
|
|
||||||
.custom-emoji {
|
.custom-emoji {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
max-height: 1.2em;
|
max-height: 1.2em;
|
||||||
|
@ -36,7 +48,7 @@ html {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rich-content {
|
.content-rich {
|
||||||
a {
|
a {
|
||||||
--at-apply: text-primary hover:underline hover:text-primary-active;
|
--at-apply: text-primary hover:underline hover:text-primary-active;
|
||||||
.invisible {
|
.invisible {
|
||||||
|
@ -46,7 +58,7 @@ html {
|
||||||
--at-apply: truncate overflow-hidden ws-nowrap;
|
--at-apply: truncate overflow-hidden ws-nowrap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b {
|
b, strong {
|
||||||
--at-apply: font-bold;
|
--at-apply: font-bold;
|
||||||
}
|
}
|
||||||
p {
|
p {
|
||||||
|
@ -62,6 +74,14 @@ html {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.zen .zen-hide {
|
.content-editor {
|
||||||
--at-apply: op0 hover:op100 transition duration-600;
|
--at-apply: outline-none;
|
||||||
|
|
||||||
|
pre {
|
||||||
|
--at-apply: font-mono bg-code rounded px3 py2;
|
||||||
|
|
||||||
|
code {
|
||||||
|
--at-apply: bg-transparent text-0.8rem p0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
7
styles/tiptap.css
Normal file
7
styles/tiptap.css
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
.ProseMirror p.is-editor-empty:first-child::before {
|
||||||
|
content: attr(data-placeholder);
|
||||||
|
float: left;
|
||||||
|
pointer-events: none;
|
||||||
|
height: 0;
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
|
@ -5,6 +5,7 @@
|
||||||
--c-bg-base: #fff;
|
--c-bg-base: #fff;
|
||||||
--c-bg-active: #f6f6f6;
|
--c-bg-active: #f6f6f6;
|
||||||
--c-bg-code: #00000006;
|
--c-bg-code: #00000006;
|
||||||
|
--c-bg-selection: #8885;
|
||||||
--c-text-base: #222;
|
--c-text-base: #222;
|
||||||
--c-text-secondary: #888;
|
--c-text-secondary: #888;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { renderToString } from 'vue/server-renderer'
|
||||||
import { format } from 'prettier'
|
import { format } from 'prettier'
|
||||||
import { contentToVNode } from '~/composables/content'
|
import { contentToVNode } from '~/composables/content'
|
||||||
|
|
||||||
describe('rich-content', () => {
|
describe('content-rich', () => {
|
||||||
it('empty', async () => {
|
it('empty', async () => {
|
||||||
const { formatted } = await render('')
|
const { formatted } = await render('')
|
||||||
expect(formatted).toMatchSnapshot()
|
expect(formatted).toMatchSnapshot()
|
||||||
|
|
Loading…
Reference in a new issue