Skip to content

SignPdf

Drag-and-drop PDF signing with fixed placement, non-overlapping markers, and PDF export. The layout combines upload controls, zoom, signer list, and a detail panel so users aged 20–45 can review and finish documents without switching pages.

Example

Drag user chips into the canvas area to pin a signature where it belongs. In this demo, the page only provides persistence callbacks. SignPdf takes care of the upload UI, drag/drop, and saving signature fields automatically.

How it works:

  • Upload a PDF using the built-in upload control.
  • Drag a signer into the PDF to create a signature field.
  • The component saves fields as they are created or updated.
Code
vue
<script setup lang="ts">
import { SignPdf } from '@point-hub/papp'

const demoUsers = [
  { id: 'alya', name: 'Alya Rahma', initials: 'AR', label: 'Menyetujui' },
  { id: 'dimas', name: 'Dimas Pratama', initials: 'DP', label: 'Mengetahui' }
]
const currentUser = demoUsers[0]

const persistence = {
  uploadPdf: async (file: File) => {
    // Upload to your storage and return the PDF URL.
    return { pdfUrl: 'https://.../your.pdf', fileUrl: 'storage/..', fileName: file.name }
  },
  createDocument: async ({ title, fileUrl, ownerId }) => {
    // Save document metadata to your DB and return the document ID.
    return 'docId'
  },
  saveSignatureField: async ({ docId, signature }) => {
    // Persist each field (page, x, y, width, height, assignedTo, signed, signedAt).
  }
}
</script>

<template>
  <SignPdf :users="demoUsers" :current-user="currentUser" :persistence="persistence" />
</template>

SignPdf API

Types

ts
export interface SignPdfUser {
  id: number | string
  name: string
  initials?: string
  role?: string
  label?: string
}

export interface PdfSignerSignature {
  id: string
  x: number
  y: number
  width: number
  height: number
  page: number
  userId: number | string | null
  name: string
  initials: string
  label?: string
  signed: boolean
}

export interface PdfSignerPersistence {
  uploadPdf?: (file: File) => Promise<{ pdfUrl: string; fileUrl?: string; fileName?: string }>
  createDocument?: (payload: { title: string; fileUrl?: string; ownerId: number | string | null }) => Promise<string>
  saveSignatureField?: (payload: {
    docId: string | null
    signature: PdfSignerSignature
    action: 'create' | 'update' | 'sign'
  }) => Promise<void>
  lockSignatures?: (docId: string | null, signatures: PdfSignerSignature[]) => Promise<void>
}

Props

PropTypeDefaultDescription
usersSignPdfUser[]built-in demo listSigners that can be dragged to the canvas.
fontUrlstring/fonts/DancingScript.ttfFont used when exporting signed fields with Dancing Script initials.
initialScalenumber0.8Initial zoom for the rendered page.
minScalenumber0.6Minimum zoom level.
maxScalenumber2.4Maximum zoom level.
currentUser`SignPdfUsernull`null
pdfUrlstring''PDF source URL to load immediately.
documentId`stringnull`null
persistencePdfSignerPersistenceundefinedOptional persistence hooks (upload, save fields, etc.).
enableUploadbooleantrueShow or hide the built-in upload control.

Events

EventPayloadWhen
signature:createPdfSignerSignatureA signature field is added to the canvas.
signature:updatePdfSignerSignatureA signature field finishes moving.
signature:signPdfSignerSignatureA signature field is signed by the active user.

Exposed methods

MethodReturnsDescription
getSignatures()PdfSignerSignature[]Read all signature fields on the canvas.
getDocumentId()`stringnull`
lockPositions()voidLock signature positions to prevent dragging.

Released under the MIT License.