I’m not a big fan of the default list behaviour of wrapInList
from prosemirror-schema-list
. I want the button to act as a toggle. So if you click the bullet list button in a bullet list, it removes the list, if you click a bullet list button in a numbered list, it swaps the numbered list for a bullet list. If you click it outside of any list, it just wraps in a bullet list.
So far, I have:
function isList(node: Node) {
return (
node.type === spec.nodes.bullet_list ||
node.type === spec.nodes.ordered_list
);
}
function toggleList(listType: NodeType) {
const lift = liftListItem(spec.nodes.list_item);
const wrap = wrapInList(listType);
return (
state: EditorState,
dispatch?: (tr: Transaction) => void,
): boolean => {
const {$from, $to} = state.selection;
const range = $from.blockRange($to);
if (!range) {
return false;
}
if (range.depth >= 2 && $from.node(range.depth - 1).type === listType) {
return lift(state, dispatch);
} else if (range.depth >= 2 && isList($from.node(range.depth - 1))) {
const tr = state.tr;
// const node = $from.node(range.depth - 1);
// TODO: how do I pass the node above to `setNodeType`?
// tr.setNodeType(range.start, listType);
if (dispatch) dispatch(tr);
return false;
} else {
return wrap(state, dispatch);
}
};
}
But I’m stuck on how to resolve that TODO item. This is my first time trying to write my own transaction code, so any help is really appreciated.