or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

conversion-utilities.mddata-models.mdeditor-components.mdentity-system.mdindex.mdkey-bindings-utilities.mdtext-modification.md
tile.json

editor-components.mddocs/

Editor Components

Core React components for rendering the rich text editor interface and individual content blocks.

Capabilities

DraftEditor (exported as Editor)

The main React component that renders the rich text editor interface. It manages user interactions, keyboard events, and renders the content blocks.

/**
 * Main Draft.js editor component
 * @param props - Editor configuration and event handlers
 */
const Editor: React.ComponentType<{
  // Core props
  editorState: EditorState,
  onChange: (editorState: EditorState) => void,
  
  // Display props
  placeholder?: string,
  readOnly?: boolean,
  tabIndex?: number,
  
  // Styling props
  customStyleMap?: {[styleName: string]: React.CSSProperties},
  blockRenderMap?: DraftBlockRenderMap,
  blockRendererFn?: (block: ContentBlock) => ?{
    component: React.ComponentType<any>,
    props?: {[key: string]: any},
    editable?: boolean
  },
  blockStyleFn?: (block: ContentBlock) => string,
  
  // Event handling
  keyBindingFn?: (e: SyntheticKeyboardEvent) => ?string,
  handleKeyCommand?: (command: string, editorState: EditorState, eventTimeStamp: number) => DraftHandleValue,
  handleBeforeInput?: (chars: string, editorState: EditorState, eventTimeStamp: number) => DraftHandleValue,
  handlePastedText?: (text: string, html?: string, editorState: EditorState) => DraftHandleValue,
  handlePastedFiles?: (files: Array<Blob>) => DraftHandleValue,
  handleDroppedFiles?: (selection: SelectionState, files: Array<Blob>) => DraftHandleValue,
  handleDrop?: (selection: SelectionState, dataTransfer: Object, isInternal: DraftDragType) => DraftHandleValue,
  handleReturn?: (e: SyntheticKeyboardEvent, editorState: EditorState) => DraftHandleValue,
  
  // Focus/blur events
  onEscape?: (e: SyntheticKeyboardEvent) => void,
  onTab?: (e: SyntheticKeyboardEvent) => void,
  onUpArrow?: (e: SyntheticKeyboardEvent) => void,
  onRightArrow?: (e: SyntheticKeyboardEvent) => void,
  onDownArrow?: (e: SyntheticKeyboardEvent) => void,
  onLeftArrow?: (e: SyntheticKeyboardEvent) => void,
  onBlur?: (e: SyntheticEvent) => void,
  onFocus?: (e: SyntheticEvent) => void,
  
  // Clipboard events
  onCut?: (e: SyntheticClipboardEvent) => void,
  onCopy?: (e: SyntheticClipboardEvent) => void,
  onSelect?: (e: SyntheticEvent) => void,
  
  // Accessibility
  ariaActiveDescendantID?: string,
  ariaAutoComplete?: string,
  ariaControls?: string,
  ariaDescribedBy?: string,
  ariaExpanded?: boolean,
  ariaLabel?: string,
  ariaLabelledBy?: string,
  ariaMultiline?: boolean,
  role?: string,
  
  // Advanced
  spellCheck?: boolean,
  stripPastedStyles?: boolean,
  autoCapitalize?: string,
  autoComplete?: string,
  autoCorrect?: string,
  textAlignment?: DraftTextAlignment,
  textDirectionality?: DraftTextDirectionality,
  webDriverTestID?: string
}>;

Usage Examples:

import React, { useState } from "react";
import { Editor, EditorState, RichUtils } from "draft-js";

// Basic editor setup
function BasicEditor() {
  const [editorState, setEditorState] = useState(EditorState.createEmpty());

  return (
    <Editor
      editorState={editorState}
      onChange={setEditorState}
      placeholder="Enter some text..."
    />
  );
}

// Editor with key command handling
function RichEditor() {
  const [editorState, setEditorState] = useState(EditorState.createEmpty());

  const handleKeyCommand = (command, editorState) => {
    const newState = RichUtils.handleKeyCommand(editorState, command);
    if (newState) {
      setEditorState(newState);
      return "handled";
    }
    return "not-handled";
  };

  const handleBeforeInput = (chars, editorState) => {
    // Custom input handling
    return "not-handled";
  };

  return (
    <Editor
      editorState={editorState}
      onChange={setEditorState}
      handleKeyCommand={handleKeyCommand}
      handleBeforeInput={handleBeforeInput}
      placeholder="Start typing..."
      spellCheck={true}
    />
  );
}

// Editor with custom styling
function StyledEditor() {
  const [editorState, setEditorState] = useState(EditorState.createEmpty());

  const customStyleMap = {
    'HIGHLIGHT': {
      backgroundColor: 'yellow',
    },
    'STRIKETHROUGH': {
      textDecoration: 'line-through',
    },
  };

  const blockStyleFn = (contentBlock) => {
    const type = contentBlock.getType();
    if (type === 'blockquote') {
      return 'superFancyBlockquote';
    }
  };

  return (
    <Editor
      editorState={editorState}
      onChange={setEditorState}
      customStyleMap={customStyleMap}
      blockStyleFn={blockStyleFn}
    />
  );
}

DraftEditorBlock (exported as EditorBlock)

Component responsible for rendering individual content blocks within the editor. Usually used internally by DraftEditor, but can be customized through blockRendererFn.

/**
 * Component for rendering individual content blocks
 * Used internally by DraftEditor, customizable via blockRendererFn prop
 */
const EditorBlock: React.ComponentType<{
  block: ContentBlock,
  blockProps?: any,
  blockStyleFn: (block: ContentBlock) => string,
  contentState: ContentState,
  customStyleMap: {[key: string]: React.CSSProperties},
  decorator: ?DraftDecoratorType,
  direction: DraftTextDirectionality,
  forceSelection: boolean,
  offsetKey: string,
  selection: SelectionState,
  tree: List<any>
}>;

Usage Example with Custom Block Renderer:

import React, { useState } from "react";
import { Editor, EditorState } from "draft-js";

// Custom block component
function ImageBlock(props) {
  const entity = props.contentState.getEntity(props.block.getEntityAt(0));
  const { src, alt } = entity.getData();
  
  return (
    <div>
      <img src={src} alt={alt} style={{ maxWidth: '100%' }} />
    </div>
  );
}

function EditorWithCustomBlocks() {
  const [editorState, setEditorState] = useState(EditorState.createEmpty());

  const blockRendererFn = (contentBlock) => {
    const type = contentBlock.getType();
    
    if (type === 'atomic') {
      return {
        component: ImageBlock,
        editable: false,
      };
    }
    
    return null;
  };

  return (
    <Editor
      editorState={editorState}
      onChange={setEditorState}
      blockRendererFn={blockRendererFn}
    />
  );
}

Types

Component-Related Types

// Handle values for event handlers
type DraftHandleValue = 'handled' | 'not-handled';

// Drag types
type DraftDragType = 'internal' | 'external';

// Text alignment
type DraftTextAlignment = 'left' | 'center' | 'right';

// Text directionality
type DraftTextDirectionality = 'LTR' | 'RTL' | 'NEUTRAL';

// Block render configuration
interface DraftBlockRenderConfig {
  element: string;
  wrapper?: React.ComponentType<any>;
  aliasedElements?: Array<string>;
}

// Block render map
type DraftBlockRenderMap = Immutable.Map<DraftBlockType, DraftBlockRenderConfig>;

// Style map for inline styles
type DraftStyleMap = {[styleName: string]: React.CSSProperties};

// Block renderer function return type
interface BlockRendererResult {
  component: React.ComponentType<any>;
  props?: {[key: string]: any};
  editable?: boolean;
}