@net7/annotator
v1.0.1
Published
Anchoring and highlighting library for web documents
Readme
@net7/annotator
A framework-agnostic TypeScript library for anchoring and highlighting text in web documents with intelligent fallback strategies.
✨ Features
- 🎯 Multiple anchoring strategies with automatic fallback
- 📝 Text highlighting with customizable styles
- 🌐 Framework-agnostic - works with any JavaScript framework
- 🔧 TypeScript support with full type definitions
- 📱 PDF document support for complex layouts
- ⚡ Event-driven architecture for reactive applications
- 🎨 Context-aware filtering for multi-document apps
🚀 Quick Start
Installation
npm install @net7/annotator
# or
yarn add @net7/annotatorBasic Usage
import { Annotator } from '@net7/annotator';
// Create annotator instance
const annotator = new Annotator();
// Set document context
annotator.setContext({ documentId: 'doc-123' });
// Create annotation from user selection
const selection = window.getSelection();
if (selection && selection.rangeCount > 0) {
const result = annotator.createAnnotation({
root: document.body,
range: selection.getRangeAt(0),
context: { documentId: 'doc-123' },
color: '#FFFF00',
metadata: { comment: 'Important note' },
});
console.log('Annotation created:', result);
}📖 API Reference
Annotator Class
Constructor
new Annotator(options?: { allowWhitespace?: boolean })Key Methods
| Method | Description |
| -------------------------- | -------------------------------------- |
| setContext(context) | Set document context for filtering |
| createAnnotation(params) | Create annotation from DOM range |
| load(annotations, root) | Load multiple annotations |
| remove(annotationId) | Remove annotation by ID |
| getEvents() | Get event emitter for highlight events |
Event Handling
// Listen to highlight events
annotator.getEvents().on('highlight', (event) => {
console.log('Highlight event:', event.type, event.payload);
});🏗️ Architecture
The library uses a smart anchoring system with automatic fallback:
- RangeSelector (Most precise) - DOM node references
- TextPositionSelector (Reliable) - Character offsets
- TextQuoteSelector (Robust) - Text content matching
When one strategy fails, it automatically tries the next one, ensuring maximum reliability across different document states.
📊 Advanced Usage
Loading Multiple Annotations
// Load existing annotations
const annotations = await fetchAnnotations();
annotator.load(annotations, document.body);
// Context-aware filtering
annotator.setContext({
documentId: 'doc-123',
pageNumber: 5,
userId: 'user-456',
});Custom Event Handling
const annotator = new Annotator({ allowWhitespace: true });
annotator.getEvents().on('highlight', (event) => {
if (event.type === 'click') {
showAnnotationDetails(event.payload);
}
});🤝 Contributing
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Write tests for your changes
- Ensure all tests pass (
npm test) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
🧪 Development
# Install dependencies
npm install
# Run tests
npm test
# Run tests with coverage
npm run test:coverage
# Build library
npm run build
# Lint code
npm run lint📚 Examples
Check out the docs/ directory for:
- Basic usage examples
- Advanced demo with full UI
- TypeScript integration examples
📄 License
This project is licensed under the BSD-2-Clause License - see the LICENSE file for details.
Third-Party Attributions
This library incorporates code from:
- Hypothesis Client (BSD-2-Clause)
- dom-anchor-text-quote (MIT)
- dom-anchor-text-position (MIT)
See NOTICE for complete attribution details.
