I want to build a schema that would allow only lists containing inline content (text or image).
Thus, I defined a schema (derived from schema-basic + schema-list) whose top node is a list:
I also have a command to indent a bullet (and its contents) using sinkListItem(mySchema.nodes.list_item)
I had two issues doing that:
this would only work if the schema provided to sinkListItem is the one indirectly attached to the view (a.k.a. view.state.schema). Otherwise the sinkListItempredicate will fail to match the two list_item types as they may be equal but different instances. So this one is kind of workarounded, but I’d love to understand why.
When creating lines of (non empty) text and trying to indent one, I get TransformError: Invalid content for node list_item. Debugging it, it seems that ReplaceAround is ok (inserted is list_item > bullet_list > list_item with the text contents) but I end up replacing with some empty content ([]), and still don’t understand why (I once thought that the problem was that block content was expected, but I define list_item as expecting inline content). Help on this one would be greatly appreciated!
Debugging more, it seems that the problem is that the indentation would insert a bullet_list into the list_item, which was not described as possibility by the schema.
Yes, that’s why that takes a parameter—you have to pass the node type from your schema
I understood that. I was more curious about why it works with view.state.schema.list_item and not directly meEditorState.schema.list_item (type objects are equal but not the same instance). I guess it expects to compare with the one from the current transaction or something.
Maybe * is what you want?
I don’t think so as this would imply multiple lists (<ul>s), whereas I only expect a (possible) single one <ul> to host nested <li>s (otherwise I would allow multiple <ul>s in a <li>):
bullet_list
list_item
paragraph
inline
bullet_list?
list_item
paragraph
list_item
paragraph
list_item
paragraph
Anyway I tried bullet_list*, with no more luck: hitting return in the paragraph (as content of the current list_item of the bullet_list top node) doesn’t create any additional list_item after it. I’m stuck in a single paragraph in a single list_item. I guess the silent fail is because this would create something invalid but I can’t spot what.
Basically what I would like to achieve is:
root bullet_list (mandatory) => ok
writing implicitly creates a list_item => ok
hitting return in any list_item creates a new list_item below at same depth => ko (doesn’t create more bullets)
sending indent command nest the current list_item (or selection) one depth level => ko but this likely requires the previous one to be ok
Looking at commands’ canSplit() which calls canReplaceWith() it seems that when I hit Return in a paragraph, it tries to match what would be added (a new paragraph) with the allowed next element (a bullet_list) and fails.
How can I tell that splitting a paragraph should create a new list_item (which a new paragraph inside)? This seems to be quite straightforward usually, and I can’t figure out what prevents it in my case.
That’s a constraint ProseMirror adds. In HTML it also leads to implicit blocks, and that kind of magic is the kind of thing ProseMirror tries to make explicit.
This is the example code from one of those ProseMirror example projects. It basically defines a Hotkey:
bind('Enter', splitListItem(schema.nodes.list_item));