feat(editor): select language
This commit is contained in:
parent
c85d9bb913
commit
0acc0f7689
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
@ -10,7 +10,8 @@
|
||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
"masto",
|
"masto",
|
||||||
"Nuxtodon",
|
"Nuxtodon",
|
||||||
"unmute"
|
"unmute",
|
||||||
|
"unstorage"
|
||||||
],
|
],
|
||||||
"i18n-ally.localesPaths": [
|
"i18n-ally.localesPaths": [
|
||||||
"locales"
|
"locales"
|
||||||
|
|
|
@ -30,7 +30,7 @@ const { editor } = useTiptap({
|
||||||
get: () => draft.params.status,
|
get: () => draft.params.status,
|
||||||
set: newVal => draft.params.status = newVal,
|
set: newVal => draft.params.status = newVal,
|
||||||
}),
|
}),
|
||||||
placeholder: draft.placeholder,
|
placeholder: computed(() => draft.placeholder),
|
||||||
autofocus: shouldExpanded,
|
autofocus: shouldExpanded,
|
||||||
onSubmit: publish,
|
onSubmit: publish,
|
||||||
onFocus() { isExpanded = true },
|
onFocus() { isExpanded = true },
|
||||||
|
|
35
components/tiptap/TiptapCodeBlock.vue
Normal file
35
components/tiptap/TiptapCodeBlock.vue
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { NodeViewContent, NodeViewWrapper, nodeViewProps } from '@tiptap/vue-3'
|
||||||
|
|
||||||
|
const props = defineProps(nodeViewProps)
|
||||||
|
|
||||||
|
const languages = [
|
||||||
|
'js',
|
||||||
|
'ts',
|
||||||
|
]
|
||||||
|
|
||||||
|
const selectedLanguage = computed({
|
||||||
|
get() {
|
||||||
|
return props.node.attrs.language
|
||||||
|
},
|
||||||
|
set(language) {
|
||||||
|
props.updateAttributes({ language })
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<NodeViewWrapper>
|
||||||
|
<div relative my2>
|
||||||
|
<select v-model="selectedLanguage" contenteditable="false" absolute top-1 right-1 rounded px2 op0 hover:op100 focus:op100 transition>
|
||||||
|
<option :value="null">
|
||||||
|
plain
|
||||||
|
</option>
|
||||||
|
<option v-for="(language, index) in languages" :key="index" :value="language">
|
||||||
|
{{ language }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
<pre><code><NodeViewContent /></code></pre>
|
||||||
|
</div>
|
||||||
|
</NodeViewWrapper>
|
||||||
|
</template>
|
|
@ -1,23 +1,24 @@
|
||||||
import { Extension, useEditor } from '@tiptap/vue-3'
|
import { Extension, VueNodeViewRenderer, useEditor } from '@tiptap/vue-3'
|
||||||
import Placeholder from '@tiptap/extension-placeholder'
|
import Placeholder from '@tiptap/extension-placeholder'
|
||||||
import Document from '@tiptap/extension-document'
|
import Document from '@tiptap/extension-document'
|
||||||
import Paragraph from '@tiptap/extension-paragraph'
|
import Paragraph from '@tiptap/extension-paragraph'
|
||||||
import Text from '@tiptap/extension-text'
|
import Text from '@tiptap/extension-text'
|
||||||
import Mention from '@tiptap/extension-mention'
|
import Mention from '@tiptap/extension-mention'
|
||||||
import CodeBlock from '@tiptap/extension-code-block'
|
|
||||||
import CharacterCount from '@tiptap/extension-character-count'
|
import CharacterCount from '@tiptap/extension-character-count'
|
||||||
import HardBreak from '@tiptap/extension-hard-break'
|
import HardBreak from '@tiptap/extension-hard-break'
|
||||||
import Bold from '@tiptap/extension-bold'
|
import Bold from '@tiptap/extension-bold'
|
||||||
import Italic from '@tiptap/extension-italic'
|
import Italic from '@tiptap/extension-italic'
|
||||||
import Code from '@tiptap/extension-code'
|
import Code from '@tiptap/extension-code'
|
||||||
import { Plugin } from 'prosemirror-state'
|
import { Plugin } from 'prosemirror-state'
|
||||||
|
import CodeBlock from '@tiptap/extension-code-block'
|
||||||
|
|
||||||
import type { Ref } from 'vue'
|
import type { Ref } from 'vue'
|
||||||
import { HashSuggestion, MentionSuggestion } from './tiptap/suggestion'
|
import { HashSuggestion, MentionSuggestion } from './tiptap/suggestion'
|
||||||
|
import TiptapCodeBlock from '~/components/tiptap/TiptapCodeBlock.vue'
|
||||||
|
|
||||||
export interface UseTiptapOptions {
|
export interface UseTiptapOptions {
|
||||||
content: Ref<string | undefined>
|
content: Ref<string | undefined>
|
||||||
placeholder: string
|
placeholder: Ref<string | undefined>
|
||||||
onSubmit: () => void
|
onSubmit: () => void
|
||||||
onFocus: () => void
|
onFocus: () => void
|
||||||
onPaste: (event: ClipboardEvent) => void
|
onPaste: (event: ClipboardEvent) => void
|
||||||
|
@ -50,12 +51,17 @@ export function useTiptap(options: UseTiptapOptions) {
|
||||||
suggestion: HashSuggestion,
|
suggestion: HashSuggestion,
|
||||||
}),
|
}),
|
||||||
Placeholder.configure({
|
Placeholder.configure({
|
||||||
placeholder,
|
placeholder: placeholder.value,
|
||||||
}),
|
}),
|
||||||
CharacterCount.configure({
|
CharacterCount.configure({
|
||||||
limit: characterLimit.value,
|
limit: characterLimit.value,
|
||||||
}),
|
}),
|
||||||
CodeBlock,
|
CodeBlock
|
||||||
|
.extend({
|
||||||
|
addNodeView() {
|
||||||
|
return VueNodeViewRenderer(TiptapCodeBlock)
|
||||||
|
},
|
||||||
|
}),
|
||||||
Extension.create({
|
Extension.create({
|
||||||
name: 'api',
|
name: 'api',
|
||||||
addKeyboardShortcuts() {
|
addKeyboardShortcuts() {
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
"@pinia/nuxt": "^0.4.5",
|
"@pinia/nuxt": "^0.4.5",
|
||||||
"@tiptap/extension-character-count": "2.0.0-beta.204",
|
"@tiptap/extension-character-count": "2.0.0-beta.204",
|
||||||
"@tiptap/extension-code-block": "2.0.0-beta.204",
|
"@tiptap/extension-code-block": "2.0.0-beta.204",
|
||||||
|
"@tiptap/extension-code-block-lowlight": "2.0.0-beta.204",
|
||||||
"@tiptap/extension-mention": "2.0.0-beta.204",
|
"@tiptap/extension-mention": "2.0.0-beta.204",
|
||||||
"@tiptap/extension-paragraph": "2.0.0-beta.204",
|
"@tiptap/extension-paragraph": "2.0.0-beta.204",
|
||||||
"@tiptap/extension-placeholder": "2.0.0-beta.204",
|
"@tiptap/extension-placeholder": "2.0.0-beta.204",
|
||||||
|
@ -55,6 +56,7 @@
|
||||||
"fuse.js": "^6.6.2",
|
"fuse.js": "^6.6.2",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"lint-staged": "^13.0.4",
|
"lint-staged": "^13.0.4",
|
||||||
|
"lowlight": "^2.8.0",
|
||||||
"lru-cache": "^7.14.1",
|
"lru-cache": "^7.14.1",
|
||||||
"masto": "^4.7.0-rc1",
|
"masto": "^4.7.0-rc1",
|
||||||
"nuxt": "^3.0.0",
|
"nuxt": "^3.0.0",
|
||||||
|
|
|
@ -12,6 +12,7 @@ specifiers:
|
||||||
'@pinia/nuxt': ^0.4.5
|
'@pinia/nuxt': ^0.4.5
|
||||||
'@tiptap/extension-character-count': 2.0.0-beta.204
|
'@tiptap/extension-character-count': 2.0.0-beta.204
|
||||||
'@tiptap/extension-code-block': 2.0.0-beta.204
|
'@tiptap/extension-code-block': 2.0.0-beta.204
|
||||||
|
'@tiptap/extension-code-block-lowlight': 2.0.0-beta.204
|
||||||
'@tiptap/extension-mention': 2.0.0-beta.204
|
'@tiptap/extension-mention': 2.0.0-beta.204
|
||||||
'@tiptap/extension-paragraph': 2.0.0-beta.204
|
'@tiptap/extension-paragraph': 2.0.0-beta.204
|
||||||
'@tiptap/extension-placeholder': 2.0.0-beta.204
|
'@tiptap/extension-placeholder': 2.0.0-beta.204
|
||||||
|
@ -39,6 +40,7 @@ specifiers:
|
||||||
fuse.js: ^6.6.2
|
fuse.js: ^6.6.2
|
||||||
js-yaml: ^4.1.0
|
js-yaml: ^4.1.0
|
||||||
lint-staged: ^13.0.4
|
lint-staged: ^13.0.4
|
||||||
|
lowlight: ^2.8.0
|
||||||
lru-cache: ^7.14.1
|
lru-cache: ^7.14.1
|
||||||
masto: ^4.7.0-rc1
|
masto: ^4.7.0-rc1
|
||||||
nuxt: ^3.0.0
|
nuxt: ^3.0.0
|
||||||
|
@ -72,6 +74,7 @@ devDependencies:
|
||||||
'@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.204
|
'@tiptap/extension-character-count': 2.0.0-beta.204
|
||||||
'@tiptap/extension-code-block': 2.0.0-beta.204
|
'@tiptap/extension-code-block': 2.0.0-beta.204
|
||||||
|
'@tiptap/extension-code-block-lowlight': 2.0.0-beta.204_czakdrv4w4d5ggkubz4l2tz4ny
|
||||||
'@tiptap/extension-mention': 2.0.0-beta.204_ggkstofzpnfxkp3gzsos4mewvi
|
'@tiptap/extension-mention': 2.0.0-beta.204_ggkstofzpnfxkp3gzsos4mewvi
|
||||||
'@tiptap/extension-paragraph': 2.0.0-beta.204
|
'@tiptap/extension-paragraph': 2.0.0-beta.204
|
||||||
'@tiptap/extension-placeholder': 2.0.0-beta.204
|
'@tiptap/extension-placeholder': 2.0.0-beta.204
|
||||||
|
@ -99,6 +102,7 @@ devDependencies:
|
||||||
fuse.js: 6.6.2
|
fuse.js: 6.6.2
|
||||||
js-yaml: 4.1.0
|
js-yaml: 4.1.0
|
||||||
lint-staged: 13.0.4
|
lint-staged: 13.0.4
|
||||||
|
lowlight: 2.8.0
|
||||||
lru-cache: 7.14.1
|
lru-cache: 7.14.1
|
||||||
masto: 4.7.0-rc1
|
masto: 4.7.0-rc1
|
||||||
nuxt: 3.0.0_hsf322ms6xhhd4b5ne6lb74y4a
|
nuxt: 3.0.0_hsf322ms6xhhd4b5ne6lb74y4a
|
||||||
|
@ -1331,6 +1335,18 @@ packages:
|
||||||
prosemirror-state: 1.4.2
|
prosemirror-state: 1.4.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@tiptap/extension-code-block-lowlight/2.0.0-beta.204_czakdrv4w4d5ggkubz4l2tz4ny:
|
||||||
|
resolution: {integrity: sha512-6n2RWlMv7V3NANK+5UfxOMaK83ps8BucleQ/XdNcZuj/glTZco8Z+2E+kazW92c4IFrSgteriYg5ZqC2NBYXrg==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tiptap/core': ^2.0.0-beta.193
|
||||||
|
'@tiptap/extension-code-block': ^2.0.0-beta.193
|
||||||
|
dependencies:
|
||||||
|
'@tiptap/extension-code-block': 2.0.0-beta.204
|
||||||
|
prosemirror-model: 1.18.3
|
||||||
|
prosemirror-state: 1.4.2
|
||||||
|
prosemirror-view: 1.29.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@tiptap/extension-code-block/2.0.0-beta.204:
|
/@tiptap/extension-code-block/2.0.0-beta.204:
|
||||||
resolution: {integrity: sha512-IIkZsBT7rxhK7yHnM2LRQfS6i+HNQxU+E6tRtPYF40YSg1xMZSC/xDy0k+NEU/xM6ZVesRofW3voB6svFPPDtw==}
|
resolution: {integrity: sha512-IIkZsBT7rxhK7yHnM2LRQfS6i+HNQxU+E6tRtPYF40YSg1xMZSC/xDy0k+NEU/xM6ZVesRofW3voB6svFPPDtw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
@ -1578,6 +1594,12 @@ packages:
|
||||||
'@types/node': 18.11.9
|
'@types/node': 18.11.9
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@types/hast/2.3.4:
|
||||||
|
resolution: {integrity: sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==}
|
||||||
|
dependencies:
|
||||||
|
'@types/unist': 2.0.6
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@types/js-yaml/4.0.5:
|
/@types/js-yaml/4.0.5:
|
||||||
resolution: {integrity: sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==}
|
resolution: {integrity: sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -4337,6 +4359,12 @@ packages:
|
||||||
reusify: 1.0.4
|
reusify: 1.0.4
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/fault/2.0.1:
|
||||||
|
resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==}
|
||||||
|
dependencies:
|
||||||
|
format: 0.2.2
|
||||||
|
dev: true
|
||||||
|
|
||||||
/fetch-blob/3.2.0:
|
/fetch-blob/3.2.0:
|
||||||
resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==}
|
resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==}
|
||||||
engines: {node: ^12.20 || >= 14.13}
|
engines: {node: ^12.20 || >= 14.13}
|
||||||
|
@ -4447,6 +4475,11 @@ packages:
|
||||||
mime-types: 2.1.35
|
mime-types: 2.1.35
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/format/0.2.2:
|
||||||
|
resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==}
|
||||||
|
engines: {node: '>=0.4.x'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/formdata-polyfill/4.0.10:
|
/formdata-polyfill/4.0.10:
|
||||||
resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
|
resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
|
||||||
engines: {node: '>=12.20.0'}
|
engines: {node: '>=12.20.0'}
|
||||||
|
@ -4770,6 +4803,11 @@ packages:
|
||||||
tslib: 2.4.1
|
tslib: 2.4.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/highlight.js/11.7.0:
|
||||||
|
resolution: {integrity: sha512-1rRqesRFhMO/PRF+G86evnyJkCgaZFOI+Z6kdj15TA18funfoqJXvgPCLSf0SWq3SRfg1j3HlDs8o4s3EGq1oQ==}
|
||||||
|
engines: {node: '>=12.0.0'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/hookable/5.4.2:
|
/hookable/5.4.2:
|
||||||
resolution: {integrity: sha512-6rOvaUiNKy9lET1X0ECnyZ5O5kSV0PJbtA5yZUgdEF7fGJEVwSLSislltyt7nFwVVALYHQJtfGeAR2Y0A0uJkg==}
|
resolution: {integrity: sha512-6rOvaUiNKy9lET1X0ECnyZ5O5kSV0PJbtA5yZUgdEF7fGJEVwSLSislltyt7nFwVVALYHQJtfGeAR2Y0A0uJkg==}
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -5481,6 +5519,14 @@ packages:
|
||||||
tslib: 2.4.1
|
tslib: 2.4.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/lowlight/2.8.0:
|
||||||
|
resolution: {integrity: sha512-WeExw1IKEkel9ZcYwzpvcFzORIB0IlleTcxJYoEuUgHASuYe/OBYbV6ym/AetG7unNVCBU/SXpgTgs2nT93mhg==}
|
||||||
|
dependencies:
|
||||||
|
'@types/hast': 2.3.4
|
||||||
|
fault: 2.0.1
|
||||||
|
highlight.js: 11.7.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
/lru-cache/6.0.0:
|
/lru-cache/6.0.0:
|
||||||
resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
|
resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
Loading…
Reference in a new issue