Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Import HTML exported by PlateStatic. #3943

Merged
merged 27 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .changeset/few-points-clean.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
'@udecode/plate-indent-list': patch
'@udecode/plate-line-height': patch
'@udecode/plate-code-block': patch
'@udecode/plate-comments': patch
'@udecode/plate-layout': patch
'@udecode/plate-media': patch
'@udecode/plate-table': patch
'@udecode/plate-docx': patch
---

Support deserialization from PlateStatic.
17 changes: 17 additions & 0 deletions .changeset/twenty-rivers-tell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
'@udecode/plate-core': patch
---

`editor.api.html.deserialize`: Support deserialization from PlateStatic.

New: `getEditorDOMFromHtmlString` returns the editor element in html string (the one with `data-slate-editor="true"`).

New utilities for checking Slate nodes in HTML:
- `isSlateVoid`: Check if an HTML element is a Slate void node
- `isSlateElement`: Check if an HTML element is a Slate element node
- `isSlateString`: Check if an HTML element is a Slate string node
- `isSlateLeaf`: Check if an HTML element is a Slate leaf node
- `isSlateNode`: Check if an HTML element is any type of Slate node
- `isSlatePluginElement`: Check if an HTML element is a Slate element node with a specific plugin key
- `isSlatePluginNode`: Check if an HTML element has a specific plugin key class
- `getSlateElements`: Get all Slate element nodes in an HTML element
4 changes: 2 additions & 2 deletions apps/www/content/docs/cn/html.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -191,14 +191,14 @@ const html = await serializeHtml(editor, { components });

### 使用方法

The `editor.api.html.deserialize` function allows you to convert HTML content into Slate value:
`editor.api.html.deserialize` 函数允许你将 HTML 内容转换为 Slate 值:

```typescript
import { createPlateEditor } from '@udecode/plate/react';

const editor = createPlateEditor({
plugins: [
// all plugins that you want to deserialize
// 所有你想要反序列化的插件
]
})
editor.children = editor.api.html.deserialize('<p>Hello, world!</p>')
Expand Down
28 changes: 28 additions & 0 deletions apps/www/public/r/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -1922,6 +1922,34 @@
],
"type": "registry:ui"
},
{
"dependencies": [],
"doc": {
"description": "A toolbar button to import editor content from a file.",
"docs": [
{
"route": "/docs/import",
"title": "Import"
}
],
"examples": [
"basic-nodes-demo"
],
"label": "New",
"title": "Import Toolbar Button"
},
"files": [
{
"path": "plate-ui/import-toolbar-button.tsx",
"type": "registry:ui"
}
],
"name": "import-toolbar-button",
"registryDependencies": [
"toolbar"
],
"type": "registry:ui"
},
{
"dependencies": [
"@udecode/plate-caption"
Expand Down
2 changes: 1 addition & 1 deletion apps/www/public/r/styles/default/comments-demo.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"type": "registry:example"
},
{
"content": "import type { Value } from '@udecode/plate';\n\nexport const commentsValue: Value = [\n {\n children: [{ text: 'Comments' }],\n type: 'h2',\n },\n {\n children: [\n {\n text: 'Add ',\n },\n {\n comment: true,\n comment_1: true,\n text: 'comments to your content',\n },\n { text: ' to provide additional context, insights, or ' },\n {\n comment: true,\n comment_2: true,\n text: 'collaborate',\n },\n {\n text: ' with others',\n },\n ],\n type: 'p',\n },\n];\n",
"content": "import type { Value } from '@udecode/plate';\n\nexport const commentsValue: Value = [\n {\n children: [{ text: 'Comments' }],\n type: 'h2',\n },\n {\n children: [\n {\n text: 'Add ',\n },\n {\n comment: true,\n comment_1: true,\n text: 'comments to your content',\n },\n { text: ' to provide additional context, insights, or ' },\n {\n comment: true,\n comment_2: true,\n text: 'collaborate',\n },\n {\n text: ' with others',\n },\n ],\n type: 'p',\n },\n];\n",
"path": "example/values/comments-value.tsx",
"target": "components/comments-value.tsx",
"type": "registry:example"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
},
"files": [
{
"content": "'use client';\n\nimport React from 'react';\n\nimport { useEditorReadOnly } from '@udecode/plate/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n} from '@udecode/plate-font/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport {\n AudioPlugin,\n FilePlugin,\n ImagePlugin,\n VideoPlugin,\n} from '@udecode/plate-media/react';\nimport {\n ArrowUpToLineIcon,\n BaselineIcon,\n BoldIcon,\n Code2Icon,\n HighlighterIcon,\n ItalicIcon,\n PaintBucketIcon,\n StrikethroughIcon,\n UnderlineIcon,\n WandSparklesIcon,\n} from 'lucide-react';\n\nimport { MoreDropdownMenu } from '@/components/plate-ui/more-dropdown-menu';\n\nimport { AIToolbarButton } from './ai-toolbar-button';\nimport { AlignDropdownMenu } from './align-dropdown-menu';\nimport { ColorDropdownMenu } from './color-dropdown-menu';\nimport { CommentToolbarButton } from './comment-toolbar-button';\nimport { EmojiDropdownMenu } from './emoji-dropdown-menu';\nimport { ExportToolbarButton } from './export-toolbar-button';\nimport { FontSizeToolbarButton } from './font-size-toolbar-button';\nimport { RedoToolbarButton, UndoToolbarButton } from './history-toolbar-button';\nimport {\n BulletedIndentListToolbarButton,\n NumberedIndentListToolbarButton,\n} from './indent-list-toolbar-button';\nimport { IndentTodoToolbarButton } from './indent-todo-toolbar-button';\nimport { IndentToolbarButton } from './indent-toolbar-button';\nimport { InsertDropdownMenu } from './insert-dropdown-menu';\nimport { LineHeightDropdownMenu } from './line-height-dropdown-menu';\nimport { LinkToolbarButton } from './link-toolbar-button';\nimport { MarkToolbarButton } from './mark-toolbar-button';\nimport { MediaToolbarButton } from './media-toolbar-button';\nimport { ModeDropdownMenu } from './mode-dropdown-menu';\nimport { OutdentToolbarButton } from './outdent-toolbar-button';\nimport { TableDropdownMenu } from './table-dropdown-menu';\nimport { ToggleToolbarButton } from './toggle-toolbar-button';\nimport { ToolbarGroup } from './toolbar';\nimport { TurnIntoDropdownMenu } from './turn-into-dropdown-menu';\n\nexport function FixedToolbarButtons() {\n const readOnly = useEditorReadOnly();\n\n return (\n <div className=\"flex w-full\">\n {!readOnly && (\n <>\n <ToolbarGroup>\n <UndoToolbarButton />\n <RedoToolbarButton />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <AIToolbarButton tooltip=\"AI commands\">\n <WandSparklesIcon />\n </AIToolbarButton>\n </ToolbarGroup>\n\n <ToolbarGroup>\n <ExportToolbarButton>\n <ArrowUpToLineIcon />\n </ExportToolbarButton>\n </ToolbarGroup>\n\n <ToolbarGroup>\n <InsertDropdownMenu />\n <TurnIntoDropdownMenu />\n <FontSizeToolbarButton />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <MarkToolbarButton nodeType={BoldPlugin.key} tooltip=\"Bold (⌘+B)\">\n <BoldIcon />\n </MarkToolbarButton>\n\n <MarkToolbarButton\n nodeType={ItalicPlugin.key}\n tooltip=\"Italic (⌘+I)\"\n >\n <ItalicIcon />\n </MarkToolbarButton>\n\n <MarkToolbarButton\n nodeType={UnderlinePlugin.key}\n tooltip=\"Underline (⌘+U)\"\n >\n <UnderlineIcon />\n </MarkToolbarButton>\n\n <MarkToolbarButton\n nodeType={StrikethroughPlugin.key}\n tooltip=\"Strikethrough (⌘+⇧+M)\"\n >\n <StrikethroughIcon />\n </MarkToolbarButton>\n\n <MarkToolbarButton nodeType={CodePlugin.key} tooltip=\"Code (⌘+E)\">\n <Code2Icon />\n </MarkToolbarButton>\n\n <ColorDropdownMenu\n nodeType={FontColorPlugin.key}\n tooltip=\"Text color\"\n >\n <BaselineIcon />\n </ColorDropdownMenu>\n\n <ColorDropdownMenu\n nodeType={FontBackgroundColorPlugin.key}\n tooltip=\"Background color\"\n >\n <PaintBucketIcon />\n </ColorDropdownMenu>\n </ToolbarGroup>\n\n <ToolbarGroup>\n <AlignDropdownMenu />\n\n <NumberedIndentListToolbarButton />\n <BulletedIndentListToolbarButton />\n <IndentTodoToolbarButton />\n <ToggleToolbarButton />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <LinkToolbarButton />\n <TableDropdownMenu />\n <EmojiDropdownMenu />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <MediaToolbarButton nodeType={ImagePlugin.key} />\n <MediaToolbarButton nodeType={VideoPlugin.key} />\n <MediaToolbarButton nodeType={AudioPlugin.key} />\n <MediaToolbarButton nodeType={FilePlugin.key} />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <LineHeightDropdownMenu />\n <OutdentToolbarButton />\n <IndentToolbarButton />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <MoreDropdownMenu />\n </ToolbarGroup>\n </>\n )}\n\n <div className=\"grow\" />\n\n <ToolbarGroup>\n <MarkToolbarButton nodeType={HighlightPlugin.key} tooltip=\"Highlight\">\n <HighlighterIcon />\n </MarkToolbarButton>\n <CommentToolbarButton />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <ModeDropdownMenu />\n </ToolbarGroup>\n </div>\n );\n}\n",
"content": "'use client';\n\nimport React from 'react';\n\nimport { useEditorReadOnly } from '@udecode/plate/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n} from '@udecode/plate-font/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport {\n AudioPlugin,\n FilePlugin,\n ImagePlugin,\n VideoPlugin,\n} from '@udecode/plate-media/react';\nimport {\n ArrowUpToLineIcon,\n BaselineIcon,\n BoldIcon,\n Code2Icon,\n HighlighterIcon,\n ItalicIcon,\n PaintBucketIcon,\n StrikethroughIcon,\n UnderlineIcon,\n WandSparklesIcon,\n} from 'lucide-react';\n\nimport { MoreDropdownMenu } from '@/components/plate-ui/more-dropdown-menu';\n\nimport { AIToolbarButton } from './ai-toolbar-button';\nimport { AlignDropdownMenu } from './align-dropdown-menu';\nimport { ColorDropdownMenu } from './color-dropdown-menu';\nimport { CommentToolbarButton } from './comment-toolbar-button';\nimport { EmojiDropdownMenu } from './emoji-dropdown-menu';\nimport { ExportToolbarButton } from './export-toolbar-button';\nimport { FontSizeToolbarButton } from './font-size-toolbar-button';\nimport { RedoToolbarButton, UndoToolbarButton } from './history-toolbar-button';\nimport { ImportToolbarButton } from './import-toolbar-button';\nimport {\n BulletedIndentListToolbarButton,\n NumberedIndentListToolbarButton,\n} from './indent-list-toolbar-button';\nimport { IndentTodoToolbarButton } from './indent-todo-toolbar-button';\nimport { IndentToolbarButton } from './indent-toolbar-button';\nimport { InsertDropdownMenu } from './insert-dropdown-menu';\nimport { LineHeightDropdownMenu } from './line-height-dropdown-menu';\nimport { LinkToolbarButton } from './link-toolbar-button';\nimport { MarkToolbarButton } from './mark-toolbar-button';\nimport { MediaToolbarButton } from './media-toolbar-button';\nimport { ModeDropdownMenu } from './mode-dropdown-menu';\nimport { OutdentToolbarButton } from './outdent-toolbar-button';\nimport { TableDropdownMenu } from './table-dropdown-menu';\nimport { ToggleToolbarButton } from './toggle-toolbar-button';\nimport { ToolbarGroup } from './toolbar';\nimport { TurnIntoDropdownMenu } from './turn-into-dropdown-menu';\n\nexport function FixedToolbarButtons() {\n const readOnly = useEditorReadOnly();\n\n return (\n <div className=\"flex w-full\">\n {!readOnly && (\n <>\n <ToolbarGroup>\n <UndoToolbarButton />\n <RedoToolbarButton />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <AIToolbarButton tooltip=\"AI commands\">\n <WandSparklesIcon />\n </AIToolbarButton>\n </ToolbarGroup>\n\n <ToolbarGroup>\n <ExportToolbarButton>\n <ArrowUpToLineIcon />\n </ExportToolbarButton>\n\n <ImportToolbarButton />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <InsertDropdownMenu />\n <TurnIntoDropdownMenu />\n <FontSizeToolbarButton />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <MarkToolbarButton nodeType={BoldPlugin.key} tooltip=\"Bold (⌘+B)\">\n <BoldIcon />\n </MarkToolbarButton>\n\n <MarkToolbarButton\n nodeType={ItalicPlugin.key}\n tooltip=\"Italic (⌘+I)\"\n >\n <ItalicIcon />\n </MarkToolbarButton>\n\n <MarkToolbarButton\n nodeType={UnderlinePlugin.key}\n tooltip=\"Underline (⌘+U)\"\n >\n <UnderlineIcon />\n </MarkToolbarButton>\n\n <MarkToolbarButton\n nodeType={StrikethroughPlugin.key}\n tooltip=\"Strikethrough (⌘+⇧+M)\"\n >\n <StrikethroughIcon />\n </MarkToolbarButton>\n\n <MarkToolbarButton nodeType={CodePlugin.key} tooltip=\"Code (⌘+E)\">\n <Code2Icon />\n </MarkToolbarButton>\n\n <ColorDropdownMenu\n nodeType={FontColorPlugin.key}\n tooltip=\"Text color\"\n >\n <BaselineIcon />\n </ColorDropdownMenu>\n\n <ColorDropdownMenu\n nodeType={FontBackgroundColorPlugin.key}\n tooltip=\"Background color\"\n >\n <PaintBucketIcon />\n </ColorDropdownMenu>\n </ToolbarGroup>\n\n <ToolbarGroup>\n <AlignDropdownMenu />\n\n <NumberedIndentListToolbarButton />\n <BulletedIndentListToolbarButton />\n <IndentTodoToolbarButton />\n <ToggleToolbarButton />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <LinkToolbarButton />\n <TableDropdownMenu />\n <EmojiDropdownMenu />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <MediaToolbarButton nodeType={ImagePlugin.key} />\n <MediaToolbarButton nodeType={VideoPlugin.key} />\n <MediaToolbarButton nodeType={AudioPlugin.key} />\n <MediaToolbarButton nodeType={FilePlugin.key} />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <LineHeightDropdownMenu />\n <OutdentToolbarButton />\n <IndentToolbarButton />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <MoreDropdownMenu />\n </ToolbarGroup>\n </>\n )}\n\n <div className=\"grow\" />\n\n <ToolbarGroup>\n <MarkToolbarButton nodeType={HighlightPlugin.key} tooltip=\"Highlight\">\n <HighlighterIcon />\n </MarkToolbarButton>\n <CommentToolbarButton />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <ModeDropdownMenu />\n </ToolbarGroup>\n </div>\n );\n}\n",
"path": "plate-ui/fixed-toolbar-buttons.tsx",
"target": "components/plate-ui/fixed-toolbar-buttons.tsx",
"type": "registry:ui"
Expand Down
2 changes: 1 addition & 1 deletion apps/www/public/r/styles/default/horizontal-rule-demo.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"type": "registry:example"
},
{
"content": "import { BaseHorizontalRulePlugin } from '@udecode/plate-horizontal-rule';\nimport { jsx } from '@udecode/plate-test-utils';\n\njsx;\n\nexport const horizontalRuleValue: any = (\n <fragment>\n <hh2>Horizontal Rule</hh2>\n <hp>\n Add horizontal rules to visually separate sections and content within your\n document.\n </hp>\n <element type={BaseHorizontalRulePlugin.key}>\n <htext />\n </element>\n </fragment>\n);\n",
"content": "import { BaseHorizontalRulePlugin } from '@udecode/plate-horizontal-rule';\nimport { jsx } from '@udecode/plate-test-utils';\n\njsx;\n\nexport const horizontalRuleValue: any = (\n <fragment>\n <hh2>Horizontal Rule</hh2>\n {/* <hp>\n Add horizontal rules to visually separate sections and content within your\n document.\n </hp> */}\n <element type={BaseHorizontalRulePlugin.key}>\n <htext />\n </element>\n </fragment>\n);\n",
"path": "example/values/horizontal-rule-value.tsx",
"target": "components/horizontal-rule-value.tsx",
"type": "registry:example"
Expand Down
2 changes: 1 addition & 1 deletion apps/www/public/r/styles/default/hr-element.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"type": "registry:ui"
},
{
"content": "import React from 'react';\n\nimport type { SlateElementProps } from '@udecode/plate';\n\nimport { cn } from '@udecode/cn';\nimport { SlateElement } from '@udecode/plate';\n\nexport function HrElementStatic({\n children,\n className,\n nodeProps,\n ...props\n}: SlateElementProps) {\n return (\n <SlateElement className={className} {...props}>\n <div className=\"cursor-text py-6\" contentEditable={false}>\n <hr\n {...nodeProps}\n className={cn(\n 'h-0.5 rounded-sm border-none bg-muted bg-clip-content'\n )}\n />\n </div>\n {children}\n </SlateElement>\n );\n}\n",
"content": "import React from 'react';\n\nimport type { SlateElementProps } from '@udecode/plate';\n\nimport { cn } from '@udecode/cn';\nimport { SlateElement } from '@udecode/plate';\n\nexport function HrElementStatic({\n children,\n className,\n nodeProps,\n ...props\n}: SlateElementProps) {\n return (\n <SlateElement className={className} nodeProps={nodeProps} {...props}>\n <div className=\"cursor-text py-6\" contentEditable={false}>\n <hr\n {...nodeProps}\n className={cn(\n 'h-0.5 rounded-sm border-none bg-muted bg-clip-content'\n )}\n />\n </div>\n {children}\n </SlateElement>\n );\n}\n",
"path": "plate-ui/hr-element-static.tsx",
"target": "components/plate-ui/hr-element-static.tsx",
"type": "registry:ui"
Expand Down
Loading
Loading