Skip to content

Commit

Permalink
docs
Browse files Browse the repository at this point in the history
  • Loading branch information
felixfeng33 authored Dec 20, 2024
1 parent 2e25ff7 commit 732fefc
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
},
"files": [
{
"content": "'use client';\n\nimport React from 'react';\n\nimport type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';\n\nimport { toDOMNode, useEditorRef } from '@udecode/plate-common/react';\nimport { ArrowDownToLineIcon } from 'lucide-react';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport { ToolbarButton } from './toolbar';\n\nexport function ExportToolbarButton({ children, ...props }: DropdownMenuProps) {\n const editor = useEditorRef();\n const openState = useOpenState();\n\n const getCanvas = async () => {\n const { default: html2canvas } = await import('html2canvas');\n\n const style = document.createElement('style');\n document.head.append(style);\n style.sheet?.insertRule(\n 'body > div:last-child img { display: inline-block !important; }'\n );\n\n const canvas = await html2canvas(toDOMNode(editor, editor)!);\n style.remove();\n\n return canvas;\n };\n\n const downloadFile = (href: string, filename: string) => {\n const element = document.createElement('a');\n element.setAttribute('href', href);\n element.setAttribute('download', filename);\n element.style.display = 'none';\n document.body.append(element);\n element.click();\n element.remove();\n };\n\n const exportToPdf = async () => {\n const canvas = await getCanvas();\n\n const PDFLib = await import('pdf-lib');\n const pdfDoc = await PDFLib.PDFDocument.create();\n const page = pdfDoc.addPage([canvas.width, canvas.height]);\n const imageEmbed = await pdfDoc.embedPng(canvas.toDataURL('PNG'));\n const { height, width } = imageEmbed.scale(1);\n page.drawImage(imageEmbed, {\n height,\n width,\n x: 0,\n y: 0,\n });\n const pdfBase64 = await pdfDoc.saveAsBase64({ dataUri: true });\n\n downloadFile(pdfBase64, 'plate.pdf');\n };\n\n const exportToImage = async () => {\n const canvas = await getCanvas();\n downloadFile(canvas.toDataURL('image/png'), 'plate.png');\n };\n\n return (\n <DropdownMenu modal={false} {...openState} {...props}>\n <DropdownMenuTrigger asChild>\n <ToolbarButton pressed={openState.open} tooltip=\"Export\" isDropdown>\n <ArrowDownToLineIcon className=\"size-4\" />\n </ToolbarButton>\n </DropdownMenuTrigger>\n\n <DropdownMenuContent align=\"start\">\n <DropdownMenuGroup>\n <DropdownMenuItem onSelect={exportToPdf}>\n Export as PDF\n </DropdownMenuItem>\n <DropdownMenuItem onSelect={exportToImage}>\n Export as Image\n </DropdownMenuItem>\n </DropdownMenuGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n",
"content": "'use client';\n\nimport React from 'react';\n\nimport type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';\n\nimport { withProps } from '@udecode/cn';\nimport { BaseAlignPlugin } from '@udecode/plate-alignment';\nimport {\n BaseBoldPlugin,\n BaseCodePlugin,\n BaseItalicPlugin,\n BaseStrikethroughPlugin,\n BaseSubscriptPlugin,\n BaseSuperscriptPlugin,\n BaseUnderlinePlugin,\n} from '@udecode/plate-basic-marks';\nimport { BaseBlockquotePlugin } from '@udecode/plate-block-quote';\nimport {\n BaseCodeBlockPlugin,\n BaseCodeLinePlugin,\n BaseCodeSyntaxPlugin,\n} from '@udecode/plate-code-block';\nimport { BaseCommentsPlugin } from '@udecode/plate-comments';\nimport {\n BaseParagraphPlugin,\n SlateLeaf,\n createSlateEditor,\n serializeHtml,\n} from '@udecode/plate-common';\nimport { toDOMNode, useEditorRef } from '@udecode/plate-common/react';\nimport { BaseDatePlugin } from '@udecode/plate-date';\nimport {\n BaseFontBackgroundColorPlugin,\n BaseFontColorPlugin,\n BaseFontSizePlugin,\n} from '@udecode/plate-font';\nimport {\n BaseHeadingPlugin,\n BaseTocPlugin,\n HEADING_KEYS,\n HEADING_LEVELS,\n} from '@udecode/plate-heading';\nimport { BaseHighlightPlugin } from '@udecode/plate-highlight';\nimport { BaseHorizontalRulePlugin } from '@udecode/plate-horizontal-rule';\nimport { BaseIndentPlugin } from '@udecode/plate-indent';\nimport { BaseIndentListPlugin } from '@udecode/plate-indent-list';\nimport { BaseKbdPlugin } from '@udecode/plate-kbd';\nimport { BaseColumnItemPlugin, BaseColumnPlugin } from '@udecode/plate-layout';\nimport { BaseLineHeightPlugin } from '@udecode/plate-line-height';\nimport { BaseLinkPlugin } from '@udecode/plate-link';\nimport {\n BaseAudioPlugin,\n BaseFilePlugin,\n BaseImagePlugin,\n BaseMediaEmbedPlugin,\n BaseVideoPlugin,\n} from '@udecode/plate-media';\nimport { BaseMentionPlugin } from '@udecode/plate-mention';\nimport {\n BaseTableCellHeaderPlugin,\n BaseTableCellPlugin,\n BaseTablePlugin,\n BaseTableRowPlugin,\n} from '@udecode/plate-table';\nimport { BaseTogglePlugin } from '@udecode/plate-toggle';\nimport { ArrowDownToLineIcon } from 'lucide-react';\nimport Prism from 'prismjs';\n\nimport { BlockquoteElementStatic } from '@/components/plate-ui/blockquote-element-static';\nimport { CodeBlockElementStatic } from '@/components/plate-ui/code-block-element-static';\nimport { CodeLeafStatic } from '@/components/plate-ui/code-leaf-static';\nimport { CodeLineElementStatic } from '@/components/plate-ui/code-line-element-static';\nimport { CodeSyntaxLeafStatic } from '@/components/plate-ui/code-syntax-leaf-static';\nimport { ColumnElementStatic } from '@/components/plate-ui/column-element-static';\nimport { ColumnGroupElementStatic } from '@/components/plate-ui/column-group-element-static';\nimport { CommentLeafStatic } from '@/components/plate-ui/comment-leaf-static';\nimport { DateElementStatic } from '@/components/plate-ui/date-element-static';\nimport { HeadingElementStatic } from '@/components/plate-ui/heading-element-static';\nimport { HighlightLeafStatic } from '@/components/plate-ui/highlight-leaf-static';\nimport { HrElementStatic } from '@/components/plate-ui/hr-element-static';\nimport { ImageElementStatic } from '@/components/plate-ui/image-element-static';\nimport {\n FireLiComponent,\n FireMarker,\n} from '@/components/plate-ui/indent-fire-marker';\nimport {\n TodoLiStatic,\n TodoMarkerStatic,\n} from '@/components/plate-ui/indent-todo-marker-static';\nimport { KbdLeafStatic } from '@/components/plate-ui/kbd-leaf-static';\nimport { LinkElementStatic } from '@/components/plate-ui/link-element-static';\nimport { MediaAudioElementStatic } from '@/components/plate-ui/media-audio-element-static';\nimport { MediaFileElementStatic } from '@/components/plate-ui/media-file-element-static';\nimport { MediaVideoElementStatic } from '@/components/plate-ui/media-video-element-static';\nimport { MentionElementStatic } from '@/components/plate-ui/mention-element-static';\nimport { ParagraphElementStatic } from '@/components/plate-ui/paragraph-element-static';\nimport {\n TableCellElementStatic,\n TableCellHeaderStaticElement,\n} from '@/components/plate-ui/table-cell-element-static';\nimport { TableElementStatic } from '@/components/plate-ui/table-element-static';\nimport { TableRowElementStatic } from '@/components/plate-ui/table-row-element-static';\nimport { TocElementStatic } from '@/components/plate-ui/toc-element-static';\nimport { ToggleElementStatic } from '@/components/plate-ui/toggle-element-static';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport { EditorStatic } from './editor-static';\nimport { ToolbarButton } from './toolbar';\n\nexport function ExportToolbarButton({ children, ...props }: DropdownMenuProps) {\n const editor = useEditorRef();\n const openState = useOpenState();\n\n const getCanvas = async () => {\n const { default: html2canvas } = await import('html2canvas');\n\n const style = document.createElement('style');\n document.head.append(style);\n style.sheet?.insertRule(\n 'body > div:last-child img { display: inline-block !important; }'\n );\n\n const canvas = await html2canvas(toDOMNode(editor, editor)!);\n style.remove();\n\n return canvas;\n };\n\n const downloadFile = ({\n content,\n filename,\n isHtml = false,\n }: {\n content: string;\n filename: string;\n isHtml?: boolean;\n }) => {\n const element = document.createElement('a');\n const href = isHtml\n ? `data:text/html;charset=utf-8,${encodeURIComponent(content)}`\n : content;\n element.setAttribute('href', href);\n element.setAttribute('download', filename);\n element.style.display = 'none';\n document.body.append(element);\n element.click();\n element.remove();\n };\n\n const exportToPdf = async () => {\n const canvas = await getCanvas();\n\n const PDFLib = await import('pdf-lib');\n const pdfDoc = await PDFLib.PDFDocument.create();\n const page = pdfDoc.addPage([canvas.width, canvas.height]);\n const imageEmbed = await pdfDoc.embedPng(canvas.toDataURL('PNG'));\n const { height, width } = imageEmbed.scale(1);\n page.drawImage(imageEmbed, {\n height,\n width,\n x: 0,\n y: 0,\n });\n const pdfBase64 = await pdfDoc.saveAsBase64({ dataUri: true });\n\n downloadFile({ content: pdfBase64, filename: 'plate.pdf' });\n };\n\n const exportToImage = async () => {\n const canvas = await getCanvas();\n downloadFile({\n content: canvas.toDataURL('image/png'),\n filename: 'plate.png',\n });\n };\n\n const exportToHtml = async () => {\n const components = {\n [BaseAudioPlugin.key]: MediaAudioElementStatic,\n [BaseBlockquotePlugin.key]: BlockquoteElementStatic,\n [BaseBoldPlugin.key]: withProps(SlateLeaf, { as: 'strong' }),\n [BaseCodeBlockPlugin.key]: CodeBlockElementStatic,\n [BaseCodeLinePlugin.key]: CodeLineElementStatic,\n [BaseCodePlugin.key]: CodeLeafStatic,\n [BaseCodeSyntaxPlugin.key]: CodeSyntaxLeafStatic,\n [BaseColumnItemPlugin.key]: ColumnElementStatic,\n [BaseColumnPlugin.key]: ColumnGroupElementStatic,\n [BaseCommentsPlugin.key]: CommentLeafStatic,\n [BaseDatePlugin.key]: DateElementStatic,\n [BaseFilePlugin.key]: MediaFileElementStatic,\n [BaseHighlightPlugin.key]: HighlightLeafStatic,\n [BaseHorizontalRulePlugin.key]: HrElementStatic,\n [BaseImagePlugin.key]: ImageElementStatic,\n [BaseItalicPlugin.key]: withProps(SlateLeaf, { as: 'em' }),\n [BaseKbdPlugin.key]: KbdLeafStatic,\n [BaseLinkPlugin.key]: LinkElementStatic,\n // [BaseMediaEmbedPlugin.key]: MediaEmbedElementStatic,\n [BaseMentionPlugin.key]: MentionElementStatic,\n [BaseParagraphPlugin.key]: ParagraphElementStatic,\n [BaseStrikethroughPlugin.key]: withProps(SlateLeaf, { as: 'del' }),\n [BaseSubscriptPlugin.key]: withProps(SlateLeaf, { as: 'sub' }),\n [BaseSuperscriptPlugin.key]: withProps(SlateLeaf, { as: 'sup' }),\n [BaseTableCellHeaderPlugin.key]: TableCellHeaderStaticElement,\n [BaseTableCellPlugin.key]: TableCellElementStatic,\n [BaseTablePlugin.key]: TableElementStatic,\n [BaseTableRowPlugin.key]: TableRowElementStatic,\n [BaseTocPlugin.key]: TocElementStatic,\n [BaseTogglePlugin.key]: ToggleElementStatic,\n [BaseUnderlinePlugin.key]: withProps(SlateLeaf, { as: 'u' }),\n [BaseVideoPlugin.key]: MediaVideoElementStatic,\n [HEADING_KEYS.h1]: withProps(HeadingElementStatic, { variant: 'h1' }),\n [HEADING_KEYS.h2]: withProps(HeadingElementStatic, { variant: 'h2' }),\n [HEADING_KEYS.h3]: withProps(HeadingElementStatic, { variant: 'h3' }),\n [HEADING_KEYS.h4]: withProps(HeadingElementStatic, { variant: 'h4' }),\n [HEADING_KEYS.h5]: withProps(HeadingElementStatic, { variant: 'h5' }),\n [HEADING_KEYS.h6]: withProps(HeadingElementStatic, { variant: 'h6' }),\n };\n\n const editorStatic = createSlateEditor({\n plugins: [\n BaseColumnPlugin,\n BaseColumnItemPlugin,\n BaseTocPlugin,\n BaseVideoPlugin,\n BaseAudioPlugin,\n BaseParagraphPlugin,\n BaseHeadingPlugin,\n BaseMediaEmbedPlugin,\n BaseBoldPlugin,\n BaseCodePlugin,\n BaseItalicPlugin,\n BaseStrikethroughPlugin,\n BaseSubscriptPlugin,\n BaseSuperscriptPlugin,\n BaseUnderlinePlugin,\n BaseBlockquotePlugin,\n BaseDatePlugin,\n BaseCodeBlockPlugin.configure({\n options: {\n prism: Prism,\n },\n }),\n BaseIndentPlugin.extend({\n inject: {\n targetPlugins: [\n BaseParagraphPlugin.key,\n BaseBlockquotePlugin.key,\n BaseCodeBlockPlugin.key,\n ],\n },\n }),\n BaseIndentListPlugin.extend({\n inject: {\n targetPlugins: [\n BaseParagraphPlugin.key,\n ...HEADING_LEVELS,\n BaseBlockquotePlugin.key,\n BaseCodeBlockPlugin.key,\n BaseTogglePlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n fire: {\n liComponent: FireLiComponent,\n markerComponent: FireMarker,\n type: 'fire',\n },\n todo: {\n liComponent: TodoLiStatic,\n markerComponent: TodoMarkerStatic,\n type: 'todo',\n },\n },\n },\n }),\n BaseLinkPlugin,\n BaseTableRowPlugin,\n BaseTablePlugin,\n BaseTableCellPlugin,\n BaseHorizontalRulePlugin,\n BaseFontColorPlugin,\n BaseFontBackgroundColorPlugin,\n BaseFontSizePlugin,\n BaseKbdPlugin,\n BaseAlignPlugin.extend({\n inject: {\n targetPlugins: [\n BaseParagraphPlugin.key,\n BaseMediaEmbedPlugin.key,\n ...HEADING_LEVELS,\n BaseImagePlugin.key,\n ],\n },\n }),\n BaseLineHeightPlugin,\n BaseHighlightPlugin,\n BaseFilePlugin,\n BaseImagePlugin,\n BaseMentionPlugin,\n BaseCommentsPlugin,\n BaseTogglePlugin,\n ],\n value: editor.children,\n });\n\n const editorHtml = await serializeHtml(editorStatic, {\n components,\n editorComponent: EditorStatic,\n props: { style: { padding: '0 calc(50% - 350px)', paddingBottom: '' } },\n });\n\n const prismCss = `<link rel=\"stylesheet\" href=\"https://platejs.org/_next/static/css/274e256ca08ece78.css\">`;\n const tailwindCss = `\n <link rel=\"stylesheet\" href=\"https://platejs.org/_next/static/css/4d3ab7d3f144d56d.css\">\n <link rel=\"stylesheet\" href=\"https://platejs.org/_next/static/css/e8dd5394bd410c4c.css\"> \n `;\n\n const html = `<!DOCTYPE html>\n <html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <meta name=\"color-scheme\" content=\"light dark\" />\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin />\n <link\n href=\"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;700&display=swap\"\n rel=\"stylesheet\"\n />\n ${tailwindCss}\n ${prismCss}\n <style>\n :root {\n --font-sans: 'Inter', sans-serif;\n --font-mono: 'JetBrains Mono', monospace;\n }\n </style>\n </head>\n <body>\n ${editorHtml}\n </body>\n </html>`;\n\n downloadFile({ content: html, filename: 'plate.html', isHtml: true });\n };\n\n return (\n <DropdownMenu modal={false} {...openState} {...props}>\n <DropdownMenuTrigger asChild>\n <ToolbarButton pressed={openState.open} tooltip=\"Export\" isDropdown>\n <ArrowDownToLineIcon className=\"size-4\" />\n </ToolbarButton>\n </DropdownMenuTrigger>\n\n <DropdownMenuContent align=\"start\">\n <DropdownMenuGroup>\n <DropdownMenuItem onSelect={exportToHtml}>\n Export as HTML\n </DropdownMenuItem>\n <DropdownMenuItem onSelect={exportToPdf}>\n Export as PDF\n </DropdownMenuItem>\n <DropdownMenuItem onSelect={exportToImage}>\n Export as Image\n </DropdownMenuItem>\n </DropdownMenuGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n",
"path": "plate-ui/export-toolbar-button.tsx",
"target": "components/plate-ui/export-toolbar-button.tsx",
"type": "registry:ui"
Expand Down
Loading

0 comments on commit 732fefc

Please sign in to comment.