Improve annotations (#5919)

* Text box/notes movement improvements 
* Fix the issue where hiding, then showing annotations looses progress 
* Fix the issue where hidig/showing annotations jumps you back up to the
top of your open document 
* Support ctrl+c and  ctrl+v and backspace to delete 
* Better handling when moving to different tool from annotate 
* Added a color picker eyedropper button  
* Auto-switch to Select after note/text placement, so users can quickly
place and type 
This commit is contained in:
EthanHealy01
2026-03-13 14:03:27 +00:00
committed by GitHub
parent 44e036da5a
commit c9d693f1eb
13 changed files with 409 additions and 245 deletions
@@ -8,6 +8,7 @@ import type {
AnnotationEvent,
AnnotationPatch,
AnnotationRect,
AnnotationSelection,
} from '@app/components/viewer/viewerTypes';
import { useDocumentReady } from '@app/components/viewer/hooks/useDocumentReady';
@@ -86,9 +87,13 @@ type AnnotationApiSurface = {
setActiveTool: (toolId: AnnotationToolId | null) => void;
getActiveTool?: () => { id: AnnotationToolId } | null;
setToolDefaults?: (toolId: AnnotationToolId, defaults: AnnotationDefaults) => void;
getSelectedAnnotation?: () => unknown | null;
getSelectedAnnotation?: () => AnnotationSelection | null;
deselectAnnotation?: () => void;
updateAnnotation?: (pageIndex: number, annotationId: string, patch: AnnotationPatch) => void;
deleteAnnotation?: (pageIndex: number, annotationId: string) => void;
deleteAnnotations?: (annotations: Array<{ pageIndex: number; id: string }>) => void;
createAnnotation?: (pageIndex: number, annotation: Record<string, unknown>) => void;
getSelectedAnnotations?: () => AnnotationSelection[];
onAnnotationEvent?: (listener: (event: AnnotationEvent) => void) => void | (() => void);
purgeAnnotation?: (pageIndex: number, annotationId: string) => void;
/** v2.7.0: move annotation without regenerating its appearance stream */
@@ -380,6 +385,26 @@ export const AnnotationAPIBridge = forwardRef<AnnotationAPI>(function Annotation
return api?.getActiveTool?.() ?? null;
},
deleteAnnotation: (pageIndex: number, annotationId: string) => {
const api = annotationApi as unknown as AnnotationApiSurface | undefined;
api?.deleteAnnotation?.(pageIndex, annotationId);
},
deleteAnnotations: (annotations: Array<{ pageIndex: number; id: string }>) => {
const api = annotationApi as unknown as AnnotationApiSurface | undefined;
api?.deleteAnnotations?.(annotations);
},
createAnnotation: (pageIndex: number, annotation: Record<string, unknown>) => {
const api = annotationApi as unknown as AnnotationApiSurface | undefined;
api?.createAnnotation?.(pageIndex, annotation);
},
getSelectedAnnotations: () => {
const api = annotationApi as unknown as AnnotationApiSurface | undefined;
return api?.getSelectedAnnotations?.() ?? [];
},
purgeAnnotation: (pageIndex: number, annotationId: string) => {
const api = annotationApi as unknown as AnnotationApiSurface | undefined;
api?.purgeAnnotation?.(pageIndex, annotationId);