feat: allow recipient to select signature color (#1325)

Allow users to select a colour for the signature. The allowed colours
are black, white, red, blue, and green.
This commit is contained in:
Catalin Pit
2024-09-06 08:23:34 +03:00
committed by GitHub
parent a6f93698b4
commit 3f82720383
7 changed files with 101 additions and 7 deletions

View File

@ -9,6 +9,13 @@ import type { StrokeOptions } from 'perfect-freehand';
import { getStroke } from 'perfect-freehand';
import { unsafe_useEffectOnce } from '@documenso/lib/client-only/hooks/use-effect-once';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@documenso/ui/primitives/select';
import { cn } from '../../lib/utils';
import { getSvgPathFromStroke } from './helper';
@ -36,6 +43,7 @@ export const SignaturePad = ({
const [isPressed, setIsPressed] = useState(false);
const [lines, setLines] = useState<Point[][]>([]);
const [currentLine, setCurrentLine] = useState<Point[]>([]);
const [selectedColor, setSelectedColor] = useState('black');
const perfectFreehandOptions = useMemo(() => {
const size = $el.current ? Math.min($el.current.height, $el.current.width) * 0.03 : 10;
@ -85,6 +93,7 @@ export const SignaturePad = ({
ctx.restore();
ctx.imageSmoothingEnabled = true;
ctx.imageSmoothingQuality = 'high';
ctx.fillStyle = selectedColor;
lines.forEach((line) => {
const pathData = new Path2D(
@ -129,6 +138,7 @@ export const SignaturePad = ({
ctx.imageSmoothingEnabled = true;
ctx.imageSmoothingQuality = 'high';
ctx.fillStyle = selectedColor;
newLines.forEach((line) => {
const pathData = new Path2D(
@ -237,7 +247,13 @@ export const SignaturePad = ({
>
<canvas
ref={$el}
className={cn('relative block dark:invert', className)}
className={cn(
'relative block',
{
'dark:hue-rotate-180 dark:invert': selectedColor === 'black',
},
className,
)}
style={{ touchAction: 'none' }}
onPointerMove={(event) => onMouseMove(event)}
onPointerDown={(event) => onMouseDown(event)}
@ -247,6 +263,44 @@ export const SignaturePad = ({
{...props}
/>
<div className="text-foreground absolute right-2 top-2 filter">
<Select defaultValue={selectedColor} onValueChange={(value) => setSelectedColor(value)}>
<SelectTrigger className="h-auto w-auto border-none p-1">
<SelectValue placeholder="" />
</SelectTrigger>
<SelectContent className="w-[150px]" align="end">
<SelectItem value="black">
<div className="text-muted-foreground flex items-center px-1 text-sm">
<div className="border-border mr-2 h-5 w-5 rounded-full border-2 bg-black shadow-sm" />
<Trans>Black</Trans>
</div>
</SelectItem>
<SelectItem value="red">
<div className="text-muted-foreground flex items-center px-1 text-sm">
<div className="border-border mr-2 h-5 w-5 rounded-full border-2 bg-[red] shadow-sm" />
<Trans>Red</Trans>
</div>
</SelectItem>
<SelectItem value="blue">
<div className="text-muted-foreground flex items-center px-1 text-sm">
<div className="border-border mr-2 h-5 w-5 rounded-full border-2 bg-[blue] shadow-sm" />
<Trans>Blue</Trans>
</div>
</SelectItem>
<SelectItem value="green">
<div className="text-muted-foreground flex items-center px-1 text-sm">
<div className="border-border mr-2 h-5 w-5 rounded-full border-2 bg-[green] shadow-sm" />
<Trans>Green</Trans>
</div>
</SelectItem>
</SelectContent>
</Select>
</div>
<div className="absolute bottom-4 right-4 flex gap-2">
<button
type="button"