├── .browserslistrc
├── .editorconfig
├── .eslintrc.js
├── .gitignore
├── .storybook
├── main.js
├── manager.js
├── preview.ts
└── webpack.config.js
├── .travis.yml
├── LICENSE.md
├── README.md
├── _config.yml
├── babel.config.js
├── jest.config.js
├── package.json
├── rollup.config.js
├── scripts
├── build-docs.sh
└── build-lib.sh
├── src
├── components
│ ├── index.ts
│ └── vue-pdf
│ │ ├── index.ts
│ │ ├── loading-task.ts
│ │ ├── vue-pdf-props.ts
│ │ └── vue-pdf.vue
├── shims-vue.d.ts
├── stories
│ ├── css
│ │ └── page.scss
│ ├── utilities
│ │ └── template-source.ts
│ └── vue-pdf
│ │ ├── source-code.ts
│ │ └── vue-pdf.stories.ts
├── vue3-pdfjs.cjs-iife.ts
└── vue3-pdfjs.ts
├── tsconfig.json
├── tsconfig.lib.types.json
└── vue.config.js
/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 10 versions
3 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.{js,jsx,ts,tsx,vue}]
2 | indent_style = space
3 | indent_size = 2
4 | end_of_line = lf
5 | trim_trailing_whitespace = true
6 | insert_final_newline = true
7 | max_line_length = 100
8 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: {
4 | node: true,
5 | },
6 | extends: [
7 | 'plugin:vue/vue3-essential',
8 | '@vue/airbnb',
9 | '@vue/typescript/recommended',
10 | ],
11 | parserOptions: {
12 | ecmaVersion: 2020,
13 | },
14 | rules: {
15 | 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
16 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
17 | },
18 | overrides: [
19 | {
20 | files: [
21 | '**/__tests__/*.{j,t}s?(x)',
22 | '**/tests/unit/**/*.spec.{j,t}s?(x)',
23 | ],
24 | env: {
25 | jest: true,
26 | },
27 | },
28 | ],
29 | };
30 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | dist/
4 | package-lock.json
5 |
6 |
7 | # local env files
8 | .env.local
9 | .env.*.local
10 |
11 | # Log files
12 | npm-debug.log*
13 | yarn-debug.log*
14 | yarn-error.log*
15 | pnpm-debug.log*
16 |
17 | # Editor directories and files
18 | .idea
19 | .vscode
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/.storybook/main.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | stories: [
3 | '../src/**/*.stories.mdx',
4 | '../src/**/*.stories.@(js|jsx|ts|tsx)'
5 | ],
6 | addons: [
7 | '@storybook/addon-links',
8 | '@storybook/addon-essentials',
9 | '@storybook/addon-actions'
10 | ],
11 | core: {
12 | builder: 'webpack4',
13 | },
14 | }
15 |
--------------------------------------------------------------------------------
/.storybook/manager.js:
--------------------------------------------------------------------------------
1 | import { addons } from "@storybook/addons";
2 | import { create } from "@storybook/theming/create";
3 |
4 | const theme = create({
5 | base: "light",
6 | brandTitle: "Vue 3 PDFJS",
7 |
8 | colorSecondary: '#012d15',
9 | barSelectedColor: '#012d15',
10 | textColor: '#012d15',
11 | });
12 |
13 | addons.setConfig({
14 | theme,
15 | });
16 |
--------------------------------------------------------------------------------
/.storybook/preview.ts:
--------------------------------------------------------------------------------
1 | import { Parameters } from '@storybook/vue3';
2 | import { themes } from '@storybook/theming';
3 |
4 | // This adds a component that can be used globally in stories
5 | // app.component('GlobalButton', Button);
6 |
7 | export const parameters: Parameters = {
8 | actions: { argTypesRegex: '^on[A-Z].*' },
9 | controls: { expanded: true },
10 | previewTabs: {
11 | docs: {
12 | hidden: false,
13 | theme: themes.dark,
14 | }
15 | },
16 | };
17 |
--------------------------------------------------------------------------------
/.storybook/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require("path");
2 |
3 | module.exports = ({config}) => {
4 | config.module.rules.push({
5 | test: /\.scss$/,
6 | use: [
7 | require.resolve("vue-style-loader"),
8 | require.resolve("css-loader"),
9 | require.resolve("sass-loader"),
10 | ],
11 | });
12 |
13 | return config;
14 | };
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | os: linux
2 | dist: xenial
3 |
4 | language: node_js
5 |
6 | node_js:
7 | - 14
8 |
9 | jobs:
10 | include:
11 | - stage: test
12 | script: npm run test:unit
13 | - stage: build library
14 | script: npm run build:lib
15 | - stage: build docs
16 | script: npm run build-storybook
17 | - stage: deploy docs
18 | script: npm run build
19 | deploy:
20 | provider: pages
21 | skip_cleanup: true
22 | token: $VUE_PDFJS_GITHUB_TRAVIS
23 | keep_history: true
24 | local_dir: dist/docs
25 | on:
26 | branch: main
27 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2020-2021 Randolph Tellis
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | [](https://travis-ci.com/randolphtellis/vue3-pdfjs) [](https://bundlephobia.com/result?p=vue3-pdfjs@latest)  
4 |
5 |  [](https://www.npmjs.com/package/vue3-pdfjs/v/latest) [](https://github.com/randolphtellis/vue3-pdfjs/blob/main/LICENSE.md)
6 |
7 | ####
DEMO
8 |
9 |
10 |
11 | ## Install
12 |
13 | ```bash
14 | npm i vue3-pdfjs
15 | or
16 | yarn add vue3-pdfjs
17 | ```
18 |
19 | ## Usage
20 |
21 | ##### Demo code can be found under the docs section here.
22 |
23 | ### Import globally
24 | ```ts
25 | import { createApp } from 'vue'
26 | import App from './App.vue'
27 | import VuePdf from 'vue3-pdfjs'
28 |
29 | const app = createApp(App)
30 | app.use(VuePdf)
31 | app.mount('#app')
32 | ```
33 |
34 |
35 |
36 | ### Basic Example
37 |
38 | Import components from the `esm` folder to enable tree shaking.
39 | Please note that Mozilla's pdfjs npm package does not export tree-shakeable ES modules. Info here - https://github.com/mozilla/pdf.js/issues/12900
40 | ```ts
41 |
68 |
69 |
70 |
71 |
72 | ```
73 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-cayman
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset',
4 | ],
5 | };
6 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: '@vue/cli-plugin-unit-jest/presets/typescript-and-babel',
3 | transform: {
4 | '^.+\\.vue$': 'vue-jest',
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue3-pdfjs",
3 | "description": "PDF Reader for Vue 3 using Mozilla's PDF.js",
4 | "author": {
5 | "name": "Randolph Tellis"
6 | },
7 | "license": "MIT",
8 | "version": "0.1.6",
9 | "private": false,
10 | "main": "cjs/index.js",
11 | "browser": "vue3-pdfjs.esm.js",
12 | "module": "esm/index.js",
13 | "unpkg": "vue3-pdfjs-browser.min.js",
14 | "types": "vue3-pdfjs.d.ts",
15 | "homepage": "https://github.com/randolphtellis/vue3-pdfjs#readme",
16 | "repository": {
17 | "type": "git",
18 | "url": "https://github.com/randolphtellis/vue3-pdfjs.git"
19 | },
20 | "bugs": {
21 | "url": "https://github.com/randolphtellis/vue3-pdfjs/issues"
22 | },
23 | "scripts": {
24 | "build:lib": "scripts/build-lib.sh",
25 | "build": "npm run build:lib && npm run build-storybook",
26 | "test:unit": "vue-cli-service test:unit --passWithNoTests",
27 | "lint": "vue-cli-service lint",
28 | "start-publish": "cd dist/lib && npm publish",
29 | "dev": "start-storybook -p 6006",
30 | "build-storybook": "scripts/build-docs.sh"
31 | },
32 | "dependencies": {
33 | "pdfjs-dist": "^2.10.377",
34 | "vue": "^3.2.19"
35 | },
36 | "devDependencies": {
37 | "@babel/core": "^7.12.7",
38 | "@rollup/plugin-alias": "^3.1.1",
39 | "@rollup/plugin-babel": "^5.2.1",
40 | "@rollup/plugin-commonjs": "^15.1.0",
41 | "@rollup/plugin-node-resolve": "^9.0.0",
42 | "@rollup/plugin-replace": "^2.3.3",
43 | "@rollup/plugin-url": "^5.0.1",
44 | "@storybook/addon-actions": "^6.3.8",
45 | "@storybook/addon-essentials": "^6.3.8",
46 | "@storybook/addon-links": "^6.3.8",
47 | "@storybook/vue3": "^6.3.8",
48 | "@types/jest": "^24.0.19",
49 | "@types/pdfjs-dist": "^2.7.4",
50 | "@typescript-eslint/eslint-plugin": "^2.33.0",
51 | "@typescript-eslint/parser": "^2.33.0",
52 | "@vue/cli-plugin-babel": "^4.5.13",
53 | "@vue/cli-plugin-eslint": "^4.5.13",
54 | "@vue/cli-plugin-typescript": "^4.5.13",
55 | "@vue/cli-plugin-unit-jest": "^4.5.13",
56 | "@vue/cli-service": "^4.5.13",
57 | "@vue/compiler-sfc": "^3.2.19",
58 | "@vue/eslint-config-airbnb": "^5.0.2",
59 | "@vue/eslint-config-typescript": "^5.0.2",
60 | "@vue/test-utils": "^2.0.0-0",
61 | "autoprefixer": "^9.8.6",
62 | "babel-loader": "^8.2.1",
63 | "cross-env": "^7.0.2",
64 | "eslint": "^6.7.2",
65 | "eslint-plugin-import": "^2.20.2",
66 | "eslint-plugin-vue": "^7.0.0-0",
67 | "minimist": "^1.2.5",
68 | "node-sass": "^4.12.0",
69 | "postcss": "^8.1.4",
70 | "postcss-nested": "^5.0.1",
71 | "postcss-simple-vars": "^6.0.1",
72 | "postcss-url": "^10.0.0",
73 | "rollup": "^2.32.1",
74 | "rollup-plugin-filesize": "^9.0.2",
75 | "rollup-plugin-postcss": "^3.1.8",
76 | "rollup-plugin-terser": "^7.0.2",
77 | "rollup-plugin-typescript2": "^0.28.0",
78 | "rollup-plugin-vue": "^6.0.0-beta.10",
79 | "sass": "^1.27.1",
80 | "sass-loader": "^8.0.2",
81 | "typescript": "^4.4.3",
82 | "vue-jest": "^5.0.0-0",
83 | "vue-loader": "^16.5.0"
84 | },
85 | "engines": {
86 | "node": ">=10.0.0"
87 | },
88 | "keywords": [
89 | "vue 3 pdf viewer",
90 | "vue 3 pdfjs",
91 | "vue 3 mozilla pdfjs",
92 | "vue 3 pdf component"
93 | ]
94 | }
95 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import fs from "fs";
2 | import path from "path";
3 | import vue from "rollup-plugin-vue";
4 | import pkg from "./package.json";
5 | import alias from "@rollup/plugin-alias";
6 | import commonjs from "@rollup/plugin-commonjs";
7 | import filesize from 'rollup-plugin-filesize';
8 | import resolve from "@rollup/plugin-node-resolve";
9 | import replace from "@rollup/plugin-replace";
10 | import babel from "@rollup/plugin-babel";
11 | import sass from 'node-sass'
12 | import postCss from "rollup-plugin-postcss"
13 | import autoprefixer from 'autoprefixer'
14 | import url from "@rollup/plugin-url"
15 | import { terser } from "rollup-plugin-terser"
16 | import typescript from 'rollup-plugin-typescript2'
17 |
18 | const projectRoot = path.resolve(__dirname, ".")
19 |
20 | const validPkgName = 'Vue3PDF'
21 |
22 | const libBuildFolder = 'dist/lib'
23 |
24 | // Get browserslist config and remove ie from es build targets
25 | const esbrowserslist = fs.readFileSync('./.browserslistrc')
26 | .toString()
27 | .split('\n')
28 | .filter((entry) => entry && entry.substring(0, 2) !== 'ie');
29 |
30 | let postVueConfig = [
31 | // Process only `
285 |
286 |
--------------------------------------------------------------------------------
/src/shims-vue.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.vue' {
2 | import type { DefineComponent } from 'vue'
3 | const component: DefineComponent<{}, {}, any>
4 | export default component
5 | }
6 |
7 | declare module 'pdfjs-dist/legacy/build/pdf.worker.entry';
8 | declare module 'pdfjs-dist/legacy/web/pdf_viewer';
9 |
--------------------------------------------------------------------------------
/src/stories/css/page.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/randolphtellis/vue3-pdfjs/600a3e2c284fb9c819189c31986456e183e42c1d/src/stories/css/page.scss
--------------------------------------------------------------------------------
/src/stories/utilities/template-source.ts:
--------------------------------------------------------------------------------
1 | export const templateSourceCode = (templateSource, args, replacing = 'v-bind="$props"') => {
2 | const propToSource = (key, val) => {
3 | const type = typeof val;
4 | switch (type) {
5 | case 'object':
6 | return `:${key}="${JSON.stringify(val)}"\n`;
7 | case 'boolean':
8 | return val ? key + `\n` : '';
9 | case 'string':
10 | return `${key}="${val}"\n`;
11 | default:
12 | return `:${key}="${val}"\n`;
13 | }
14 | };
15 |
16 | return templateSource.replace(
17 | replacing,
18 | Object.keys(args)
19 | .map((key) => propToSource(key, args[key]))
20 | .join(' ')
21 | );
22 | };
--------------------------------------------------------------------------------
/src/stories/vue-pdf/source-code.ts:
--------------------------------------------------------------------------------
1 | export const singleSource = `
2 |
5 | `;
6 |
--------------------------------------------------------------------------------
/src/stories/vue-pdf/vue-pdf.stories.ts:
--------------------------------------------------------------------------------
1 | import '../css/page.scss'
2 | import { Meta } from '@storybook/vue3'
3 | import VuePdf from '../../components/vue-pdf/vue-pdf.vue'
4 | import { templateSourceCode } from '../utilities/template-source'
5 | import { singleSource } from './source-code'
6 | import { actions } from '@storybook/addon-actions'
7 |
8 | export default {
9 | title: 'Pdf Viewer',
10 | component: VuePdf,
11 | argTypes: {
12 | src: { control: { type: 'object', required: true, default: 'https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf' } }
13 | },
14 | } as Meta;
15 |
16 | export const Default = (args: any, { argTypes }) => ({
17 | props: Object.keys(argTypes),
18 | components: { VuePdf },
19 | setup() {
20 | const action = actions('totalPages', 'pdfLoaded', 'textContent', 'pageLoaded')
21 | return {
22 | args,
23 | action
24 | }
25 | },
26 | template: `
27 |
28 | `
29 | });
30 |
31 | Default.args = {
32 | src: 'https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf',
33 | page: 1,
34 | enableTextSelection: true,
35 | enableAnnotations: true
36 | };
37 |
38 |
39 | Default.parameters = {
40 | docs: { source: { code: templateSourceCode(singleSource, Default.args) } },
41 | };
42 |
--------------------------------------------------------------------------------
/src/vue3-pdfjs.cjs-iife.ts:
--------------------------------------------------------------------------------
1 | // iife/cjs usage extends esm default export - so import it all
2 | import plugin, * as components from './vue3-pdfjs';
3 |
4 | // Attach named exports directly to plugin. IIFE/CJS will
5 | // only expose one global var, with component exports exposed as properties of
6 | // that global var (eg. plugin.component)
7 | type NamedExports = Exclude;
8 | type ExtendedPlugin = typeof plugin & NamedExports;
9 | Object.entries(components).forEach(([componentName, component]) => {
10 | if (componentName !== 'default') {
11 | const key = componentName as Exclude;
12 | const val = component as Exclude;
13 | (plugin as ExtendedPlugin)[key] = val;
14 | }
15 | });
16 |
17 | export default plugin;
18 |
--------------------------------------------------------------------------------
/src/vue3-pdfjs.ts:
--------------------------------------------------------------------------------
1 | import { App as Application, Plugin } from 'vue';
2 | import * as components from './components';
3 |
4 | const install: Exclude = (app: Application) => {
5 | Object.entries(components).forEach(([componentName, component]) => {
6 | app.component(componentName, component);
7 | });
8 | };
9 |
10 | export default install;
11 |
12 | export * from './components';
13 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es3",
4 | "module": "ES2015",
5 | "strict": true,
6 | "jsx": "preserve",
7 | "importHelpers": true,
8 | "moduleResolution": "node",
9 | "skipLibCheck": true,
10 | "esModuleInterop": true,
11 | "allowSyntheticDefaultImports": true,
12 | "sourceMap": true,
13 | "baseUrl": ".",
14 | "types": [
15 | "webpack-env",
16 | "jest"
17 | ],
18 | "paths": {
19 | "@/*": [
20 | "src/*"
21 | ]
22 | },
23 | "lib": [
24 | "es5",
25 | "es6",
26 | "es2016",
27 | "es2017",
28 | "esnext",
29 | "dom",
30 | "dom.iterable",
31 | "scripthost"
32 | ]
33 | },
34 | "exclude": [
35 | "node_modules",
36 | "dist",
37 | "src/main.ts",
38 | "src/stories/*",
39 | ],
40 | "include": [
41 | "src/**/*.ts",
42 | "src/**/*.tsx",
43 | "src/**/*.vue"
44 | ]
45 | }
46 |
--------------------------------------------------------------------------------
/tsconfig.lib.types.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "declaration": true,
4 | "incremental": true,
5 | "target": "es3",
6 | "module": "ES2015",
7 | "strict": true,
8 | "jsx": "preserve",
9 | "importHelpers": true,
10 | "moduleResolution": "node",
11 | "skipLibCheck": true,
12 | "esModuleInterop": true,
13 | "allowSyntheticDefaultImports": true,
14 | "sourceMap": true,
15 | "baseUrl": ".",
16 | "types": [
17 | "webpack-env",
18 | "jest"
19 | ],
20 | "paths": {
21 | "@/*": [
22 | "src/*"
23 | ]
24 | },
25 | "lib": [
26 | "es5",
27 | "es6",
28 | "es2016",
29 | "es2017",
30 | "esnext",
31 | "dom",
32 | "dom.iterable",
33 | "scripthost"
34 | ]
35 | },
36 | "exclude": [
37 | "node_modules",
38 | "dist",
39 | "src/main.ts",
40 | "src/stories/*",
41 | ],
42 | "include": [
43 | "src/**/*.ts",
44 | "src/**/*.tsx",
45 | "src/**/*.vue"
46 | ]
47 | }
48 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | lintOnSave: false,
3 | outputDir: 'dist/app'
4 | };
5 |
--------------------------------------------------------------------------------