Add drupal:mdx-fill event support to MDX editor for external content injection
>>> [!note] Migrated issue <!-- Drupal.org comment --> <!-- Migrated from issue #3581363. --> Reported by: [unqunq](https://www.drupal.org/user/933228) Related to !1524 !1345 !1344 >>> <p>[Tracker]<br> <strong>Update Summary: </strong>Patch adds onRef callback and drupal:mdx-fill CustomEvent support to the MDX editor<br> <strong>Short Description: </strong>Allow external Drupal modules to inject content into the MDX editor via a DOM CustomEvent<br> <strong>Check-in Date: </strong>03/25/2026<br> <em>Metadata is used by the <a href="https://www.drupalstarforge.ai/" title="AI Tracker">AI Tracker.</a> Docs and additional fields <a href="https://www.drupalstarforge.ai/ai-dashboard/docs" title="AI Issue Tracker Documentation">here</a>.</em><br> [/Tracker]</p> <h3 id="summary-problem-motivation">Problem/Motivation</h3> <p>The MDX editor is a self-contained React application. Its internal <code>MDXEditorMethods</code> ref (which exposes <code>setMarkdown()</code>) is private to the <code>Editor</code> component and cannot be reached from outside React.</p> <p>This makes it impossible for external Drupal modules to programmatically update the editor content after it has mounted -- for example, after an AJAX response that loads content from a remote source (a URL, uploaded file, or API endpoint).</p> <p>Specifically, the <a href="https://www.drupal.org/project/document_loader">Document Loader</a> module's <code>document_loader_mdx</code> submodule needs to inject loaded document content into the MDX editor from a Drupal AJAX command. Without this patch, the hidden textarea value can be updated (which persists on form submit) but the visible React editor does not re-render to reflect the new content.</p> <h3 id="summary-proposed-resolution">Proposed resolution</h3> <p>Add two small changes to the MDX editor source:</p> <p><strong>1. <code>Editor.jsx</code> -- accept an <code>onRef</code> callback prop</strong></p> <p>After the editor mounts, call the <code>onRef</code> prop (if provided) with the <code>MDXEditorMethods</code> ref. This lets the parent (<code>main.jsx</code>) hold a reference to the editor instance.</p> <p><strong>2. <code>main.jsx</code> -- expose the ref via a <code>drupal:mdx-fill</code> DOM CustomEvent</strong></p> <p>After rendering, add a <code>drupal:mdx-fill</code> event listener on the hidden textarea. When the event fires (dispatched by an external Drupal AJAX command), call <code>editorRef.current.setMarkdown(event.detail.content)</code> to visually update the editor.</p> <p>This pattern (bridging a React ref to a DOM custom event) is necessary because Drupal's JS layer and the React component tree cannot share a reference directly -- they live in separate execution contexts.</p> <p>The patch is minimal and non-breaking: <code>onRef</code> is optional and defaults to nothing; the event listener is passive.</p> <h3 id="summary-remaining-tasks">Remaining tasks</h3> <ul> <li>Review the patch</li> <li>Rebuild the JS bundle (<code>npm run build</code> in <code>ui/mdxeditor/</code>) and include updated dist files</li> <li>Commit to the <code>ai</code> module</li> </ul> <h3>Optional: Other details as applicable (e.g., User interface changes, API changes, Data model changes)</h3> <p><strong>API addition:</strong> The <code>Editor</code> component gains an optional <code>onRef</code> prop of type <code>(ref: MDXEditorMethods) =&amp;gt; void</code>. This is additive and does not affect existing usage.</p> <p><strong>Event contract:</strong> External modules can now dispatch a <code>drupal:mdx-fill</code> CustomEvent on the hidden textarea with <code>detail: { content: string }</code> to update the editor content at any time after mount.</p> <p>Example from a Drupal AJAX command:</p> <pre> textarea.dispatchEvent(new CustomEvent('drupal:mdx-fill', { bubbles: true, detail: { content: markdownString }, })); </pre><p>The patch is included below and is also shipped with the <code>document_loader_mdx</code> module at <code>patches/ai-mdx-editor-drupal-fill-event.patch</code>.</p> <h3 id="summary-ai-usage">AI usage (if applicable)</h3> <p>[x] AI Assisted Code<br> This code was mainly generated by a human, with AI autocompleting or parts AI generated, but under full human supervision.</p> > Related issue: [Issue #3580850](https://www.drupal.org/node/3580850)
issue