Skip to content

Editor SetValue stripping out listStart from deserialized Markdown breaking list rendering. #4649

@tycomo

Description

@tycomo

Description

Hi all,

I noticed that I was having issues with certain markdown lists not being displayed correctly after performing deserialization and setting the markdown value in the editor (see the hardcoded markdown I used and the output of the editor below).

First, I initialized a basic editor from the starter kit with deserialization and logging.

const markdown = `
# Random Markdown Questions

## Question 1
1. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
   - A) Aliquam tortor purus
   - B) Aliquam tortor purus
   - C) Aliquam tortor purus
   - D) Aliquam tortor purus

---

## Question 2
2. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
   - A) Aliquam tortor purus
   - B) Aliquam tortor purus 
   - C) Aliquam tortor purus
   - D) Aliquam tortor purus

---
`


export function PlateEditor() {
  const editor = usePlateEditor({
    plugins: EditorKit,
  });

  const markdownValue = editor.getApi(MarkdownPlugin).markdown.deserialize(markdown, {
    remarkPlugins: [remarkMath, remarkGfm, remarkMdx, remarkMention],
  })

  console.log('markdownValue', markdownValue);

  //set the const markdown to the editor
  editor.tf.setValue(markdownValue);
  console.log('editor.children', editor.children);

  if (!editor) return null;

  return (
    <Plate editor={editor}>
      <EditorContainer variant="default">
        <Editor variant="default" />
      </EditorContainer>
    </Plate>
  );
}

Here is the editor output where both questions start with 1:

Image

I thought this was an issue with deserialization but in my console logs I see that the correct start value is defined.

Image

What is unexpected is that after this I see that the editor children do not have this value

Image

Because of this, it seems in my block-list component (left the same from the sample template) listStart is always null.

function List(props: PlateElementProps) {
  const { listStart, listStyleType } = props.element as TListElement;
  const { Li, Marker } = config[listStyleType] ?? {};
  const List = isOrderedList(props.element) ? 'ol' : 'ul';

  return (
    <List
      className="relative m-0 p-0"
      style={{ listStyleType }}
      start={listStart}
    >
      {Marker && <Marker {...props} />}
      {Li ? <Li {...props} /> : <li>{props.children}</li>}
    </List>
  );
}

I was able to work around this by overriding the deserializer and adding a custom property to the list items that "survives" setValue in the editor and then use that in block-list but that is just a temporary workaround.

I believe the expected behavior is that the listStart value from deserialization are accessible in the component to be able to render the correct values and that they also need to be available to be used for exporting to maintain list numbering (haven't been able to test export yet).

Reproduction URL

You can see the issue with the platejs block here: https://platejs.org/blocks/markdown-to-slate-demo

Reproduction steps

1. Setup Editor Similar to Above.
2. Deserialize the hardcoded markdown.
3. Notice that listStart is captured but not accessible to be used in the UI.

Plate version

49.2.21

Slate React version

0.117.4

Screenshots

See attached above.

Logs

See above.

Browsers

Chrome

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingplugin:list-classicBulleted & ordered lists

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions