1717 * under the License.
1818 */
1919
20- import { FC , useCallback , useEffect , useRef } from " react" ;
21- import { useTranslation } from " react-i18next" ;
20+ import { FC , useCallback , useEffect , useRef } from ' react' ;
21+ import { useTranslation } from ' react-i18next' ;
2222
23- import { StacksEditor } from " @stackoverflow/stacks-editor" ;
23+ import { StacksEditor } from ' @stackoverflow/stacks-editor' ;
2424
25- import " @stackoverflow/stacks" ;
26- import " @stackoverflow/stacks/dist/css/stacks.css" ;
25+ import ' @stackoverflow/stacks' ;
26+ import ' @stackoverflow/stacks/dist/css/stacks.css' ;
2727
28- import "@stackoverflow/stacks-editor/dist/styles.css" ;
28+ import '@stackoverflow/stacks-editor/dist/styles.css' ;
29+ import { createOnChangePlugin } from './onChange-plugin' ;
2930
3031export interface EditorProps {
3132 value : string ;
@@ -46,13 +47,13 @@ const Component: FC<EditorProps> = ({
4647 onChange,
4748 onFocus,
4849 onBlur,
49- placeholder = "" ,
50+ placeholder = '' ,
5051 autoFocus = false ,
5152 imageUploadHandler,
5253 uploadConfig,
5354} ) => {
54- const { t } = useTranslation ( " plugin" , {
55- keyPrefix : " editor_stacks.frontend" ,
55+ const { t } = useTranslation ( ' plugin' , {
56+ keyPrefix : ' editor_stacks.frontend' ,
5657 } ) ;
5758 const containerRef = useRef < HTMLDivElement > ( null ) ;
5859 const editorInstanceRef = useRef < StacksEditor | null > ( null ) ;
@@ -61,7 +62,7 @@ const Component: FC<EditorProps> = ({
6162 const onFocusRef = useRef ( onFocus ) ;
6263 const onBlurRef = useRef ( onBlur ) ;
6364 const autoFocusTimeoutRef = useRef < ReturnType < typeof setTimeout > | null > (
64- null
65+ null ,
6566 ) ;
6667
6768 // Version compatibility temporarily disabled
@@ -76,13 +77,13 @@ const Component: FC<EditorProps> = ({
7677 if ( ! containerRef . current ) return ;
7778
7879 containerRef . current ?. classList . remove (
79- " theme-light" ,
80- " theme-dark" ,
81- " theme-system"
80+ ' theme-light' ,
81+ ' theme-dark' ,
82+ ' theme-system' ,
8283 ) ;
8384 const themeAttr =
84- document . documentElement . getAttribute ( " data-bs-theme" ) ||
85- document . body . getAttribute ( " data-bs-theme" ) ;
85+ document . documentElement . getAttribute ( ' data-bs-theme' ) ||
86+ document . body . getAttribute ( ' data-bs-theme' ) ;
8687
8788 if ( themeAttr ) {
8889 containerRef . current ?. classList . add ( `theme-${ themeAttr } ` ) ;
@@ -99,11 +100,11 @@ const Component: FC<EditorProps> = ({
99100 } ) ;
100101 observer . observe ( document . documentElement , {
101102 attributes : true ,
102- attributeFilter : [ " data-bs-theme" , " class" ] ,
103+ attributeFilter : [ ' data-bs-theme' , ' class' ] ,
103104 } ) ;
104105 observer . observe ( document . body , {
105106 attributes : true ,
106- attributeFilter : [ " data-bs-theme" , " class" ] ,
107+ attributeFilter : [ ' data-bs-theme' , ' class' ] ,
107108 } ) ;
108109 return ( ) => observer . disconnect ( ) ;
109110 } , [ syncTheme ] ) ;
@@ -116,8 +117,8 @@ const Component: FC<EditorProps> = ({
116117 let editorInstance : StacksEditor | null = null ;
117118
118119 try {
119- editorInstance = new StacksEditor ( containerRef . current , value || "" , {
120- placeholderText : placeholder || t ( " placeholder" , "" ) ,
120+ editorInstance = new StacksEditor ( containerRef . current , value || '' , {
121+ placeholderText : placeholder || t ( ' placeholder' , '' ) ,
121122 parserFeatures : {
122123 tables : true ,
123124 html : false ,
@@ -129,37 +130,26 @@ const Component: FC<EditorProps> = ({
129130 acceptedFileTypes : uploadConfig ?. allowedExtensions ,
130131 }
131132 : undefined ,
133+ editorPlugins : onChange
134+ ? [
135+ createOnChangePlugin ( ( content ) => {
136+ onChangeRef . current ?.( content ) ;
137+ } ) ,
138+ ]
139+ : [ ] ,
132140 } ) ;
133141
134142 editorInstanceRef . current = editorInstance ;
135143 isInitializedRef . current = true ;
136144
137145 const editor = editorInstance ;
138-
139- const originalDispatch = editor . editorView . props . dispatchTransaction ;
140- editor . editorView . setProps ( {
141- dispatchTransaction : ( tr ) => {
142- if ( originalDispatch ) {
143- originalDispatch . call ( editor . editorView , tr ) ;
144- } else {
145- const newState = editor . editorView . state . apply ( tr ) ;
146- editor . editorView . updateState ( newState ) ;
147- }
148-
149- if ( tr . docChanged && onChangeRef . current ) {
150- const newContent = editor . content ;
151- onChangeRef . current ( newContent ) ;
152- }
153- } ,
154- } ) ;
155-
156146 const editorElement = editor . dom as HTMLElement ;
157147 const handleFocus = ( ) => onFocusRef . current ?.( ) ;
158148 const handleBlur = ( ) => onBlurRef . current ?.( ) ;
159149
160150 if ( editorElement ) {
161- editorElement . addEventListener ( " focus" , handleFocus , true ) ;
162- editorElement . addEventListener ( " blur" , handleBlur , true ) ;
151+ editorElement . addEventListener ( ' focus' , handleFocus , true ) ;
152+ editorElement . addEventListener ( ' blur' , handleBlur , true ) ;
163153 }
164154
165155 if ( autoFocus ) {
@@ -177,25 +167,27 @@ const Component: FC<EditorProps> = ({
177167 }
178168
179169 if ( editorElement ) {
180- editorElement . removeEventListener ( " focus" , handleFocus , true ) ;
181- editorElement . removeEventListener ( " blur" , handleBlur , true ) ;
170+ editorElement . removeEventListener ( ' focus' , handleFocus , true ) ;
171+ editorElement . removeEventListener ( ' blur' , handleBlur , true ) ;
182172 }
183173
184174 if ( editorInstance ) {
185175 try {
186176 editorInstance . destroy ( ) ;
187177 } catch ( e ) {
188- console . error ( " Error destroying editor:" , e ) ;
178+ console . error ( ' Error destroying editor:' , e ) ;
189179 }
190180 }
191181
192182 editorInstanceRef . current = null ;
193183 isInitializedRef . current = false ;
194184
195- containerRef . current ! . innerHTML = "" ;
185+ if ( containerRef . current ) {
186+ containerRef . current . innerHTML = '' ;
187+ }
196188 } ;
197189 } catch ( error ) {
198- console . error ( " Failed to initialize Stacks Editor:" , error ) ;
190+ console . error ( ' Failed to initialize Stacks Editor:' , error ) ;
199191 isInitializedRef . current = false ;
200192 }
201193 } , [ ] ) ;
@@ -211,7 +203,7 @@ const Component: FC<EditorProps> = ({
211203 editor . content = value ;
212204 }
213205 } catch ( error ) {
214- console . error ( " Error syncing editor content:" , error ) ;
206+ console . error ( ' Error syncing editor content:' , error ) ;
215207 }
216208 } , [ value ] ) ;
217209
0 commit comments