slate
slate copied to clipboard
Nesting Block Elements
Problem
I am creating a FeedbackElement
that can wrap any element. So it could appear at the root of the editor (ie. one of the editors children) or as a child of some block node: like a paragraph. FeedbackElement
s can contain other FeedbackElements
, or really any element, like images, lists, etc.
The only issue with this is that the default normalizeNode
does not permit this (especially as a child of a paragraph). I could get this to work by completely disabling normalisation using a plugin that modifies normalizeNode
to a noop function. But, of course, you don't want to do this because it creates its own sets of bugs.
The type definition for feedback is as follows:
export type FeedbackElement = {
type: "feedback";
feedback: string;
children: Element[];
};
Solution There should be a way to nest block elements.
[
{
"type": "paragraph",
"children": [
{
"text": "example "
},
{
"type": "feedback",
"feedback": "great job with this!"
"children": [
{
"text": "some text "
},
]
},
]
},
{
"type": "paragraph",
"children": [
{
"text": ""
}
]
}
]
I also hit this problem, but with lists.
If I have a list like https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ul
the slate editor will remove the sublist element in the <li>
This is due to https://github.com/ianstormtaylor/slate/blob/1d8010be8500ef5c98dbd4179354db1986d5c8f4/packages/slate/src/create-editor.ts#L253-L256
More context: https://github.com/plone/volto/issues/4538
@jayaike I've been exploring this similar problem, here's possible fixes:
- override
normalizeNode
, wrap the inline children with a container<span>
or something similar. This way Slate sees element as first child - my chosen fix was to write code in my
normalizeNode
that lifts the child<ul>
to be a sibling of its original parent<li>
@tiberiuichim yea im also thinking of modifying the default normalizeNode fn to support my needs.
- Allow merging of adjacent text nodes that have the same properties
- Allow nesting of block nodes
I see no reason why block nodes should not be nested. Nested block nodes would be similar to inline-block in regular HTML which is of course a thing.
@jayaike We usually implement isInline => true for all our custom elements.
@tiberiuichim yes i considered this but that wont cover the case (for me) of where i wrap maybe 4 block elements. since inline elements dont typically contain block elements.
whereas a block element can contain block elements and inline elements.
my use case would be something like this.
<feedback>
<p>Here is some random <feedback>data</feedback></p>
<feedback><img src="..." /></feedback>
</feedback>
so really it is an inline-block type of element you could say
Does anyone have an example of how to overwrite the normalizeNode method to support this?