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​