fix: debounce display of signing canvas
Debounces the display of the signing canvas to avoid situtations where the canvas renders to 2px due to rendering while a transition is being performed.
This commit is contained in:
@@ -5,6 +5,7 @@ import { Button, IconButton } from "@documenso/ui";
|
|||||||
import { Dialog, Transition } from "@headlessui/react";
|
import { Dialog, Transition } from "@headlessui/react";
|
||||||
import { LanguageIcon, PencilIcon, TrashIcon } from "@heroicons/react/24/outline";
|
import { LanguageIcon, PencilIcon, TrashIcon } from "@heroicons/react/24/outline";
|
||||||
import SignatureCanvas from "react-signature-canvas";
|
import SignatureCanvas from "react-signature-canvas";
|
||||||
|
import { useDebouncedValue } from "../../hooks/use-debounced-value";
|
||||||
|
|
||||||
const tabs = [
|
const tabs = [
|
||||||
{ name: "Type", icon: LanguageIcon, current: true },
|
{ name: "Type", icon: LanguageIcon, current: true },
|
||||||
@@ -15,6 +16,9 @@ export default function SignatureDialog(props: any) {
|
|||||||
const [currentTab, setCurrentTab] = useState(tabs[0]);
|
const [currentTab, setCurrentTab] = useState(tabs[0]);
|
||||||
const [typedSignature, setTypedSignature] = useState("");
|
const [typedSignature, setTypedSignature] = useState("");
|
||||||
const [signatureEmpty, setSignatureEmpty] = useState(true);
|
const [signatureEmpty, setSignatureEmpty] = useState(true);
|
||||||
|
// This is a workaround to prevent the canvas from being rendered when the dialog is closed
|
||||||
|
// we also need the debounce to avoid rendering while transitions are occuring.
|
||||||
|
const showCanvas = useDebouncedValue<boolean>(props.open, 1);
|
||||||
let signCanvasRef: any | undefined;
|
let signCanvasRef: any | undefined;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -126,19 +130,21 @@ export default function SignatureDialog(props: any) {
|
|||||||
""
|
""
|
||||||
)}
|
)}
|
||||||
{isCurrentTab("Draw") ? (
|
{isCurrentTab("Draw") ? (
|
||||||
<div className="">
|
<div className="" key={props.open ? "closed" : "open"}>
|
||||||
<SignatureCanvas
|
{showCanvas && (
|
||||||
ref={(ref) => {
|
<SignatureCanvas
|
||||||
signCanvasRef = ref;
|
ref={(ref) => {
|
||||||
}}
|
signCanvasRef = ref;
|
||||||
canvasProps={{
|
}}
|
||||||
className: "sigCanvas border-b b-2 border-slate w-full h-full mb-3",
|
canvasProps={{
|
||||||
}}
|
className: "sigCanvas border-b b-2 border-slate w-full h-full mb-3",
|
||||||
clearOnResize={true}
|
}}
|
||||||
onEnd={() => {
|
clearOnResize={true}
|
||||||
setSignatureEmpty(signCanvasRef?.isEmpty());
|
onEnd={() => {
|
||||||
}}
|
setSignatureEmpty(signCanvasRef?.isEmpty());
|
||||||
/>
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<IconButton
|
<IconButton
|
||||||
className="float-left block"
|
className="float-left block"
|
||||||
icon={TrashIcon}
|
icon={TrashIcon}
|
||||||
|
|||||||
18
apps/web/hooks/use-debounced-value.ts
Normal file
18
apps/web/hooks/use-debounced-value.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
export function useDebouncedValue<T>(value: T, delay: number) {
|
||||||
|
// State and setters for debounced value
|
||||||
|
const [debouncedValue, setDebouncedValue] = useState(value);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handler = setTimeout(() => {
|
||||||
|
setDebouncedValue(value);
|
||||||
|
}, delay);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
clearTimeout(handler);
|
||||||
|
};
|
||||||
|
}, [value, delay]);
|
||||||
|
|
||||||
|
return debouncedValue;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user