Ghost/ghost/admin/app/components/react-component.js
Kevin Ansfield d991da399c Added support for building/rendering react components
no issue

- updated ember-cli-build and eslint config to support jsx
- added `react` and `react-dom` libraries
  - included them in the build so the `React` and `ReactDom` globals are available for use by third party components
  - added vendor shims so we can do things like `import * from 'react'` where the imports are referenced directly to the already imported modules
- added `<ReactComponent>` component
  - designed to be extended from in specific react component classes
  - renders a div and calls `renderComponent()` action once inserted - this should be replaced in any extended classes in order to render a react component
  - handles react rendering and teardown
- added `<ReactMobiledocEditor>` react component that renders an editor composed of components provided by the `react-mobiledoc-editor` package
- added `<KoenigReactEditor>` ember component that renders `<ReactMobiledocEditor>` and handles pass-through of Ember arguments and handling of actions
- updated `<GhKoenigEditorReact>` to render `<KoenigReactEditor>` in place of `<KoenigEditor>`
2022-07-19 12:48:53 +01:00

47 lines
1.2 KiB
JavaScript

import Component from '@glimmer/component';
import {action} from '@ember/object';
import {createRoot} from 'react-dom/client';
export default class ReactComponent extends Component {
@action
renderComponent() {
// eslint-disable-next-line
console.error('Components extending ReactComponent must implement a `renderComponent()` action that calls `this.reactRender()');
}
/**
* Renders a react component as the current ember element
* @param {React.Component} reactComponent. e.g., <HelloWorld />
*/
reactRender(element, reactComponent) {
if (element !== this.elem) {
this.unmountReactElement();
}
this.elem = element;
this.root = createRoot(this.elem);
this.root.render(reactComponent);
}
/**
* Removes a mounted React component from the DOM and
* cleans up its event handlers and state.
*/
unmountReactElement() {
if (!this.root) {
return;
}
this.root.unmount();
}
/**
* Cleans up the rendered react component as the ember
* component gets destroyed
*/
willDestroy() {
super.willDestroy();
this.unmountReactElement();
}
}