Revert "refactor(front): replace MarkdownInputField with RichInputField for improved JSON handling in text uploads, update Tiptap component to support JSONContent, and increment dependency versions for better compatibility"

This reverts commit e959a0bc3e.
This commit is contained in:
keven1024
2025-10-16 15:43:55 +08:00
parent 083005dac3
commit 0df8ee0a8d
5 changed files with 110 additions and 130 deletions

View File

@@ -0,0 +1,13 @@
<template>
<Tiptap v-model="value" />
</template>
<script setup lang="ts">
import Tiptap from '@/components/Tiptap.vue'
import type { RuleExpression } from 'vee-validate'
const props = defineProps<{
name: string
rules?: RuleExpression<string>
}>()
const { value, } = useField<string>(props.name, props.rules)
</script>

View File

@@ -1,20 +0,0 @@
<template>
<Tiptap :model-value="jsonValue" @update:model-value="(v) => setValue(JSON.stringify(v))" />
</template>
<script setup lang="ts">
import Tiptap from '@/components/Tiptap.vue'
import type { RuleExpression } from 'vee-validate'
const props = defineProps<{
name: string
rules?: RuleExpression<string>
}>()
const { value, setValue } = useField<string>(props.name, props.rules)
const jsonValue = computed(() => {
try {
return value.value ? JSON.parse(value.value) : {}
} catch (error) {
return {}
}
})
</script>

View File

@@ -1,92 +1,74 @@
<script lang="ts" setup>
import RichInputField from '@/components/Field/RichInputField.vue'
import FormButton from '@/components/Field/FormButton.vue'
import Button from '@/components/ui/button/Button.vue'
import showDrawer from '@/lib/showDrawer'
import { h } from 'vue'
import TextShareDrawer from '@/components/Drawer/TextShareDrawer.vue'
import { cx } from 'class-variance-authority'
import PickupShareBtn from '@/components/PickupShareBtn.vue'
import { isEmpty } from 'lodash-es'
const form = useFormContext()
const { t } = useI18n()
const isEmptyRichText = (value: string) => {
if (isEmpty(value)) return true
try {
const { content } = JSON.parse(value) || {}
return (
content?.reduce((acc: boolean, item: any) => {
const { type, content } = item || {}
if (!type || !['paragraph'].includes(type)) {
return acc
}
return acc + (content?.length ?? 0)
}, 0) == 0
)
} catch (error) {
return true
}
}
const isEmptyText = computed(() => isEmptyRichText(form?.values.text))
import MarkdownInputField from "@/components/Field/MarkdownInputField.vue";
import FormButton from "@/components/Field/FormButton.vue";
import Button from "@/components/ui/button/Button.vue";
import showDrawer from "@/lib/showDrawer";
import { h } from "vue";
import TextShareDrawer from "@/components/Drawer/TextShareDrawer.vue";
import { cx } from "class-variance-authority";
import PickupShareBtn from "@/components/PickupShareBtn.vue";
const form = useFormContext();
const { t } = useI18n();
const emit = defineEmits<{
(e: 'change', key: string): void
}>()
(e: "change", key: string): void;
}>();
const handleTextShare = ({ type, config }: { type: string; config: any }) => {
form?.setFieldValue('handle_type', type)
form?.setFieldValue('config', config)
emit('change', 'result')
}
form?.setFieldValue("handle_type", type);
form?.setFieldValue("config", config);
emit("change", "result");
};
</script>
<template>
<div class="gap-5 flex flex-col">
<div class="text-xl font-normal">{{ t('text.uploadText') }}</div>
<div class="relative">
<RichInputField
name="text"
:placeholder="t('text.uploadTextPlaceholder')"
class="max-h-[50vh] min-h-40 overflow-y-auto max-w-full [&>*]:pr-10"
:rules="(v) => !isEmptyRichText(v)"
/>
<Button
variant="ghost"
size="icon"
:class="
cx(
'absolute right-2 top-2 hover:bg-black/10 transition-all duration-300',
!isEmptyText ? 'opacity-100' : 'opacity-0 pointer-events-none'
)
"
@click="
() => {
form?.setValues({ text: '' })
}
"
>
<LucideX />
</Button>
</div>
<div class="flex flex-row gap-3">
<FormButton
@click="
async (form) => {
const { text } = form?.values || {}
showDrawer({
render: ({ hide }) =>
h(TextShareDrawer, {
hide,
text,
onTextHandle: handleTextShare,
}),
})
}
"
>
<LucideShare class="size-4" />{{ t('btn.submit') }}
</FormButton>
<PickupShareBtn />
</div>
<div class="gap-5 flex flex-col">
<div class="text-xl font-normal">{{ t("text.uploadText") }}</div>
<div class="relative">
<MarkdownInputField
name="text"
:placeholder="t('text.uploadTextPlaceholder')"
class="max-h-[50vh] min-h-40 overflow-y-auto max-w-full [&>*]:pr-10"
rules="required"
/>
<Button
variant="ghost"
size="icon"
:class="
cx(
'absolute right-2 top-2 hover:bg-black/10 transition-all duration-300',
form?.values.text?.length > 0
? 'opacity-100'
: 'opacity-0 pointer-events-none',
)
"
@click="
() => {
form?.setValues({ text: '' });
}
"
>
<LucideX />
</Button>
</div>
<div class="flex flex-row gap-3">
<FormButton
@click="
async (form) => {
const { text } = form?.values || {};
showDrawer({
render: ({ hide }) =>
h(TextShareDrawer, {
hide,
text,
onTextHandle: handleTextShare,
}),
});
}
"
>
<LucideShare class="size-4" />{{ t("btn.submit") }}
</FormButton>
<PickupShareBtn />
</div>
</div>
</template>

View File

@@ -1,13 +1,14 @@
<script setup lang="ts">
import { Editor, EditorContent, type JSONContent } from '@tiptap/vue-3'
import { Editor, EditorContent } from '@tiptap/vue-3'
import StarterKit from '@tiptap/starter-kit'
import { Markdown } from 'tiptap-markdown'
import Placeholder from '@tiptap/extension-placeholder'
const props = defineProps<{
modelValue?: JSONContent
modelValue?: string
placeholder?: string
}>()
const emit = defineEmits<{
(e: 'update:modelValue', value?: JSONContent): void
(e: 'update:modelValue', value: string): void
}>()
const editor = ref<Editor | undefined>(undefined)
@@ -16,20 +17,24 @@ onMounted(() => {
content: props.modelValue,
extensions: [
StarterKit,
Markdown.configure({
transformPastedText: true,
transformCopiedText: true,
}),
Placeholder.configure({
placeholder: props.placeholder ?? '',
}),
// CommandsPlugin,
],
onUpdate: (v) => {
emit('update:modelValue', editor.value?.getJSON?.())
onUpdate: () => {
emit('update:modelValue', editor.value?.storage?.markdown?.getMarkdown() ?? '')
},
})
})
watch(
() => props.modelValue,
(value) => {
if (value !== editor.value?.getJSON?.()) {
if (value !== editor.value?.storage?.markdown?.getMarkdown()) {
editor.value?.commands.setContent(value ?? '')
}
}

View File

@@ -13,20 +13,20 @@
"@nuxt/image": "1.10.0",
"@nuxtjs/i18n": "9.5.5",
"@pinia/nuxt": "^0.11.2",
"@tailwindcss/postcss": "^4.1.14",
"@tailwindcss/vite": "^4.1.14",
"@tanstack/vue-query": "^5.90.2",
"@tiptap/extension-blockquote": "^3.6.6",
"@tiptap/extension-bold": "^3.6.6",
"@tiptap/extension-heading": "^3.6.6",
"@tiptap/extension-italic": "^3.6.6",
"@tiptap/extension-paragraph": "^3.6.6",
"@tiptap/extension-placeholder": "^3.6.6",
"@tiptap/extension-strike": "^3.6.6",
"@tiptap/extension-text": "^3.6.6",
"@tiptap/pm": "^3.6.6",
"@tiptap/starter-kit": "^3.6.6",
"@tiptap/vue-3": "^3.6.6",
"@tailwindcss/postcss": "^4.1.13",
"@tailwindcss/vite": "^4.1.13",
"@tanstack/vue-query": "^5.90.1",
"@tiptap/extension-blockquote": "^2.26.1",
"@tiptap/extension-bold": "^2.26.1",
"@tiptap/extension-heading": "^2.26.1",
"@tiptap/extension-italic": "^2.26.1",
"@tiptap/extension-paragraph": "^2.26.1",
"@tiptap/extension-placeholder": "^2.26.1",
"@tiptap/extension-strike": "^2.26.1",
"@tiptap/extension-text": "^2.26.1",
"@tiptap/pm": "^2.26.1",
"@tiptap/starter-kit": "^2.26.1",
"@tiptap/vue-3": "^2.26.1",
"@unovis/ts": "^1.6.1",
"@unovis/vue": "^1.6.1",
"@vee-validate/nuxt": "^4.15.1",
@@ -39,22 +39,22 @@
"lodash-es": "^4.17.21",
"lucide-vue-next": "^0.542.0",
"markdown-it": "^14.1.0",
"motion-v": "^1.7.2",
"motion-v": "^1.7.1",
"nanoid": "^5.1.6",
"nuxt": "4.1.2",
"nuxt-lucide-icons": "1.0.5",
"pinia": "^3.0.3",
"pixi.js": "^8.14.0",
"pixi.js": "^8.13.2",
"qrcode": "^1.5.4",
"reka-ui": "^2.5.1",
"reka-ui": "^2.5.0",
"shadcn-nuxt": "2.0.1",
"spark-md5": "^3.0.2",
"tailwind-merge": "^3.3.1",
"tailwindcss": "^4.1.14",
"tailwindcss": "^4.1.13",
"tiptap-markdown": "^0.8.10",
"tw-animate-css": "^1.4.0",
"tw-animate-css": "^1.3.8",
"vaul-vue": "^0.4.1",
"vue": "^3.5.22",
"vue": "^3.5.21",
"vue-router": "^4.5.1",
"vue-sonner": "^1.3.2",
"vue3-pixi": "1.0.0-beta.2"
@@ -64,7 +64,7 @@
"esbuild": "0.25.6"
},
"devDependencies": {
"@tailwindcss/typography": "^0.5.19",
"@tailwindcss/typography": "^0.5.18",
"@types/lodash-es": "^4.17.12",
"@types/markdown-it": "^14.1.2",
"@types/qrcode": "^1.5.5",