Comprehensive wrapper around ProseMirror packages providing unified entry point for rich text editing functionality in Tiptap framework
—
Input rules provide automatic text transformations based on typing patterns, while keymaps bind keyboard commands to editor actions. Together they create responsive editing experiences.
Input rules automatically transform text as users type, providing shortcuts and typography improvements.
/**
* An input rule transforms text based on pattern matching
*/
class InputRule {
/**
* Create a new input rule
*/
constructor(
match: RegExp,
handler: string | ((state: EditorState, match: string[], start: number, end: number) => Transaction | null),
options?: { undoable?: boolean }
);
}Create and manage input rule plugins.
/**
* Create an input rules plugin
*/
function inputRules(config: { rules: InputRule[] }): Plugin;
/**
* Undo the last input rule transformation
*/
function undoInputRule(state: EditorState, dispatch?: (tr: Transaction) => void): boolean;Convenient functions for common input rule patterns.
/**
* Create an input rule that wraps matched text in a node
*/
function wrappingInputRule(
regexp: RegExp,
nodeType: NodeType,
getAttrs?: Attrs | ((match: string[]) => Attrs | null),
joinPredicate?: (match: string[], node: Node) => boolean
): InputRule;
/**
* Create an input rule that changes text block type
*/
function textblockTypeInputRule(
regexp: RegExp,
nodeType: NodeType,
getAttrs?: Attrs | ((match: string[]) => Attrs | null)
): InputRule;Pre-defined input rules for common typography transformations.
/**
* Convert -- to em dash
*/
const emDash: InputRule;
/**
* Convert ... to ellipsis character
*/
const ellipsis: InputRule;
/**
* Convert opening quotes
*/
const openDoubleQuote: InputRule;
/**
* Convert closing quotes
*/
const closeDoubleQuote: InputRule;
/**
* Convert opening single quotes
*/
const openSingleQuote: InputRule;
/**
* Convert closing single quotes
*/
const closeSingleQuote: InputRule;
/**
* Combined smart quote rules
*/
const smartQuotes: InputRule[];Keymaps bind keyboard shortcuts to editor commands.
/**
* Create a keymap plugin from key bindings
*/
function keymap(bindings: { [key: string]: Command | false }): Plugin;
/**
* Create a keydown event handler from bindings
*/
function keydownHandler(bindings: { [key: string]: Command | false }): (view: EditorView, event: KeyboardEvent) => boolean;Key combinations use standard notation for cross-platform compatibility.
/**
* Key binding specification
*/
interface KeyBinding {
[key: string]: Command | false;
}
/**
* Key notation examples:
* - "Mod-b" (Ctrl on PC/Linux, Cmd on Mac)
* - "Alt-Enter"
* - "Shift-Ctrl-z"
* - "Backspace"
* - "Delete"
* - "ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"
* - "Home", "End"
* - "PageUp", "PageDown"
*/Usage Examples:
import {
InputRule,
inputRules,
wrappingInputRule,
textblockTypeInputRule,
smartQuotes,
emDash,
ellipsis
} from "@tiptap/pm/inputrules";
import { keymap } from "@tiptap/pm/keymap";
import { toggleMark, setBlockType } from "@tiptap/pm/commands";
// Custom input rules
const rules = [
// Convert ** to bold
new InputRule(
/\*\*([^*]+)\*\*$/,
(state, match, start, end) => {
const tr = state.tr.delete(start, end);
const mark = state.schema.marks.strong.create();
return tr.insert(start, state.schema.text(match[1], [mark]));
}
),
// Wrap selection in blockquote with >
wrappingInputRule(
/^\s*>\s$/,
state.schema.nodes.blockquote
),
// Convert # to heading
textblockTypeInputRule(
/^#\s/,
state.schema.nodes.heading,
{ level: 1 }
),
// Typography rules
...smartQuotes,
emDash,
ellipsis
];
// Create input rules plugin
const inputRulesPlugin = inputRules({ rules });
// Custom keymap
const myKeymap = keymap({
// Formatting
"Mod-b": toggleMark(schema.marks.strong),
"Mod-i": toggleMark(schema.marks.em),
"Mod-`": toggleMark(schema.marks.code),
// Block types
"Shift-Ctrl-1": setBlockType(schema.nodes.heading, { level: 1 }),
"Shift-Ctrl-2": setBlockType(schema.nodes.heading, { level: 2 }),
"Shift-Ctrl-0": setBlockType(schema.nodes.paragraph),
// Custom commands
"Mod-Enter": (state, dispatch) => {
if (dispatch) {
dispatch(state.tr.insertText("\n"));
}
return true;
},
// Disable default behavior
"Ctrl-d": false
});
// Combine with editor
const state = EditorState.create({
schema: mySchema,
plugins: [
inputRulesPlugin,
myKeymap
]
});Create rules that apply conditionally based on context.
// Only apply in specific node types
const codeBlockRule = new InputRule(
/```(\w+)?\s$/,
(state, match, start, end) => {
// Only apply at document level
if (state.selection.$from.depth > 1) return null;
const attrs = match[1] ? { language: match[1] } : {};
return state.tr
.delete(start, end)
.setBlockType(start, start, schema.nodes.code_block, attrs);
}
);
// Rules with custom undo behavior
const undoableRule = new InputRule(
/-->/g,
"→",
{ undoable: true }
);Input rules can perform sophisticated document transformations.
// Auto-link URLs
const autoLinkRule = new InputRule(
/(https?:\/\/[^\s]+)$/,
(state, match, start, end) => {
const url = match[1];
const mark = schema.marks.link.create({ href: url });
return state.tr
.addMark(start, end, mark)
.insertText(" ", end);
}
);
// Smart list continuation
const listContinueRule = new InputRule(
/^(\d+)\.\s$/,
(state, match, start, end) => {
const number = parseInt(match[1]);
return state.tr
.delete(start, end)
.wrapIn(schema.nodes.ordered_list, { order: number })
.wrapIn(schema.nodes.list_item);
}
);Combine multiple keymaps with priority ordering.
import { baseKeymap } from "@tiptap/pm/commands";
const editorKeymaps = [
// Highest priority - custom overrides
keymap({
"Enter": customEnterCommand,
"Tab": customTabCommand
}),
// Medium priority - feature-specific
keymap({
"Mod-k": insertLinkCommand,
"Mod-Shift-k": removeLinkCommand
}),
// Lowest priority - base commands
keymap(baseKeymap)
];
const state = EditorState.create({
schema: mySchema,
plugins: editorKeymaps
});Handle platform differences in key bindings.
const platformKeymap = keymap({
// Cross-platform modifier
"Mod-z": undo,
"Mod-Shift-z": redo,
// Platform-specific alternatives
...(navigator.platform.includes("Mac") ? {
"Cmd-y": redo // Mac alternative
} : {
"Ctrl-y": redo // Windows/Linux alternative
})
});/**
* Input rule configuration
*/
interface InputRuleConfig {
rules: InputRule[];
}
/**
* Key binding map
*/
interface Keymap {
[key: string]: Command | false;
}
/**
* Input rule handler function
*/
type InputRuleHandler = (
state: EditorState,
match: string[],
start: number,
end: number
) => Transaction | null;
/**
* Input rule options
*/
interface InputRuleOptions {
undoable?: boolean;
}Install with Tessl CLI
npx tessl i tessl/npm-tiptap--pm