Components
Draggables
Draggables
Allows movement of blocks, such as paragraph or tables, within the editor.
🌳 Blocks
Easily create headings of various levels, from H1 to H6, to structure your content and make it more organized.
Create blockquotes to emphasize important information or highlight quotes from external sources.
// Use code blocks to showcase code snippetsfunction greet() { console.info('Hello World!');}
🌱 Marks
Add style and emphasis to your text using the mark plugins, which offers a variety of formatting options.
Make text bold, italic, underlined, or apply a combination of these styles for a visually striking effect.
Add strikethrough to indicate deleted or outdated content.
Write code snippets with inline
code
formatting for easy readability.Installation
npx @udecode/plate-ui@latest add draggable
Examples
import { createPlugins } from '@udecode/plate-common';
import { createDndPlugin } from '@udecode/plate-dnd';
import { createNodeIdPlugin } from '@udecode/plate-node-id';
import { createPlateUI } from '@/lib/plate/create-plate-ui';
import { withDraggables } from './withDraggables';
const plugins = createPlugins(
[
// ...otherPlugins,
createNodeIdPlugin(),
createDndPlugin({ options: { enableScroller: true } }),
],
{
components: withDraggables(createPlateUI()),
}
);
Provider
Wrap Plate
with DndProvider
from react-dnd
.
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
<DndProvider backend={HTML5Backend}>
<Plate plugins={plugins} />
</DndProvider>;
Examples
import { createAlignPlugin } from '@udecode/plate-alignment';
import { createAutoformatPlugin } from '@udecode/plate-autoformat';
import {
createBoldPlugin,
createCodePlugin,
createItalicPlugin,
createStrikethroughPlugin,
createSubscriptPlugin,
createSuperscriptPlugin,
createUnderlinePlugin,
MARK_BOLD,
MARK_CODE,
MARK_ITALIC,
MARK_STRIKETHROUGH,
MARK_SUBSCRIPT,
MARK_SUPERSCRIPT,
MARK_UNDERLINE,
} from '@udecode/plate-basic-marks';
import {
createBlockquotePlugin,
ELEMENT_BLOCKQUOTE,
} from '@udecode/plate-block-quote';
import {
createExitBreakPlugin,
createSoftBreakPlugin,
} from '@udecode/plate-break';
import {
createCodeBlockPlugin,
ELEMENT_CODE_BLOCK,
ELEMENT_CODE_LINE,
ELEMENT_CODE_SYNTAX,
isCodeBlockEmpty,
isSelectionAtCodeBlockStart,
unwrapCodeBlock,
} from '@udecode/plate-code-block';
import { createComboboxPlugin } from '@udecode/plate-combobox';
import { createCommentsPlugin, MARK_COMMENT } from '@udecode/plate-comments';
import {
createPlugins,
isBlockAboveEmpty,
isSelectionAtBlockStart,
PlateLeaf,
RenderAfterEditable,
someNode,
withProps,
} from '@udecode/plate-common';
import { createDndPlugin } from '@udecode/plate-dnd';
import { createEmojiPlugin } from '@udecode/plate-emoji';
import {
createExcalidrawPlugin,
ELEMENT_EXCALIDRAW,
} from '@udecode/plate-excalidraw';
import {
createFontBackgroundColorPlugin,
createFontColorPlugin,
createFontSizePlugin,
} from '@udecode/plate-font';
import {
createHeadingPlugin,
ELEMENT_H1,
ELEMENT_H2,
ELEMENT_H3,
ELEMENT_H4,
ELEMENT_H5,
ELEMENT_H6,
KEYS_HEADING,
} from '@udecode/plate-heading';
import {
createHighlightPlugin,
MARK_HIGHLIGHT,
} from '@udecode/plate-highlight';
import {
createHorizontalRulePlugin,
ELEMENT_HR,
} from '@udecode/plate-horizontal-rule';
import { createIndentPlugin } from '@udecode/plate-indent';
import {
createIndentListPlugin,
KEY_LIST_STYLE_TYPE,
} from '@udecode/plate-indent-list';
import { createJuicePlugin } from '@udecode/plate-juice';
import { createKbdPlugin, MARK_KBD } from '@udecode/plate-kbd';
import { createLineHeightPlugin } from '@udecode/plate-line-height';
import { createLinkPlugin, ELEMENT_LINK } from '@udecode/plate-link';
import {
createTodoListPlugin,
ELEMENT_LI,
ELEMENT_OL,
ELEMENT_TODO_LI,
ELEMENT_UL,
} from '@udecode/plate-list';
import {
createImagePlugin,
createMediaEmbedPlugin,
ELEMENT_IMAGE,
ELEMENT_MEDIA_EMBED,
} from '@udecode/plate-media';
import {
createMentionPlugin,
ELEMENT_MENTION,
ELEMENT_MENTION_INPUT,
} from '@udecode/plate-mention';
import { createNodeIdPlugin } from '@udecode/plate-node-id';
import {
createParagraphPlugin,
ELEMENT_PARAGRAPH,
} from '@udecode/plate-paragraph';
import { createResetNodePlugin } from '@udecode/plate-reset-node';
import { createSelectOnBackspacePlugin } from '@udecode/plate-select';
import { createBlockSelectionPlugin } from '@udecode/plate-selection';
import { createDeserializeDocxPlugin } from '@udecode/plate-serializer-docx';
import { createDeserializeMdPlugin } from '@udecode/plate-serializer-md';
import { createTabbablePlugin } from '@udecode/plate-tabbable';
import {
createTablePlugin,
ELEMENT_TABLE,
ELEMENT_TD,
ELEMENT_TH,
ELEMENT_TR,
} from '@udecode/plate-table';
import { createTrailingBlockPlugin } from '@udecode/plate-trailing-block';
import { autoformatPlugin } from '@/lib/plate/autoformatPlugin';
import { dragOverCursorPlugin } from '@/lib/plate/dragOverCursorPlugin';
import { BlockquoteElement } from '@/components/plate-ui/blockquote-element';
import { CodeBlockElement } from '@/components/plate-ui/code-block-element';
import { CodeLeaf } from '@/components/plate-ui/code-leaf';
import { CodeLineElement } from '@/components/plate-ui/code-line-element';
import { CodeSyntaxLeaf } from '@/components/plate-ui/code-syntax-leaf';
import { CommentLeaf } from '@/components/plate-ui/comment-leaf';
import { EmojiCombobox } from '@/components/plate-ui/emoji-combobox';
import { ExcalidrawElement } from '@/components/plate-ui/excalidraw-element';
import { HeadingElement } from '@/components/plate-ui/heading-element';
import { HighlightLeaf } from '@/components/plate-ui/highlight-leaf';
import { HrElement } from '@/components/plate-ui/hr-element';
import { ImageElement } from '@/components/plate-ui/image-element';
import { KbdLeaf } from '@/components/plate-ui/kbd-leaf';
import { LinkElement } from '@/components/plate-ui/link-element';
import { LinkFloatingToolbar } from '@/components/plate-ui/link-floating-toolbar';
import { ListElement } from '@/components/plate-ui/list-element';
import { MediaEmbedElement } from '@/components/plate-ui/media-embed-element';
import { MentionElement } from '@/components/plate-ui/mention-element';
import { MentionInputElement } from '@/components/plate-ui/mention-input-element';
import { ParagraphElement } from '@/components/plate-ui/paragraph-element';
import { withPlaceholders } from '@/components/plate-ui/placeholder';
import {
TableCellElement,
TableCellHeaderElement,
} from '@/components/plate-ui/table-cell-element';
import { TableElement } from '@/components/plate-ui/table-element';
import { TableRowElement } from '@/components/plate-ui/table-row-element';
import { TodoListElement } from '@/components/plate-ui/todo-list-element';
import { withDraggables } from '@/components/plate-ui/with-draggables';
import { TabbableElement } from '@/components/plate/tabbable-element';
const resetBlockTypesCommonRule = {
types: [ELEMENT_BLOCKQUOTE, ELEMENT_TODO_LI],
defaultType: ELEMENT_PARAGRAPH,
};
const resetBlockTypesCodeBlockRule = {
types: [ELEMENT_CODE_BLOCK],
defaultType: ELEMENT_PARAGRAPH,
onReset: unwrapCodeBlock,
};
export const plugins = createPlugins(
[
// Nodes
createParagraphPlugin(),
createHeadingPlugin(),
createBlockquotePlugin(),
createCodeBlockPlugin(),
createHorizontalRulePlugin(),
createLinkPlugin({
renderAfterEditable: LinkFloatingToolbar as RenderAfterEditable,
}),
createImagePlugin(),
createMediaEmbedPlugin(),
createMentionPlugin(),
createTablePlugin(),
createTodoListPlugin(),
createExcalidrawPlugin(),
// Marks
createBoldPlugin(),
createItalicPlugin(),
createUnderlinePlugin(),
createStrikethroughPlugin(),
createCodePlugin(),
createSubscriptPlugin(),
createSuperscriptPlugin(),
createFontColorPlugin(),
createFontBackgroundColorPlugin(),
createFontSizePlugin(),
createHighlightPlugin(),
createKbdPlugin(),
// Block Style
createAlignPlugin({
inject: {
props: {
validTypes: [ELEMENT_PARAGRAPH, ELEMENT_H1, ELEMENT_H2, ELEMENT_H3],
},
},
}),
createIndentPlugin({
inject: {
props: {
validTypes: [
ELEMENT_PARAGRAPH,
ELEMENT_H1,
ELEMENT_H2,
ELEMENT_H3,
ELEMENT_BLOCKQUOTE,
ELEMENT_CODE_BLOCK,
],
},
},
}),
createIndentListPlugin(),
createLineHeightPlugin({
inject: {
props: {
defaultNodeValue: 1.5,
validNodeValues: [1, 1.2, 1.5, 2, 3],
validTypes: [ELEMENT_PARAGRAPH, ELEMENT_H1, ELEMENT_H2, ELEMENT_H3],
},
},
}),
// Functionality
createAutoformatPlugin(autoformatPlugin),
createBlockSelectionPlugin({
options: {
sizes: {
top: 0,
bottom: 0,
},
},
}),
createComboboxPlugin(),
createDndPlugin({
options: { enableScroller: true },
}),
createEmojiPlugin({
renderAfterEditable: EmojiCombobox,
}),
createExitBreakPlugin({
options: {
rules: [
{
hotkey: 'mod+enter',
},
{
hotkey: 'mod+shift+enter',
before: true,
},
{
hotkey: 'enter',
query: {
start: true,
end: true,
allow: KEYS_HEADING,
},
relative: true,
level: 1,
},
],
},
}),
createNodeIdPlugin(),
createResetNodePlugin({
options: {
rules: [
{
...resetBlockTypesCommonRule,
hotkey: 'Enter',
predicate: isBlockAboveEmpty,
},
{
...resetBlockTypesCommonRule,
hotkey: 'Backspace',
predicate: isSelectionAtBlockStart,
},
{
...resetBlockTypesCodeBlockRule,
hotkey: 'Enter',
predicate: isCodeBlockEmpty,
},
{
...resetBlockTypesCodeBlockRule,
hotkey: 'Backspace',
predicate: isSelectionAtCodeBlockStart,
},
],
},
}),
createSelectOnBackspacePlugin({
options: {
query: {
allow: [ELEMENT_IMAGE, ELEMENT_HR],
},
},
}),
createSoftBreakPlugin({
options: {
rules: [
{ hotkey: 'shift+enter' },
{
hotkey: 'enter',
query: {
allow: [ELEMENT_CODE_BLOCK, ELEMENT_BLOCKQUOTE, ELEMENT_TD],
},
},
],
},
}),
createTabbablePlugin({
options: {
query: (editor) => {
if (isSelectionAtBlockStart(editor)) return false;
return !someNode(editor, {
match: (n) => {
return !!(
n.type &&
([ELEMENT_TABLE, ELEMENT_LI, ELEMENT_CODE_BLOCK].includes(
n.type as string
) ||
n[KEY_LIST_STYLE_TYPE])
);
},
});
},
},
plugins: [
{
key: 'tabbable_element',
isElement: true,
isVoid: true,
component: TabbableElement,
},
],
}),
createTrailingBlockPlugin({
options: { type: ELEMENT_PARAGRAPH },
}),
dragOverCursorPlugin,
// Collaboration
createCommentsPlugin(),
// Deserialization
createDeserializeDocxPlugin(),
createDeserializeMdPlugin(),
createJuicePlugin(),
],
{
components: withDraggables(
withPlaceholders({
[ELEMENT_BLOCKQUOTE]: BlockquoteElement,
[ELEMENT_CODE_BLOCK]: CodeBlockElement,
[ELEMENT_CODE_LINE]: CodeLineElement,
[ELEMENT_CODE_SYNTAX]: CodeSyntaxLeaf,
[ELEMENT_HR]: HrElement,
[ELEMENT_H1]: withProps(HeadingElement, { variant: 'h1' }),
[ELEMENT_H2]: withProps(HeadingElement, { variant: 'h2' }),
[ELEMENT_H3]: withProps(HeadingElement, { variant: 'h3' }),
[ELEMENT_H4]: withProps(HeadingElement, { variant: 'h4' }),
[ELEMENT_H5]: withProps(HeadingElement, { variant: 'h5' }),
[ELEMENT_H6]: withProps(HeadingElement, { variant: 'h6' }),
[ELEMENT_IMAGE]: ImageElement,
[ELEMENT_LINK]: LinkElement,
[ELEMENT_MEDIA_EMBED]: MediaEmbedElement,
[ELEMENT_MENTION]: MentionElement,
[ELEMENT_MENTION_INPUT]: MentionInputElement,
[ELEMENT_UL]: withProps(ListElement, { variant: 'ul' }),
[ELEMENT_OL]: withProps(ListElement, { variant: 'ol' }),
[ELEMENT_PARAGRAPH]: ParagraphElement,
[ELEMENT_TABLE]: TableElement,
[ELEMENT_TD]: TableCellElement,
[ELEMENT_TH]: TableCellHeaderElement,
[ELEMENT_TODO_LI]: TodoListElement,
[ELEMENT_TR]: TableRowElement,
[ELEMENT_EXCALIDRAW]: ExcalidrawElement,
[MARK_BOLD]: withProps(PlateLeaf, { as: 'strong' }),
[MARK_CODE]: CodeLeaf,
[MARK_HIGHLIGHT]: HighlightLeaf,
[MARK_ITALIC]: withProps(PlateLeaf, { as: 'em' }),
[MARK_KBD]: KbdLeaf,
[MARK_STRIKETHROUGH]: withProps(PlateLeaf, { as: 's' }),
[MARK_SUBSCRIPT]: withProps(PlateLeaf, { as: 'sub' }),
[MARK_SUPERSCRIPT]: withProps(PlateLeaf, { as: 'sup' }),
[MARK_UNDERLINE]: withProps(PlateLeaf, { as: 'u' }),
[MARK_COMMENT]: CommentLeaf,
})
),
}
);