Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Publish Package to Azure Artifacts

on:
push:
branches:
- main # only run when commits land in main (direct push or PR merge)

jobs:
publish:
runs-on: ubuntu-latest

steps:
- name: Checkout repo
uses: actions/checkout@v3

- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: 20
registry-url: "https://pkgs.dev.azure.com/${{ secrets.AZURE_ORG }}/${{ secrets.AZURE_PROJECT }}/_packaging/${{ secrets.AZURE_FEED }}/npm/registry/"

- name: Install dependencies
run: yarn install --frozen-lockfile

- name: Build
run: yarn build

- name: Publish to Azure Artifacts
run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.AZURE_NPM_TOKEN }}
52 changes: 52 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,58 @@ const MyLoadingRenderer = ({ document, fileName }) => {
}}
/>;
```
### Overriding PDF Controls

You can override the default PDF controls by passing a callback function to `config.pdfControls.overrideComponent`. This function receives several parameters: the current PDF state, the pdfControls config, and handler functions for zooming in, zooming out, resetting zoom, and toggling pagination. Your function should return a React element to render custom controls.

Example:

```tsx
const MyPDFControls = (
pdfState,
pdfControlsConfig,
pdfZoomOut,
pdfZoomIn,
pdfZoomReset,
pdfTogglePaginated
) => {
// Example: Only show a custom zoom in/out
return (
<div>
<button onClick={pdfZoomOut}>-</button>
<span>{pdfState.zoomLevel.toFixed(2)}</span>
<button onClick={pdfZoomIn}>+</button>
<button onClick={pdfZoomReset} disabled={pdfState.zoomLevel === pdfState.defaultZoomLevel}>
Reset
</button>
<button onClick={pdfTogglePaginated}>
{pdfState.paginated ? "Single Page" : "Paginated"}
</button>
</div>
);
};

<DocViewer
pluginRenderers={DocViewerRenderers}
documents={docs}
config={{
pdfControls: {
overrideComponent: MyPDFControls,
},
}}
/>
```

The parameters provided to your override function are:

- `pdfState`: The current PDF renderer state (e.g., `zoomLevel`, `paginated`, `numPages`, etc.)
- `pdfControlsConfig`: The current pdfControls config object.
- `pdfZoomOut`: Function to decrease zoom.
- `pdfZoomIn`: Function to increase zoom.
- `pdfZoomReset`: Function to reset zoom to default.
- `pdfTogglePaginated`: Function to toggle between paginated and continuous scroll.

If your override returns a React element, it will replace the default PDF controls UI.

### Overriding No Renderer (Error)

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"name": "@cyntler/react-doc-viewer",
"name": "@unitfly/react-doc-viewer",
"version": "1.17.1",
"description": "File viewer for React.",
"author": "Matthew Mogford / Damian Cyntler",
"author": "Matthew Mogford / Damian Cyntler / Toma Karadole",
"type": "module",
"keywords": [
"reactjs",
Expand Down
27 changes: 27 additions & 0 deletions src/models.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { FC, ReactElement, ComponentType, PropsWithChildren } from "react";
import { IMainState } from "./store/mainStateReducer";
import { FileLoaderFunction } from "./utils/fileLoaders";
import { IPDFState } from "./renderers/pdf/state/reducer";

export interface IConfig {
header?: IHeaderConfig;
loadingRenderer?: ILoadingRendererConfig;
noRenderer?: INoRendererConfig;
csvDelimiter?: string;
pdfControls?: IPdfControlsConfig;
pdfZoom?: IPdfZoomConfig;
pdfVerticalScrollByDefault?: boolean;
}
Expand All @@ -33,6 +35,19 @@ export interface IHeaderConfig {
overrideComponent?: IHeaderOverride;
}

export interface IPdfControlsConfig {
disableControls?: boolean;
disableZoom?: boolean;
disablePagination?: boolean;
disableDownload?: boolean;
position?: "top-left" | "top-right" | "bottom-left" | "bottom-right";
paginated?: boolean;
initialZoom?: number;
zoomJump?: number;
defaultZoom?: number;
overrideComponent?: IPdfControlsOverride;
}

export interface IPdfZoomConfig {
defaultZoom: number;
zoomJump: number;
Expand All @@ -45,6 +60,18 @@ export type IHeaderOverride = (
// eslint-disable-next-line @typescript-eslint/no-explicit-any
) => ReactElement<any, any> | null;

export type IPdfControlsOverride = {
(
state: IPDFState,
config: IPdfControlsConfig,
pdfZoomOut?: () => void,
pdfZoomIn?: () => void,
pdfZoomReset?: () => void,
pdfTogglePaginated?: () => void,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
): ReactElement<any, any> | null;
};

export interface ITheme {
primary?: string;
secondary?: string;
Expand Down
129 changes: 72 additions & 57 deletions src/renderers/pdf/components/PDFControls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,74 +13,89 @@ import {
ZoomOutPDFIcon,
} from "./icons";
import PDFPagination from "./PDFPagination";
import { DocViewerContext } from "../../../store/DocViewerProvider";

const PDFControls: FC = () => {
const { t } = useTranslation();
const { state: pdfState, dispatch } = useContext(PDFContext);

const {
state: {
mainState,
paginated,
zoomLevel,
numPages,
zoomJump,
defaultZoomLevel,
},
dispatch,
} = useContext(PDFContext);
mainState,
paginated,
zoomLevel,
numPages,
zoomJump,
defaultZoomLevel,
} = pdfState;

const { state: viewerState } = useContext(DocViewerContext);
const { config } = viewerState;

const currentDocument = mainState?.currentDocument || null;

return (
<Container id="pdf-controls">
{paginated && numPages > 1 && <PDFPagination />}
const pdfZoomOut = () => dispatch(setZoomLevel(zoomLevel - zoomJump));
const pdfZoomIn = () => dispatch(setZoomLevel(zoomLevel + zoomJump));
const pdfZoomReset = () => dispatch(setZoomLevel(defaultZoomLevel));
const pdfTogglePaginated = () => dispatch(setPDFPaginated(!paginated));

const override = config?.pdfControls?.overrideComponent?.(
pdfState,
config.pdfControls,
pdfZoomOut,
pdfZoomIn,
pdfZoomReset,
pdfTogglePaginated,
);

if (override) {
return override;
} else {
return (
<Container id="pdf-controls">
{paginated && numPages > 1 && <PDFPagination />}

{currentDocument?.fileData && (
<DownloadButton
id="pdf-download"
href={currentDocument?.fileData as string}
download={currentDocument?.fileName || currentDocument?.uri}
title={t("downloadButtonLabel")}
>
<DownloadPDFIcon color="#000" size="75%" />
</DownloadButton>
)}

<ControlButton id="pdf-zoom-out" onMouseDown={pdfZoomOut}>
<ZoomOutPDFIcon color="#000" size="80%" />
</ControlButton>

<ControlButton id="pdf-zoom-in" onMouseDown={pdfZoomIn}>
<ZoomInPDFIcon color="#000" size="80%" />
</ControlButton>

{currentDocument?.fileData && (
<DownloadButton
id="pdf-download"
href={currentDocument?.fileData as string}
download={currentDocument?.fileName || currentDocument?.uri}
title={t("downloadButtonLabel")}
>
<DownloadPDFIcon color="#000" size="75%" />
</DownloadButton>
)}

<ControlButton
id="pdf-zoom-out"
onMouseDown={() => dispatch(setZoomLevel(zoomLevel - zoomJump))}
>
<ZoomOutPDFIcon color="#000" size="80%" />
</ControlButton>

<ControlButton
id="pdf-zoom-in"
onMouseDown={() => dispatch(setZoomLevel(zoomLevel + zoomJump))}
>
<ZoomInPDFIcon color="#000" size="80%" />
</ControlButton>

<ControlButton
id="pdf-zoom-reset"
onMouseDown={() => dispatch(setZoomLevel(defaultZoomLevel))}
disabled={zoomLevel === defaultZoomLevel}
>
<ResetZoomPDFIcon color="#000" size="70%" />
</ControlButton>

{numPages > 1 && (
<ControlButton
id="pdf-toggle-pagination"
onMouseDown={() => dispatch(setPDFPaginated(!paginated))}
id="pdf-zoom-reset"
onMouseDown={pdfZoomReset}
disabled={zoomLevel === defaultZoomLevel}
>
<TogglePaginationPDFIcon
color="#000"
size="70%"
reverse={paginated}
/>
<ResetZoomPDFIcon color="#000" size="70%" />
</ControlButton>
)}
</Container>
);

{numPages > 1 && (
<ControlButton
id="pdf-toggle-pagination"
onMouseDown={pdfTogglePaginated}
>
<TogglePaginationPDFIcon
color="#000"
size="70%"
reverse={paginated}
/>
</ControlButton>
)}
</Container>
);
}
};

export default PDFControls;
Expand Down