diff --git a/apps/www/content/docs/components/changelog.mdx b/apps/www/content/docs/components/changelog.mdx index ee862f88eb..ab56ac564a 100644 --- a/apps/www/content/docs/components/changelog.mdx +++ b/apps/www/content/docs/components/changelog.mdx @@ -10,6 +10,46 @@ Use the [CLI](https://platejs.org/docs/components/cli) to install the latest ver ## December 2024 #17 +### December 21 #17.4 + +Update `tailwind.config.cjs` for better font support in the HTML export: + +```ts +fontFamily: { + heading: [ + 'var(--font-heading)', + 'ui-sans-serif', + '-apple-system', + 'BlinkMacSystemFont', + 'Segoe UI Variable Display', + 'Segoe UI', + 'Helvetica', + 'Apple Color Emoji', + 'Arial', + 'sans-serif', + 'Segoe UI Emoji', + 'Segoe UI Symbol', + 'Noto Color Emoji', + ], + mono: ['var(--font-mono)', ...fontFamily.mono], + sans: [ + 'var(--font-sans)', + 'ui-sans-serif', + '-apple-system', + 'BlinkMacSystemFont', + 'Segoe UI Variable Display', + 'Segoe UI', + 'Helvetica', + 'Apple Color Emoji', + 'Arial', + 'sans-serif', + 'Segoe UI Emoji', + 'Segoe UI Symbol', + 'Noto Color Emoji', + ], +``` + + ### December 20 #17.3 - `insertColumnGroup`, `toggleColumnGroup`: use `columns` option instead of `layout` diff --git a/apps/www/public/r/styles/default/export-toolbar-button.json b/apps/www/public/r/styles/default/export-toolbar-button.json index 9b101bcf62..c5c9cdd268 100644 --- a/apps/www/public/r/styles/default/export-toolbar-button.json +++ b/apps/www/public/r/styles/default/export-toolbar-button.json @@ -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 { 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\nconst siteUrl = 'https://platejs.org';\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 = ``;\n const tailwindCss = ``;\n\n const html = `\n \n \n \n \n \n \n \n \n ${tailwindCss}\n ${prismCss}\n \n \n \n ${editorHtml}\n \n `;\n\n downloadFile({ content: html, filename: 'plate.html', isHtml: true });\n };\n\n return (\n \n \n \n \n \n \n\n \n \n \n Export as HTML\n \n \n Export as PDF\n \n \n Export as Image\n \n \n \n \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\nconst siteUrl = 'https://platejs.org';\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 = ``;\n const tailwindCss = ``;\n\n const html = `\n \n \n \n \n \n \n \n \n ${tailwindCss}\n ${prismCss}\n \n \n \n ${editorHtml}\n \n `;\n\n downloadFile({ content: html, filename: 'plate.html', isHtml: true });\n };\n\n return (\n \n \n \n \n \n \n\n \n \n \n Export as HTML\n \n \n Export as PDF\n \n \n Export as Image\n \n \n \n \n );\n}\n", "path": "plate-ui/export-toolbar-button.tsx", "target": "components/plate-ui/export-toolbar-button.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/index.json b/apps/www/public/r/styles/default/index.json index aeafcf6bee..990a108c3a 100644 --- a/apps/www/public/r/styles/default/index.json +++ b/apps/www/public/r/styles/default/index.json @@ -23,6 +23,42 @@ ], "theme": { "extend": { + "fontFamily": { + "heading": [ + "var(--font-heading)", + "ui-sans-serif", + "-apple-system", + "BlinkMacSystemFont", + "Segoe UI Variable Display", + "Segoe UI", + "Helvetica", + "Apple Color Emoji", + "Arial", + "sans-serif", + "Segoe UI Emoji", + "Segoe UI Symbol", + "Noto Color Emoji" + ], + "mono": [ + "var(--font-mono)", + "...require(\"tailwindcss/defaultTheme\").fontFamily.mono" + ], + "sans": [ + "var(--font-sans)", + "ui-sans-serif", + "-apple-system", + "BlinkMacSystemFont", + "Segoe UI Variable Display", + "Segoe UI", + "Helvetica", + "Apple Color Emoji", + "Arial", + "sans-serif", + "Segoe UI Emoji", + "Segoe UI Symbol", + "Noto Color Emoji" + ] + }, "colors": { "brand": { "DEFAULT": "hsl(var(--brand))", diff --git a/apps/www/scripts/build-registry.mts b/apps/www/scripts/build-registry.mts index 8cc0f540a8..6ad631d2df 100644 --- a/apps/www/scripts/build-registry.mts +++ b/apps/www/scripts/build-registry.mts @@ -527,6 +527,39 @@ async function buildStylesIndex() { plugins: [`require("tailwindcss-animate")`, `require("tailwind-scrollbar-hide")`], theme: { extend: { + fontFamily: { + heading: [ + 'var(--font-heading)', + 'ui-sans-serif', + '-apple-system', + 'BlinkMacSystemFont', + 'Segoe UI Variable Display', + 'Segoe UI', + 'Helvetica', + 'Apple Color Emoji', + 'Arial', + 'sans-serif', + 'Segoe UI Emoji', + 'Segoe UI Symbol', + 'Noto Color Emoji', + ], + mono: ['var(--font-mono)', `...require("tailwindcss/defaultTheme").fontFamily.mono`], + sans: [ + 'var(--font-sans)', + 'ui-sans-serif', + '-apple-system', + 'BlinkMacSystemFont', + 'Segoe UI Variable Display', + 'Segoe UI', + 'Helvetica', + 'Apple Color Emoji', + 'Arial', + 'sans-serif', + 'Segoe UI Emoji', + 'Segoe UI Symbol', + 'Noto Color Emoji', + ], + }, colors: { brand: { DEFAULT: 'hsl(var(--brand))', diff --git a/apps/www/src/registry/default/lib/create-html-document.ts b/apps/www/src/registry/default/lib/create-html-document.ts index 3383dd4a7b..ddf1df590c 100644 --- a/apps/www/src/registry/default/lib/create-html-document.ts +++ b/apps/www/src/registry/default/lib/create-html-document.ts @@ -20,13 +20,13 @@ export function createHtmlDocument({ diff --git a/apps/www/src/registry/default/plate-ui/export-toolbar-button.tsx b/apps/www/src/registry/default/plate-ui/export-toolbar-button.tsx index 1358a9512b..b774fbabd7 100644 --- a/apps/www/src/registry/default/plate-ui/export-toolbar-button.tsx +++ b/apps/www/src/registry/default/plate-ui/export-toolbar-button.tsx @@ -332,15 +332,15 @@ export function ExportToolbarButton({ children, ...props }: DropdownMenuProps) { ${tailwindCss} ${prismCss} diff --git a/tailwind.config.cjs b/tailwind.config.cjs index 5dace29d89..38e8c90380 100644 --- a/tailwind.config.cjs +++ b/tailwind.config.cjs @@ -1,4 +1,3 @@ -const { fontFamily } = require('tailwindcss/defaultTheme'); const plugin = require('tailwindcss/plugin'); /** @type {import('tailwindcss').Config} */ @@ -86,9 +85,40 @@ module.exports = { }, }, fontFamily: { - heading: ['var(--font-heading)', ...fontFamily.sans], - mono: ['var(--font-mono)', ...fontFamily.mono], - sans: ['var(--font-sans)', ...fontFamily.sans], + heading: [ + 'var(--font-heading)', + 'ui-sans-serif', + '-apple-system', + 'BlinkMacSystemFont', + 'Segoe UI Variable Display', + 'Segoe UI', + 'Helvetica', + 'Apple Color Emoji', + 'Arial', + 'sans-serif', + 'Segoe UI Emoji', + 'Segoe UI Symbol', + 'Noto Color Emoji', + ], + mono: [ + 'var(--font-mono)', + ...require('tailwindcss/defaultTheme').fontFamily.mono, + ], + sans: [ + 'var(--font-sans)', + 'ui-sans-serif', + '-apple-system', + 'BlinkMacSystemFont', + 'Segoe UI Variable Display', + 'Segoe UI', + 'Helvetica', + 'Apple Color Emoji', + 'Arial', + 'sans-serif', + 'Segoe UI Emoji', + 'Segoe UI Symbol', + 'Noto Color Emoji', + ], }, keyframes: { 'accordion-down': {