I have a custom todo list item spec, which looks almost identical to the list item from prosemirror-schema-list. The only difference is that it has an attribute:
attrs: {
done: { default: false },
},
When splitting this item with the standard split function, it basically works, with the unwanted side effect that the item’s done
state is copied over. When splitting a done todo, the todo that is created on the next line is also done, which is not exactly userfriendly. Another usecase is, that when splitting right at the beginning of the paragraph of that item, the original item shall be made undone, while the newly created item shall inherit the done state.
To work around that, i copy-pasted the splitListItem
and made a little tweak. Here’s the relevant part (my modification starts at the comment “modification start”):
let nextType = $to.pos == $from.end() ? grandParent.contentMatchAt(0).defaultType : null
let tr = state.tr.delete($from.pos, $to.pos)
let types = nextType ? [null, {type: nextType}] : undefined
if (!canSplit(tr.doc, $from.pos, 2, types)) return false
// modification start
const isAtStartOfParagraph = $from.parentOffset === 0
if (isAtStartOfParagraph) {
tr = tr.setNodeMarkup($from.pos - 2, null, {done: false})
}
const done = isAtStartOfParagraph ? grandParent.attrs.done : false
types = nextType
? [
{type: itemType, attrs: { done }} as any,
{type: nextType}
]
: [
{type: itemType, attrs: { done }} as any
]
// modification end
if (dispatch) dispatch(tr.split($from.pos, 2, types).scrollIntoView())
return true
This approach basically works, and i have two questions.
Question 1
As you can see, i’m overwriting the types
variable, even though it was previously used in the canSplit
check. canSplit
will return false otherwise. Is my approach ok, or do you have any suggestions how this could be improved?
Question 2
Do you think it would make sense to extend the API of splitListItem
so this kind of hack could be avoided? I see two approaches:
- The first part of the function is extracted to a separate, reusable function, and exported to the packages’s api
- The user of the function could be allowed to pass some kind of option (e.g. a callback function) where the logic i’ve implemented could be executed