@aeaton/react-prosemirror
Advanced tools
Comparing version
@@ -39,14 +39,13 @@ 'use strict'; | ||
value: function componentDidMount() { | ||
var _this2 = this; | ||
var _props = this.props, | ||
onChange = _props.onChange, | ||
options = _props.options; | ||
var view = new _prosemirrorView.EditorView(this.editor, { | ||
state: _prosemirrorState.EditorState.create({ | ||
schema: this.props.schema, | ||
doc: this.props.value, | ||
plugins: this.props.plugins | ||
}), | ||
var view = new _prosemirrorView.EditorView(this.editorNode, { | ||
state: _prosemirrorState.EditorState.create(options), | ||
dispatchTransaction: function dispatchTransaction(transaction) { | ||
var state = view.state.apply(transaction); | ||
view.updateState(state); | ||
_this2.props.onChange(state.doc.content); | ||
onChange(state.doc.content); | ||
} | ||
@@ -61,8 +60,14 @@ }); | ||
}, { | ||
key: 'shouldComponentUpdate', | ||
value: function shouldComponentUpdate() { | ||
// never re-render | ||
return false; | ||
} | ||
}, { | ||
key: 'render', | ||
value: function render() { | ||
var _this3 = this; | ||
var _this2 = this; | ||
return _react2.default.createElement('div', { ref: function ref(node) { | ||
_this3.editor = node; | ||
_this2.editorNode = node; | ||
} }); | ||
@@ -69,0 +74,0 @@ } |
@@ -31,51 +31,49 @@ 'use strict'; | ||
var parser = function parser(schema) { | ||
var parser = _prosemirrorModel.DOMParser.fromSchema(schema); | ||
return function (content) { | ||
var container = document.createElement('article'); | ||
container.innerHTML = content; | ||
return parser.parse(container); | ||
}; | ||
}; | ||
var serializer = function serializer(schema) { | ||
var serializer = _prosemirrorModel.DOMSerializer.fromSchema(schema); | ||
return function (content) { | ||
var container = document.createElement('article'); | ||
container.appendChild(serializer.serializeFragment(content)); | ||
return container.innerHTML; | ||
}; | ||
}; | ||
var HtmlEditor = function (_React$Component) { | ||
_inherits(HtmlEditor, _React$Component); | ||
function HtmlEditor(props) { | ||
function HtmlEditor() { | ||
_classCallCheck(this, HtmlEditor); | ||
var _this = _possibleConstructorReturn(this, (HtmlEditor.__proto__ || Object.getPrototypeOf(HtmlEditor)).call(this, props)); | ||
_this.state = { | ||
value: undefined | ||
}; | ||
return _this; | ||
return _possibleConstructorReturn(this, (HtmlEditor.__proto__ || Object.getPrototypeOf(HtmlEditor)).apply(this, arguments)); | ||
} | ||
_createClass(HtmlEditor, [{ | ||
key: 'parse', | ||
value: function parse(content) { | ||
var container = document.createElement('article'); | ||
container.innerHTML = content; | ||
return this.parser.parse(container); | ||
} | ||
}, { | ||
key: 'serialize', | ||
value: function serialize(content) { | ||
var container = document.createElement('article'); | ||
container.appendChild(this.serializer.serializeFragment(content)); | ||
return container.innerHTML; | ||
} | ||
}, { | ||
key: 'componentWillMount', | ||
value: function componentWillMount() { | ||
var _this2 = this; | ||
var _props = this.props, | ||
schema = _props.schema, | ||
value = _props.value, | ||
onChange = _props.onChange; | ||
onChange = _props.onChange, | ||
options = _props.options; | ||
var schema = options.schema; | ||
this.parser = _prosemirrorModel.DOMParser.fromSchema(schema); | ||
this.serializer = _prosemirrorModel.DOMSerializer.fromSchema(schema); | ||
var parse = parser(schema); | ||
var serialize = serializer(schema); | ||
this.handleChange = (0, _debounce2.default)(function (value) { | ||
onChange(_this2.serialize(value)); | ||
options.doc = parse(value); | ||
this.onChange = (0, _debounce2.default)(function (value) { | ||
onChange(serialize(value)); | ||
}, 1000, { maxWait: 5000 }); | ||
this.setState({ | ||
value: this.parse(value) | ||
}); | ||
} | ||
@@ -88,8 +86,13 @@ }, { | ||
}, { | ||
key: 'shouldComponentUpdate', | ||
value: function shouldComponentUpdate() { | ||
// never re-render | ||
return false; | ||
} | ||
}, { | ||
key: 'render', | ||
value: function render() { | ||
return _react2.default.createElement(_Editor2.default, { | ||
value: this.state.value, | ||
plugins: this.props.plugins, | ||
onChange: this.handleChange | ||
options: this.props.options, | ||
onChange: this.onChange | ||
}); | ||
@@ -96,0 +99,0 @@ } |
{ | ||
"name": "@aeaton/react-prosemirror", | ||
"version": "0.1.1", | ||
"version": "0.2.0", | ||
"description": "A React component for ProseMirror", | ||
@@ -28,5 +28,11 @@ "main": "dist", | ||
"css-loader": "^0.28.7", | ||
"prosemirror-example-setup": "^1.0.0", | ||
"prosemirror-commands": "^1.0.0", | ||
"prosemirror-dropcursor": "^1.0.0", | ||
"prosemirror-gapcursor": "^1.0.0", | ||
"prosemirror-history": "^1.0.0", | ||
"prosemirror-inputrules": "^1.0.0", | ||
"prosemirror-keymap": "^1.0.0", | ||
"prosemirror-menu": "^1.0.1", | ||
"prosemirror-schema-basic": "^1.0.0", | ||
"prosemirror-schema-list": "^1.0.0", | ||
"react": "^16.0.0", | ||
@@ -33,0 +39,0 @@ "react-dom": "^16.0.0", |
@@ -9,23 +9,21 @@ ## Installation | ||
## Demo | ||
[View demo](http://git.macropus.org/react-prosemirror/) | ||
## Usage | ||
Use `npm run styleguide` to see live examples in [the styleguide](http://git.macropus.org/react-prosemirror/). | ||
The [`example`](example) folder contains ProseMirror configuration adapted from `prosemirror-schema-basic`. | ||
Example usage, using `prosemirror-example-setup` to provide a menu bar, keymaps, etc: | ||
```js | ||
import React from 'react' | ||
import { HtmlEditor } from '@aeaton/react-prosemirror' | ||
import { schema } from 'prosemirror-schema-basic' | ||
import { exampleSetup } from 'prosemirror-example-setup' | ||
import * as options from './example' | ||
import 'prosemirror-menu/style/menu.css' | ||
import 'prosemirror-example-setup/style/style.css' | ||
import './example/style.css' | ||
const plugins = exampleSetup({ schema, floatingMenu: false }) | ||
const Editor = ({ value, onChange }) => ( | ||
<HtmlEditor | ||
schema={schema} | ||
plugins={plugins} | ||
options={options} | ||
value={value} | ||
@@ -38,1 +36,2 @@ onChange={onChange} | ||
``` | ||
@@ -8,3 +8,3 @@ import React from 'react' | ||
componentDidMount () { | ||
const { onChange, ...options } = this.props | ||
const { onChange, options } = this.props | ||
@@ -21,8 +21,8 @@ const view = new EditorView(this.editorNode, { | ||
// TODO: what should happen here? | ||
componentWillReceiveProps (props) { | ||
// TODO: what should happen here? | ||
} | ||
// never re-render | ||
shouldComponentUpdate () { | ||
// never re-render | ||
return false | ||
@@ -29,0 +29,0 @@ } |
An editor for content stored as ProseMirror JSON. | ||
```js | ||
const { schema } = require('prosemirror-schema-basic') | ||
const { exampleSetup } = require('prosemirror-example-setup') | ||
const options = require('../../example') | ||
require('prosemirror-menu/style/menu.css') | ||
require('prosemirror-example-setup/style/style.css') | ||
require('../styles.css') | ||
require('../../example/style.css') | ||
require('../../styleguide/style.css') | ||
const plugins = exampleSetup({ schema, floatingMenu: false }) | ||
initialState = { | ||
@@ -21,4 +18,3 @@ doc: {} | ||
<Editor | ||
plugins={plugins} | ||
schema={schema} | ||
options={options} | ||
onChange={doc => setState({ doc })} | ||
@@ -25,0 +21,0 @@ /> |
@@ -7,28 +7,35 @@ import React from 'react' | ||
class HtmlEditor extends React.Component { | ||
parse (content) { | ||
const parser = schema => { | ||
const parser = DOMParser.fromSchema(schema) | ||
return content => { | ||
const container = document.createElement('article') | ||
container.innerHTML = content | ||
return this.parser.parse(container) | ||
return parser.parse(container) | ||
} | ||
} | ||
serialize (content) { | ||
const serializer = schema => { | ||
const serializer = DOMSerializer.fromSchema(schema) | ||
return content => { | ||
const container = document.createElement('article') | ||
container.appendChild(this.serializer.serializeFragment(content)) | ||
container.appendChild(serializer.serializeFragment(content)) | ||
return container.innerHTML | ||
} | ||
} | ||
class HtmlEditor extends React.Component { | ||
componentWillMount () { | ||
const { schema, value, onChange, ...options } = this.props | ||
const { value, onChange, options } = this.props | ||
const { schema } = options | ||
this.parser = DOMParser.fromSchema(schema) | ||
this.serializer = DOMSerializer.fromSchema(schema) | ||
const parse = parser(schema) | ||
const serialize = serializer(schema) | ||
this.setState({ | ||
...options, | ||
doc: this.parse(value), | ||
onChange: debounce(value => { | ||
onChange(this.serialize(value)) | ||
}, 1000, { maxWait: 5000 }) | ||
}) | ||
options.doc = parse(value) | ||
this.onChange = debounce(value => { | ||
onChange(serialize(value)) | ||
}, 1000, { maxWait: 5000 }) | ||
} | ||
@@ -40,4 +47,14 @@ | ||
shouldComponentUpdate () { | ||
// never re-render | ||
return false | ||
} | ||
render () { | ||
return <Editor {...this.state} /> | ||
return ( | ||
<Editor | ||
options={this.props.options} | ||
onChange={this.onChange} | ||
/> | ||
) | ||
} | ||
@@ -44,0 +61,0 @@ } |
@@ -6,11 +6,8 @@ An editor for content stored as HTML. | ||
```js | ||
const { schema } = require('prosemirror-schema-basic') | ||
const { exampleSetup } = require('prosemirror-example-setup') | ||
const options = require('../../example') | ||
require('prosemirror-menu/style/menu.css') | ||
require('prosemirror-example-setup/style/style.css') | ||
require('../styles.css') | ||
require('../../example/style.css') | ||
require('../../styleguide/style.css') | ||
const plugins = exampleSetup({ schema, floatingMenu: false }) | ||
initialState = { | ||
@@ -25,4 +22,3 @@ value: `<h1>This is a title</h1><p>This is a paragraph.</p>` | ||
<HtmlEditor | ||
plugins={plugins} | ||
schema={schema} | ||
options={options} | ||
value={state.value} | ||
@@ -29,0 +25,0 @@ onChange={value => setState({ value })} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
235
3.98%18491
-0.62%25
31.58%13
-7.14%36
-2.7%