Skip to content

Commit

Permalink
onBeforePrint improvements prep for v3-beta2
Browse files Browse the repository at this point in the history
  • Loading branch information
MatthewHerbst committed Aug 19, 2024
1 parent a1f45be commit dc77a1d
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 55 deletions.
10 changes: 6 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,21 @@

## (BETA) 3.0.0 (15 Jul 2024)

React 19 support + API modernization [717](https://github.com/MatthewHerbst/react-to-print/pull/717)
- FEATURE [717](https://github.com/MatthewHerbst/react-to-print/pull/717): React 19 support + API modernization
- CHORE: package size reduced by 18.7kb (34%)

### BREAKING CHANGES

- `content` renamed to `contentRef` and type changed from `() => React.ReactInstance` to `RefObject<Element | Text>`. The core impact here is that Class components now need to have the ref forwarded via props internally to a DOM node
- React ^16.8.0 required (dropped support for React versions that don't support hooks)
- `onBeforeGetContent` removed. Use `onBeforePrint`
- React >= 16.8.0 required (dropped support for React versions that don't support hooks)
- `onBeforeGetContent` removed. Use `onBeforePrint`, which similar to `onBeforeGetContent`, now runs before the print iframe is loaded
- `removeAfterPrint` renamed to `preserveAfterPrint` which defaults to `false`
- `ReactToPrint` removed. Use `useReactToPrint`
- `PrintContextConsumer` removed. Use `useReactToPrint`
- `trigger`removed, call the function returned by `useReactToPrint`
- `trigger` removed, use the function returned by `useReactToPrint`
- `IReactToPrintProps` renamed to `UseReactToPrintOptions`
- Default package export removed, use named `useReactToPrint` export
- Removed `event?: unknown` type from `useReactToPrint` callback. `optionalContent` is now the only (optional) argument
- Build is now ES6 code. Previously it was ES5
- No longer officially support IE11 (will still try but no promises)

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
],
"scripts": {
"build": "NODE_ENV=production webpack --progress",
"lint": "eslint src/**/*.{ts,tsx}",
"lint": "eslint ./src",
"prepare": "npm run build && husky install",
"start": "NODE_ENV=development webpack serve"
},
Expand Down
49 changes: 29 additions & 20 deletions src/hooks/useReactToPrint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@ import type { UseReactToPrintOptions } from "../types/UseReactToPrintOptions";
import { getContentNode } from "../utils/getContentNode";
import { generatePrintWindow } from "../utils/generatePrintWindow";
import { logMessages } from "../utils/logMessage";
import { handleOnBeforePrint } from "../utils/handleOnBeforePrint";
import { UseReactToPrintHookContent } from "../types/UseReactToPrintHookContent";
import { handlePrintWindowOnLoad } from "../utils/handlePrintWindowOnLoad";
import { HandlePrintWindowOnLoadData } from "../utils/handlePrintWindowOnLoad";
import { removePrintIframe } from "../utils/removePrintIframe";
import { UseReactToPrintFn } from "../types/UseReactToPrintFn";
import { appendPrintWindow } from "../utils/appendPrintWindow";
import { startPrint } from "../utils/startPrint";

export function useReactToPrint(options: UseReactToPrintOptions): UseReactToPrintFn {
const {
contentRef,
fonts,
ignoreGlobalStyles,
onBeforePrint,
onPrintError,
preserveAfterPrint,
suppressErrors,
} = options;
Expand Down Expand Up @@ -65,6 +68,10 @@ export function useReactToPrint(options: UseReactToPrintOptions): UseReactToPrin

const printWindow = generatePrintWindow();

/**
* Keeps track of loaded resources, kicking off the actual print function once all
* resources have been marked (loaded or failed)
*/
const markLoaded = (resource: Element | Font | FontFace, errorMessages?: unknown[]) => {
if (resourcesLoaded.includes(resource)) {
logMessages({
Expand Down Expand Up @@ -93,27 +100,29 @@ export function useReactToPrint(options: UseReactToPrintOptions): UseReactToPrin
const numResourcesManaged = resourcesLoaded.length + resourcesErrored.length;

if (numResourcesManaged === numResourcesToLoad) {
handleOnBeforePrint(
printWindow,
options,
);
startPrint(printWindow, options);
}
};

printWindow.onload = () => handlePrintWindowOnLoad(
printWindow,
markLoaded,
{
clonedContentNode,
contentNode,
numResourcesToLoad,
renderComponentImgNodes,
renderComponentVideoNodes,
},
options
);

document.body.appendChild(printWindow);
const data: HandlePrintWindowOnLoadData = {
clonedContentNode,
contentNode,
numResourcesToLoad,
renderComponentImgNodes,
renderComponentVideoNodes,
}

// Ensure we run `onBeforePrint` before appending the print window, which kicks off loading
// needed resources once mounted
if (onBeforePrint) {
onBeforePrint()
.then(() => appendPrintWindow(printWindow, markLoaded, data, options))
.catch((error: Error) => {
onPrintError?.("onBeforePrint", error);
});
} else {
appendPrintWindow(printWindow, markLoaded, data, options);
}
}, [options]);

return handlePrint;
Expand Down
3 changes: 2 additions & 1 deletion src/types/UseReactToPrintOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ export interface UseReactToPrintOptions {
onAfterPrint?: () => void;
/**
* Callback function that triggers before print. This can be used to change the content on the
* page before printing as an alternative to, or in conjunction with `@media print` queries
* page before printing as an alternative to, or in conjunction with `@media print` queries. Is
* run prior to the print iframe being mounted.
*/
onBeforePrint?: () => Promise<void>;
/**
Expand Down
19 changes: 19 additions & 0 deletions src/utils/appendPrintWindow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Font } from "../types/Font";
import { UseReactToPrintOptions } from "../types/UseReactToPrintOptions";
import { handlePrintWindowOnLoad, HandlePrintWindowOnLoadData } from "./handlePrintWindowOnLoad";

export function appendPrintWindow(
printWindow: HTMLIFrameElement,
markLoaded: (resource: Element | Font | FontFace, errorMessages?: unknown[]) => void,
data: HandlePrintWindowOnLoadData,
options: UseReactToPrintOptions,
) {
printWindow.onload = () => handlePrintWindowOnLoad(
printWindow,
markLoaded,
data,
options
);

document.body.appendChild(printWindow);
}
28 changes: 0 additions & 28 deletions src/utils/handleOnBeforePrint.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/utils/handlePrintWindowOnLoad.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { startPrint } from "./startPrint";
import { Font } from "../types/Font";
import type { UseReactToPrintOptions } from "../types/UseReactToPrintOptions";

type HandlePrintWindowOnLoadData = {
export type HandlePrintWindowOnLoadData = {
clonedContentNode: Node;
contentNode: Node;
numResourcesToLoad: number;
Expand Down

0 comments on commit dc77a1d

Please sign in to comment.