@signosoft/signpad-js 0.2.3 → 0.3.0

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/README.md CHANGED
@@ -2,14 +2,14 @@
2
2
 
3
3
  ## 📍 Table of Contents
4
4
 
5
- | Core Concepts & Overview | Getting Started & Usage | Advanced & Support |
6
- | :---------------------------------------- | :--------------------------------- | :--------------------------------- |
7
- | 📜 [Description](#-description) | 📦 [Installation](#-installation) | 🤝 [Feedback](#-feedback--support) |
8
- | 🎬 [Demo](#-demo) | 🔐 [Licensing](#-get-your-license) | 📄 [License](#-license) |
9
- | ⚙️ [Tech stack](#-tech-stack--built-with) | 🚀 [Quick Start](#-quick-start) | |
10
- | | 📋 [Properties](#-properties) | |
11
- | | 🧩 [Methods](#-methods) | |
12
- | | 🎨 [Styling](#-styling--theming) | |
5
+ | Core Concepts & Overview | Getting Started & Usage | Advanced & Support |
6
+ | :---------------------------------------- | :-------------------------------- | :--------------------------------- |
7
+ | 📜 [Description](#-description) | 📦 [Installation](#-installation) | 💬 [Feedback](#-feedback--support) |
8
+ | 🎬 [Demo](#-demo) | 🔐 [Licensing](#-lease-setup) | 🛠️ [Contributing](#-contributing) |
9
+ | ⚙️ [Tech stack](#-tech-stack--built-with) | 🚀 [Quick Start](#-quick-start) | 📄 [License](#-license) |
10
+ | | 📋 [Properties](#-properties) | |
11
+ | | 🧩 [Methods](#-methods) | |
12
+ | | 🎨 [Styling](#-styling--theming) | |
13
13
 
14
14
  ## 📜 Description
15
15
 
@@ -38,33 +38,61 @@ It expertly handles the complexities of **WebHID device connections**, signature
38
38
  - [![Vite](https://img.shields.io/badge/Vite-646CFF?logo=vite&logoColor=fff)](https://vitejs.dev/)
39
39
  <br/>
40
40
 
41
- ## 🔐 Get your license
41
+ ## 🔐 Lease Setup
42
42
 
43
- To use the Signosoft Signpad component and its hardware drivers, a valid license key is **required**.
43
+ To use the Signosoft Signpad component and its hardware drivers, a valid `lease` is **required**.
44
44
 
45
45
  #### 🛑 CRITICAL: Mandatory Initialization
46
46
 
47
- Without a valid license key, the component <b>WILL NOT INITIALIZE</b> and all hardware communication features will be <b>disabled</b>.
47
+ Without a valid lease, the component <b>WILL NOT INITIALIZE</b> and hardware communication features will be <b>disabled</b>.
48
48
 
49
- ### 1. How to obtain a license:
49
+ ### 1. Lease flow
50
50
 
51
- 1. Go to [www.signosoft.com](https://www.signosoft.com)
52
- 2. **Sign in** to your account.
53
- 3. Navigate to **Settings** > **Get License**.
54
- 4. Click **Generate API Key** (License Key).
55
- 5. Copy your key and add it to your configuration.
51
+ 1. Generate/get your license key in Signosoft portal.
52
+ 2. Request a lease from the Signosoft lease API.
53
+ 3. Put the returned lease into `config.lease`.
56
54
 
57
- ### 2. Implementation:
55
+ > Security note: In production, call the lease API from your backend and return only the lease to frontend.
58
56
 
59
- Add the key to the `licenseKey` field in your configuration object:
57
+ ### 2. Frontend implementation (plain JavaScript reference)
60
58
 
61
- ```typescript
62
- const config: SignpadConfig = {
63
- licenseKey: "YOUR-LICENSE-KEY-HERE", // Required
64
- // ... other options
59
+ ```javascript
60
+ async function fetchLease() {
61
+ try {
62
+ const response = await fetch(
63
+ "https://test.signosoft.com/api/v1/driver/leases",
64
+ {
65
+ method: "POST",
66
+ headers: { "Content-Type": "application/json" },
67
+ body: JSON.stringify({
68
+ licenceKey: "YOUR-LICENSE-KEY",
69
+ validityHours: 24,
70
+ port: 4204,
71
+ }),
72
+ },
73
+ );
65
74
 
66
- // For local development, ensure your license is valid for localhost.
67
- };
75
+ if (!response.ok) {
76
+ const errorText = await response.text();
77
+ throw new Error(
78
+ `License server error: ${response.statusText} - ${errorText}`,
79
+ );
80
+ }
81
+
82
+ return await response.json();
83
+ } catch (error) {
84
+ console.error("Signosoft Signpad: License initialization failed", error);
85
+ throw error;
86
+ }
87
+ }
88
+
89
+ async function applyLeaseToConfig(currentConfig) {
90
+ const lease = await fetchLease();
91
+ return {
92
+ ...currentConfig,
93
+ lease,
94
+ };
95
+ }
68
96
  ```
69
97
 
70
98
  <br/>
@@ -169,7 +197,13 @@ export class SignosoftSignpadDirective implements OnChanges {
169
197
  Import the library, the directive, and add the **`CUSTOM_ELEMENTS_SCHEMA`**.
170
198
 
171
199
  ```typescript
172
- import { Component, ViewChild, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";
200
+ import {
201
+ Component,
202
+ ViewChild,
203
+ CUSTOM_ELEMENTS_SCHEMA,
204
+ AfterViewInit,
205
+ signal,
206
+ } from "@angular/core";
173
207
  import "@signosoft/signpad-js"; // Import the Web Component registration
174
208
  import {
175
209
  type SignosoftSignpad,
@@ -184,14 +218,54 @@ import { SignosoftSignpadDirective } from "./directives/signosoft-signpad.direct
184
218
  templateUrl: "./app.component.html",
185
219
  schemas: [CUSTOM_ELEMENTS_SCHEMA], // Mandatory for custom HTML tags
186
220
  })
187
- export class AppComponent {
221
+ export class AppComponent implements AfterViewInit {
188
222
  @ViewChild(SignosoftSignpadDirective)
189
223
  signpadDirective!: SignosoftSignpadDirective;
190
224
 
191
- config: SignpadConfig = {
192
- licenseKey: "YOUR-LICENSE-KEY",
193
- // More info in "properties" section
194
- };
225
+ public config = signal<SignpadConfig>({
226
+ lease: undefined,
227
+ });
228
+
229
+ async ngAfterViewInit() {
230
+ await this.applyLeaseToConfig();
231
+ }
232
+
233
+ public async fetchLease(): Promise<any> {
234
+ try {
235
+ const response = await fetch(
236
+ "https://test.signosoft.com/api/v1/driver/leases",
237
+ {
238
+ method: "POST",
239
+ headers: { "Content-Type": "application/json" },
240
+ body: JSON.stringify({
241
+ licenceKey: "YOUR-LICENSE-KEY",
242
+ validityHours: 24,
243
+ port: 4204,
244
+ }),
245
+ },
246
+ );
247
+
248
+ if (!response.ok) {
249
+ const errorText = await response.text();
250
+ throw new Error(
251
+ `License server error: ${response.statusText} - ${errorText}`,
252
+ );
253
+ }
254
+
255
+ return await response.json();
256
+ } catch (error) {
257
+ console.error("Signosoft Signpad: License initialization failed", error);
258
+ throw error;
259
+ }
260
+ }
261
+
262
+ public async applyLeaseToConfig() {
263
+ const lease = await this.fetchLease();
264
+ this.config.update((currentConfig) => ({
265
+ ...currentConfig,
266
+ lease,
267
+ }));
268
+ }
195
269
 
196
270
  // Helper to access methods easily (ok, clear, cancel, etc.)
197
271
  public get signpad(): SignosoftSignpad | undefined {
@@ -207,7 +281,7 @@ Use the custom tag in your HTML and bind the configuration object.
207
281
  ```html
208
282
  <div>
209
283
  <div>
210
- <signosoft-signpad [config]="config"></signosoft-signpad>
284
+ <signosoft-signpad [config]="config()"></signosoft-signpad>
211
285
  </div>
212
286
  </div>
213
287
  ```
@@ -235,21 +309,50 @@ npm install @signosoft/signpad-js
235
309
 
236
310
  ## 2. Implementation
237
311
 
238
- In React, we use the `useRef` hook to interact with the component's methods (like `ok()` or `clear()`) and pass the configuration directly via props.
312
+ In React, we use `useRef` for methods and `useEffect` to fetch a lease before updating config.
239
313
 
240
314
  ```tsx
241
- import { useRef } from "react";
315
+ import { useEffect, useRef, useState } from "react";
242
316
  import "@signosoft/signpad-js"; // Registers the web component
243
317
  import type { SignpadConfig } from "@signosoft/signpad-js";
244
318
 
319
+ async function fetchLease() {
320
+ try {
321
+ const response = await fetch(
322
+ "https://test.signosoft.com/api/v1/driver/leases",
323
+ {
324
+ method: "POST",
325
+ headers: { "Content-Type": "application/json" },
326
+ body: JSON.stringify({
327
+ licenceKey: "YOUR-LICENSE-KEY",
328
+ validityHours: 24,
329
+ port: 4204,
330
+ }),
331
+ },
332
+ );
333
+
334
+ if (!response.ok) {
335
+ const errorText = await response.text();
336
+ throw new Error(
337
+ `License server error: ${response.statusText} - ${errorText}`,
338
+ );
339
+ }
340
+
341
+ return await response.json();
342
+ } catch (error) {
343
+ console.error("Signosoft Signpad: License initialization failed", error);
344
+ throw error;
345
+ }
346
+ }
347
+
245
348
  function App() {
246
349
  // Use ref to access component methods (ok, clear, connect, etc. by signpadRef.current)
247
350
  const signpadRef = useRef<any>(null);
351
+ const [config, setConfig] = useState<SignpadConfig>({ lease: undefined });
248
352
 
249
- const config: SignpadConfig = {
250
- licenseKey: "YOUR-LICENSE-KEY",
251
- // More info in "properties" section
252
- };
353
+ useEffect(() => {
354
+ fetchLease().then((lease) => setConfig((prev) => ({ ...prev, lease })));
355
+ }, []);
253
356
 
254
357
  return (
255
358
  <div>
@@ -309,7 +412,7 @@ export default defineConfig({
309
412
 
310
413
  ## 3. Implementation
311
414
 
312
- In Vue 3, we use `ref` to hold the reference to the DOM element and pass the configuration via the `:config` attribute.
415
+ In Vue 3, we use `ref` for both the element and config, then fetch the lease and assign it to config.
313
416
 
314
417
  ```typescript
315
418
  <script setup lang="ts">
@@ -320,11 +423,40 @@ import type { SignpadConfig, SignosoftSignpad, IPenData } from "@signosoft/signp
320
423
  // Use ref to access component methods (ok, clear, connect, etc. by signpadRef.value)
321
424
  const signpadRef = ref<SignosoftSignpad | null>(null);
322
425
 
323
- const signpadConfig: SignpadConfig = {
324
- licenseKey: "YOUR-LICENSE-KEY",
325
- // More info in "properties" section
426
+ const signpadConfig = ref<SignpadConfig>({ lease: undefined });
427
+
428
+ const fetchLease = async () => {
429
+ try {
430
+ const response = await fetch("https://test.signosoft.com/api/v1/driver/leases", {
431
+ method: "POST",
432
+ headers: { "Content-Type": "application/json" },
433
+ body: JSON.stringify({
434
+ licenceKey: "YOUR-LICENSE-KEY",
435
+ validityHours: 24,
436
+ port: 4204,
437
+ }),
438
+ });
439
+
440
+ if (!response.ok) {
441
+ const errorText = await response.text();
442
+ throw new Error(`License server error: ${response.statusText} - ${errorText}`);
443
+ }
444
+
445
+ return await response.json();
446
+ } catch (error) {
447
+ console.error("Signosoft Signpad: License initialization failed", error);
448
+ throw error;
449
+ }
326
450
  };
327
451
 
452
+ fetchLease()
453
+ .then((lease) => {
454
+ signpadConfig.value = {
455
+ ...signpadConfig.value,
456
+ lease,
457
+ };
458
+ });
459
+
328
460
  </script>
329
461
 
330
462
  <template>
@@ -376,8 +508,41 @@ const pad = document.querySelector("signosoft-signpad");
376
508
 
377
509
  // 1. Initial Configuration
378
510
  pad.config = {
379
- licenseKey: "YOUR-LICENSE-KEY",
511
+ lease: undefined,
512
+ };
513
+
514
+ const fetchLease = async () => {
515
+ try {
516
+ const response = await fetch(
517
+ "https://test.signosoft.com/api/v1/driver/leases",
518
+ {
519
+ method: "POST",
520
+ headers: { "Content-Type": "application/json" },
521
+ body: JSON.stringify({
522
+ licenceKey: "YOUR-LICENSE-KEY",
523
+ validityHours: 24,
524
+ port: 4204,
525
+ }),
526
+ },
527
+ );
528
+
529
+ if (!response.ok) {
530
+ const errorText = await response.text();
531
+ throw new Error(
532
+ `License server error: ${response.statusText} - ${errorText}`,
533
+ );
534
+ }
535
+
536
+ return await response.json();
537
+ } catch (error) {
538
+ console.error("Signosoft Signpad: License initialization failed", error);
539
+ throw error;
540
+ }
380
541
  };
542
+
543
+ fetchLease().then((lease) => {
544
+ pad.config = { ...pad.config, lease };
545
+ });
381
546
  ```
382
547
 
383
548
  ## 3. HTML Structure
@@ -421,10 +586,9 @@ The component is primarily configured through a single `config` property. This o
421
586
 
422
587
  ### 🔑 Core Options
423
588
 
424
- | Option | Type | Required | Description |
425
- | :------------------- | :------- | :------- | :-------------------------------------------------------------------- |
426
- | **`licenseKey`** | `string` | **Yes** | Your unique API key from signosoft.com. Mandatory for initialization. |
427
- | `customCssVariables` | `object` | No | Custom theme object generated via the `getSignpadTheme` utility. |
589
+ | Option | Type | Required | Description |
590
+ | :---------- | :------- | :------- | :---------------------------------------------------------------------------- |
591
+ | **`lease`** | `object` | **Yes** | Lease payload returned from the lease API call. Mandatory for initialization. |
428
592
 
429
593
  ### 🔄 autoconnectOptions
430
594
 
@@ -482,25 +646,27 @@ The component provides two ways to interact with internal processes.
482
646
 
483
647
  These allow you to **inject custom logic** directly into the internal button flows. Your code runs alongside the component's internal logic.
484
648
 
485
- | Handler | Arguments | Description |
486
- | :------------- | :----------- | :---------------------------------------------------------------------- |
487
- | `handleOk` | `data?: any` | Extends the internal OK button logic. Receives captured signature data. |
488
- | `handleClear` | — | Extends the internal Clear button logic. |
489
- | `handleCancel` | — | Extends the internal Cancel button logic. |
649
+ | Handler | Arguments | Description |
650
+ | :------------- | :---------------------------------- | :---------------------------------------------------------------------- |
651
+ | `handleOk` | `data?: ISignatureConfirmationData` | Extends the internal OK button logic. Receives captured signature data. |
652
+ | `handleClear` | — | Extends the internal Clear button logic. |
653
+ | `handleCancel` | — | Extends the internal Cancel button logic. |
490
654
 
491
655
  #### 🔔 Event Callbacks (`eventCallbacks`)
492
656
 
493
657
  Standard event listeners triggered _after_ specific actions. Useful for observing the component from your application state.
494
658
 
495
- | Callback | Payload | Description |
496
- | :------------- | :------------------------------ | :------------------------------------------------------------------------------------------------- |
497
- | `onPen` | `event: CustomEvent<IPenData> ` | Dispatched when a device or mouse fallback are in contact with component or signature pad display. |
498
- | `onConnect` | `event: CustomEvent` | Dispatched when a device or mouse fallback connects. |
499
- | `onDisconnect` | — | Dispatched when the hardware connection is closed. |
500
- | `onOk` | `data: any` | Dispatched when signature is confirmed. |
501
- | `onClear` | — | Dispatched when the canvas has been cleared. |
502
- | `onCancel` | — | Dispatched when the user aborts the session. |
503
- | `onError` | `error: Error` | Dispatched on critical failures (License, Driver, etc.). |
659
+ | Callback | Payload | Description |
660
+ | :------------- | :----------------------------------------------- | :------------------------------------------------------------------------------------------------- |
661
+ | `onPen` | `event: CustomEvent<IPenData> ` | Dispatched when a device or mouse fallback are in contact with component or signature pad display. |
662
+ | `onConnect` | `event: CustomEvent` | Dispatched when a device or mouse fallback connects. |
663
+ | `onDisconnect` | — | Dispatched when the hardware connection is closed. |
664
+ | `onOk` | `event: CustomEvent<ISignatureConfirmationData>` | Dispatched when signature is confirmed. |
665
+ | `onClear` | — | Dispatched when the canvas has been cleared. |
666
+ | `onCancel` | — | Dispatched when the user aborts the session. |
667
+ | `onError` | `error: Error` | Dispatched on critical failures (Lease, Driver, etc.). |
668
+
669
+ > `actionHandlers` and `eventCallbacks` are separate hooks and can both be configured.
504
670
 
505
671
  ---
506
672
 
@@ -508,7 +674,7 @@ Standard event listeners triggered _after_ specific actions. Useful for observin
508
674
 
509
675
  ```typescript
510
676
  this.config = {
511
- licenseKey: "your-signosoft-license-key",
677
+ lease: leasePayloadFromApi,
512
678
  autoconnectOptions: {
513
679
  autoConnect: true,
514
680
  },
@@ -532,15 +698,15 @@ this.config = {
532
698
 
533
699
  The following methods are available on the component instance to control the signing process programmatically.
534
700
 
535
- | Method | Returns | Description |
536
- | :--------------- | :----------------- | :------------------------------------------------------------------------------- |
537
- | `connect()` | `Promise<boolean>` | Connects device to component |
538
- | `disconnect()` | `Promise<void>` | Disconnects device from component |
539
- | `startSigning()` | `Promise<void>` | Initializes a new signing session on the canvas and hardware. |
540
- | `stopSigning()` | `Promise<any>` | Immediately ends the session and returns the captured signature data. |
541
- | `ok()` | `Promise<any>` | Finalizes the session, cleans the device screen, and returns the signature data. |
542
- | `clear()` | `Promise<void>` | Wipes the signature from the UI and hardware without ending the session. |
543
- | `cancel()` | `Promise<void>` | Aborts the current session and resets the component state. |
701
+ | Method | Returns | Description |
702
+ | :--------------- | :------------------------------------------------- | :------------------------------------------------------------------------------- |
703
+ | `connect()` | `Promise<boolean>` | Connects device to component |
704
+ | `disconnect()` | `Promise<void>` | Disconnects device from component |
705
+ | `startSigning()` | `Promise<void>` | Initializes a new signing session on the canvas and hardware. |
706
+ | `stopSigning()` | `Promise<any>` | Immediately ends the session and returns the captured signature data. |
707
+ | `ok()` | `Promise<ISignatureConfirmationData \| undefined>` | Finalizes the session, cleans the device screen, and returns the signature data. |
708
+ | `clear()` | `Promise<void>` | Wipes the signature from the UI and hardware without ending the session. |
709
+ | `cancel()` | `Promise<void>` | Aborts the current session and resets the component state. |
544
710
 
545
711
  ---
546
712
 
@@ -599,6 +765,87 @@ This is the standard way to confirm a signature. It:
599
765
  3. Dispatches the `SIGN_OK` event.
600
766
  4. Returns the final signature payload (coordinates, pressure, metadata).
601
767
 
768
+ **Returned payload shape (`ISignatureConfirmationData`)**
769
+
770
+ ```js
771
+ [
772
+ points, // index 0: Data about each point
773
+ imageBase64, // index 1: Image in base64
774
+ metadata, // index 2: Information about tablet and canvas
775
+ ];
776
+ ```
777
+
778
+ ```js
779
+ // [0] Points structure
780
+ {
781
+ absoluteX: number,
782
+ absoluteY: number,
783
+ inContact: boolean,
784
+ pressure: number,
785
+ ready: boolean,
786
+ relativeX: number, // normalized 0..1
787
+ relativeY: number, // normalized 0..1
788
+ sequence: number,
789
+ timestamp: number | bigint
790
+ }
791
+ ```
792
+
793
+ ```js
794
+ // [1] Image structure
795
+ {
796
+ data: image / png;
797
+ (base64, Some - long - string);
798
+ }
799
+ ```
800
+
801
+ ```js
802
+ // [2] Metadata structure
803
+ {
804
+ canvas: {
805
+ top: number,
806
+ left: number,
807
+ right: number,
808
+ bottom: number,
809
+ width: number,
810
+ height: number,
811
+ cssWidth: number,
812
+ cssHeight: number,
813
+ dpr: number
814
+ },
815
+ tablet: {
816
+ name: string,
817
+ aspectRatio: number,
818
+ isCanvasStyleTablet: boolean,
819
+ screenWidth: number,
820
+ screenHeight: number,
821
+ drawingArea: { x: number, y: number, width: number, height: number },
822
+ serialNumber: Promise<string> | string,
823
+ vendorId: number | null,
824
+ productId: number | null
825
+ }
826
+ }
827
+ ```
828
+
829
+ `handleOk(data)` receives the same structure. `onOk` receives it in `event.detail`.
830
+
831
+ #### 📜 `onPen` payload
832
+
833
+ `onPen` is emitted continuously while writing and provides a single `IPenData` object in `event.detail`.
834
+
835
+ ```js
836
+ {
837
+ absoluteX: number,
838
+ absoluteY: number,
839
+ inContact: boolean,
840
+ pressure: number,
841
+ ready: boolean,
842
+ relativeX: number, // normalized 0..1
843
+ relativeY: number, // normalized 0..1
844
+ sequence: number,
845
+ timestamp: number | bigint
846
+ }
847
+ ```
848
+
602
849
  #### 📜 `stopSigning()`
603
850
 
604
851
  A low-level method that forces the driver to stop capturing data and returns the raw signature object. Unlike `ok()`, it does not trigger the full "Finalization" flow (UI transitions or device screen clearing).
@@ -613,44 +860,97 @@ Stops the session immediately. It does not collect any signature data and resets
613
860
 
614
861
  ## 🎨 Styling & Theming
615
862
 
616
- The component is designed to be fully customizable to match your brand's identity. You can style it using **CSS Variables** or by using our built-in **Theme Generator**.
617
-
618
- ### 🛠️ Built-in Theme Generator
619
-
620
- The easiest way to create a consistent theme is to use our CLI utility. It generates a configuration object that you can pass directly to the component.
621
-
622
- **1. Run the generator in your terminal:**
623
-
624
- ```bash
625
- npx getSignpadTheme
626
- ```
627
-
628
- The CLI will guide you through:
629
-
630
- - **Output path:** Where to save the file.
631
- - **Filename:** What to call the file.
632
- - **Format:** Choose between `.js` or `.ts`.
863
+ The component uses a hybrid theming model:
633
864
 
634
- **2. Import and apply the theme:**
635
- Once generated, import the file and pass it to your configuration object:
865
+ - It ships with complete default styles (works out of the box).
866
+ - You can override the visual design through CSS variables.
636
867
 
637
- ```typescript
638
- import { myCustomTheme } from "./styles/myCustomTheme";
868
+ ## ✍️ Override via CSS
639
869
 
640
- this.config = {
641
- licenseKey: "...",
642
- customCssVariables: myCustomTheme,
643
- };
644
- ```
870
+ You can override variables in your stylesheet
645
871
 
646
- ### ✍️ Manual CSS Customization
872
+ ### 📎 Copy-Paste Starter
647
873
 
648
- You can override the CSS variables directly in your global stylesheet to fine-tune the appearance:
874
+ Paste this directly into your app stylesheet and adjust values:
649
875
 
650
876
  ```css
651
877
  signosoft-signpad {
652
- --primary-color-0: #0056b3;
653
- --sign-canvas-bg-base: #ffffff;
878
+ /* Color Variables */
879
+ --primary-color-0: #4e56ea;
880
+ --primary-color-10: #7178ee;
881
+ --background-color-0: #f1f2fd;
882
+ --background-color-10: #e3e4fc;
883
+ --text-color-0: #333e4a;
884
+ --white-color: #ffffff;
885
+ --grey-color: #b5b9be;
886
+
887
+ /* Constraints */
888
+ --min-height: 48px;
889
+ --spacing-constraints: 16px 24px;
890
+
891
+ /* CSS Variables */
892
+ --sign-font-family: Arial, Helvetica, sans-serif;
893
+
894
+ /* Top Bar */
895
+ --sign-top-bar-bg-base: var(--background-color-10);
896
+ --sign-top-bar-text-base: var(--primary-color-0);
897
+ --sign-top-bar-padding: var(--spacing-constraints);
898
+ --sign-top-bar-min-height: var(--min-height);
899
+
900
+ /* Canvas Area */
901
+ --sign-canvas-bg-base: var(--background-color-0);
902
+
903
+ /* Line */
904
+ --sign-line-height: 22px;
905
+ --sign-line-margin-bottom: 16px;
906
+ --sign-line-border-base: var(--primary-color-10);
907
+ --sign-line-additional-text-color: var(--text-color-0);
908
+ --sign-line-margin: 0px 24px var(--sign-line-margin-bottom) 24px;
909
+ --sign-canvas-line-text-font-size: 12px;
910
+ --sign-canvas-height-offset: var(--sign-line-height);
911
+
912
+ /* Bottom Bar */
913
+ --sign-bottom-bar-bg-base: var(--background-color-10);
914
+ --sign-bottom-bar-padding: var(--spacing-constraints);
915
+ --sign-bottom-bar-min-height: var(--min-height);
916
+ --sign-bottom-bar-gap: 12px;
917
+
918
+ /* Button general settings */
919
+ --sign-button-font-size: 16px;
920
+ --sign-button-padding: 14px 16px;
921
+ --sign-button-min-height: var(--min-height);
922
+ --sign-button-border-radius: 8px;
923
+ --sign-button-font-weight: 500;
924
+
925
+ /* Primary Buttons (OK, Clear, Cancel) */
926
+ --sign-button-primary-bg-base: var(--primary-color-0);
927
+ --sign-button-primary-bg-hover: var(--primary-color-10);
928
+ --sign-button-primary-bg-disabled: var(--grey-color);
929
+ --sign-button-primary-text-base: var(--white-color);
930
+ --sign-button-primary-text-hover: var(--white-color);
931
+ --sign-button-primary-text-disabled: var(--white-color);
932
+
933
+ /* Link Buttons (Connect signpad) */
934
+ --sign-button-link-bg-base: transparent;
935
+ --sign-button-link-bg-hover: var(--background-color-10);
936
+ --sign-button-link-bg-disabled: transparent;
937
+ --sign-button-link-text-base: var(--primary-color-0);
938
+ --sign-button-link-text-hover: var(--primary-color-10);
939
+ --sign-button-link-text-disabled: var(--grey-color);
940
+ --sign-button-link-border-base: 1px solid var(--primary-color-0);
941
+ --sign-button-link-border-hover: 1px solid var(--primary-color-10);
942
+ --sign-button-link-border-disabled: 1px solid var(--grey-color);
943
+
944
+ /* Device State Text Colors */
945
+ --sign-device-state-text-color-connected: green;
946
+ --sign-device-state-text-color-disconnected: red;
947
+
948
+ /* Loading Overlay */
949
+ --sign-loading-overlay-bg-color: rgba(255, 255, 255, 0.8);
950
+ --sign-loading-overlay-text-color: var(--text-color-0);
951
+ --sign-loading-overlay-spinner-color: var(--primary-color-0);
952
+ --sign-loading-overlay-spinner-border-color: rgba(78, 86, 234, 0.1);
953
+ --sign-loading-overlay-spinner-size: 30px;
654
954
  }
655
955
  ```
656
956
 
@@ -678,41 +978,44 @@ signosoft-signpad {
678
978
 
679
979
  #### Top Bar
680
980
 
681
- | Variable | Description |
682
- | :-------------------------- | :------------------------------- |
683
- | `--sign-top-bar-bg-base` | Background color of the top bar. |
684
- | `--sign-top-bar-text-base` | Text color in the top bar. |
685
- | `--sign-top-bar-padding` | Inner padding of the top bar. |
686
- | `--sign-top-bar-min-height` | Minimum height of the top bar. |
981
+ | Variable | Default | Description |
982
+ | :-------------------------- | :--------------------------- | :------------------------------- |
983
+ | `--sign-top-bar-bg-base` | `var(--background-color-10)` | Background color of the top bar. |
984
+ | `--sign-top-bar-text-base` | `var(--primary-color-0)` | Text color in the top bar. |
985
+ | `--sign-top-bar-padding` | `var(--spacing-constraints)` | Inner padding of the top bar. |
986
+ | `--sign-top-bar-min-height` | `var(--min-height)` | Minimum height of the top bar. |
687
987
 
688
988
  #### Canvas & Signature Line
689
989
 
690
- | Variable | Description |
691
- | :---------------------------------- | :-------------------------------------------- |
692
- | `--sign-canvas-bg-base` | Background color of the drawing area. |
693
- | `--sign-line-height` | Vertical offset/height for the guide line. |
694
- | `--sign-line-border-base` | Color of the signature guide line. |
695
- | `--sign-line-additional-text-color` | Color of the helper text below the line. |
696
- | `--sign-line-margin` | Spacing around the guide line. |
697
- | `--sign-canvas-line-text-font-size` | Font size for guide line labels. |
698
- | `--sign-canvas-height-offset` | Canvas offset calculation for the guide line. |
990
+ | Variable | Default | Description |
991
+ | :---------------------------------- | :--------------------------------------------- | :-------------------------------------------- |
992
+ | `--sign-canvas-bg-base` | `var(--background-color-0)` | Background color of the drawing area. |
993
+ | `--sign-line-height` | `22px` | Vertical offset/height for the guide line. |
994
+ | `--sign-line-margin-bottom` | `16px` | Bottom spacing used in canvas line layout. |
995
+ | `--sign-line-border-base` | `var(--primary-color-10)` | Color of the signature guide line. |
996
+ | `--sign-line-additional-text-color` | `var(--text-color-0)` | Color of the helper text below the line. |
997
+ | `--sign-line-margin` | `0px 24px var(--sign-line-margin-bottom) 24px` | Spacing around the guide line. |
998
+ | `--sign-canvas-line-text-font-size` | `12px` | Font size for guide line labels. |
999
+ | `--sign-canvas-height-offset` | `var(--sign-line-height)` | Canvas offset calculation for the guide line. |
699
1000
 
700
1001
  #### Bottom Bar
701
1002
 
702
- | Variable | Description |
703
- | :----------------------------- | :--------------------------------------- |
704
- | `--sign-bottom-bar-bg-base` | Background color of the bottom bar. |
705
- | `--sign-bottom-bar-padding` | Inner padding of the bottom bar. |
706
- | `--sign-bottom-bar-min-height` | Minimum height of the bottom bar. |
707
- | `--sign-bottom-bar-gap` | Space between buttons in the bottom bar. |
1003
+ | Variable | Default | Description |
1004
+ | :----------------------------- | :--------------------------- | :--------------------------------------- |
1005
+ | `--sign-bottom-bar-bg-base` | `var(--background-color-10)` | Background color of the bottom bar. |
1006
+ | `--sign-bottom-bar-padding` | `var(--spacing-constraints)` | Inner padding of the bottom bar. |
1007
+ | `--sign-bottom-bar-min-height` | `var(--min-height)` | Minimum height of the bottom bar. |
1008
+ | `--sign-bottom-bar-gap` | `12px` | Space between buttons in the bottom bar. |
708
1009
 
709
1010
  #### Buttons (General)
710
1011
 
711
- | Variable | Default | Description |
712
- | :------------------------- | :------------ | :------------------------------- |
713
- | `--sign-button-font-size` | `12px - 16px` | Fluid font size for all buttons. |
714
- | `--sign-button-padding` | `14px 16px` | Inner padding for all buttons. |
715
- | `--sign-button-min-height` | `48px` | Minimum height for buttons. |
1012
+ | Variable | Default | Description |
1013
+ | :---------------------------- | :------------------ | :----------------------------- |
1014
+ | `--sign-button-font-size` | `16px` | Font size for all buttons. |
1015
+ | `--sign-button-padding` | `14px 16px` | Inner padding for all buttons. |
1016
+ | `--sign-button-min-height` | `var(--min-height)` | Minimum height for buttons. |
1017
+ | `--sign-button-border-radius` | `8px` | Border radius for all buttons. |
1018
+ | `--sign-button-font-weight` | `500` | Font weight for all buttons. |
716
1019
 
717
1020
  #### Primary Buttons (OK, Clear, Cancel)
718
1021
 
@@ -727,31 +1030,130 @@ signosoft-signpad {
727
1030
 
728
1031
  #### Link/Connect Buttons
729
1032
 
730
- | Variable | Description |
731
- | :-------------------------------- | :------------------------------------------- |
732
- | `--sign-button-link-bg-base` | Background color for secondary/link buttons. |
733
- | `--sign-button-link-text-base` | Text color for secondary/link buttons. |
734
- | `--sign-button-link-border-base` | Border for secondary/link buttons. |
735
- | `--sign-button-link-text-hover` | Hover text color. |
736
- | `--sign-button-link-border-hover` | Hover border color. |
1033
+ | Variable | Default | Description |
1034
+ | :----------------------------------- | :---------------------------------- | :------------------------------------------- |
1035
+ | `--sign-button-link-bg-base` | `transparent` | Background color for secondary/link buttons. |
1036
+ | `--sign-button-link-bg-hover` | `var(--background-color-10)` | Hover background color. |
1037
+ | `--sign-button-link-bg-disabled` | `transparent` | Disabled background color. |
1038
+ | `--sign-button-link-text-base` | `var(--primary-color-0)` | Text color for secondary/link buttons. |
1039
+ | `--sign-button-link-text-hover` | `var(--primary-color-10)` | Hover text color. |
1040
+ | `--sign-button-link-text-disabled` | `var(--grey-color)` | Disabled text color. |
1041
+ | `--sign-button-link-border-base` | `1px solid var(--primary-color-0)` | Border for secondary/link buttons. |
1042
+ | `--sign-button-link-border-hover` | `1px solid var(--primary-color-10)` | Hover border color. |
1043
+ | `--sign-button-link-border-disabled` | `1px solid var(--grey-color)` | Disabled border color. |
737
1044
 
738
1045
  #### Status & Overlays
739
1046
 
740
- | Variable | Default | Description |
741
- | :-------------------------------------------- | :---------- | :--------------------------------- |
742
- | `--sign-device-state-text-color-connected` | `green` | Text color when device is ready. |
743
- | `--sign-device-state-text-color-disconnected` | `red` | Text color when disconnected. |
744
- | `--sign-loading-overlay-bg-color` | `rgba(...)` | Background of the loading spinner. |
745
- | `--sign-loading-overlay-spinner-color` | `#4e56ea` | Color of the animated spinner. |
746
- | `--sign-loading-overlay-spinner-size` | `30px` | Size of the spinner icon. |
1047
+ | Variable | Default | Description |
1048
+ | :-------------------------------------------- | :------------------------- | :--------------------------------- |
1049
+ | `--sign-device-state-text-color-connected` | `green` | Text color when device is ready. |
1050
+ | `--sign-device-state-text-color-disconnected` | `red` | Text color when disconnected. |
1051
+ | `--sign-loading-overlay-bg-color` | `rgba(255, 255, 255, 0.8)` | Background of the loading spinner. |
1052
+ | `--sign-loading-overlay-text-color` | `var(--text-color-0)` | Loading overlay text color. |
1053
+ | `--sign-loading-overlay-spinner-color` | `var(--primary-color-0)` | Color of the animated spinner. |
1054
+ | `--sign-loading-overlay-spinner-border-color` | `rgba(78, 86, 234, 0.1)` | Base border color of spinner ring. |
1055
+ | `--sign-loading-overlay-spinner-size` | `30px` | Size of the spinner icon. |
747
1056
 
748
- ## 🤝 Feedback & Support
1057
+ ## 💬 Feedback & Support
749
1058
 
750
1059
  We are constantly working to improve our components and drivers. Your feedback is essential to us. Whether you found a bug, have a feature request, or need technical assistance, please reach out to us:
751
1060
 
752
1061
  - 📧 **Support Email:** [esign@signosoft.com](mailto:esign@signosoft.com)
753
1062
  - 🌐 **Official Website:** [www.signosoft.com](https://www.signosoft.com)
754
1063
 
1064
+ ## 🛠️ Contributing
1065
+
1066
+ ### Commit naming convention
1067
+
1068
+ - Every commit message must start with Jira task id and category:
1069
+ - `MAIN-000/<category>: <summary>`
1070
+ - For work in progress:
1071
+ - `MAIN-000/<category>: WIP - <summary>`
1072
+
1073
+ Allowed categories:
1074
+
1075
+ - `feat`: adding a new feature
1076
+ - `fix`: fixing a bug
1077
+ - `refactor`: performance/readability/maintainability change
1078
+ - `chore`: docs, formatting, tests, cleanup, tooling
1079
+ - `merge`: branch merge into `main`
1080
+
1081
+ Use infinitive verb form in commit summaries:
1082
+
1083
+ - <span style="color: #16a34a;"><strong>RIGHT:</strong></span> `add`, `fix`, `remove`, `update`, `refactor`
1084
+ - <span style="color: #dc2626;"><strong>WRONG:</strong></span> Continuous tense: `adding`, `removing` Past tense: `added`, `fixed`
1085
+
1086
+ Examples:
1087
+
1088
+ ```bash
1089
+ git commit -m "MAIN-000/feat: add new button component; add button to templates"
1090
+ ```
1091
+
1092
+ ```bash
1093
+ git commit -m "MAIN-000/fix: add stop directive to button component to prevent propagation"
1094
+ ```
1095
+
1096
+ ```bash
1097
+ git commit -m "MAIN-000/refactor: rewrite button component in TypeScript"
1098
+ ```
1099
+
1100
+ ```bash
1101
+ git commit -m "MAIN-000/chore: write button documentation"
1102
+ ```
1103
+
1104
+ ```bash
1105
+ git commit -m "MAIN-000/merge: new button"
1106
+ ```
1107
+
1108
+ ```bash
1109
+ git commit -m "MAIN-000/feat: WIP - basic signing functionality"
1110
+ ```
1111
+
1112
+ ### Versioning and release commits
1113
+
1114
+ Follow Semantic Versioning:
1115
+
1116
+ - `MAJOR` (`x.0.0`): breaking changes
1117
+ - `MINOR` (`x.y.0`): backward-compatible feature set
1118
+ - `PATCH` (`x.y.z`): backward-compatible bug fixes
1119
+
1120
+ Commit naming for version bumps:
1121
+
1122
+ - Version-only change: use `chore`
1123
+ - Version bump with actual code/features in same commit: use `feat`/`fix`/`refactor` based on dominant change
1124
+ - For release commits, include both versions in message: `release from <old> to <new>`
1125
+
1126
+ Example (version bump with feature changes):
1127
+
1128
+ ```bash
1129
+ git commit -m "MAIN-000/feat: release from 0.2.4 to 0.3.0 - add signature method"
1130
+ ```
1131
+
1132
+ Example (version-only commit):
1133
+
1134
+ ```bash
1135
+ git commit -m "MAIN-000/chore: release from 0.2.4 to 0.3.0"
1136
+ ```
1137
+
1138
+ How version increment works:
1139
+
1140
+ - `PATCH` (`x.y.Z`): increase patch only (`1.4.2` -> `1.4.3`)
1141
+ - `MINOR` (`x.Y.0`): increase minor, reset patch (`1.4.9` -> `1.5.0`)
1142
+ - `MAJOR` (`X.0.0`): increase major, reset minor and patch (`1.9.7` -> `2.0.0`)
1143
+
1144
+ Examples:
1145
+
1146
+ ```bash
1147
+ # patch
1148
+ git commit -m "MAIN-000/fix: release from 1.0.0 to 1.0.1 - fix onPen throttle edge case"
1149
+
1150
+ # minor
1151
+ git commit -m "MAIN-000/feat: release from 1.1.1 to 1.2.0 - add lease refresh helper"
1152
+
1153
+ # major
1154
+ git commit -m "MAIN-000/refactor: release from 1.1.1 to 2.0.0 - remove legacy API"
1155
+ ```
1156
+
755
1157
  ## 📄 License
756
1158
 
757
1159
  **Proprietary Commercial License**