@@ -7,34 +7,23 @@ import Underline from "@tiptap/extension-underline";
77import Typography from "@tiptap/extension-typography" ;
88import Link from "@tiptap/extension-link" ;
99import Placeholder from "@tiptap/extension-placeholder" ;
10- import { useState , useCallback , useMemo } from "react" ;
11- import TurndownService from "turndown " ;
10+ import { useState , useCallback , useMemo , useEffect } from "react" ;
11+ import { markdownToHtml , htmlToMarkdown } from "./utils " ;
1212
1313import { Button } from "@/components/ui/Button" ;
1414import { Card , CardContent , CardHeader , CardTitle } from "@/components/ui/Card" ;
1515import { Toolbar } from "@/components/common/TextEditor" ;
1616
1717interface TextEditorProps {
1818 markdownOutput ?: boolean ;
19+ value ?: string ;
20+ onChange ?: ( value : string ) => void ;
1921}
2022
21- const TextEditor = ( { markdownOutput = false } : TextEditorProps ) => {
23+ const TextEditor = ( { markdownOutput = false , value , onChange } : TextEditorProps ) => {
2224 const [ markdownContent , setMarkdownContent ] = useState ( "" ) ;
2325
24- const turndownService = useMemo ( ( ) => {
25- const service = new TurndownService ( {
26- headingStyle : "atx" ,
27- codeBlockStyle : "fenced" ,
28- } ) ;
29-
30- // Custom rule for underline tags
31- service . addRule ( "underline" , {
32- filter : "u" ,
33- replacement : ( content ) => `<u>${ content } </u>` ,
34- } ) ;
35-
36- return service ;
37- } , [ ] ) ;
26+ const htmlContent = useMemo ( ( ) => markdownToHtml ( value || "" ) , [ value ] ) ;
3827
3928 const editor = useEditor ( {
4029 extensions : [
@@ -55,20 +44,24 @@ const TextEditor = ({ markdownOutput = false }: TextEditorProps) => {
5544 allowBase64 : true ,
5645 } ) ,
5746 ] ,
58- content : "" ,
47+ content : htmlContent ,
5948 immediatelyRender : false ,
6049 onCreate : ( { editor } ) => {
6150 const html = editor . getHTML ( ) ;
62- setMarkdownContent ( turndownService . turndown ( html ) ) ;
51+ setMarkdownContent ( htmlToMarkdown ( html ) ) ;
6352 } ,
6453 onUpdate : ( { editor } ) => {
6554 const html = editor . getHTML ( ) ;
66- setMarkdownContent ( turndownService . turndown ( html ) ) ;
55+ const markdown = htmlToMarkdown ( html ) ;
56+ setMarkdownContent ( markdown ) ;
57+ onChange ?.( html ) ;
58+ console . log ( "markdown: " , markdown ) ;
59+ console . log ( "html: " , html ) ;
6760 } ,
6861 editorProps : {
6962 attributes : {
7063 class :
71- "prose dark:prose-invert max-w-none mx-auto focus:outline-none min -h-[300px] p-3 prose-blockquote:border-primary prose-blockquote:bg-muted/50 prose-blockquote:pl-4 prose-blockquote:py-1 prose-blockquote:before:content-none prose-blockquote:not-italic prose-code:bg-muted prose-code:px-1.5 prose-code:py-0.5 prose-code: rounded prose-code:before:content-none prose-code:after:content-none prose-pre:bg-muted prose-pre:border prose-pre:text-foreground" ,
64+ "prose dark:prose-invert max-w-none mx-auto focus:outline-none max -h-[300px] p-3 prose-blockquote:border-primary prose-blockquote:bg-muted/50 prose-blockquote:pl-4 prose-blockquote:py-1 prose-blockquote:before:content-none prose-blockquote:not-italic prose-code:bg-muted prose-code:rounded prose-code:before:content-none prose-code:after:content-none prose-pre:bg-muted prose-pre:border prose-pre:text-foreground prose-pre:p-3 " ,
7265 } ,
7366 } ,
7467 } ) ;
@@ -132,6 +125,12 @@ const TextEditor = ({ markdownOutput = false }: TextEditorProps) => {
132125 editor . chain ( ) . focus ( ) . extendMarkRange ( "link" ) . setLink ( { href : url } ) . run ( ) ;
133126 } , [ editor ] ) ;
134127
128+ useEffect ( ( ) => {
129+ if ( editor && htmlContent !== undefined && editor . getHTML ( ) !== htmlContent ) {
130+ editor . commands . setContent ( htmlContent ) ;
131+ }
132+ } , [ editor , htmlContent ] ) ;
133+
135134 if ( ! editor ) {
136135 return (
137136 < div className = "flex h-64 items-center justify-center" >
0 commit comments