I'm not sure that TextEditor was designed to be re-used outside of its original context.
This is what I've been using in my Formulaire extension:
import app from 'flarum/app';
import Component from 'flarum/Component';
/* global m, s9e */
export default class RichTextField extends Component {
config(isInitialized, context) {
if (isInitialized) return;
// Similar to the post preview, refresh every 50ms if the content has changed
let preview;
const updateInterval = setInterval(() => {
const content = this.element.querySelector('textarea').value;
if (preview === content) return;
preview = content;
if (preview) {
s9e.TextFormatter.preview(preview, this.element.querySelector('.js-preview'));
} else {
// This is just to show a paragraph in the preview area when there's nothing to render
const placeholder = document.createElement('P');
placeholder.className = 'FormulaireRichPlaceholder';
placeholder.innerText = app.translator.trans('kilowhat-formulaire.forum.rich-text.preview-placeholder');
this.element.querySelector('.js-preview').innerHTML = '';
this.element.querySelector('.js-preview').appendChild(placeholder);
}
}, 50);
context.onunload = () => clearInterval(updateInterval);
}
view() {
return m('.FormulaireRich', [
m('.FormulaireRichPreview.js-preview', {
onclick: event => {
event.preventDefault();
this.element.querySelector('textarea').focus();
},
}),
m('textarea.FormControl', this.props),
]);
}
}
The field component is then used with a simple value and onchange props like normal fields.
If course the downside is that you don't get the markdown autocomplete, emoji autocomplete or the editor toolbar.
Server-side the plain text needs to be parsed before storing in the database as XML. And unparsed+rendered at run time to obtain plain text and html output.