diff --git a/.eslintrc.js b/.eslintrc.js index db56d42..47fa709 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -11,11 +11,23 @@ module.exports = { extends: [ 'plugin:vue/essential', 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', ], parserOptions: { - parser: '@babel/eslint-parser', - requireConfigFile: false, + parser: '@typescript-eslint/parser', + ecmaVersion: 2021, + sourceType: 'module', }, + parser: 'vue-eslint-parser', + overrides: [ + { + files: ['tests/**/*.ts'], + env: { + 'vitest/globals': true, + }, + plugins: ['vitest'], + }, + ], rules: { 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', diff --git a/.github/workflows/node.yml b/.github/workflows/node.yml index a83e4e3..bf4f3bd 100644 --- a/.github/workflows/node.yml +++ b/.github/workflows/node.yml @@ -52,7 +52,7 @@ jobs: run: npm run lint - name: Build library - run: npm run build:lib + run: npm run build - name: Check build changes run: | diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index e4a293a..0a2a906 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -47,7 +47,7 @@ jobs: CYPRESS_INSTALL_BINARY: 0 run: | npm i - npm run build:lib + npm run build - name: Publish to npm run: npm publish --provenance --access public diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 5c014b2..bc697bc 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -1,7 +1,7 @@ # SPDX-FileCopyrightText: 2026 LibreCode coop and contributors # SPDX-License-Identifier: AGPL-3.0-or-later -name: Deploy A DEMO +name: Deploy Demo on: workflow_dispatch: @@ -16,17 +16,28 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - - name: Set up Node.js + - name: Read package.json node and npm engines version + uses: skjnldsv/read-package-engines-version-actions@8205673bab74a63eb9b8093402fd9e0e018663a1 # v2.2 + id: versions + with: + fallbackNode: '^20' + fallbackNpm: '^10' + + - name: Set up node ${{ steps.versions.outputs.nodeVersion }} uses: actions/setup-node@v4 + with: + node-version: ${{ steps.versions.outputs.nodeVersion }} + + - name: Set up npm ${{ steps.versions.outputs.npmVersion }} + run: npm i -g 'npm@${{ steps.versions.outputs.npmVersion }}' - name: Install & Build run: | npm i - npm install -g cross-env - cross-env PUBLIC_PATH=/pdf-elements/ npm run build + npm run build:demo - name: Deploy uses: JamesIves/github-pages-deploy-action@v4 with: branch: gh-pages - folder: dist + folder: dist-demo diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..a572b9f --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,52 @@ +# SPDX-FileCopyrightText: 2026 LibreCode coop and contributors +# SPDX-License-Identifier: AGPL-3.0-or-later + +name: Tests + +on: + pull_request: + push: + branches: + - main + +permissions: + contents: read + +concurrency: + group: tests-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + test: + runs-on: ubuntu-latest + + name: NPM test + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Read package.json node and npm engines version + uses: skjnldsv/read-package-engines-version-actions@8205673bab74a63eb9b8093402fd9e0e018663a1 # v2.2 + id: versions + with: + fallbackNode: '^20' + fallbackNpm: '^10' + + - name: Set up node ${{ steps.versions.outputs.nodeVersion }} + uses: actions/setup-node@v4 + with: + node-version: ${{ steps.versions.outputs.nodeVersion }} + + - name: Set up npm ${{ steps.versions.outputs.npmVersion }} + run: npm i -g 'npm@${{ steps.versions.outputs.npmVersion }}' + + - name: Install dependencies + env: + CYPRESS_INSTALL_BINARY: 0 + PUPPETEER_SKIP_DOWNLOAD: true + run: npm i + + - name: Test + run: npm run test diff --git a/.npmignore b/.npmignore index 438781d..534324e 100644 --- a/.npmignore +++ b/.npmignore @@ -4,12 +4,16 @@ # Source files src/ examples/ +tests/ # Config files .babelrc .eslintrc.js -vue.config.js +env.d.ts postcss.config.js +tsconfig.json +vite.config.ts +vitest.config.ts REUSE.toml LICENSES/ CONTRIBUTING.md diff --git a/README.md b/README.md index 58d8d76..b0e442c 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,16 @@ SPDX-License-Identifier: AGPL-3.0-or-later # PDF Elements -A Vue 2 component for rendering PDFs with draggable and resizable element overlays. +A Vue 3 component for rendering PDFs with draggable and resizable element overlays. **[Demo](https://libresign.github.io/pdf-elements/)** · [Examples](examples/) +## Development + +- `npm run dev` - Run the demo with Vite +- `npm run build` - Build the library (ESM + types) +- `npm run build:demo` - Build the demo to `dist-demo` + ## API ### Props @@ -28,6 +34,23 @@ A Vue 2 component for rendering PDFs with draggable and resizable element overla | `ignoreClickOutsideSelectors` | Array | `[]` | CSS selectors that keep the selection active when clicking outside the element | | `pageCountFormat` | String | `'{currentPage} of {totalPages}'` | Format string for page counter | | `autoFitZoom` | Boolean | `false` | Automatically adjust zoom to fit viewport on window resize | +| `pdfjsOptions` | Object | `{}` | Options passed to PDF.js `getDocument` (advanced) | + +### PDF.js options + +`pdfjsOptions` is forwarded to PDF.js `getDocument(...)` and can be used to tune performance. + +Example: + +```ts + +``` ### Events diff --git a/REUSE.toml b/REUSE.toml index a6d2e50..90cb2c5 100644 --- a/REUSE.toml +++ b/REUSE.toml @@ -12,11 +12,15 @@ default-copyright = "2025 LibreCode coop and contributors" path = [ ".babelrc", ".eslintrc.js", + "env.d.ts", "package.json", "package-lock.json", "postcss.config.js", - "vue.config.js", + "tsconfig.json", + "vite.config.ts", + "vitest.config.ts", "examples/**", + "tests/**", "dist/**", ] precedence = "aggregate" diff --git a/env.d.ts b/env.d.ts new file mode 100644 index 0000000..2c3ed98 --- /dev/null +++ b/env.d.ts @@ -0,0 +1,7 @@ +/// + +declare module '*.vue' { + import type { DefineComponent } from 'vue' + const component: DefineComponent, Record, unknown> + export default component +} diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..9faac68 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,94 @@ +// SPDX-FileCopyrightText: 2026 LibreCode coop and contributors +// SPDX-License-Identifier: AGPL-3.0-or-later + +const js = require('@eslint/js') +const globals = require('globals') +const vue = require('eslint-plugin-vue') +const tsPlugin = require('@typescript-eslint/eslint-plugin') +const tsParser = require('@typescript-eslint/parser') +const vueParser = require('vue-eslint-parser') +const vitest = require('eslint-plugin-vitest') + +const vitestGlobals = { + afterAll: 'readonly', + afterEach: 'readonly', + beforeAll: 'readonly', + beforeEach: 'readonly', + describe: 'readonly', + expect: 'readonly', + it: 'readonly', + test: 'readonly', + vi: 'readonly', +} + +module.exports = [ + { + ignores: ['dist/**', 'dist-demo/**', 'node_modules/**', '.eslintrc.js'], + }, + js.configs.recommended, + { + files: ['**/*.{ts,vue}'], + languageOptions: { + parser: vueParser, + parserOptions: { + parser: tsParser, + ecmaVersion: 2021, + sourceType: 'module', + }, + globals: { + ...globals.browser, + ...globals.es2021, + }, + }, + plugins: { + vue, + '@typescript-eslint': tsPlugin, + }, + rules: { + ...vue.configs['flat/essential'].rules, + ...tsPlugin.configs.recommended.rules, + 'no-undef': 'off', + '@typescript-eslint/no-explicit-any': 'off', + 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', + 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', + }, + }, + { + files: ['eslint.config.js', '**/*.config.js', '**/*.config.cjs', 'postcss.config.js'], + languageOptions: { + globals: { + ...globals.node, + ...globals.es2021, + }, + sourceType: 'script', + }, + rules: { + 'no-undef': 'off', + }, + }, + { + files: ['vite.config.ts', 'vitest.config.ts'], + languageOptions: { + globals: { + ...globals.node, + ...globals.es2021, + }, + }, + }, + { + files: ['tests/**/*.ts'], + plugins: { + vitest, + }, + languageOptions: { + globals: { + ...globals.browser, + ...globals.es2021, + ...vitestGlobals, + }, + }, + rules: { + ...(vitest.configs?.recommended?.rules || {}), + }, + }, +] diff --git a/examples/basic/App.vue b/examples/basic/App.vue index 6ed1217..15df9bc 100644 --- a/examples/basic/App.vue +++ b/examples/basic/App.vue @@ -56,8 +56,8 @@ SPDX-License-Identifier: AGPL-3.0-or-later -