1
0
mirror of https://github.com/tabler/tabler.git synced 2026-08-05 19:03:18 +04:00

Add "Signature" component documentation to the UI components section in docs.json

This commit is contained in:
Bartek
2026-08-04 16:31:27 +02:00
parent 52fe729781
commit 364559b381
2 changed files with 190 additions and 0 deletions
+186
View File
@@ -0,0 +1,186 @@
---
title: Signature
summary: A signature pad lets users sign with a mouse, a pen, or a finger. Use it to confirm an order, accept a contract, or hand over a delivery.
docs-libs: [signature_pad]
description: Collect a drawn signature from users.
layout: '@layouts/DocsMdxLayout.astro'
---
import Example from '@components/Example.astro';
import Icon from '@ui/Icon.astro';
import { Code } from 'astro:components';
import { site } from '@shared/lib/site.ts';
## Overview
The signature pad is a `canvas` element with Tabler styles around it. Drawing is handled by the [Signature Pad](https://github.com/szimek/signature_pad) library.
Use the `signature` class on the wrapper and `signature-canvas` on the canvas. The wrapper draws a solid border, and the canvas adds a dashed one, so the signing area is easy to see. The cursor turns into a crosshair over the canvas.
Try it below. Draw with the mouse, or with a finger on a touch screen.
<Example>
<div class="signature position-relative" style="width: 100%; max-width: 26rem;"> <canvas id="signature-overview" class="signature-canvas" width="400" height="200" style="height: 10rem"></canvas> </div>
</Example>
## Installation
The library is not part of the Tabler bundle. Install it with npm:
```shell
npm install signature_pad
```
Or include it from a CDN:
<Code
lang="html"
code={`<script src="${site.cdnUrl}/dist/libs/signature_pad/dist/signature_pad.umd.min.js"></script>`}
/>
## Usage
### Markup
Wrap the canvas in a `signature` element. Set `width` and `height` on the canvas, so it has a size before the script runs.
Also set the height in CSS. Tabler styles the canvas with `width: 100%`, so without a CSS height the canvas keeps the ratio of its attributes. The resize code below then reads a new height on every run, and the pad gets shorter each time.
<Example codeOnly>
<div class="signature position-relative"> <canvas id="signature-default" class="signature-canvas" width="400" height="400" style="height: 16rem"></canvas> </div>
</Example>
### Init the pad
Create the pad after the DOM is ready. Set a transparent background, so the canvas follows the card or the page. Take the pen color from the canvas text color, so the signature also works in dark mode.
```js
document.addEventListener('DOMContentLoaded', function () {
const canvas = document.getElementById('signature-default')
const signaturePad = new SignaturePad(canvas, {
backgroundColor: 'transparent',
penColor: getComputedStyle(canvas).color,
})
})
```
### Keep the drawing sharp
A canvas has two sizes: the CSS size and the pixel size. On a retina screen they differ, and the line looks blurry. Scale the canvas to the device pixel ratio, and do it again on resize.
```js
function resizeCanvas() {
const ratio = Math.max(window.devicePixelRatio || 1, 1)
canvas.width = canvas.offsetWidth * ratio
canvas.height = canvas.offsetHeight * ratio
canvas.getContext('2d').scale(ratio, ratio)
// resizing clears the canvas, so put the drawing back
signaturePad.fromData(signaturePad.toData())
}
window.addEventListener('resize', resizeCanvas)
resizeCanvas()
```
### Clear button
Place a button in the corner of the wrapper and call `clear()` on it. The wrapper needs `position-relative` for this.
<Example>
<div class="signature position-relative" style="width: 100%; max-width: 26rem;"> <div class="position-absolute top-0 end-0 p-2"> <button type="button" class="btn btn-icon" id="signature-clear-button" title="Clear signature"> <Icon name="trash" /> </button> </div> <canvas id="signature-clear" class="signature-canvas" width="400" height="200" style="height: 10rem"></canvas> </div>
</Example>
```js
document.getElementById('signature-clear-button').addEventListener('click', function () {
signaturePad.clear()
})
```
### Pen color
Change `penColor` at any time. New strokes use the new color, and the old ones keep theirs.
```js
document.getElementById('pen-color').addEventListener('input', function (event) {
signaturePad.penColor = event.target.value
})
```
### Save the signature
Use `toDataURL()` to read the drawing. Without arguments you get a PNG. Pass `image/svg+xml` for a vector file. Check `isEmpty()` first, so you do not save a blank pad.
```js
if (signaturePad.isEmpty()) {
// ask the user to sign first
} else {
const png = signaturePad.toDataURL()
const svg = signaturePad.toDataURL('image/svg+xml')
}
```
Use `fromDataURL()` to show a signature you saved earlier.
### Pad inside a modal
A canvas has no size while the modal is hidden, so the pad must start after the modal opens. Listen for the Bootstrap `shown.bs.modal` event instead of `DOMContentLoaded`.
```js
document.getElementById('modal-signature').addEventListener('shown.bs.modal', function () {
// create the pad here
})
```
## Examples
### Signature in a form
Put the pad in a form group with a label, the same as any other field. Add the legal text under it when the signature is binding.
<Example bg="surface-secondary" column>
<div class="card"> <div class="card-body"> <h3 class="card-title">Confirm transfer</h3> <div class="mb-3"> <label class="form-label required">Signature</label> <div class="signature position-relative"> <div class="position-absolute top-0 end-0 p-2"> <button type="button" class="btn btn-icon" id="signature-form-clear" title="Clear signature"> <Icon name="trash" /> </button> </div> <canvas id="signature-form" class="signature-canvas" width="400" height="180" style="height: 9rem"></canvas> </div> </div> <div class="text-secondary fs-5">I agree that this signature is the electronic representation of my signature for all purposes when I use it on documents.</div> <div class="mt-4 d-flex"> <button type="button" class="btn">Cancel</button> <button type="button" class="btn btn-primary ms-auto">Confirm transfer</button> </div> </div> </div>
</Example>
## Accessibility
- A canvas cannot be used with a keyboard. Offer a second way to sign, for example a text field where the user types their full name.
- Give the pad a real `<label>`, so users know what they sign. Link it to the field with `for` and `id`.
- Use a `<button type="button">` for the clear action. A `div` with button classes is not reachable with the keyboard.
- Tell users what happens with the drawing. A signature is personal data, so say where you store it and for how long.
- Do not rely on the dashed border alone. Add a short hint, for example `Sign inside the box`.
<script>{`
document.addEventListener('DOMContentLoaded', function () {
if (typeof SignaturePad === 'undefined') return;
['signature-overview', 'signature-clear', 'signature-form'].forEach(function (id) {
const canvas = document.getElementById(id);
if (!canvas) return;
const signaturePad = new SignaturePad(canvas, {
backgroundColor: 'transparent',
penColor: getComputedStyle(canvas).color,
});
function resizeCanvas() {
const ratio = Math.max(window.devicePixelRatio || 1, 1);
canvas.width = canvas.offsetWidth * ratio;
canvas.height = canvas.offsetHeight * ratio;
canvas.getContext('2d').scale(ratio, ratio);
signaturePad.fromData(signaturePad.toData());
}
window.addEventListener('resize', resizeCanvas);
resizeCanvas();
const button = document.getElementById(id + '-button') || document.getElementById(id + '-clear');
if (button) {
button.addEventListener('click', function () {
signaturePad.clear();
});
}
});
});
`}</script>
+4
View File
@@ -272,6 +272,10 @@
"title": "Segmented Control",
"url": "/ui/components/segmented-control/"
},
{
"title": "Signature",
"url": "/ui/components/signature/"
},
{
"title": "Spinner",
"url": "/ui/components/spinner/"