draftjs-logo

Draft.js

Build Status npm version

Live Demo


Status

THIS PROJECT IS CURRENTLY IN MAINTENANCE MODE. It will not receive any feature updates, only critical security bug patches. On 31st December 2022 the repo will be fully archived.

For users looking for an open source alternative, Meta have been working on migrating to a new framework, called Lexical. It's still experimental, and we're working on adding migration guides, but, we believe, it provides a more performant and accessible alternative.


Draft.js is a JavaScript rich text editor framework, built for React and backed by an immutable model.

  • Extensible and Customizable: We provide the building blocks to enable the creation of a broad variety of rich text composition experiences, from basic text styles to embedded media.
  • Declarative Rich Text: Draft.js fits seamlessly into React applications, abstracting away the details of rendering, selection, and input behavior with a familiar declarative API.
  • Immutable Editor State: The Draft.js model is built with immutable-js, offering an API with functional state updates and aggressively leveraging data persistence for scalable memory usage.

Learn how to use Draft.js in your own project.

Draft.js is used in production on Facebook, including status and comment inputs, Notes, and messenger.com.

API Notice

Before getting started, please be aware that we recently changed the API of Entity storage in Draft.

Previously, the old API was set to be removed in v0.11.0. Since, the plans have changed— v0.11.0 still supports the old API and v0.12.0 will remove it. Refer to the docs for more information and information on how to migrate.

Getting Started

npm install --save draft-js react react-dom

or

yarn add draft-js react react-dom

Draft.js depends on React and React DOM which must also be installed.

Using Draft.js

import React from 'react';
import ReactDOM from 'react-dom';
import {Editor, EditorState} from 'draft-js';

function MyEditor() {

  
  constructor(props) {
    super(props);
    this.state = {editorState: EditorState.createEmpty()};
    this.onChange = (editorState) => this.setState({editorState});
    this.setEditor = (editor) => {
      this.editor = editor;
    };
    this.focusEditor = () => {
      if (this.editor) {
        this.editor.focus();
      }
    };
  }

  componentDidMount() {
    this.focusEditor();
  }

  render() {
    return (
      <div style={styles.editor} onClick={this.focusEditor}>
        <Editor
          ref={this.setEditor}
          editorState={this.state.editorState}
          onChange={this.onChange}
        />
      </div>
    );
  }
}

const styles = {
  editor: {
    border: '1px solid gray',
    minHeight: '6em'
  }
};

ReactDOM.render(
  <MyEditor />,
  document.getElementById('container')
);

Since the release of React 16.8, you can use Hooks as a way to work with EditorState without using a class.

import React from "react";
import { Editor, EditorState } from "draft-js";
import "draft-js/dist/Draft.css";

export default function MyEditor() {
  const [editorState, setEditorState] = React.useState(() =>
    EditorState.createEmpty()
  );

  const editor = React.useRef(null);
  function focusEditor() {
    editor.current.focus();
  }

  return (
    <div
      style={{ border: "1px solid black", minHeight: "6em", cursor: "text" }}
      onClick={focusEditor}
    >
      <Editor
        ref={editor}
        editorState={editorState}
        onChange={setEditorState}
        placeholder="Write something!"
      />
    </div>
  );
}

Note that the editor itself is only as tall as its contents. In order to give users a visual cue, we recommend setting a border and a minimum height via the .DraftEditor-root CSS selector, or using a wrapper div like in the above example.

Because Draft.js supports unicode, you must have the following meta tag in the <head> </head> block of your HTML file:

<meta charset="utf-8" />

Further examples of how Draft.js can be used are provided in the /examples directory of this repo.

Building Draft.js

Draft.js is built with Yarn v1. Using other package managers mgiht work, but is not officially supported.

To clone and build, run:

git clone https://github.com/facebook/draft-js.git
cd draft-js
yarn install
yarn run build

Examples

To run the examples in the /examples directory, first build Draft.js locally as described above. Then, open the example HTML files in your browser.

Browser Support

IE / Edge
IE / Edge
Firefox
Firefox
Chrome
Chrome
Safari
Safari
iOS Safari
iOS Safari
Chrome for Android
Chrome for Android
IE11, Edge [1, 2] last 2 versions last 2 versions last 2 versions not fully supported [3] not fully supported [3]

[1] May need a shim or a polyfill for some syntax used in Draft.js (docs).

[2] IME inputs have known issues in these browsers, especially Korean (docs).

[3] There are known issues with mobile browsers, especially on Android (docs).

Resources and Ecosystem

Check out this curated list of articles and open-sourced projects/utilities: Awesome Draft-JS.

Discussion and Support

Join our Slack team!

Contribute

We welcome pull requests. Learn how to contribute.

License

Draft.js is MIT licensed.

Examples provided in this repository and in the documentation are separately licensed.

facebookarchive/draft-js

{
"props": {
"initialPayload": {
"allShortcutsEnabled": false,
"path": "/",
"repo": {
"id": 52113921,
"defaultBranch": "main",
"name": "draft-js",
"ownerLogin": "facebookarchive",
"currentUserCanPush": false,
"isFork": false,
"isEmpty": false,
"createdAt": "2016-02-19T20:18:26.000Z",
"ownerAvatar": "https://avatars.githubusercontent.com/u/7560860?v=4",
"public": true,
"private": false,
"isOrgOwned": true
},
"currentUser": null,
"refInfo": {
"name": "main",
"listCacheKey": "v0:1634747375.884501",
"canEdit": false,
"refType": "branch",
"currentOid": "afdb5c3177c13fd26cb0abbdc439488f3e21b73b"
},
"tree": {
"items": [
{
"name": ".dependabot",
"path": ".dependabot",
"contentType": "directory"
},
{
"name": ".github",
"path": ".github",
"contentType": "directory"
},
{
"name": "docs",
"path": "docs",
"contentType": "directory"
},
{
"name": "examples/draft-0-10-0",
"path": "examples/draft-0-10-0",
"contentType": "directory",
"hasSimplifiedPath": true
},
{
"name": "meta",
"path": "meta",
"contentType": "directory"
},
{
"name": "scripts",
"path": "scripts",
"contentType": "directory"
},
{
"name": "src",
"path": "src",
"contentType": "directory"
},
{
"name": "website",
"path": "website",
"contentType": "directory"
},
{
"name": ".alexignore",
"path": ".alexignore",
"contentType": "file"
},
{
"name": ".alexrc.js",
"path": ".alexrc.js",
"contentType": "file"
},
{
"name": ".eslintignore",
"path": ".eslintignore",
"contentType": "file"
},
{
"name": ".eslintrc.js",
"path": ".eslintrc.js",
"contentType": "file"
},
{
"name": ".gitignore",
"path": ".gitignore",
"contentType": "file"
},
{
"name": "CHANGELOG.md",
"path": "CHANGELOG.md",
"contentType": "file"
},
{
"name": "CODE_OF_CONDUCT.md",
"path": "CODE_OF_CONDUCT.md",
"contentType": "file"
},
{
"name": "CONTRIBUTING.md",
"path": "CONTRIBUTING.md",
"contentType": "file"
},
{
"name": "LICENSE",
"path": "LICENSE",
"contentType": "file"
},
{
"name": "LICENSE-examples",
"path": "LICENSE-examples",
"contentType": "file"
},
{
"name": "README.md",
"path": "README.md",
"contentType": "file"
},
{
"name": "gulpfile.js",
"path": "gulpfile.js",
"contentType": "file"
},
{
"name": "package.json",
"path": "package.json",
"contentType": "file"
},
{
"name": "prettier.config.js",
"path": "prettier.config.js",
"contentType": "file"
},
{
"name": "yarn.lock",
"path": "yarn.lock",
"contentType": "file"
}
],
"templateDirectorySuggestionUrl": null,
"readme": null,
"totalCount": 23,
"showBranchInfobar": false
},
"fileTree": null,
"fileTreeProcessingTime": null,
"foldersToFetch": [],
"treeExpanded": false,
"symbolsExpanded": false,
"isOverview": true,
"overview": {
"banners": {
"shouldRecommendReadme": false,
"isPersonalRepo": false,
"showUseActionBanner": false,
"actionSlug": null,
"actionId": null,
"showProtectBranchBanner": false,
"publishBannersInfo": {
"dismissActionNoticePath": "/settings/dismiss-notice/publish_action_from_repo",
"releasePath": "/facebookarchive/draft-js/releases/new?marketplace=true",
"showPublishActionBanner": false
},
"interactionLimitBanner": null,
"showInvitationBanner": false,
"inviterName": null,
"actionsMigrationBannerInfo": {
"releaseTags": [],
"showImmutableActionsMigrationBanner": false,
"initialMigrationStatus": null
}
},
"codeButton": {
"contactPath": "/contact",
"isEnterprise": false,
"local": {
"protocolInfo": {
"httpAvailable": true,
"sshAvailable": null,
"httpUrl": "https://github.com/facebookarchive/draft-js.git",
"showCloneWarning": null,
"sshUrl": null,
"sshCertificatesRequired": null,
"sshCertificatesAvailable": null,
"ghCliUrl": "gh repo clone facebookarchive/draft-js",
"defaultProtocol": "http",
"newSshKeyUrl": "/settings/ssh/new",
"setProtocolPath": "/users/set_protocol"
},
"platformInfo": {
"cloneUrl": "https://desktop.github.com",
"showVisualStudioCloneButton": false,
"visualStudioCloneUrl": "https://windows.github.com",
"showXcodeCloneButton": false,
"xcodeCloneUrl": "xcode://clone?repo=https%3A%2F%2Fgithub.com%2Ffacebookarchive%2Fdraft-js",
"zipballUrl": "/facebookarchive/draft-js/archive/refs/heads/main.zip"
}
},
"newCodespacePath": "/codespaces/new?hide_repo_select=true&repo=52113921"
},
"popovers": {
"rename": null,
"renamedParentRepo": null
},
"commitCount": "1,201",
"overviewFiles": [
{
"displayName": "README.md",
"repoName": "draft-js",
"refName": "main",
"path": "README.md",
"preferredFileType": "readme",
"tabName": "README",
"richText": "<article class=\"markdown-body entry-content container-lg\" itemprop=\"text\"><p align=\"center\" dir=\"auto\">\n <a href=\"http://draftjs.org/\" rel=\"nofollow\">\n <img src=\"https://camo.githubusercontent.com/8856666b61da6182a8d45bdccb66ed09afed4856e5c3777a2279a8f63a6aa920/68747470733a2f2f64726166746a732e6f72672f696d672f64726166746a732d6c6f676f2e737667\" alt=\"draftjs-logo\" width=\"8%\" data-canonical-src=\"https://draftjs.org/img/draftjs-logo.svg\" style=\"max-width: 100%;\">\n </a>\n</p>\n<div class=\"markdown-heading\" dir=\"auto\"><h1 align=\"center\" tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">\n Draft.js\n</h1><a id=\"user-content---draftjs\" class=\"anchor\" aria-label=\"Permalink: \n Draft.js\n\" href=\"#--draftjs\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p align=\"center\" dir=\"auto\">\n <a href=\"https://travis-ci.org/facebook/draft-js\" rel=\"nofollow\">\n <img src=\"https://camo.githubusercontent.com/69da40884584c4c80fafe2289e197a02e6dc0d96212556f41c395bfaf01a1b07/68747470733a2f2f696d672e736869656c64732e696f2f7472617669732f66616365626f6f6b2f64726166742d6a732f6d61737465722e7376673f7374796c653d666c6174\" alt=\"Build Status\" data-canonical-src=\"https://img.shields.io/travis/facebook/draft-js/master.svg?style=flat\" style=\"max-width: 100%;\">\n </a>\n <a href=\"https://yarn.pm/draft-js\" rel=\"nofollow\">\n <img src=\"https://camo.githubusercontent.com/548d36120ea5be3f3127629d20528cd113e1912a59df4ea906a2ff46ad8ebc82/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f64726166742d6a732e7376673f7374796c653d666c6174\" alt=\"npm version\" data-canonical-src=\"https://img.shields.io/npm/v/draft-js.svg?style=flat\" style=\"max-width: 100%;\">\n </a>\n</p>\n<p align=\"center\" dir=\"auto\">\n <a target=\"_blank\" rel=\"noopener noreferrer nofollow\" href=\"https://camo.githubusercontent.com/e0f4e36b5b4e58daf0a6c1d2f08e94b9ace24e43e0d776092a146f6cc9d13953/68747470733a2f2f6d656469612e67697068792e636f6d2f6d656469612f5848556a6178454c7063313153695253714e2f67697068792e676966\"><img src=\"https://camo.githubusercontent.com/e0f4e36b5b4e58daf0a6c1d2f08e94b9ace24e43e0d776092a146f6cc9d13953/68747470733a2f2f6d656469612e67697068792e636f6d2f6d656469612f5848556a6178454c7063313153695253714e2f67697068792e676966\" alt=\"Live Demo\" data-animated-image=\"\" data-canonical-src=\"https://media.giphy.com/media/XHUjaxELpc11SiRSqN/giphy.gif\" style=\"max-width: 100%;\"></a>\n</p>\n<hr>\n<div class=\"markdown-heading\" dir=\"auto\"><h2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Status</h2><a id=\"user-content-status\" class=\"anchor\" aria-label=\"Permalink: Status\" href=\"#status\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\"><strong>THIS PROJECT IS CURRENTLY IN MAINTENANCE MODE. It will not receive any feature updates, only critical security bug patches. On 31st December 2022 the repo will be fully archived.</strong></p>\n<p dir=\"auto\">For users looking for an open source alternative, Meta have been working on migrating to a new framework, called <a href=\"https://github.com/facebook/lexical\">Lexical</a>. It's still experimental, and we're working on adding migration guides, but, we believe, it provides a more performant and accessible alternative.</p>\n<hr>\n<p dir=\"auto\">Draft.js is a JavaScript rich text editor framework, built for React and\nbacked by an immutable model.</p>\n<ul dir=\"auto\">\n<li><strong>Extensible and Customizable:</strong> We provide the building blocks to enable\nthe creation of a broad variety of rich text composition experiences, from\nbasic text styles to embedded media.</li>\n<li><strong>Declarative Rich Text:</strong> Draft.js fits seamlessly into\n<a href=\"http://facebook.github.io/react/\" rel=\"nofollow\">React</a> applications,\nabstracting away the details of rendering, selection, and input behavior with a\nfamiliar declarative API.</li>\n<li><strong>Immutable Editor State:</strong> The Draft.js model is built\nwith <a href=\"https://facebook.github.io/immutable-js/\" rel=\"nofollow\">immutable-js</a>, offering\nan API with functional state updates and aggressively leveraging data persistence\nfor scalable memory usage.</li>\n</ul>\n<p dir=\"auto\"><a href=\"https://draftjs.org/docs/getting-started/\" rel=\"nofollow\">Learn how to use Draft.js in your own project.</a></p>\n<p dir=\"auto\">Draft.js is used in production on Facebook, including status and\ncomment inputs, <a href=\"https://www.facebook.com/notes/\" rel=\"nofollow\">Notes</a>, and\n<a href=\"https://www.messenger.com\" rel=\"nofollow\">messenger.com</a>.</p>\n<div class=\"markdown-heading\" dir=\"auto\"><h2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">API Notice</h2><a id=\"user-content-api-notice\" class=\"anchor\" aria-label=\"Permalink: API Notice\" href=\"#api-notice\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\">Before getting started, please be aware that we recently changed the API of\nEntity storage in Draft.</p>\n<p dir=\"auto\">Previously, the old API was set to be removed in <code>v0.11.0</code>. Since, the plans have changed— <code>v0.11.0</code> still supports the old API and <code>v0.12.0</code> will remove it. Refer to <a href=\"https://draftjs.org/docs/v0-10-api-migration\" rel=\"nofollow\">the docs</a> for more information and information on how to migrate.</p>\n<div class=\"markdown-heading\" dir=\"auto\"><h2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Getting Started</h2><a id=\"user-content-getting-started\" class=\"anchor\" aria-label=\"Permalink: Getting Started\" href=\"#getting-started\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<div class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"npm install --save draft-js react react-dom\n\nor\n\nyarn add draft-js react react-dom\"><pre class=\"notranslate\"><code>npm install --save draft-js react react-dom\n\nor\n\nyarn add draft-js react react-dom\n</code></pre></div>\n<p dir=\"auto\">Draft.js depends on React and React DOM which must also be installed.</p>\n<div class=\"markdown-heading\" dir=\"auto\"><h3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Using Draft.js</h3><a id=\"user-content-using-draftjs\" class=\"anchor\" aria-label=\"Permalink: Using Draft.js\" href=\"#using-draftjs\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<div class=\"highlight highlight-source-js notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"import React from 'react';\nimport ReactDOM from 'react-dom';\nimport {Editor, EditorState} from 'draft-js';\n\nfunction MyEditor() {\n\n \n constructor(props) {\n super(props);\n this.state = {editorState: EditorState.createEmpty()};\n this.onChange = (editorState) =&gt; this.setState({editorState});\n this.setEditor = (editor) =&gt; {\n this.editor = editor;\n };\n this.focusEditor = () =&gt; {\n if (this.editor) {\n this.editor.focus();\n }\n };\n }\n\n componentDidMount() {\n this.focusEditor();\n }\n\n render() {\n return (\n &lt;div style={styles.editor} onClick={this.focusEditor}&gt;\n &lt;Editor\n ref={this.setEditor}\n editorState={this.state.editorState}\n onChange={this.onChange}\n /&gt;\n &lt;/div&gt;\n );\n }\n}\n\nconst styles = {\n editor: {\n border: '1px solid gray',\n minHeight: '6em'\n }\n};\n\nReactDOM.render(\n &lt;MyEditor /&gt;,\n document.getElementById('container')\n);\"><pre><span class=\"pl-k\">import</span> <span class=\"pl-v\">React</span> <span class=\"pl-k\">from</span> <span class=\"pl-s\">'react'</span><span class=\"pl-kos\">;</span>\n<span class=\"pl-k\">import</span> <span class=\"pl-v\">ReactDOM</span> <span class=\"pl-k\">from</span> <span class=\"pl-s\">'react-dom'</span><span class=\"pl-kos\">;</span>\n<span class=\"pl-k\">import</span> <span class=\"pl-kos\">{</span><span class=\"pl-v\">Editor</span><span class=\"pl-kos\">,</span> <span class=\"pl-v\">EditorState</span><span class=\"pl-kos\">}</span> <span class=\"pl-k\">from</span> <span class=\"pl-s\">'draft-js'</span><span class=\"pl-kos\">;</span>\n\n<span class=\"pl-k\">function</span> <span class=\"pl-v\">MyEditor</span><span class=\"pl-kos\">(</span><span class=\"pl-kos\">)</span> <span class=\"pl-kos\">{</span>\n\n \n <span class=\"pl-en\">constructor</span><span class=\"pl-kos\">(</span><span class=\"pl-s1\">props</span><span class=\"pl-kos\">)</span><span class=\"pl-kos\"></span> <span class=\"pl-kos\">{</span>\n <span class=\"pl-smi\">super</span><span class=\"pl-kos\">(</span><span class=\"pl-s1\">props</span><span class=\"pl-kos\">)</span><span class=\"pl-kos\">;</span>\n <span class=\"pl-smi\">this</span><span class=\"pl-kos\">.</span><span class=\"pl-c1\">state</span> <span class=\"pl-c1\">=</span> <span class=\"pl-kos\">{</span><span class=\"pl-c1\">editorState</span>: <span class=\"pl-v\">EditorState</span><span class=\"pl-kos\">.</span><span class=\"pl-en\">createEmpty</span><span class=\"pl-kos\">(</span><span class=\"pl-kos\">)</span><span class=\"pl-kos\">}</span><span class=\"pl-kos\">;</span>\n <span class=\"pl-smi\">this</span><span class=\"pl-kos\">.</span><span class=\"pl-en\">onChange</span> <span class=\"pl-c1\">=</span> <span class=\"pl-kos\">(</span><span class=\"pl-s1\">editorState</span><span class=\"pl-kos\">)</span> <span class=\"pl-c1\">=&gt;</span> <span class=\"pl-smi\">this</span><span class=\"pl-kos\">.</span><span class=\"pl-en\">setState</span><span class=\"pl-kos\">(</span><span class=\"pl-kos\">{</span>editorState<span class=\"pl-kos\">}</span><span class=\"pl-kos\">)</span><span class=\"pl-kos\">;</span>\n <span class=\"pl-smi\">this</span><span class=\"pl-kos\">.</span><span class=\"pl-en\">setEditor</span> <span class=\"pl-c1\">=</span> <span class=\"pl-kos\">(</span><span class=\"pl-s1\">editor</span><span class=\"pl-kos\">)</span> <span class=\"pl-c1\">=&gt;</span> <span class=\"pl-kos\">{</span>\n <span class=\"pl-smi\">this</span><span class=\"pl-kos\">.</span><span class=\"pl-c1\">editor</span> <span class=\"pl-c1\">=</span> <span class=\"pl-s1\">editor</span><span class=\"pl-kos\">;</span>\n <span class=\"pl-kos\">}</span><span class=\"pl-kos\">;</span>\n <span class=\"pl-smi\">this</span><span class=\"pl-kos\">.</span><span class=\"pl-en\">focusEditor</span> <span class=\"pl-c1\">=</span> <span class=\"pl-kos\">(</span><span class=\"pl-kos\">)</span> <span class=\"pl-c1\">=&gt;</span> <span class=\"pl-kos\">{</span>\n <span class=\"pl-k\">if</span> <span class=\"pl-kos\">(</span><span class=\"pl-smi\">this</span><span class=\"pl-kos\">.</span><span class=\"pl-c1\">editor</span><span class=\"pl-kos\">)</span> <span class=\"pl-kos\">{</span>\n <span class=\"pl-smi\">this</span><span class=\"pl-kos\">.</span><span class=\"pl-c1\">editor</span><span class=\"pl-kos\">.</span><span class=\"pl-en\">focus</span><span class=\"pl-kos\">(</span><span class=\"pl-kos\">)</span><span class=\"pl-kos\">;</span>\n <span class=\"pl-kos\">}</span>\n <span class=\"pl-kos\">}</span><span class=\"pl-kos\">;</span>\n <span class=\"pl-kos\">}</span>\n\n <span class=\"pl-en\">componentDidMount</span><span class=\"pl-kos\">(</span><span class=\"pl-kos\">)</span><span class=\"pl-kos\"></span> <span class=\"pl-kos\">{</span>\n <span class=\"pl-smi\">this</span><span class=\"pl-kos\">.</span><span class=\"pl-en\">focusEditor</span><span class=\"pl-kos\">(</span><span class=\"pl-kos\">)</span><span class=\"pl-kos\">;</span>\n <span class=\"pl-kos\">}</span>\n\n <span class=\"pl-en\">render</span><span class=\"pl-kos\">(</span><span class=\"pl-kos\">)</span><span class=\"pl-kos\"></span> <span class=\"pl-kos\">{</span>\n <span class=\"pl-k\">return</span> <span class=\"pl-kos\">(</span>\n <span class=\"pl-c1\">&lt;</span><span class=\"pl-ent\">div</span> <span class=\"pl-c1\">style</span><span class=\"pl-c1\">=</span><span class=\"pl-kos\">{</span><span class=\"pl-s1\">styles</span><span class=\"pl-kos\">.</span><span class=\"pl-c1\">editor</span><span class=\"pl-kos\">}</span> <span class=\"pl-c1\">onClick</span><span class=\"pl-c1\">=</span><span class=\"pl-kos\">{</span><span class=\"pl-smi\">this</span><span class=\"pl-kos\">.</span><span class=\"pl-c1\">focusEditor</span><span class=\"pl-kos\">}</span><span class=\"pl-c1\">&gt;</span>\n <span class=\"pl-c1\">&lt;</span><span class=\"pl-ent\">Editor</span>\n <span class=\"pl-c1\">ref</span><span class=\"pl-c1\">=</span><span class=\"pl-kos\">{</span><span class=\"pl-smi\">this</span><span class=\"pl-kos\">.</span><span class=\"pl-c1\">setEditor</span><span class=\"pl-kos\">}</span>\n <span class=\"pl-c1\">editorState</span><span class=\"pl-c1\">=</span><span class=\"pl-kos\">{</span><span class=\"pl-smi\">this</span><span class=\"pl-kos\">.</span><span class=\"pl-c1\">state</span><span class=\"pl-kos\">.</span><span class=\"pl-c1\">editorState</span><span class=\"pl-kos\">}</span>\n <span class=\"pl-c1\">onChange</span><span class=\"pl-c1\">=</span><span class=\"pl-kos\">{</span><span class=\"pl-smi\">this</span><span class=\"pl-kos\">.</span><span class=\"pl-c1\">onChange</span><span class=\"pl-kos\">}</span>\n <span class=\"pl-c1\">/</span><span class=\"pl-c1\">&gt;</span>\n <span class=\"pl-c1\">&lt;</span><span class=\"pl-c1\">/</span><span class=\"pl-ent\">div</span><span class=\"pl-c1\">&gt;</span>\n <span class=\"pl-kos\">)</span><span class=\"pl-kos\">;</span>\n <span class=\"pl-kos\">}</span>\n<span class=\"pl-kos\">}</span>\n\n<span class=\"pl-k\">const</span> <span class=\"pl-s1\">styles</span> <span class=\"pl-c1\">=</span> <span class=\"pl-kos\">{</span>\n <span class=\"pl-c1\">editor</span>: <span class=\"pl-kos\">{</span>\n <span class=\"pl-c1\">border</span>: <span class=\"pl-s\">'1px solid gray'</span><span class=\"pl-kos\">,</span>\n <span class=\"pl-c1\">minHeight</span>: <span class=\"pl-s\">'6em'</span>\n <span class=\"pl-kos\">}</span>\n<span class=\"pl-kos\">}</span><span class=\"pl-kos\">;</span>\n\n<span class=\"pl-v\">ReactDOM</span><span class=\"pl-kos\">.</span><span class=\"pl-en\">render</span><span class=\"pl-kos\">(</span>\n <span class=\"pl-c1\">&lt;</span><span class=\"pl-ent\">MyEditor</span> <span class=\"pl-c1\">/</span><span class=\"pl-c1\">&gt;</span><span class=\"pl-kos\">,</span>\n <span class=\"pl-smi\">document</span><span class=\"pl-kos\">.</span><span class=\"pl-en\">getElementById</span><span class=\"pl-kos\">(</span><span class=\"pl-s\">'container'</span><span class=\"pl-kos\">)</span>\n<span class=\"pl-kos\">)</span><span class=\"pl-kos\">;</span></pre></div>\n<p dir=\"auto\">Since the release of React 16.8, you can use <a href=\"https://reactjs.org/docs/hooks-intro.html\" rel=\"nofollow\">Hooks</a> as a way to work with <code>EditorState</code> without using a class.</p>\n<div class=\"highlight highlight-source-js notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"import React from &quot;react&quot;;\nimport { Editor, EditorState } from &quot;draft-js&quot;;\nimport &quot;draft-js/dist/Draft.css&quot;;\n\nexport default function MyEditor() {\n const [editorState, setEditorState] = React.useState(() =&gt;\n EditorState.createEmpty()\n );\n\n const editor = React.useRef(null);\n function focusEditor() {\n editor.current.focus();\n }\n\n return (\n &lt;div\n style={{ border: &quot;1px solid black&quot;, minHeight: &quot;6em&quot;, cursor: &quot;text&quot; }}\n onClick={focusEditor}\n &gt;\n &lt;Editor\n ref={editor}\n editorState={editorState}\n onChange={setEditorState}\n placeholder=&quot;Write something!&quot;\n /&gt;\n &lt;/div&gt;\n );\n}\n\"><pre><span class=\"pl-k\">import</span> <span class=\"pl-v\">React</span> <span class=\"pl-k\">from</span> <span class=\"pl-s\">\"react\"</span><span class=\"pl-kos\">;</span>\n<span class=\"pl-k\">import</span> <span class=\"pl-kos\">{</span> <span class=\"pl-v\">Editor</span><span class=\"pl-kos\">,</span> <span class=\"pl-v\">EditorState</span> <span class=\"pl-kos\">}</span> <span class=\"pl-k\">from</span> <span class=\"pl-s\">\"draft-js\"</span><span class=\"pl-kos\">;</span>\n<span class=\"pl-k\">import</span> <span class=\"pl-s\">\"draft-js/dist/Draft.css\"</span><span class=\"pl-kos\">;</span>\n\n<span class=\"pl-k\">export</span> <span class=\"pl-k\">default</span> <span class=\"pl-k\">function</span> <span class=\"pl-v\">MyEditor</span><span class=\"pl-kos\">(</span><span class=\"pl-kos\">)</span> <span class=\"pl-kos\">{</span>\n <span class=\"pl-k\">const</span> <span class=\"pl-kos\">[</span><span class=\"pl-s1\">editorState</span><span class=\"pl-kos\">,</span> <span class=\"pl-s1\">setEditorState</span><span class=\"pl-kos\">]</span> <span class=\"pl-c1\">=</span> <span class=\"pl-v\">React</span><span class=\"pl-kos\">.</span><span class=\"pl-en\">useState</span><span class=\"pl-kos\">(</span><span class=\"pl-kos\">(</span><span class=\"pl-kos\">)</span> <span class=\"pl-c1\">=&gt;</span>\n <span class=\"pl-v\">EditorState</span><span class=\"pl-kos\">.</span><span class=\"pl-en\">createEmpty</span><span class=\"pl-kos\">(</span><span class=\"pl-kos\">)</span>\n <span class=\"pl-kos\">)</span><span class=\"pl-kos\">;</span>\n\n <span class=\"pl-k\">const</span> <span class=\"pl-s1\">editor</span> <span class=\"pl-c1\">=</span> <span class=\"pl-v\">React</span><span class=\"pl-kos\">.</span><span class=\"pl-en\">useRef</span><span class=\"pl-kos\">(</span><span class=\"pl-c1\">null</span><span class=\"pl-kos\">)</span><span class=\"pl-kos\">;</span>\n <span class=\"pl-k\">function</span> <span class=\"pl-en\">focusEditor</span><span class=\"pl-kos\">(</span><span class=\"pl-kos\">)</span> <span class=\"pl-kos\">{</span>\n <span class=\"pl-s1\">editor</span><span class=\"pl-kos\">.</span><span class=\"pl-c1\">current</span><span class=\"pl-kos\">.</span><span class=\"pl-en\">focus</span><span class=\"pl-kos\">(</span><span class=\"pl-kos\">)</span><span class=\"pl-kos\">;</span>\n <span class=\"pl-kos\">}</span>\n\n <span class=\"pl-k\">return</span> <span class=\"pl-kos\">(</span>\n <span class=\"pl-c1\">&lt;</span><span class=\"pl-ent\">div</span>\n <span class=\"pl-c1\">style</span><span class=\"pl-c1\">=</span><span class=\"pl-kos\">{</span><span class=\"pl-kos\">{</span> <span class=\"pl-c1\">border</span>: <span class=\"pl-s\">\"1px solid black\"</span><span class=\"pl-kos\">,</span> <span class=\"pl-c1\">minHeight</span>: <span class=\"pl-s\">\"6em\"</span><span class=\"pl-kos\">,</span> <span class=\"pl-c1\">cursor</span>: <span class=\"pl-s\">\"text\"</span> <span class=\"pl-kos\">}</span><span class=\"pl-kos\">}</span>\n <span class=\"pl-c1\">onClick</span><span class=\"pl-c1\">=</span><span class=\"pl-kos\">{</span><span class=\"pl-s1\">focusEditor</span><span class=\"pl-kos\">}</span>\n <span class=\"pl-c1\">&gt;</span>\n <span class=\"pl-c1\">&lt;</span><span class=\"pl-ent\">Editor</span>\n <span class=\"pl-c1\">ref</span><span class=\"pl-c1\">=</span><span class=\"pl-kos\">{</span><span class=\"pl-s1\">editor</span><span class=\"pl-kos\">}</span>\n <span class=\"pl-c1\">editorState</span><span class=\"pl-c1\">=</span><span class=\"pl-kos\">{</span><span class=\"pl-s1\">editorState</span><span class=\"pl-kos\">}</span>\n <span class=\"pl-c1\">onChange</span><span class=\"pl-c1\">=</span><span class=\"pl-kos\">{</span><span class=\"pl-s1\">setEditorState</span><span class=\"pl-kos\">}</span>\n <span class=\"pl-c1\">placeholder</span><span class=\"pl-c1\">=</span><span class=\"pl-s\">\"Write something!\"</span>\n <span class=\"pl-c1\">/</span><span class=\"pl-c1\">&gt;</span>\n <span class=\"pl-c1\">&lt;</span><span class=\"pl-c1\">/</span><span class=\"pl-ent\">div</span><span class=\"pl-c1\">&gt;</span>\n <span class=\"pl-kos\">)</span><span class=\"pl-kos\">;</span>\n<span class=\"pl-kos\">}</span></pre></div>\n<p dir=\"auto\">Note that the editor itself is only as tall as its contents. In order to give users a visual cue, we recommend setting a border and a minimum height via the <code>.DraftEditor-root</code> CSS selector, or using a wrapper div like in the above example.</p>\n<p dir=\"auto\">Because Draft.js supports unicode, you must have the following meta tag in the <code>&lt;head&gt;</code> <code>&lt;/head&gt;</code> block of your HTML file:</p>\n<div class=\"highlight highlight-text-html-basic notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"&lt;meta charset=&quot;utf-8&quot; /&gt;\"><pre><span class=\"pl-kos\">&lt;</span><span class=\"pl-ent\">meta</span> <span class=\"pl-c1\">charset</span>=\"<span class=\"pl-s\">utf-8</span>\" /&gt;</pre></div>\n<p dir=\"auto\">Further examples of how Draft.js can be used are provided in the <code>/examples</code> directory of this repo.</p>\n<div class=\"markdown-heading\" dir=\"auto\"><h3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Building Draft.js</h3><a id=\"user-content-building-draftjs\" class=\"anchor\" aria-label=\"Permalink: Building Draft.js\" href=\"#building-draftjs\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\">Draft.js is built with <a href=\"https://classic.yarnpkg.com/en/\" rel=\"nofollow\">Yarn</a> v1. Using other package managers mgiht work, but is not officially supported.</p>\n<p dir=\"auto\">To clone and build, run:</p>\n<div class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"git clone https://github.com/facebook/draft-js.git\ncd draft-js\nyarn install\nyarn run build\"><pre class=\"notranslate\"><code>git clone https://github.com/facebook/draft-js.git\ncd draft-js\nyarn install\nyarn run build\n</code></pre></div>\n<div class=\"markdown-heading\" dir=\"auto\"><h3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Examples</h3><a id=\"user-content-examples\" class=\"anchor\" aria-label=\"Permalink: Examples\" href=\"#examples\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\">To run the examples in the <code>/examples</code> directory, first build Draft.js locally as described above. Then, open the example HTML files in your browser.</p>\n<div class=\"markdown-heading\" dir=\"auto\"><h2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Browser Support</h2><a id=\"user-content-browser-support\" class=\"anchor\" aria-label=\"Permalink: Browser Support\" href=\"#browser-support\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<markdown-accessiblity-table><table>\n<thead>\n<tr>\n<th><a target=\"_blank\" rel=\"noopener noreferrer nofollow\" href=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_32x32.png\"><img src=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_32x32.png\" alt=\"IE / Edge\" style=\"max-width: 100%;\"></a> <br> IE / Edge</th>\n<th><a target=\"_blank\" rel=\"noopener noreferrer nofollow\" href=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_32x32.png\"><img src=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_32x32.png\" alt=\"Firefox\" style=\"max-width: 100%;\"></a> <br> Firefox</th>\n<th><a target=\"_blank\" rel=\"noopener noreferrer nofollow\" href=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_32x32.png\"><img src=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_32x32.png\" alt=\"Chrome\" style=\"max-width: 100%;\"></a> <br> Chrome</th>\n<th><a target=\"_blank\" rel=\"noopener noreferrer nofollow\" href=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_32x32.png\"><img src=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_32x32.png\" alt=\"Safari\" style=\"max-width: 100%;\"></a> <br> Safari</th>\n<th><a target=\"_blank\" rel=\"noopener noreferrer nofollow\" href=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari-ios/safari-ios_32x32.png\"><img src=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari-ios/safari-ios_32x32.png\" alt=\"iOS Safari\" style=\"max-width: 100%;\"></a> <br>iOS Safari</th>\n<th><a target=\"_blank\" rel=\"noopener noreferrer nofollow\" href=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_32x32.png\"><img src=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_32x32.png\" alt=\"Chrome for Android\" style=\"max-width: 100%;\"></a> <br> Chrome for Android</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>IE11, Edge [1, 2]</td>\n<td>last 2 versions</td>\n<td>last 2 versions</td>\n<td>last 2 versions</td>\n<td>not fully supported [3]</td>\n<td>not fully supported [3]</td>\n</tr>\n</tbody>\n</table></markdown-accessiblity-table>\n<p dir=\"auto\">[1] May need a shim or a polyfill for some syntax used in Draft.js (<a href=\"https://draftjs.org/docs/advanced-topics-issues-and-pitfalls/#polyfills\" rel=\"nofollow\">docs</a>).</p>\n<p dir=\"auto\">[2] IME inputs have known issues in these browsers, especially Korean (<a href=\"https://draftjs.org/docs/advanced-topics-issues-and-pitfalls/#ime-and-internet-explorer\" rel=\"nofollow\">docs</a>).</p>\n<p dir=\"auto\">[3] There are known issues with mobile browsers, especially on Android (<a href=\"https://draftjs.org/docs/advanced-topics-issues-and-pitfalls/#mobile-not-yet-supported\" rel=\"nofollow\">docs</a>).</p>\n<div class=\"markdown-heading\" dir=\"auto\"><h2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Resources and Ecosystem</h2><a id=\"user-content-resources-and-ecosystem\" class=\"anchor\" aria-label=\"Permalink: Resources and Ecosystem\" href=\"#resources-and-ecosystem\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\">Check out this curated list of articles and open-sourced projects/utilities: <a href=\"https://github.com/nikgraf/awesome-draft-js\">Awesome Draft-JS</a>.</p>\n<div class=\"markdown-heading\" dir=\"auto\"><h2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Discussion and Support</h2><a id=\"user-content-discussion-and-support\" class=\"anchor\" aria-label=\"Permalink: Discussion and Support\" href=\"#discussion-and-support\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\">Join our <a href=\"https://draftjs.herokuapp.com\" rel=\"nofollow\">Slack team</a>!</p>\n<div class=\"markdown-heading\" dir=\"auto\"><h2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">Contribute</h2><a id=\"user-content-contribute\" class=\"anchor\" aria-label=\"Permalink: Contribute\" href=\"#contribute\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\">We welcome pull requests. Learn how to\n<a href=\"https://github.com/facebook/draft-js/blob/master/CONTRIBUTING.md\">contribute</a>.</p>\n<div class=\"markdown-heading\" dir=\"auto\"><h2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\">License</h2><a id=\"user-content-license\" class=\"anchor\" aria-label=\"Permalink: License\" href=\"#license\"><svg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"><path d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"></path></svg></a></div>\n<p dir=\"auto\">Draft.js is <a href=\"https://github.com/facebook/draft-js/blob/master/LICENSE\">MIT licensed</a>.</p>\n<p dir=\"auto\">Examples provided in this repository and in the documentation are separately\nlicensed.</p>\n</article>",
"loaded": true,
"timedOut": false,
"errorMessage": null,
"headerInfo": {
"toc": [
{
"level": 1,
"text": "\n Draft.js\n",
"anchor": "--draftjs",
"htmlText": "\n Draft.js\n"
},
{
"level": 2,
"text": "Status",
"anchor": "status",
"htmlText": "Status"
},
{
"level": 2,
"text": "API Notice",
"anchor": "api-notice",
"htmlText": "API Notice"
},
{
"level": 2,
"text": "Getting Started",
"anchor": "getting-started",
"htmlText": "Getting Started"
},
{
"level": 3,
"text": "Using Draft.js",
"anchor": "using-draftjs",
"htmlText": "Using Draft.js"
},
{
"level": 3,
"text": "Building Draft.js",
"anchor": "building-draftjs",
"htmlText": "Building Draft.js"
},
{
"level": 3,
"text": "Examples",
"anchor": "examples",
"htmlText": "Examples"
},
{
"level": 2,
"text": "Browser Support",
"anchor": "browser-support",
"htmlText": "Browser Support"
},
{
"level": 2,
"text": "Resources and Ecosystem",
"anchor": "resources-and-ecosystem",
"htmlText": "Resources and Ecosystem"
},
{
"level": 2,
"text": "Discussion and Support",
"anchor": "discussion-and-support",
"htmlText": "Discussion and Support"
},
{
"level": 2,
"text": "Contribute",
"anchor": "contribute",
"htmlText": "Contribute"
},
{
"level": 2,
"text": "License",
"anchor": "license",
"htmlText": "License"
}
],
"siteNavLoginPath": "/login?return_to=https%3A%2F%2Fgithub.com%2Ffacebookarchive%2Fdraft-js"
}
},
{
"displayName": "CODE_OF_CONDUCT.md",
"repoName": "draft-js",
"refName": "main",
"path": "CODE_OF_CONDUCT.md",
"preferredFileType": "code_of_conduct",
"tabName": "Code of conduct",
"richText": null,
"loaded": false,
"timedOut": false,
"errorMessage": null,
"headerInfo": {
"toc": null,
"siteNavLoginPath": "/login?return_to=https%3A%2F%2Fgithub.com%2Ffacebookarchive%2Fdraft-js"
}
},
{
"displayName": "LICENSE",
"repoName": "draft-js",
"refName": "main",
"path": "LICENSE",
"preferredFileType": "license",
"tabName": "MIT",
"richText": null,
"loaded": false,
"timedOut": false,
"errorMessage": null,
"headerInfo": {
"toc": null,
"siteNavLoginPath": "/login?return_to=https%3A%2F%2Fgithub.com%2Ffacebookarchive%2Fdraft-js"
}
},
{
"displayName": "LICENSE-examples",
"repoName": "draft-js",
"refName": "main",
"path": "LICENSE-examples",
"preferredFileType": "license",
"tabName": "License",
"richText": null,
"loaded": false,
"timedOut": false,
"errorMessage": null,
"headerInfo": {
"toc": null,
"siteNavLoginPath": "/login?return_to=https%3A%2F%2Fgithub.com%2Ffacebookarchive%2Fdraft-js"
}
}
],
"overviewFilesProcessingTime": 0
}
},
"appPayload": {
"helpUrl": "https://docs.github.com",
"findFileWorkerPath": "/assets-cdn/worker/find-file-worker-1583894afd38.js",
"findInFileWorkerPath": "/assets-cdn/worker/find-in-file-worker-03b87d52cf57.js",
"githubDevUrl": null,
"enabled_features": {
"code_nav_ui_events": false,
"overview_shared_code_dropdown_button": false,
"react_blob_overlay": false,
"copilot_conversational_ux_embedding_update": false,
"copilot_smell_icebreaker_ux": true,
"copilot_workspace": false,
"accessible_code_button": true
}
}
}
}
{
"accept-ranges": "bytes",
"cache-control": "max-age=0, private, must-revalidate",
"content-encoding": "gzip",
"content-security-policy": "default-src 'none'; base-uri 'self'; child-src github.com/assets-cdn/worker/ github.com/webpack/ github.com/assets/ gist.github.com/assets-cdn/worker/; connect-src 'self' uploads.github.com www.githubstatus.com collector.github.com raw.githubusercontent.com api.github.com github-cloud.s3.amazonaws.com github-production-repository-file-5c1aeb.s3.amazonaws.com github-production-upload-manifest-file-7fdce7.s3.amazonaws.com github-production-user-asset-6210df.s3.amazonaws.com *.rel.tunnels.api.visualstudio.com wss://*.rel.tunnels.api.visualstudio.com objects-origin.githubusercontent.com copilot-proxy.githubusercontent.com proxy.individual.githubcopilot.com proxy.business.githubcopilot.com proxy.enterprise.githubcopilot.com *.actions.githubusercontent.com wss://*.actions.githubusercontent.com productionresultssa0.blob.core.windows.net/ productionresultssa1.blob.core.windows.net/ productionresultssa2.blob.core.windows.net/ productionresultssa3.blob.core.windows.net/ productionresultssa4.blob.core.windows.net/ productionresultssa5.blob.core.windows.net/ productionresultssa6.blob.core.windows.net/ productionresultssa7.blob.core.windows.net/ productionresultssa8.blob.core.windows.net/ productionresultssa9.blob.core.windows.net/ productionresultssa10.blob.core.windows.net/ productionresultssa11.blob.core.windows.net/ productionresultssa12.blob.core.windows.net/ productionresultssa13.blob.core.windows.net/ productionresultssa14.blob.core.windows.net/ productionresultssa15.blob.core.windows.net/ productionresultssa16.blob.core.windows.net/ productionresultssa17.blob.core.windows.net/ productionresultssa18.blob.core.windows.net/ productionresultssa19.blob.core.windows.net/ github-production-repository-image-32fea6.s3.amazonaws.com github-production-release-asset-2e65be.s3.amazonaws.com insights.github.com wss://alive.github.com api.githubcopilot.com api.individual.githubcopilot.com api.business.githubcopilot.com api.enterprise.githubcopilot.com; font-src github.githubassets.com; form-action 'self' github.com gist.github.com copilot-workspace.githubnext.com objects-origin.githubusercontent.com; frame-ancestors 'none'; frame-src viewscreen.githubusercontent.com notebooks.githubusercontent.com; img-src 'self' data: blob: github.githubassets.com media.githubusercontent.com camo.githubusercontent.com identicons.github.com avatars.githubusercontent.com private-avatars.githubusercontent.com github-cloud.s3.amazonaws.com objects.githubusercontent.com secured-user-images.githubusercontent.com/ user-images.githubusercontent.com/ private-user-images.githubusercontent.com opengraph.githubassets.com github-production-user-asset-6210df.s3.amazonaws.com customer-stories-feed.github.com spotlights-feed.github.com objects-origin.githubusercontent.com *.githubusercontent.com; manifest-src 'self'; media-src github.com user-images.githubusercontent.com/ secured-user-images.githubusercontent.com/ private-user-images.githubusercontent.com github-production-user-asset-6210df.s3.amazonaws.com gist.github.com; script-src github.githubassets.com; style-src 'unsafe-inline' github.githubassets.com; upgrade-insecure-requests; worker-src github.com/assets-cdn/worker/ github.com/webpack/ github.com/assets/ gist.github.com/assets-cdn/worker/",
"content-type": "text/html; charset=utf-8",
"date": "Sat, 05 Oct 2024 03:30:23 GMT",
"etag": "a791672e04dc305fc857106aab9d9aca",
"referrer-policy": "no-referrer-when-downgrade",
"server": "GitHub.com",
"set-cookie": "logged_in=no; Path=/; Domain=github.com; Expires=Sun, 05 Oct 2025 03:30:22 GMT; HttpOnly; Secure; SameSite=Lax",
"strict-transport-security": "max-age=31536000; includeSubdomains; preload",
"transfer-encoding": "chunked",
"vary": "X-PJAX, X-PJAX-Container, Turbo-Visit, Turbo-Frame, Accept-Encoding, Accept, X-Requested-With",
"x-content-type-options": "nosniff",
"x-frame-options": "deny",
"x-github-request-id": "CD66:3B460B:4CD939F:694DC76:6700B2CE",
"x-xss-protection": "0"
}