Do you want to request a feature or report a bug?
Feature
What is the current behavior?
Project requires .css file, so JavaScript only users (using CSS-in-JS) can't use without manually copying over contents from node_modules/draft-js/dist/Draft.css.
What is the expected behavior?
It would be nice to have a way to use the Draft.css styles without relying on having .css imports in place for those that use css-in-js (like styled-components, emotion etc.). I personally think having the styles included under the hood would be the best long term solution. So perhaps the best non-breaking minor change would be to also expose the styles as a string that could be injected, like the following for styled-components:
import { Editor, EditorState, resetStylesCssString } from "draft-js";
import styled from "styled-components";
const StyledEditor = styled(Editor)`
${resetStylesCssString}
`
const RichTextEditor = () => {
const [editorState, setEditorState] = React.useState(
EditorState.createEmpty()
);
return (
<StyledEditor
editorState={editorState}
onChange={editorState => setEditorState(editorState)}
/>
);
};
Which versions of Draft.js, and which browser / OS are affected by this issue? Did this work in previous versions of Draft.js?
n/a
This is an interesting feature request, I'll bring it up for discussion with other frontend engineers. I'd prefer to have a consistent solution that matches the direction of React projects instead of offering a once-off solution. Have you considered setting up a build step based on PostCSS in your tooling?
@claudiopro We could add more tooling, but we would prefer not to "eject" from the default Next.js setup we have. To me, it seems like many of the most popular react libraries on npm support declarative CSS-in-JS (or have styled embedded in component internals) without requiring imperative .css importing. Examples:
etc.
Currently this is our workaround:
// Copied from node_modules/draft-js/dist/Draft.css
// View why this needs to be included at https://draftjs.org/docs/advanced-topics-issues-and-pitfalls.html#missing-draft-css
// Hoping to replace with less brittle CSS-in-JS option in the future per https://github.com/facebook/draft-js/issues/2060
const draftJsCss = `
.DraftEditor-editorContainer,.DraftEditor-root,.public-DraftEditor-content{height:inherit;text-align:initial}.public-DraftEditor-content[contenteditable=true]{-webkit-user-modify:read-write-plaintext-only}.DraftEditor-root{position:relative}.DraftEditor-editorContainer{background-color:rgba(255,255,255,0);border-left:.1px solid transparent;position:relative;z-index:1}.public-DraftEditor-block{position:relative}.DraftEditor-alignLeft .public-DraftStyleDefault-block{text-align:left}.DraftEditor-alignLeft .public-DraftEditorPlaceholder-root{left:0;text-align:left}.DraftEditor-alignCenter .public-DraftStyleDefault-block{text-align:center}.DraftEditor-alignCenter .public-DraftEditorPlaceholder-root{margin:0 auto;text-align:center;width:100%}.DraftEditor-alignRight .public-DraftStyleDefault-block{text-align:right}.DraftEditor-alignRight .public-DraftEditorPlaceholder-root{right:0;text-align:right}.public-DraftEditorPlaceholder-root{color:#9197a3;position:absolute;z-index:1}.public-DraftEditorPlaceholder-hasFocus{color:#bdc1c9}.DraftEditorPlaceholder-hidden{display:none}.public-DraftStyleDefault-block{position:relative;white-space:pre-wrap}.public-DraftStyleDefault-ltr{direction:ltr;text-align:left}.public-DraftStyleDefault-rtl{direction:rtl;text-align:right}.public-DraftStyleDefault-listLTR{direction:ltr}.public-DraftStyleDefault-listRTL{direction:rtl}.public-DraftStyleDefault-ol,.public-DraftStyleDefault-ul{margin:16px 0;padding:0}.public-DraftStyleDefault-depth0.public-DraftStyleDefault-listLTR{margin-left:1.5em}.public-DraftStyleDefault-depth0.public-DraftStyleDefault-listRTL{margin-right:1.5em}.public-DraftStyleDefault-depth1.public-DraftStyleDefault-listLTR{margin-left:3em}.public-DraftStyleDefault-depth1.public-DraftStyleDefault-listRTL{margin-right:3em}.public-DraftStyleDefault-depth2.public-DraftStyleDefault-listLTR{margin-left:4.5em}.public-DraftStyleDefault-depth2.public-DraftStyleDefault-listRTL{margin-right:4.5em}.public-DraftStyleDefault-depth3.public-DraftStyleDefault-listLTR{margin-left:6em}.public-DraftStyleDefault-depth3.public-DraftStyleDefault-listRTL{margin-right:6em}.public-DraftStyleDefault-depth4.public-DraftStyleDefault-listLTR{margin-left:7.5em}.public-DraftStyleDefault-depth4.public-DraftStyleDefault-listRTL{margin-right:7.5em}.public-DraftStyleDefault-unorderedListItem{list-style-type:square;position:relative}.public-DraftStyleDefault-unorderedListItem.public-DraftStyleDefault-depth0{list-style-type:disc}.public-DraftStyleDefault-unorderedListItem.public-DraftStyleDefault-depth1{list-style-type:circle}.public-DraftStyleDefault-orderedListItem{list-style-type:none;position:relative}.public-DraftStyleDefault-orderedListItem.public-DraftStyleDefault-listLTR:before{left:-36px;position:absolute;text-align:right;width:30px}.public-DraftStyleDefault-orderedListItem.public-DraftStyleDefault-listRTL:before{position:absolute;right:-36px;text-align:left;width:30px}.public-DraftStyleDefault-orderedListItem:before{content:counter(ol0) ". ";counter-increment:ol0}.public-DraftStyleDefault-orderedListItem.public-DraftStyleDefault-depth1:before{content:counter(ol1) ". ";counter-increment:ol1}.public-DraftStyleDefault-orderedListItem.public-DraftStyleDefault-depth2:before{content:counter(ol2) ". ";counter-increment:ol2}.public-DraftStyleDefault-orderedListItem.public-DraftStyleDefault-depth3:before{content:counter(ol3) ". ";counter-increment:ol3}.public-DraftStyleDefault-orderedListItem.public-DraftStyleDefault-depth4:before{content:counter(ol4) ". ";counter-increment:ol4}.public-DraftStyleDefault-depth0.public-DraftStyleDefault-reset{counter-reset:ol0}.public-DraftStyleDefault-depth1.public-DraftStyleDefault-reset{counter-reset:ol1}.public-DraftStyleDefault-depth2.public-DraftStyleDefault-reset{counter-reset:ol2}.public-DraftStyleDefault-depth3.public-DraftStyleDefault-reset{counter-reset:ol3}.public-DraftStyleDefault-depth4.public-DraftStyleDefault-reset{counter-reset:ol4}
`;
export default draftJsCss;
...
import styled from "styled-components";
import draftJsCss from "../utils/draftJsCss";
const StyledWrapper = styled.div`
& {
${draftJsCss}
}
`;
...
<StyledWrapper>
<Editor
editorState={editorState}
onChange={editorState => setEditorState(editorState)}
/>
</StyledWrapper>
...
Yes, Draft.js is historically tied to Facebook's own CSS module system and this was never changed since its release. Since then, many internal teams decided to adopt some form of CSS-in-JS library like emotion of which I'm a big fan. I'll leave this feature open as it's a good discussion starter to rethink how Draft.js is styled and plan towards a better integration in React based frameworks.