refactor(editor): migrate to native @tiptap/markdown extension

- Replace community `tiptap-markdown` with official `@tiptap/markdown`
- Use new API: `editor.getMarkdown()` instead of `editor.storage.markdown.getMarkdown()`
- Add `contentType: 'markdown'` for direct markdown loading
- Remove unused `@tiptap/extension-color` (no UI was using it)
- Remove custom MarkdownStorage type declaration

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Anton Tranelis 2026-01-12 18:15:18 +01:00
parent 02bce69ab3
commit 77391dde19
3 changed files with 468 additions and 412 deletions

View File

@ -103,11 +103,11 @@
"@maplibre/maplibre-gl-leaflet": "^0.1.3",
"@tiptap/core": "^3.13.0",
"@tiptap/extension-bubble-menu": "^3.13.0",
"@tiptap/extension-color": "^3.13.0",
"@tiptap/extension-image": "^3.13.0",
"@tiptap/extension-link": "^3.13.0",
"@tiptap/extension-placeholder": "^3.13.0",
"@tiptap/extension-youtube": "^3.13.0",
"@tiptap/markdown": "^3.15.3",
"@tiptap/pm": "^3.6.5",
"@tiptap/react": "^3.13.0",
"@tiptap/starter-kit": "^3.13.0",
@ -132,7 +132,6 @@
"react-toastify": "^9.1.3",
"remark-breaks": "^4.0.0",
"tippy.js": "^6.3.7",
"tiptap-markdown": "^0.9.0",
"yet-another-react-lightbox": "^3.28.0"
},
"imports": {

View File

@ -1,11 +1,10 @@
import { Color } from '@tiptap/extension-color'
import { Image } from '@tiptap/extension-image'
import { Link } from '@tiptap/extension-link'
import { Placeholder } from '@tiptap/extension-placeholder'
import { Markdown } from '@tiptap/markdown'
import { EditorContent, useEditor } from '@tiptap/react'
import { StarterKit } from '@tiptap/starter-kit'
import { useEffect, useMemo } from 'react'
import { Markdown } from 'tiptap-markdown'
import { useGetItemColor } from '#components/Map/hooks/useItemColor'
import { useItems } from '#components/Map/hooks/useItems'
@ -17,13 +16,9 @@ import {
createHashtagSuggestion,
createItemMentionSuggestion,
} from '#components/TipTap/extensions'
import { preprocessMarkdown } from '#components/TipTap/utils/preprocessMarkdown'
import { InputLabel } from './InputLabel'
import { TextEditorMenu } from './TextEditorMenu'
import type { MarkdownStorage } from 'tiptap-markdown'
interface RichTextEditorProps {
labelTitle?: string
labelStyle?: string
@ -34,11 +29,6 @@ interface RichTextEditorProps {
updateFormValue?: (value: string) => void
}
declare module '@tiptap/core' {
interface Storage {
markdown: MarkdownStorage
}
}
/**
* @category Input
@ -64,7 +54,7 @@ export function RichTextEditor({
)
const handleChange = () => {
let newValue: string | undefined = editor.storage.markdown.getMarkdown()
let newValue: string | undefined = editor.getMarkdown()
const regex = /!\[.*?\]\(.*?\)/g
newValue = newValue.replace(regex, (match: string) => match + '\n\n')
@ -75,7 +65,6 @@ export function RichTextEditor({
const editor = useEditor({
extensions: [
Color.configure({ types: ['textStyle', 'listItem'] }),
StarterKit.configure({
bulletList: {
keepMarks: true,
@ -86,11 +75,7 @@ export function RichTextEditor({
keepAttributes: false,
},
}),
Markdown.configure({
linkify: true,
transformCopiedText: true,
transformPastedText: true,
}),
Markdown,
Image,
Link,
Placeholder.configure({
@ -108,7 +93,8 @@ export function RichTextEditor({
getItemColor,
}),
],
content: preprocessMarkdown(defaultValue),
content: defaultValue,
contentType: 'markdown',
onUpdate: handleChange,
editorProps: {
attributes: {
@ -118,8 +104,8 @@ export function RichTextEditor({
})
useEffect(() => {
if (editor.storage.markdown.getMarkdown() === '' || !editor.storage.markdown.getMarkdown()) {
editor.commands.setContent(preprocessMarkdown(defaultValue))
if (editor.getMarkdown() === '' || !editor.getMarkdown()) {
editor.commands.setContent(defaultValue, { contentType: 'markdown' })
}
}, [defaultValue, editor])

849
package-lock.json generated

File diff suppressed because it is too large Load Diff