[Feature] Expose the list nesting depth to Crepe's listItemBlockConfig.renderLabel
Initial checklist
- I agree to follow the code of conduct
- I searched issues and discussions and couldn't find anything (or linked relevant results below)
Problem
listItemBlockConfig.renderLabel is the documented hook for customising list markers in Crepe, but the callback only receives:
renderLabel: ({ label, listType, checked }) => stringThere is no way to know which nesting level the item being rendered is at, so per-level marker styles cannot be implemented through this API — for example Word's default multilevel scheme, where ordered lists cycle through 1. → a) → i. and bullet lists cycle through ● → ■ → ◆ as the nesting gets deeper. The same limitation is why every level currently renders as a decimal number (#2415).
A related symptom: because renderLabel cannot see the level, a custom renderer has to fall back to walking the document itself and attaching decorations — i.e. re-deriving information the renderer already has.
Solution
Pass the nesting depth to renderLabel, e.g.:
renderLabel: ({ label, listType, checked, depth /* 1 = top level */ }) => stringIt would also be enough (and possibly more useful) to pass the resolved position or the list_item node itself, so a renderer can derive the depth, the parent list's order attribute, and anything else it needs:
renderLabel: ({ label, listType, checked, node, pos }) => stringWith depth (or pos) available, the Word-style scheme above becomes a pure function of the callback's arguments.
Alternatives
- Reconstruct the depth outside the API. This is what we ended up doing in epytor: a separate ProseMirror plugin walks the document on every change, computes
(depth, index, order)per item, and attaches node decorations carrying the level and the marker text, with CSS drawing the marker. It works, but it duplicates work the list-item component already does and has to be re-verified whenever the list-item DOM changes. - Use
listItemSchema/node view extensions to replace the whole list-item rendering — much heavier than the problem warrants. - Ship a custom
bulletIconper level — not possible either, sincebulletIconis a single value in the feature config, not a function of the level.
Environment
@milkdown/crepe/@milkdown/kit7.22.1- Host: VS Code 1.137 webview (Chromium), also reproducible in a plain browser
Source: Milkdown/milkdown