Delete signature

This commit is contained in:
Reece Browne 2025-09-23 18:16:21 +01:00
parent fc2f34ee15
commit bac61c7e9e
4 changed files with 88 additions and 7 deletions

View File

@ -461,6 +461,7 @@ const SignSettings = ({ parameters, onParameterChange, disabled = false, onActiv
/>
</div>
{/* Signature Creation based on type */}
{parameters.signatureType === 'canvas' && (
<Paper withBorder p="md">

View File

@ -1,4 +1,4 @@
import React, { useEffect, useMemo, useState } from 'react';
import React, { useEffect, useMemo, useState, useRef } from 'react';
import { createPluginRegistration } from '@embedpdf/core';
import { EmbedPDF } from '@embedpdf/core/react';
import { usePdfiumEngine } from '@embedpdf/engines/react';
@ -46,6 +46,7 @@ interface LocalEmbedPDFProps {
export function LocalEmbedPDF({ file, url, enableSignature = false, onSignatureAdded, signatureApiRef }: LocalEmbedPDFProps) {
const [pdfUrl, setPdfUrl] = useState<string | null>(null);
const [annotations, setAnnotations] = useState<Array<{id: string, pageIndex: number, rect: any}>>([]);
// Convert File to URL if needed
useEffect(() => {
@ -217,14 +218,34 @@ export function LocalEmbedPDF({ file, url, enableSignature = false, onSignatureA
},
});
// Listen for annotation events to notify parent component
if (onSignatureAdded) {
// Listen for annotation events to track annotations and notify parent
annotationApi.onAnnotationEvent((event: any) => {
if (event.type === 'create' && event.committed) {
// Add to annotations list
setAnnotations(prev => [...prev, {
id: event.annotation.id,
pageIndex: event.pageIndex,
rect: event.annotation.rect
}]);
// Notify parent if callback provided
if (onSignatureAdded) {
onSignatureAdded(event.annotation);
}
});
} else if (event.type === 'delete' && event.committed) {
// Remove from annotations list
setAnnotations(prev => prev.filter(ann => ann.id !== event.annotation.id));
} else if (event.type === 'loaded') {
// Handle initial load of annotations
const loadedAnnotations = event.annotations || [];
setAnnotations(loadedAnnotations.map((ann: any) => ({
id: ann.id,
pageIndex: ann.pageIndex || 0,
rect: ann.rect
})));
}
});
} : undefined}
>
<ZoomAPIBridge />
@ -297,6 +318,7 @@ export function LocalEmbedPDF({ file, url, enableSignature = false, onSignatureA
)}
/>
</Viewport>
</GlobalPointerProvider>
</EmbedPDF>
</div>

View File

@ -9,6 +9,8 @@ export interface SignatureAPI {
addTextSignature: (text: string, x: number, y: number, pageIndex: number) => void;
activateDrawMode: () => void;
activateSignaturePlacementMode: () => void;
activateDeleteMode: () => void;
deleteAnnotation: (annotationId: string, pageIndex: number) => void;
updateDrawSettings: (color: string, size: number) => void;
deactivateTools: () => void;
applySignatureFromParameters: (params: SignParameters) => void;
@ -20,6 +22,30 @@ export const SignatureAPIBridge = forwardRef<SignatureAPI, SignatureAPIBridgePro
const { provides: annotationApi } = useAnnotationCapability();
const { signatureConfig } = useSignature();
// Enable keyboard deletion of selected annotations
useEffect(() => {
if (!annotationApi) return;
const handleKeyDown = (event: KeyboardEvent) => {
if (event.key === 'Delete' || event.key === 'Backspace') {
const selectedAnnotation = annotationApi.getSelectedAnnotation?.();
if (selectedAnnotation) {
const annotation = selectedAnnotation as any;
const pageIndex = annotation.object?.pageIndex || 0;
const id = annotation.object?.id;
if (id) {
annotationApi.deleteAnnotation(pageIndex, id);
}
}
}
};
document.addEventListener('keydown', handleKeyDown);
return () => document.removeEventListener('keydown', handleKeyDown);
}, [annotationApi]);
useImperativeHandle(ref, () => ({
addImageSignature: (signatureData: string, x: number, y: number, width: number, height: number, pageIndex: number) => {
if (!annotationApi) return;
@ -183,6 +209,19 @@ export const SignatureAPIBridge = forwardRef<SignatureAPI, SignatureAPIBridgePro
}, 50);
},
activateDeleteMode: () => {
if (!annotationApi) return;
// Activate selection tool to allow selecting and deleting annotations
// Users can click annotations to select them, then press Delete key or right-click to delete
annotationApi.setActiveTool('select');
},
deleteAnnotation: (annotationId: string, pageIndex: number) => {
if (!annotationApi) return;
// Delete specific annotation by ID
annotationApi.deleteAnnotation(pageIndex, annotationId);
},
deactivateTools: () => {
if (!annotationApi) return;
annotationApi.setActiveTool(null);
@ -208,6 +247,11 @@ export const SignatureAPIBridge = forwardRef<SignatureAPI, SignatureAPIBridgePro
id: uuidV4(),
created: new Date(),
});
// Switch to select mode after placing signature so it can be easily deleted
setTimeout(() => {
annotationApi.setActiveTool('select');
}, 100);
}
break;
@ -231,6 +275,11 @@ export const SignatureAPIBridge = forwardRef<SignatureAPI, SignatureAPIBridgePro
id: uuidV4(),
created: new Date(),
});
// Switch to select mode after placing signature so it can be easily deleted
setTimeout(() => {
annotationApi.setActiveTool('select');
}, 100);
}
break;

View File

@ -17,6 +17,7 @@ interface SignatureActions {
activateDrawMode: () => void;
deactivateDrawMode: () => void;
activateSignaturePlacementMode: () => void;
activateDeleteMode: () => void;
updateDrawSettings: (color: string, size: number) => void;
}
@ -86,6 +87,13 @@ export const SignatureProvider: React.FC<{ children: ReactNode }> = ({ children
}
}, [state.signatureConfig, setPlacementMode]);
const activateDeleteMode = useCallback(() => {
if (signatureApiRef.current) {
signatureApiRef.current.activateDeleteMode();
setPlacementMode(true);
}
}, [setPlacementMode]);
const updateDrawSettings = useCallback((color: string, size: number) => {
if (signatureApiRef.current) {
signatureApiRef.current.updateDrawSettings(color, size);
@ -103,6 +111,7 @@ export const SignatureProvider: React.FC<{ children: ReactNode }> = ({ children
activateDrawMode,
deactivateDrawMode,
activateSignaturePlacementMode,
activateDeleteMode,
updateDrawSettings,
};