import type { SxProps, Theme } from '@mui/material'; export type ViewerMode = 'read' | 'highlight'; /** * Quote-based anchor for DOM-change-resilient annotation restoration. * prefix/suffix provide fuzzy-match fallback when domPath fails. */ export interface TextAnchor { exact: string; prefix?: string; suffix?: string; startPath?: string; endPath?: string; domPath?: string; startOffset?: number; endOffset?: number; hintBlockIndex?: number; } export interface Annotation { id: string; documentId: string; anchor: TextAnchor; color: string; memo?: string; createdAt: string; status?: 'active' | 'detached'; } /** * @security The `content` prop must be pre-sanitized by the caller. * This component does NOT sanitize HTML internally. * Pass empty string to render a placeholder instead of raw HTML. */ export interface EliceHtmlViewerProps { /** Pre-sanitized HTML string. @security Caller must sanitize before passing. */ content: string; documentId: string; defaultMode?: ViewerMode; onAnnotationCreate?: (annotation: Annotation) => void; onAnnotationUpdate?: (annotation: Annotation) => void; onAnnotationDelete?: (id: string) => void; /** Controlled annotations. When provided, internal storage is bypassed. */ annotations?: Annotation[]; colors?: string[]; sx?: SxProps; } export interface HighlightRect { x: number; y: number; width: number; height: number; annotationId: string; color: string; } export type GestureState = { kind: 'idle'; } | { kind: 'pressing'; startX: number; startY: number; startTime: number; pointerType: string; } | { kind: 'longPressArmed'; startX: number; startY: number; } | { kind: 'selecting'; anchorRange: Range; } | { kind: 'scrolling'; }; export interface MenuPosition { x: number; y: number; } export interface HtmlViewerState { mode: ViewerMode; annotations: Annotation[]; activeAnnotationId: string | null; pendingRange: Range | null; menuPosition: MenuPosition | null; } export type HtmlViewerAction = { type: 'SET_MODE'; payload: ViewerMode; } | { type: 'ADD_ANNOTATION'; payload: Annotation; } | { type: 'UPDATE_ANNOTATION'; payload: Annotation; } | { type: 'DELETE_ANNOTATION'; payload: string; } | { type: 'SET_ACTIVE_ANNOTATION'; payload: string | null; } | { type: 'SET_PENDING_RANGE'; payload: Range | null; } | { type: 'SET_MENU_POSITION'; payload: MenuPosition | null; } | { type: 'SYNC_ANNOTATIONS'; payload: Annotation[]; };