Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
felixfeng33 committed Nov 26, 2024
1 parent b8864d2 commit 4282a3b
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 105 deletions.
2 changes: 0 additions & 2 deletions apps/www/content/docs/examples/export.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ title: Export

Install the [PDF Toolbar Button](/docs/plate-ui/pdf-toolbar-button) component.

```
## Examples

### Plate UI
Expand Down
179 changes: 77 additions & 102 deletions apps/www/src/registry/default/plate-ui/export-toolbar-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

import React from 'react';

import { withRef } from '@udecode/cn';
import type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';

import { toDOMNode, useEditorRef } from '@udecode/plate-common/react';
import { ArrowDownToLineIcon } from 'lucide-react';

Expand All @@ -14,105 +15,79 @@ import {
DropdownMenuTrigger,
useOpenState,
} from './dropdown-menu';
import {
ToolbarSplitButton,
ToolbarSplitButtonPrimary,
ToolbarSplitButtonSecondary,
} from './toolbar';

export const ExportToolbarButton = withRef<typeof ToolbarSplitButton>(
({ children, ...props }, ref) => {
const editor = useEditorRef();
const openState = useOpenState();

const getCanvas = async () => {
const { default: html2canvas } = await import('html2canvas');

const style = document.createElement('style');
document.head.append(style);
style.sheet?.insertRule(
'body > div:last-child img { display: inline-block !important; }'
);

const canvas = await html2canvas(toDOMNode(editor, editor)!);
style.remove();

return canvas;
};

const downloadFile = (href: string, filename: string) => {
const element = document.createElement('a');
element.setAttribute('href', href);
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.append(element);
element.click();
element.remove();
};

const exportToPdf = async () => {
const canvas = await getCanvas();

const PDFLib = await import('pdf-lib');
const pdfDoc = await PDFLib.PDFDocument.create();
const page = pdfDoc.addPage([canvas.width, canvas.height]);
const imageEmbed = await pdfDoc.embedPng(canvas.toDataURL('PNG'));

page.drawImage(imageEmbed, {
height: canvas.height,
width: canvas.width,
x: 0,
y: 0,
});
const pdfBase64 = await pdfDoc.saveAsBase64({ dataUri: true });

downloadFile(pdfBase64, 'plate.pdf');
};

const exportToImage = async () => {
const canvas = await getCanvas();
downloadFile(canvas.toDataURL('image/png'), 'plate.png');
};

return (
<ToolbarSplitButton
ref={ref}
onClick={exportToPdf}
onKeyDown={(e) => {
if (e.key === 'ArrowDown') {
e.preventDefault();
openState.onOpenChange(true);
}
}}
pressed={openState.open}
tooltip="Export"
{...props}
>
<ToolbarSplitButtonPrimary>
<ArrowDownToLineIcon className="size-4" />
</ToolbarSplitButtonPrimary>

<DropdownMenu {...openState} modal={false}>
<DropdownMenuTrigger asChild>
<ToolbarSplitButtonSecondary />
</DropdownMenuTrigger>

<DropdownMenuContent
onClick={(e) => e.stopPropagation()}
align="start"
alignOffset={-32}
>
<DropdownMenuGroup>
<DropdownMenuItem onSelect={exportToPdf}>
Export as PDF
</DropdownMenuItem>
<DropdownMenuItem onSelect={exportToImage}>
Export as Image
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
</ToolbarSplitButton>
import { ToolbarButton } from './toolbar';

export function ExportToolbarButton({ children, ...props }: DropdownMenuProps) {
const editor = useEditorRef();
const openState = useOpenState();

const getCanvas = async () => {
const { default: html2canvas } = await import('html2canvas');

const style = document.createElement('style');
document.head.append(style);
style.sheet?.insertRule(
'body > div:last-child img { display: inline-block !important; }'
);
}
);

const canvas = await html2canvas(toDOMNode(editor, editor)!);
style.remove();

return canvas;
};

const downloadFile = (href: string, filename: string) => {
const element = document.createElement('a');
element.setAttribute('href', href);
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.append(element);
element.click();
element.remove();
};

const exportToPdf = async () => {
const canvas = await getCanvas();

const PDFLib = await import('pdf-lib');
const pdfDoc = await PDFLib.PDFDocument.create();
const page = pdfDoc.addPage([canvas.width, canvas.height]);
const imageEmbed = await pdfDoc.embedPng(canvas.toDataURL('PNG'));

page.drawImage(imageEmbed, {
height: canvas.height,
width: canvas.width,
x: 0,
y: 0,
});
const pdfBase64 = await pdfDoc.saveAsBase64({ dataUri: true });

downloadFile(pdfBase64, 'plate.pdf');
};

const exportToImage = async () => {
const canvas = await getCanvas();
downloadFile(canvas.toDataURL('image/png'), 'plate.png');
};

return (
<DropdownMenu modal={false} {...openState} {...props}>
<DropdownMenuTrigger asChild>
<ToolbarButton pressed={openState.open} tooltip="Export" isDropdown>
<ArrowDownToLineIcon className="size-4" />
</ToolbarButton>
</DropdownMenuTrigger>

<DropdownMenuContent align="start">
<DropdownMenuGroup>
<DropdownMenuItem onSelect={exportToPdf}>
Export as PDF
</DropdownMenuItem>
<DropdownMenuItem onSelect={exportToImage}>
Export as Image
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export function FixedToolbarButtons() {
</ToolbarGroup>

<ToolbarGroup>
<ExportToolbarButton tooltip="Export File">
<ExportToolbarButton>
<ArrowUpToLineIcon />
</ExportToolbarButton>
</ToolbarGroup>
Expand Down

0 comments on commit 4282a3b

Please sign in to comment.