chainCommands(
liftListItem(listItemType),
wrapInList(listNodeType),
)(state, dispatch);
Thank you for the quick response!
It turns out that I was confused by the API without throughly check the implementation. In case there might be new folks who might encounter this issue, I’d like to share what I’ve learned below.
While conceptually I know how this could be done, I did not use the right APIs to do it.
First I started with the following codes:
chainCommands(
liftListItem(listItemType),
wrapInList(listNodeType),
)(state, dispatch);
But it did not work, because chainCommands()
does not run all commands chained, instead, it will stop at the first command that returns true
.
So I proceeded using my own chaining logic by manually applying sequential transactions to state:
liftListItem(listItemType)(state, (transaction => {
const nextState = state.apply(transaction);
wrapInList(listNodeType)(nextState, (transaction) => {
dispatch(transaction);
});
}));
But it dos not work because PM will complain that inconsistency state changes and throw error.
So I looked inside the actual codes of prosmirror-schema-list
, then realized that commands like liftListItem
and wrapInList
are just a wrapper of multiple transforms, and to make it does what I need, I should change their API from
liftListItem(listItemType)(state, dispatch); // This returns a boolean
to
liftListItem(listItemType)(state.tr); // This returns a transaction.
Thus, I could do this:
function toggleList(state, dispatch) {
let tr = state.tr;
tr = liftListItem(listItemType)(tr);
tr = wrapInList(listNodeType)(tr);
if (state.tr !== tr) {
// something changed, will apply.
dispatch && dispatch(tr);
return true;
} else {
return false;
}
}
What I did is just refactor “command” into “transform”.
I also learned that people had asked for the similar thing at Refactor Commands into Transform Helpers which is also worthy reading.
Thanks.