Skip to content

Commit

Permalink
sync
Browse files Browse the repository at this point in the history
  • Loading branch information
felixfeng33 committed Nov 26, 2024
1 parent f41f771 commit 6a864cb
Show file tree
Hide file tree
Showing 15 changed files with 193 additions and 15 deletions.
3 changes: 2 additions & 1 deletion apps/www/public/r/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -1975,7 +1975,8 @@
"outdent-toolbar-button",
"table-dropdown-menu",
"toggle-toolbar-button",
"turn-into-dropdown-menu"
"turn-into-dropdown-menu",
"export-toolbar-button"
],
"type": "registry:ui"
},
Expand Down
2 changes: 1 addition & 1 deletion apps/www/public/r/styles/default/editor.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
},
"files": [
{
"content": "'use client';\n\nimport React from 'react';\n\nimport type { PlateContentProps } from '@udecode/plate-common/react';\nimport type { VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@udecode/cn';\nimport {\n PlateContent,\n useEditorContainerRef,\n useEditorRef,\n} from '@udecode/plate-common/react';\nimport { cva } from 'class-variance-authority';\n\nconst editorContainerVariants = cva(\n 'relative w-full cursor-text overflow-y-auto caret-primary selection:bg-brand/25 [&_.slate-selection-area]:border [&_.slate-selection-area]:border-brand/25 [&_.slate-selection-area]:bg-brand/15',\n {\n defaultVariants: {\n variant: 'default',\n },\n variants: {\n variant: {\n default: 'h-full',\n demo: 'h-[650px]',\n },\n },\n }\n);\n\nexport const EditorContainer = ({\n className,\n variant,\n ...props\n}: React.HTMLAttributes<HTMLDivElement> &\n VariantProps<typeof editorContainerVariants>) => {\n const editor = useEditorRef();\n const containerRef = useEditorContainerRef();\n\n return (\n <div\n id={editor.uid}\n ref={containerRef}\n className={cn(\n 'ignore-click-outside/toolbar',\n editorContainerVariants({ variant }),\n className\n )}\n // Adding this role attribute could cause the content captured by html2canvas to be incorrectly centered.\n // role=\"button\"\n {...props}\n />\n );\n};\n\nEditorContainer.displayName = 'EditorContainer';\n\nconst editorVariants = cva(\n cn(\n 'group/editor',\n 'relative w-full overflow-x-hidden whitespace-pre-wrap break-words',\n 'rounded-md ring-offset-background placeholder:text-muted-foreground/80 focus-visible:outline-none',\n '[&_[data-slate-placeholder]]:text-muted-foreground/80 [&_[data-slate-placeholder]]:!opacity-100',\n '[&_[data-slate-placeholder]]:top-[auto_!important]',\n '[&_strong]:font-bold'\n ),\n {\n defaultVariants: {\n variant: 'default',\n },\n variants: {\n disabled: {\n true: 'cursor-not-allowed opacity-50',\n },\n focused: {\n true: 'ring-2 ring-ring ring-offset-2',\n },\n variant: {\n ai: 'w-full px-0 text-base md:text-sm',\n aiChat:\n 'max-h-[min(70vh,320px)] w-full max-w-[700px] overflow-y-auto px-3 py-2 text-base md:text-sm',\n default:\n 'size-full px-16 pb-72 pt-4 text-base sm:px-[max(64px,calc(50%-350px))]',\n demo: 'size-full px-16 pb-72 pt-4 text-base sm:px-[max(64px,calc(50%-350px))]',\n fullWidth: 'size-full px-16 pb-72 pt-4 text-base sm:px-24',\n none: '',\n },\n },\n }\n);\n\nexport type EditorProps = PlateContentProps &\n VariantProps<typeof editorVariants>;\n\nexport const Editor = React.forwardRef<HTMLDivElement, EditorProps>(\n ({ className, disabled, focused, variant, ...props }, ref) => {\n return (\n <PlateContent\n ref={ref}\n className={cn(\n editorVariants({\n disabled,\n focused,\n variant,\n }),\n className\n )}\n disabled={disabled}\n disableDefaultStyles\n {...props}\n />\n );\n }\n);\n\nEditor.displayName = 'Editor';\n",
"content": "'use client';\n\nimport React from 'react';\n\nimport type { PlateContentProps } from '@udecode/plate-common/react';\nimport type { VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@udecode/cn';\nimport {\n PlateContent,\n useEditorContainerRef,\n useEditorRef,\n} from '@udecode/plate-common/react';\nimport { cva } from 'class-variance-authority';\n\nconst editorContainerVariants = cva(\n 'relative w-full cursor-text overflow-y-auto caret-primary selection:bg-brand/25 [&_.slate-selection-area]:border [&_.slate-selection-area]:border-brand/25 [&_.slate-selection-area]:bg-brand/15',\n {\n defaultVariants: {\n variant: 'default',\n },\n variants: {\n variant: {\n default: 'h-full',\n demo: 'h-[650px]',\n },\n },\n }\n);\n\nexport const EditorContainer = ({\n className,\n variant,\n ...props\n}: React.HTMLAttributes<HTMLDivElement> &\n VariantProps<typeof editorContainerVariants>) => {\n const editor = useEditorRef();\n const containerRef = useEditorContainerRef();\n\n return (\n <div\n id={editor.uid}\n ref={containerRef}\n className={cn(\n 'ignore-click-outside/toolbar',\n editorContainerVariants({ variant }),\n className\n )}\n {...props}\n />\n );\n};\n\nEditorContainer.displayName = 'EditorContainer';\n\nconst editorVariants = cva(\n cn(\n 'group/editor',\n 'relative w-full overflow-x-hidden whitespace-pre-wrap break-words',\n 'rounded-md ring-offset-background placeholder:text-muted-foreground/80 focus-visible:outline-none',\n '[&_[data-slate-placeholder]]:text-muted-foreground/80 [&_[data-slate-placeholder]]:!opacity-100',\n '[&_[data-slate-placeholder]]:top-[auto_!important]',\n '[&_strong]:font-bold'\n ),\n {\n defaultVariants: {\n variant: 'default',\n },\n variants: {\n disabled: {\n true: 'cursor-not-allowed opacity-50',\n },\n focused: {\n true: 'ring-2 ring-ring ring-offset-2',\n },\n variant: {\n ai: 'w-full px-0 text-base md:text-sm',\n aiChat:\n 'max-h-[min(70vh,320px)] w-full max-w-[700px] overflow-y-auto px-3 py-2 text-base md:text-sm',\n default:\n 'size-full px-16 pb-72 pt-4 text-base sm:px-[max(64px,calc(50%-350px))]',\n demo: 'size-full px-16 pb-72 pt-4 text-base sm:px-[max(64px,calc(50%-350px))]',\n fullWidth: 'size-full px-16 pb-72 pt-4 text-base sm:px-24',\n none: '',\n },\n },\n }\n);\n\nexport type EditorProps = PlateContentProps &\n VariantProps<typeof editorVariants>;\n\nexport const Editor = React.forwardRef<HTMLDivElement, EditorProps>(\n ({ className, disabled, focused, variant, ...props }, ref) => {\n return (\n <PlateContent\n ref={ref}\n className={cn(\n editorVariants({\n disabled,\n focused,\n variant,\n }),\n className\n )}\n disabled={disabled}\n disableDefaultStyles\n {...props}\n />\n );\n }\n);\n\nEditor.displayName = 'Editor';\n",
"path": "plate-ui/editor.tsx",
"target": "components/plate-ui/editor.tsx",
"type": "registry:ui"
Expand Down
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 { withRef } from '@udecode/cn';\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 {\n ToolbarSplitButton,\n ToolbarSplitButtonPrimary,\n ToolbarSplitButtonSecondary,\n} from './toolbar';\n\nexport const ExportToolbarButton = withRef<typeof ToolbarSplitButton>(\n ({ children, ...props }, ref) => {\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\n page.drawImage(imageEmbed, {\n height: canvas.height,\n width: canvas.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 <ToolbarSplitButton\n ref={ref}\n onClick={exportToPdf}\n onKeyDown={(e) => {\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n openState.onOpenChange(true);\n }\n }}\n pressed={openState.open}\n tooltip=\"Export\"\n {...props}\n >\n <ToolbarSplitButtonPrimary>\n <ArrowDownToLineIcon className=\"size-4\" />\n </ToolbarSplitButtonPrimary>\n\n <DropdownMenu {...openState} modal={false}>\n <DropdownMenuTrigger asChild>\n <ToolbarSplitButtonSecondary />\n </DropdownMenuTrigger>\n\n <DropdownMenuContent\n onClick={(e) => e.stopPropagation()}\n align=\"start\"\n alignOffset={-32}\n >\n <DropdownMenuGroup>\n <DropdownMenuItem onSelect={exportToPdf}>\n Export as PDF\n </DropdownMenuItem>\n <DropdownMenuItem onSelect={exportToImage}>\n Export via Image\n </DropdownMenuItem>\n </DropdownMenuGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n </ToolbarSplitButton>\n );\n }\n);\n",
"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",
"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 6a864cb

Please sign in to comment.