UNPKG

react-signature-canvas-component

Version:

A responsive signature canvas component for React and Next.js applications.

3 lines 4.95 kB
"use client"; "use client";import P,{useState as u,useRef as z,useEffect as D}from"react";import{RotateCcw as F,Palette as q,Pen as b}from"lucide-react";import{jsx as s,jsxs as i}from"react/jsx-runtime";var M=P.forwardRef(({onSignatureChange:h,disabled:r=!1,controls:T=!0,title:I="Draw Your Signature",info:R=!0},W)=>{let c=z(null),[w,x]=u(!1),[f,d]=u(null),[C,k]=u(!0),[l,E]=u("#1f2937"),[g,m]=u(3),[Y,B]=u(!1),A=["#1f2937","#9ca3af","#000000","#3b82f6","#059669","#dc2626","#7c2d12"],N=t=>{let o=c.current,e=o.getBoundingClientRect(),a=o.width/e.width,n=o.height/e.height;return{x:(t.clientX-e.left)*a,y:(t.clientY-e.top)*n}},S=t=>{let o=c.current,e=o.getBoundingClientRect(),a=o.width/e.width,n=o.height/e.height;return{x:(t.clientX-e.left)*a,y:(t.clientY-e.top)*n}},X=t=>{if(r)return;t.preventDefault(),x(!0);let o=N(t);d(o);let a=c.current.getContext("2d");a.beginPath(),a.arc(o.x,o.y,g/2,0,2*Math.PI),a.fillStyle=l,a.fill()},$=t=>{if(r)return;t.preventDefault(),x(!0);let o=t.touches[0],e=S(o);d(e);let n=c.current.getContext("2d");n.beginPath(),n.arc(e.x,e.y,g/2,0,2*Math.PI),n.fillStyle=l,n.fill()},L=t=>{if(!w||r)return;t.preventDefault();let e=c.current.getContext("2d"),a=N(t);e.beginPath(),e.moveTo(f.x,f.y),e.lineTo(a.x,a.y),e.strokeStyle=l,e.lineWidth=g,e.lineCap="round",e.lineJoin="round",e.stroke(),d(a)},j=t=>{if(!w||r)return;t.preventDefault();let e=c.current.getContext("2d"),a=t.touches[0],n=S(a);e.beginPath(),e.moveTo(f.x,f.y),e.lineTo(n.x,n.y),e.strokeStyle=l,e.lineWidth=g,e.lineCap="round",e.lineJoin="round",e.stroke(),d(n)},v=()=>{x(!1),d(null),H()},p=()=>{let t=c.current;if(!t)return!0;let a=t.getContext("2d").getImageData(0,0,t.width,t.height).data;for(let n=0;n<a.length;n+=4)if(a[n+3]>0)return!1;return!0},H=()=>{let t=p();k(t),h&&h(t)},y=()=>{let t=c.current;if(!t)return;t.getContext("2d").clearRect(0,0,t.width,t.height),k(!0),h&&h(!0)},J=()=>p()?null:c.current.toDataURL("image/png"),U=()=>new Promise(t=>{if(p()){t(null);return}c.current.toBlob(t,"image/png")});P.useImperativeHandle(W,()=>({getSignatureData:J,getSignatureBlob:U,checkIfEmpty:p,clearCanvas:y}));let G=t=>{let o=Math.max(1,Math.min(10,g+t));m(o)};return D(()=>{r&&y()},[r]),D(()=>{let t=c.current},[]),i("div",{className:"space-y-4",children:[i("div",{className:"flex items-center justify-between",children:[s("label",{className:"block text-sm font-medium text-gray-700",children:I}),i("div",{className:"flex items-center space-x-2",children:[T&&i("div",{className:"flex items-center space-x-1 bg-gray-100 rounded-lg p-1",children:[i("button",{onClick:()=>m(3),disabled:r,className:"p-1 text-gray-600 hover:text-gray-800 disabled:opacity-50 disabled:cursor-not-allowed",title:"Set stroke width to 3px",children:[s(b,{className:"w-3 h-3"})," "]}),i("button",{onClick:()=>m(4),disabled:r,className:"p-1 text-gray-600 hover:text-gray-800 disabled:opacity-50 disabled:cursor-not-allowed",title:"Set stroke width to 4px",children:[s(b,{className:"w-4 h-4"})," "]}),i("button",{onClick:()=>m(5),disabled:r,className:"p-1 text-gray-600 hover:text-gray-800 disabled:opacity-50 disabled:cursor-not-allowed",title:"Set stroke width to 5px",children:[s(b,{className:"w-5 h-5"})," "]})]}),s("div",{className:"relative",children:i("label",{htmlFor:"signature-color-picker",className:`flex items-center space-x-2 px-3 py-1 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors disabled:opacity-50 ${r?"cursor-not-allowed":"cursor-pointer"}`,title:"Choose color",children:[s(q,{className:"w-4 h-4 text-gray-600"}),s("div",{className:"w-4 h-4 rounded border-2 border-white shadow-sm",style:{backgroundColor:l}}),s("input",{type:"color",id:"signature-color-picker",value:l,onChange:t=>E(t.target.value),disabled:r,className:"absolute inset-0 w-full h-full opacity-0 cursor-pointer"})]})})]})]}),i("div",{className:`border-2 border-dashed rounded-lg p-4 transition-colors ${r?"border-gray-200 bg-gray-50":"border-gray-300 bg-gray-50"}`,children:[s("canvas",{ref:c,width:500,height:200,className:`w-full border border-gray-200 rounded bg-white touch-none ${r?"cursor-not-allowed opacity-50":"cursor-crosshair"}`,style:{maxWidth:"100%",height:"auto"},onMouseDown:X,onMouseMove:L,onMouseUp:v,onMouseLeave:v,onTouchStart:$,onTouchMove:j,onTouchEnd:v}),R&&i("div",{className:"flex justify-between items-center mt-3",children:[i("button",{onClick:y,disabled:r,className:"flex items-center space-x-2 px-3 py-2 text-sm text-gray-600 hover:text-gray-800 hover:bg-gray-100 rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed",children:[s(F,{className:"w-4 h-4"}),s("span",{children:"Clear Signature"})]}),s("div",{className:`text-xs px-3 py-1 rounded-full ${C?"text-amber-700 bg-amber-100":"text-green-700 bg-green-100"}`,children:C?"Please sign above":"Signature ready"})]})]}),Y&&s("div",{className:"fixed inset-0 z-5",onClick:()=>B(!1)})]})});M.displayName="SignatureCanvas";var tt=M;export{tt as default}; //# sourceMappingURL=index.mjs.map