slate icon indicating copy to clipboard operation
slate copied to clipboard

`Transforms.setNodes` unexpected behavior of `children`

Open electroluxcode opened this issue 1 year ago • 5 comments

Description

it refer https://docs.slatejs.org/api/transforms#transforms.setnodes-editor-editor-props-partial-less-than-node-greater-than-options

Transforms.setNodes(editor: Editor, props: Partial<Node>, options?)

props: Partial<Node> has a prop named children ,However, when I read the source code in path packages\slate\src\interfaces\transforms\general.ts, I found that the props parameter named children did not render . There's this code

if (key === 'children' || key === 'text') {
  throw new Error(`Cannot set the "${key}" property of nodes! `)
}

this code makes it impossible for setNodes to handle nested cases with 'children'

Expectation

maybe setNodes should be able to handle nested cases with 'children'

Environment

  • Slate Version: 0.103
  • Operating System: window
  • Browser: Chrome

eg

for example

   const path = ReactEditor.findPath(editor, element)
      const newProperties = {
        "type": "one",
        "children": [
          {
            "type": "two",
            "children": [
              {
                "type": "three",
                children:[{
                  text:"shouldbe replace"
                }]
              }
            ]
          }
        ]
      } as any

      Transforms.setNodes(editor, newProperties, { at: path })

this code will only render first level and missing children

it seem deliberate in reading source,i have quesion why would do that

thanks

electroluxcode avatar Jul 26 '24 06:07 electroluxcode

Adding nodes should not use setNodes, but rather APIs such as insertNodes

WindRunnerMax avatar Jul 27 '24 08:07 WindRunnerMax

Adding nodes should not use setNodes, but rather APIs such as insertNodes

hi, @WindrunnerMax thanks for your reply I understand your point; indeed, I can use the insertNode API. However, my requirement is to transform a section of nodes entirely into another node.

For example, in Markdown syntax, inputting - Your content automatically transforms into a ul (unordered list).

Currently, my workaround is to first use the removeNode API and then the insertNode API to replace setNodes, but this approach doesn't seem to be expectations and semantics.

for example,After removing and insert nodes, the cursor will be positioned on the next line. You need to manually control the cursor position by developer

electroluxcode avatar Jul 28 '24 11:07 electroluxcode

@electroluxcode Changing the content using setNodes wouldn't solve the selection problem. This isn't supported by Slate for the same reason that Slate isn't a controlled component. I wrote the following essay explaining why.

https://github.com/ianstormtaylor/slate/issues/5281#issuecomment-2234431664

12joan avatar Jul 30 '24 19:07 12joan

slate-diff can indeed solve the problem of setNodes. However, I think that slate should import the slate-diff library and use it as the logic of setNodes instead of making users perform additional operations.

electroluxcode avatar Sep 14 '24 08:09 electroluxcode

slate-diff can indeed solve the problem of setNodes. However, I think that slate should import the slate-diff library and use it as the logic of setNodes instead of making users perform additional operations.

Unfortunately, that would severely increase Slate's bundle size and code complexity, and harm the predictability of its API. I don't think it's a good candidate for inclusion in core.

12joan avatar Sep 14 '24 08:09 12joan