Plate's value gone when triggered <ListToolbarButton/>
Description
Hello everyone, I'm new in Plate and Slate. I need some help!. I try to create text editor for submitting a review with basic mark, basic element and list element.
Case 1 ✅
I'm start with p element then make a list. It works for both unordered and ordered list
https://user-images.githubusercontent.com/33742791/145608366-7a322501-d8e0-4d19-9007-9bdae7141906.mov
Case 2 💥
I'm start with blockquote element then make a list . It doesn't work for both unordered and ordered list. It also doesn't work for EVERY elements (e.g. h1, h2, code_block, etc.) except p.
https://user-images.githubusercontent.com/33742791/145608852-03cd70cd-e5c2-4c68-a965-34ff7aa9c294.mov
Case 3 ✅
I use autoformat to make a list. It works for every elements
https://user-images.githubusercontent.com/33742791/145611133-6ca8d7e7-8b88-4a45-a3ea-562a707c8165.mov
Case 4 💥
I try to click unordered list on your playground without any modification. Then I get the same behaviour. every elements (except p) got destroyed
https://user-images.githubusercontent.com/33742791/145609754-c5faffea-536e-430c-bb34-d291a9fc0bd6.mov
here is my code full https://github.com/thinc-org/cugetreg-frontend/tree/yu/feat/review/src/common/components/RichTextV2
here is my summarized code
// plugin
export const plugins = createPlugins(
[
/** Element */
createParagraphPlugin(),
createHeadingPlugin(),
createBlockquotePlugin(),
createListPlugin(),
createTodoListPlugin(),
/** Mark */
createBoldPlugin(),
createItalicPlugin(),
createUnderlinePlugin(),
createStrikethroughPlugin(),
createCodePlugin(),
/* *Other */
createExitBreakPlugin({ options: exitBreakOptions }),
createResetNodePlugin({ options: resetNodeOptions }),
createSoftBreakPlugin({ options: softBreakOptions }),
createAutoformatPlugin({ options: autoformatOptions }),
],
{
components: createPlateUI(),
}
)
// Toolbar
export const Toolbar = () => {
return (
<StyledHeadingToolbar>
<ToolbarButton mode="mark" type={RichTextMarkType.BOLD} icon={MdFormatBold} />
<ToolbarButton mode="mark" type={RichTextMarkType.ITALIC} icon={MdFormatItalic} />
<ToolbarButton mode="mark" type={RichTextMarkType.UNDERLINE} icon={MdFormatUnderlined} />
<ToolbarButton mode="mark" type={RichTextMarkType.STRIKETHROUGH} icon={MdStrikethroughS} />
<ToolbarButton mode="mark" type={RichTextMarkType.CODE} icon={MdCode} />
<VerticalDivider />
<ToolbarButton mode="block" type={RichTextBlockType.H1} icon={CgFormatHeading} />
<ToolbarButton mode="block" type={RichTextBlockType.BLOCK_QUOTE} icon={MdFormatQuote} />
<ToolbarButton mode="block" type={RichTextBlockType.CODE_BLOCK} icon={MdCode} />
<ToolbarButton mode="list" type={RichTextBlockType.ORDER_LIST} icon={MdFormatListNumberedRtl} />
<ToolbarButton mode="list" type={RichTextBlockType.UNORDER_LIST} icon={MdFormatListBulleted} />
<Spacer />
<ToolbarButton mode="none" type={RichTextActionType.UNDO} icon={MdUndo} />
<ToolbarButton mode="none" type={RichTextActionType.REDO} icon={MdRedo} />
</StyledHeadingToolbar>
)
}
import { IconButton, TooltipProps } from '@mui/material'
// Custom ToolbarButton
export const ToolbarButton: React.FC<ToolbarButtonProps> = ({ mode, type, icon }) => {
const editor = usePlateEditorRef()
const tooltipProps: Omit<TooltipProps, 'children'> = {
title: RichTextTooltip[type],
placement: 'bottom-end',
}
const createOnMouseDown = (type: ToolbarButtonProps['type']): (() => void) => {
if (type === RichTextActionType.UNDO) return () => editor?.undo()
else if (type === RichTextActionType.REDO) return () => editor?.redo()
return () => {}
}
const getPluginType = (editor: PlateEditor<{}> | undefined, type: ToolbarButtonProps['type']): string => {
if (!editor) return ''
return getPlatePluginType(editor, type)
}
const withIconButton = (IconComponent: IconType, onMouseDown?: () => void) => {
return (
<IconButton size="small" disableRipple onMouseDown={onMouseDown}>
<IconComponent fontSize="0.9em" />
</IconButton>
)
}
switch (mode) {
case 'mark':
return (
<BootstrapTooltip {...tooltipProps}>
<SpanWrapper>
<MarkToolbarButton type={getPluginType(editor, type)} icon={withIconButton(icon)} />
</SpanWrapper>
</BootstrapTooltip>
)
case 'block':
return (
<BootstrapTooltip {...tooltipProps}>
<SpanWrapper>
<BlockToolbarButton type={getPluginType(editor, type)} icon={withIconButton(icon)} />
</SpanWrapper>
</BootstrapTooltip>
)
case 'list':
return (
<BootstrapTooltip {...tooltipProps}>
<SpanWrapper>
<ListToolbarButton type={getPluginType(editor, type)} icon={withIconButton(icon)} />
</SpanWrapper>
</BootstrapTooltip>
)
default:
return <BootstrapTooltip {...tooltipProps}>{withIconButton(icon, createOnMouseDown(type))}</BootstrapTooltip>
}
}
Expectation
summary:
ListToolbarButtonshould have behaviour like autoformat
- If
unordered_listbutton was click when the element is notp, the editor shall change element toulcorrectly without any data lost - If
ordered_listbutton was click when the element is notp, the system shall change element toolcorrectly without any data lost
Environment
- slate: 0.71.0
- slate-react: 0.71.0
- browser: chrome, brave
I stuck with this bug for a long time. Please help me 😢 Thank you in advance!
@zbeyens facing the same trouble with lists.
Im experiencing the same issue. I also noticed the demo(https://codesandbox.io/s/2mh1c) is doing the same.
Fixed in v22 https://github.com/udecode/plate/pull/2472