feat: basic integration with TipTap (#87)
parent
019a36c9bb
commit
c2810fd5eb
|
@ -14,6 +14,6 @@ const emojiObject = emojisArrayToObject(props.emojis || [])
|
|||
|
||||
export default () => h(
|
||||
'div',
|
||||
{ class: 'rich-content' },
|
||||
{ class: 'content-rich' },
|
||||
contentToVNode(props.content, emojiObject),
|
||||
)
|
||||
|
|
|
@ -13,6 +13,6 @@ import { isPreviewHelpOpen, isPublishDialogOpen, isSigninDialogOpen, isUserSwitc
|
|||
<HelpPreview />
|
||||
</ModalDialog>
|
||||
<ModalDialog v-model="isPublishDialogOpen">
|
||||
<PublishWidget draft-key="dialog" expanded min-w-180 p6 />
|
||||
<PublishWidget draft-key="dialog" expanded min-w-180 />
|
||||
</ModalDialog>
|
||||
</template>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import type { CreateStatusParams, StatusVisibility } from 'masto'
|
||||
import { fileOpen } from 'browser-fs-access'
|
||||
import { useDropZone } from '@vueuse/core'
|
||||
import { EditorContent } from '@tiptap/vue-3'
|
||||
|
||||
const {
|
||||
draftKey,
|
||||
|
@ -15,10 +16,19 @@ const {
|
|||
expanded?: boolean
|
||||
}>()
|
||||
|
||||
const expanded = $ref(_expanded)
|
||||
let isExpanded = $ref(_expanded)
|
||||
let isSending = $ref(false)
|
||||
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(() => {
|
||||
return {
|
||||
...draft.params,
|
||||
|
@ -87,11 +97,16 @@ function chooseVisibility(visibility: StatusVisibility) {
|
|||
}
|
||||
|
||||
async function publish() {
|
||||
if (process.dev) {
|
||||
alert(JSON.stringify(draft.params, null, 2))
|
||||
return
|
||||
}
|
||||
try {
|
||||
isSending = true
|
||||
if (!draft.editingStatus)
|
||||
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 })
|
||||
isPublishDialogOpen.value = false
|
||||
|
@ -111,6 +126,7 @@ async function onDrop(files: File[] | null) {
|
|||
const { isOverDropZone } = useDropZone(dropZoneRef, onDrop)
|
||||
|
||||
onUnmounted(() => {
|
||||
// Remove draft if it's empty
|
||||
if (!draft.attachments.length && !draft.params.status) {
|
||||
nextTick(() => {
|
||||
delete currentUserDrafts.value[draftKey]
|
||||
|
@ -138,7 +154,7 @@ onUnmounted(() => {
|
|||
<div
|
||||
ref="dropZoneRef"
|
||||
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' : '']"
|
||||
>
|
||||
<div v-if="draft.params.sensitive">
|
||||
|
@ -151,22 +167,17 @@ onUnmounted(() => {
|
|||
>
|
||||
</div>
|
||||
|
||||
<textarea
|
||||
v-model="draft.params.status"
|
||||
:placeholder="placeholder"
|
||||
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"
|
||||
<EditorContent
|
||||
:editor="editor"
|
||||
:class="isExpanded ? 'min-h-120px' : ''"
|
||||
/>
|
||||
|
||||
<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
|
||||
v-for="(att, idx) in draft.attachments" :key="att.id"
|
||||
:attachment="att"
|
||||
|
@ -174,18 +185,28 @@ onUnmounted(() => {
|
|||
/>
|
||||
</div>
|
||||
|
||||
<div v-if="isUploading" flex gap-2 justify-end items-center>
|
||||
<div op50 i-ri:loader-2-fill animate-spin text-2xl />
|
||||
Uploading...
|
||||
</div>
|
||||
|
||||
<div flex="~ gap-2">
|
||||
<div
|
||||
v-if="isExpanded" flex="~ gap-2" m="l--1" pt-2
|
||||
border="t base"
|
||||
>
|
||||
<CommonTooltip placement="bottom" content="Add images, a video or an audio file">
|
||||
<button btn-action-icon @click="pickAttachments">
|
||||
<div i-ri:upload-line />
|
||||
<div i-ri:image-add-line />
|
||||
</button>
|
||||
</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 />
|
||||
|
||||
<CommonTooltip placement="bottom" content="Add content warning">
|
||||
|
|
|
@ -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>
|
|
@ -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,
|
||||
}
|
||||
}
|
|
@ -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'
|
||||
: 'https://elk.zone'
|
||||
|
||||
export const POST_CHARS_LIMIT = 500
|
||||
|
||||
export const DEFAULT_SERVER = 'mas.to'
|
||||
|
||||
export const STORAGE_KEY_DRAFTS = 'elk-drafts'
|
||||
|
|
|
@ -15,6 +15,7 @@ export default defineNuxtConfig({
|
|||
'floating-vue/dist/style.css',
|
||||
'~/styles/vars.css',
|
||||
'~/styles/global.css',
|
||||
'~/styles/tiptap.css',
|
||||
'~/styles/dropdown.css',
|
||||
],
|
||||
alias: {
|
||||
|
|
10
package.json
10
package.json
|
@ -23,6 +23,15 @@
|
|||
"@iconify-json/ri": "^1.1.4",
|
||||
"@iconify-json/twemoji": "^1.1.6",
|
||||
"@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/js-yaml": "^4.0.5",
|
||||
"@types/prettier": "^2.7.1",
|
||||
|
@ -51,6 +60,7 @@
|
|||
"sanitize-html": "^2.7.3",
|
||||
"shiki": "^0.11.1",
|
||||
"theme-vitesse": "^0.6.0",
|
||||
"tippy.js": "^6.3.7",
|
||||
"typescript": "^4.9.3",
|
||||
"ufo": "^1.0.0",
|
||||
"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/twemoji': ^1.1.6
|
||||
'@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/js-yaml': ^4.0.5
|
||||
'@types/prettier': ^2.7.1
|
||||
|
@ -36,6 +45,7 @@ specifiers:
|
|||
sanitize-html: ^2.7.3
|
||||
shiki: ^0.11.1
|
||||
theme-vitesse: ^0.6.0
|
||||
tippy.js: ^6.3.7
|
||||
typescript: ^4.9.3
|
||||
ufo: ^1.0.0
|
||||
unplugin-auto-import: ^0.11.5
|
||||
|
@ -49,6 +59,15 @@ devDependencies:
|
|||
'@iconify-json/ri': 1.1.4
|
||||
'@iconify-json/twemoji': 1.1.6
|
||||
'@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/js-yaml': 4.0.5
|
||||
'@types/prettier': 2.7.1
|
||||
|
@ -77,6 +96,7 @@ devDependencies:
|
|||
sanitize-html: 2.7.3
|
||||
shiki: 0.11.1
|
||||
theme-vitesse: 0.6.0
|
||||
tippy.js: 6.3.7
|
||||
typescript: 4.9.3
|
||||
ufo: 1.0.0
|
||||
unplugin-auto-import: 0.11.5
|
||||
|
@ -926,6 +946,10 @@ packages:
|
|||
resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==}
|
||||
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:
|
||||
resolution: {integrity: sha512-1hv7dBOZZwo3SEupxn4UA2N0EDThqSSS+wI1St1TNTBtOZvUchyIClyHcnDcjjrReTPZ47Faedrhblv4n+T5UQ==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
|
@ -1066,6 +1090,283 @@ packages:
|
|||
rollup: 2.79.1
|
||||
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:
|
||||
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
|
@ -5424,6 +5725,10 @@ packages:
|
|||
wcwidth: 1.0.1
|
||||
dev: true
|
||||
|
||||
/orderedmap/2.1.0:
|
||||
resolution: {integrity: sha512-/pIFexOm6S70EPdznemIz3BQZoJ4VTFrhqzu0ACBqBgeLsLxq8e6Jim63ImIfwW/zAD1AlXpRMlOv3aghmo4dA==}
|
||||
dev: true
|
||||
|
||||
/os-tmpdir/1.0.2:
|
||||
resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
@ -5997,6 +6302,82 @@ packages:
|
|||
resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
|
||||
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:
|
||||
resolution: {integrity: sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==}
|
||||
dev: true
|
||||
|
@ -6236,6 +6617,10 @@ packages:
|
|||
fsevents: 2.3.2
|
||||
dev: true
|
||||
|
||||
/rope-sequence/1.3.3:
|
||||
resolution: {integrity: sha512-85aZYCxweiD5J8yTEbw+E6A27zSnLPNDL0WfPdw3YYodq7WjnTKo0q4dtyQ2gz23iPT8Q9CUyJtAaUNcTxRf5Q==}
|
||||
dev: true
|
||||
|
||||
/run-async/2.4.1:
|
||||
resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==}
|
||||
engines: {node: '>=0.12.0'}
|
||||
|
@ -6732,6 +7117,12 @@ packages:
|
|||
engines: {node: '>=14.0.0'}
|
||||
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:
|
||||
resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==}
|
||||
engines: {node: '>=0.6.0'}
|
||||
|
@ -7448,6 +7839,10 @@ packages:
|
|||
'@vue/shared': 3.2.45
|
||||
dev: true
|
||||
|
||||
/w3c-keyname/2.2.6:
|
||||
resolution: {integrity: sha512-f+fciywl1SJEniZHD6H+kUO8gOnwIr7f4ijKA6+ZvJFjeGi1r4PDLl53Ayud9O/rk64RqgoQine0feoeOU0kXg==}
|
||||
dev: true
|
||||
|
||||
/wcwidth/1.0.1:
|
||||
resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==}
|
||||
dependencies:
|
||||
|
|
|
@ -24,11 +24,23 @@
|
|||
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 */
|
||||
html {
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.zen .zen-hide {
|
||||
--at-apply: op0 hover:op100 transition duration-600;
|
||||
}
|
||||
|
||||
.custom-emoji {
|
||||
display: inline-block;
|
||||
max-height: 1.2em;
|
||||
|
@ -36,7 +48,7 @@ html {
|
|||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.rich-content {
|
||||
.content-rich {
|
||||
a {
|
||||
--at-apply: text-primary hover:underline hover:text-primary-active;
|
||||
.invisible {
|
||||
|
@ -46,7 +58,7 @@ html {
|
|||
--at-apply: truncate overflow-hidden ws-nowrap;
|
||||
}
|
||||
}
|
||||
b {
|
||||
b, strong {
|
||||
--at-apply: font-bold;
|
||||
}
|
||||
p {
|
||||
|
@ -62,6 +74,14 @@ html {
|
|||
}
|
||||
}
|
||||
|
||||
.zen .zen-hide {
|
||||
--at-apply: op0 hover:op100 transition duration-600;
|
||||
.content-editor {
|
||||
--at-apply: outline-none;
|
||||
|
||||
pre {
|
||||
--at-apply: font-mono bg-code rounded px3 py2;
|
||||
|
||||
code {
|
||||
--at-apply: bg-transparent text-0.8rem p0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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-active: #f6f6f6;
|
||||
--c-bg-code: #00000006;
|
||||
--c-bg-selection: #8885;
|
||||
--c-text-base: #222;
|
||||
--c-text-secondary: #888;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import { renderToString } from 'vue/server-renderer'
|
|||
import { format } from 'prettier'
|
||||
import { contentToVNode } from '~/composables/content'
|
||||
|
||||
describe('rich-content', () => {
|
||||
describe('content-rich', () => {
|
||||
it('empty', async () => {
|
||||
const { formatted } = await render('')
|
||||
expect(formatted).toMatchSnapshot()
|
||||
|
|
Loading…
Reference in New Issue