consider removing `slate-schema`
See original GitHub issueRight now we have a slate-schema
package with the goal of helping people write “normalizations” for their editor, to ensure it’s always in a valid state. This is something that existing in the older versions of Slate and was preserved.
Thing is, I’m not really convinced that it’s totally necessary. With the much more readable helpers (especially the iterables) in the newer version of Slate, I think there’s no longer as big of a win from the schema rules conciseness.
It used to be that schema rules were absolutely more concise than writing the imperative alternative. Now that’s not so true.
For example, here’s the forced-layout
written using slate-schema
:
const withSchema = defineSchema([
{
for: 'node',
match: 'editor',
validate: {
children: [
{ match: { type: 'title' }, min: 1, max: 1 },
{ match: { type: 'paragraph' }, min: 1 },
],
},
normalize: (editor, error) => {
const { code, path } = error
const [index] = path
const type = index === 0 ? 'title' : 'paragraph'
switch (code) {
case 'child_invalid':
case 'child_max_invalid': {
Editor.setNodes(editor, { type }, { at: path })
break
}
case 'child_min_invalid': {
const block = { type, children: [{ text: '' }] }
Editor.insertNodes(editor, block, { at: path })
break
}
}
},
},
])
And here it is using just a plain plugin:
const withSchema = editor => {
const { normalizeNode } = editor
editor.normalizeNode = path => {
if (path.length === 0) {
if (editor.children.length < 1) {
const title = { type: 'title', children: [{ text: 'Untitled' }] }
Editor.insertNodes(editor, title, { at: path.concat(0) })
}
if (editor.children.length < 2) {
const paragraph = { type: 'paragraph', children: [{ text: '' }] }
Editor.insertNodes(editor, paragraph, { at: path.concat(1) })
}
for (const [child, childPath] of Node.children(editor, path)) {
const type = childPath[0] === 0 ? 'title' : 'paragraph'
if (child.type !== type) {
Editor.setNodes(editor, { type }, { at: childPath })
}
}
}
return normalizeNode(path)
}
return editor
}
Both similar in LOC.
The slate-schema
version is definitely more declarative. With the benefit of guaranteeing that as long as you write the validate
dictionary correctly at least you won’t have invalid nodes.
But there are also downsides…
- If you write the
validate
dictionary incorrectly it can be hard to figure out what’s going wrong. - And when you need to debug why a specific schema error is triggering the callstack for doing that is very convoluted.
- And it requires learning a whole new
SchemaError
andSchemaRule
interface. - And when writing more complex rules, the errors often have different properties depending on the failure, which you have to work around.
- And there are many situations that aren’t able to be expressed by the declarative schema at all.
There’s a few cases which get trickier without the declarative schema. The parent
validation is definitely easily to write declaratively, since otherwise you need to enforce it while iterating the parent itself.
But even that one isn’t a clear win, because understanding when the parent
rule fires takes extra knowledge. And it doesn’t allow you to do grandparent
, or cousin
, or any number of slightly different needs.
I think a case could be made for dropping the slate-schema
package entirely and just telling people to use normalizeNode
instead. And cases which are hard to model are either (a) that way because they are in fact very complex, or (b) could benefit from additional helper functions in one of the interfaces.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:7
- Comments:5 (4 by maintainers)
Top GitHub Comments
Something to chew on for sure. I feel like to a degree having it as a first class feature is good for advertising that it exists and sets it apart from other editors that arent as good at dealing with this problem.
From an api perspective while theres more of a learning curve for a new user, the schema does add a structure and organization that I think people are unlikely to be able to achieve with just using normalizeNode. My normalizations tend to be much sloppier when done via the latter.
Id like to see schema stay in but wont be upset if it gets dropped.
Never really understood schema either. I know that might not be the go-to reason to drop something, but for me personally, it was always confusing. If the same functionality can be achieved by other means, I don’t see a reason to keep it. Just my 2 cents.