diff --git a/README.md b/README.md index d9bded9..cf151cc 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,12 @@ and [@editorjs/header](https://www.npmjs.com/package/@editorjs/header). Take a look on their [Github](https://github.com/editor-js) page to find more available plugins (or take a look at [the storybook example](src/__stories__/config.ts)). +## Additional Props + +| Name | Type | Default | Description | +| :------------------------ | :-------: | :-----: | :----------------------------------------------------------------------------------------------------------------------- | +| reinitializeOnPropsChange | `boolean` | `false` | editor-js is initialised again on [componentDidUpdate](https://reactjs.org/docs/react-component.html#componentdidupdate) | + ## Licence [MIT](LICENCE) diff --git a/src/__stories__/index.stories.tsx b/src/__stories__/index.stories.tsx index f44fb3f..21259db 100644 --- a/src/__stories__/index.stories.tsx +++ b/src/__stories__/index.stories.tsx @@ -1,4 +1,5 @@ /* eslint-disable class-methods-use-this */ +/* eslint-disable react/prop-types */ import React from 'react' import { storiesOf } from '@storybook/react' import { action } from '@storybook/addon-actions' @@ -12,6 +13,29 @@ import { CustomReact, Button } from './custom-plugin-react' import EditorJs from '..' +const SaveButton = ({ + onClick, +}: { + onClick: (event: React.MouseEvent) => void +}) => ( + +) + storiesOf('ReactEditorJs', module) .add('default', () => { let instance: EditorJS = null @@ -32,8 +56,100 @@ storiesOf('ReactEditorJs', module) /> ) }) - .add('with custom plugins', () => { - let instance: EditorJS = null + .add('controlled EditorJs', () => { + const App = () => { + const [appData, setAppData] = React.useState(data) + let editorInstance: EditorJS = null + + const onSave = async () => { + if (editorInstance) { + try { + const outputData = await editorInstance.save() + action('EditorJs onSave')(outputData) + setAppData(appData) + } catch (error) { + action('EditorJs was not able to save data')(error) + } + } + } + + const onChange = () => { + action('EditorJs onChange') + onSave() + } + + return ( +
+ + { + editorInstance = instance + action('EditorJs editorInstance')(instance) + }} + onChange={onChange} + /> +
+ ) + } + + return + }) + .add('controlled App -> Editor -> EditorJs', () => { + // the ยด` renders an `` component, which renders `EditorJs` + const App = () => { + const [appData, setAppData] = React.useState(data) + + const onChange = (newAppData: any) => { + setAppData(newAppData) + } + + return + } + + const Editor = ({ + appData, + onChange, + }: { + appData: any + onChange: (data: any) => void + }) => { + let editorInstance: EditorJS = null + + const onChangeHandler = async () => { + if (editorInstance) { + try { + const outputData = await editorInstance.save() + action('EditorJs onSave')(outputData) + onChange(outputData) + } catch (error) { + action('EditorJs was not able to save data')(error) + } + } + } + + return ( +
+ + { + editorInstance = instance + action('EditorJs editorInstance')(instance) + }} + // reinitializeOnPropsChange + onChange={onChangeHandler} + /> +
+ ) + } + + return + }) + .add('with custom tool (react)', () => { + let editorInstance: EditorJS = null const customData = { time: new Date().getTime(), @@ -74,37 +190,24 @@ storiesOf('ReactEditorJs', module) } const onSave = async () => { - try { - const outputData = await instance.save() - action('EditorJs onSave')(outputData) - } catch (e) { - action('EditorJs onSave failed')(e) + if (editorInstance) { + try { + const outputData = await editorInstance.save() + action('EditorJs onSave')(outputData) + } catch (e) { + action('EditorJs onSave failed')(e) + } } } return (
- + { - instance = editorInstance + editorInstance={instance => { + editorInstance = instance action('EditorJs editorInstance')(editorInstance) }} /> diff --git a/src/index.tsx b/src/index.tsx index c5e84f2..6d2a45d 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -7,6 +7,8 @@ export interface IEditorJsProps extends EditorJS.EditorConfig { children?: ReactElement // Id of Element that should contain the Editor holder?: string + // reinitialize editor.js when component did update + reinitializeOnPropsChange?: boolean // editorjs instance editorInstance?: (instance: EditorJS) => void } @@ -19,6 +21,8 @@ const EditorJs: FunctionComponent = (props): ReactElement => { const { holder: customHolder, editorInstance, + /* optimise performance */ + reinitializeOnPropsChange, /* eslint-disable-next-line */ children, tools, @@ -50,14 +54,21 @@ const EditorJs: FunctionComponent = (props): ReactElement => { return (): void => { // destroys the editor - if (instance) { + if (instance && reinitializeOnPropsChange) { instance.isReady.then(() => { instance.destroy() instance = undefined }) } } - }, [holder, editorInstance, otherProps, props, tools]) + }, [ + holder, + editorInstance, + otherProps, + props, + tools, + reinitializeOnPropsChange, + ]) return (children as ReactElement) ||
}