import { wrapInList, liftListItem } from 'prosemirror-schema-list'; import type { Node, NodeType } from 'prosemirror-model'; import type { Transaction, EditorState } from 'prosemirror-state'; import { findParentNode, isList } from '../utils'; type Attr = Record; interface TextStyleAttr { color?: string; fontsize?: string; } export const toggleList = ( listType: NodeType, itemType: NodeType, listStyleType: string, textStyleAttr: TextStyleAttr = {}, ) => { return (state: EditorState, dispatch: (tr: Transaction) => void) => { const { schema, selection } = state; const { $from, $to } = selection; const range = $from.blockRange($to); if (!range) return false; const parentList = findParentNode((node: Node) => isList(node, schema))(selection); if (range.depth >= 1 && parentList && range.depth - parentList.depth <= 1) { if (parentList.node.type === listType && !listStyleType) { return liftListItem(itemType)(state, dispatch); } if (isList(parentList.node, schema) && listType.validContent(parentList.node.content)) { const { tr } = state; const nodeAttrs: Attr = { ...parentList.node.attrs, ...textStyleAttr, }; if (listStyleType) nodeAttrs.listStyleType = listStyleType; tr.setNodeMarkup(parentList.pos, listType, nodeAttrs); if (dispatch) dispatch(tr); return false; } } const nodeAttrs: Attr = { ...textStyleAttr, }; if (listStyleType) nodeAttrs.listStyleType = listStyleType; return wrapInList(listType, nodeAttrs)(state, dispatch); }; };