-
Hi, I’m having issues with the toolbar and working with multiple editors with unique ids where each editor gets their own toolbar. If I toggle a toolbar element, the element gets toggled on all the toolbars.. Is it possible to avoid this behavior? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 3 replies
-
You can use |
Beta Was this translation helpful? Give feedback.
-
I had the exact same issue. I managed to solve it by creating a // ToolbarButtonsHelper.jsx
import { Children, cloneElement, isValidElement } from 'react';
import {
ToolbarElement,
ToolbarMark,
ToolbarLink,
getPlatePluginType,
ToolbarList,
useStoreEditorState,
useEventEditorId,
someNode,
isMarkActive,
} from '@udecode/plate';
export function Button({ editor: passedEditor, children }) {
const focusedEditor = useStoreEditorState(useEventEditorId('focus'));
const isPassedEditorFocused = focusedEditor === passedEditor;
const isTextSelected = !!focusedEditor?.selection;
const isSelectionFocused = isPassedEditorFocused && isTextSelected;
const childrenWithProps = Children.map(children, (child) => {
if (isValidElement(child)) {
return cloneElement(child, { isSelectionFocused, editor: focusedEditor });
}
return child;
});
return <>{childrenWithProps}</>;
}
Button.Element = ({
isSelectionFocused, editor, plugin, icon,
}) => {
const type = getPlatePluginType(editor, plugin);
const isActive = isSelectionFocused && someNode(editor, { match: { type } });
return <ToolbarElement type={type} active={isActive} icon={icon} />;
};
Button.Mark = ({
isSelectionFocused, editor, plugin, icon,
}) => {
const type = getPlatePluginType(editor, plugin);
const isActive = isSelectionFocused && isMarkActive(editor, type);
return <ToolbarMark type={type} active={isActive} icon={icon} />;
};
Button.List = ({
isSelectionFocused, editor, plugin, icon,
}) => {
const type = getPlatePluginType(editor, plugin);
const isActive = isSelectionFocused && someNode(editor, { match: { type } });
return <ToolbarList type={type} active={isActive} icon={icon} />;
};
Button.Link = ({
isSelectionFocused, editor, plugin, icon,
}) => {
const type = getPlatePluginType(editor, plugin);
const isActive = isSelectionFocused && someNode(editor, { match: { type } });
return <ToolbarLink active={isActive} icon={icon} />;
}; You can then create predefined sets of toolbars from the component above, like the one below: // ToolbarButtons.jsx
import {
ELEMENT_H3,
ELEMENT_BLOCKQUOTE,
MARK_BOLD,
MARK_ITALIC,
MARK_UNDERLINE,
MARK_STRIKETHROUGH,
ELEMENT_TODO_LI,
MARK_SUBSCRIPT,
ELEMENT_UL,
ELEMENT_OL,
ELEMENT_LINK,
} from '@udecode/plate';
import {
FaHeading,
FaQuoteRight,
FaBold,
FaItalic,
FaUnderline,
FaStrikethrough,
FaSubscript,
FaListUl,
FaListOl,
FaCheckSquare,
FaLink,
} from 'react-icons/fa';
import { Button } from './utils/ToolbarButtonHelper';
function ToolbarButtons({ editor }) {
return (
<Button editor={editor}>
<Button.Element plugin={ELEMENT_H3} icon={<FaHeading />} />
<Button.Mark plugin={MARK_BOLD} icon={<FaBold />} />
<Button.Mark plugin={MARK_ITALIC} icon={<FaItalic />} />
<Button.Mark plugin={MARK_UNDERLINE} icon={<FaUnderline />} />
<Button.Mark plugin={MARK_STRIKETHROUGH} icon={<FaStrikethrough />} />
<Button.Mark plugin={MARK_SUBSCRIPT} icon={<FaSubscript />} />
<Button.Element plugin={ELEMENT_BLOCKQUOTE} icon={<FaQuoteRight />} />
<Button.List plugin={ELEMENT_UL} icon={<FaListUl />} />
<Button.List plugin={ELEMENT_OL} icon={<FaListOl />} />
<Button.Element plugin={ELEMENT_TODO_LI} icon={<FaCheckSquare />} />
<Button.Link plugin={ELEMENT_LINK} icon={<FaLink />} />
</Button>
);
}
export default ToolbarButtons; And then as said earlier, use it alongside your // Anywhere else
...
const EDITOR_ID = "my-plate-id";
function Editor() {
const editorRef = useStoreEditorRef(EDITOR_ID);
return (
<div>
<HeadingToolbar>
<ToolbarButtons editor={editorRef} />
</HeadeingToolbar>
<Plate
id={EDITOR_ID}
...
/>
</div>
);
}
export default Editor; Hope this helps. |
Beta Was this translation helpful? Give feedback.
-
Re-reading the issue, I was proposing a solution for a common toolbar but your issue is about a toolbar for each editor, which should be resolved by passing the correct editor id: You may need to fork the components as @sepsol did |
Beta Was this translation helpful? Give feedback.
I had the exact same issue. I managed to solve it by creating a
ToolbarButtonHelper.jsx
andToolbarButtons.jsx
components. I then import the later one into any component I want and pass it theeditorRef
which can be obtained by calling theuseStoreEditorRef()
hook and passing it theid
you passed to theplate
component.