11import { type AlpineComponentMeta } from '@Core/ts/types' ;
22
3- // Global type declarations for WordPress editor
4- declare global {
5- interface Window {
6- tinymce ?: {
7- get ( id : string ) : TinyMCEEditor | null ;
8- } ;
9- quicktags ?: unknown ;
10- }
11- }
12-
133interface TinyMCEEditor {
144 getContent ( ) : string ;
155 setContent ( content : string ) : void ;
@@ -22,22 +12,44 @@ interface TinyMCEEditor {
2212
2313interface WPEditorConfig {
2414 name : string ;
15+ editorId : string ;
2516 placeholder ?: string ;
2617}
2718
2819interface AlpineComponent {
2920 $el : HTMLElement ;
3021}
3122
23+ interface WPEditorComponent {
24+ name : string ;
25+ editorId : string ;
26+ placeholder : string ;
27+ editorInstance : TinyMCEEditor | null ;
28+ isVisualMode : boolean ;
29+ initialized : boolean ;
30+ init ( this : AlpineComponent & WPEditorComponent ) : void ;
31+ setupTinyMCE ( this : AlpineComponent & WPEditorComponent ) : void ;
32+ setupTextarea ( this : AlpineComponent & WPEditorComponent ) : void ;
33+ setupQuickTags ( this : AlpineComponent & WPEditorComponent ) : void ;
34+ setupFormResetListener ( this : AlpineComponent & WPEditorComponent ) : void ;
35+ syncEditorToForm ( this : AlpineComponent & WPEditorComponent ) : void ;
36+ syncTextareaToForm ( this : AlpineComponent & WPEditorComponent ) : void ;
37+ updateFormValue ( this : AlpineComponent & WPEditorComponent , content : string ) : void ;
38+ triggerBlur ( this : AlpineComponent & WPEditorComponent ) : void ;
39+ getContent ( this : AlpineComponent & WPEditorComponent ) : string ;
40+ setContent ( this : AlpineComponent & WPEditorComponent , content : string ) : void ;
41+ }
42+
3243/**
3344 * WordPress Editor Alpine.js Component
3445 * Integrates wp_editor (TinyMCE/QuickTags) with tutorForm validation system
3546 */
36- export const wpEditor = ( config : WPEditorConfig ) => {
37- const { name, placeholder = '' } = config ;
47+ export const wpEditor = ( config : WPEditorConfig ) : WPEditorComponent => {
48+ const { name, editorId , placeholder = '' } = config ;
3849
3950 return {
4051 name,
52+ editorId,
4153 placeholder,
4254 editorInstance : null as TinyMCEEditor | null ,
4355 isVisualMode : true ,
@@ -57,13 +69,17 @@ export const wpEditor = (config: WPEditorConfig) => {
5769 this . setupQuickTags ( ) ;
5870 }
5971
72+ // Listen for form reset events
73+ this . setupFormResetListener ( ) ;
74+
6075 this . initialized = true ;
6176 } ,
6277
63- setupTinyMCE ( this : AlpineComponent & ReturnType < typeof wpEditor > ) {
78+ setupTinyMCE ( this : AlpineComponent & WPEditorComponent ) {
6479 // TinyMCE might not be initialized immediately
6580 const checkEditor = ( ) => {
66- const editor = window . tinymce ?. get ( this . name ) ;
81+ // Use editorId instead of name to support multiple editors
82+ const editor = window . tinymce ?. get ( this . editorId ) ;
6783
6884 if ( editor ) {
6985 this . editorInstance = editor ;
@@ -109,8 +125,8 @@ export const wpEditor = (config: WPEditorConfig) => {
109125 checkEditor ( ) ;
110126 } ,
111127
112- setupTextarea ( this : AlpineComponent & ReturnType < typeof wpEditor > ) {
113- const textarea = document . getElementById ( this . name ) as HTMLTextAreaElement ;
128+ setupTextarea ( this : AlpineComponent & WPEditorComponent ) {
129+ const textarea = document . getElementById ( this . editorId ) as HTMLTextAreaElement ;
114130
115131 if ( textarea ) {
116132 // Set placeholder
@@ -135,15 +151,14 @@ export const wpEditor = (config: WPEditorConfig) => {
135151 }
136152 } ,
137153
138- setupQuickTags ( this : AlpineComponent & ReturnType < typeof wpEditor > ) {
154+ setupQuickTags ( this : AlpineComponent & WPEditorComponent ) {
139155 // QuickTags buttons trigger changes in text mode
140- const textarea = document . getElementById ( this . name ) as HTMLTextAreaElement ;
156+ const textarea = document . getElementById ( this . editorId ) as HTMLTextAreaElement ;
141157
142158 if ( textarea ) {
143159 // Monitor for QuickTags button clicks
144- // Monitor for QuickTags button clicks
145- // QuickTags toolbars usually have ID "qt_{name}_toolbar"
146- const toolbarId = `qt_${ this . name } _toolbar` ;
160+ // QuickTags toolbars usually have ID "qt_{editorId}_toolbar"
161+ const toolbarId = `qt_${ this . editorId } _toolbar` ;
147162 const toolbar = document . getElementById ( toolbarId ) ;
148163
149164 if ( toolbar ) {
@@ -159,21 +174,37 @@ export const wpEditor = (config: WPEditorConfig) => {
159174 }
160175 } ,
161176
162- syncEditorToForm ( this : AlpineComponent & ReturnType < typeof wpEditor > ) {
177+ setupFormResetListener ( this : AlpineComponent & WPEditorComponent ) {
178+ // Listen for form reset events from tutorForm
179+ window . addEventListener ( 'tutor-form-reset' , ( event : Event ) => {
180+ const customEvent = event as CustomEvent ;
181+ const { formId, defaultValues } = customEvent . detail || { } ;
182+
183+ // Check if this reset event is for our form by checking if our element is inside the form
184+ const form = this . $el . closest ( 'form' ) ;
185+ if ( form && form . getAttribute ( 'x-data' ) ?. includes ( `id: '${ formId } '` ) ) {
186+ // Reset editor content to default value
187+ const defaultValue = defaultValues ?. [ this . name ] || '' ;
188+ this . setContent ( defaultValue ) ;
189+ }
190+ } ) ;
191+ } ,
192+
193+ syncEditorToForm ( this : AlpineComponent & WPEditorComponent ) {
163194 if ( this . editorInstance ) {
164195 const content = this . editorInstance . getContent ( ) ;
165196 this . updateFormValue ( content ) ;
166197 }
167198 } ,
168199
169- syncTextareaToForm ( this : AlpineComponent & ReturnType < typeof wpEditor > ) {
200+ syncTextareaToForm ( this : AlpineComponent & WPEditorComponent ) {
170201 const textarea = document . getElementById ( this . name ) as HTMLTextAreaElement ;
171202 if ( textarea ) {
172203 this . updateFormValue ( textarea . value ) ;
173204 }
174205 } ,
175206
176- updateFormValue ( this : AlpineComponent & ReturnType < typeof wpEditor > , content : string ) {
207+ updateFormValue ( this : AlpineComponent & WPEditorComponent , content : string ) {
177208 // Get the hidden input that's bound to the form
178209 const hiddenInput = this . $el . querySelector ( `input[name="${ this . name } "]` ) as HTMLInputElement ;
179210
@@ -186,15 +217,15 @@ export const wpEditor = (config: WPEditorConfig) => {
186217 }
187218 } ,
188219
189- triggerBlur ( this : AlpineComponent & ReturnType < typeof wpEditor > ) {
220+ triggerBlur ( this : AlpineComponent & WPEditorComponent ) {
190221 const hiddenInput = this . $el . querySelector ( `input[name="${ this . name } "]` ) as HTMLInputElement ;
191222
192223 if ( hiddenInput ) {
193224 hiddenInput . dispatchEvent ( new Event ( 'blur' , { bubbles : true } ) ) ;
194225 }
195226 } ,
196227
197- getContent ( this : AlpineComponent & ReturnType < typeof wpEditor > ) : string {
228+ getContent ( this : AlpineComponent & WPEditorComponent ) : string {
198229 if ( this . isVisualMode && this . editorInstance ) {
199230 return this . editorInstance . getContent ( ) ;
200231 }
@@ -203,7 +234,7 @@ export const wpEditor = (config: WPEditorConfig) => {
203234 return textarea ? textarea . value : '' ;
204235 } ,
205236
206- setContent ( this : AlpineComponent & ReturnType < typeof wpEditor > , content : string ) {
237+ setContent ( this : AlpineComponent & WPEditorComponent , content : string ) {
207238 if ( this . isVisualMode && this . editorInstance ) {
208239 this . editorInstance . setContent ( content ) ;
209240 }
0 commit comments