OpenMAIC-React / src /lib /prosemirror /commands /setTextIndent.ts
muthuk1's picture
Convert OpenMAIC from Next.js to React (Vite)
f56a29b verified
import type { Schema } from 'prosemirror-model';
import { type Transaction, TextSelection, AllSelection } from 'prosemirror-state';
import type { EditorView } from 'prosemirror-view';
import { isList } from '../utils';
type IndentKey = 'indent' | 'textIndent';
function setNodeIndentMarkup(
tr: Transaction,
pos: number,
delta: number,
indentKey: IndentKey,
): Transaction {
if (!tr.doc) return tr;
const node = tr.doc.nodeAt(pos);
if (!node) return tr;
const minIndent = 0;
const maxIndent = 8;
let indent = (node.attrs[indentKey] || 0) + delta;
if (indent < minIndent) indent = minIndent;
if (indent > maxIndent) indent = maxIndent;
if (indent === node.attrs[indentKey]) return tr;
const nodeAttrs = {
...node.attrs,
[indentKey]: indent,
};
return tr.setNodeMarkup(pos, node.type, nodeAttrs, node.marks);
}
const setIndent = (
tr: Transaction,
schema: Schema,
delta: number,
indentKey: IndentKey,
): Transaction => {
const { selection, doc } = tr;
if (!selection || !doc) return tr;
if (!(selection instanceof TextSelection || selection instanceof AllSelection)) return tr;
const { from, to } = selection;
doc.nodesBetween(from, to, (node, pos) => {
const nodeType = node.type;
if (nodeType.name === 'paragraph' || nodeType.name === 'blockquote') {
tr = setNodeIndentMarkup(tr, pos, delta, indentKey);
return false;
} else if (isList(node, schema)) return false;
return true;
});
return tr;
};
export const indentCommand = (view: EditorView, delta: number) => {
const { state } = view;
const { schema, selection } = state;
const tr = setIndent(state.tr.setSelection(selection), schema, delta, 'indent');
if (tr.docChanged) {
view.dispatch(tr);
return true;
}
return false;
};
export const textIndentCommand = (view: EditorView, delta: number) => {
const { state } = view;
const { schema, selection } = state;
const tr = setIndent(state.tr.setSelection(selection), schema, delta, 'textIndent');
if (tr.docChanged) {
view.dispatch(tr);
return true;
}
return false;
};