# MDX Editor

Integrates [MDXEditor](https://mdxeditor.dev/) as a rich text editor for Drupal
text formats, following the same architecture as the CKEditor 5 module.

## Requirements

- Drupal 11+
- `drupal:editor` core module

## Building the JavaScript

```bash
cd js
npm install
npm run build
```

The build outputs to `js/dist/`. Commit the `dist/` directory to version control.

## Architecture

### PHP plugin system

MDXEditor plugins are discovered from `*.mdxeditor.yml` files in any module
directory (same mechanism as `*.ckeditor5.yml`). A plugin definition looks like:

```yaml
mymodule_myplugin:
  label: 'My Plugin'
  toolbar_items:
    myButton:
      label: 'My Button'
  library: 'mymodule/mdxeditor.plugin.myplugin'  # optional
```

- `plugin_id` must be prefixed with the providing module name.
- `toolbar_items` lists the toolbar item IDs this plugin contributes.
- `library` is an optional Drupal library that provides the JS code for the
  plugin (required when the plugin adds custom React components).

### JavaScript plugin registry

The editor JS exposes `window.MdxEditorDrupal` with the following API:

```js
// Shared React/MDXEditor instances (use these – do NOT bundle your own):
window.MdxEditorDrupal.React
window.MdxEditorDrupal.ReactDOM
window.MdxEditorDrupal.MDXEditor  // all @mdxeditor/editor exports

// Register a contrib plugin:
window.MdxEditorDrupal.registerPlugin(
  'mymodule_myplugin',
  (config) => [myMdxPlugin(config)],   // returns MDXEditor plugin instances
  { myButton: () => <MyButton /> },    // toolbar item render functions
);
```

### Building a contrib plugin JS library

Your plugin's Vite config should mark React and MDXEditor as externals:

```js
rollupOptions: {
  external: ['react', 'react-dom', '@mdxeditor/editor'],
  output: {
    globals: {
      react: 'MdxEditorDrupal.React',
      'react-dom': 'MdxEditorDrupal.ReactDOM',
      '@mdxeditor/editor': 'MdxEditorDrupal.MDXEditor',
    },
  },
}
```

Your library in `mymodule.libraries.yml`:

```yaml
mdxeditor.plugin.myplugin:
  js:
    js/dist/myPlugin.js: { minified: true, preprocess: false }
  dependencies:
    - mdxeditor/editor   # ensures core loads first
```

## Programmatic content update

To set the editor content from external code:

```js
const textarea = document.querySelector('[data-editor-id="my_format"]');
textarea.dispatchEvent(new CustomEvent('mdxeditor:setContent', {
  detail: { content: '## Hello World' },
}));
```