@caipira/vue-reader
v0.0.5
Published
Headless e-book reader toolkit for vue
Downloads
80
Readme
@caipira/vue-reader
Headless reader toolkit for Vue 3.
This package provides a set of tools for creating your own custom reader. It currently supports:
- Raw text
- EPUB
What is included
- Headless epub reader via
useEpubReader,useEpubReaderStateanduseEpubReaderNavigation - Colors hook
setReaderColors - Dictionary integration hook
setReaderDictionary
Install
npm install @caipira/vue-readerUsage
Script:
import { useTemplateRef } from 'vue';
import {
useEpubReader,
setReaderColors,
useEpubReaderState,
useEpubReaderNavigation,
} from '@caipira/vue-reader';
const epubSrc = 'https://example.com/book.epub';
const containerRef = useTemplateRef<HTMLDivElement>('containerRef');
setReaderColors({
background: '#0f172a',
text: '#f8fafc',
highlight: '#facc15',
});
const reader = useEpubReader(() => epubSrc, containerRef);
const { error, loading } = useEpubReaderState();
const { goForward, goBackward } = useEpubReaderNavigation();Template:
<section class="w-full flex justify-between">
<button
icon="chevron-left"
@click="goBackward"
/>
<button
icon="chevron-right"
@click="goForward"
/>
</section>
<div
ref="containerRef"
class="h-full w-full overflow-hidden"
:class="{ 'opacity-0': loading || error }"
/>Dictionary API
The reader uses your dictionary adapter to classify words as known or unknown.
Unknown words are highlighted automatically in the viewport.
Implement and register a dictionary adapter:
import type {
ReaderDictionaryApi,
ReaderDictionaryWordStatus,
} from '@caipira/vue-reader';
import { setReaderDictionary } from '@caipira/vue-reader';
function createDictionary(): ReaderDictionaryApi {
const cache = new Map<string, ReaderDictionaryWordStatus>();
return {
async classifyWords(language, lemmas, contextKey) {
// Load/sync dictionary data for `language` once, then classify lemmas.
// `contextKey` can be used as a cache partition key.
const result = new Map<string, ReaderDictionaryWordStatus>();
for (const lemma of lemmas) {
const status = cache.get(lemma) ?? 'unknown';
result.set(lemma, status);
}
return result;
},
clear() {
cache.clear();
},
};
}
setReaderDictionary(createDictionary());Contract
classifyWords(language, lemmas, contextKey)Returns aMap<lemma, 'known' | 'unknown'>.clear()Clears adapter caches when reader state is torn down.
Word highlighting and lookup flow
When a dictionary is registered with setReaderDictionary(...):
- Unknown words are highlighted automatically.
- Users can
Ctrl+click (orCmd+click on macOS) a word to trigger lookup.
You can handle lookup events by extending your dictionary object with an optional onWordLookup callback (matching the UI integration):
import type { ReaderDictionaryApi } from '@caipira/vue-reader';
import { setReaderDictionary } from '@caipira/vue-reader';
const dictionary = createDictionary() as ReaderDictionaryApi & {
onWordLookup?: (payload: { language: string; word: string; context: string }) => void;
};
dictionary.onWordLookup = ({ language, word, context }) => {
// Open your dictionary UI (drawer/modal/popover) and query definitions.
openDictionaryDrawer({ language, word, context });
};
setReaderDictionary(dictionary);The context value contains nearby text around the clicked word, useful for disambiguation.
Public API
useEpubReader(src, containerRef, options)useEpubReaderState()useEpubReaderNavigation()setReaderColors({ background, text, highlight })setReaderDictionary(dictionary)useReaderDictionary()
Adapters
Preferences adapter
Use preferences to load and persist reader settings from your app-specific store.
Storage adapter
Use storage to override default sessionStorage-based locator persistence.
Build
npm run typecheck
npm run build