|
1 | | -# editorjs-blocks-react-renderer |
2 | | -Renders EditorJS block format to React components. |
| 1 | +# Editor.js Blocks React Renderer |
| 2 | + |
| 3 | +Renders Editor.js blocks to semantic React HTML5 components. Unnopinated and flexible. |
| 4 | + |
| 5 | +[](https://www.npmjs.com/package/editorjs-blocks-react-renderer) |
| 6 | +[](https://www.npmjs.com/package/editorjs-blocks-react-renderer) |
| 7 | + |
| 8 | +An unnopinated React library that renders flexible HTML5 React components from [Editor.js](https://editorjs.io/) block style data. |
| 9 | + |
| 10 | +It follows semantic practices and without inlining styles. It's flexible enough to allow developers to include their own styles via CSS classes, which can be passed to each renderer via configuration. |
| 11 | + |
| 12 | +This also supports server side rendering. |
| 13 | + |
| 14 | +## Usage |
| 15 | + |
| 16 | +Install the package via npm: |
| 17 | +```sh |
| 18 | +npm i -S editorjs-blocks-react-renderer |
| 19 | +``` |
| 20 | + |
| 21 | +Import in your component: |
| 22 | +```js |
| 23 | +import Blocks from 'editorjs-blocks-react-renderer'; |
| 24 | +``` |
| 25 | + |
| 26 | +Use it with a [block style data](https://editorjs.io/saving-data) from Editor.js: |
| 27 | +```jsx |
| 28 | +export const Article = () => <Blocks data={dataFromEditor} />; |
| 29 | +``` |
| 30 | + |
| 31 | +## Render a single block |
| 32 | + |
| 33 | +Blocks are independent and you can import only a set of them and use them diretly: |
| 34 | +```jsx |
| 35 | +import { Header } from 'editorjs-react-renderer'; |
| 36 | + |
| 37 | +const dataHeader = { |
| 38 | + "text": "Heading 2", |
| 39 | + "level": 2 |
| 40 | +} |
| 41 | + |
| 42 | +export const Heading () => <Header data={dataHeader} />; |
| 43 | +``` |
| 44 | + |
| 45 | +## Internal blocks |
| 46 | + |
| 47 | +The package ships with the following renderers, but you can include your custom ones: |
| 48 | +- Code |
| 49 | +- Header |
| 50 | +- Paragraph |
| 51 | +- Image |
| 52 | +- Embed |
| 53 | +- List |
| 54 | +- Table |
| 55 | +- Quote |
| 56 | +- Delimiter |
| 57 | + |
| 58 | +## Styling and optional configs |
| 59 | + |
| 60 | +This library does not include/force any style nor inlines any styles. Before you ask, we're not supporting inline styles due to [Content-Security-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) requirements. |
| 61 | + |
| 62 | +However, each renderer supports a set of props, including `className` which can be used to style each block. You just need to pass a `config` object to `Blocks` or directly to any renderer like so: |
| 63 | + |
| 64 | +```jsx |
| 65 | +<Blocks data={dataFromEditor} config={{ |
| 66 | + code: { |
| 67 | + className: "language-js" |
| 68 | + }, |
| 69 | + delimiter: { |
| 70 | + className: "article-hr" |
| 71 | + }, |
| 72 | + embed: { |
| 73 | + className: "styled-iframe", |
| 74 | + rel: "nofollower", |
| 75 | + sandbox: "allow-fullscreen" |
| 76 | + } |
| 77 | + header: { |
| 78 | + className: "lead" |
| 79 | + }, |
| 80 | + image: { |
| 81 | + className: "img-fluid", |
| 82 | + actionsClassNames: { |
| 83 | + stretched: 'image-block--stretched', |
| 84 | + withBorder: 'image-block--with-border', |
| 85 | + withBackground: 'image-block--with-background', |
| 86 | + } |
| 87 | + }, |
| 88 | + list: { |
| 89 | + className: "unstyled-list" |
| 90 | + }, |
| 91 | + paragraph: { |
| 92 | + className: "lead" |
| 93 | + }, |
| 94 | + quote: { |
| 95 | + className: "block-quote", |
| 96 | + actionsClassNames: { |
| 97 | + alignment: 'text-align-{alignment}', // This is a substitution placeholder: left or center. |
| 98 | + } |
| 99 | + }, |
| 100 | + table: { |
| 101 | + className: "table" |
| 102 | + } |
| 103 | +}} /> |
| 104 | +``` |
| 105 | + |
| 106 | +Above you have all allowed properties for each renderer. |
| 107 | + |
| 108 | +So, in theory, any CSS framework (such as Bootstrap) can work seamlessly with this library as long as you pass the correct properties. |
| 109 | + |
| 110 | +## Custom Renderers |
| 111 | + |
| 112 | +You can provide your own custom renderers or replace the default ones by passing a `renderers` object to the `Blocks`. |
| 113 | + |
| 114 | +```tsx |
| 115 | +const Checklist = ({ |
| 116 | + data, className = "" |
| 117 | +}: { |
| 118 | + data: {[s:string]: any} |
| 119 | + className?: string |
| 120 | +}) => { |
| 121 | + |
| 122 | + return ( |
| 123 | + <> |
| 124 | + {data?.items.map((item, i) => ( |
| 125 | + <p key={i}> |
| 126 | + <label> |
| 127 | + <input type="checkbox" /> {ReactHtmlParser(item)} |
| 128 | + </label> |
| 129 | + </p> |
| 130 | + ))} |
| 131 | + </> |
| 132 | + ) |
| 133 | +} |
| 134 | + |
| 135 | +export default () => <Blocks data={dataFromEditor} renderers={{ |
| 136 | + checklist: Checklist |
| 137 | +}} /> |
| 138 | +``` |
| 139 | + |
| 140 | +## Inspiration |
| 141 | + |
| 142 | +- [EditorJS-React-Renderer](https://github.com/BomdiZane/EditorJS-React-Renderer) but without opinated inline styles. |
0 commit comments