Text folding

Does anyone have any good ideas for how to implement folding in ProseMirror. I would like to be able to fold/unfold text under a heading until the next heading at the same level.

The approach I am currently considering is to insert a small “-” icon ahead of each heading and set the hidden property on the contents to be hidden if the icon is clicked, and unset it when it is clicked again. What is the best way of identifying the content to be hidden, setting the attribute and removing it again using the ProseMirror API? or should I use a different approach?

Hmm, haven’t done this but I’d suspect the steps are as follows:

  1. Add “-” icon next to each heading
  2. Upon click find the range you want to fold. Range will be from just after current heading to just before the next heading. Not sure of best way to find this position… consult docs. In the past I’ve had to walk over all of the nodes at the root level (pm.doc.child())
  3. Add a mark range for this position (<= v0.10, >= v0.11 does not have this, @marijn is working on its replacement). Essentially giving this entire range a CSS class.

Wes,

Thanks a lot for the feedback. Am I correct in assuming that ranges are ephemeral, in the sense that if I persist pm.doc I will have to reapply the ranges? ie the ranges live in the editor, not in the doc.

Yes, that’s correct.

@maacl Did you ever end up with an implementation for text folding that you liked?

I’m new to PM and wanted to do something very similar to the original post.

Has anyone created something like this that I could use as a guide? If not, could someone outline the steps involved?

@cbeninati @zbum I never got around to implementing this, sorry.

I would like to be able to fold/unfold text under a heading until the next heading at the same level.

output

@maacl @cbeninati @zbum I have implemented the folding of headings which does identical to what you have mentioned.

The implementation is basically

  • find a slice of all the nodes up until a heading of the same level is encountered
  • delete it from the doc
  • stringify the slice as a node Dom attribute in heading that was collapsed.
  • for uncollapsing, parse the JSON string saved in the Dom attribute and append it below the heading.

Links:

  • Collapsible Headings | bangle.dev a live example of collapsing.
  • Here is the source code. Since it is basically just a plugin and a command you can skip the bangle.dev part and directly use it in a Prosemirror code base.
1 Like