Skip to content
Genom
API reference

@genomdev/vue

Vue bindings for the Genom viewer

13 exported symbols across 1 entry point

@genomdev/vue

Classes

Viewerfrom @genomdev/core
class Viewer
state
ViewerState
container
HTMLElement
view
DocumentView | undefined
The live view, for reaching format-specific APIs such as page navigation.
registry
FormatRegistry
content
(options?: ExtractOptions) => Promise<ContentDocument>
The open document as content: blocks, markdown, chunks, addresses. Built with the walk the format module brought, so this needs no dispatcher and no second parse — and it is the same tree extraction produces on a server, which is why an address minted there resolves here. Memoised: the tree does not change while the document is open.
search
(options?: ExtractOptions) => Promise<DocumentSearch>
Search over the extracted text, with hits highlighted in the document.
on
<K extends keyof ViewerEventMap & string>(event: K, handler: Handler<ViewerEventMap[K]>) => () => void
Subscribes to a named event. Returns an unsubscribe function.
once
<K extends keyof ViewerEventMap & string>(event: K, handler: Handler<ViewerEventMap[K]>) => () => void
emit
<K extends keyof ViewerEventMap & string>(event: K, payload: ViewerEventMap[K]) => void
Emits an event. Renderers and plugins report through here.
subscribe
(listener: (state: ViewerState) => void) => () => void
Subscribes to state as a whole. Kept beside the event bus because a UI framework wants a store rather than a stream: `useSyncExternalStore` needs exactly this shape.
open
(input: ByteSourceInput | GenomDocument, options?: ViewerOptions) => Promise<void>
Opens a file and mounts its view. Calling it again before the previous call settles is correct: the older result is discarded. That is the normal case when a reader picks files in quick succession.
refresh
() => void
Re-renders the current view.
zoom
number
The scale the document is drawn at, and one otherwise. A renderer that cannot scale reports nothing, and a viewer over one reads as being at its natural size — which it is.
setZoom
(zoom: number) => void
Changes the scale the document is drawn at. Here rather than only on the renderer because this is the object an application holds: the React, Vue and Angular wrappers all pass their options in at mount and none of them could reach a zoom control without it, so the only way to change the scale through them was to open the file again. Nothing is laid out again — see `dom/scale.ts` for why a zoom is a transform.
pageCount
number
How many pages, sheets or slides the open document came to.
currentPage
number
The one the reader is looking at, counted from nought.
goToPage
(index: number, behavior?: ScrollBehavior) => void
Scrolls to a page, a sheet or a slide. Here for the same reason as {@link setZoom}: this is the object an application holds, and until it had this the renderers' navigation could not be reached from the React, Vue or Angular wrappers at all.
close
() => void
Closes the document and clears the container.
destroy
() => void
Releases every resource. The instance must not be used afterwards.

Functions

createViewerfrom @genomdev/core
function createViewer(container: HTMLElement, options?: ViewerOptions): Viewer

Creates a viewer mounted into the given element.

useGenom
function useGenom(options?: ViewerOptions): UseGenomResult

Binds a {@link Viewer} to a Vue component's lifecycle. The viewer is created when `containerRef` receives an element rather than on setup: there is no DOM node before the component mounts, and the viewer needs one in its constructor.

Interfaces

FormatModulefrom @genomdev/core
interface FormatModule<TDocument extends GenomDocument = GenomDocument>

A format: everything one file type needs, in one value. `@genomdev/docx` exports one of these for Word, covering both generations. Nothing else has to know that `.doc` exists.

id
string
Stable identifier, used for options and events: `docx`, `pdf`.
formats
readonly FormatId[]
Every format id this module opens.
detect?
readonly DetectRule[] | undefined
How to recognise the format from the file.
open
(source: ByteSource, options?: OpenOptions) => Promise<TDocument>
canOpen?
((source: ByteSource, detection: DetectionResult) => Promise<boolean>) | undefined
Confirms that the source really is this format. Only needed where a rule cannot decide — an OLE2 file is a `.doc`, an `.xls` or a `.ppt`, and telling them apart means reading the directory.
walk?
((document: TDocument, hash: string, options: ResolvedOptions) => Promise<WalkResult>) | undefined
Turns the parsed model into the content tree. Declared as a method rather than as a property on purpose: TypeScript checks method parameters bivariantly, and without that a `FormatModule<DocxDocument>` could not be put in a list beside a `FormatModule<PdfDocument>` — which is the only thing a registry ever does with them.
LazyFormatfrom @genomdev/core
interface LazyFormat

A format that has not been loaded yet. The descriptor carries the recognition rules, so the registry can decide whether this is the module it needs before paying for it. `load` resolves to the module itself, which in a bundler is a chunk of its own.

id
string
formats
readonly FormatId[]
detect?
readonly DetectRule[] | undefined
load
() => Promise<FormatModule>
UseGenomResult
interface UseGenomResult
containerRef
Ref<HTMLElement | null, HTMLElement | null>
Bind this to the container element with `ref`.
state
Ref<ViewerState, ViewerState>
open
(input: ByteSourceInput | GenomDocument | GenomDocument) => Promise<void>
close
() => void
viewer
ShallowRef<Viewer | undefined>
ViewerEventMapfrom @genomdev/core
interface ViewerEventMap

One bus, named events, typed payloads. What this replaces: a callback per format, declared in that format's options. `onSelectionChange` existed only for workbooks, nothing equivalent existed for slides, and every framework wrapper had to know which formats had which callbacks. A wrapper subscribing to one bus is the same size whatever the formats are, which is why Angular and Vue cost a hundred lines each. Format-specific events keep their format as a prefix — `sheet:select`, `slide:change` — so a name says where it came from and two formats cannot collide.

status
ViewerStateEvent
Any change of viewer state: status, progress, error.
'document:open'
{ document: GenomDocument; detection: DetectionResult | undefined; }
'document:close'
Record<string, never>
'page:change'
{ index: number; total: number | undefined; }
'zoom:change'
{ zoom: number; }
The zoom changed, whoever changed it. On the bus rather than only in a callback because a gesture changes it: a reader pinching the document is not something the application asked for, and a toolbar showing a stale number is the commonest way a zoom control looks broken.
'selection:change'
{ text: string; }
'link:activate'
{ href: string; event: MouseEvent; }
A link was followed. `preventDefault` on the event stops the navigation.
error
{ error: Error; }
ViewerOptionsfrom @genomdev/core
interface ViewerOptions extends OpenOptions
formats?
readonly FormatEntry[] | undefined
The formats this viewer can open, eager or lazy. Lazy descriptors are the interesting case: they carry the rules that recognise a file, so the right module is fetched and the others never are.
registry?
FormatRegistry | undefined
A registry built by hand, for an application that shares one.
zoom?
number | undefined
fit?
"none" | "width" | "page" | undefined
initialPage?
number | undefined
options?
Readonly<Record<string, Record<string, unknown>>> | undefined
Renderer options, addressed by format id: `{ xlsx: { formulaBar: false } }`.
decorate?
Readonly<Record<string, Decorator>> | undefined
Decorators, keyed `format:kind` — `xlsx:cell`, `docx:hyperlink`.
plugins?
readonly ViewerPlugin[] | undefined
ViewerPluginfrom @genomdev/core
interface ViewerPlugin

An extension that gets the viewer itself. Returns its own teardown.

name
string
setup
(viewer: Viewer) => (() => void) | void
ViewerStatefrom @genomdev/core
interface ViewerState
status
ViewerStatus
document
GenomDocument | undefined
detection
DetectionResult | undefined
error
Error | undefined
progress
number
Parse and layout progress, 0..1.

Type aliases

FormatEntryfrom @genomdev/core
type FormatEntry = FormatModule | LazyFormat

Either an already-loaded format or a promise of one.

ViewerStatusfrom @genomdev/core
type ViewerStatus = 'idle' | 'loading' | 'ready' | 'error'

The viewer: bytes in, a document on the screen, and a way to reach it after. The one place that knows the whole path — recognise, load the module, open, mount. The React, Vue and Angular wrappers are adapters over this class, so their behaviour is identical by construction rather than by convention. Three things here are the API rather than the implementation. **Formats are values.** `formats: [docx, pdf]` — eager modules or lazy descriptors, mixed freely. Nothing is registered globally, nothing is discovered, and an application that shows PDFs ships no Word parser. **Options are addressed by format.** `options: { xlsx: { formulaBar: false } }` rather than one flat bag whose keys collide the moment two formats want the same word. **Everything reports through one bus.** `viewer.on('page:change', …)`, and the format-specific events carry their format in the name. Extension has two levels, and the cheap one comes first: `decorate` changes an element a renderer already produced, which survives the renderer being rewritten; `plugins` get the viewer itself, for what nobody anticipated.

Values

GenomViewer
GenomViewer: import("/repo/node_modules/.pnpm/vue@3.5.40_typescript@5.9.3/node_modules/vue/dist/vue").DefineComponent<import("/repo/node_modules/.pnpm/vue@3.5.40_typescript@5.9.3/node_modules/vue/dist/vue").ExtractPropTypes<{ file: { type: PropType<ByteSourceInput | GenomDocument | undefined>; default: undefined; }; formats: { type: PropType<readonly FormatEntry[]>; default: undefined; }; options: { type: PropType<ViewerOptions>; default: () => {}; }; }>, () => import("/repo/node_modules/.pnpm/vue@3.5.40_typescript@5.9.3/node_modules/vue/dist/vue").VNode<import("/repo/node_modules/.pnpm/vue@3.5.40_typescript@5.9.3/node_modules/vue/dist/vue").RendererNode, import("/repo/node_modules/.pnpm/vue@3.5.40_typescript@5.9.3/node_modules/vue/dist/vue").RendererElement, { [key: string]: any; }>, {}, {}, {}, import("/repo/node_modules/.pnpm/vue@3.5.40_typescript@5.9.3/node_modules/vue/dist/vue").ComponentOptionsMixin, import("/repo/node_modules/.pnpm/vue@3.5.40_typescript@5.9.3/node_modules/vue/dist/vue").ComponentOptionsMixin, { stateChange: (_state: ViewerState) => true; pageChange: (_payload: ViewerEventMap["page:change"]) => true; documentOpen: (_payload: ViewerEventMap["document:open"]) => true; viewerError: (_payload: ViewerEventMap["error"]) => true; }, string, import("/repo/node_modules/.pnpm/vue@3.5.40_typescript@5.9.3/node_modules/vue/dist/vue").PublicProps, Readonly<import("/repo/node_modules/.pnpm/vue@3.5.40_typescript@5.9.3/node_modules/vue/dist/vue").ExtractPropTypes<{ file: { type: PropType<ByteSourceInput | GenomDocument | undefined>; default: undefined; }; formats: { type: PropType<readonly FormatEntry[]>; default: undefined; }; options: { type: PropType<ViewerOptions>; default: () => {}; }; }>> & Readonly<{ onStateChange?: ((_state: ViewerState) => any) | undefined; onPageChange?: ((_payload: { index: number; total: number | undefined; }) => any) | undefined; onDocumentOpen?: ((_payload: { document: GenomDocument; detection: import("/repo/packages/core/dist/document-6CwVt9Xs").a9 | undefined; }) => any) | undefined; onViewerError?: ((_payload: { error: Error; }) => any) | undefined; }>, { file: ByteSourceInput | GenomDocument | undefined; formats: readonly FormatEntry[]; options: ViewerOptions; }, {}, {}, {}, string, import("/repo/node_modules/.pnpm/vue@3.5.40_typescript@5.9.3/node_modules/vue/dist/vue").ComponentProvideOptions, true, {}, any>

A document viewer component for Vue 3. Written with a render function rather than as a single-file component: the package is built with the monorepo's shared toolchain, and this avoids adding a separate SFC compilation step for what amounts to one container element.