@semiont/react-ui 0.2.35-build.97 → 0.2.35-build.99

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _semiont_core from '@semiont/core';
2
- import { components, ResourceUri, Selector, AnnotationUri, ResourceAnnotationUri, EventBus, ResourceEvent, EventMap, AnnotationProgress, StoredEvent, paths, Motivation as Motivation$9, GenerationProgress, GenerationContext } from '@semiont/core';
2
+ import { components, ResourceUri, Selector, AnnotationUri, ResourceAnnotationUri, ResourceEvent, EventMap, EventBus, AnnotationProgress, StoredEvent, paths, Motivation as Motivation$9, GenerationProgress, GenerationContext } from '@semiont/core';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import * as React$1 from 'react';
5
5
  import React__default, { ComponentType, ReactNode, KeyboardEvent as KeyboardEvent$1, Component, ErrorInfo } from 'react';
@@ -96,8 +96,6 @@ interface AnnotationUIState {
96
96
  selectedShape: ShapeType;
97
97
  /** ID of currently hovered annotation (optional - only set when hovering) */
98
98
  hoveredAnnotationId?: string | null;
99
- /** ID of currently hovered comment for panel highlighting (optional - only set when hovering) */
100
- hoveredCommentId?: string | null;
101
99
  /** ID of annotation to scroll to (optional - only set when scrolling needed) */
102
100
  scrollToAnnotationId?: string | null;
103
101
  }
@@ -786,28 +784,40 @@ declare const jsonLightHighlightStyle: HighlightStyle;
786
784
  * CodeMirror Inline Widgets
787
785
  *
788
786
  * Custom widgets for enhancing the document editing experience:
789
- * - Wiki link pills (clickable, styled)
790
- * - Reference previews (hover for context)
791
- * - Entity type badges
787
+ * - Reference resolution indicators (resolved 🔗, generating ✨, stub ❓)
788
+ *
789
+ * Event handling uses delegation — no per-widget listeners.
790
+ * Data attributes on the container enable CodeMirrorRenderer to handle
791
+ * clicks and hovers via a single set of delegated handlers.
792
792
  */
793
793
 
794
794
  type Annotation$j = components['schemas']['Annotation'];
795
795
  /**
796
796
  * Reference Resolution Widget
797
- * Shows a small indicator next to references with hover preview
797
+ * Shows a small indicator next to references with hover preview.
798
+ *
799
+ * All event handling is delegated — the widget sets data attributes
800
+ * and CodeMirrorRenderer handles events via container-level listeners.
798
801
  */
799
802
  declare class ReferenceResolutionWidget extends WidgetType {
800
803
  readonly annotation: Annotation$j;
801
804
  readonly targetDocumentName?: string | undefined;
802
- readonly eventBus?: EventBus | undefined;
803
805
  readonly isGenerating?: boolean | undefined;
804
- constructor(annotation: Annotation$j, targetDocumentName?: string | undefined, eventBus?: EventBus | undefined, isGenerating?: boolean | undefined);
806
+ constructor(annotation: Annotation$j, targetDocumentName?: string | undefined, isGenerating?: boolean | undefined);
805
807
  eq(other: ReferenceResolutionWidget): boolean;
806
808
  toDOM(): HTMLSpanElement;
807
- private showPreview;
808
- private hidePreview;
809
809
  ignoreEvent(event: Event): boolean;
810
810
  }
811
+ /**
812
+ * Show a tooltip preview on a widget container.
813
+ * Called from delegated mouseenter handler in CodeMirrorRenderer.
814
+ */
815
+ declare function showWidgetPreview(container: HTMLElement, documentName: string): void;
816
+ /**
817
+ * Hide the tooltip preview from a widget container.
818
+ * Called from delegated mouseleave handler in CodeMirrorRenderer.
819
+ */
820
+ declare function hideWidgetPreview(container: HTMLElement): void;
811
821
 
812
822
  type SelectionMotivation = 'linking' | 'highlighting' | 'assessing' | 'commenting' | 'tagging';
813
823
  type ClickAction = 'detail' | 'follow' | 'jsonld' | 'deleting';
@@ -1732,7 +1742,6 @@ interface Props$b {
1732
1742
  editable?: boolean;
1733
1743
  newAnnotationIds?: Set<string>;
1734
1744
  hoveredAnnotationId?: string | null;
1735
- hoveredCommentId?: string | null;
1736
1745
  scrollToAnnotationId?: string | null;
1737
1746
  sourceView?: boolean;
1738
1747
  showLineNumbers?: boolean;
@@ -1742,7 +1751,7 @@ interface Props$b {
1742
1751
  generatingReferenceId?: string | null;
1743
1752
  hoverDelayMs: number;
1744
1753
  }
1745
- declare function CodeMirrorRenderer({ content, segments, onChange, editable, newAnnotationIds, hoveredAnnotationId, hoveredCommentId, scrollToAnnotationId, sourceView, showLineNumbers, enableWidgets, eventBus, getTargetDocumentName, generatingReferenceId, hoverDelayMs }: Props$b): react_jsx_runtime.JSX.Element;
1754
+ declare function CodeMirrorRenderer({ content, segments, onChange, editable, newAnnotationIds, hoveredAnnotationId, scrollToAnnotationId, sourceView, showLineNumbers, enableWidgets, eventBus, getTargetDocumentName, generatingReferenceId, hoverDelayMs }: Props$b): react_jsx_runtime.JSX.Element;
1746
1755
 
1747
1756
  type Motivation$6 = components['schemas']['Motivation'];
1748
1757
  interface AnnotateReferencesProgressWidgetProps {
@@ -2050,7 +2059,6 @@ interface Props$6 {
2050
2059
  resourceUri: string;
2051
2060
  annotations: AnnotationsCollection;
2052
2061
  hoveredAnnotationId?: string | null;
2053
- hoveredCommentId?: string | null;
2054
2062
  selectedClick?: ClickAction;
2055
2063
  annotateMode: boolean;
2056
2064
  hoverDelayMs?: number;
@@ -3945,4 +3953,4 @@ interface ResolutionFlowState {
3945
3953
  */
3946
3954
  declare function useResolutionFlow(rUri: ResourceUri): ResolutionFlowState;
3947
3955
 
3948
- export { ANNOTATORS, AUTH_EVENTS, AVAILABLE_LOCALES, AdminDevOpsPage, type AdminDevOpsPageProps, AdminSecurityPage, type AdminSecurityPageProps, type AdminUser, type AdminUserStats, AdminUsersPage, type AdminUsersPageProps, AnnotateReferencesProgressWidget, AnnotateToolbar, AnnotateView, type Annotation$l as Annotation, type AnnotationConfig, type AnnotationCreationHandler, type AnnotationFlowState, type AnnotationHandlers, AnnotationHistory, type AnnotationManager, AnnotationOverlay, AnnotationProvider, type AnnotationProviderProps, type AnnotationUIState, type AnnotationsCollection, type Annotator, ApiClientProvider, type ApiClientProviderProps, AssessmentEntry, AssessmentPanel, AssistSection, AsyncErrorBoundary, type AttentionFlowState, AuthErrorDisplay, type AuthErrorDisplayProps, type AuthEventDetail, type AuthEventType, AuthTokenProvider, type AuthTokenProviderProps, type AvailableLocale, type BorderRadiusToken, BrowseView, Button, ButtonGroup, type ButtonGroupProps, type ButtonProps, type CacheManager, CacheProvider, type CacheProviderProps, type ClickAction, CodeMirrorRenderer, CollaborationPanel, CollapsibleResourceNavigation, type CollapsibleResourceNavigationProps, type ColorToken, CommentEntry, CommentsPanel, ComposeLoadingState, type ComposeLoadingStateProps, type ContextCorrelationFlowConfig, type ContextCorrelationFlowState, type CreateAnnotationParams, type CreateConfig, type DeleteAnnotationParams, type DetectionConfig, type DevOpsFeature, type DrawingMode, EntityTagsPage, type EntityTagsPageProps, EntityTypeBadges, ErrorBoundary, Footer, type GenerationFlowState, type GenerationOptions, HOVER_DELAY_MS, HighlightEntry, HighlightPanel, HistoryEvent, type HoverEmitterProps, type HoverHandlers, ImageURLSchema, ImageViewer, JsonLdPanel, JsonLdView, type KeyboardShortcut, KeyboardShortcutsHelpModal, LeftSidebar, type LinkComponentProps, LiveRegionProvider, type Motivation$8 as Motivation, type NavigationItem, NavigationMenu, type NavigationMenuHelper, type NavigationProps, type OAuthProvider, type OAuthUser, OAuthUserSchema, ObservableLink, type ObservableLinkProps, type OpenResource, OpenResourcesManager, OpenResourcesProvider, type OverlayAnnotation, PageLayout, PanelHeader, type PanelNavigationState, PopupContainer, PopupHeader, ProposeEntitiesModal, QUERY_KEYS, RecentDocumentsPage, type RecentDocumentsPageProps, ReferenceEntry, ReferenceResolutionWidget, ReferencesPanel, ResizeHandle, type ResolutionFlowState, type ResolvedTheme, ResourceAnnotationsProvider, ResourceCard, type ResourceCardProps, ResourceComposePage, type ResourceComposePageProps, ResourceDiscoveryPage, type ResourceDiscoveryPageProps, ResourceErrorState, type ResourceErrorStateProps, ResourceInfoPanel, ResourceLoadingState, ResourceSearchModal, type ResourceSearchModalProps, ResourceTagsInline, ResourceViewer, ResourceViewerPage, type ResourceViewerPageProps, type RouteBuilder, type SaveResourceParams, SearchModal, type SearchModalProps, SelectedTextDisplay, type SelectionMotivation, type SelectorType, SemiontBranding, SemiontFavicon, type SemiontResource$4 as SemiontResource, SessionExpiryBanner, SessionManager, SessionProvider, SessionTimer, SettingsPanel, type ShadowToken, type ShapeType, SignInForm, type SignInFormProps, SignUpForm, type SignUpFormProps, SimpleNavigation, type SimpleNavigationItem, type SimpleNavigationProps, SkipLinks, SortableResourceTab, type SortableResourceTabProps, type SpacingToken, StatisticsPanel, StatusDisplay, type StreamStatus, SvgDrawingCanvas, TagEntry, TagSchemasPage, type TagSchemasPageProps, TaggingPanel, type TextSegment, type TextSelection, type Theme, ThemeProvider, ToastContainer, type ToastMessage, ToastProvider, type ToastType, Toolbar, type ToolbarPanelType, type TransitionToken, TranslationManager, TranslationProvider, type TranslationProviderProps, type TypographyToken, type UICreateAnnotationParams, UnifiedAnnotationsPanel, UnifiedHeader, type UseResourceContentResult, UserMenuSkeleton, WelcomePage, type WelcomePageProps, applyHighlights, buildSourceToRenderedMap, buildTextNodeIndex, buttonStyles, clearHighlights, createHoverHandlers, cssVariables, dispatch401Error, dispatch403Error, dispatchAuthEvent, faviconPaths, formatTime, generateCSSVariables, getResourceIcon, getSelectedShapeForSelectorType, getSelectorType, getShortcutDisplay, getSupportedShapes, isShapeSupported, jsonLightHighlightStyle, jsonLightTheme, onAuthEvent, resolveAnnotationRanges, sanitizeImageURL, saveSelectedShapeForSelectorType, supportsDetection, toOverlayAnnotations, tokens, useAdmin, useAnnotationFlow, useAnnotationManager, useAnnotations, useApiClient, useAttentionFlow, useAuthApi, useAuthToken, useCacheManager, useContextCorrelationFlow, useDebounce, useDebouncedCallback, useDocumentAnnouncements, useDoubleKeyPress, useDropdown, useEntityTypes, useEventSubscription, useEventSubscriptions, useFormAnnouncements, useGenerationFlow, useHealth, useHoverDelay, useHoverEmitter, useIsTyping, useKeyboardShortcuts, useLanguageChangeAnnouncements, useLineNumbers, useLiveRegion, useLoadingState, useLocalStorage, useObservableExternalNavigation, useObservableRouter, useOpenResources, usePanelNavigation, usePanelWidth, usePreloadTranslations, useResolutionFlow, useResourceAnnotations, useResourceContent, useResourceEvents, useResourceLoadingAnnouncements, useResources, useRovingTabIndex, useSearchAnnouncements, useSessionContext, useSessionExpiry, useTheme, useToast, useTranslations };
3956
+ export { ANNOTATORS, AUTH_EVENTS, AVAILABLE_LOCALES, AdminDevOpsPage, type AdminDevOpsPageProps, AdminSecurityPage, type AdminSecurityPageProps, type AdminUser, type AdminUserStats, AdminUsersPage, type AdminUsersPageProps, AnnotateReferencesProgressWidget, AnnotateToolbar, AnnotateView, type Annotation$l as Annotation, type AnnotationConfig, type AnnotationCreationHandler, type AnnotationFlowState, type AnnotationHandlers, AnnotationHistory, type AnnotationManager, AnnotationOverlay, AnnotationProvider, type AnnotationProviderProps, type AnnotationUIState, type AnnotationsCollection, type Annotator, ApiClientProvider, type ApiClientProviderProps, AssessmentEntry, AssessmentPanel, AssistSection, AsyncErrorBoundary, type AttentionFlowState, AuthErrorDisplay, type AuthErrorDisplayProps, type AuthEventDetail, type AuthEventType, AuthTokenProvider, type AuthTokenProviderProps, type AvailableLocale, type BorderRadiusToken, BrowseView, Button, ButtonGroup, type ButtonGroupProps, type ButtonProps, type CacheManager, CacheProvider, type CacheProviderProps, type ClickAction, CodeMirrorRenderer, CollaborationPanel, CollapsibleResourceNavigation, type CollapsibleResourceNavigationProps, type ColorToken, CommentEntry, CommentsPanel, ComposeLoadingState, type ComposeLoadingStateProps, type ContextCorrelationFlowConfig, type ContextCorrelationFlowState, type CreateAnnotationParams, type CreateConfig, type DeleteAnnotationParams, type DetectionConfig, type DevOpsFeature, type DrawingMode, EntityTagsPage, type EntityTagsPageProps, EntityTypeBadges, ErrorBoundary, Footer, type GenerationFlowState, type GenerationOptions, HOVER_DELAY_MS, HighlightEntry, HighlightPanel, HistoryEvent, type HoverEmitterProps, type HoverHandlers, ImageURLSchema, ImageViewer, JsonLdPanel, JsonLdView, type KeyboardShortcut, KeyboardShortcutsHelpModal, LeftSidebar, type LinkComponentProps, LiveRegionProvider, type Motivation$8 as Motivation, type NavigationItem, NavigationMenu, type NavigationMenuHelper, type NavigationProps, type OAuthProvider, type OAuthUser, OAuthUserSchema, ObservableLink, type ObservableLinkProps, type OpenResource, OpenResourcesManager, OpenResourcesProvider, type OverlayAnnotation, PageLayout, PanelHeader, type PanelNavigationState, PopupContainer, PopupHeader, ProposeEntitiesModal, QUERY_KEYS, RecentDocumentsPage, type RecentDocumentsPageProps, ReferenceEntry, ReferenceResolutionWidget, ReferencesPanel, ResizeHandle, type ResolutionFlowState, type ResolvedTheme, ResourceAnnotationsProvider, ResourceCard, type ResourceCardProps, ResourceComposePage, type ResourceComposePageProps, ResourceDiscoveryPage, type ResourceDiscoveryPageProps, ResourceErrorState, type ResourceErrorStateProps, ResourceInfoPanel, ResourceLoadingState, ResourceSearchModal, type ResourceSearchModalProps, ResourceTagsInline, ResourceViewer, ResourceViewerPage, type ResourceViewerPageProps, type RouteBuilder, type SaveResourceParams, SearchModal, type SearchModalProps, SelectedTextDisplay, type SelectionMotivation, type SelectorType, SemiontBranding, SemiontFavicon, type SemiontResource$4 as SemiontResource, SessionExpiryBanner, SessionManager, SessionProvider, SessionTimer, SettingsPanel, type ShadowToken, type ShapeType, SignInForm, type SignInFormProps, SignUpForm, type SignUpFormProps, SimpleNavigation, type SimpleNavigationItem, type SimpleNavigationProps, SkipLinks, SortableResourceTab, type SortableResourceTabProps, type SpacingToken, StatisticsPanel, StatusDisplay, type StreamStatus, SvgDrawingCanvas, TagEntry, TagSchemasPage, type TagSchemasPageProps, TaggingPanel, type TextSegment, type TextSelection, type Theme, ThemeProvider, ToastContainer, type ToastMessage, ToastProvider, type ToastType, Toolbar, type ToolbarPanelType, type TransitionToken, TranslationManager, TranslationProvider, type TranslationProviderProps, type TypographyToken, type UICreateAnnotationParams, UnifiedAnnotationsPanel, UnifiedHeader, type UseResourceContentResult, UserMenuSkeleton, WelcomePage, type WelcomePageProps, applyHighlights, buildSourceToRenderedMap, buildTextNodeIndex, buttonStyles, clearHighlights, createHoverHandlers, cssVariables, dispatch401Error, dispatch403Error, dispatchAuthEvent, faviconPaths, formatTime, generateCSSVariables, getResourceIcon, getSelectedShapeForSelectorType, getSelectorType, getShortcutDisplay, getSupportedShapes, hideWidgetPreview, isShapeSupported, jsonLightHighlightStyle, jsonLightTheme, onAuthEvent, resolveAnnotationRanges, sanitizeImageURL, saveSelectedShapeForSelectorType, showWidgetPreview, supportsDetection, toOverlayAnnotations, tokens, useAdmin, useAnnotationFlow, useAnnotationManager, useAnnotations, useApiClient, useAttentionFlow, useAuthApi, useAuthToken, useCacheManager, useContextCorrelationFlow, useDebounce, useDebouncedCallback, useDocumentAnnouncements, useDoubleKeyPress, useDropdown, useEntityTypes, useEventSubscription, useEventSubscriptions, useFormAnnouncements, useGenerationFlow, useHealth, useHoverDelay, useHoverEmitter, useIsTyping, useKeyboardShortcuts, useLanguageChangeAnnouncements, useLineNumbers, useLiveRegion, useLoadingState, useLocalStorage, useObservableExternalNavigation, useObservableRouter, useOpenResources, usePanelNavigation, usePanelWidth, usePreloadTranslations, useResolutionFlow, useResourceAnnotations, useResourceContent, useResourceEvents, useResourceLoadingAnnouncements, useResources, useRovingTabIndex, useSearchAnnouncements, useSessionContext, useSessionExpiry, useTheme, useToast, useTranslations };
package/dist/index.mjs CHANGED
@@ -17131,11 +17131,10 @@ var jsonLightHighlightStyle = HighlightStyle.define([
17131
17131
  // src/lib/codemirror-widgets.ts
17132
17132
  import { isResolvedReference, getBodySource } from "@semiont/api-client";
17133
17133
  var ReferenceResolutionWidget = class extends WidgetType {
17134
- constructor(annotation, targetDocumentName, eventBus, isGenerating) {
17134
+ constructor(annotation, targetDocumentName, isGenerating) {
17135
17135
  super();
17136
17136
  this.annotation = annotation;
17137
17137
  this.targetDocumentName = targetDocumentName;
17138
- this.eventBus = eventBus;
17139
17138
  this.isGenerating = isGenerating;
17140
17139
  }
17141
17140
  eq(other) {
@@ -17152,10 +17151,17 @@ var ReferenceResolutionWidget = class extends WidgetType {
17152
17151
  margin-left: 4px;
17153
17152
  position: relative;
17154
17153
  `;
17154
+ const isResolved = isResolvedReference(this.annotation);
17155
+ const bodySource = getBodySource(this.annotation.body);
17156
+ container.dataset.widgetAnnotationId = this.annotation.id;
17157
+ container.dataset.widgetMotivation = this.annotation.motivation;
17158
+ container.dataset.widgetResolved = isResolved ? "true" : "false";
17159
+ if (bodySource) container.dataset.widgetBodySource = bodySource;
17160
+ if (this.targetDocumentName) container.dataset.widgetTargetName = this.targetDocumentName;
17161
+ if (this.isGenerating) container.dataset.widgetGenerating = "true";
17155
17162
  const indicator = document.createElement("button");
17156
17163
  indicator.className = "reference-indicator";
17157
17164
  indicator.type = "button";
17158
- const isResolved = isResolvedReference(this.annotation);
17159
17165
  if (isResolved) {
17160
17166
  indicator.innerHTML = '<span aria-hidden="true">\u{1F517}</span>';
17161
17167
  indicator.setAttribute("aria-label", this.targetDocumentName ? `Reference link to ${this.targetDocumentName}` : "Reference link to document");
@@ -17171,13 +17177,6 @@ var ReferenceResolutionWidget = class extends WidgetType {
17171
17177
  margin: 0;
17172
17178
  vertical-align: baseline;
17173
17179
  `;
17174
- indicator.style.cssText += `
17175
- &:focus {
17176
- outline: 2px solid #3b82f6;
17177
- outline-offset: 2px;
17178
- opacity: 1;
17179
- }
17180
- `;
17181
17180
  } else if (this.isGenerating) {
17182
17181
  indicator.innerHTML = `
17183
17182
  <span style="position: relative; display: inline-flex; align-items: center; justify-content: center;" aria-hidden="true">
@@ -17226,82 +17225,40 @@ var ReferenceResolutionWidget = class extends WidgetType {
17226
17225
  margin: 0;
17227
17226
  vertical-align: baseline;
17228
17227
  `;
17229
- indicator.style.cssText += `
17230
- &:focus {
17231
- outline: 2px solid #3b82f6;
17232
- outline-offset: 2px;
17233
- opacity: 1;
17234
- }
17235
- `;
17236
- }
17237
- if (!this.isGenerating) {
17238
- indicator.addEventListener("mouseenter", () => {
17239
- indicator.style.opacity = "1";
17240
- if (isResolved && this.targetDocumentName && this.targetDocumentName.trim() !== "") {
17241
- this.showPreview(container, this.targetDocumentName);
17242
- }
17243
- });
17244
- indicator.addEventListener("mouseleave", () => {
17245
- indicator.style.opacity = "0.6";
17246
- if (isResolved) {
17247
- this.hidePreview(container);
17248
- }
17249
- });
17250
- const bodySource = getBodySource(this.annotation.body);
17251
- if (isResolved && bodySource && this.eventBus) {
17252
- const eventBus = this.eventBus;
17253
- indicator.addEventListener("click", (e6) => {
17254
- e6.preventDefault();
17255
- e6.stopPropagation();
17256
- eventBus.get("navigation:reference-navigate").next({ documentId: bodySource });
17257
- });
17258
- } else if (!isResolved && this.eventBus) {
17259
- const eventBus = this.eventBus;
17260
- const annotation = this.annotation;
17261
- indicator.addEventListener("click", (e6) => {
17262
- e6.preventDefault();
17263
- e6.stopPropagation();
17264
- eventBus.get("attend:click").next({ annotationId: annotation.id, motivation: annotation.motivation });
17265
- });
17266
- }
17267
17228
  }
17268
17229
  container.appendChild(indicator);
17269
17230
  return container;
17270
17231
  }
17271
- showPreview(container, documentName) {
17272
- if (!documentName || documentName.trim() === "") {
17273
- return;
17274
- }
17275
- const tooltip = document.createElement("div");
17276
- tooltip.className = "reference-tooltip";
17277
- tooltip.textContent = `\u2192 ${documentName}`;
17278
- tooltip.style.cssText = `
17279
- position: absolute;
17280
- bottom: 100%;
17281
- left: 50%;
17282
- transform: translateX(-50%) translateY(-4px);
17283
- padding: 4px 8px;
17284
- background: rgba(0, 0, 0, 0.8);
17285
- color: white;
17286
- border-radius: 4px;
17287
- font-size: 11px;
17288
- white-space: nowrap;
17289
- pointer-events: none;
17290
- z-index: 1000;
17291
- animation: fadeIn 0.2s ease;
17292
- `;
17293
- container.appendChild(tooltip);
17294
- }
17295
- hidePreview(container) {
17296
- const tooltip = container.querySelector(".reference-tooltip");
17297
- if (tooltip) {
17298
- tooltip.remove();
17299
- }
17300
- }
17301
17232
  ignoreEvent(event) {
17302
17233
  return event.type === "click";
17303
17234
  }
17304
17235
  };
17236
+ function showWidgetPreview(container, documentName) {
17237
+ if (!documentName || documentName.trim() === "") return;
17238
+ const tooltip = document.createElement("div");
17239
+ tooltip.className = "reference-tooltip";
17240
+ tooltip.textContent = `\u2192 ${documentName}`;
17241
+ tooltip.style.cssText = `
17242
+ position: absolute;
17243
+ bottom: 100%;
17244
+ left: 50%;
17245
+ transform: translateX(-50%) translateY(-4px);
17246
+ padding: 4px 8px;
17247
+ background: rgba(0, 0, 0, 0.8);
17248
+ color: white;
17249
+ border-radius: 4px;
17250
+ font-size: 11px;
17251
+ white-space: nowrap;
17252
+ pointer-events: none;
17253
+ z-index: 1000;
17254
+ animation: fadeIn 0.2s ease;
17255
+ `;
17256
+ container.appendChild(tooltip);
17257
+ }
17258
+ function hideWidgetPreview(container) {
17259
+ const tooltip = container.querySelector(".reference-tooltip");
17260
+ if (tooltip) tooltip.remove();
17261
+ }
17305
17262
 
17306
17263
  // src/lib/media-shapes.ts
17307
17264
  import { isPdfMimeType } from "@semiont/api-client";
@@ -26199,8 +26156,14 @@ function convertSegmentPositions(segments, content4) {
26199
26156
  }
26200
26157
  }
26201
26158
  const convertPosition = (pos) => {
26202
- const crlfsBefore = crlfPositions.filter((crlfPos) => crlfPos < pos).length;
26203
- return pos - crlfsBefore;
26159
+ let lo = 0;
26160
+ let hi = crlfPositions.length;
26161
+ while (lo < hi) {
26162
+ const mid = lo + hi >>> 1;
26163
+ if (crlfPositions[mid] < pos) lo = mid + 1;
26164
+ else hi = mid;
26165
+ }
26166
+ return pos - lo;
26204
26167
  };
26205
26168
  return segments.map((seg) => ({
26206
26169
  ...seg,
@@ -26278,7 +26241,7 @@ function createAnnotationDecorationsField() {
26278
26241
  provide: (field) => EditorView.decorations.from(field)
26279
26242
  });
26280
26243
  }
26281
- function buildWidgetDecorations(_content, segments, generatingReferenceId, eventBus, getTargetDocumentName) {
26244
+ function buildWidgetDecorations(_content, segments, generatingReferenceId, getTargetDocumentName) {
26282
26245
  const builder = new RangeSetBuilder();
26283
26246
  const allAnnotatedSegments = segments.filter((s11) => s11.annotation).sort((a15, b8) => a15.end - b8.end);
26284
26247
  for (const segment of allAnnotatedSegments) {
@@ -26291,7 +26254,6 @@ function buildWidgetDecorations(_content, segments, generatingReferenceId, event
26291
26254
  const widget = new ReferenceResolutionWidget(
26292
26255
  annotation,
26293
26256
  targetName,
26294
- eventBus,
26295
26257
  isGenerating
26296
26258
  );
26297
26259
  builder.add(
@@ -26315,7 +26277,6 @@ var widgetDecorationsField = StateField.define({
26315
26277
  effect.value.content,
26316
26278
  effect.value.segments,
26317
26279
  effect.value.generatingReferenceId,
26318
- effect.value.eventBus,
26319
26280
  effect.value.getTargetDocumentName
26320
26281
  );
26321
26282
  }
@@ -26331,7 +26292,6 @@ function CodeMirrorRenderer({
26331
26292
  editable: editable2 = false,
26332
26293
  newAnnotationIds,
26333
26294
  hoveredAnnotationId,
26334
- hoveredCommentId,
26335
26295
  scrollToAnnotationId,
26336
26296
  sourceView = false,
26337
26297
  showLineNumbers = false,
@@ -26346,10 +26306,16 @@ function CodeMirrorRenderer({
26346
26306
  const contentRef = useRef7(content4);
26347
26307
  const convertedSegments = convertSegmentPositions(segments, content4);
26348
26308
  const segmentsRef = useRef7(convertedSegments);
26309
+ const segmentsByIdRef = useRef7(/* @__PURE__ */ new Map());
26349
26310
  const lineNumbersCompartment = useRef7(new Compartment());
26350
26311
  const eventBusRef = useRef7(eventBus);
26351
26312
  const getTargetDocumentNameRef = useRef7(getTargetDocumentName);
26352
26313
  segmentsRef.current = segments;
26314
+ const segmentsById = /* @__PURE__ */ new Map();
26315
+ for (const s11 of segments) {
26316
+ if (s11.annotation) segmentsById.set(s11.annotation.id, s11);
26317
+ }
26318
+ segmentsByIdRef.current = segmentsById;
26353
26319
  eventBusRef.current = eventBus;
26354
26320
  getTargetDocumentNameRef.current = getTargetDocumentName;
26355
26321
  useEffect10(() => {
@@ -26379,7 +26345,7 @@ function CodeMirrorRenderer({
26379
26345
  const annotationElement = target.closest("[data-annotation-id]");
26380
26346
  const annotationId = annotationElement?.getAttribute("data-annotation-id");
26381
26347
  if (annotationId && eventBusRef.current) {
26382
- const segment = segmentsRef.current.find((s11) => s11.annotation?.id === annotationId);
26348
+ const segment = segmentsByIdRef.current.get(annotationId);
26383
26349
  if (segment?.annotation) {
26384
26350
  event.preventDefault();
26385
26351
  eventBusRef.current.get("attend:click").next({
@@ -26457,11 +26423,54 @@ function CodeMirrorRenderer({
26457
26423
  const annotationElement = target.closest("[data-annotation-id]");
26458
26424
  if (annotationElement) handleMouseLeave();
26459
26425
  };
26426
+ const handleWidgetClick = (e6) => {
26427
+ const target = e6.target;
26428
+ const widget = target.closest(".reference-preview-widget");
26429
+ if (!widget || widget.dataset.widgetGenerating === "true") return;
26430
+ e6.preventDefault();
26431
+ e6.stopPropagation();
26432
+ const annotationId = widget.dataset.widgetAnnotationId;
26433
+ const bodySource = widget.dataset.widgetBodySource;
26434
+ const isResolved = widget.dataset.widgetResolved === "true";
26435
+ if (!annotationId || !eventBusRef.current) return;
26436
+ if (isResolved && bodySource) {
26437
+ eventBusRef.current.get("navigation:reference-navigate").next({ documentId: bodySource });
26438
+ } else {
26439
+ const motivation = widget.dataset.widgetMotivation || "linking";
26440
+ eventBusRef.current.get("attend:click").next({ annotationId, motivation });
26441
+ }
26442
+ };
26443
+ const handleWidgetMouseEnter = (e6) => {
26444
+ const target = e6.target;
26445
+ const widget = target.closest(".reference-preview-widget");
26446
+ if (!widget || widget.dataset.widgetGenerating === "true") return;
26447
+ const indicator = widget.querySelector(".reference-indicator");
26448
+ if (indicator) indicator.style.opacity = "1";
26449
+ if (widget.dataset.widgetResolved === "true" && widget.dataset.widgetTargetName) {
26450
+ showWidgetPreview(widget, widget.dataset.widgetTargetName);
26451
+ }
26452
+ };
26453
+ const handleWidgetMouseLeave = (e6) => {
26454
+ const target = e6.target;
26455
+ const widget = target.closest(".reference-preview-widget");
26456
+ if (!widget) return;
26457
+ const indicator = widget.querySelector(".reference-indicator");
26458
+ if (indicator) indicator.style.opacity = "0.6";
26459
+ if (widget.dataset.widgetResolved === "true") {
26460
+ hideWidgetPreview(widget);
26461
+ }
26462
+ };
26460
26463
  container.addEventListener("mouseover", handleMouseOver);
26461
26464
  container.addEventListener("mouseout", handleMouseOut);
26465
+ container.addEventListener("click", handleWidgetClick);
26466
+ container.addEventListener("mouseenter", handleWidgetMouseEnter, true);
26467
+ container.addEventListener("mouseleave", handleWidgetMouseLeave, true);
26462
26468
  return () => {
26463
26469
  container.removeEventListener("mouseover", handleMouseOver);
26464
26470
  container.removeEventListener("mouseout", handleMouseOut);
26471
+ container.removeEventListener("click", handleWidgetClick);
26472
+ container.removeEventListener("mouseenter", handleWidgetMouseEnter, true);
26473
+ container.removeEventListener("mouseleave", handleWidgetMouseLeave, true);
26465
26474
  cleanupHover();
26466
26475
  view.destroy();
26467
26476
  viewRef.current = null;
@@ -26502,7 +26511,6 @@ function CodeMirrorRenderer({
26502
26511
  content: content4,
26503
26512
  segments: convertedSegments,
26504
26513
  generatingReferenceId,
26505
- eventBus: eventBusRef.current,
26506
26514
  getTargetDocumentName: getTargetDocumentNameRef.current
26507
26515
  })
26508
26516
  });
@@ -26535,34 +26543,6 @@ function CodeMirrorRenderer({
26535
26543
  element2.classList.remove("annotation-pulse");
26536
26544
  };
26537
26545
  }, [hoveredAnnotationId]);
26538
- useEffect10(() => {
26539
- if (!viewRef.current || !hoveredCommentId) return void 0;
26540
- const view = viewRef.current;
26541
- const element2 = view.contentDOM.querySelector(
26542
- `[data-annotation-id="${CSS.escape(hoveredCommentId)}"]`
26543
- );
26544
- if (!element2) return void 0;
26545
- const scrollContainer = element2.closest(".semiont-annotate-view__content") || element2.closest(".semiont-document-viewer__scrollable-body");
26546
- if (scrollContainer) {
26547
- const elementRect = element2.getBoundingClientRect();
26548
- const containerRect = scrollContainer.getBoundingClientRect();
26549
- const isVisible = elementRect.top >= containerRect.top && elementRect.bottom <= containerRect.bottom;
26550
- if (!isVisible) {
26551
- const elementTop = element2.offsetTop;
26552
- const containerHeight = scrollContainer.clientHeight;
26553
- const elementHeight = element2.offsetHeight;
26554
- const scrollTo = elementTop - containerHeight / 2 + elementHeight / 2;
26555
- scrollContainer.scrollTo({ top: scrollTo, behavior: "smooth" });
26556
- }
26557
- }
26558
- const timeoutId = setTimeout(() => {
26559
- element2.classList.add("annotation-pulse");
26560
- }, 100);
26561
- return () => {
26562
- clearTimeout(timeoutId);
26563
- element2.classList.remove("annotation-pulse");
26564
- };
26565
- }, [hoveredCommentId]);
26566
26546
  useEffect10(() => {
26567
26547
  if (!viewRef.current || !scrollToAnnotationId) return;
26568
26548
  scrollAnnotationIntoView(scrollToAnnotationId, viewRef.current.contentDOM);
@@ -30122,13 +30102,14 @@ function ProposeEntitiesModal({
30122
30102
  // src/components/resource/AnnotateView.tsx
30123
30103
  import { useRef as useRef12, useEffect as useEffect18, useCallback as useCallback13, lazy, Suspense } from "react";
30124
30104
  import { resourceUri as toResourceUri } from "@semiont/core";
30125
- import { getTextPositionSelector as getTextPositionSelector2, getTextQuoteSelector, getTargetSelector as getTargetSelector2, getMimeCategory, isPdfMimeType as isPdfMimeType2, extractContext, findTextWithContext } from "@semiont/api-client";
30105
+ import { getTextPositionSelector as getTextPositionSelector2, getTextQuoteSelector, getTargetSelector as getTargetSelector2, getMimeCategory, isPdfMimeType as isPdfMimeType2, extractContext, findTextWithContext, buildContentCache } from "@semiont/api-client";
30126
30106
  import { jsx as jsx22, jsxs as jsxs13 } from "react/jsx-runtime";
30127
30107
  var PdfAnnotationCanvas = lazy(() => import("./PdfAnnotationCanvas.client-HNYRKFDS.mjs").then((mod) => ({ default: mod.PdfAnnotationCanvas })));
30128
30108
  function segmentTextWithAnnotations(content4, annotations) {
30129
30109
  if (!content4) {
30130
30110
  return [{ exact: "", start: 0, end: 0 }];
30131
30111
  }
30112
+ const cache2 = buildContentCache(content4);
30132
30113
  const normalizedAnnotations = annotations.map((ann) => {
30133
30114
  const targetSelector = getTargetSelector2(ann.target);
30134
30115
  const posSelector = getTextPositionSelector2(targetSelector);
@@ -30140,8 +30121,8 @@ function segmentTextWithAnnotations(content4, annotations) {
30140
30121
  quoteSelector.exact,
30141
30122
  quoteSelector.prefix,
30142
30123
  quoteSelector.suffix,
30143
- posSelector?.start
30144
- // Position hint for fuzzy matching
30124
+ posSelector?.start,
30125
+ cache2
30145
30126
  );
30146
30127
  }
30147
30128
  const start2 = position4?.start ?? posSelector?.start ?? 0;
@@ -30204,7 +30185,7 @@ function AnnotateView({
30204
30185
  const { highlights, references, assessments, comments, tags: tags3 } = annotations;
30205
30186
  const allAnnotations = [...highlights, ...references, ...assessments, ...comments, ...tags3];
30206
30187
  const segments = segmentTextWithAnnotations(content4, allAnnotations);
30207
- const { selectedMotivation, selectedClick, selectedShape, hoveredAnnotationId, hoveredCommentId, scrollToAnnotationId } = uiState;
30188
+ const { selectedMotivation, selectedClick, selectedShape, hoveredAnnotationId, scrollToAnnotationId } = uiState;
30208
30189
  const onUIStateChangeRef = useRef12(onUIStateChange);
30209
30190
  onUIStateChangeRef.current = onUIStateChange;
30210
30191
  const handleToolbarSelectionChanged = useCallback13(({ motivation }) => {
@@ -30337,7 +30318,6 @@ function AnnotateView({
30337
30318
  editable: false,
30338
30319
  newAnnotationIds,
30339
30320
  ...hoveredAnnotationId !== void 0 && { hoveredAnnotationId },
30340
- ...hoveredCommentId !== void 0 && { hoveredCommentId },
30341
30321
  ...scrollToAnnotationId !== void 0 && { scrollToAnnotationId },
30342
30322
  sourceView: true,
30343
30323
  showLineNumbers,
@@ -30372,7 +30352,7 @@ function AnnotateView({
30372
30352
  drawingMode: selectedMotivation ? selectedShape : null,
30373
30353
  selectedMotivation,
30374
30354
  eventBus,
30375
- hoveredAnnotationId: hoveredCommentId || hoveredAnnotationId || null,
30355
+ hoveredAnnotationId: hoveredAnnotationId || null,
30376
30356
  hoverDelayMs
30377
30357
  }
30378
30358
  ) }) })
@@ -30399,7 +30379,7 @@ function AnnotateView({
30399
30379
  drawingMode: selectedMotivation ? selectedShape : null,
30400
30380
  selectedMotivation,
30401
30381
  eventBus,
30402
- hoveredAnnotationId: hoveredCommentId || hoveredAnnotationId || null,
30382
+ hoveredAnnotationId: hoveredAnnotationId || null,
30403
30383
  hoverDelayMs
30404
30384
  }
30405
30385
  ) })
@@ -45695,7 +45675,6 @@ function ResourceViewer({
45695
45675
  const [jsonLdAnnotation, setJsonLdAnnotation] = useState17(null);
45696
45676
  const [deleteConfirmation, setDeleteConfirmation] = useState17(null);
45697
45677
  const hoveredAnnotationId = hoveredAnnotationIdProp ?? null;
45698
- const [hoveredCommentId, _setHoveredCommentId] = useState17(null);
45699
45678
  const [scrollToAnnotationId, setScrollToAnnotationId] = useState17(null);
45700
45679
  const [_focusedAnnotationId, setFocusedAnnotationId] = useState17(null);
45701
45680
  const focusAnnotation = useCallback16((annotationId) => {
@@ -45826,7 +45805,6 @@ function ResourceViewer({
45826
45805
  mimeType,
45827
45806
  resourceUri: resource["@id"],
45828
45807
  annotations: annotationsCollection,
45829
- hoveredCommentId,
45830
45808
  selectedClick,
45831
45809
  hoverDelayMs,
45832
45810
  annotateMode
@@ -57520,6 +57498,7 @@ export {
57520
57498
  getSchemaCategory as getTagCategory,
57521
57499
  getTagSchema,
57522
57500
  getTagSchemasByDomain,
57501
+ hideWidgetPreview,
57523
57502
  isShapeSupported,
57524
57503
  isValidCategory,
57525
57504
  jsonLightHighlightStyle,
@@ -57529,6 +57508,7 @@ export {
57529
57508
  resolveAnnotationRanges,
57530
57509
  sanitizeImageURL,
57531
57510
  saveSelectedShapeForSelectorType,
57511
+ showWidgetPreview,
57532
57512
  supportsDetection,
57533
57513
  toOverlayAnnotations,
57534
57514
  tokens,