diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 0000000..e6fca03
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,70 @@
+# SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+name: Bug report
+description: Report a reproducible problem in PDF Elements
+title: "[Bug]: "
+labels:
+ - bug
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thanks for helping improve PDF Elements. Please provide a minimal, reproducible report and do not upload confidential PDFs.
+
+ - type: textarea
+ id: description
+ attributes:
+ label: What happened?
+ description: Describe the problem and what you expected instead.
+ placeholder: Tell us what you observed and what should have happened.
+ validations:
+ required: true
+
+ - type: textarea
+ id: reproduce
+ attributes:
+ label: Steps to reproduce
+ description: Include the smallest set of steps, code or sample needed to reproduce the issue.
+ placeholder: |
+ 1. Render PDFElements with...
+ 2. Add an element...
+ 3. Resize...
+ validations:
+ required: true
+
+ - type: input
+ id: version
+ attributes:
+ label: PDF Elements version
+ placeholder: e.g. 1.2.7
+ validations:
+ required: true
+
+ - type: input
+ id: vue
+ attributes:
+ label: Vue version
+ placeholder: e.g. 3.5.28
+
+ - type: input
+ id: environment
+ attributes:
+ label: Browser and operating system
+ placeholder: e.g. Firefox 143 on Fedora 42
+
+ - type: textarea
+ id: logs
+ attributes:
+ label: Console output or screenshots
+ description: Paste relevant logs or drag screenshots here. Remove secrets and sensitive data.
+
+ - type: checkboxes
+ id: checks
+ attributes:
+ label: Before submitting
+ options:
+ - label: I searched existing issues for duplicates.
+ required: true
+ - label: I removed confidential or sensitive information from the report.
+ required: true
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 0000000..6523418
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,11 @@
+# SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+blank_issues_enabled: true
+contact_links:
+ - name: Live demo
+ url: https://libresign.github.io/pdf-elements/
+ about: Reproduce and explore PDF Elements behavior in the browser.
+ - name: LibreSign
+ url: https://github.com/LibreSign/libresign
+ about: Report issues that belong to the LibreSign application rather than the PDF Elements component.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
new file mode 100644
index 0000000..94a3cbb
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -0,0 +1,51 @@
+# SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+name: Feature request
+description: Propose an improvement or new use case for PDF Elements
+title: "[Feature]: "
+labels:
+ - enhancement
+body:
+ - type: textarea
+ id: problem
+ attributes:
+ label: What problem would this solve?
+ description: Describe the user or developer problem before describing the solution.
+ validations:
+ required: true
+
+ - type: textarea
+ id: use-case
+ attributes:
+ label: Use case
+ description: Show where this would be useful in a real PDF or document workflow.
+ validations:
+ required: true
+
+ - type: textarea
+ id: proposal
+ attributes:
+ label: Proposed solution
+ description: Describe an API, UI or behavior if you already have an approach in mind.
+
+ - type: textarea
+ id: alternatives
+ attributes:
+ label: Alternatives considered
+ description: Include workarounds or alternative approaches you have tried.
+
+ - type: checkboxes
+ id: contribution
+ attributes:
+ label: Contribution
+ options:
+ - label: I would be interested in working on this change.
+
+ - type: checkboxes
+ id: checks
+ attributes:
+ label: Before submitting
+ options:
+ - label: I searched existing issues for similar requests.
+ required: true
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 0000000..9f9d30f
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,20 @@
+
+
+## What does this change?
+
+Describe the problem and the approach used to solve it.
+
+## How was it tested?
+
+List the automated or manual checks you ran.
+
+## Checklist
+
+- [ ] The change is focused on one problem.
+- [ ] Tests were added or updated when behavior changed.
+- [ ] Documentation was updated when public behavior or APIs changed.
+- [ ] `npm run lint`, `npm run typecheck`, `npm run test` and `npm run build` pass when applicable.
+- [ ] New source files include SPDX headers.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 3149c1c..9a60c70 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -5,67 +5,113 @@ SPDX-License-Identifier: AGPL-3.0-or-later
# Contributing to @libresign/pdf-elements
-Thank you for your interest in contributing to @libresign/pdf-elements! We welcome contributions from the community.
+Contributions are welcome. You do not need to work on a large feature to help: bug reports, reproduction cases, documentation, accessibility improvements, tests and focused code changes are all useful.
-## Code of Conduct
+## Before you start
+
+- Check the [open issues](https://github.com/LibreSign/pdf-elements/issues) to avoid duplicate work.
+- For a substantial behavior or API change, open an issue first so the approach can be discussed before implementation.
+- Keep pull requests focused on one problem whenever possible.
+
+## Reporting bugs
+
+Use the bug report template and include:
+
+- a clear description of the problem;
+- exact steps to reproduce it;
+- expected and actual behavior;
+- browser and operating-system information when relevant;
+- a minimal reproduction or sample PDF when possible;
+- screenshots or console output when they help explain the issue.
+
+Please avoid attaching confidential or sensitive documents.
+
+## Suggesting improvements
+
+Feature requests are welcome. Describe the user problem first, then the proposed solution. Concrete use cases make requests easier to evaluate and implement.
+
+Good contributions are not limited to new features. Improvements to documentation, test coverage, accessibility, performance and developer experience are also valuable.
+
+## Development setup
+
+1. Fork the repository.
+2. Clone your fork:
-This project follows the LibreSign Code of Conduct. By participating, you are expected to uphold this code.
+ ```bash
+ git clone https://github.com/YOUR-USERNAME/pdf-elements.git
+ cd pdf-elements
+ ```
-## How to Contribute
+3. Install dependencies:
-### Reporting Bugs
+ ```bash
+ npm ci
+ ```
-Before creating bug reports, please check the issue list as you might find out that you don't need to create one. When you are creating a bug report, please include as many details as possible:
+4. Start the demo:
-* Use a clear and descriptive title
-* Describe the exact steps which reproduce the problem
-* Provide specific examples to demonstrate the steps
-* Describe the behavior you observed after following the steps
-* Explain which behavior you expected to see instead and why
-* Include screenshots if possible
+ ```bash
+ npm run dev
+ ```
-### Suggesting Enhancements
+5. Create a focused branch and make your changes.
-Enhancement suggestions are tracked as GitHub issues. When creating an enhancement suggestion, please include:
+## Validate your change
-* Use a clear and descriptive title
-* Provide a detailed description of the suggested enhancement
-* Provide examples of how the enhancement would be used
-* Explain why this enhancement would be useful
+Run the checks relevant to your change before opening a pull request:
-### Pull Requests
+```bash
+npm run lint
+npm run typecheck
+npm run test
+npm run build
+```
-* Fill in the required template
-* Follow the JavaScript/Vue.js style guide
-* Include SPDX headers in all new files
-* Update the README.md with details of changes if needed
-* Update the CHANGELOG.md following Keep a Changelog format
-* Ensure all tests pass and linting is clean
+For user-interface or browser behavior changes, also run:
-## Development Setup
+```bash
+npm run test:e2e
+```
-1. Fork the repository
-2. Clone your fork: `git clone https://github.com/YOUR-USERNAME/pdf-elements.git`
-3. Install dependencies: `npm install`
-4. Create a feature branch: `git checkout -b my-feature`
-5. Make your changes
-6. Run lint: `npm run lint`
-7. Build the library: `npm run build:lib`
-8. Commit your changes: `git commit -am 'Add some feature'`
-9. Push to the branch: `git push origin my-feature`
-10. Create a Pull Request
+The CI executes linting, type checking, package validation, unit tests and Playwright coverage.
-## Coding Standards
+## Pull requests
-* Use 2 spaces for indentation
-* Follow Vue.js style guide
-* Add SPDX headers to all source files:
- ```javascript
- // SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
- // SPDX-License-Identifier: AGPL-3.0-or-later
+A good pull request should:
+
+- explain the problem being solved;
+- describe the approach taken;
+- include regression coverage for bug fixes when practical;
+- update documentation when public behavior changes;
+- include SPDX headers in new source files;
+- keep unrelated refactors out of the same change.
+
+Use meaningful Conventional Commit-style messages where possible, for example:
+
+```
+fix: keep element coordinates after zoom
+feat: expose custom page footer slot
+docs: add worker configuration example
+test: cover cancelled element placement
+```
+
+## Coding standards
+
+- Follow the existing Vue and TypeScript conventions in the repository.
+- Use the repository ESLint configuration instead of manually formatting around lint rules.
+- Add SPDX headers to new source files:
+
+ ```text
+ SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
+ SPDX-License-Identifier: AGPL-3.0-or-later
```
-* Write meaningful commit messages
-* Keep pull requests focused on a single feature or fix
+
+- Prefer small components and focused changes.
+- Add or update tests for behavior changes.
+
+## Code of Conduct
+
+This project follows the [LibreSign Code of Conduct](https://github.com/LibreSign/libresign/blob/main/CODE_OF_CONDUCT.md). By participating, you are expected to follow it.
## License
diff --git a/README.md b/README.md
index c0df9e2..93b6adb 100644
--- a/README.md
+++ b/README.md
@@ -5,119 +5,50 @@ SPDX-License-Identifier: AGPL-3.0-or-later
# PDF Elements
-A Vue 3 component for rendering PDFs with draggable and resizable element overlays.
+[](https://www.npmjs.com/package/@libresign/pdf-elements)
+[](https://github.com/LibreSign/pdf-elements/actions/workflows/node.yml)
+[](https://github.com/LibreSign/pdf-elements/actions/workflows/tests.yml)
-**[Demo](https://libresign.github.io/pdf-elements/)** · [Examples](examples/)
+A Vue 3 PDF viewer for building interactive document workflows with draggable, resizable and fully customizable overlay elements.
+
+Use it to build signature placement, form-field positioning, annotations, review tools, document preparation flows and other PDF experiences where users need to place or manipulate elements on top of a document.
+
+**[Try the live demo](https://libresign.github.io/pdf-elements/)** · [Getting started](docs/GETTING_STARTED.md) · [API](docs/API.md) · [Examples](examples/) · [Contributing](CONTRIBUTING.md)

-## 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
-
-| Prop | Type | Default | Description |
-|------|------|---------|-------------|
-| `width` | String | `'100%'` | Container width |
-| `height` | String | `'100%'` | Container height |
-| `initFiles` | Array | `[]` | PDF files to load |
-| `initFileNames` | Array | `[]` | Names for the PDF files |
-| `initialScale` | Number | `1` | Initial zoom scale |
-| `showPageFooter` | Boolean | `true` | Show page footer with document name and page number |
-| `hideSelectionUI` | Boolean | `false` | Hide selection handles and actions UI |
-| `showSelectionHandles` | Boolean | `true` | Show resize/move handles on selected elements |
-| `showElementActions` | Boolean | `true` | Show action buttons on selected elements |
-| `readOnly` | Boolean | `false` | Disable drag, resize, and actions for elements |
-| `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
-
-- `pdf-elements:end-init` - Emitted when PDF is loaded
-- `pdf-elements:adding-ended` - Emitted when interactive placement ends. Payload: `{ reason: 'placed', object, docIndex, pageIndex }` on success or `{ reason: 'cancelled' }` when the placement is cancelled.
-
-### Exposed methods
-
-- `startAddingElement(templateObject)` - Starts interactive placement mode.
-- `cancelAdding()` - Cancels the current placement session and emits `pdf-elements:adding-ended` with `{ reason: 'cancelled' }` when a session was active.
-
-### Slots
-
-- `element-{type}` - Custom element rendering (e.g., `element-signature`)
-- `custom` - Fallback for elements without specific type
-- `actions` - Custom action buttons
-
-#### `actions` slot props
-
-The `actions` slot receives:
-
-- `object`
-- `onDelete`
-- `onDuplicate`
-- `toolbarClass` (`pdf-elements-actions-toolbar`)
-- `actionClass` (`pdf-elements-action-btn`)
-- `actionAttrs` (`{ 'data-pdf-elements-action': 'true' }`)
-
-Use these hooks to style third-party button components consistently (for example, Nextcloud `NcButton`) without relying on internal scoped selectors.
-
-Example:
-
-```vue
-
-
- Duplicate
-
-
-```
-
-### Theme variables
-
-Action toolbar and action buttons can be themed via CSS variables and follow host theme tokens by default.
-
-| Variable | Description |
-|---|---|
-| `--pdf-elements-toolbar-gap` | Toolbar button gap |
-| `--pdf-elements-toolbar-padding` | Toolbar padding |
-| `--pdf-elements-toolbar-background` | Toolbar background color |
-| `--pdf-elements-toolbar-color` | Toolbar text/icon color |
-| `--pdf-elements-toolbar-border-color` | Toolbar border color |
-| `--pdf-elements-toolbar-border-radius` | Toolbar border radius |
-| `--pdf-elements-toolbar-shadow` | Toolbar shadow |
-| `--pdf-elements-action-btn-border` | Action button border |
-| `--pdf-elements-action-btn-background` | Action button background |
-| `--pdf-elements-action-btn-color` | Action button text/icon color |
-| `--pdf-elements-action-btn-padding` | Action button padding |
-| `--pdf-elements-action-btn-radius` | Action button border radius |
-| `--pdf-elements-action-btn-min-height` | Action button min height |
-| `--pdf-elements-action-btn-min-width` | Action button min width |
-| `--pdf-elements-action-btn-shadow` | Action button shadow |
-| `--pdf-elements-action-btn-hover-background` | Action button hover background |
+## Why PDF Elements?
+
+PDF rendering is only part of many document workflows. Applications often also need to let users place, move, resize, inspect or remove interactive elements over PDF pages.
+
+PDF Elements provides that interaction layer as a reusable Vue 3 component.
+
+- **PDF.js-based rendering** for browser PDF viewing
+- **Draggable and resizable overlays** positioned directly on PDF pages
+- **Custom element types** rendered through Vue slots
+- **Interactive placement mode** for adding elements to a document
+- **Multiple PDF documents** in the same component
+- **Read-only mode** for review and presentation flows
+- **Custom action toolbars** for host-application controls
+- **Themeable UI** using CSS variables
+- **Typed public API** for TypeScript projects
+
+PDF Elements does **not** cryptographically sign or modify the PDF by itself. It focuses on the browser interaction layer, so it can be connected to signing, storage, form or document-processing backends.
+
+## Use cases
+
+PDF Elements can be used for:
+
+- electronic-signature and document-preparation interfaces;
+- signature, initials, date or text placement;
+- PDF annotation and review tools;
+- document form builders;
+- approval and document workflows;
+- applications that need coordinates and sizing for PDF overlays.
+
+## Documentation
+
+- [Getting started](docs/GETTING_STARTED.md)
+- [API reference](docs/API.md)
+- [Basic example](examples/basic/)
+- [Contributing](CONTRIBUTING.md)
diff --git a/docs/API.md b/docs/API.md
new file mode 100644
index 0000000..caa0a14
--- /dev/null
+++ b/docs/API.md
@@ -0,0 +1,105 @@
+
+
+# PDF Elements API
+
+## Props
+
+| Prop | Type | Default | Description |
+|------|------|---------|-------------|
+| `width` | String | `'100%'` | Container width |
+| `height` | String | `'100%'` | Container height |
+| `initFiles` | Array | `[]` | PDF files to load |
+| `initFileNames` | Array | `[]` | Names for the PDF files |
+| `initialScale` | Number | `1` | Initial zoom scale |
+| `showPageFooter` | Boolean | `true` | Show page footer with document name and page number |
+| `hideSelectionUI` | Boolean | `false` | Hide selection handles and actions UI |
+| `showSelectionHandles` | Boolean | `true` | Show resize/move handles on selected elements |
+| `showElementActions` | Boolean | `true` | Show action buttons on selected elements |
+| `readOnly` | Boolean | `false` | Disable drag, resize, and actions for elements |
+| `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` |
+
+## PDF.js options
+
+`pdfjsOptions` is forwarded to PDF.js `getDocument(...)`.
+
+```vue
+
+```
+
+## Events
+
+- `pdf-elements:end-init` - Emitted when PDF is loaded.
+- `pdf-elements:adding-ended` - Emitted when interactive placement ends. Payload: `{ reason: 'placed', object, docIndex, pageIndex }` on success or `{ reason: 'cancelled' }` when placement is cancelled.
+
+## Exposed methods
+
+- `startAddingElement(templateObject)` - Starts interactive placement mode.
+- `cancelAdding()` - Cancels the current placement session and emits `pdf-elements:adding-ended` with `{ reason: 'cancelled' }` when a session was active.
+
+## Slots
+
+- `element-{type}` - Custom element rendering, for example `element-signature`.
+- `custom` - Fallback for elements without a specific type slot.
+- `actions` - Custom action buttons.
+
+### `actions` slot props
+
+The `actions` slot receives:
+
+- `object`
+- `onDelete`
+- `onDuplicate`
+- `toolbarClass` (`pdf-elements-actions-toolbar`)
+- `actionClass` (`pdf-elements-action-btn`)
+- `actionAttrs` (`{ 'data-pdf-elements-action': 'true' }`)
+
+These hooks allow host applications to style third-party button components consistently without depending on internal scoped selectors.
+
+```vue
+
+
+ Duplicate
+
+
+```
+
+## Theme variables
+
+Action toolbar and action buttons can be themed via CSS variables and follow host theme tokens by default.
+
+| Variable | Description |
+|---|---|
+| `--pdf-elements-toolbar-gap` | Toolbar button gap |
+| `--pdf-elements-toolbar-padding` | Toolbar padding |
+| `--pdf-elements-toolbar-background` | Toolbar background color |
+| `--pdf-elements-toolbar-color` | Toolbar text/icon color |
+| `--pdf-elements-toolbar-border-color` | Toolbar border color |
+| `--pdf-elements-toolbar-border-radius` | Toolbar border radius |
+| `--pdf-elements-toolbar-shadow` | Toolbar shadow |
+| `--pdf-elements-action-btn-border` | Action button border |
+| `--pdf-elements-action-btn-background` | Action button background |
+| `--pdf-elements-action-btn-color` | Action button text/icon color |
+| `--pdf-elements-action-btn-padding` | Action button padding |
+| `--pdf-elements-action-btn-radius` | Action button border radius |
+| `--pdf-elements-action-btn-min-height` | Action button min height |
+| `--pdf-elements-action-btn-min-width` | Action button min width |
+| `--pdf-elements-action-btn-shadow` | Action button shadow |
+| `--pdf-elements-action-btn-hover-background` | Action button hover background |
diff --git a/docs/GETTING_STARTED.md b/docs/GETTING_STARTED.md
new file mode 100644
index 0000000..a9d7109
--- /dev/null
+++ b/docs/GETTING_STARTED.md
@@ -0,0 +1,55 @@
+
+
+# Getting started
+
+## Install
+
+```bash
+npm install @libresign/pdf-elements
+```
+
+## Basic usage
+
+```vue
+
+
+
+
+
+
+
+
{{ object.label }}
+
+
+
+```
+
+For a fuller integration with custom controls, actions and document handling, see the [basic example](../examples/basic/).
+
+For the available props, events, methods, slots and theme variables, see the [API reference](API.md).
diff --git a/package.json b/package.json
index 83700f0..31ec5a8 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@libresign/pdf-elements",
- "description": "PDF viewer with draggable and resizable element overlays for Vue 3",
+ "description": "Vue 3 PDF viewer with draggable and resizable overlay elements for document workflows",
"version": "1.2.7",
"author": "LibreCode ",
"private": false,
@@ -24,15 +24,21 @@
"bugs": {
"url": "https://github.com/LibreSign/pdf-elements/issues"
},
- "homepage": "https://github.com/LibreSign/pdf-elements#readme",
+ "homepage": "https://libresign.github.io/pdf-elements/",
"keywords": [
"pdf",
- "viewer",
+ "pdfjs",
+ "pdf-viewer",
+ "pdf-editor",
+ "document-workflow",
+ "electronic-signature",
"annotations",
+ "overlay",
"draggable",
"resizable",
- "libresign",
- "vue3"
+ "vue",
+ "vue3",
+ "libresign"
],
"scripts": {
"dev": "vite",