diff --git a/.babelrc b/.babelrc
index 6b35d80..d785532 100644
--- a/.babelrc
+++ b/.babelrc
@@ -1,9 +1,10 @@
{
- presets: [
- 'env',
- 'react'
+ "presets": [
+ "env",
+ "react",
+ "stage-2",
],
- plugins: [
- 'transform-object-rest-spread'
+ "plugins": [
+ "transform-object-rest-spread"
]
}
diff --git a/README.md b/README.md
index f373440..c24cb9c 100644
--- a/README.md
+++ b/README.md
@@ -36,18 +36,16 @@ const EditorWithPlugins = plugins(Editor); // Rich text editor component with pl
const toHTML = plugins(convertFromHTML); // function to convert from HTML including plugin functionality
const fromHTML = plugins(convertToHTML); // function to convert to HTML including plugin functionality
-const MyEditor = React.createClass({
- getInitialState() {
- return {
- editorState: EditorState.createWithContent(fromHTML('
'))
- };
- },
-
- onChange(editorState) {
+class MyEditor extends React.Comonent {
+ state = {
+ editorState: EditorState.createWithContent(fromHTML(''))
+ }
+
+ onChange = (editorState) => {
const html = toHTML(editorState.getCurrentContent());
console.log(html); // don't actually convert to HTML on every change!
this.setState({editorState});
- },
+ }
render() {
return (
diff --git a/example/ToolbarButton.js b/example/ToolbarButton.js
index 7388406..7b3c823 100644
--- a/example/ToolbarButton.js
+++ b/example/ToolbarButton.js
@@ -1,13 +1,5 @@
-window.ToolbarButton = createReactClass({
- getDefaultProps: function() {
- return {
- active: false,
- label: '',
- onClick: function() {}
- };
- },
-
- render: function() {
+class ToolbarButton extends React.Component {
+ render () {
var toolbarButtonStyle = {
display: 'inline-block',
minWidth: '24px',
@@ -29,4 +21,12 @@ window.ToolbarButton = createReactClass({
}, this.props.label)
);
}
-});
+};
+
+ToolbarButton.defaultProps = {
+ active: false,
+ label: '',
+ onClick: function() {}
+};
+
+window.ToolbarButton = ToolbarButton;
\ No newline at end of file
diff --git a/example/blockStyles.html b/example/blockStyles.html
index eb52965..9e79096 100644
--- a/example/blockStyles.html
+++ b/example/blockStyles.html
@@ -16,7 +16,6 @@
-
@@ -95,19 +94,17 @@
const toHTML = BlockPlugin(convertToHTML);
const fromHTML = BlockPlugin(convertFromHTML);
- const BlockStylesExample = createReactClass({
- getInitialState() {
- return {
- editorState: EditorState.createWithContent(
- fromHTML('Block style plugin
')
- )
- };
- },
+ class BlockStylesExample extends React.Component {
+ state = {
+ editorState: EditorState.createWithContent(
+ fromHTML('Block style plugin
')
+ )
+ }
- onChange(editorState) {
+ onChange = (editorState) => {
console.log(toHTML(editorState.getCurrentContent()));
this.setState({editorState});
- },
+ }
render() {
return (
@@ -125,7 +122,7 @@
);
}
- });
+ };
const WrappedComponent = KeyCommandController(BlockStylesExample);
@@ -135,6 +132,6 @@
);
diff --git a/example/inlineStyles.html b/example/inlineStyles.html
index 1a7323f..66ca917 100644
--- a/example/inlineStyles.html
+++ b/example/inlineStyles.html
@@ -16,7 +16,6 @@
-
@@ -93,19 +92,17 @@
const toHTML = InlinePlugin(convertToHTML);
const fromHTML = InlinePlugin(convertFromHTML);
- const InlineStylesExample = createReactClass({
- getInitialState() {
- return {
- editorState: EditorState.createWithContent(
- fromHTML('Inline styles example
')
- )
- };
- },
+ class InlineStylesExample extends React.Component {
+ state = {
+ editorState: EditorState.createWithContent(
+ fromHTML('Inline styles example
')
+ )
+ }
- onChange(editorState) {
+ onChange = (editorState) => {
console.log(toHTML(editorState.getCurrentContent()));
this.setState({editorState});
- },
+ }
render() {
return (
@@ -116,7 +113,7 @@
/>
);
}
- });
+ };
ReactDOM.render(
,
@@ -124,6 +121,6 @@
);
diff --git a/example/link.html b/example/link.html
index 053a97f..ced37da 100644
--- a/example/link.html
+++ b/example/link.html
@@ -16,7 +16,6 @@
-
@@ -122,19 +121,17 @@
const toHTML = LinkPlugin(convertToHTML);
const fromHTML = LinkPlugin(convertFromHTML);
- const LinkExample = createReactClass({
- getInitialState() {
- return {
- editorState: EditorState.createWithContent(
- fromHTML('')
- )
- };
- },
+ class LinkExample extends React.Component {
+ state = {
+ editorState: EditorState.createWithContent(
+ fromHTML('')
+ )
+ }
- onChange(editorState) {
+ onChange = (editorState) => {
console.log(toHTML(editorState.getCurrentContent()));
this.setState({editorState});
- },
+ }
render() {
return (
@@ -144,7 +141,7 @@
/>
);
}
- });
+ };
ReactDOM.render(
,
@@ -152,6 +149,6 @@
);
diff --git a/example/mention.html b/example/mention.html
index d1f2f34..4573d22 100644
--- a/example/mention.html
+++ b/example/mention.html
@@ -16,7 +16,6 @@
-
@@ -104,32 +103,20 @@
return results;
};
- const MentionResults = createReactClass({
- propTypes: {
- search: PropTypes.string.isRequired,
- offset: PropTypes.number.isRequired,
- length: PropTypes.number.isRequired,
- results: PropTypes.array.isRequired,
- onSelect: PropTypes.func.isRequired,
- addKeyCommandListener: PropTypes.func.isRequired,
- removeKeyCommandListener: PropTypes.func.isRequired
- },
-
- getInitialState() {
- return {
- selection: 0
- };
- },
+ class MentionResults extends React.Component {
+ state = {
+ selection: 0
+ }
componentDidMount() {
this.props.addKeyCommandListener(this.handleKeyCommand);
- },
+ }
componentWillUnmount() {
this.props.removeKeyCommandListener(this.handleKeyCommand);
- },
+ }
- handleKeyCommand(editorState, command, keyboardEvent) {
+ handleKeyCommand = (editorState, command, keyboardEvent) => {
const {
search,
offset,
@@ -163,9 +150,9 @@
default:
return null;
}
- },
+ }
- arrowUp() {
+ arrowUp = () => {
const {selection} = this.state;
if (selection > 0) {
@@ -173,9 +160,9 @@
selection: selection - 1
});
}
- },
+ }
- arrowDown() {
+ arrowDown = () => {
const {results} = this.props;
const {selection} = this.state;
@@ -184,9 +171,9 @@
selection: selection + 1
});
}
- },
+ }
- selectItem({value, text}) {
+ selectItem = ({value, text}) => {
const {
search,
offset,
@@ -195,9 +182,9 @@
} = this.props;
onSelect({value, text}, {search, offset, length});
- },
+ }
- renderResults() {
+ renderResults = () => {
const {
results,
} = this.props;
@@ -254,7 +241,7 @@
);
});
- },
+ }
render() {
return (
@@ -269,19 +256,22 @@
);
}
- });
+ };
- const TYPING_TRIGGER_REGEX = new RegExp('(\\B@[\\w\\s]{1,10})$');
+ MentionResults.propTypes = {
+ search: PropTypes.string.isRequired,
+ offset: PropTypes.number.isRequired,
+ length: PropTypes.number.isRequired,
+ results: PropTypes.array.isRequired,
+ onSelect: PropTypes.func.isRequired,
+ addKeyCommandListener: PropTypes.func.isRequired,
+ removeKeyCommandListener: PropTypes.func.isRequired
+ };
- const MentionOverlay = createReactClass({
- propTypes: {
- editorState: PropTypes.object.isRequired,
- onChange: PropTypes.func.isRequired,
- addKeyCommandListener: PropTypes.func.isRequired,
- removeKeyCommandListener: PropTypes.func.isRequired
- },
+ const TYPING_TRIGGER_REGEX = new RegExp('(\\B@[\\w\\s]{1,10})$');
- getCurrentSearch() {
+ class MentionOverlay extends React.Component {
+ getCurrentSearch = () => {
const selection = this.props.editorState.getSelection();
const contentState = this.props.editorState.getCurrentContent();
const blockText = contentState.getBlockForKey(selection.getStartKey()).getText();
@@ -305,9 +295,9 @@
offset: offset - beforeCursorText.length - 1,
length: 1 + beforeCursorText.length + pastCursorText.length
};
- },
+ }
- selectOption(option, {offset, length}) {
+ selectOption = (option, {offset, length}) => {
const {
editorState,
onChange
@@ -337,14 +327,14 @@
'insert-characters'
)
);
- },
+ }
- getResults(search) {
+ getResults = (search) => {
const regex = new RegExp(search.trim(), 'i');
return this.props.users.filter(({value, text}) => {
return (text.match(regex) !== null || value.toString().match(regex) !== null);
});
- },
+ }
render() {
const {
@@ -360,7 +350,7 @@
top,
left,
height
- } = getVisibleSelectionRect(window);
+ } = getVisibleSelectionRect(window) || {};
const results = this.getResults(currentSearch.search);
@@ -390,7 +380,14 @@
return null;
}
- });
+ };
+
+ MentionOverlay.propTypes = {
+ editorState: PropTypes.object.isRequired,
+ onChange: PropTypes.func.isRequired,
+ addKeyCommandListener: PropTypes.func.isRequired,
+ removeKeyCommandListener: PropTypes.func.isRequired
+ };
const MentionPlugin = createPlugin({
decorators: MentionDecorator,
@@ -403,19 +400,17 @@
const toHTML = MentionPlugin(convertToHTML);
const fromHTML = MentionPlugin(convertFromHTML);
- const MentionExample = createReactClass({
- getInitialState() {
- return {
- editorState: EditorState.createWithContent(
- fromHTML('Mention example @user1. Type @ to add a new mention for User 1 or User 2
')
- )
- };
- },
+ class MentionExample extends React.Component {
+ state = {
+ editorState: EditorState.createWithContent(
+ fromHTML('Mention example @user1. Type @ to add a new mention for User 1 or User 2
')
+ )
+ }
- onChange(editorState) {
+ onChange = (editorState) => {
console.log(toHTML(editorState.getCurrentContent()));
this.setState({editorState});
- },
+ }
render() {
return (
@@ -426,7 +421,7 @@
/>
);
}
- });
+ };
ReactDOM.render(
,
@@ -434,6 +429,6 @@
);
diff --git a/example/token.html b/example/token.html
index d12ae6a..ab673cb 100644
--- a/example/token.html
+++ b/example/token.html
@@ -16,7 +16,6 @@
-
@@ -126,19 +125,17 @@
const toHTML = TokenPlugin(convertToHTML);
const fromHTML = TokenPlugin(convertFromHTML);
- const TokenExample = createReactClass({
- getInitialState() {
- return {
- editorState: EditorState.createWithContent(
- fromHTML('Token example {{ token }}
')
- )
- };
- },
+ class TokenExample extends React.Component {
+ state ={
+ editorState: EditorState.createWithContent(
+ fromHTML('Token example {{ token }}
')
+ )
+ }
- onChange(editorState) {
+ onChange = (editorState) => {
console.log(toHTML(editorState.getCurrentContent()));
this.setState({editorState});
- },
+ }
render() {
return (
@@ -148,7 +145,7 @@
/>
);
}
- });
+ };
ReactDOM.render(
,
@@ -156,6 +153,6 @@
);
diff --git a/package.json b/package.json
index 6e4a904..f958db4 100644
--- a/package.json
+++ b/package.json
@@ -31,7 +31,6 @@
"react-dom": "^15.0.0 || ^16.0.0"
},
"dependencies": {
- "create-react-class": "^15.6.2",
"immutable": "^3.8.1",
"invariant": "^2.2.1",
"prop-types": "^15.6.0"
@@ -43,6 +42,7 @@
"babel-plugin-transform-object-rest-spread": "^6.6.5",
"babel-preset-env": "^1.6.1",
"babel-preset-react": "^6.5.0",
+ "babel-preset-stage-2": "^6.24.1",
"babel-standalone": "^6.7.7",
"draft-convert": "^1.3.1",
"draft-js": "^0.8.1",
diff --git a/src/components/Editor.js b/src/components/Editor.js
index 4dc6d26..20f4223 100644
--- a/src/components/Editor.js
+++ b/src/components/Editor.js
@@ -1,6 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
-import createReactClass from 'create-react-class';
import {List} from 'immutable';
import {
Editor,
@@ -11,68 +10,15 @@ import {
import KeyCommandController from './KeyCommandController';
import OverlayWrapper from './OverlayWrapper';
-const propTypes = {
- className: PropTypes.string,
- editorState: PropTypes.object,
- onChange: PropTypes.func,
- decorators: PropTypes.array,
- baseDecorator: PropTypes.func,
- styleMap: PropTypes.object,
- buttons: PropTypes.array,
- overlays: PropTypes.array,
- blockRendererFn: PropTypes.func,
- blockStyleFn: PropTypes.func,
- keyBindingFn: PropTypes.func,
- addKeyCommandListener: PropTypes.func.isRequired,
- removeKeyCommandListener: PropTypes.func.isRequired,
- handleReturn: PropTypes.func,
- onEscape: PropTypes.func,
- onTab: PropTypes.func,
- onUpArrow: PropTypes.func,
- onDownArrow: PropTypes.func,
- readOnly: PropTypes.bool,
- showButtons: PropTypes.bool
-};
-
-const EditorWrapper = createReactClass({
- propTypes,
-
- childContextTypes: {
- getEditorState: PropTypes.func,
- getReadOnly: PropTypes.func,
- setReadOnly: PropTypes.func,
- onChange: PropTypes.func,
- focus: PropTypes.func,
- blur: PropTypes.func
- },
-
- getDefaultProps() {
- return {
- className: '',
- editorState: EditorState.createEmpty(),
- onChange: () => {},
- decorators: [],
- baseDecorator: CompositeDecorator,
- styleMap: {},
- buttons: [],
- overlays: [],
- blockRendererFn: () => {},
- blockStyleFn: () => {},
- keyBindingFn: () => {},
- readOnly: false,
- showButtons: true
- };
- },
-
- getInitialState() {
+class EditorWrapper extends React.Component {
+ constructor(props) {
+ super(props);
const { baseDecorator } = this.props;
-
- const decorator = new baseDecorator(this.props.decorators);
- return {
- decorator,
+ this.state = {
+ decorator: new baseDecorator(this.props.decorators),
readOnly: false
};
- },
+ }
getChildContext() {
return {
@@ -83,7 +29,7 @@ const EditorWrapper = createReactClass({
focus: this.focus,
blur: this.blur
};
- },
+ }
componentWillReceiveProps(nextProps) {
if (nextProps.decorators.length === this.state.decorator._decorators.length) {
@@ -96,48 +42,48 @@ const EditorWrapper = createReactClass({
}
this.setState({decorator: new nextProps.baseDecorator(nextProps.decorators)});
- },
+ }
- keyBindingFn(e) {
+ keyBindingFn = (e) => {
const pluginsCommand = this.props.keyBindingFn(e);
if (pluginsCommand) {
return pluginsCommand;
}
return getDefaultKeyBinding(e);
- },
+ }
- handleReturn(e) {
+ handleReturn = (e) => {
return (this.props.handleReturn && this.props.handleReturn(e)) || this.props.handleKeyCommand('return', e);
- },
+ }
- onEscape(e) {
+ onEscape = (e) => {
return (this.props.onEscape && this.props.onEscape(e)) || this.props.handleKeyCommand('escape', e);
- },
+ }
- onTab(e) {
+ onTab = (e) => {
return (this.props.onTab && this.props.onTab(e)) || this.props.handleKeyCommand('tab', e);
- },
+ }
- onUpArrow(e) {
+ onUpArrow = (e) => {
return (this.props.onUpArrow && this.props.onUpArrow(e)) || this.props.handleKeyCommand('up-arrow', e);
- },
+ }
- onDownArrow(e) {
+ onDownArrow = (e) => {
return (this.props.onDownArrow && this.props.onDownArrow(e)) || this.props.handleKeyCommand('down-arrow', e);
- },
+ }
- focus() {
+ focus = () => {
this.refs.editor.focus();
- },
+ }
- blur() {
+ blur = () => {
this.refs.editor.blur();
- },
+ }
- getOtherProps() {
+ getOtherProps = () => {
const propKeys = Object.keys(this.props);
- const propTypeKeys = Object.keys(propTypes);
+ const propTypeKeys = Object.keys(EditorWrapper.propTypes);
const propsToPass = propKeys.filter((prop) => {
return propTypeKeys.indexOf(prop) === -1;
@@ -147,17 +93,17 @@ const EditorWrapper = createReactClass({
acc[prop] = this.props[prop];
return acc;
}, {});
- },
+ }
- getReadOnly() {
+ getReadOnly = () => {
return this.state.readOnly || this.props.readOnly;
- },
+ }
- setReadOnly(readOnly) {
+ setReadOnly = (readOnly) => {
this.setState({readOnly});
- },
+ }
- getDecoratedState() {
+ getDecoratedState = () => {
const {editorState} = this.props;
const {decorator} = this.state;
@@ -168,9 +114,9 @@ const EditorWrapper = createReactClass({
}
return EditorState.set(editorState, {decorator});
- },
+ }
- renderPluginButtons() {
+ renderPluginButtons = () => {
const {
onChange,
addKeyCommandListener,
@@ -197,9 +143,9 @@ const EditorWrapper = createReactClass({
/>
);
});
- },
+ }
- renderOverlays() {
+ renderOverlays = () => {
const {
onChange,
addKeyCommandListener,
@@ -221,7 +167,7 @@ const EditorWrapper = createReactClass({
);
});
- },
+ }
render() {
const {
@@ -268,6 +214,54 @@ const EditorWrapper = createReactClass({
);
}
-});
+};
+
+EditorWrapper.childContextTypes = {
+ getEditorState: PropTypes.func,
+ getReadOnly: PropTypes.func,
+ setReadOnly: PropTypes.func,
+ onChange: PropTypes.func,
+ focus: PropTypes.func,
+ blur: PropTypes.func
+};
+
+EditorWrapper.defaultProps = {
+ className: '',
+ editorState: EditorState.createEmpty(),
+ onChange: () => {},
+ decorators: [],
+ baseDecorator: CompositeDecorator,
+ styleMap: {},
+ buttons: [],
+ overlays: [],
+ blockRendererFn: () => {},
+ blockStyleFn: () => {},
+ keyBindingFn: () => {},
+ readOnly: false,
+ showButtons: true
+};
+
+EditorWrapper.propTypes = {
+ className: PropTypes.string,
+ editorState: PropTypes.object,
+ onChange: PropTypes.func,
+ decorators: PropTypes.array,
+ baseDecorator: PropTypes.func,
+ styleMap: PropTypes.object,
+ buttons: PropTypes.array,
+ overlays: PropTypes.array,
+ blockRendererFn: PropTypes.func,
+ blockStyleFn: PropTypes.func,
+ keyBindingFn: PropTypes.func,
+ addKeyCommandListener: PropTypes.func.isRequired,
+ removeKeyCommandListener: PropTypes.func.isRequired,
+ handleReturn: PropTypes.func,
+ onEscape: PropTypes.func,
+ onTab: PropTypes.func,
+ onUpArrow: PropTypes.func,
+ onDownArrow: PropTypes.func,
+ readOnly: PropTypes.bool,
+ showButtons: PropTypes.bool
+};
export default KeyCommandController(EditorWrapper);
diff --git a/src/components/KeyCommandController.js b/src/components/KeyCommandController.js
index f5e378d..e5927b5 100644
--- a/src/components/KeyCommandController.js
+++ b/src/components/KeyCommandController.js
@@ -1,6 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
-import createReactClass from 'create-react-class';
import invariant from 'invariant';
import {List} from 'immutable';
import {EditorState} from 'draft-js';
@@ -11,146 +10,148 @@ const providedProps = {
handleKeyCommand: PropTypes.func
};
-const KeyCommandController = (Component) => createReactClass({
- displayName: `KeyCommandController(${Component.displayName})`,
-
- propTypes: {
- editorState: PropTypes.object,
- onChange: PropTypes.func,
- keyCommandListeners: PropTypes.arrayOf(PropTypes.func),
- ...providedProps
- },
-
- getDefaultProps() {
- return {
- keyCommandListeners: []
- };
- },
-
- componentWillMount() {
- this.keyCommandOverrides = List(this.props.keyCommandListeners);
- this.keyCommandListeners = List();
- },
-
- componentDidMount() {
- // ensure valid props for deferral
- const propNames = Object.keys(providedProps);
- const presentProps = propNames.filter((propName) => this.props[propName] !== undefined);
- const nonePresent = presentProps.length === 0;
- const allPresent = presentProps.length === propNames.length;
-
- invariant(
- nonePresent || allPresent,
- `KeyCommandController: A KeyCommandController is receiving only some props (${presentProps.join(', ')}) necessary to defer to a parent key command controller.`
- );
-
- if (allPresent) {
- this.props.keyCommandListeners.forEach((listener) => {
- this.props.addKeyCommandListener(listener);
- });
+const KeyCommandController = (Component) => {
+ class KeyCommand extends React.Component {
+ componentWillMount() {
+ this.keyCommandOverrides = List(this.props.keyCommandListeners);
+ this.keyCommandListeners = List();
}
- },
- componentWillUnmount() {
- if (this.props.removeKeyCommandListener) {
- this.props.keyCommandListeners.forEach((listener) => {
- this.props.removeKeyCommandListener(listener);
- });
+ componentDidMount() {
+ // ensure valid props for deferral
+ const propNames = Object.keys(providedProps);
+ const presentProps = propNames.filter((propName) => this.props[propName] !== undefined);
+ const nonePresent = presentProps.length === 0;
+ const allPresent = presentProps.length === propNames.length;
+
+ invariant(
+ nonePresent || allPresent,
+ `KeyCommandController: A KeyCommandController is receiving only some props (${presentProps.join(', ')}) necessary to defer to a parent key command controller.`
+ );
+
+ if (allPresent) {
+ this.props.keyCommandListeners.forEach((listener) => {
+ this.props.addKeyCommandListener(listener);
+ });
+ }
}
- },
-
- addKeyCommandListener(listener) {
- const {addKeyCommandListener} = this.props;
- if (addKeyCommandListener) {
- addKeyCommandListener(listener);
- return;
+ componentWillUnmount() {
+ if (this.props.removeKeyCommandListener) {
+ this.props.keyCommandListeners.forEach((listener) => {
+ this.props.removeKeyCommandListener(listener);
+ });
+ }
}
- this.keyCommandListeners = this.keyCommandListeners.unshift(listener);
- },
+ addKeyCommandListener = (listener) => {
+ const {addKeyCommandListener} = this.props;
- removeKeyCommandListener(listener) {
- const {removeKeyCommandListener} = this.props;
+ if (addKeyCommandListener) {
+ addKeyCommandListener(listener);
+ return;
+ }
- if (removeKeyCommandListener) {
- removeKeyCommandListener(listener);
- return;
+ this.keyCommandListeners = this.keyCommandListeners.unshift(listener);
}
- this.keyCommandListeners = this.keyCommandListeners.filterNot((l) => l === listener);
- },
+ removeKeyCommandListener = (listener) => {
+ const {removeKeyCommandListener} = this.props;
- handleKeyCommand(command, keyboardEvent = null) {
- const {editorState, onChange, handleKeyCommand} = this.props;
+ if (removeKeyCommandListener) {
+ removeKeyCommandListener(listener);
+ return;
+ }
- if (handleKeyCommand) {
- return handleKeyCommand(command, keyboardEvent);
+ this.keyCommandListeners = this.keyCommandListeners.filterNot((l) => l === listener);
}
- const result = this.keyCommandListeners.concat(this.keyCommandOverrides).reduce(({state, hasChanged}, listener) => {
- if (hasChanged === true) {
- return {
- state,
- hasChanged
- };
+ handleKeyCommand = (command, keyboardEvent = null) => {
+ const {editorState, onChange, handleKeyCommand} = this.props;
+
+ if (handleKeyCommand) {
+ return handleKeyCommand(command, keyboardEvent);
}
- const listenerResult = listener(state, command, keyboardEvent);
- const isEditorState = listenerResult instanceof EditorState;
+ const result = this.keyCommandListeners.concat(this.keyCommandOverrides).reduce(({state, hasChanged}, listener) => {
+ if (hasChanged === true) {
+ return {
+ state,
+ hasChanged
+ };
+ }
- if (listenerResult === true || (isEditorState && listenerResult !== state)) {
- if (isEditorState) {
- onChange(listenerResult);
+ const listenerResult = listener(state, command, keyboardEvent);
+ const isEditorState = listenerResult instanceof EditorState;
+
+ if (listenerResult === true || (isEditorState && listenerResult !== state)) {
+ if (isEditorState) {
+ onChange(listenerResult);
+ return {
+ state: listenerResult,
+ hasChanged: true
+ };
+ }
return {
- state: listenerResult,
+ state,
hasChanged: true
};
}
+
return {
state,
- hasChanged: true
+ hasChanged
};
- }
+ }, {state: editorState, hasChanged: false});
- return {
- state,
- hasChanged
- };
- }, {state: editorState, hasChanged: false});
-
- return result.hasChanged;
- },
-
- focus() {
- this.refs.editor.focus();
- },
-
- blur() {
- this.refs.editor.blur();
- },
-
- render() {
- const {
- editorState,
- onChange,
- keyCommandListeners, // eslint-disable-line no-unused-vars
- ...others
- } = this.props;
-
-
- return (
-
- );
+ return result.hasChanged;
+ }
+
+ focus = () => {
+ this.refs.editor.focus();
+ }
+
+ blur = () => {
+ this.refs.editor.blur();
+ }
+
+ render() {
+ const {
+ editorState,
+ onChange,
+ keyCommandListeners, // eslint-disable-line no-unused-vars
+ ...others
+ } = this.props;
+
+
+ return (
+
+ );
+ }
}
-});
+
+ KeyCommand.displayName = `KeyCommandController(${Component.displayName})`;
+
+ KeyCommand.propTypes = {
+ editorState: PropTypes.object,
+ onChange: PropTypes.func,
+ keyCommandListeners: PropTypes.arrayOf(PropTypes.func),
+ ...providedProps
+ };
+
+ KeyCommand.defaultProps = {
+ keyCommandListeners: []
+ };
+
+ return KeyCommand;
+};
export default KeyCommandController;
diff --git a/src/components/OverlayWrapper.js b/src/components/OverlayWrapper.js
index 9f1274a..bffb717 100644
--- a/src/components/OverlayWrapper.js
+++ b/src/components/OverlayWrapper.js
@@ -1,33 +1,34 @@
import React from 'react';
import ReactDOM from 'react-dom';
-import createReactClass from 'create-react-class';
-export default createReactClass({
- getInitialState() {
+export default class OverlayWrapper extends React.Component {
+ constructor(props) {
+ super(props);
const node = document.createElement('div');
document.body.appendChild(node);
-
- return {node};
- },
+ this.state = {
+ node
+ };
+ }
componentDidMount() {
this.renderOverlay();
- },
+ }
componentDidUpdate() {
this.renderOverlay();
- },
+ }
componentWillUnmount() {
ReactDOM.unmountComponentAtNode(this.state.node);
- },
+ }
renderOverlay() {
const child = React.Children.only(this.props.children);
ReactDOM.render(child, this.state.node);
- },
+ }
render() {
return null;
}
-});
+};
diff --git a/src/components/Toolbar.js b/src/components/Toolbar.js
index 9c8fc4d..9a42c69 100644
--- a/src/components/Toolbar.js
+++ b/src/components/Toolbar.js
@@ -1,32 +1,18 @@
import React from 'react';
import PropTypes from 'prop-types';
-import createReactClass from 'create-react-class';
import KeyCommandController from './KeyCommandController';
-const Toolbar = createReactClass({
- propTypes: {
- editorState: PropTypes.object,
- onChange: PropTypes.func,
- buttons: PropTypes.array,
- addKeyCommandListener: PropTypes.func.isRequired,
- removeKeyCommandListener: PropTypes.func.isRequired
- },
-
- childContextTypes: {
- getEditorState: PropTypes.func,
- onChange: PropTypes.func
- },
-
+class Toolbar extends React.Component {
getChildContext() {
return {
getEditorState: this.getEditorState,
onChange: this.props.onChange
};
- },
+ }
getEditorState() {
return this.props.editorState;
- },
+ }
renderButtons() {
const {
@@ -50,7 +36,7 @@ const Toolbar = createReactClass({
/>
);
});
- },
+ }
render() {
return (
@@ -59,6 +45,19 @@ const Toolbar = createReactClass({
);
}
-});
+};
+
+Toolbar.propTypes = {
+ editorState: PropTypes.object,
+ onChange: PropTypes.func,
+ buttons: PropTypes.array,
+ addKeyCommandListener: PropTypes.func.isRequired,
+ removeKeyCommandListener: PropTypes.func.isRequired
+};
+
+Toolbar.childContextTypes = {
+ getEditorState: PropTypes.func,
+ onChange: PropTypes.func
+};
export default KeyCommandController(Toolbar);
diff --git a/src/plugins/createPlugin.js b/src/plugins/createPlugin.js
index c70e3ba..1a9c07a 100644
--- a/src/plugins/createPlugin.js
+++ b/src/plugins/createPlugin.js
@@ -1,6 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
-import createReactClass from 'create-react-class';
import {OrderedSet} from 'immutable';
import memoize from '../util/memoize';
import compose from '../util/compose';
@@ -50,44 +49,18 @@ const createPlugin = ({
if (ToWrap.prototype && ToWrap.prototype.isReactComponent) {
// wrapping an Editor component
- return createReactClass({
- displayName,
-
- propTypes: {
- styleMap: PropTypes.object,
- decorators: PropTypes.array,
- buttons: PropTypes.array,
- overlays: PropTypes.array,
- blockRendererFn: PropTypes.func,
- blockStyleFn: PropTypes.func,
- keyBindingFn: PropTypes.func,
- keyCommandListeners: PropTypes.arrayOf(PropTypes.func)
- },
-
- getDefaultProps() {
- return {
- styleMap: emptyObject,
- decorators: emptyArray,
- buttons: emptyArray,
- overlays: emptyArray,
- blockRendererFn: emptyFunction,
- blockStyleFn: emptyFunction,
- keyBindingFn: emptyFunction,
- keyCommandListeners: emptyArray
- };
- },
-
- focus() {
+ class Wrapper extends React.Component {
+ focus = () => {
if (this.refs.child.focus) {
this.refs.child.focus();
}
- },
+ }
- blur() {
+ blur = () => {
if (this.refs.child.blur) {
this.refs.child.blur();
}
- },
+ }
render() {
const newStyleMap = memoizedAssign(this.props.styleMap, styleMap);
@@ -114,7 +87,33 @@ const createPlugin = ({
/>
);
}
- });
+ };
+
+ Wrapper.displayName = displayName;
+
+ Wrapper.propTypes = {
+ styleMap: PropTypes.object,
+ decorators: PropTypes.array,
+ buttons: PropTypes.array,
+ overlays: PropTypes.array,
+ blockRendererFn: PropTypes.func,
+ blockStyleFn: PropTypes.func,
+ keyBindingFn: PropTypes.func,
+ keyCommandListeners: PropTypes.arrayOf(PropTypes.func)
+ };
+
+ Wrapper.defaultProps = {
+ styleMap: emptyObject,
+ decorators: emptyArray,
+ buttons: emptyArray,
+ overlays: emptyArray,
+ blockRendererFn: emptyFunction,
+ blockStyleFn: emptyFunction,
+ keyBindingFn: emptyFunction,
+ keyCommandListeners: emptyArray
+ };
+
+ return Wrapper;
} else {
// wrapping a converter function
return (...args) => {
diff --git a/yarn.lock b/yarn.lock
index 48e6d5a..ffb3b7a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -185,6 +185,14 @@ babel-generator@^6.26.0:
source-map "^0.5.6"
trim-right "^1.0.1"
+babel-helper-bindify-decorators@^6.24.1:
+ version "6.24.1"
+ resolved "https://widen.jfrog.io/widen/api/npm/npm-virtual/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz?dl=https://registry.yarnpkg.com/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz#14c19e5f142d7b47f19a52431e52b1ccbc40a330"
+ dependencies:
+ babel-runtime "^6.22.0"
+ babel-traverse "^6.24.1"
+ babel-types "^6.24.1"
+
babel-helper-builder-binary-assignment-operator-visitor@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664"
@@ -227,6 +235,15 @@ babel-helper-explode-assignable-expression@^6.24.1:
babel-traverse "^6.24.1"
babel-types "^6.24.1"
+babel-helper-explode-class@^6.24.1:
+ version "6.24.1"
+ resolved "https://widen.jfrog.io/widen/api/npm/npm-virtual/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz?dl=https://registry.yarnpkg.com/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz#7dc2a3910dee007056e1e31d640ced3d54eaa9eb"
+ dependencies:
+ babel-helper-bindify-decorators "^6.24.1"
+ babel-runtime "^6.22.0"
+ babel-traverse "^6.24.1"
+ babel-types "^6.24.1"
+
babel-helper-function-name@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9"
@@ -319,6 +336,22 @@ babel-plugin-syntax-async-functions@^6.8.0:
version "6.13.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95"
+babel-plugin-syntax-async-generators@^6.5.0:
+ version "6.13.0"
+ resolved "https://widen.jfrog.io/widen/api/npm/npm-virtual/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz?dl=https://registry.yarnpkg.com/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz#6bc963ebb16eccbae6b92b596eb7f35c342a8b9a"
+
+babel-plugin-syntax-class-properties@^6.8.0:
+ version "6.13.0"
+ resolved "https://widen.jfrog.io/widen/api/npm/npm-virtual/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz?dl=https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de"
+
+babel-plugin-syntax-decorators@^6.13.0:
+ version "6.13.0"
+ resolved "https://widen.jfrog.io/widen/api/npm/npm-virtual/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz?dl=https://registry.yarnpkg.com/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b"
+
+babel-plugin-syntax-dynamic-import@^6.18.0:
+ version "6.18.0"
+ resolved "https://widen.jfrog.io/widen/api/npm/npm-virtual/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz?dl=https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da"
+
babel-plugin-syntax-exponentiation-operator@^6.8.0:
version "6.13.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de"
@@ -339,7 +372,15 @@ babel-plugin-syntax-trailing-function-commas@^6.22.0:
version "6.22.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3"
-babel-plugin-transform-async-to-generator@^6.22.0:
+babel-plugin-transform-async-generator-functions@^6.24.1:
+ version "6.24.1"
+ resolved "https://widen.jfrog.io/widen/api/npm/npm-virtual/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz?dl=https://registry.yarnpkg.com/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz#f058900145fd3e9907a6ddf28da59f215258a5db"
+ dependencies:
+ babel-helper-remap-async-to-generator "^6.24.1"
+ babel-plugin-syntax-async-generators "^6.5.0"
+ babel-runtime "^6.22.0"
+
+babel-plugin-transform-async-to-generator@^6.22.0, babel-plugin-transform-async-to-generator@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761"
dependencies:
@@ -347,6 +388,25 @@ babel-plugin-transform-async-to-generator@^6.22.0:
babel-plugin-syntax-async-functions "^6.8.0"
babel-runtime "^6.22.0"
+babel-plugin-transform-class-properties@^6.24.1:
+ version "6.24.1"
+ resolved "https://widen.jfrog.io/widen/api/npm/npm-virtual/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz?dl=https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac"
+ dependencies:
+ babel-helper-function-name "^6.24.1"
+ babel-plugin-syntax-class-properties "^6.8.0"
+ babel-runtime "^6.22.0"
+ babel-template "^6.24.1"
+
+babel-plugin-transform-decorators@^6.24.1:
+ version "6.24.1"
+ resolved "https://widen.jfrog.io/widen/api/npm/npm-virtual/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz?dl=https://registry.yarnpkg.com/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz#788013d8f8c6b5222bdf7b344390dfd77569e24d"
+ dependencies:
+ babel-helper-explode-class "^6.24.1"
+ babel-plugin-syntax-decorators "^6.13.0"
+ babel-runtime "^6.22.0"
+ babel-template "^6.24.1"
+ babel-types "^6.24.1"
+
babel-plugin-transform-es2015-arrow-functions@^6.22.0:
version "6.22.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221"
@@ -515,7 +575,7 @@ babel-plugin-transform-es2015-unicode-regex@^6.22.0:
babel-runtime "^6.22.0"
regexpu-core "^2.0.0"
-babel-plugin-transform-exponentiation-operator@^6.22.0:
+babel-plugin-transform-exponentiation-operator@^6.22.0, babel-plugin-transform-exponentiation-operator@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e"
dependencies:
@@ -530,7 +590,7 @@ babel-plugin-transform-flow-strip-types@^6.22.0:
babel-plugin-syntax-flow "^6.18.0"
babel-runtime "^6.22.0"
-babel-plugin-transform-object-rest-spread@^6.6.5:
+babel-plugin-transform-object-rest-spread@^6.22.0, babel-plugin-transform-object-rest-spread@^6.6.5:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06"
dependencies:
@@ -638,6 +698,25 @@ babel-preset-react@^6.5.0:
babel-plugin-transform-react-jsx-source "^6.22.0"
babel-preset-flow "^6.23.0"
+babel-preset-stage-2@^6.24.1:
+ version "6.24.1"
+ resolved "https://widen.jfrog.io/widen/api/npm/npm-virtual/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz?dl=https://registry.yarnpkg.com/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz#d9e2960fb3d71187f0e64eec62bc07767219bdc1"
+ dependencies:
+ babel-plugin-syntax-dynamic-import "^6.18.0"
+ babel-plugin-transform-class-properties "^6.24.1"
+ babel-plugin-transform-decorators "^6.24.1"
+ babel-preset-stage-3 "^6.24.1"
+
+babel-preset-stage-3@^6.24.1:
+ version "6.24.1"
+ resolved "https://widen.jfrog.io/widen/api/npm/npm-virtual/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz?dl=https://registry.yarnpkg.com/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz#836ada0a9e7a7fa37cb138fb9326f87934a48395"
+ dependencies:
+ babel-plugin-syntax-trailing-function-commas "^6.22.0"
+ babel-plugin-transform-async-generator-functions "^6.24.1"
+ babel-plugin-transform-async-to-generator "^6.24.1"
+ babel-plugin-transform-exponentiation-operator "^6.24.1"
+ babel-plugin-transform-object-rest-spread "^6.22.0"
+
babel-register@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071"
@@ -890,14 +969,6 @@ core-util-is@1.0.2, core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
-create-react-class@^15.6.2:
- version "15.6.2"
- resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.2.tgz#cf1ed15f12aad7f14ef5f2dfe05e6c42f91ef02a"
- dependencies:
- fbjs "^0.8.9"
- loose-envify "^1.3.1"
- object-assign "^4.1.1"
-
cryptiles@2.x.x:
version "2.0.5"
resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
@@ -1050,7 +1121,7 @@ extsprintf@1.3.0, extsprintf@^1.2.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
-fbjs@^0.8.16, fbjs@^0.8.3, fbjs@^0.8.9:
+fbjs@^0.8.16, fbjs@^0.8.3:
version "0.8.16"
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
dependencies: