@signosoft/signpad-js 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ PROPRIETARY COMMERCIAL LICENSE
2
+
3
+ Copyright (c) 2026, Signosoft
4
+
5
+ This software, "@signosoft/signpad-js", is proprietary to Signosoft and is protected by copyright laws.
6
+
7
+ **A valid, paid, and active commercial license agreement with Signosoft is strictly required for the use, operation, reproduction, distribution, or any deployment of this software in any environment, including but not limited to development, testing, staging, and production.**
8
+
9
+ Any use of this software without a current, valid, and fully paid commercial license from Signosoft is expressly prohibited. Unauthorized use constitutes a violation of our intellectual property rights and the terms of this license.
10
+
11
+ In the event that Signosoft discovers unauthorized use of this software, appropriate legal action may be pursued to enforce our rights and seek damages, including but not limited to injunctive relief, monetary compensation, and recovery of legal costs, in accordance with applicable laws.
12
+
13
+ You may not reverse-engineer, decompile, disassemble, or attempt to derive the source code of this software, except as permitted by applicable law.
14
+
15
+ For information on how to obtain a valid commercial license, including terms, pricing, and support, please contact Signosoft directly:
16
+
17
+ Email: [esign@signosoft.com]
18
+ Website: [https://www.signosoft.com]
19
+
20
+ ALL RIGHTS RESERVED.
package/README.md ADDED
@@ -0,0 +1,242 @@
1
+ # @signosoft/signpad-js
2
+
3
+ [![npm version](https://badge.fury.io/js/%40signosoft%2Fsignpad-js.svg)](https://www.npmjs.com/package/@signosoft)
4
+ [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](LICENSE)
5
+
6
+ A LitElement web component for capturing signatures using a tablet (like Wacom) or mouse input, integrating seamlessly with the Signosoft signature driver powered by WebAssembly.
7
+
8
+ ## Table of Contents
9
+
10
+ - [Features](#features)
11
+ - [Installation](#installation)
12
+ - [Usage](#usage)
13
+ - [Basic HTML Integration](#basic-html-integration)
14
+ - [JavaScript Integration](#javascript-integration)
15
+ - [Properties](#properties)
16
+ - [Events](#events)
17
+ - [Public Methods](#public-methods)
18
+ - [Styling](#styling)
19
+
20
+ ## Features
21
+
22
+ - **Plug-and-Play Web Component:** Easily integrate into any web application or framework.
23
+ - **Wacom Tablet Integration:** Connects with Signosoft's signature driver for high-fidelity pen input from supported tablets, utilizing WebAssembly for driver communication.
24
+ - **Mouse Input Fallback:** Provides a seamless fallback to mouse input if a tablet is not connected or detected.
25
+ - **Customizable UI:** Control visibility of top/bottom bars, action buttons (OK, Clear, Cancel), and text elements.
26
+ - **Styling Flexibility:** Apply custom CSS variables to match your application's theme.
27
+ - **Event-Driven:** Emits custom events for pen movements, signature actions (OK, Clear, Cancel), and connection status.
28
+ - **TypeScript Support:** Fully typed for a robust development experience.
29
+
30
+ ## Installation
31
+
32
+ You can install the component via npm:
33
+
34
+ ```bash
35
+ npm install @signosoft/signpad-js
36
+ ```
37
+
38
+ ## Usage
39
+
40
+ ### Basic HTML Integration
41
+
42
+ Once installed, you can simply include the component in your HTML. Make sure your build process (e.g., Vite) correctly bundles the component for browser usage.
43
+
44
+ ```html
45
+ <signosoft-signpad
46
+ licenseKey="YOUR_BACKEND_LICENSE_KEY_HERE"
47
+ .okButton="${async () => console.log("OK Button Pressed from outside!")}
48
+ .clearButton=${async () => console.log("Clear Button Pressed from outside!")}
49
+ .cancelButton=${async () => console.log("Cancel Button Pressed from outside!")}
50
+
51
+ @sign-ok=${(e: CustomEvent) => console.log("Signature OK event:", e.detail)}
52
+ @sign-clear=${(e: CustomEvent) => console.log("Signature Clear event:", e.detail)}
53
+ @sign-cancel=${(e: CustomEvent) => console.log("Signature Cancel event:", e.detail)}
54
+ @sign-pen=${(e: CustomEvent) => {console.log('Pen data:', e.detail) }}
55
+ @sign-disconnect=${() => console.log("Device disconnected!")}
56
+ @sign-error=${(e: CustomEvent) => console.error("Signpad error:", e.detail)}
57
+ </signosoft-signpad>
58
+ <button
59
+ onclick="document.querySelector('signosoft-signpad').connectTablet(true)"
60
+ >
61
+ External Connect
62
+ </button>
63
+ <button
64
+ onclick="document.querySelector('signosoft-signpad').disconnectTablet()"
65
+ >
66
+ External Disconnect
67
+ </button>
68
+ <button onclick="document.querySelector('signosoft-signpad').clear()">
69
+ External Clear
70
+ </button>
71
+ <button onclick="document.querySelector('signosoft-signpad').ok()">
72
+ External OK
73
+ </button>
74
+ <button onclick="document.querySelector('signosoft-signpad').cancel()">
75
+ External Cancel
76
+ </button>
77
+ ```
78
+
79
+ Note: Remember to replace `YOUR_BACKEND_LICENSE_KEY_HERE` with your actual backend license key for the Signosoft driver. The paths to the script might need adjustment based on your specific project setup and how you bundle the component.
80
+
81
+ ### JavaScript Integration
82
+
83
+ You can also interact with the component programmatically:
84
+
85
+ ```typescript
86
+ import { SignosoftSignpad } from "@signosoft/signpad-js";
87
+
88
+ // If you're using a bundler (like Vite, Webpack), the component might be automatically registered.
89
+ // If not, or for explicit registration, you can do:
90
+ if (!customElements.get("signosoft-signpad")) {
91
+ customElements.define("signosoft-signpad", SignosoftSignpad);
92
+ }
93
+
94
+ const signpad = document.createElement("signosoft-signpad") as SignosoftSignpad;
95
+ signpad.licenseKey = "YOUR_BACKEND_LICENSE_KEY_HERE";
96
+ signpad.topBarVisible = true;
97
+ signpad.bottomBarVisible = true;
98
+ signpad.minThickness = 2;
99
+ signpad.maxThickness = 8;
100
+ signpad.penColor = "blue";
101
+
102
+ // Assign callback functions for internal button actions
103
+ signpad.OkButton = async () => {
104
+ console.log("Custom OK action triggered!");
105
+ // Here, you would typically retrieve the signature image/data
106
+ // For example: const imageData = await signpad.getSignatureImage(); // (if such a method existed)
107
+ // Then process or send the signature data.
108
+ };
109
+
110
+ signpad.ClearButton = async () => {
111
+ console.log("Custom Clear action triggered!");
112
+ };
113
+
114
+ signpad.CancelButton = async () => {
115
+ console.log("Custom Cancel action triggered!");
116
+ };
117
+
118
+ // Listen for custom events
119
+ signpad.addEventListener("sign-ok", (event) => {
120
+ console.log("Signature confirmed:", event.detail);
121
+ });
122
+ signpad.addEventListener("sign-error", (event) => {
123
+ console.error("An error occurred:", event.detail);
124
+ });
125
+ signpad.addEventListener("sign-pen", (event) => {
126
+ // console.log('Pen data:', event.detail);
127
+ });
128
+
129
+ document.body.appendChild(signpad);
130
+
131
+ // Programmatically connect the tablet
132
+ async function connectAndSign() {
133
+ const connected = await signpad.connectTablet(true); // Attempt auto-connect
134
+ if (connected) {
135
+ console.log("Tablet connected and ready for signing!");
136
+ } else {
137
+ console.warn("Could not connect to tablet.");
138
+ }
139
+ }
140
+
141
+ connectAndSign();
142
+
143
+ // To disconnect later:
144
+ // await signpad.disconnectTablet();
145
+ ```
146
+
147
+ ## Properties
148
+
149
+ You can customize the component's behavior and appearance using the following properties:
150
+
151
+ | Property | Type | Default Value | Description |
152
+ | :----------------------- | :--------------------------------- | :-------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
153
+ | `licenseKey` | `string` | `"DEBUG-licence-backend-key-localhost"` | Backend license key for the signature driver. **Crucial for driver functionality.** |
154
+ | `topBarVisible` | `boolean` | `true` | Controls the visibility of the top action bar (containing Clear, Disconnect/Connect buttons). |
155
+ | `bottomBarVisible` | `boolean` | `true` | Controls the visibility of the bottom action bar (containing OK, Clear, Cancel buttons). |
156
+ | `okButtonVisible` | `boolean` | `true` | Controls the visibility of the 'OK' button in the bottom bar. |
157
+ | `clearButtonVisible` | `boolean` | `true` | Controls the visibility of the 'Clear' button in the bottom bar. |
158
+ | `cancelButtonVisible` | `boolean` | `true` | Controls the visibility of the 'Cancel' button in the bottom bar. |
159
+ | `canvasLineVisible` | `boolean` | `true` | Controls the visibility of the line on the canvas that separates device state/additional text. |
160
+ | `deviceStateTextVisible` | `boolean` | `true` | Controls the visibility of the device state text in the canvas footer. |
161
+ | `customDeviceStateText` | `string \| null` | `null` | Optional custom text to display for the device state, overriding the default. |
162
+ | `minThickness` | `number` | `1` | Minimum pen stroke thickness in pixels. |
163
+ | `maxThickness` | `number` | `5` | Maximum pen stroke thickness in pixels (at full pressure). |
164
+ | `penColor` | `string` | `"#000000"` | Pen stroke color (CSS color, e.g., `'#000000'` or `'red'`). |
165
+ | `customCssVariables` | `Record<string, string>` | `{}` | An object containing CSS custom property names as keys and their values as strings. These will be applied directly to the component's host element for styling customization. E.g., `{ "--signpad-canvas-bg": "#f9f9f9" }`. |
166
+ | `OkButton` | `() => Promise<void> \| undefined` | `undefined` | Optional callback function (async or sync) to execute when the public `ok()` method is called, either internally or externally. It runs after the component's internal processing. |
167
+ | `ClearButton` | `() => Promise<void> \| undefined` | `undefined` | Optional callback function (async or sync) to execute when the public `clear()` method is called, either internally or externally. It runs after the component's internal processing. |
168
+ | `CancelButton` | `() => Promise<void> \| undefined` | `undefined` | Optional callback function (async or sync) to execute when the public `cancel()` method is called, either internally or externally. It runs after the component's internal processing. |
169
+ | `canvasAdditionalText` | `string \| null` | `null` | Optional additional text to display in the canvas footer. If `null` or empty, a default text will be shown. Default behavior is "Connect your device to start signing" when disconnected/error, and "Sign with [device name]" when connected. |
170
+
171
+ ## Events
172
+
173
+ The component dispatches several [custom events](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent) that you can listen for:
174
+
175
+ | Event Name | Detail Type (`event.detail`) | Description |
176
+ | :---------------- | :--------------------------- | :---------------------------------------------------------------------------------------------------------- |
177
+ | `sign-pen` | `PenData` | Fired on every pen movement (Wacom or mouse) with `penData` (x, y, pressure, inContact, etc.). |
178
+ | `sign-clear` | `void` | Fired when the signature is cleared (via internal UI button, tablet event, or `clear()` method). |
179
+ | `sign-cancel` | `void` | Fired when the signature process is cancelled (via internal UI button, tablet event, or `cancel()` method). |
180
+ | `sign-ok` | `void` | Fired when the 'OK' action is completed (via internal UI button, tablet event, or `ok()` method). |
181
+ | `sign-disconnect` | `void` | Fired if the tablet unexpectedly disconnects. |
182
+ | `sign-error` | `Error` | Fired when an error occurs during connection or initialization, or any other critical issue. |
183
+
184
+ ## Public Methods
185
+
186
+ You can programmatically control the component using its public methods:
187
+
188
+ | Method | Arguments | Returns | Description |
189
+ | :------------------- | :----------------------------------------- | :----------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
190
+ | `connectTablet()` | `autoConnect?: boolean` (default: `false`) | `Promise<boolean>` | Connects to the signature tablet. This involves obtaining a license, initializing the signature layer, connecting to the device, and starting the signing process. If `autoConnect` is `true`, it attempts to select the first available device automatically. Returns `true` on success, `false` otherwise. |
191
+ | `disconnectTablet()` | `void` | `Promise<void>` | Disconnects from the signature tablet and resets its state. |
192
+ | `clear()` | `void` | `Promise<void>` | Clears the current signature from both the tablet's screen and the component's canvas. Invokes the optional `ClearButton` external callback (if provided) and then dispatches a `sign-clear` custom event. |
193
+ | `ok()` | `void` | `Promise<void>` | Handles the 'OK' action, typically stopping the signing process. If an `OkButton` callback function is provided, it will be executed. Afterwards, a `sign-ok` custom event is dispatched. |
194
+ | `cancel()` | `void` | `Promise<void>` | Handles the 'Cancel' action, which typically clears any drawn signature and stops the signing process. If a `CancelButton` callback function is provided, it will be executed. Finally, a `sign-cancel` custom event is dispatched. |
195
+
196
+ ## Styling
197
+
198
+ The component can be styled using standard CSS and by overriding custom CSS variables on the host element (`<signosoft-signpad>`) or through the `customCssVariables` property.
199
+
200
+ Example of custom CSS variables (check `signosoft-signpad.css` for a full list of available variables):
201
+
202
+ ```css
203
+ export const myCustomSignpadTheme = {
204
+ // Top Bar
205
+ "--sign-top-bar-bg-base": "#e3e4fc",
206
+ "--sign-top-bar-text-base": "#4e56ea",
207
+
208
+ // Canvas Area
209
+ "--sign-canvas-bg-base": "#f1f2fd",
210
+
211
+ // Line
212
+ "--sign-line-height-base": "22px",
213
+ "--sign-line-border-base": "#7178ee",
214
+ "--sign-line-additional-text-color": "#333E4A",
215
+
216
+ // Bottom Bar
217
+ "--sign-bottom-bar-bg-base": "#e3e4fc",
218
+
219
+ // Primary Buttons (OK, Clear, Cancel)
220
+ "--sign-button-primary-bg-base": "#4e56ea",
221
+ "--sign-button-primary-bg-hover": "#7178ee",
222
+ "--sign-button-primary-bg-disabled": "#b5b9be",
223
+ "--sign-button-primary-text-base": "#ffffff",
224
+ "--sign-button-primary-text-hover": "#ffffff",
225
+ "--sign-button-primary-text-disabled": "white",
226
+
227
+ // Link Buttons (Connect signpad)
228
+ "--sign-button-link-bg-base": "transparent",
229
+ "--sign-button-link-bg-hover": "#e3e4fc",
230
+ "--sign-button-link-bg-disabled": "transparent",
231
+ "--sign-button-link-text-base": "#4e56ea",
232
+ "--sign-button-link-text-hover": "#7178ee",
233
+ "--sign-button-link-text-disabled": "#b5b9be",
234
+ "--sign-button-link-border-base": "1px solid #4e56ea",
235
+ "--sign-button-link-border-hover": "1px solid #7178ee",
236
+ "--sign-button-link-border-disabled": "1px solid #b5b9be",
237
+
238
+ // Device State Text Colors
239
+ "--sign-device-state-text-color-connected": "green",
240
+ "--sign-device-state-text-color-disconnected": "red",
241
+ };
242
+ ```
@@ -0,0 +1,143 @@
1
+ import { CSSResult } from 'lit';
2
+ import { LitElement } from 'lit';
3
+ import { TemplateResult } from 'lit-html';
4
+
5
+ /**
6
+ * `signosoft-signpad` web component for capturing signatures using a tablet or mouse.
7
+ * This component orchestrates signature capture, manages canvas drawing,
8
+ * handles mouse input fallback, and provides custom events for application integration.
9
+ *
10
+ * @element signosoft-signpad
11
+ *
12
+ * @fires sign-pen - Fired on every pen movement (Wacom or mouse) with `penData` in `event.detail`.
13
+ * @fires sign-clear - Fired when the signature is cleared (via internal UI button, tablet event, or by calling the public `clear()` method).
14
+ * @fires sign-cancel - Fired when the signature process is cancelled (via internal UI button, tablet event, or by calling the public `cancel()` method).
15
+ * @fires sign-ok - Fired when the 'OK' action is completed (via internal UI button, tablet event, or by calling the public `ok()` method).
16
+ * @fires sign-disconnect - Fired if the tablet unexpectedly disconnects.
17
+ * @fires sign-error - Fired when an error occurs during connection or initialization.
18
+ *
19
+ * @property {string} licenseKey - Backend license key for the signature driver.
20
+ * @property {boolean} topBarVisible - Controls the visibility of the top action bar.
21
+ * @property {boolean} bottomBarVisible - Controls the visibility of the bottom action bar with OK, Clear, Cancel buttons.
22
+ * @property {boolean} okButtonVisible - Controls the visibility of the 'OK' button.
23
+ * @property {boolean} clearButtonVisible - Controls the visibility of the 'Clear' button.
24
+ * @property {boolean} cancelButtonVisible - Controls the visibility of the 'Cancel' button.
25
+ * @property {boolean} canvasLineVisible - Controls the visibility of the line on the canvas.
26
+ * @property {boolean} deviceStateTextVisible - Controls the visibility of the device state text.
27
+ * @property {string | null} [customDeviceStateText] - Optional custom text to display for the device state, overriding the default.
28
+ * @property {number} minThickness - Minimum pen stroke thickness in pixels.
29
+ * @property {number} maxThickness - Maximum pen stroke thickness in pixels (at full pressure).
30
+ * @property {string} penColor - Pen stroke color (CSS color, e.g., '#000000' or 'red').
31
+ * @property {Record<string, string>} [customCssVariables] - An object containing CSS custom property names as keys and their values as strings. These will be applied directly to the component's host element for styling customization.
32
+ * @property {function} [OkButton] - Optional callback function (async or sync) to execute when the public `ok()` method is called, either internally or externally. It runs after the component's internal processing.
33
+ * @property {function} [ClearButton] - Optional callback function (async or sync) to execute when the public `clear()` method is called, either internally or externally. It runs after the component's internal processing.
34
+ * @property {function} [CancelButton] - Optional callback function (async or sync) to execute when the public `cancel()` method is called, either internally or externally. It runs after the component's internal processing.
35
+ * @property {string | null} [canvasAdditionalText] - Optional additional text to display in the canvas footer. If null or empty, a default text will be shown. Default behavior is "Sign area with mouse or pen" when disconnected/error, and "Sign with [device name]" when connected.
36
+ */
37
+ export declare class SignosoftSignpad extends LitElement {
38
+ licenseKey: string;
39
+ canvasAdditionalText: string | null;
40
+ topBarVisible: boolean;
41
+ bottomBarVisible: boolean;
42
+ okButtonVisible: boolean;
43
+ clearButtonVisible: boolean;
44
+ cancelButtonVisible: boolean;
45
+ canvasLineVisible: boolean;
46
+ deviceStateTextVisible: boolean;
47
+ customDeviceStateText: string | null;
48
+ minThickness: number;
49
+ maxThickness: number;
50
+ penColor: string;
51
+ OkButton?: () => Promise<void>;
52
+ ClearButton?: () => Promise<void>;
53
+ CancelButton?: () => Promise<void>;
54
+ customCssVariables: Record<string, string>;
55
+ canvasRef: HTMLCanvasElement;
56
+ private _deviceStateText;
57
+ private _isConnected;
58
+ private _hasStartedDrawing;
59
+ private _isDisconnectingIntentionally;
60
+ private licenseServerUrl;
61
+ private sigLayer;
62
+ private canvasPainter;
63
+ private mouseInputHandler;
64
+ private offscreenDrawingCanvas;
65
+ static styles: CSSResult[];
66
+ constructor();
67
+ /**
68
+ * Invoked once after the component's first render.
69
+ * Initializes CanvasPainter and MouseInputHandler, then starts driver initialization.
70
+ */
71
+ protected firstUpdated(): void;
72
+ /**
73
+ * Invoked before the component's render method is called.
74
+ * Updates CanvasPainter's drawing options if related properties have changed.
75
+ */
76
+ protected willUpdate(changedProperties: Map<string | number | symbol, unknown>): void;
77
+ /**
78
+ * Invoked after the component's render method is called and its DOM has been updated.
79
+ * Applies custom CSS variables from the `customCssVariables` property to the host element.
80
+ */
81
+ protected updated(changedProperties: Map<PropertyKey, unknown>): void;
82
+ /**
83
+ * Prepares the SignatureLayer instance.
84
+ * This method now creates a new instance if `sigLayer` is null.
85
+ */
86
+ private prepareSignatureLayer;
87
+ /**
88
+ * Sets up internal callbacks for the SignatureLayer instance.
89
+ * These callbacks ensure that actions from the Wacom tablet (e.g., OK, Clear, Cancel)
90
+ * trigger the corresponding public methods of this component.
91
+ */
92
+ private setupCallbacks;
93
+ /**
94
+ * Dispatches a custom event from this web component.
95
+ * @param name - The name of the custom event to dispatch.
96
+ * @param [detail] - Optional data to include with the event, accessible via `event.detail`.
97
+ */
98
+ private dispatch;
99
+ /**
100
+ * Connects to the signature tablet.
101
+ * This involves obtaining a license, initializing the signature layer,
102
+ * connecting to the device, and starting the signing process.
103
+ * This method strategically passes an offscreen canvas or the actual visible canvas to SignatureLayer
104
+ * based on the detected device, to prevent unwanted internal drawing by SignatureLayer.
105
+ * This method can be invoked externally (e.g., from a "Connect Signpad" button).
106
+ * @param autoConnect - If true, attempts to automatically select the first available device.
107
+ * @returns True if successfully connected and signing started, false otherwise.
108
+ */
109
+ connectTablet(autoConnect?: boolean): Promise<boolean>;
110
+ /**
111
+ * Disconnects from the signature tablet and resets its state.
112
+ * This method can be invoked externally.
113
+ * @returns A promise that resolves when the tablet is disconnected.
114
+ */
115
+ disconnectTablet(): Promise<void>;
116
+ /**
117
+ * Clears the current signature from both the tablet's screen and the component's canvas.
118
+ * Invokes the optional `ClearButton` external callback (if provided)
119
+ * and then dispatches a 'sign-clear' custom event.
120
+ * This method can be invoked externally or internally (e.g., from a "Clear" button).
121
+ */
122
+ clear(): Promise<void>;
123
+ /**
124
+ * Handles the 'OK' action, typically stopping the signing process and preparing the signature for submission.
125
+ * If an `OkButton` callback function is provided via properties, it will be executed.
126
+ * Afterwards, a `sign-ok` custom event is dispatched.
127
+ * This method can be invoked externally or internally (e.g., from an "OK" button).
128
+ */
129
+ ok(): Promise<void>;
130
+ /**
131
+ * Handles the 'Cancel' action, which typically clears any drawn signature and stops the signing process.
132
+ * If a `CancelButton` callback function is provided via properties, it will be executed.
133
+ * Finally, a `sign-cancel` custom event is dispatched.
134
+ * This method can be invoked externally or internally (e.g., from a "Cancel" button).
135
+ */
136
+ cancel(): Promise<void>;
137
+ /**
138
+ * Renders the component's HTML template.
139
+ */
140
+ render(): TemplateResult<1>;
141
+ }
142
+
143
+ export { }