formatIndent

How formatIndent inputType applies indentation to paragraphs and varies across browsers.

Overview

The formatIndent inputType is triggered when the user increases indentation of selected paragraphs (typically via Tab or toolbar button). The browser increases the left margin or padding of the affected elements.

Basic Behavior

Scenario: Paragraph selected

Before (Paragraph selected)

HTML:
<p>This is a paragraph.</p>

After formatIndent

HTML:
<p style="margin-left: 40px;">This is a paragraph.</p>
Left margin increased (indented)

Browser-Specific Behavior

Chrome/Edge

  • Applies margin-left or padding-left via inline style
  • Increment amount varies (typically 40px)

Firefox

  • Similar behavior to Chrome
  • May use different increment values

Safari

  • Indentation behavior may differ
  • May use different CSS properties

Editor-Specific Handling

Different editor frameworks handle indentation differently. Here's how major editors implement formatIndent:

Slate.js

Indentation

Slate applies indentation as a block property:

    import { Editor, Transforms, Element } from 'slate';

element.addEventListener('beforeinput', (e) => {
  if (e.inputType === 'formatIndent') {
    e.preventDefault();
    
    // Get current indent level
    const [match] = Editor.nodes(editor, {
      match: n => Element.isElement(n) && Editor.isBlock(editor, n),
    });
    
    const currentIndent = match?.[0]?.indent || 0;
    
    // Increase indent
    Transforms.setNodes(editor, {
      indent: currentIndent + 1,
    }, {
      match: n => Element.isElement(n) && Editor.isBlock(editor, n),
    });
  }
});
  
  • Block property: Indentation is stored as a property on block elements.
  • Incremental: Increases indent level by 1 each time.
ProseMirror

Indentation

ProseMirror uses block attribute:

    view.dom.addEventListener('beforeinput', (e) => {
  if (e.inputType === 'formatIndent') {
    e.preventDefault();
    const { state, dispatch } = view;
    const { $from } = state.selection;
    
    // Get current indent
    const currentIndent = $from.node(-1)?.attrs.indent || 0;
    
    // Increase indent
    const tr = state.tr.setNodeMarkup($from.before(-1), null, {
      ...$from.node(-1).attrs,
      indent: currentIndent + 1,
    });
    
    dispatch(tr);
  }
});
  
  • Block attribute: Indentation is stored as an attribute on block nodes.
Draft.js

Indentation

Draft.js uses block-level styles:

    import { EditorState, RichUtils } from 'draft-js';

function handleIndent(editorState) {
  // Draft.js may use block-level styles or custom block types for indentation
  return RichUtils.onTab({ preventDefault: () => {} }, editorState, 4);
}

element.addEventListener('beforeinput', (e) => {
  if (e.inputType === 'formatIndent') {
    e.preventDefault();
    const newState = handleIndent(editorState);
    setEditorState(newState);
  }
});
  
  • Tab handling: Uses RichUtils.onTab() for indentation.

Related resources