/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ /** * Single annotation pin — a 14px circle anchored to a screen point. * * The dot itself is small; we wrap it in a 24×24 invisible hit-target * so it stays comfortable on touch and doesn't fight pointer events * on the surrounding canvas. The pin sits in the canvas overlay layer * (`AnnotationLayer`) which positions it absolutely each frame. */ import { forwardRef } from 'react'; import { cn } from '@/lib/utils'; export interface AnnotationPinProps { /** Index in the rendered list — 1-based. Shown inside the dot when ≤ 9. */ index: number; /** Highlights the dot with the emerald ring used for selection across the viewer. */ selected?: boolean; /** Tooltip preview when the user hovers (author + first ~40 chars of note). */ preview?: string; /** Called when the dot is clicked. */ onClick?: () => void; /** Called when the dot is right-clicked — used by the layer for "delete via menu". */ onContextMenu?: (e: React.MouseEvent) => void; /** Visual variant. `draft` is a slightly washed-out pin used while the note input is open. */ variant?: 'idle' | 'draft'; } export const AnnotationPin = forwardRef( function AnnotationPin({ index, selected, preview, onClick, onContextMenu, variant = 'idle' }, ref) { // 1-character glyph: the index for ≤ 9, ellipsis otherwise. Keeps // the pin readable at 14px without feeling crowded. const glyph = index <= 9 ? String(index) : '·'; return ( ); }, );