Overview
The formatOutdent inputType is triggered when the user decreases indentation of selected paragraphs (typically via Shift + Tab or toolbar button). The browser decreases the left margin or padding of the affected elements.
Basic Behavior
Scenario: Indented paragraph selected
Before (Indented paragraph selected)
HTML:
<p style="margin-left: 40px;">This is an indented paragraph.</p>
After formatOutdent
HTML:
<p>This is an indented paragraph.</p>
Left margin decreased (outdented)
Difference from formatIndent
formatOutdent (Shift + Tab)
- Decreases indentation (moves left)
- Cannot go below 0 indent
formatIndent (Tab)
- Increases indentation (moves right)
- Can increase indefinitely
Editor-Specific Handling
Different editor frameworks handle outdentation similarly to indentation. Here's how major editors implement formatOutdent:
Slate.js
Outdentation
Slate decreases indent level:
import { Editor, Transforms, Element } from 'slate';
element.addEventListener('beforeinput', (e) => {
if (e.inputType === 'formatOutdent') {
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;
// Decrease indent (minimum 0)
Transforms.setNodes(editor, {
indent: Math.max(0, currentIndent - 1),
}, {
match: n => Element.isElement(n) && Editor.isBlock(editor, n),
});
}
});
- Decremental: Decreases indent level by 1, minimum 0.
- Same pattern: Uses same Transforms API as formatIndent.
ProseMirror
Outdentation
ProseMirror decreases indent attribute:
view.dom.addEventListener('beforeinput', (e) => {
if (e.inputType === 'formatOutdent') {
e.preventDefault();
const { state, dispatch } = view;
const { $from } = state.selection;
// Get current indent
const currentIndent = $from.node(-1)?.attrs.indent || 0;
// Decrease indent (minimum 0)
const tr = state.tr.setNodeMarkup($from.before(-1), null, {
...$from.node(-1).attrs,
indent: Math.max(0, currentIndent - 1),
});
dispatch(tr);
}
});
- Minimum check: Ensures indent does not go below 0.
Draft.js
Outdentation
Draft.js handles Shift+Tab:
import { EditorState, RichUtils } from 'draft-js';
function handleOutdent(editorState) {
// Draft.js may use block-level styles or custom block types for outdentation
return RichUtils.onTab({ preventDefault: () => {}, shiftKey: true }, editorState, 4);
}
element.addEventListener('beforeinput', (e) => {
if (e.inputType === 'formatOutdent') {
e.preventDefault();
const newState = handleOutdent(editorState);
setEditorState(newState);
}
});
- Shift+Tab: Uses
RichUtils.onTab()with shiftKey flag.