Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/sandanat/vue-pdf-app

VUEjs v2 PDF viewer based on Mozilla's PDFJS
https://github.com/sandanat/vue-pdf-app

pdf vue2

Last synced: 5 days ago
JSON representation

VUEjs v2 PDF viewer based on Mozilla's PDFJS

Awesome Lists containing this project

README

        

VUEjs v2 PDF viewer based on Mozilla's PDFJS.

[![](https://data.jsdelivr.com/v1/package/npm/vue-pdf-app/badge)](https://www.jsdelivr.com/package/npm/vue-pdf-app)

[![npm version](https://badge.fury.io/js/vue-pdf-app.svg)](https://badge.fury.io/js/vue-pdf-app)

100% PDFJS functionality:

- zoom
- open
- print
- download
- rotate
- text selection
- search panel
- pdf document password
- thumbnail, outline, attachments, annotation layers

Easily localized configurable toolbar

NEW Toolbar custom UI

Cross-browser support (including IE11)

Color customization (IE11 not supported)

Buttons icons customization

Light/dark themes

Built-in typescript support

UMD/Unpkg support:

| File | Size | Gzipped |
| ---------------------- | ---------------------------------- | ---------- |
| vue-pdf-app.umd.min.js | 1742.89 KiB | 478.86 KiB |
| vue-pdf-app.umd.js | 3115.59 KiB | 677.87 KiB |
| vue-pdf-app.common.js | 3115.12 KiB | 677.71 KiB |
| icons/main.css | 15 - 40 KiB (depends from browser) | |

# Example

```vue



import VuePdfApp from "vue-pdf-app";
// import this to use default icons for buttons
import "vue-pdf-app/dist/icons/main.css";

export default {
components: {
VuePdfApp
}
};

```

![pdf sample](./readme/sample.png "Pdf expample")

[Live demo](https://codesandbox.io/s/vue-2-vue-pdf-app-wz5kv)

[Live demo 2](https://codepen.io/sandanat/pen/xxVdgYM)

[Examples source code](https://github.com/sandanat/vue-pdf-app/tree/master/examples "Examples source code")

[FAQ](https://github.com/sandanat/vue-pdf-app/blob/master/FAQ.md)

# API

## :pdf

- Type: `string | null | ArrayBuffer | TypedArray`
- Required: `false`
- Usage:

```vue

```

## :title

- Description: `true` renames document title to pdf file name.
- Type: `boolean`
- Required: `false`
- Default: `false`
- Usage:

```vue

```

## :theme.sync

- Type: `"dark" | "light"`
- Required: `false`
- Usage:

```vue

```

## new :fileName

- Description: when pdf is passed like an array buffer default download file name is `document.pdf`. Set this prop to override it.
- Type: `string`
- Required: `false`
- Usage:

```vue

```

## new :pageScale

- Description: default page scale.
- Type: `number | "page-actual"| "page-width"| "page-height"| "page-fit"| "auto"`
- Required: `false`
- Usage:

```vue
// 20%

```

## new :pageNumber

- Description: pdfjs stores last viewed page of a file in `window.localStorage.getItem("pdfjs.history")`. Specify the prop to override it.
- Type: `number`
- Required: `false`
- Usage:

```vue

```

## :config

- Description: toolbar configuration. Toolbar is available by default. Specify `false` for buttons or whole group of buttons to disable them.
- Type: `toolbar config (see below)`
- Required: `false`
- Default: `toolbar config`
- Usage:

```vue

export default {
data() {
return {
// disable "Previous page" button
config: {
toolbar: {
toolbarViewerLeft: {
previous: false
}
}
},

// disable whole page navigation panel
config2: {
toolbar: {
toolbarViewerLeft: false
}
},

// disable whole panel
config3: {
toolbar: false
}
};
}
};

```

Config specification

![Config legend](./readme/config-legend.jpg "Config legend")



{
sidebar: {
viewThumbnail: true,
viewOutline: true,
viewAttachments: true,
},
secondaryToolbar: {
secondaryPresentationMode: true,
secondaryOpenFile: true,
secondaryPrint: true,
secondaryDownload: true,
secondaryViewBookmark: true,
firstPage: true,
lastPage: true,
pageRotateCw: true,
pageRotateCcw: true,
cursorSelectTool: true,
cursorHandTool: true,
scrollVertical: true,
scrollHorizontal: true,
scrollWrapped: true,
spreadNone: true,
spreadOdd: true,
spreadEven: true,
documentProperties: true,
},
toolbar: {
toolbarViewerLeft: {
findbar: true,
previous: true,
next: true,
pageNumber: true,
},
toolbarViewerRight: {
presentationMode: true,
openFile: true,
print: true,
download: true,
viewBookmark: true,
},
toolbarViewerMiddle: {
zoomOut: true,
zoomIn: true,
scaleSelectContainer: true,
},
},
errorWrapper: true,
};

## new :id-config

- Description: If default toolbar UI doesn't suite you it is possible to build custom toolbar. The prop contains elements ID to which to bind functionality. If element ID is specified in this prop appropriate button will be hidden in a default toolbar. May not work with UI framework components. That is because pdfjs internally manages attributes specific to a certain HTML element (for instance pdfjs toggles `disabled` attribute of a button but it won't if a div is used instead of a button). So it is better to use native HTML element specified as recommended in ID config specification below. Four slots are specially designed to build custom toolbar (are situated near a pdf page): `viewer-header, viewer-prepend, viewer-append, viewer-footer` (refer slots API). It is also possible to use other slots or elements outside vue-pdf-app.
- Type: `ID config (see below)`
- Required: `false`
- Usage:

```vue


Zoom out



Zoom in



export default {
data() {
return {
idConfig: { zoomIn: "zoomInId", zoomOut: "zoomOutId" }
};
}
};

```

ID config specification


{

cursorHandTool?: string; // <button> is recommended
cursorSelectTool?: string; // <button> is recommended
documentProperties?: string; // <button> is recommended
download?: string; // <button> is recommended
findbar?: string; // <div> is recommended
findEntireWord?: string; // <input type="checkbox"> is recommended
findHighlightAll?: string; // <input type="checkbox"> is recommended
findMessage?: string; // <span> is recommended
findInput?: string; // <input type="text"> is recommended
findMatchCase?: string; // <input type="checkbox"> is recommended
findNext?: string; // <button> is recommended
findPrevious?: string; // <button> is recommended
findResultsCount?: string; // <span> is recommended
firstPage?: string; // <button> is recommended
lastPage?: string; // <button> is recommended
nextPage?: string; // <button> is recommended
numPages?: string; // total pages qty. <span> is recommended
openFile?: string; // <button> is recommended
pageNumber?: string; // input for page number. <input type="number"> is recommended
pageRotateCcw?: string; // <button> is recommended
pageRotateCw?: string; // <button> is recommended
presentationMode?: string; // <button> is recommended
previousPage?: string; // <button> is recommended
print?: string; // <button> is recommended
scrollHorizontal?: string; // <button> is recommended
scrollVertical?: string; // <button> is recommended
scrollWrapped?: string; // <button> is recommended
sidebarToggle?: string; // <button> is recommended
spreadEven?: string; // <button> is recommended
spreadNone?: string; // <button> is recommended
spreadOdd?: string; // <button> is recommended
toggleFindbar?: string; // <button> is recommended
viewAttachments?: string; // <button> is recommended
viewBookmark?: string; // <a> tag is recommended
viewOutline?: string; // <button> tag is recommended
viewThumbnail?: string; // <button> tag is recommended
zoomIn?: string; // <button> tag is recommended
zoomOut?: string; // <button> tag is recommended
}


> ℹ️ Note that elements must be in HTML document by the time vue-pdf-app is mounting (use `v-show` instead of `v-if` directive if necessary). Otherwise an error occurs.

## @after-created(PDFViewerApplication)

- Description: emitted only once when Pdfjs library is binded to vue component. Can be used to set Pdfjs config before pdf document opening.
- Arguments:
- PDFViewerApplication - [pdf application](https://github.com/mozilla/pdf.js/blob/master/web/app.js#L198)
- Usage:

```vue

```

## @open(PDFViewerApplication)

- Description: emitted when pdf is opened but pages are not rendered.
- Arguments:
- PDFViewerApplication - [pdf application](https://github.com/mozilla/pdf.js/blob/master/web/app.js#L198)
- Usage:

```vue

```

## @pages-rendered(PDFViewerApplication)

- Description: emitted when pdf document pages are rendered. Can be used to set default pages scale, for instance.
- Arguments:
- PDFViewerApplication - [pdf application](https://github.com/mozilla/pdf.js/blob/master/web/app.js#L198)
- Usage:

```vue

export default {
methods: {
pagesRendered(pdfApp) {
setTimeout(() => (pdfApp.pdfViewer.currentScaleValue = "page-height"));
}
}
};

```

> ℹ️ Events are triggered in the following order `after-created (once) => open => pages-rendered`

## Slots

### Slot names

- toolbar-left-prepend
- toolbar-left-append
- toolbar-middle-prepend
- toolbar-middle-append
- toolbar-right-prepend
- toolbar-right-append
- toolbar-sidebar-prepend
- toolbar-sidebar-append
- secondary-toolbar-prepend
- secondary-toolbar-append
- footer
- NEW viewer-header: slot before `viewer-prepend` slot. Can be used to build custom toolbar.
- NEW viewer-prepend: slot before `viewerContainer` div. Can be used to build custom toolbar.
- NEW viewer-append: slot after `viewerContainer` div. Can be used to build custom toolbar.
- NEW viewer-footer: slot after `viewer-append` slot. Can be used to build custom toolbar.

### Slot props

Each slot has props:

1. toggleTheme

Type: (): void.

Description: toggle theme handler

1. NEW isSidebarHidden

Type: boolean

Description: state of a sidebar (visible or hidden). Can be used to manage visibility of custom Attachments, Outline and Thumbnail buttons

1. NEW isFindbarHidden

Type: boolean

Description: state of a findbar (visible or hidden). Can be used to manage visibility of custom findbar

```vue


Toggle theme

```

# Color customization (IE11 not supported)

Colors of the pdf viewer are customized via custom css properties:

```html

/* for dark theme */
.pdf-app.dark {
--pdf-toolbar-color: black;
}

/* for light theme */
.pdf-app.light {
--pdf-toolbar-color: white;
}

```

Custom css properties specification


Property
Applied to selectors
Description


--pdf-app-background-color
.pdf-app
Background color for root pdf container


--pdf-button-hover-font-color

.pdf-app .toolbarButton:hover



.pdf-app .toolbarButton:focus


.pdf-app .dropdownToolbarButton:hover


.pdf-app .secondaryToolbarButton:hover


.pdf-app .secondaryToolbarButton:focus



Hover color for buttons of toolbar and secondary toolbar


--pdf-button-toggled-color

.pdf-app .toolbarButton.toggled


.pdf-app .splitToolbarButton.toggled > .toolbarButton.toggled


.pdf-app .secondaryToolbarButton.toggled


.pdf-app .outlineItemToggler:hover


.pdf-app .outlineItemToggler:hover + a


.pdf-app .outlineItemToggler:hover ~ .outlineItems


.pdf-app .outlineItem > a:hover


.pdf-app .attachmentsItem > button:hover


Background color for toggleable buttons when selected, outline items on hover, attachment items on hover
toggleable items



--pdf-dialog-button-color
.pdf-app .dialog .overlayButton

dialog buttons



--pdf-dialog-button-font-color
.pdf-app .dialog .overlayButton

dialog buttons



--pdf-error-more-info-color
.pdf-app #errorMoreInfo

error more info



--pdf-error-more-info-font-color
.pdf-app #errorMoreInfo

error more info



--pdf-error-wrapper-color
.pdf-app #errorWrapper

error wrapper



--pdf-find-input-placeholder-font-color
.pdf-app #findInput::placeholder

find input placeholder



--pdf-find-message-font-color
.pdf-app #findMsg

find message



--pdf-find-results-count-color
.pdf-app #findResultsCount

find results count



--pdf-find-results-count-font-color
.pdf-app #findResultsCount

find results count



--pdf-horizontal-toolbar-separator-color
.pdf-app .horizontalToolbarSeparator

horizontal separator



--pdf-input-color
.pdf-app .toolbarField

toolbar field



--pdf-input-font-color
.pdf-app .toolbarField

toolbar field



--pdf-loading-bar-color
.pdf-app #loadingBar .progress

loading bar color



--pdf-loading-bar-secondary-color
.pdf-app #loadingBar .progress.indeterminate .glimmer

loading bar secondary color



--pdf-not-found-color
.pdf-app #findInput.notFound

not found



--pdf-overlay-container-color
.pdf-app #overlayContainer
Background color for overlay container of dialogs


--pdf-overlay-container-dialog-color
.pdf-app #overlayContainer > .container > .dialog

Background color for document properties, password, print dialogs



--pdf-overlay-container-dialog-font-color
.pdf-app #overlayContainer > .container > .dialog

Font color for document properties, password, print dialogs



--pdf-overlay-container-dialog-separator-color
.pdf-app .dialog .separator

dialog separator



--pdf-sidebar-content-color
.pdf-app #sidebarContent

Background color for sidebar



--pdf-split-toolbar-button-separator-color

.pdf-app .splitToolbarButtonSeparator


.pdf-app .verticalToolbarSeparator


vertical separator



--pdf-thumbnail-selection-ring-selected-color
.pdf-app .thumbnail.selected > .thumbnailSelectionRing

Border color for selected thumbnail
thumbnail border



--pdf-thumbnail-selection-ring-color

.pdf-app a:focus > .thumbnail > .thumbnailSelectionRing


.pdf-app .thumbnail:hover > .thumbnailSelectionRing


Border color for thumbnail on hover and focus
thumbnail border



--pdf-toolbar-color

.pdf-app #toolbarContainer


.pdf-app .findbar


.pdf-app .secondaryToolbar


.pdf-app .doorHanger:after


.pdf-app .doorHangerRight:after


.pdf-app .dropdownToolbarButton > select


.pdf-app .dropdownToolbarButton > select > option


Background color for toolbar, findbar, secondary toolbar, page scale dropdown



--pdf-toolbar-font-color

.pdf-app .toolbarButton


.pdf-app .dropdownToolbarButton


.pdf-app .secondaryToolbarButton


.pdf-app .dropdownToolbarButton > select


.pdf-app .toolbarLabel


.pdf-app .outlineItem > a


.pdf-app .attachmentsItem > button


Font color for toolbar, findbar, secondary toolbar, page scale dropdown, attachments name


--pdf-toolbar-sidebar-color
.pdf-app #toolbarSidebar

sidebar


# Icons customization

To use default icons `import "vue-pdf-app/dist/icons/main.css";`.

To use custom icons you have to implement [icons.css](https://github.com/sandanat/vue-pdf-app/blob/master/src/sass/icons.scss):

```css
.vue-pdf-app-icon::before,
.vue-pdf-app-icon::after {
font-family: "your font family";
}

.vue-pdf-app-icon.zoom-out::before {
content: "icon code";
}
```

# Light/dark themes

Algorithm of theme apply
Algorithm of theme apply

Toggle theme button is not implemented by default.
It's up to you to decide where to place it.
The button can be implemented with slots:

```vue


Toggle theme

```

# Localized panel

English is the default language for panel.
Use `` in your html for localization.
See [localization file examples](https://github.com/mozilla/pdf.js/tree/master/l10n "file examples").

# Examples

## Script tag (unpkg)

```html




Vue-pdf-app demo




body,
html {
padding: 0;
margin: 0;
}






new Vue({
components: {
VuePdfApp: window["vue-pdf-app"]
}
}).$mount("#app");

```

## Typescript

```vue



import "vue-pdf-app/dist/icons/main.css";
import VuePdfApp from "vue-pdf-app";
import { Component, Vue } from "vue-property-decorator";

@Component({
components: {
VuePdfApp
}
})
export default class App extends Vue {}

```

## Lazy loading

PDFJS is a huge package (see the library size table above).
So use lazy loading to split your bundle into small pieces.

```vue



import "vue-pdf-app/dist/icons/main.css";
import Loader from "./components/Loader.vue";

export default {
name: "App",
components: {
"vue-pdf-app": () => ({
component: new Promise((res) => {
return setTimeout(
() => res(import(/* webpackChunkName: "pdf-viewer" */ "vue-pdf-app")),
4000
);
}),
loading: Loader
})
}
};

```

## PDFJS interaction

You can interact with pdfjs library when pdf is opened via `open` event.

```vue






PDF info:



{{ item.name }}: {{ item.value }}




import "vue-pdf-app/dist/icons/main.css";
import VuePdfApp from "vue-pdf-app";

export default {
name: "App",
components: {
VuePdfApp
},
data() {
return {
info: []
};
},
methods: {
async openHandler(pdfApp) {
this.info = [];
const info = await pdfApp.pdfDocument
.getMetadata()
.catch(console.error.bind(console));

if (!info) return;
const props = Object.keys(info.info);
props.forEach((prop) => {
const obj = {
name: prop,
value: info.info[prop]
};
this.info.push(obj);
});
}
}
};

```