useAnnotationsContext Hook
The useAnnotationsContext hook provides access to all annotation state and methods within components wrapped by the AnnotationsContextProvider.
Basic Usage
Import and use the hook in any component inside the provider:
tsx
import { useAnnotationsContext } from '@linkurious/ogma-annotations-react';
function MyComponent() {
const context = useAnnotationsContext();
return (
<div>
<p>Annotations: {context.annotations.features.length}</p>
</div>
);
}Destructuring Values
Typically, you'll destructure only the values you need:
tsx
function Toolbar() {
const { editor, canUndo, canRedo, undo, redo } = useAnnotationsContext();
return (
<>
<button onClick={() => editor.enableArrowDrawing({})}>Add Arrow</button>
<button onClick={undo} disabled={!canUndo}>Undo</button>
<button onClick={redo} disabled={!canRedo}>Redo</button>
</>
);
}Available Values
The hook returns an object (IAnnotationsContext) with the following properties:
Core State
annotations
- Type:
AnnotationCollection - Description: All annotations currently in the graph
tsx
const { annotations } = useAnnotationsContext();
console.log(annotations.features.length); // Number of annotations
annotations.features.forEach(annotation => {
console.log(annotation.id, annotation.properties.type);
});editor
- Type:
Control - Description: The annotations editor (Control instance) for direct access to all methods
tsx
const { editor } = useAnnotationsContext();
// Enable drawing modes
editor.enableArrowDrawing({...});
editor.enableTextDrawing({...});
// Get annotations
const all = editor.getAnnotations();
const selected = editor.getSelectedAnnotations();Selection State
currentAnnotation
- Type:
AnnotationFeature | null - Description: The currently selected annotation, or
nullif none selected
tsx
const { currentAnnotation } = useAnnotationsContext();
if (currentAnnotation) {
console.log('Selected:', currentAnnotation.id);
console.log('Type:', currentAnnotation.properties.type);
}setCurrentAnnotation
- Type:
(annotation: AnnotationFeature | null) => void - Description: Manually set the current annotation
tsx
const { setCurrentAnnotation, annotations } = useAnnotationsContext();
// Select the first annotation
if (annotations.features.length > 0) {
setCurrentAnnotation(annotations.features[0]);
}
// Deselect
setCurrentAnnotation(null);Arrow Style State
arrowStyle
- Type:
ArrowStyles - Description: Current arrow style for the selected arrow or for new arrows
tsx
const { arrowStyle } = useAnnotationsContext();
console.log(arrowStyle.strokeColor); // e.g., '#3498db'
console.log(arrowStyle.strokeWidth); // e.g., 2
console.log(arrowStyle.head); // e.g., 'arrow'setArrowStyle
- Type:
(style: ArrowStyles) => void - Description: Update the arrow style (automatically applies to selected arrow)
tsx
const { arrowStyle, setArrowStyle } = useAnnotationsContext();
// Change color
setArrowStyle({
...arrowStyle,
strokeColor: '#e74c3c'
});
// Change width
setArrowStyle({
...arrowStyle,
strokeWidth: 5
});
// Change arrow head
setArrowStyle({
...arrowStyle,
head: 'arrow',
tail: 'none'
});Automatic Updates
When you call setArrowStyle, the provider automatically updates the currently selected arrow annotation!
arrowWidthFactor
- Type:
number - Description: Width scaling factor for arrows (adjusted based on graph scale)
setArrowWidthFactor
- Type:
(factor: number) => void - Description: Set the arrow width scaling factor
Text Style State
textStyle
- Type:
TextStyle - Description: Current text style for the selected text or for new text annotations
tsx
const { textStyle } = useAnnotationsContext();
console.log(textStyle.font); // e.g., 'Arial'
console.log(textStyle.fontSize); // e.g., 16
console.log(textStyle.color); // e.g., '#2c3e50'
console.log(textStyle.background); // e.g., '#ffffff'setTextStyle
- Type:
(style: TextStyle) => void - Description: Update the text style (automatically applies to selected text)
tsx
const { textStyle, setTextStyle } = useAnnotationsContext();
// Change font
setTextStyle({
...textStyle,
font: 'Arial'
});
// Change size and color
setTextStyle({
...textStyle,
fontSize: 18,
color: '#e74c3c'
});
// Change background
setTextStyle({
...textStyle,
background: '#f0f0f0',
borderRadius: 4,
padding: 12
});textSizeFactor
- Type:
number - Description: Size scaling factor for text (adjusted based on graph scale)
setTextSizeFactor
- Type:
(factor: number) => void - Description: Set the text size scaling factor
History Management
canUndo
- Type:
boolean - Description: Whether undo operation is available
canRedo
- Type:
boolean - Description: Whether redo operation is available
undo
- Type:
() => boolean - Description: Undo the last action, returns
trueif successful
redo
- Type:
() => boolean - Description: Redo the last undone action, returns
trueif successful
clearHistory
- Type:
() => void - Description: Clear the undo/redo history
tsx
function HistoryControls() {
const { canUndo, canRedo, undo, redo, clearHistory } = useAnnotationsContext();
return (
<div>
<button onClick={undo} disabled={!canUndo}>Undo</button>
<button onClick={redo} disabled={!canRedo}>Redo</button>
<button onClick={clearHistory}>Clear History</button>
</div>
);
}Annotation Management
add
- Type:
(annotation: Annotation | AnnotationCollection) => void - Description: Add one or more annotations
tsx
const { add } = useAnnotationsContext();
import { createArrow, createText } from '@linkurious/ogma-annotations';
// Add single annotation
add(createArrow(0, 0, 100, 100, { strokeColor: '#3498db' }));
// Add multiple annotations
add({
type: 'FeatureCollection',
features: [
createArrow(0, 0, 100, 100),
createText(50, 50, 'Label')
]
});remove
- Type:
(annotation: Annotation | AnnotationCollection) => void - Description: Remove one or more annotations
tsx
const { remove, editor } = useAnnotationsContext();
// Remove selected annotations
const selected = editor.getSelectedAnnotations();
remove(selected);
// Remove all annotations
const all = editor.getAnnotations();
remove(all);select
- Type:
(ids: string | string[]) => void - Description: Select annotation(s) by ID
tsx
const { select } = useAnnotationsContext();
// Select by ID
select('annotation-123');
// Select multiple
select(['annotation-123', 'annotation-456']);cancelDrawing
- Type:
() => void - Description: Cancel the current drawing operation
tsx
const { cancelDrawing } = useAnnotationsContext();
// Cancel on Escape key
React.useEffect(() => {
const handleKeyDown = (evt: KeyboardEvent) => {
if (evt.key === 'Escape') {
cancelDrawing();
}
};
document.addEventListener('keydown', handleKeyDown);
return () => document.removeEventListener('keydown', handleKeyDown);
}, [cancelDrawing]);Drawing Methods
enableBoxDrawing
- Type:
(style?: Partial<BoxStyle>) => void - Description: Enable box drawing mode
tsx
const { editor } = useAnnotationsContext();
editor.enableBoxDrawing({
background: '#f0f0f0',
borderRadius: 8,
padding: 12
});enablePolygonDrawing
- Type:
(style?: Partial<PolygonStyle>) => void - Description: Enable polygon drawing mode
tsx
const { editor } = useAnnotationsContext();
editor.enablePolygonDrawing({
strokeColor: '#3498db',
strokeWidth: 2,
background: 'rgba(52, 152, 219, 0.2)'
});enableCommentDrawing
- Type:
(options?) => void - Description: Enable comment drawing mode (text with arrow)
tsx
const { editor } = useAnnotationsContext();
editor.enableCommentDrawing({
offsetX: 200,
offsetY: -150,
commentStyle: {
content: '',
style: {
color: '#2c3e50',
background: '#ffffff',
fontSize: 16,
font: 'Arial'
}
},
arrowStyle: {
style: {
strokeColor: '#3498db',
strokeWidth: 2,
head: 'arrow'
}
}
});TypeScript Types
The hook returns IAnnotationsContext. Import the type for type safety:
tsx
import { useAnnotationsContext, type IAnnotationsContext } from '@linkurious/ogma-annotations-react';
function MyComponent() {
const context: IAnnotationsContext = useAnnotationsContext();
// Fully typed!
}Common Patterns
Conditional Rendering Based on Selection
tsx
function StylePanel() {
const { currentAnnotation } = useAnnotationsContext();
if (!currentAnnotation) {
return <div>No annotation selected</div>;
}
return (
<div>
<h3>Editing: {currentAnnotation.id}</h3>
{isArrow(currentAnnotation) && <ArrowStyleControls />}
{isText(currentAnnotation) && <TextStyleControls />}
</div>
);
}Syncing with External State
tsx
function AnnotationsSync() {
const { annotations } = useAnnotationsContext();
// Save to localStorage whenever annotations change
React.useEffect(() => {
localStorage.setItem('annotations', JSON.stringify(annotations));
}, [annotations]);
// Or sync with a backend
React.useEffect(() => {
fetch('/api/annotations', {
method: 'POST',
body: JSON.stringify(annotations)
});
}, [annotations]);
return null; // This component just handles syncing
}Building a Delete Button
tsx
function DeleteButton() {
const { editor, remove, currentAnnotation } = useAnnotationsContext();
const handleDelete = React.useCallback(() => {
const selected = editor.getSelectedAnnotations();
if (selected.features.length > 0) {
remove(selected);
}
}, [editor, remove]);
return (
<button
onClick={handleDelete}
disabled={!currentAnnotation}
>
Delete Selected
</button>
);
}Creating a Toolbar
tsx
function Toolbar() {
const { editor, undo, redo, canUndo, canRedo } = useAnnotationsContext();
const handleArrow = React.useCallback(() => {
editor.enableArrowDrawing({ strokeColor: '#3498db' });
}, [editor]);
const handleText = React.useCallback(() => {
editor.enableTextDrawing({ fontSize: 16 });
}, [editor]);
const handleBox = React.useCallback(() => {
editor.enableBoxDrawing({});
}, [editor]);
return (
<div className="toolbar">
<button onClick={handleArrow}>Arrow</button>
<button onClick={handleText}>Text</button>
<button onClick={handleBox}>Box</button>
<span className="separator" />
<button onClick={undo} disabled={!canUndo}>Undo</button>
<button onClick={redo} disabled={!canRedo}>Redo</button>
</div>
);
}Next Steps
- Creating Annotations Interactively - Enable user-driven creation
- Managing Styles - Build style controls
- Building UI Components - Create complete toolbars and panels