Reputation: 1013
I'm having issues integrating Draft.js with Material UI's TextField
component (or Input
). I followed the documentation (https://material-ui.com/components/text-fields/#integration-with-3rd-party-input-libraries) but it still fails. I've integrated another package using the same method before which worked but there are issues with integrating Draft.js.
Code below:
import React, { useState, useRef, forwardRef } from "react";
import Editor, { createEditorStateWithText } from "draft-js-plugins-editor";
import createEmojiPlugin from "draft-js-emoji-plugin";
import { TextField, makeStyles } from "@material-ui/core";
import { isObject } from "lodash";
import { findDOMNode } from "react-dom";
import classNames from 'classnames';
function InputWrapper(props) {
const { component: Component, inputRef, ...other } = props;
const ref = useRef();
React.useImperativeHandle(inputRef, () => ({
focus: () => {
findDOMNode(inputRef.current).focus();
},
}));
return <Component ref={ref} {...other} />;
}
const emojiPlugin = createEmojiPlugin();
const { EmojiSuggestions, EmojiSelect } = emojiPlugin;
const plugins = [emojiPlugin];
const text = `Cool, we can have all sorts of Emojis here. š
šæāļøšš aaaand maybe a few more here š²āļøš» Quite fun!`;
const useStyles = makeStyles((theme) => ({
textField: {
width: "100%",
minHeight: 31,
tabSize: 8,
fontVariantLigatures: "none",
boxSizing: "content-box",
userSelect: "text",
whiteSpace: "pre-wrap",
},
}));
let DraftInput = (props, ref) => {
const {
InputProps,
InputLabelProps,
value,
handleEnterKeyPress,
onChange,
id,
...other
} = props;
const [editorState, setEditorState] = useState(
createEditorStateWithText(text)
);
const baseClasses = useStyles();
const handleChange = (state) => {
setEditorState(state);
// onChange(state);
};
const propClass =
isObject(InputProps) && InputProps.hasOwnProperty("className")
? InputProps.className
: false;
const classes = classNames([baseClasses, propClass, "emoji-input"]);
return (
<div>
<TextField
inputRef={ref}
autoFocus={true}
value={value}
InputProps={{
inputComponent: InputWrapper,
inputProps: {
component: Editor,
onChange: handleChange,
editorState,
},
...InputProps,
}}
InputLabelProps={{
...InputLabelProps,
}}
{...InputProps}
{...other}
/>
</div>
);
};
DraftInput = forwardRef(DraftInput);
export default DraftInput;
Note: there's still test data being used.
Upvotes: 1
Views: 1895
Reputation: 701
This is how I got it to work.
import Editor from "@draft-js-plugins/editor";
const DraftField = React.forwardRef(function DraftField(props, ref) {
const { component: Component, editorRef, handleOnChange, ...rest } = props;
React.useImperativeHandle(ref, () => ({
focus: () => {
editorRef?.current?.focus();
},
}));
return <Component {...rest} ref={editorRef} onChange={handleOnChange} />;
});
const DraftEditor = () => {
const [editorState, setEditorState] = React.useState();
const editorRef = React.useRef(null);
const handleOnChange = (newEditorState) => {
setEditorState(newEditorState);
};
return (
<TextField
fullWidth
label="Content"
InputProps={{
inputProps: {
component: Editor,
editorRef,
editorState,
handleOnChange
},
inputComponent: DraftField,
}}
/>
);
};
Upvotes: 1