Skip to main content

CnSignatureCapture

Typed + drawn signature widget with an affirmation checkbox and an audit-payload emit. For sign-plan / sign-off / e-signature flows where a typed name or a free-hand canvas stroke is sufficient evidence (cryptographic signatures live elsewhere).

Two capture modes:

  • typed — text input rendered in a signature-style font.
  • drawn<canvas> with mouse + touch handlers producing a PNG data-URL.

The user toggles modes via a radio group when both are allowed; otherwise the single allowed mode renders directly.

Try it

<template>
<CnSignatureCapture
:allow-typed="true"
:allow-drawn="true"
affirmation="I confirm the plan is accurate."
@change="onSigned" />
</template>

<script>
import { CnSignatureCapture } from '@conduction/nextcloud-vue'

export default {
components: { CnSignatureCapture },
methods: {
onSigned({ mode, value, affirmed, audit }) {
// mode: 'typed' | 'drawn'
// value: text (typed) | 'data:image/png;base64,…' (drawn)
// affirmed: boolean (only meaningful when affirmation prop is set)
// audit: { capturedAt, mode, canvasWidth?, canvasHeight? }
},
},
}
</script>

Props

PropTypeDefaultDescription
allowTypedBooleantrueEnable the typed-signature mode.
allowDrawnBooleantrueEnable the drawn-signature canvas.
initialMode'typed'|'drawn''typed'Preferred starting mode when both are allowed.
affirmationString''Optional affirmation text rendered next to a checkbox. Empty hides the checkbox.
canvasWidthNumber360Drawn-mode canvas width (used in the emitted PNG).
canvasHeightNumber120Drawn-mode canvas height.
lineWidthNumber2Stroke width for drawn mode.
strokeColorString'#000'Stroke colour (CSS colour string).
typedFontString'"Brush Script MT", cursive'Font family for the typed-signature preview.
typedPlaceholderString'Type your name'Typed input + preview placeholder.
typedAriaLabelString'Typed signature input'ARIA label for the typed input.
drawnAriaLabelString'Drawn signature canvas'ARIA label for the canvas.
drawnHintString'Draw your signature inside the box.'Hint text under the canvas.
typedModeLabelString'Type'Mode-picker label for typed mode.
drawnModeLabelString'Draw'Mode-picker label for drawn mode.
clearLabelString'Clear'Clear-button label.

Events

EventPayloadDescription
change{ mode, value, affirmed, audit }Emitted on every state mutation (typed input, stroke end, mode switch, affirmation toggle, clear).

Public methods

MethodSignatureDescription
getSignature()Return the current payload (same shape as change) without emitting. Useful for snapshotting on submit.
clear()Reset both modes' content + affirmation. Emits a change with empty value.

Audit payload

Every emit carries an audit block:

{
capturedAt: '2026-05-20T17:34:12.123Z', // ISO timestamp
mode: 'typed' | 'drawn',
canvasWidth?: number, // drawn mode only
canvasHeight?: number, // drawn mode only
}

Persist audit alongside the signed document so the server-side record carries the capture metadata.

What this widget is NOT

  • A cryptographic signature (no PKI, no chain-of-trust). Use @nextcloud/openssl or an external e-sign service for binding signatures.
  • A biometric capture (no pressure / velocity sampling).

The component is for evidentiary-typed/drawn signatures where the user's intent is recorded; the legal binding is handled by the consuming app's policy.

See also