1- import { useCallback , useEffect , useMemo , useState } from 'react' ;
1+ import { useCallback , useMemo , useState } from 'react' ;
22
33import katexLib from 'katex' ;
44
5- import { ActionButton , Button } from '@/components' ;
5+ import { ActionButton , Button , Label } from '@/components' ;
66import { Dialog , DialogContent , DialogFooter , DialogTitle , DialogTrigger } from '@/components/ui/dialog' ;
77import { Textarea } from '@/components/ui/textarea' ;
88import type { IKatexAttrs } from '@/extensions/Katex/Katex' ;
@@ -12,51 +12,55 @@ import { useAttributes } from '@/hooks/useAttributes';
1212import { useButtonProps } from '@/hooks/useButtonProps' ;
1313import { useLocale } from '@/locales' ;
1414import { useEditorInstance } from '@/store/editor' ;
15+ import { parseJSONString } from '@/utils/columns' ;
1516
1617export function RichTextKatex ( ) {
1718 const { t } = useLocale ( ) ;
1819 const [ visible , toggleVisible ] = useState ( false ) ;
1920
20- const buttonProps = useButtonProps ( Katex . name ) ;
21+ const buttonProps = useButtonProps ( Katex . name ) ;
2122
22- const {
23- icon = undefined ,
24- tooltip = undefined ,
25- tooltipOptions = { } ,
26- isActive = undefined ,
27- } = buttonProps ?. componentProps ?? { } ;
23+ const {
24+ icon = undefined ,
25+ tooltip = undefined ,
26+ tooltipOptions = { } ,
27+ isActive = undefined ,
28+ } = buttonProps ?. componentProps ?? { } ;
2829
29- const { editorDisabled } = useToggleActive ( isActive ) ;
30+ const { editorDisabled } = useToggleActive ( isActive ) ;
3031
3132 const editor = useEditorInstance ( ) ;
3233
3334 const attrs = useAttributes < IKatexAttrs > ( editor , Katex . name , {
3435 text : '' ,
35- defaultShowPicker : false ,
36+ macros : '' ,
3637 } ) ;
37- const { text, defaultShowPicker } = attrs ;
38+ const { text, macros } = attrs ;
3839
39- const [ currentValue , setCurrentValue ] = useState ( text || '' ) ;
40+ const [ currentValue , setCurrentValue ] = useState ( decodeURIComponent ( text || '' ) ) ;
41+ const [ currentMacros , setCurrentMacros ] = useState ( decodeURIComponent ( macros || '' ) ) ;
4042
4143 const submit = useCallback ( ( ) => {
42- editor . chain ( ) . focus ( ) . setKatex ( { text : currentValue } ) . run ( ) ;
44+
45+ editor . chain ( ) . focus ( ) . setKatex ( {
46+ text : encodeURIComponent ( currentValue ) ,
47+ macros : encodeURIComponent ( currentMacros ) ,
48+ } ) . run ( ) ;
49+
4350 setCurrentValue ( '' ) ;
51+ setCurrentMacros ( '' ) ;
4452 toggleVisible ( false ) ;
45- } , [ editor , currentValue ] ) ;
46-
47- useEffect ( ( ) => {
48- if ( defaultShowPicker ) {
49- editor . chain ( ) . updateAttributes ( Katex . name , { defaultShowPicker : false } ) . focus ( ) . run ( ) ;
50- }
51- } , [ editor , defaultShowPicker ] ) ;
53+ } , [ editor , currentValue , currentMacros ] ) ;
5254
5355 const formatText = useMemo ( ( ) => {
5456 try {
55- return katexLib . renderToString ( `${ currentValue } ` ) ;
57+ return katexLib . renderToString ( currentValue , {
58+ macros : parseJSONString ( currentMacros )
59+ } ) ;
5660 } catch {
5761 return currentValue ;
5862 }
59- } , [ currentValue ] ) ;
63+ } , [ currentMacros , currentValue ] ) ;
6064
6165 const previewContent = useMemo (
6266 ( ) => {
@@ -75,14 +79,14 @@ export function RichTextKatex() {
7579 open = { visible }
7680 >
7781 < DialogTrigger
78- asChild
79- disabled = { editorDisabled }
82+ asChild
83+ disabled = { editorDisabled }
8084 >
8185 < ActionButton
8286 disabled = { editorDisabled }
83- icon = { icon }
84- tooltip = { tooltip }
85- tooltipOptions = { tooltipOptions }
87+ icon = { icon }
88+ tooltip = { tooltip }
89+ tooltipOptions = { tooltipOptions }
8690 action = { ( ) => {
8791 if ( editorDisabled ) return ;
8892 toggleVisible ( true ) ;
@@ -92,26 +96,48 @@ export function RichTextKatex() {
9296
9397 < DialogContent className = "richtext-z-[99999] !richtext-max-w-[1300px]" >
9498 < DialogTitle >
95- { t ( 'editor.formula.dialog.text' ) }
99+ { t ( 'editor.formula.dialog.text' ) }
96100 </ DialogTitle >
97101
98102 < div
99103 style = { { height : '100%' , border : '1px solid hsl(var(--border))' } }
100104 >
101105 < div className = "richtext-flex richtext-gap-[10px] richtext-rounded-[10px] richtext-p-[10px]" >
102- < Textarea
103- autoFocus
104- className = "richtext-flex-1"
105- onChange = { e => setCurrentValue ( e . target . value ) }
106- placeholder = "Text"
107-
108- required
109- rows = { 10 }
110- value = { currentValue }
111- style = { {
112- color : 'hsl(var(--foreground))' ,
113- } }
114- />
106+ < div className = 'richtext-flex-1' >
107+ < Label className = "mb-[6px]" >
108+ Expression
109+ </ Label >
110+
111+ < Textarea
112+ autoFocus
113+ className = "richtext-mb-[10px]"
114+ onChange = { e => setCurrentValue ( e . target . value ) }
115+ placeholder = "Text"
116+ required
117+ rows = { 10 }
118+ value = { currentValue }
119+ style = { {
120+ color : 'hsl(var(--foreground))' ,
121+ } }
122+ />
123+
124+ < Label className = "mb-[6px]" >
125+ Macros
126+ </ Label >
127+
128+ < Textarea
129+ className = "richtext-flex-1"
130+ placeholder = "Macros"
131+ rows = { 10 }
132+ value = { currentMacros }
133+ onChange = { e => {
134+ setCurrentMacros ( e . target . value ) ;
135+ } }
136+ style = { {
137+ color : 'hsl(var(--foreground))' ,
138+ } }
139+ />
140+ </ div >
115141
116142 < div
117143 className = "richtext-flex richtext-flex-1 richtext-items-center richtext-justify-center richtext-rounded-[10px] richtext-p-[10px]"
0 commit comments