[SuperEditor] Add toggleable headers (Resolves #2276)#2404
[SuperEditor] Add toggleable headers (Resolves #2276)#2404angelosilvestre wants to merge 1 commit into
Conversation
|
@matthew-carroll I still haven't figured out an ideal API to expand/collapse groups, but can you do a first pass review on this PR? |
|
@angelosilvestre do you think we should hold off on this work until we figure out tree based documents? Or do you think most of the work would be interchangeable and it's worth the effort right now? https://github.com/superlistapp/super_editor/discussions/2403 |
|
@matthew-carroll I'm not entirely sure.
We could probably find a way to implement that with the API introduced by this PR. This PR is basically a way to extract trees from the list of nodes. This probably won't work for tables, but for more simpler requirements this might work. Also, the |
[SuperEditor] Add toggleable headers. Resolves #2276
This PR adds the ability to group nodes together under header nodes or list item nodes, where each group can be collapsed/expanded by tapping on a button near it.
The groups are created upon initialization, when adding or removing a node, and when changing a node that couldn’t start a group to a node that can start a group. For example, typing "# " at the beginning of a paragraph converts it to a header node and creates a new group.
Navigating using the arrow keys skips nodes inside a collapsed group. For example, pressing ARROW DOWN skips nodes that are inside a collapsed group.
The user cannot start or end a selection inside a collapsed group. Also, if the selection starts or ends within a group and the user collapses the group, the selection is adjusted to avoid starting or ending inside the collapsed group.
Node grouping is customizable and apps can implement their own grouping logic, if desirable.
Implementation
A
GroupBuilderinterface was added with the methods required to grouping nodes:canStartGroup: to signal the document layout that the current node can start a group, for example, when it is a level one header.canAddToGroup: to signal the document layout that a node can be added to an existing group.build: to create the widget for this group.SuperEditorwill take a list ofGroupBuilders as a constructor parameter.Previously, all components were organized into a vertical list of components inside the
SingleColumnDocumentLayout. Now, whenever aGroupBuilderreturnstrueforcanStartGroup, the document layout will callcanAddToGroupto each node below it, untilcanAddToGroupreturnsfalse. After gathering all nodes that are part of the group,SingleColumnDocumentLayoutcallsbuildon theGroupBuilderto create a widget subtree for that group.To handle the key navigation, at the current state of this PR, it was added an
isComponentVisiblemethod to theDocumentLayoutinterface, so the layout can report that a component is not currently visible. This is yet subject to change, depending on how we expose an API to programmatically collapse/expand/check state of a group.This PR adds
HeaderGroupBuilderandListItemGroupBuilderwith default behavior for headers and list items. All customization can be done using constructor parameters for these builders. For example, customizing the toggle button, restricting the maximum number of children of a group, etc.ToggleableGroupis the default widget used for headers and list items, which includes a default button that fades in when the mouse enters, fades out when the mouse leaves, animates upon tap. It also includes a vertical line below the button, that also fades in/out. The widget can optionally animate the expanding/collapsing of a group.A change that might be regrettable is that I changed
_SingleColumnDocumentLayoutStateto be public, so I can access information about groups inside tests. Once we figure out a public API for that this can be reverted.Remaining work
Screen.Recording.2024-11-11.at.16.23.53.mov