docs/api/nodes/element.md
Element objects are a type of Node in a Slate document that contain other Element nodes or Text nodes.
interface Element {
children: Node[]
}
Element nodes behave differently depending on the Slate editor's configuration. An element can be:
editor.isInlineeditor.isVoidA "block" element can only be siblings with other "block" elements. An "inline" node can be siblings with Text nodes or other "inline" elements.
In a not "void" element, Slate handles the rendering of its children (e.g. in a paragraph where the Text and Inline children are rendered by Slate). In a "void" element, the children are rendered by the Element's render code.
Some void elements are effectively stand-ins for text, such as with the Mentions example, where the mention element renders the character's name. Users might want to format Void elements like this with bold, or set their font and size, so editor.markableVoid tells Slate whether or not to apply Marks to the text children of void elements.
Void Elements must
attributes and children (so, their outermost HTML element can't be an HTML void element)contentEditable={false} (for Firefox)Typical rendering code will resemble this thematic-break (horizontal rule) element:
return (
<div {...attributes} contentEditable={false}>
{children}
<hr />
</div>
)
For a "markable" void such as a mention element, marks on the empty child element can be used to determine how the void element is rendered (Slate Marks are applied only to Text leaves):
const Mention = ({ attributes, children, element }) => {
const selected = useSelected()
const focused = useFocused()
const style: React.CSSProperties = {
padding: '3px 3px 2px',
margin: '0 1px',
verticalAlign: 'baseline',
display: 'inline-block',
borderRadius: '4px',
backgroundColor: '#eee',
fontSize: '0.9em',
boxShadow: selected && focused ? '0 0 0 2px #B4D5FF' : 'none',
}
// See if our empty text child has any styling marks applied and apply those
if (element.children[0].bold) {
style.fontWeight = 'bold'
}
if (element.children[0].italic) {
style.fontStyle = 'italic'
}
return (
<span
{...attributes}
contentEditable={false}
data-cy={`mention-${element.character.replace(' ', '-')}`}
style={style}
>
{children}@{element.character}
</span>
)
}
Element.matches(element: Element, props: Partial<Element>) => booleanCheck if an element matches a set of props. Note: This checks custom properties, but it does not ensure that any children are equivalent.
Element.isAncestor(value: any) => value is AncestorCheck if a value implements the 'Ancestor' interface.
Element.isElement(value: any) => value is ElementCheck if a value implements the Element interface.
Element.isElementList(value: any) => value is Element[]Check if a value is an array of Element objects.
Element.isElementType<T Extends Element>(value: any, elementVal: string, ElementKey: string = 'type'): value is TCheck if a value implements the Element interface and has elementKey with selected value.
Default it check to type key value