### Install Project Dependencies Source: https://github.com/springload/draftail/blob/main/docs/CONTRIBUTING.md Commands to set up the local development environment by installing the required Node version and project dependencies. ```bash nvm install npm install touch .env ``` -------------------------------- ### Development Workflow Commands Source: https://github.com/springload/draftail/blob/main/docs/CONTRIBUTING.md Standard commands for managing the development lifecycle, including starting the server, linting, formatting, and running tests. ```bash nvm use npm run start npm run lint npm run format npm run test:watch npm run test:coverage npm run report:coverage npm run report:build npm run report:size npm run report:package npm run ``` -------------------------------- ### Update Toolbar Control Descriptions in Draftail Source: https://github.com/springload/draftail/blob/main/CHANGELOG.md This example shows how to update Draftail controls to leverage the new 'description' prop for enhanced tooltips, improving accessibility and user experience. It demonstrates adding descriptions to 'Header 3' and 'Bulleted list' controls. ```diff blockTypes={[ { type: BLOCK_TYPE.HEADER_THREE, label: 'H3', // Use a description to further convey what the control does. + description: 'Heading 3', }, { type: BLOCK_TYPE.UNORDERED_LIST_ITEM, // The icon is enough – but use the new prop to help screen reader users. - label: 'UL', + description: 'Bulleted list', icon: 'icon-list-ul', }, ]} ``` -------------------------------- ### Controlled Draftail Editor with State Management Source: https://context7.com/springload/draftail/llms.txt Illustrates using Draftail as a controlled component, managing the editor's state externally with React's useState hook. This example includes a word count display that updates in real-time as the user types. ```tsx import React, { useState } from "react"; import { EditorState, RawDraftContentState } from "draft-js"; import { DraftailEditor, BLOCK_TYPE, INLINE_STYLE, createEditorStateFromRaw, serialiseEditorStateToRaw, } from "draftail"; const ControlledEditor = () => { const [editorState, setEditorState] = useState(() => createEditorStateFromRaw({ blocks: [{ key: "a", text: "Start typing...", type: "unstyled" }], entityMap: {}, }) ); const handleChange = (newState: EditorState) => { setEditorState(newState); // Get raw content for serialization const rawContent = serialiseEditorStateToRaw(newState); console.log("Current content:", rawContent); }; const getWordCount = () => { const content = editorState.getCurrentContent(); const text = content.getPlainText(); return text.trim().split(/\s+/).filter(Boolean).length; }; return (

Word count: {getWordCount()}

); }; ``` -------------------------------- ### Perform Editor Operations with DraftUtils Source: https://context7.com/springload/draftail/llms.txt Provides examples of using the DraftUtils API to manipulate blocks, entities, and selections within the Draft.js editor state. These utilities simplify tasks like resetting block types, updating entity data, and managing newline behavior. ```tsx import { EditorState, Modifier, RichUtils } from "draft-js"; import { DraftUtils, BLOCK_TYPE, ENTITY_TYPE } from "draftail"; const editorState = /* your editor state */; const selectedBlock = DraftUtils.getSelectedBlock(editorState); const entityKey = DraftUtils.getSelectionEntity(editorState); const entitySelection = DraftUtils.getEntitySelection(editorState, entityKey); const newState = DraftUtils.resetBlockWithType(editorState, BLOCK_TYPE.HEADER_TWO, "New heading text"); const updatedState = DraftUtils.updateBlockEntity(editorState, blockWithEntity, { src: "new-image.jpg", alt: "Updated alt text" }); const stateWithHR = DraftUtils.addHorizontalRuleRemovingSelection(editorState); const stateWithBR = DraftUtils.addLineBreak(editorState); const stateWithoutBlock = DraftUtils.removeBlock(editorState, blockKey); const stateWithoutEntity = DraftUtils.removeBlockEntity(editorState, entityKey, blockKey); const newLineState = DraftUtils.handleNewLine(editorState, keyboardEvent); const linkStrategy = DraftUtils.getEntityTypeStrategy(ENTITY_TYPE.LINK); ``` -------------------------------- ### Project Release and Distribution Source: https://github.com/springload/draftail/blob/main/docs/CONTRIBUTING.md Commands used to build the distribution files, verify package size, and publish the package to the registry. ```bash npm run dist npm run report:size npm run report:package npm publish ``` -------------------------------- ### Integrate draft-js-plugins with Draftail Source: https://context7.com/springload/draftail/llms.txt Demonstrates how to initialize plugins like hashtag, linkify, and emoji, and pass them to the DraftailEditor component. This enables advanced text features and requires importing corresponding CSS files. ```tsx import React from "react"; import { DraftailEditor, BLOCK_TYPE, INLINE_STYLE } from "draftail"; import createHashtagPlugin from "draft-js-hashtag-plugin"; import createLinkifyPlugin from "draft-js-linkify-plugin"; import createEmojiPlugin from "draft-js-emoji-plugin"; import "draft-js-hashtag-plugin/lib/plugin.css"; import "draft-js-linkify-plugin/lib/plugin.css"; import "draft-js-emoji-plugin/lib/plugin.css"; const hashtagPlugin = createHashtagPlugin(); const linkifyPlugin = createLinkifyPlugin({ target: "_blank", rel: "noopener noreferrer", }); const emojiPlugin = createEmojiPlugin(); const { EmojiSuggestions, EmojiSelect } = emojiPlugin; const EditorWithPlugins = () => (
); ``` -------------------------------- ### Configure Draftail Command Palette Source: https://context7.com/springload/draftail/llms.txt Demonstrates how to enable and customize the slash-command palette in the DraftailEditor component. It includes configuration for block types, entity types, and custom actions like clearing content or inserting dynamic data. ```tsx import React from "react"; import { DraftailEditor, DraftUtils, BLOCK_TYPE, ENTITY_TYPE } from "draftail"; const EditorWithCommandPalette = () => ( EditorState.createEmpty(), }, { type: "insert-date", description: "Insert current date", onSelect: ({ editorState }) => { const date = new Date().toLocaleDateString(); const block = DraftUtils.getSelectedBlock(editorState); return DraftUtils.resetBlockWithType(editorState, block.getType(), date); }, }, ], }, ]} /> ); ``` -------------------------------- ### Draftail: Customize Toolbar with Custom Controls Source: https://context7.com/springload/draftail/llms.txt Illustrates how to customize Draftail's toolbar by adding custom controls like a word counter and a 'clear formatting' button. It shows how to integrate these controls into different toolbar types (inline, block, meta) and configure custom toolbar layouts. ```tsx import React from "react"; import { DraftailEditor, Toolbar, FloatingToolbar, BlockToolbar, MetaToolbar, InlineToolbar, ToolbarButton, BLOCK_TYPE, INLINE_STYLE, } from "draftail"; // Custom word count control for meta toolbar const WordCount = ({ getEditorState }) => { const editorState = getEditorState(); const content = editorState.getCurrentContent(); const text = content.getPlainText(); const words = text.trim().split(/\s+/).filter(Boolean).length; const chars = text.length; return ( {words} words | {chars} characters ); }; // Custom formatting control const CustomControl = ({ getEditorState, onChange }) => { const clearFormatting = () => { const editorState = getEditorState(); // Clear all inline styles from selection let newState = editorState; const styles = ["BOLD", "ITALIC", "UNDERLINE", "STRIKETHROUGH", "CODE"]; styles.forEach((style) => { const currentStyle = newState.getCurrentInlineStyle(); if (currentStyle.has(style)) { newState = RichUtils.toggleInlineStyle(newState, style); } }); onChange(newState); }; return ( ); }; // Editor with custom toolbar configuration const EditorWithCustomToolbars = () => ( ( <> )} bottomToolbar={MetaToolbar} enableHorizontalRule /> ); // Editor with floating toolbar only const MinimalEditor = () => ( ); ``` -------------------------------- ### Set Location with JavaScript Source: https://github.com/springload/draftail/blob/main/public/index.html This snippet demonstrates how to set the current location using JavaScript. It's a simple assignment that can be used to redirect the user or update the browser's URL. ```javascript location = "https://www.draftail.org/"; ``` -------------------------------- ### Implement Block-Level Image Entities in Draftail Source: https://context7.com/springload/draftail/llms.txt This snippet demonstrates how to create a custom ImageSource component for selecting files and an ImageBlock component for rendering and editing images within the editor. It uses Draftail's entity system to manage atomic blocks. ```tsx import React, { Component } from "react"; import { DraftailEditor, DraftUtils, ENTITY_TYPE } from "draftail"; class ImageSource extends Component { onSelectImage = (e) => { const { editorState, entityType, onComplete } = this.props; const file = e.target.files[0]; if (!file) { this.props.onClose(); return; } const reader = new FileReader(); reader.onload = (event) => { const content = editorState.getCurrentContent(); const contentWithEntity = content.createEntity( entityType.type, "IMMUTABLE", { src: event.target.result, alt: file.name } ); const entityKey = contentWithEntity.getLastCreatedEntityKey(); const nextState = AtomicBlockUtils.insertAtomicBlock( EditorState.set(editorState, { currentContent: contentWithEntity }), entityKey, " " ); onComplete(nextState); }; reader.readAsDataURL(file); }; render() { return (
); } } class ImageBlock extends Component { changeAlt = (e) => { const { block, blockProps } = this.props; const { editorState, onChange } = blockProps; const data = { alt: e.target.value }; onChange(DraftUtils.updateBlockEntity(editorState, block, data)); }; render() { const { blockProps } = this.props; const { entity, onEditEntity, onRemoveEntity, lockEditor, unlockEditor } = blockProps; const { src, alt } = entity.getData(); return (
{alt
); } } ``` -------------------------------- ### Draftail: Define Custom Block Types Source: https://context7.com/springload/draftail/llms.txt Demonstrates how to add custom block types to Draftail, such as 'tiny-text', 'callout', and 'lead' paragraphs, by specifying their type, label, description, and corresponding HTML element. ```tsx import React from "react"; import { DraftailEditor, BLOCK_TYPE } from "draftail"; const EditorWithCustomBlocks = () => ( ); ``` -------------------------------- ### Draftail Constants and Types Definition (TypeScript) Source: https://context7.com/springload/draftail/llms.txt This snippet demonstrates the import and usage of Draftail's predefined constants for block types, inline styles, and entity types. It also shows how to define custom block, inline style, and entity types for extended editor functionality. ```typescript import { BLOCK_TYPE, INLINE_STYLE, ENTITY_TYPE, BlockType, InlineStyle, EntityType, BlockTypeControl, InlineStyleControl, EntityTypeControl, EntitySourceProps, EntityDecoratorProps, EntityBlockProps, ControlComponentProps, } from "draftail"; // Block types available const blockTypes: BlockType[] = [ BLOCK_TYPE.UNSTYLED, // "unstyled" - paragraph BLOCK_TYPE.HEADER_ONE, // "header-one" BLOCK_TYPE.HEADER_TWO, // "header-two" BLOCK_TYPE.HEADER_THREE, // "header-three" BLOCK_TYPE.HEADER_FOUR, // "header-four" BLOCK_TYPE.HEADER_FIVE, // "header-five" BLOCK_TYPE.HEADER_SIX, // "header-six" BLOCK_TYPE.UNORDERED_LIST_ITEM, // "unordered-list-item" BLOCK_TYPE.ORDERED_LIST_ITEM, // "ordered-list-item" BLOCK_TYPE.BLOCKQUOTE, // "blockquote" BLOCK_TYPE.CODE, // "code-block" BLOCK_TYPE.ATOMIC, // "atomic" - for entities ]; // Inline styles available const inlineStyles: InlineStyle[] = [ INLINE_STYLE.BOLD, // "BOLD" INLINE_STYLE.ITALIC, // "ITALIC" INLINE_STYLE.CODE, // "CODE" INLINE_STYLE.UNDERLINE, // "UNDERLINE" INLINE_STYLE.STRIKETHROUGH, // "STRIKETHROUGH" INLINE_STYLE.MARK, // "MARK" INLINE_STYLE.SMALL, // "SMALL" INLINE_STYLE.SUPERSCRIPT, // "SUPERSCRIPT" INLINE_STYLE.SUBSCRIPT, // "SUBSCRIPT" INLINE_STYLE.KEYBOARD, // "KEYBOARD" ]; // Built-in entity types const entityTypes: EntityType[] = [ ENTITY_TYPE.LINK, // "LINK" ENTITY_TYPE.IMAGE, // "IMAGE" ENTITY_TYPE.HORIZONTAL_RULE, // "HORIZONTAL_RULE" ]; // Type definitions for custom implementations const myBlockType: BlockTypeControl = { type: "custom-block", label: "CB", description: "Custom block", icon: "#icon-custom", element: "div", }; const myInlineStyle: InlineStyleControl = { type: "CUSTOM_STYLE", label: "CS", description: "Custom style", style: { color: "red" }, }; const myEntityType: EntityTypeControl = { type: "CUSTOM_ENTITY", description: "Custom entity", source: MySourceComponent, // Assuming MySourceComponent is defined elsewhere decorator: MyDecoratorComponent, // Assuming MyDecoratorComponent is defined elsewhere attributes: ["data1", "data2"], }; ``` -------------------------------- ### Implement Link Entity with Source and Decorator in Draftail Source: https://context7.com/springload/draftail/llms.txt This snippet provides a complete implementation of a link entity in Draftail. It includes a LinkSource component for modal-based URL input and a Link decorator component for rendering interactive links within the editor. ```tsx import React, { Component } from "react"; import { EditorState, Modifier, RichUtils } from "draft-js"; import { DraftailEditor, ENTITY_TYPE } from "draftail"; class LinkSource extends Component { constructor(props) { super(props); const { entity } = props; this.state = { url: entity ? entity.getData().url : "" }; } onConfirm = (e) => { e.preventDefault(); const { editorState, entityType, onComplete } = this.props; const { url } = this.state; const content = editorState.getCurrentContent(); const contentWithEntity = content.createEntity(entityType.type, "MUTABLE", { url: url.trim() }); const entityKey = contentWithEntity.getLastCreatedEntityKey(); const selection = editorState.getSelection(); let nextState; if (selection.isCollapsed()) { const newContent = Modifier.insertText(contentWithEntity, selection, url, undefined, entityKey); nextState = EditorState.push(editorState, newContent, "insert-characters"); } else { nextState = RichUtils.toggleLink(editorState, selection, entityKey); } onComplete(nextState); }; render() { const { onClose } = this.props; return (
this.setState({ url: e.target.value })} placeholder="https://example.com" autoFocus />
); } } const Link = ({ entityKey, contentState, children, onEdit, onRemove }) => { const { url } = contentState.getEntity(entityKey).getData(); return ( { if (e.altKey) { window.open(url, "_blank"); } }}> {children} ); }; const EditorWithLinks = () => ( ); ``` -------------------------------- ### Custom Block Types Source: https://context7.com/springload/draftail/llms.txt This section demonstrates how to define and use custom block types in Draftail, allowing for specialized content rendering and behavior. ```APIDOC ## Custom Block Types Custom block types enable specialized content blocks with unique rendering and behavior. Each block type can specify a DOM element and custom styling. ### Example Usage ```tsx import React from "react"; import { DraftailEditor, BLOCK_TYPE } from "draftail"; const EditorWithCustomBlocks = () => ( ); ``` ### Block Type Configuration - **type** (string) - Required - Unique identifier for the block type. - **label** (string) - Optional - Text label for the block type in the UI. - **description** (string) - Optional - Description of the block type. - **element** (string) - Optional - The DOM element to render for this block type (e.g., 'p', 'div', 'aside'). - **icon** (string) - Optional - Icon identifier for the block type. ``` -------------------------------- ### Serialize and Deserialize Draftail Editor Content Source: https://context7.com/springload/draftail/llms.txt Shows how to convert between Draft.js EditorState and raw JSON using draftjs-conductor utilities. This is essential for saving editor content to a backend API and re-hydrating it for editing. ```tsx import { DraftailEditor, createEditorStateFromRaw, serialiseEditorStateToRaw } from "draftail"; const rawContent = { blocks: [ { key: "abc123", type: "header-two", text: "Welcome to the Editor", depth: 0, inlineStyleRanges: [], entityRanges: [], data: {} }, { key: "def456", type: "unstyled", text: "This is bold text with a link.", depth: 0, inlineStyleRanges: [{ offset: 8, length: 4, style: "BOLD" }], entityRanges: [{ offset: 23, length: 4, key: 0 }], data: {} }, ], entityMap: { "0": { type: "LINK", mutability: "MUTABLE", data: { url: "https://example.com" } } }, }; const editorState = createEditorStateFromRaw(rawContent); const savedContent = serialiseEditorStateToRaw(editorState); const saveToServer = async (content) => { await fetch("/api/content", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ content }), }); }; const loadFromServer = async () => { const response = await fetch("/api/content"); const { content } = await response.json(); return createEditorStateFromRaw(content); }; ``` -------------------------------- ### Uncontrolled Draftail Editor with Auto-Save Source: https://context7.com/springload/draftail/llms.txt Demonstrates an uncontrolled Draftail editor instance that automatically saves content to local storage at a specified interval. It configures various block types, inline styles, and editor features like undo/redo controls and spell check. ```tsx import React from "react"; import { DraftailEditor, BLOCK_TYPE, INLINE_STYLE, ENTITY_TYPE, } from "draftail"; import "draftail/dist/draftail.css"; // Uncontrolled editor with auto-save const SimpleEditor = () => { const initialContent = { blocks: [ { key: "abc123", text: "Hello, world!", type: "unstyled", depth: 0, inlineStyleRanges: [], entityRanges: [], }, ], entityMap: {}, }; const handleSave = (content) => { console.log("Content saved:", content); localStorage.setItem("editor-content", JSON.stringify(content)); }; return ( ); }; ``` -------------------------------- ### Toolbar Customization Source: https://context7.com/springload/draftail/llms.txt This section covers customizing the Draftail editor's toolbar, including adding custom controls and configuring toolbar layouts. ```APIDOC ## Toolbar Customization Draftail provides multiple toolbar components that can be combined or replaced: Toolbar (static), FloatingToolbar (selection-based), BlockToolbar, and MetaToolbar. Custom controls can be added to any toolbar position. ### Custom Controls Custom controls can be created as React components that receive `getEditorState` and `onChange` props. #### Word Count Control Example ```tsx // Custom word count control for meta toolbar const WordCount = ({ getEditorState }) => { const editorState = getEditorState(); const content = editorState.getCurrentContent(); const text = content.getPlainText(); const words = text.trim().split(/\s+/).filter(Boolean).length; const chars = text.length; return ( {words} words | {chars} characters ); }; ``` #### Clear Formatting Control Example ```tsx import { RichUtils } from "draft-js"; // Custom formatting control const CustomControl = ({ getEditorState, onChange }) => { const clearFormatting = () => { const editorState = getEditorState(); // Clear all inline styles from selection let newState = editorState; const styles = ["BOLD", "ITALIC", "UNDERLINE", "STRIKETHROUGH", "CODE"]; styles.forEach((style) => { const currentStyle = newState.getCurrentInlineStyle(); if (currentStyle.has(style)) { newState = RichUtils.toggleInlineStyle(newState, style); } }); onChange(newState); }; return ( ); }; ``` ### Toolbar Configuration - **controls** (Array) - An array of control objects, each specifying the type of toolbar (`inline`, `block`, `meta`) and the component to use. - **topToolbar** (Component) - A React component to render the top toolbar. Can be a built-in component or a custom one. - **bottomToolbar** (Component) - A React component to render the bottom toolbar. #### Example: Editor with Custom Toolbars ```tsx import React from "react"; import { DraftailEditor, Toolbar, FloatingToolbar, BlockToolbar, MetaToolbar, InlineToolbar, ToolbarButton, BLOCK_TYPE, INLINE_STYLE, } from "draftail"; // Assuming WordCount and CustomControl are defined as above const EditorWithCustomToolbars = () => ( ( <> )} bottomToolbar={MetaToolbar} enableHorizontalRule /> ); ``` #### Example: Editor with Floating Toolbar Only ```tsx // Assuming DraftailEditor, FloatingToolbar, BLOCK_TYPE, INLINE_STYLE are imported const MinimalEditor = () => ( ); ``` ``` -------------------------------- ### Define Custom Inline Styles in Draftail Source: https://context7.com/springload/draftail/llms.txt This snippet shows how to configure the DraftailEditor with custom inline styles, including CSS-based highlights, redaction effects, and custom font families. ```tsx import React from "react"; import { DraftailEditor, INLINE_STYLE } from "draftail"; const EditorWithCustomStyles = () => ( ); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.