UNPKG

prosemirror-flat-list

Version:
65 lines (55 loc) 1.77 kB
import type { Command } from 'prosemirror-state' import type { ListAttributes, ProsemirrorNode } from '../types' import { isListNode } from '../utils/is-list-node' import { setSafeSelection } from './set-safe-selection' /** * @public @group Commands */ export interface ToggleCollapsedOptions { /** * If this value exists, the command will set the `collapsed` attribute to * this value instead of toggle it. */ collapsed?: boolean /** * An optional function to accept a list node and return whether or not this * node can toggle its `collapsed` attribute. */ isToggleable?: (node: ProsemirrorNode) => boolean } /** * Return a command function that toggle the `collapsed` attribute of the list node. * * @public @group Commands */ export function createToggleCollapsedCommand( options: ToggleCollapsedOptions = {}, ): Command { const { collapsed = undefined, isToggleable = defaultIsToggleable } = options const toggleCollapsed: Command = (state, dispatch) => { const { $from } = state.selection for (let depth = $from.depth; depth >= 0; depth--) { const node = $from.node(depth) if (isListNode(node) && isToggleable(node)) { if (dispatch) { const pos = $from.before(depth) const attrs = node.attrs as ListAttributes const tr = state.tr tr.setNodeAttribute(pos, 'collapsed', collapsed ?? !attrs.collapsed) dispatch(setSafeSelection(tr)) } return true } } return false } return toggleCollapsed } function defaultIsToggleable(node: ProsemirrorNode): boolean { const attrs = node.attrs as ListAttributes return ( attrs.kind === 'toggle' && node.childCount >= 2 && !isListNode(node.firstChild) ) }