Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
02d8a8c
ci: migrate to GitHub Actions w/ matrix (#84)
agilgur5 Jun 11, 2022
6bfa53a
docs: change CI badge to use GH Actions instead of Travis
agilgur5 Jun 11, 2022
70def79
deps: use rollup-plugin-node-externals
agilgur5 May 18, 2022
9a98a34
deps: upgrade to rpt2 `0.32.1` to fix `configPlugin` declarationMap i…
agilgur5 Jun 11, 2022
9c6c3ae
deps: use `@agilgur5/tsconfig` to simplify `tsconfig` (#87)
agilgur5 Jun 13, 2022
36ed95a
deps: migrate from Enzyme to RTL (#88)
agilgur5 Jun 15, 2022
9d68e79
deps: update peerDeps to support React 18 without warnings (#89)
agilgur5 Jun 16, 2022
c542b5e
docs: fix & update badges (#99)
agilgur5 Jul 13, 2023
fc84322
fix(ci): temporarily pin matrix to Node 16 on Ubuntu (#113)
agilgur5 Dec 31, 2024
ad13e65
fix(ci): update `codecov-action` to v5 (#114)
agilgur5 Dec 31, 2024
b5f2674
fix(ci): run GH action on external PRs as well (#112)
agilgur5 Dec 31, 2024
98774b0
deps: update `node-canvas`, Node, actions, + `npm audit fix` (#115)
agilgur5 Dec 31, 2024
917b070
deps: update peerDeps to support React 19 without warnings (#116)
agilgur5 Jan 3, 2025
f74f31a
deps: update `jest` et al to v29, `concurrently` to v9 (#118)
agilgur5 Feb 11, 2025
8250eb1
docs: update examples to use newer React syntax (#119)
agilgur5 Feb 11, 2025
ca97b54
docs: update link to new CodeSandbox example (#120)
agilgur5 Feb 14, 2025
9560517
docs: update other CodeSandbox link as well (#121)
agilgur5 Feb 15, 2025
43b414b
deps: move peer types to optional peerDeps (#122)
agilgur5 Feb 15, 2025
6e6c5ca
pkg: update description to mention current features (#123)
agilgur5 Feb 15, 2025
b816b72
pkg: release v1.1.0-alpha.1 -- native TypeScript
agilgur5 Feb 15, 2025
21390c1
deps: remove no longer used `changelog-maker` devDep (#124)
agilgur5 Feb 15, 2025
03b00a8
fix(pkg): add `types` to `package.json#exports` (#126)
daltonkyemiller Mar 12, 2025
c85c1db
refactor: use `types` consistently instead of `typings` (#130)
agilgur5 Mar 27, 2025
98e9c46
fix(pkg): move `types` above `default` (#131)
agilgur5 Mar 29, 2025
d79a7b1
deps: fix install on Node 22.14+ by updating `canvas` et al (#132)
agilgur5 Mar 29, 2025
2695c44
pkg: release v1.1.0-alpha.2 -- add `package.json#exports.types`
agilgur5 Mar 29, 2025
e7e5aa1
ci: pin actions & limit token permissions (#133)
agilgur5 Apr 6, 2025
bf8bd02
gh: create a bug report issue form + chooser config (#134)
agilgur5 Apr 12, 2025
3c96dad
fix: resolve trim-canvas import error in SignatureCanvas
Hamza65523 Nov 2, 2025
3ece5cb
fix(signature-canvas): add universal import handling for trim-canvas …
Hamza65523 Nov 2, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions .github/ISSUE_TEMPLATE/bug-report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: Reproducible Bug Report
description: If you found a bug within `react-signature-canvas` itself and have a minimal reproduction of it. For support requests, use StackOverflow.
body:
# larger description of what this template's intended usage is
- type: markdown
attributes:
value: |
This template is to report a reproducible bug within `react-signature-canvas` itself.

Issues [should _not_](https://docs.github.com/en/get-started/using-github/communicating-on-github) be used for support requests -- use [StackOverflow](https://stackoverflow.com/search?q=react-signature-canvas) for that instead.

This should _not_ be used for issues with the underlying `signature_pad` -- use [`signature_pad`'s issues](https://github.com/szimek/signature_pad/issues) for that instead.

Before opening a new issue, please do a [search of existing issues](https://github.com/agilgur5/react-signature-canvas/issues?q=is%3Aissue).
If a relevant open issue exists, you should :+1: upvote it instead.
If a relevant closed issue exists, please follow the directions of the closing comments.
Do not open duplicates of existing issues.

# require that users have searched existing issues
- type: checkboxes
attributes:
label: Have you searched the existing issues?
description: Please search to see if an issue already exists for the problem you encountered
options:
- label: I have searched the existing issues and cannot find my problem
required: true

# require that users provide a minimal reproduction
- type: input
attributes:
label: Provide a link to code that _minimally_ reproduces this bug
description: |
Link to a [minimal reproduction](https://stackoverflow.com/help/minimal-reproducible-example) via a public [CodeSandbox](https://codesandbox.io/s/github/agilgur5/react-signature-canvas/tree/codesandbox-example), StackBlitz project, or GitHub repository.

_Skipping this or providing an invalid link may result in your issue being summarily closed._
placeholder: 'https://codesandbox.io/p/sandbox/my-minimal-react-signature-canvas-bug-reproduction'
validations:
required: true

# require that users provide their environment details
- type: textarea
attributes:
label: Provide version numbers for your environment by running the below command
description: npx envinfo --npmPackages react-signature-canvas,react,react-dom,typescript --npmGlobalPackages typescript --binaries --browsers --system os
render: text # render as a ```text code block
# example output to clue in user about what it should look like
placeholder: |
System:
OS: macOS 14.5
Binaries:
Node: 22.14.0 - ~/.local/share/mise/installs/node/22.14.0/bin/node
Yarn: 1.22.19 - /usr/local/bin/yarn
npm: 10.9.2 - ~/.local/share/mise/installs/node/22.14.0/bin/npm
Browsers:
Chrome: 134.0.6998.166
Safari: 17.5
npmPackages:
react: ^19.0.0 => 19.0.0
react-dom: ^19.0.0 => 19.0.0
react-signature-canvas: ^1.0.7 => 1.0.7
typescript: ^4.6.3 => 4.6.4
validations:
required: true

# describe the problem
- type: textarea
attributes:
label: Describe the problem, how to reproduce it, and why you believe the behavior is a bug in this library
description: What is the current behavior vs. the expected behavior?
render: markdown # render directly as markdown
# example output to clue in user about what it should look like
placeholder: |
In the provided reproduction, run `npm run typecheck`. This results in a TypeScript error: `Could not find a declaration file for module 'react-signature-canvas'`.
As this library is natively written in TypeScript, I assumed that type declarations should be provided and that a TS build would succeed.
validations:
required: true
7 changes: 7 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
contact_links:
- name: Search on StackOverflow
url: https://stackoverflow.com/search?q=react-signature-canvas
about: Use StackOverflow for support questions. Issues are for reproducible bug reports and feature requests.
- name: Upstream `signature_pad`'s issues
url: https://github.com/szimek/signature_pad/issues
about: This library is a wrapper around `signature_pad`. If you have an with `signature_pad` itself (as opposed to this wrapper), please see its issue tracker.
38 changes: 38 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: CI
on: [push, pull_request]

permissions:
contents: read

jobs:
ci:
name: CI - Node ${{ matrix.node-version }}, ${{ matrix.os }}

runs-on: ${{ matrix.os }}
strategy:
matrix:
node-version: [18.x, 20.x, 22.x] # LTS Node: https://nodejs.org/en/about/releases/
os: [ubuntu-latest]

steps:
- name: Checkout repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Install
run: npm ci

- name: Typecheck
run: npm run tsc
- name: Lint
run: npm run lint
- name: Build
run: npm run build

- name: Test w/ coverage report
run: npm run test:coverage
- name: Upload coverage report to Codecov
uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5.4.0
12 changes: 0 additions & 12 deletions .travis.yml

This file was deleted.

46 changes: 28 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,42 +8,43 @@
<!-- releases / versioning -->
[![package-json](https://img.shields.io/github/package-json/v/agilgur5/react-signature-canvas.svg)](https://npmjs.org/package/react-signature-canvas)
[![releases](https://img.shields.io/github/tag-pre/agilgur5/react-signature-canvas.svg)](https://github.com/agilgur5/react-signature-canvas/releases)
[![commits](https://img.shields.io/github/commits-since/agilgur5/react-signature-canvas/v1.0.5.svg)](https://github.com/agilgur5/react-signature-canvas/commits/main)
[![commits](https://img.shields.io/github/commits-since/agilgur5/react-signature-canvas/latest.svg)](https://github.com/agilgur5/react-signature-canvas/commits/main)
<br><!-- downloads -->
[![dt](https://img.shields.io/npm/dt/react-signature-canvas.svg)](https://npmjs.org/package/react-signature-canvas)
[![dy](https://img.shields.io/npm/dy/react-signature-canvas.svg)](https://npmjs.org/package/react-signature-canvas)
[![dm](https://img.shields.io/npm/dm/react-signature-canvas.svg)](https://npmjs.org/package/react-signature-canvas)
[![dw](https://img.shields.io/npm/dw/react-signature-canvas.svg)](https://npmjs.org/package/react-signature-canvas)
<br><!-- status / activity -->
[![typings](https://img.shields.io/npm/types/react-signature-canvas.svg)](src/index.tsx)
[![build status](https://img.shields.io/travis/com/agilgur5/react-signature-canvas/main.svg)](https://app.travis-ci.com/github/agilgur5/react-signature-canvas/branches)
[![build status](https://img.shields.io/github/actions/workflow/status/agilgur5/react-signature-canvas/ci.yml?branch=main)](https://github.com/agilgur5/react-signature-canvas/actions/workflows/ci.yml?query=branch%3Amain)
[![code coverage](https://img.shields.io/codecov/c/gh/agilgur5/react-signature-canvas/main.svg)](https://codecov.io/gh/agilgur5/react-signature-canvas)
<br>
[![NPM](https://nodei.co/npm/react-signature-canvas.png?downloads=true&downloadRank=true&stars=true)](https://npmjs.org/package/react-signature-canvas)
<br>

A React wrapper component around [signature_pad](https://github.com/szimek/signature_pad).

Originally, this was just an _unopinionated_ fork of [react-signature-pad](https://github.com/blackjk3/react-signature-pad) that did not impose any styling or wrap any other unwanted elements around your canvas -- it's just a wrapper around a single canvas element!
Hence the naming difference.
Nowadays, this repo / library has significantly evolved, introducing new features, fixing various bugs, and now wrapping the upstream `signature_pad` to have its updates and bugfixes baked in.

This fork also allows you to directly pass [props](#props) to the underlying canvas element, has new, documented [API methods](#api) you can use, has new, documented [props](#props) you can pass to it, has a [live demo](https://agilgur5.github.io/react-signature-canvas/), has a [CodeSandbox playground](https://codesandbox.io/s/github/agilgur5/react-signature-canvas/tree/cra-example), has [100% test coverage](https://codecov.io/gh/agilgur5/react-signature-canvas), and is [written in TypeScript](src/index.tsx).
This fork also allows you to directly pass [props](#props) to the underlying canvas element, has new, documented [API methods](#api) you can use, has new, documented [props](#props) you can pass to it, has a [live demo](https://agilgur5.github.io/react-signature-canvas/), has a [CodeSandbox playground](https://codesandbox.io/s/github/agilgur5/react-signature-canvas/tree/codesandbox-example), has [100% test coverage](https://codecov.io/gh/agilgur5/react-signature-canvas), and is [written in TypeScript](src/index.tsx).

## Installation

`npm i -S react-signature-canvas`
```sh
npm i -S react-signature-canvas
```

## Usage

```javascript
```jsx
import React from 'react'
import ReactDOM from 'react-dom'
import { createRoot } from 'react-dom/client'
import SignatureCanvas from 'react-signature-canvas'

ReactDOM.render(
createRoot(
document.getElementById('my-react-container')
).render(
<SignatureCanvas penColor='green'
canvasProps={{width: 500, height: 200, className: 'sigCanvas'}} />,
document.getElementById('react-container')
)
```

Expand Down Expand Up @@ -80,10 +81,17 @@ Of these props, all, except for `canvasProps` and `clearOnResize`, are passed th

### API

All API methods require a ref to the SignatureCanvas in order to use and are instance methods of the ref.
All API methods require [a ref](https://react.dev/learn/manipulating-the-dom-with-refs) to the SignatureCanvas in order to use and are instance methods of the ref.

```jsx
import React, { useRef } from 'react'
import SignatureCanvas from 'react-signature-canvas'

```javascript
<SignatureCanvas ref={(ref) => { this.sigCanvas = ref }} />
function MyApp() {
const sigCanvas = useRef(null);

return <SignatureCanvas ref={sigCanvas} />
}
```

- `isEmpty()` : `boolean`, self-explanatory
Expand All @@ -108,8 +116,10 @@ The API methods are _mostly_ just wrappers around [`signature_pad`'s API](https:
You can interact with the example in a few different ways:

1. Run `npm start` and navigate to [http://localhost:1234/](http://localhost:1234/).<br>
Hosted locally via the [`example/`](example/) directory
Hosted locally via the [`example/`](example/) directory

1. [View the live demo here](https://agilgur5.github.io/react-signature-canvas/).<br>
Hosted via the [`gh-pages` branch](https://github.com/agilgur5/react-signature-canvas/tree/gh-pages), a standalone version of the code in [`example/`](example/)
1. [Play with the CodeSandbox here](https://codesandbox.io/s/github/agilgur5/react-signature-canvas/tree/cra-example).<br>
Hosted via the [`cra-example` branch](https://github.com/agilgur5/react-signature-canvas/tree/gh-pages), a standalone version using [Create React App](https://github.com/facebook/create-react-app).
Hosted via the [`gh-pages` branch](https://github.com/agilgur5/react-signature-canvas/tree/gh-pages), a standalone version of the code in [`example/`](example/)

1. [Play with the CodeSandbox here](https://codesandbox.io/s/github/agilgur5/react-signature-canvas/tree/codesandbox-example).<br>
Hosted via the [`codesandbox-example` branch](https://github.com/agilgur5/react-signature-canvas/tree/codesandbox-example), a slightly modified version of the above.
46 changes: 18 additions & 28 deletions example/src/index.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,36 @@
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import React, { useState, useRef } from 'react'
import { createRoot } from 'react-dom/client'

import SignaturePad from '../../src/index.tsx'
import SignatureCanvas from '../../src/index.tsx'

import * as styles from './styles.module.css'

class App extends Component {
state = { trimmedDataURL: null }
function App () {
const sigCanvas = useRef(null)
const [trimmedDataURL, setTrimmedDataURL] = useState(null)

sigPad = {}

clear = () => {
this.sigPad.clear()
function clear () {
sigCanvas.current.clear()
}

trim = () => {
this.setState({
trimmedDataURL: this.sigPad.getTrimmedCanvas().toDataURL('image/png')
})
function trim () {
setTrimmedDataURL(sigCanvas.current.getTrimmedCanvas().toDataURL('image/png'))
}

render () {
const { trimmedDataURL } = this.state
return <div className={styles.container}>
return (
<div className={styles.container}>
<div className={styles.sigContainer}>
<SignaturePad canvasProps={{ className: styles.sigPad }}
ref={(ref) => { this.sigPad = ref }} />
<SignatureCanvas canvasProps={{ className: styles.sigCanvas }} ref={sigCanvas} />
</div>
<div>
<button className={styles.buttons} onClick={this.clear}>
Clear
</button>
<button className={styles.buttons} onClick={this.trim}>
Trim
</button>
<button className={styles.buttons} onClick={clear}>Clear</button>
<button className={styles.buttons} onClick={trim}>Trim</button>
</div>
{trimmedDataURL
? <img className={styles.sigImage} alt='signature'
src={trimmedDataURL} />
? <img className={styles.sigImage} alt='signature' src={trimmedDataURL} />
: null}
</div>
}
)
}

ReactDOM.render(<App />, document.getElementById('container'))
createRoot(document.getElementById('container')).render(<App />)
2 changes: 1 addition & 1 deletion example/src/styles.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ body {
background-color: #fff;
}

.sigPad {
.sigCanvas {
width: 100%;
height: 100%;
}
Expand Down
2 changes: 0 additions & 2 deletions jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ const config: Config.InitialOptions = {
injectGlobals: false, // use @jest/globals
testEnvironment: 'jsdom',
setupFilesAfterEnv: [
// configure enzyme w/ react adapter
'<rootDir>/test/config/configure-enzyme.js',
// polyfill window.resizeTo
'window-resizeto/polyfill'
],
Expand Down
Loading