@semiont/react-ui 0.2.35-build.101 → 0.2.35-build.102

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.
Files changed (71) hide show
  1. package/dist/{EventBusContext-DMI4uwYk.d.mts → EventBusContext-BsIUjdWP.d.mts} +4 -4
  2. package/dist/{PdfAnnotationCanvas.client-HNYRKFDS.mjs → PdfAnnotationCanvas.client-COQREPXU.mjs} +7 -7
  3. package/dist/PdfAnnotationCanvas.client-COQREPXU.mjs.map +1 -0
  4. package/dist/{chunk-YI5IX5ZA.mjs → chunk-2HGWOLVN.mjs} +1 -1
  5. package/dist/{chunk-YI5IX5ZA.mjs.map → chunk-2HGWOLVN.mjs.map} +1 -1
  6. package/dist/{chunk-MWQ5CNKW.mjs → chunk-ZPV43WN2.mjs} +11 -11
  7. package/dist/chunk-ZPV43WN2.mjs.map +1 -0
  8. package/dist/index.d.mts +164 -164
  9. package/dist/index.mjs +194 -194
  10. package/dist/index.mjs.map +1 -1
  11. package/dist/test-utils.d.mts +2 -2
  12. package/dist/test-utils.mjs +1 -1
  13. package/package.json +1 -1
  14. package/src/components/AnnotateReferencesProgressWidget.tsx +5 -5
  15. package/src/components/CodeMirrorRenderer.tsx +5 -5
  16. package/src/components/Toolbar.tsx +2 -2
  17. package/src/components/annotation/AnnotateToolbar.tsx +9 -9
  18. package/src/components/annotation/__tests__/AnnotateToolbar.test.tsx +17 -17
  19. package/src/components/image-annotation/AnnotationOverlay.tsx +10 -10
  20. package/src/components/image-annotation/SvgDrawingCanvas.tsx +4 -4
  21. package/src/components/navigation/CollapsibleResourceNavigation.tsx +7 -7
  22. package/src/components/navigation/ObservableLink.tsx +3 -3
  23. package/src/components/navigation/SimpleNavigation.tsx +2 -2
  24. package/src/components/pdf-annotation/PdfAnnotationCanvas.tsx +8 -8
  25. package/src/components/resource/AnnotateView.tsx +12 -12
  26. package/src/components/resource/BrowseView.tsx +9 -9
  27. package/src/components/resource/ResourceViewer.tsx +23 -23
  28. package/src/components/resource/__tests__/BrowseView.test.tsx +27 -27
  29. package/src/components/resource/__tests__/ResourceViewer.mode-switch.test.tsx +1 -1
  30. package/src/components/resource/panels/AssessmentEntry.tsx +2 -2
  31. package/src/components/resource/panels/AssessmentPanel.tsx +7 -7
  32. package/src/components/resource/panels/AssistSection.tsx +5 -5
  33. package/src/components/resource/panels/CommentEntry.tsx +2 -2
  34. package/src/components/resource/panels/CommentsPanel.tsx +7 -7
  35. package/src/components/resource/panels/HighlightEntry.tsx +2 -2
  36. package/src/components/resource/panels/HighlightPanel.tsx +5 -5
  37. package/src/components/resource/panels/ReferenceEntry.tsx +8 -8
  38. package/src/components/resource/panels/ReferencesPanel.tsx +10 -10
  39. package/src/components/resource/panels/ResourceInfoPanel.tsx +6 -6
  40. package/src/components/resource/panels/TagEntry.tsx +2 -2
  41. package/src/components/resource/panels/TaggingPanel.tsx +8 -8
  42. package/src/components/resource/panels/UnifiedAnnotationsPanel.tsx +2 -2
  43. package/src/components/resource/panels/__tests__/AssessmentPanel.test.tsx +4 -4
  44. package/src/components/resource/panels/__tests__/AssistSection.test.tsx +4 -4
  45. package/src/components/resource/panels/__tests__/CommentEntry.test.tsx +8 -8
  46. package/src/components/resource/panels/__tests__/CommentsPanel.test.tsx +3 -3
  47. package/src/components/resource/panels/__tests__/HighlightPanel.annotationProgress.test.tsx +1 -1
  48. package/src/components/resource/panels/__tests__/ReferencesPanel.test.tsx +3 -3
  49. package/src/components/resource/panels/__tests__/ResourceInfoPanel.test.tsx +9 -9
  50. package/src/components/resource/panels/__tests__/TaggingPanel.test.tsx +5 -5
  51. package/src/features/admin-devops/components/AdminDevOpsPage.tsx +1 -1
  52. package/src/features/admin-security/components/AdminSecurityPage.tsx +1 -1
  53. package/src/features/admin-users/components/AdminUsersPage.tsx +1 -1
  54. package/src/features/moderate-entity-tags/components/EntityTagsPage.tsx +1 -1
  55. package/src/features/moderate-recent/components/RecentDocumentsPage.tsx +1 -1
  56. package/src/features/moderate-tag-schemas/components/TagSchemasPage.tsx +1 -1
  57. package/src/features/resource-compose/components/ResourceComposePage.tsx +1 -1
  58. package/src/features/resource-discovery/components/ResourceDiscoveryPage.tsx +1 -1
  59. package/src/features/resource-viewer/__tests__/AnnotationCreationPending.test.tsx +26 -26
  60. package/src/features/resource-viewer/__tests__/AnnotationDeletionIntegration.test.tsx +21 -21
  61. package/src/features/resource-viewer/__tests__/AnnotationProgressDismissal.test.tsx +23 -23
  62. package/src/features/resource-viewer/__tests__/{ResolutionFlowIntegration.test.tsx → BindFlowIntegration.test.tsx} +49 -49
  63. package/src/features/resource-viewer/__tests__/DetectionFlowBug.test.tsx +18 -18
  64. package/src/features/resource-viewer/__tests__/DetectionFlowIntegration.test.tsx +19 -19
  65. package/src/features/resource-viewer/__tests__/ResourceMutations.test.tsx +19 -19
  66. package/src/features/resource-viewer/__tests__/ToastNotifications.test.tsx +13 -13
  67. package/src/features/resource-viewer/__tests__/{GenerationFlowIntegration.test.tsx → YieldFlowIntegration.test.tsx} +34 -34
  68. package/src/features/resource-viewer/__tests__/annotation-progress-flow.test.tsx +11 -11
  69. package/src/features/resource-viewer/components/ResourceViewerPage.tsx +55 -55
  70. package/dist/PdfAnnotationCanvas.client-HNYRKFDS.mjs.map +0 -1
  71. package/dist/chunk-MWQ5CNKW.mjs.map +0 -1
@@ -2,8 +2,8 @@ import { ReactElement } from 'react';
2
2
  import { RenderOptions, RenderResult } from '@testing-library/react';
3
3
  export * from '@testing-library/react';
4
4
  import { QueryClient } from '@tanstack/react-query';
5
- import { T as TranslationManager, S as SessionManager, O as OpenResourcesManager } from './EventBusContext-DMI4uwYk.mjs';
6
- export { r as resetEventBusForTesting } from './EventBusContext-DMI4uwYk.mjs';
5
+ import { T as TranslationManager, S as SessionManager, O as OpenResourcesManager } from './EventBusContext-BsIUjdWP.mjs';
6
+ export { r as resetEventBusForTesting } from './EventBusContext-BsIUjdWP.mjs';
7
7
  import { EventBus } from '@semiont/core';
8
8
  export { vi } from 'vitest';
9
9
  import 'react/jsx-runtime';
@@ -10,7 +10,7 @@ import {
10
10
  EventBusProvider,
11
11
  resetEventBusForTesting,
12
12
  useEventBus
13
- } from "./chunk-YI5IX5ZA.mjs";
13
+ } from "./chunk-2HGWOLVN.mjs";
14
14
  import "./chunk-JH7BXE2P.mjs";
15
15
  import {
16
16
  __commonJS,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@semiont/react-ui",
3
- "version": "0.2.35-build.101",
3
+ "version": "0.2.35-build.102",
4
4
  "description": "React components and hooks for Semiont",
5
5
  "main": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.mts",
@@ -2,18 +2,18 @@
2
2
 
3
3
  import { useTranslations } from '../contexts/TranslationContext';
4
4
  import { useEventBus } from '../contexts/EventBusContext';
5
- import type { AnnotationProgress } from '@semiont/core';
5
+ import type { MarkProgress } from '@semiont/core';
6
6
  import type { components } from '@semiont/core';
7
7
 
8
8
  type Motivation = components['schemas']['Motivation'];
9
9
 
10
- // Extended AnnotationProgress with optional request parameters
11
- interface EnrichedAnnotationProgress extends AnnotationProgress {
10
+ // Extended MarkProgress with optional request parameters
11
+ interface EnrichedMarkProgress extends MarkProgress {
12
12
  requestParams?: Array<{ label: string; value: string }>;
13
13
  }
14
14
 
15
15
  interface AnnotateReferencesProgressWidgetProps {
16
- progress: AnnotationProgress | null;
16
+ progress: MarkProgress | null;
17
17
  annotationType?: Motivation | 'reference';
18
18
  }
19
19
 
@@ -58,7 +58,7 @@ export function AnnotateReferencesProgressWidget({ progress, annotationType = 'r
58
58
 
59
59
  {/* Request Parameters */}
60
60
  {(() => {
61
- const enrichedProgress = progress as EnrichedAnnotationProgress;
61
+ const enrichedProgress = progress as EnrichedMarkProgress;
62
62
  return enrichedProgress.requestParams && enrichedProgress.requestParams.length > 0 && (
63
63
  <div className="semiont-annotation-progress__params">
64
64
  <div className="semiont-annotation-progress__params-title">Request Parameters:</div>
@@ -10,7 +10,7 @@ import { scrollAnnotationIntoView } from '../lib/scroll-utils';
10
10
  import { isHighlight, isReference, isResolvedReference, isComment, isAssessment, isTag, getBodySource } from '@semiont/api-client';
11
11
  import type { components } from '@semiont/core';
12
12
  import type { EventBus } from "@semiont/core";
13
- import { createHoverHandlers } from '../hooks/useAttentionFlow';
13
+ import { createHoverHandlers } from '../hooks/useBeckonFlow';
14
14
 
15
15
  type Annotation = components['schemas']['Annotation'];
16
16
 
@@ -348,7 +348,7 @@ export function CodeMirrorRenderer({
348
348
  const segment = segmentsByIdRef.current.get(annotationId);
349
349
  if (segment?.annotation) {
350
350
  event.preventDefault();
351
- eventBusRef.current.get('attend:click').next({
351
+ eventBusRef.current.get('browse:click').next({
352
352
  annotationId,
353
353
  motivation: segment.annotation.motivation
354
354
  });
@@ -416,7 +416,7 @@ export function CodeMirrorRenderer({
416
416
  const container = view.dom;
417
417
 
418
418
  const { handleMouseEnter, handleMouseLeave, cleanup: cleanupHover } = createHoverHandlers(
419
- (annotationId) => eventBusRef.current?.get('attend:hover').next({ annotationId }),
419
+ (annotationId) => eventBusRef.current?.get('beckon:hover').next({ annotationId }),
420
420
  hoverDelayMs
421
421
  );
422
422
 
@@ -449,10 +449,10 @@ export function CodeMirrorRenderer({
449
449
  if (!annotationId || !eventBusRef.current) return;
450
450
 
451
451
  if (isResolved && bodySource) {
452
- eventBusRef.current.get('navigation:reference-navigate').next({ documentId: bodySource });
452
+ eventBusRef.current.get('browse:reference-navigate').next({ documentId: bodySource });
453
453
  } else {
454
454
  const motivation = (widget.dataset.widgetMotivation || 'linking') as Annotation['motivation'];
455
- eventBusRef.current.get('attend:click').next({ annotationId, motivation });
455
+ eventBusRef.current.get('browse:click').next({ annotationId, motivation });
456
456
  }
457
457
  };
458
458
 
@@ -17,7 +17,7 @@ interface Props<T extends string = string> {
17
17
  /**
18
18
  * Toolbar component for panel navigation
19
19
  *
20
- * @emits attend:panel-toggle - Toggle panel visibility. Payload: { panel: string }
20
+ * @emits browse:panel-toggle - Toggle panel visibility. Payload: { panel: string }
21
21
  */
22
22
  export function Toolbar<T extends string = string>({
23
23
  context,
@@ -28,7 +28,7 @@ export function Toolbar<T extends string = string>({
28
28
  const eventBus = useEventBus();
29
29
 
30
30
  const handlePanelToggle = (panel: string) => {
31
- eventBus.get('attend:panel-toggle').next({ panel });
31
+ eventBus.get('browse:panel-toggle').next({ panel });
32
32
  };
33
33
 
34
34
  return (
@@ -102,10 +102,10 @@ function DropdownGroup({
102
102
  /**
103
103
  * Toolbar for annotation controls with mode, selection, click, and shape options
104
104
  *
105
- * @emits annotate:selection-changed - Selection motivation changed. Payload: { motivation: SelectionMotivation | null }
106
- * @emits annotate:click-changed - Click action mode changed. Payload: { action: ClickAction }
107
- * @emits annotate:shape-changed - Drawing shape changed. Payload: { shape: ShapeType }
108
- * @emits annotate:mode-toggled - View mode toggled between browse and annotate. Payload: undefined
105
+ * @emits mark:selection-changed - Selection motivation changed. Payload: { motivation: SelectionMotivation | null }
106
+ * @emits mark:click-changed - Click action mode changed. Payload: { action: ClickAction }
107
+ * @emits mark:shape-changed - Drawing shape changed. Payload: { shape: ShapeType }
108
+ * @emits mark:mode-toggled - View mode toggled between browse and annotate. Payload: undefined
109
109
  */
110
110
  export function AnnotateToolbar({
111
111
  selectedMotivation,
@@ -188,9 +188,9 @@ export function AnnotateToolbar({
188
188
  const handleSelectionClick = (motivation: SelectionMotivation | null) => {
189
189
  // If null is clicked, always deselect. Otherwise toggle.
190
190
  if (motivation === null) {
191
- eventBus.get('annotate:selection-changed').next({ motivation: null });
191
+ eventBus.get('mark:selection-changed').next({ motivation: null });
192
192
  } else {
193
- eventBus.get('annotate:selection-changed').next({
193
+ eventBus.get('mark:selection-changed').next({
194
194
  motivation: selectedMotivation === motivation ? null : motivation
195
195
  });
196
196
  }
@@ -200,21 +200,21 @@ export function AnnotateToolbar({
200
200
  };
201
201
 
202
202
  const handleClickClick = (action: ClickAction) => {
203
- eventBus.get('annotate:click-changed').next({ action });
203
+ eventBus.get('mark:click-changed').next({ action });
204
204
  // Close dropdown after selection
205
205
  setClickPinned(false);
206
206
  setClickHovered(false);
207
207
  };
208
208
 
209
209
  const handleShapeClick = (shape: ShapeType) => {
210
- eventBus.get('annotate:shape-changed').next({ shape });
210
+ eventBus.get('mark:shape-changed').next({ shape });
211
211
  // Close dropdown after selection
212
212
  setShapePinned(false);
213
213
  setShapeHovered(false);
214
214
  };
215
215
 
216
216
  const handleModeToggle = () => {
217
- eventBus.get('annotate:mode-toggled').next(undefined);
217
+ eventBus.get('mark:mode-toggled').next(undefined);
218
218
  setModePinned(false);
219
219
  setModeHovered(false);
220
220
  };
@@ -51,10 +51,10 @@ function createEventTracker() {
51
51
  };
52
52
 
53
53
  const toolbarEvents = [
54
- 'annotate:mode-toggled',
55
- 'annotate:click-changed',
56
- 'annotate:selection-changed',
57
- 'annotate:shape-changed',
54
+ 'mark:mode-toggled',
55
+ 'mark:click-changed',
56
+ 'mark:selection-changed',
57
+ 'mark:shape-changed',
58
58
  ] as const;
59
59
 
60
60
  toolbarEvents.forEach(eventName => {
@@ -215,7 +215,7 @@ describe('AnnotateToolbar', () => {
215
215
  });
216
216
  });
217
217
 
218
- it('emits annotate:mode-toggled event when Browse is clicked in Annotate mode', async () => {
218
+ it('emits mark:mode-toggled event when Browse is clicked in Annotate mode', async () => {
219
219
  const tracker = createEventTracker();
220
220
  renderWithIntl(
221
221
  <AnnotateToolbar
@@ -234,11 +234,11 @@ describe('AnnotateToolbar', () => {
234
234
  });
235
235
 
236
236
  await waitFor(() => {
237
- expect(tracker.events.some(e => e.event === 'annotate:mode-toggled')).toBe(true);
237
+ expect(tracker.events.some(e => e.event === 'mark:mode-toggled')).toBe(true);
238
238
  });
239
239
  });
240
240
 
241
- it('emits annotate:mode-toggled event when Annotate is clicked in Browse mode', async () => {
241
+ it('emits mark:mode-toggled event when Annotate is clicked in Browse mode', async () => {
242
242
  const tracker = createEventTracker();
243
243
  renderWithIntl(
244
244
  <AnnotateToolbar
@@ -257,7 +257,7 @@ describe('AnnotateToolbar', () => {
257
257
  });
258
258
 
259
259
  await waitFor(() => {
260
- expect(tracker.events.some(e => e.event === 'annotate:mode-toggled')).toBe(true);
260
+ expect(tracker.events.some(e => e.event === 'mark:mode-toggled')).toBe(true);
261
261
  });
262
262
  });
263
263
 
@@ -283,7 +283,7 @@ describe('AnnotateToolbar', () => {
283
283
 
284
284
  // Verify the event was emitted
285
285
  await waitFor(() => {
286
- expect(tracker.events.some(e => e.event === 'annotate:mode-toggled')).toBe(true);
286
+ expect(tracker.events.some(e => e.event === 'mark:mode-toggled')).toBe(true);
287
287
  });
288
288
 
289
289
  // Simulate mode change by rerendering with new mode
@@ -311,7 +311,7 @@ describe('AnnotateToolbar', () => {
311
311
  });
312
312
 
313
313
  describe('CLICK Group Interactions', () => {
314
- it('emits annotate:click-changed event when clicking an action', async () => {
314
+ it('emits mark:click-changed event when clicking an action', async () => {
315
315
  const tracker = createEventTracker();
316
316
  renderWithIntl(
317
317
  <AnnotateToolbar {...defaultProps} />,
@@ -329,7 +329,7 @@ describe('AnnotateToolbar', () => {
329
329
  fireEvent.click(screen.getByText('Follow'));
330
330
  await waitFor(() => {
331
331
  expect(tracker.events.some(e =>
332
- e.event === 'annotate:click-changed' && e.payload?.action === 'follow'
332
+ e.event === 'mark:click-changed' && e.payload?.action === 'follow'
333
333
  )).toBe(true);
334
334
  });
335
335
  });
@@ -343,7 +343,7 @@ describe('AnnotateToolbar', () => {
343
343
  });
344
344
 
345
345
  describe('MOTIVATION Group Interactions', () => {
346
- it('emits annotate:selection-changed event when clicking a motivation', async () => {
346
+ it('emits mark:selection-changed event when clicking a motivation', async () => {
347
347
  const tracker = createEventTracker();
348
348
  renderWithIntl(
349
349
  <AnnotateToolbar {...defaultProps} />,
@@ -361,7 +361,7 @@ describe('AnnotateToolbar', () => {
361
361
  fireEvent.click(screen.getByText('Reference'));
362
362
  await waitFor(() => {
363
363
  expect(tracker.events.some(e =>
364
- e.event === 'annotate:selection-changed' && e.payload?.motivation === 'linking'
364
+ e.event === 'mark:selection-changed' && e.payload?.motivation === 'linking'
365
365
  )).toBe(true);
366
366
  });
367
367
  });
@@ -389,7 +389,7 @@ describe('AnnotateToolbar', () => {
389
389
  fireEvent.click(within(dropdown).getByText('Highlight'));
390
390
  await waitFor(() => {
391
391
  expect(tracker.events.some(e =>
392
- e.event === 'annotate:selection-changed' && e.payload?.motivation === 'highlighting'
392
+ e.event === 'mark:selection-changed' && e.payload?.motivation === 'highlighting'
393
393
  )).toBe(true);
394
394
  });
395
395
 
@@ -418,14 +418,14 @@ describe('AnnotateToolbar', () => {
418
418
  fireEvent.click(within(dropdown2).getByText('Highlight'));
419
419
  await waitFor(() => {
420
420
  expect(tracker.events.some(e =>
421
- e.event === 'annotate:selection-changed' && e.payload?.motivation === null
421
+ e.event === 'mark:selection-changed' && e.payload?.motivation === null
422
422
  )).toBe(true);
423
423
  });
424
424
  });
425
425
  });
426
426
 
427
427
  describe('SHAPE Group Interactions', () => {
428
- it('emits annotate:shape-changed event when clicking a shape', async () => {
428
+ it('emits mark:shape-changed event when clicking a shape', async () => {
429
429
  const tracker = createEventTracker();
430
430
  renderWithIntl(
431
431
  <AnnotateToolbar
@@ -447,7 +447,7 @@ describe('AnnotateToolbar', () => {
447
447
  fireEvent.click(screen.getByText('Circle'));
448
448
  await waitFor(() => {
449
449
  expect(tracker.events.some(e =>
450
- e.event === 'annotate:shape-changed' && e.payload?.shape === 'circle'
450
+ e.event === 'mark:shape-changed' && e.payload?.shape === 'circle'
451
451
  )).toBe(true);
452
452
  });
453
453
  });
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { useMemo } from 'react';
4
4
  import type { components } from '@semiont/core';
5
- import { createHoverHandlers } from '../../hooks/useAttentionFlow';
5
+ import { createHoverHandlers } from '../../hooks/useBeckonFlow';
6
6
  import { getSvgSelector, isHighlight, isReference, isAssessment, isComment, isTag, isBodyResolved, isResolvedReference } from '@semiont/api-client';
7
7
  import { parseSvgSelector } from '@semiont/api-client';
8
8
  import type { EventBus } from "@semiont/core"
@@ -63,8 +63,8 @@ function getAnnotationTooltip(annotation: Annotation): string {
63
63
  /**
64
64
  * Render annotation overlay - displays existing annotations as SVG shapes
65
65
  *
66
- * @emits attend:hover - Annotation hovered or unhovered. Payload: { annotationId: string | null }
67
- * @emits attend:click - Annotation clicked. Payload: { annotationId: string, motivation: Motivation }
66
+ * @emits beckon:hover - Annotation hovered or unhovered. Payload: { annotationId: string | null }
67
+ * @emits browse:click - Annotation clicked. Payload: { annotationId: string, motivation: Motivation }
68
68
  */
69
69
  export function AnnotationOverlay({
70
70
  annotations,
@@ -81,7 +81,7 @@ export function AnnotationOverlay({
81
81
  const scaleY = displayHeight / imageHeight;
82
82
 
83
83
  const { handleMouseEnter, handleMouseLeave } = useMemo(
84
- () => createHoverHandlers((annotationId) => eventBus?.get('attend:hover').next({ annotationId }), hoverDelayMs),
84
+ () => createHoverHandlers((annotationId) => eventBus?.get('beckon:hover').next({ annotationId }), hoverDelayMs),
85
85
  [eventBus, hoverDelayMs]
86
86
  );
87
87
 
@@ -131,7 +131,7 @@ export function AnnotationOverlay({
131
131
  className="semiont-annotation-overlay__shape"
132
132
  data-hovered={isHovered ? 'true' : 'false'}
133
133
  data-selected={isSelected ? 'true' : 'false'}
134
- onClick={() => eventBus?.get('attend:click').next({ annotationId: annotation.id, motivation: annotation.motivation })}
134
+ onClick={() => eventBus?.get('browse:click').next({ annotationId: annotation.id, motivation: annotation.motivation })}
135
135
  onMouseEnter={() => handleMouseEnter(annotation.id)}
136
136
  onMouseLeave={handleMouseLeave}
137
137
  />
@@ -144,7 +144,7 @@ export function AnnotationOverlay({
144
144
  style={{ userSelect: 'none' }}
145
145
  onClick={(e) => {
146
146
  e.stopPropagation();
147
- eventBus?.get('attend:click').next({ annotationId: annotation.id, motivation: annotation.motivation });
147
+ eventBus?.get('browse:click').next({ annotationId: annotation.id, motivation: annotation.motivation });
148
148
  }}
149
149
  onMouseEnter={() => handleMouseEnter(annotation.id)}
150
150
  onMouseLeave={handleMouseLeave}
@@ -178,7 +178,7 @@ export function AnnotationOverlay({
178
178
  className="semiont-annotation-overlay__shape"
179
179
  data-hovered={isHovered ? 'true' : 'false'}
180
180
  data-selected={isSelected ? 'true' : 'false'}
181
- onClick={() => eventBus?.get('attend:click').next({ annotationId: annotation.id, motivation: annotation.motivation })}
181
+ onClick={() => eventBus?.get('browse:click').next({ annotationId: annotation.id, motivation: annotation.motivation })}
182
182
  onMouseEnter={() => handleMouseEnter(annotation.id)}
183
183
  onMouseLeave={handleMouseLeave}
184
184
  />
@@ -191,7 +191,7 @@ export function AnnotationOverlay({
191
191
  style={{ userSelect: 'none' }}
192
192
  onClick={(e) => {
193
193
  e.stopPropagation();
194
- eventBus?.get('attend:click').next({ annotationId: annotation.id, motivation: annotation.motivation });
194
+ eventBus?.get('browse:click').next({ annotationId: annotation.id, motivation: annotation.motivation });
195
195
  }}
196
196
  onMouseEnter={() => handleMouseEnter(annotation.id)}
197
197
  onMouseLeave={handleMouseLeave}
@@ -238,7 +238,7 @@ export function AnnotationOverlay({
238
238
  className="semiont-annotation-overlay__shape"
239
239
  data-hovered={isHovered ? 'true' : 'false'}
240
240
  data-selected={isSelected ? 'true' : 'false'}
241
- onClick={() => eventBus?.get('attend:click').next({ annotationId: annotation.id, motivation: annotation.motivation })}
241
+ onClick={() => eventBus?.get('browse:click').next({ annotationId: annotation.id, motivation: annotation.motivation })}
242
242
  onMouseEnter={() => handleMouseEnter(annotation.id)}
243
243
  onMouseLeave={handleMouseLeave}
244
244
  />
@@ -251,7 +251,7 @@ export function AnnotationOverlay({
251
251
  style={{ userSelect: 'none' }}
252
252
  onClick={(e) => {
253
253
  e.stopPropagation();
254
- eventBus?.get('attend:click').next({ annotationId: annotation.id, motivation: annotation.motivation });
254
+ eventBus?.get('browse:click').next({ annotationId: annotation.id, motivation: annotation.motivation });
255
255
  }}
256
256
  onMouseEnter={() => handleMouseEnter(annotation.id)}
257
257
  onMouseLeave={handleMouseLeave}
@@ -49,8 +49,8 @@ interface SvgDrawingCanvasProps {
49
49
  /**
50
50
  * SVG-based drawing canvas for creating image annotations with shapes
51
51
  *
52
- * @emits attend:click - Annotation clicked on canvas. Payload: { annotationId: string, motivation: Motivation }
53
- * @emits annotate:requested - New annotation drawn on canvas. Payload: { selector: SvgSelector, motivation: SelectionMotivation }
52
+ * @emits browse:click - Annotation clicked on canvas. Payload: { annotationId: string, motivation: Motivation }
53
+ * @emits mark:requested - New annotation drawn on canvas. Payload: { selector: SvgSelector, motivation: SelectionMotivation }
54
54
  */
55
55
  export function SvgDrawingCanvas({
56
56
  resourceUri,
@@ -216,7 +216,7 @@ export function SvgDrawingCanvas({
216
216
  });
217
217
 
218
218
  if (clickedAnnotation) {
219
- eventBus?.get('attend:click').next({ annotationId: clickedAnnotation.id, motivation: clickedAnnotation.motivation });
219
+ eventBus?.get('browse:click').next({ annotationId: clickedAnnotation.id, motivation: clickedAnnotation.motivation });
220
220
  setIsDrawing(false);
221
221
  setStartPoint(null);
222
222
  setCurrentPoint(null);
@@ -279,7 +279,7 @@ export function SvgDrawingCanvas({
279
279
 
280
280
  // Emit annotation:requested event with SvgSelector
281
281
  if (eventBus && selectedMotivation) {
282
- eventBus.get('annotate:requested').next({
282
+ eventBus.get('mark:requested').next({
283
283
  selector: {
284
284
  type: 'SvgSelector',
285
285
  value: nativeSvg
@@ -28,9 +28,9 @@ import './CollapsibleResourceNavigation.css';
28
28
  * Supports drag and drop for resource reordering when expanded.
29
29
  * Platform-agnostic design for use across different React environments.
30
30
  *
31
- * @emits navigation:resource-reorder - Resource tab reordered. Payload: { oldIndex: number, newIndex: number }
32
- * @emits navigation:resource-close - Resource tab closed. Payload: { resourceId: string }
33
- * @emits navigation:sidebar-toggle - Toggle sidebar collapsed/expanded state. Payload: undefined
31
+ * @emits browse:resource-reorder - Resource tab reordered. Payload: { oldIndex: number, newIndex: number }
32
+ * @emits browse:resource-close - Resource tab closed. Payload: { resourceId: string }
33
+ * @emits browse:sidebar-toggle - Toggle sidebar collapsed/expanded state. Payload: undefined
34
34
  */
35
35
  export function CollapsibleResourceNavigation({
36
36
  fixedItems,
@@ -110,7 +110,7 @@ export function CollapsibleResourceNavigation({
110
110
  }
111
111
 
112
112
  // Emit event
113
- eventBus.get('navigation:resource-reorder').next({ oldIndex: currentIndex, newIndex });
113
+ eventBus.get('browse:resource-reorder').next({ oldIndex: currentIndex, newIndex });
114
114
 
115
115
  // Announce the change
116
116
  const resource = resources[currentIndex];
@@ -123,7 +123,7 @@ export function CollapsibleResourceNavigation({
123
123
  e.stopPropagation();
124
124
 
125
125
  // Emit event
126
- eventBus.get('navigation:resource-close').next({ resourceId });
126
+ eventBus.get('browse:resource-close').next({ resourceId });
127
127
 
128
128
  // If we're closing the currently viewed resource, navigate to first fixed item or trigger callback
129
129
  const resourceHref = getResourceHref(resourceId);
@@ -151,7 +151,7 @@ export function CollapsibleResourceNavigation({
151
151
  const newIndex = resources.findIndex((resource) => resource.id === over.id);
152
152
  if (oldIndex !== -1 && newIndex !== -1) {
153
153
  // Emit event
154
- eventBus.get('navigation:resource-reorder').next({ oldIndex, newIndex });
154
+ eventBus.get('browse:resource-reorder').next({ oldIndex, newIndex });
155
155
  const resource = resources[oldIndex];
156
156
  announceDrop(resource.name, newIndex + 1, resources.length);
157
157
  }
@@ -189,7 +189,7 @@ export function CollapsibleResourceNavigation({
189
189
  <span className="semiont-nav-section__header-text">{mergedTranslations.title}</span>
190
190
  )}
191
191
  <button
192
- onClick={() => eventBus.get('navigation:sidebar-toggle').next(undefined)}
192
+ onClick={() => eventBus.get('browse:sidebar-toggle').next(undefined)}
193
193
  className="semiont-nav-section__header-icon"
194
194
  title={isCollapsed ? mergedTranslations.expandSidebar : mergedTranslations.collapseSidebar}
195
195
  aria-label={isCollapsed ? mergedTranslations.expandSidebar : mergedTranslations.collapseSidebar}
@@ -27,7 +27,7 @@ export interface ObservableLinkProps extends React.AnchorHTMLAttributes<HTMLAnch
27
27
  * - State coordination before navigation
28
28
  * - Logging navigation flows
29
29
  *
30
- * The component emits 'navigation:link-clicked' event before allowing
30
+ * The component emits 'browse:link-clicked' event before allowing
31
31
  * the browser to follow the link.
32
32
  *
33
33
  * @example
@@ -51,7 +51,7 @@ export interface ObservableLinkProps extends React.AnchorHTMLAttributes<HTMLAnch
51
51
  * </Link>
52
52
  * ```
53
53
  *
54
- * @emits navigation:link-clicked - Link clicked by user. Payload: { href: string, label?: string }
54
+ * @emits browse:link-clicked - Link clicked by user. Payload: { href: string, label?: string }
55
55
  */
56
56
  export function ObservableLink({
57
57
  href,
@@ -70,7 +70,7 @@ export function ObservableLink({
70
70
 
71
71
  const handleClick = useCallback((e: React.MouseEvent<HTMLAnchorElement>) => {
72
72
  // Emit event for observability
73
- eventBus.get('navigation:link-clicked').next({
73
+ eventBus.get('browse:link-clicked').next({
74
74
  href,
75
75
  label
76
76
  });
@@ -29,7 +29,7 @@ export interface SimpleNavigationProps {
29
29
  * Simple navigation component for Admin and Moderation modes.
30
30
  * Renders a section header with optional dropdown and static navigation tabs.
31
31
  *
32
- * @emits navigation:sidebar-toggle - Toggle sidebar collapsed/expanded state. Payload: undefined
32
+ * @emits browse:sidebar-toggle - Toggle sidebar collapsed/expanded state. Payload: undefined
33
33
  */
34
34
  export function SimpleNavigation({
35
35
  title,
@@ -86,7 +86,7 @@ export function SimpleNavigation({
86
86
  !isCollapsed && <span className="semiont-nav-section__header-text">{title}</span>
87
87
  )}
88
88
  <button
89
- onClick={() => eventBus.get('navigation:sidebar-toggle').next(undefined)}
89
+ onClick={() => eventBus.get('browse:sidebar-toggle').next(undefined)}
90
90
  className="semiont-nav-section__header-icon"
91
91
  title={isCollapsed ? expandSidebarLabel : collapseSidebarLabel}
92
92
  aria-label={isCollapsed ? expandSidebarLabel : collapseSidebarLabel}
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import React, { useRef, useState, useCallback, useEffect, useMemo } from 'react';
4
- import { createHoverHandlers } from '../../hooks/useAttentionFlow';
4
+ import { createHoverHandlers } from '../../hooks/useBeckonFlow';
5
5
  import type { components, ResourceUri } from '@semiont/core';
6
6
  import { getTargetSelector } from '@semiont/api-client';
7
7
  import type { SelectionMotivation } from '../annotation/AnnotateToolbar';
@@ -61,9 +61,9 @@ interface PdfAnnotationCanvasProps {
61
61
  /**
62
62
  * PDF annotation canvas with page navigation and rectangle drawing
63
63
  *
64
- * @emits attend:click - Annotation clicked on PDF. Payload: { annotationId: string, motivation: Motivation }
65
- * @emits annotate:requested - New annotation drawn on PDF. Payload: { selector: FragmentSelector, motivation: SelectionMotivation }
66
- * @emits attend:hover - Annotation hovered or unhovered. Payload: { annotationId: string | null }
64
+ * @emits browse:click - Annotation clicked on PDF. Payload: { annotationId: string, motivation: Motivation }
65
+ * @emits mark:requested - New annotation drawn on PDF. Payload: { selector: FragmentSelector, motivation: SelectionMotivation }
66
+ * @emits beckon:hover - Annotation hovered or unhovered. Payload: { annotationId: string | null }
67
67
  */
68
68
  export function PdfAnnotationCanvas({
69
69
  resourceUri,
@@ -287,7 +287,7 @@ export function PdfAnnotationCanvas({
287
287
  });
288
288
 
289
289
  if (clickedAnnotation) {
290
- eventBus?.get('attend:click').next({ annotationId: clickedAnnotation.id, motivation: clickedAnnotation.motivation });
290
+ eventBus?.get('browse:click').next({ annotationId: clickedAnnotation.id, motivation: clickedAnnotation.motivation });
291
291
  setIsDrawing(false);
292
292
  setSelection(null);
293
293
  return;
@@ -326,7 +326,7 @@ export function PdfAnnotationCanvas({
326
326
 
327
327
  // Emit annotation:requested event with FragmentSelector
328
328
  if (selectedMotivation) {
329
- eventBus.get('annotate:requested').next({
329
+ eventBus.get('mark:requested').next({
330
330
  selector: {
331
331
  type: 'FragmentSelector',
332
332
  conformsTo: 'http://tools.ietf.org/rfc/rfc3778',
@@ -364,7 +364,7 @@ export function PdfAnnotationCanvas({
364
364
 
365
365
  // Hover handlers with currentHover guard and dwell delay
366
366
  const { handleMouseEnter, handleMouseLeave } = useMemo(
367
- () => createHoverHandlers((annotationId) => eventBus?.get('attend:hover').next({ annotationId }), hoverDelayMs),
367
+ () => createHoverHandlers((annotationId) => eventBus?.get('beckon:hover').next({ annotationId }), hoverDelayMs),
368
368
  [eventBus, hoverDelayMs]
369
369
  );
370
370
 
@@ -464,7 +464,7 @@ export function PdfAnnotationCanvas({
464
464
  cursor: 'pointer',
465
465
  opacity: isSelected ? 1 : isHovered ? 0.9 : 0.7
466
466
  }}
467
- onClick={() => eventBus?.get('attend:click').next({ annotationId: ann.id, motivation: ann.motivation })}
467
+ onClick={() => eventBus?.get('browse:click').next({ annotationId: ann.id, motivation: ann.motivation })}
468
468
  onMouseEnter={() => handleMouseEnter(ann.id)}
469
469
  onMouseLeave={handleMouseLeave}
470
470
  />
@@ -132,11 +132,11 @@ function segmentTextWithAnnotations(content: string, annotations: Annotation[]):
132
132
  /**
133
133
  * View component for annotating resources with text selection and drawing
134
134
  *
135
- * @emits annotate:requested - User requested to create annotation. Payload: { selector: Selector | Selector[], motivation: SelectionMotivation }
136
- * @subscribes annotate:selection-changed - Toolbar selection changed. Payload: { motivation: string | null }
137
- * @subscribes annotate:click-changed - Toolbar click action changed. Payload: { action: string }
138
- * @subscribes annotate:shape-changed - Toolbar shape changed. Payload: { shape: string }
139
- * @subscribes attend:hover - Annotation hovered. Payload: { annotationId: string | null }
135
+ * @emits mark:requested - User requested to create annotation. Payload: { selector: Selector | Selector[], motivation: SelectionMotivation }
136
+ * @subscribes mark:selection-changed - Toolbar selection changed. Payload: { motivation: string | null }
137
+ * @subscribes mark:click-changed - Toolbar click action changed. Payload: { action: string }
138
+ * @subscribes mark:shape-changed - Toolbar shape changed. Payload: { shape: string }
139
+ * @subscribes beckon:hover - Annotation hovered. Payload: { annotationId: string | null }
140
140
  */
141
141
  export function AnnotateView({
142
142
  content,
@@ -189,10 +189,10 @@ export function AnnotateView({
189
189
 
190
190
  // Subscribe to toolbar events and annotation hover
191
191
  useEventSubscriptions({
192
- 'annotate:selection-changed': handleToolbarSelectionChanged,
193
- 'annotate:click-changed': handleToolbarClickChanged,
194
- 'annotate:shape-changed': handleToolbarShapeChanged,
195
- 'attend:hover': handleAnnotationHover,
192
+ 'mark:selection-changed': handleToolbarSelectionChanged,
193
+ 'mark:click-changed': handleToolbarClickChanged,
194
+ 'mark:shape-changed': handleToolbarShapeChanged,
195
+ 'beckon:hover': handleAnnotationHover,
196
196
  });
197
197
 
198
198
  // Handle text annotation with sparkle or immediate creation
@@ -214,7 +214,7 @@ export function AnnotateView({
214
214
 
215
215
  const handleMouseUp = (e: MouseEvent) => {
216
216
  // Skip if the mouseUp came from PDF or image canvas
217
- // (those components handle their own annotate:requested events)
217
+ // (those components handle their own mark:requested events)
218
218
  const target = e.target as Element;
219
219
  if (target.closest('.semiont-pdf-annotation-canvas') ||
220
220
  target.closest('.semiont-svg-drawing-canvas')) {
@@ -254,7 +254,7 @@ export function AnnotateView({
254
254
 
255
255
  // Unified flow: all text annotations use BOTH TextPositionSelector and TextQuoteSelector
256
256
  if (selectedMotivation) {
257
- eventBus.get('annotate:requested').next({
257
+ eventBus.get('mark:requested').next({
258
258
  selector: [
259
259
  {
260
260
  type: 'TextPositionSelector',
@@ -288,7 +288,7 @@ export function AnnotateView({
288
288
 
289
289
  // Unified flow: all text annotations use BOTH TextPositionSelector and TextQuoteSelector
290
290
  if (selectedMotivation) {
291
- eventBus.get('annotate:requested').next({
291
+ eventBus.get('mark:requested').next({
292
292
  selector: [
293
293
  {
294
294
  type: 'TextPositionSelector',