@libraz/mejiro-react 0.8.0 → 0.9.1

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 (4) hide show
  1. package/README.md +12 -3
  2. package/dist/index.d.ts +521 -151
  3. package/dist/index.js +1973 -1443
  4. package/package.json +8 -8
package/dist/index.d.ts CHANGED
@@ -1,8 +1,9 @@
1
- import { MejiroLocale, MejiroMessages, EditableSettings, FontChoice, PageHeaderData, MejiroStorage, Annotation, ReadingPositionValue } from '@libraz/mejiro';
2
- export { Annotation, EditableSettings, FontChoice, MejiroLocale, MejiroMessages, PageHeaderData, ReadingPositionValue, enMessages, jaMessages } from '@libraz/mejiro';
1
+ import { MejiroLocale, MejiroMessages, EditableSettings, FontChoice, ImageOverlayRect, PageHeaderData, MejiroStorage, Annotation, ReadingPositionValue } from '@libraz/mejiro';
2
+ export { Annotation, EditableSettings, FontChoice, ImageOverlayRect, MejiroLocale, MejiroMessages, PageHeaderData, ReadingPositionValue, enMessages, jaMessages } from '@libraz/mejiro';
3
3
  import * as react from 'react';
4
- import { ReactNode, CSSProperties, PointerEvent, TextareaHTMLAttributes, RefObject } from 'react';
5
- import { EpubBook, AssetResolver, EditableEpub, ManuscriptDialect, EpubChapter, EditableEpubBook, AnnotatedParagraph, AddImageInput, EditableEpubImage, EpubExportOptions, EpubProjectMetadata, EpubProject } from '@libraz/mejiro/epub';
4
+ import { ReactNode, CSSProperties, PointerEvent, TextareaHTMLAttributes, MutableRefObject, RefObject } from 'react';
5
+ import { EpubBook, AssetResolver, EpubParseLimits, EditableEpub, ManuscriptDialect, EpubChapter, EditableEpubBook, EditableEpubSelection, AnnotatedParagraph, AddImageInput, EditableEpubImage, EpubExportOptions, EpubProjectMetadata, EpubProjectAsset, EpubProject } from '@libraz/mejiro/epub';
6
+ export { EditableEpubSelection } from '@libraz/mejiro/epub';
6
7
  import { ChapterLayout, SpreadResult, BookOptions, ComputePageSizeOptions, InChapterAnchor, ReadingAnchor, ManuscriptChapter, PageResult, AnchorRect, AnchorRange, MejiroBook } from '@libraz/mejiro/book';
7
8
  import { RenderPage } from '@libraz/mejiro/render';
8
9
  import { FontFamily, InlineAnnotation } from '@libraz/mejiro/browser';
@@ -31,6 +32,10 @@ declare function resolveMessages(locale: MejiroLocale | undefined, overrides: Pa
31
32
  /** Replace `{name}` placeholders in a template. */
32
33
  declare function format(template: string, vars: Record<string, string | number>): string;
33
34
 
35
+ /**
36
+ * Layout of {@link MejiroChapterNav}: `'select'` is a compact dropdown,
37
+ * `'panel'` a chapter list with titles, headings and a text preview.
38
+ */
34
39
  type MejiroChapterNavVariant = 'select' | 'panel';
35
40
  /** Props for {@link MejiroChapterNav}. */
36
41
  interface MejiroChapterNavProps {
@@ -57,7 +62,7 @@ declare function MejiroChapterNav({ epub, chapter, onChange, variant, }: MejiroC
57
62
  interface MejiroDropZoneProps {
58
63
  /** File `accept` filter for the picker. @defaultValue '.epub' */
59
64
  accept?: string;
60
- /** Validator. Defaults to `name.endsWith('.epub')`. */
65
+ /** Validator. Defaults to the `accept` filter, with extensions matched case-insensitively. */
61
66
  validateFile?: (file: File) => boolean;
62
67
  /** Called with the selected/dropped file. */
63
68
  onFile: (file: File) => void;
@@ -69,7 +74,9 @@ interface MejiroDropZoneProps {
69
74
  style?: CSSProperties;
70
75
  }
71
76
  /**
72
- * Drop zone for EPUB files. Combines drag-and-drop with a click-to-open file picker.
77
+ * Drop zone for EPUB files. Combines drag-and-drop with a click-to-open file
78
+ * picker. The root is a real button, so it is reachable with Tab, announced as
79
+ * a control by screen readers, and opens the picker on Enter / Space.
73
80
  */
74
81
  declare function MejiroDropZone({ accept, validateFile, onFile, children, className, style, }: MejiroDropZoneProps): ReactNode;
75
82
 
@@ -93,6 +100,7 @@ interface MejiroSettingsPanelProps {
93
100
  */
94
101
  declare function MejiroSettingsPanel({ open, settings, onChange, fonts, minFontSize, maxFontSize, }: MejiroSettingsPanelProps): ReactNode;
95
102
 
103
+ /** Props for {@link MejiroEditor}. */
96
104
  interface MejiroEditorProps {
97
105
  /** URL fetched and loaded on mount. */
98
106
  epubUrl?: string;
@@ -139,18 +147,27 @@ interface MejiroEditorProps {
139
147
  * custom auth headers.
140
148
  */
141
149
  assetResolver?: AssetResolver;
150
+ /**
151
+ * Archive resource limits applied while opening an EPUB. Raise them for
152
+ * trusted, image-heavy books; tighten them for a public drop zone. Omitted
153
+ * fields keep their `DEFAULT_EPUB_PARSE_LIMITS` value.
154
+ */
155
+ limits?: Partial<EpubParseLimits>;
142
156
  /** Called after an EPUB is loaded into the editor. */
143
157
  onLoad?: (editor: EditableEpub) => void;
144
158
  /** Called after export completes. */
145
159
  onExport?: (buffer: ArrayBuffer) => void;
146
- /** Called when loading or parsing an EPUB fails. */
160
+ /**
161
+ * Called when loading, image insertion or export fails. The error is also
162
+ * shown in the editor.
163
+ */
147
164
  onError?: (error: Error) => void;
148
165
  }
149
166
  /**
150
167
  * Declarative restrictions on the export pipeline. Mejiro applies the
151
- * transforms in this order: `watermark` (modifies the EPUB in-place) →
152
- * `encrypt` (replaces the buffer with the result) → `allowDownload` (skips
153
- * the browser download when `false`).
168
+ * transforms in this order: `watermark` (applied to an export-only copy of the
169
+ * book, never to the edited document) → `encrypt` (replaces the buffer with the
170
+ * result) → `allowDownload` (skips the browser download when `false`).
154
171
  */
155
172
  interface MejiroExportPolicy {
156
173
  /**
@@ -166,24 +183,27 @@ interface MejiroExportPolicy {
166
183
  */
167
184
  encrypt?: (buffer: ArrayBuffer) => ArrayBuffer | Promise<ArrayBuffer>;
168
185
  /**
169
- * Embeds a visible watermark string into the EPUB. Implemented by writing
170
- * the text as XHTML metadata; renderers may surface it differently.
186
+ * Embeds a visible watermark string into the exported EPUB. Implemented as a
187
+ * paragraph block prefixed with `[mejiro-watermark]` at the top of every
188
+ * chapter, so a downstream renderer can theme it by that prefix. The block
189
+ * only exists in the exported file — the edited document is unchanged.
171
190
  */
172
191
  watermark?: {
173
192
  text: string;
174
- opacity?: number;
175
193
  };
176
194
  }
177
195
  /** EPUB editor UI for proofreading, ruby edits, image insertion, and export. */
178
- declare function MejiroEditor({ epubUrl, fonts, enableProofread, enableRuby, enableImages, enableExport, onBeforeExport, exportPolicy, assetResolver, onLoad, onExport, onError, }: MejiroEditorProps): ReactNode;
196
+ declare function MejiroEditor({ epubUrl, fonts, enableProofread, enableRuby, enableImages, enableExport, onBeforeExport, exportPolicy, assetResolver, limits, onLoad, onExport, onError, }: MejiroEditorProps): ReactNode;
179
197
 
180
- /** Rectangle describing an image overlay position and size. */
181
- interface ImageRect {
182
- x: number;
183
- y: number;
184
- w: number;
185
- h: number;
186
- }
198
+ /**
199
+ * Rectangle describing an image overlay position and size.
200
+ *
201
+ * @deprecated Alias of {@link ImageOverlayRect}, which is the single name for
202
+ * this shape across the package family. The core package exports an unrelated
203
+ * `ImageRect` (an exclusion rectangle, with margin fields), so the two names
204
+ * collide when both packages are imported into one module.
205
+ */
206
+ type ImageRect = ImageOverlayRect;
187
207
  /** Options for {@link useImageOverlay}. */
188
208
  interface UseImageOverlayOptions {
189
209
  /** Default image width in pixels. @defaultValue 120 */
@@ -200,7 +220,7 @@ interface UseImageOverlayOptions {
200
220
  /** Return value of {@link useImageOverlay}. */
201
221
  interface UseImageOverlayReturn {
202
222
  /** Current image rectangle, or `null` if no overlay is active. */
203
- imageRect: ImageRect | null;
223
+ imageRect: ImageOverlayRect | null;
204
224
  /** Whether an image overlay is currently active. */
205
225
  hasImage: boolean;
206
226
  /** Toggle the image overlay on/off. */
@@ -214,6 +234,11 @@ interface UseImageOverlayReturn {
214
234
  * React hook that manages a draggable/resizable image overlay
215
235
  * with automatic text reflow via {@link ChapterLayout.syncImages}.
216
236
  *
237
+ * While an overlay is active the exclusion is re-issued whenever `layout` is
238
+ * replaced, `spreadIdx` changes or `options.margin` changes, so a re-layout, a
239
+ * page turn or a new margin never leaves the overlay drawn without its matching
240
+ * text reflow.
241
+ *
217
242
  * @param layout - Current chapter layout (or `null` if not yet loaded).
218
243
  * @param spreadIdx - Current spread index.
219
244
  * @param onUpdate - Called with the updated {@link SpreadResult} after every reflow.
@@ -246,6 +271,10 @@ interface MejiroImageOverlayProps {
246
271
  */
247
272
  declare function MejiroImageOverlay({ rect, label, onOverlayPointerDown, onResizePointerDown, onClose, }: MejiroImageOverlayProps): ReactNode;
248
273
 
274
+ /**
275
+ * Where {@link MejiroReader} places its chapter navigation: the header
276
+ * dropdown (`'select'`), the side chapter list (`'panel'`), both, or neither.
277
+ */
249
278
  type MejiroChapterNavMode = 'select' | 'panel' | 'both' | 'none';
250
279
  /**
251
280
  * Reading-flow mode for {@link MejiroReader}.
@@ -256,8 +285,9 @@ type MejiroReaderMode = 'paginated' | 'scroll';
256
285
  /**
257
286
  * Two-page vs single-page rendering of a spread.
258
287
  * - `double` — always render two pages (default).
259
- * - `single` — render only the right page, centered.
260
- * - `auto` — switch based on the surface aspect ratio (single when portrait).
288
+ * - `single` — render one page at a time, centered; spread indices count pages.
289
+ * - `auto` — switch based on the surface aspect ratio (single when portrait),
290
+ * converting the index so the page on screen stays visible.
261
291
  */
262
292
  type MejiroSpreadMode = 'double' | 'single' | 'auto';
263
293
  /**
@@ -289,9 +319,13 @@ type MejiroTheme = MejiroThemeName | {
289
319
  };
290
320
  /** Reading position exposed by {@link MejiroReaderHandle.getReadingPosition}. */
291
321
  interface ReadingPosition {
322
+ /** Zero-based index of the current chapter. */
292
323
  chapter: number;
324
+ /** Zero-based index of the current spread within the chapter. */
293
325
  spreadIdx: number;
326
+ /** Number of pages in the current chapter's layout. */
294
327
  totalPages: number;
328
+ /** Number of spreads in the current chapter's layout. */
295
329
  totalSpreads: number;
296
330
  }
297
331
  /**
@@ -341,14 +375,16 @@ interface MejiroReaderHandle {
341
375
  */
342
376
  goToAnchor(anchor: ReadingAnchor): Promise<void>;
343
377
  /**
344
- * Returns the {@link ReadingAnchor} at the start of the current spread,
345
- * or `null` if the layout is not ready.
378
+ * Returns the {@link ReadingAnchor} at the start of the text on the current
379
+ * spread, or `null` if the layout is not ready. When an image blocks every
380
+ * page of the spread, the anchor is where the text resumes after it; `null`
381
+ * again if none follows.
346
382
  */
347
383
  getAnchor(): ReadingAnchor | null;
348
384
  /**
349
385
  * Returns the half-open range of {@link ReadingAnchor}s visible on the
350
- * current spread. `end` points at the start of the next spread (or the end
351
- * of the chapter for the last spread).
386
+ * current spread. `end` points at the start of the text on the next spread
387
+ * that has any (or the end of the chapter when none does).
352
388
  */
353
389
  getVisibleRange(): {
354
390
  start: ReadingAnchor;
@@ -357,6 +393,12 @@ interface MejiroReaderHandle {
357
393
  /**
358
394
  * Updates book options at runtime. Same shape as {@link MejiroBook.setOptions}
359
395
  * — font / size changes re-measure and re-layout asynchronously.
396
+ *
397
+ * Successive calls are coalesced into a single application; the returned
398
+ * promise resolves once that application has settled. A failed application
399
+ * (such as a font that measures as a fallback under `strictFontCheck`) is
400
+ * reported through {@link MejiroReaderProps.onError} rather than rejecting
401
+ * the promise.
360
402
  */
361
403
  setOptions(partial: Partial<BookOptions>): Promise<void>;
362
404
  /**
@@ -413,7 +455,9 @@ interface MejiroReaderCommonProps {
413
455
  /**
414
456
  * Controlled spread index. When supplied, the reader is driven by this
415
457
  * value and emits {@link MejiroReaderProps.onSpreadIdxChange} on user
416
- * navigation. Combine with `useReadingPosition` for save/restore.
458
+ * navigation. A spread index does not survive reflow, so persist the
459
+ * reading position with `useReadingPosition` and the handle's
460
+ * `getAnchor` / `goToAnchor` instead.
417
461
  */
418
462
  spreadIdx?: number;
419
463
  /**
@@ -430,8 +474,10 @@ interface MejiroReaderCommonProps {
430
474
  */
431
475
  mode?: MejiroReaderMode;
432
476
  /**
433
- * Spread layout. `double` (default) renders two pages; `single` renders
434
- * only the right page; `auto` flips to `single` for portrait viewports.
477
+ * Spread layout. `double` (default) renders two pages; `single` renders one
478
+ * page at a time, and `spreadIdx`, `goToSpread`, `onSpreadIdxChange` and
479
+ * `spreadChanged` then count pages; `auto` flips to `single` for portrait
480
+ * viewports, keeping the page on screen visible.
435
481
  */
436
482
  spreadMode?: MejiroSpreadMode;
437
483
  /**
@@ -462,6 +508,13 @@ interface MejiroReaderCommonProps {
462
508
  * sending bearer tokens or cookies.
463
509
  */
464
510
  fetchOptions?: RequestInit;
511
+ /**
512
+ * Resource limits applied while parsing an EPUB the reader loads itself
513
+ * (URL mode and the drop zone / file picker). Untrusted files reach this
514
+ * component directly, so hosts that accept them should tighten the
515
+ * defaults here.
516
+ */
517
+ limits?: Partial<EpubParseLimits>;
465
518
  /**
466
519
  * Custom EPUB fetcher used in place of the global `fetch`. Overrides
467
520
  * {@link fetchOptions} when set.
@@ -542,9 +595,10 @@ interface MejiroReaderCommonProps {
542
595
  /**
543
596
  * Reader-side annotations to render as highlights. Each annotation whose
544
597
  * `chapter` matches the current chapter is converted to spread-local
545
- * rectangles via `ChapterLayout.selectionRects` and drawn on top of the
546
- * page content. Pair with {@link useAnnotations} for persistence, or pass
547
- * any shape that satisfies `{ chapter, start, end }`.
598
+ * rectangles via `ChapterLayout.selectionRects`; the rectangles landing on
599
+ * the spread on screen are drawn on top of the page content. Pair with
600
+ * {@link useAnnotations} for persistence, or pass any shape that satisfies
601
+ * `{ chapter, start, end }`.
548
602
  */
549
603
  annotations?: ReadonlyArray<{
550
604
  chapter: number;
@@ -554,7 +608,11 @@ interface MejiroReaderCommonProps {
554
608
  }>;
555
609
  /** Called after a successful EPUB load. */
556
610
  onLoad?: (book: EpubBook) => void;
557
- /** Called when loading or parsing an EPUB fails. */
611
+ /**
612
+ * Called when loading or parsing an EPUB fails, and when applying an option
613
+ * change fails (such as a font that measures as a fallback under
614
+ * `strictFontCheck`; without it, a font that fails to load is not an error).
615
+ */
558
616
  onError?: (error: Error) => void;
559
617
  /** Called when the chapter index changes. */
560
618
  onChapterChange?: (chapter: number) => void;
@@ -623,18 +681,31 @@ interface MejiroReaderManuscriptProps extends MejiroReaderCommonProps {
623
681
  * modes — TypeScript prevents passing more than one source at once.
624
682
  */
625
683
  type MejiroReaderProps = MejiroReaderControlledProps | MejiroReaderUrlProps | MejiroReaderFileProps | MejiroReaderManuscriptProps;
684
+ /**
685
+ * Full-page EPUB reader. Composes the package's primitives into a working
686
+ * reader; features opt out via the `enableX` props or all chrome via `bare`.
687
+ * The `ref` exposes {@link MejiroReaderHandle} for imperative navigation.
688
+ */
626
689
  declare const MejiroReader: react.ForwardRefExoticComponent<MejiroReaderProps & react.RefAttributes<MejiroReaderHandle>>;
627
690
 
691
+ /** One chapter of the manuscript being edited. */
628
692
  interface ManuscriptEditorChapter {
693
+ /** Stable identifier; survives reordering and title edits. */
629
694
  id: string;
695
+ /** Chapter title; an empty title falls back to the localized "untitled" label. */
630
696
  title: string;
697
+ /** Chapter body in the editor's manuscript notation. */
631
698
  body: string;
632
699
  }
633
700
  /** Autosave payload emitted by {@link MejiroManuscriptEditor}. */
634
701
  interface ManuscriptAutosaveDraft {
702
+ /** Book title as currently entered. */
635
703
  title: string;
704
+ /** Author name as currently entered. */
636
705
  author: string;
706
+ /** Selected cover image, or `null` when none is set. */
637
707
  cover: File | null;
708
+ /** Chapters in reading order, as plain (non-reactive) copies. */
638
709
  chapters: ManuscriptEditorChapter[];
639
710
  }
640
711
  /**
@@ -644,14 +715,23 @@ interface ManuscriptAutosaveDraft {
644
715
  * supplied here.
645
716
  */
646
717
  interface ManuscriptPreviewProps {
718
+ /** Header subtitle of the preview reader. */
647
719
  subtitle?: string;
720
+ /** Header title of the preview reader. */
648
721
  title?: string;
722
+ /** Where the preview places its chapter navigation. @defaultValue 'panel' */
649
723
  chapterNavMode?: 'select' | 'panel' | 'both' | 'none';
724
+ /** Show the preview header. */
650
725
  enableHeader?: boolean;
726
+ /** Show the preview chapter navigation. */
651
727
  enableChapterNav?: boolean;
728
+ /** Show the preview settings panel toggle. */
652
729
  enableSettings?: boolean;
730
+ /** Show the preview layout statistics. */
653
731
  enableStats?: boolean;
732
+ /** Enable arrow-key page turns in the preview. */
654
733
  enableKeyboard?: boolean;
734
+ /** Show the preview page indicator. */
655
735
  enablePageIndicator?: boolean;
656
736
  /** Book options forwarded to the embedded reader preview. */
657
737
  options?: Partial<BookOptions>;
@@ -666,8 +746,10 @@ interface ManuscriptPreviewProps {
666
746
  * to `true` to demo the fullscreen-reader behavior.
667
747
  */
668
748
  enableSurfaceTap?: boolean;
749
+ /** Render the preview without any reader chrome. */
669
750
  bare?: boolean;
670
751
  }
752
+ /** Props for {@link MejiroManuscriptEditor}. */
671
753
  interface MejiroManuscriptEditorProps {
672
754
  /** Font choices passed to the preview reader. */
673
755
  fonts?: FontChoice[];
@@ -695,6 +777,12 @@ interface MejiroManuscriptEditorProps {
695
777
  onCoverChange?: (cover: File | null) => void;
696
778
  /** Initial chapters. */
697
779
  chapters?: ManuscriptEditorChapter[];
780
+ /**
781
+ * Manuscript notation dialect. Drives the notation highlighter, the live
782
+ * preview, and the exported EPUB alike, so the whole editor interprets one
783
+ * dialect. @defaultValue `'mejiro'`
784
+ */
785
+ dialect?: ManuscriptDialect;
698
786
  /**
699
787
  * Called whenever the chapter draft settles (debounced by
700
788
  * {@link MejiroManuscriptEditorProps.autosaveDelay}). Use to persist drafts
@@ -710,17 +798,30 @@ interface MejiroManuscriptEditorProps {
710
798
  */
711
799
  previewProps?: ManuscriptPreviewProps;
712
800
  /**
713
- * Resolves URL-only project assets (e.g. covers/illustrations registered as
714
- * `{ url, ... }`) into bytes at export time. Forwarded to `project.export()`
715
- * so authors can register signed-URL references without holding raw bytes
716
- * client-side until publish.
801
+ * Resolver for URL-only assets, forwarded to `project.export()`. This editor
802
+ * owns a `File` cover and manuscript text only, and embeds the cover bytes
803
+ * itself, so nothing it registers is URL-only — build the project through
804
+ * `useEpubProject` (`setCover` / `setAssets`) to author `{ url }` asset
805
+ * references that must be fetched at export time.
717
806
  */
718
807
  assetResolver?: AssetResolver;
719
808
  /** Called after export completes. */
720
809
  onExport?: (buffer: ArrayBuffer) => void;
810
+ /**
811
+ * Called when the EPUB export fails (asset resolution, cover reading, or
812
+ * packaging). The same error is shown in the editor panel, so hosts only
813
+ * need this to log or report it.
814
+ */
815
+ onError?: (error: Error) => void;
816
+ /**
817
+ * Which side of the editor the manuscript panel sits on. `'right'` (the
818
+ * default) puts the preview on the left; `'left'` mirrors the layout.
819
+ * @defaultValue 'right'
820
+ */
821
+ panelSide?: 'left' | 'right';
721
822
  }
722
823
  /** Manuscript-to-EPUB editor for author drafts from posting sites. */
723
- declare function MejiroManuscriptEditor({ fonts, title: titleProp, onTitleChange, author: authorProp, onAuthorChange, cover: coverProp, onCoverChange, chapters: initialChapters, onAutosave, autosaveDelay, previewProps, assetResolver, onExport, }: MejiroManuscriptEditorProps): ReactNode;
824
+ declare function MejiroManuscriptEditor({ fonts, title: titleProp, onTitleChange, author: authorProp, onAuthorChange, cover: coverProp, onCoverChange, chapters: initialChapters, dialect, onAutosave, autosaveDelay, previewProps, assetResolver, onExport, onError, panelSide, }: MejiroManuscriptEditorProps): ReactNode;
724
825
 
725
826
  /** Props for {@link MejiroNotationHighlighter}. */
726
827
  interface MejiroNotationHighlighterProps extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'value' | 'onChange'> {
@@ -809,6 +910,60 @@ interface MejiroPageViewProps {
809
910
  */
810
911
  declare function MejiroPageView({ result, fontFamily, lineSpacing, slotMode, className, style, }: MejiroPageViewProps): ReactNode;
811
912
 
913
+ /** A single image overlay placed on a specific spread. */
914
+ interface MultiImageItem {
915
+ /** Stable ID for the overlay (auto-assigned on add). */
916
+ id: string;
917
+ /** Position and size in pixels, relative to the right page. */
918
+ rect: ImageRect;
919
+ }
920
+ /** Options for {@link useMultiImageOverlay}. */
921
+ interface UseMultiImageOverlayOptions {
922
+ /** Default image width. @defaultValue 120 */
923
+ defaultWidth?: number;
924
+ /** Default image height. @defaultValue 160 */
925
+ defaultHeight?: number;
926
+ /** Default x. @defaultValue 80 */
927
+ defaultX?: number;
928
+ /** Default y. @defaultValue 100 */
929
+ defaultY?: number;
930
+ /** Margin around each image, in pixels. Defaults to the book's font size. */
931
+ margin?: number;
932
+ /** Called after every reflow caused by adding/removing/moving an image. */
933
+ onUpdate?: (spread: SpreadResult) => void;
934
+ }
935
+ /** Return value of {@link useMultiImageOverlay}. */
936
+ interface UseMultiImageOverlayReturn {
937
+ /**
938
+ * Map of all images keyed by spread index. A new map whenever the images or
939
+ * the margin they are applied with change, and a replacement layout has them
940
+ * before any view renders from it, so this map and the layout together key
941
+ * anything derived from the layout.
942
+ */
943
+ imagesBySpread: Map<number, MultiImageItem[]>;
944
+ /** Images on the current spread; a new array whenever `imagesBySpread` changes. */
945
+ currentImages: MultiImageItem[];
946
+ /** Whether any spread has at least one image. */
947
+ hasImages: boolean;
948
+ /** Add a new image on the current spread. */
949
+ addImage: (overrides?: Partial<ImageRect>) => MultiImageItem;
950
+ /** Remove the image with the given id. */
951
+ removeImage: (id: string) => void;
952
+ /** Replace an image's rectangle. */
953
+ updateImage: (id: string, rect: Partial<ImageRect>) => void;
954
+ /** Remove every image (or only those on `spreadIdx` if given). */
955
+ clearImages: (spreadIdx?: number) => void;
956
+ /** Pointer-down handler for the overlay body (drag). */
957
+ onOverlayPointerDown: (id: string, e: PointerEvent) => void;
958
+ /** Pointer-down handler for the resize handle. */
959
+ onResizePointerDown: (id: string, e: PointerEvent) => void;
960
+ }
961
+ /**
962
+ * React hook that manages multiple draggable/resizable image overlays
963
+ * per spread with automatic reflow via {@link ChapterLayout.setImages}.
964
+ */
965
+ declare function useMultiImageOverlay(layout: ChapterLayout | null, spreadIdx: number, options?: UseMultiImageOverlayOptions): UseMultiImageOverlayReturn;
966
+
812
967
  /** Props for {@link MejiroScrollView}. */
813
968
  interface MejiroScrollViewProps {
814
969
  /** Layout containing the pages to render. */
@@ -839,6 +994,31 @@ interface MejiroScrollViewProps {
839
994
  scrollToPage?: number;
840
995
  /** Vertical gap between pages (px). @defaultValue 24 */
841
996
  pageGap?: number;
997
+ /**
998
+ * Selection rectangles to highlight. Compute via
999
+ * {@link ChapterLayout.selectionRects}; each entry is painted on the page its
1000
+ * `pageIdx` addresses. An entry may carry a `color` fill.
1001
+ */
1002
+ selectionRects?: readonly (AnchorRect & {
1003
+ color?: string;
1004
+ })[];
1005
+ /** Zero-based spread whose pages carry {@link MejiroScrollViewProps.images}. */
1006
+ spreadIdx?: number;
1007
+ /**
1008
+ * Image overlays on the spread at {@link MejiroScrollViewProps.spreadIdx}.
1009
+ * Each renders on the page whose area contains its centre (see
1010
+ * `overlayPageSide`), matching {@link MejiroSpread}'s single-page routing.
1011
+ * The layout reflows in place when its images change, so a new array here is
1012
+ * also what re-reads the pages; `useMultiImageOverlay`'s `currentImages`
1013
+ * provides one on every change.
1014
+ */
1015
+ images?: MultiImageItem[];
1016
+ /** Pointer-down on an image overlay. */
1017
+ onImagePointerDown?: (id: string, e: PointerEvent) => void;
1018
+ /** Pointer-down on an image resize handle. */
1019
+ onImageResizePointerDown?: (id: string, e: PointerEvent) => void;
1020
+ /** Image overlay close button. */
1021
+ onImageClose?: (id: string) => void;
842
1022
  }
843
1023
  /**
844
1024
  * Continuous-scroll variant of {@link MejiroSpread}. Stacks every page in
@@ -846,7 +1026,7 @@ interface MejiroScrollViewProps {
846
1026
  * detected via `IntersectionObserver` and reported through
847
1027
  * {@link MejiroScrollViewProps.onVisiblePageChange}.
848
1028
  */
849
- declare function MejiroScrollView({ layout, pageWidth, pageHeight, contentHeight, fontFamily, fontSize, lineSpacing, onVisiblePageChange, scrollToPage, pageGap, }: MejiroScrollViewProps): ReactNode;
1029
+ declare function MejiroScrollView({ layout, pageWidth, pageHeight, contentHeight, fontFamily, fontSize, lineSpacing, slotMode, onVisiblePageChange, scrollToPage, pageGap, selectionRects, spreadIdx, images, onImagePointerDown, onImageResizePointerDown, onImageClose, }: MejiroScrollViewProps): ReactNode;
850
1030
 
851
1031
  /** Props for {@link MejiroSelectionLayer}. */
852
1032
  interface MejiroSelectionLayerProps {
@@ -854,8 +1034,14 @@ interface MejiroSelectionLayerProps {
854
1034
  * Spread-local rectangles to highlight. Compute these via
855
1035
  * {@link ChapterLayout.selectionRects} and pass the full array; the layer
856
1036
  * picks the entries matching {@link MejiroSelectionLayerProps.side}.
1037
+ *
1038
+ * A rectangle may carry its own `color`, which becomes that rectangle's
1039
+ * fill. Entries without one take the fill from the shipped stylesheet
1040
+ * (`.mejiro-selection-rect`, themeable via `--mejiro-selection-bg`).
857
1041
  */
858
- rects: readonly AnchorRect[];
1042
+ rects: readonly (AnchorRect & {
1043
+ color?: string;
1044
+ })[];
859
1045
  /** Which page-side this layer is rendered into. */
860
1046
  side: 'right' | 'left';
861
1047
  /** Optional class added to the outer wrapper. */
@@ -864,7 +1050,7 @@ interface MejiroSelectionLayerProps {
864
1050
  style?: CSSProperties;
865
1051
  /** Optional class for each rectangle (defaults to `mejiro-selection-rect`). */
866
1052
  rectClassName?: string;
867
- /** Optional inline style for each rectangle. */
1053
+ /** Optional inline style for each rectangle. Takes precedence over `color`. */
868
1054
  rectStyle?: CSSProperties;
869
1055
  }
870
1056
  /**
@@ -928,7 +1114,7 @@ interface MejiroShelfProps<T = unknown> {
928
1114
  currentId?: string;
929
1115
  /** Called when the user picks a volume. */
930
1116
  onSelect?: (volume: VolumeInfo<T>) => void;
931
- /** Heading shown above the grid. @defaultValue 'Library' */
1117
+ /** Heading shown above the grid. Defaults to the active message catalog's `shelfTitle`. */
932
1118
  title?: string;
933
1119
  }
934
1120
  /**
@@ -937,55 +1123,6 @@ interface MejiroShelfProps<T = unknown> {
937
1123
  */
938
1124
  declare function MejiroShelf<T = unknown>({ volumes, currentId, onSelect, title, }: MejiroShelfProps<T>): ReactNode;
939
1125
 
940
- /** A single image overlay placed on a specific spread. */
941
- interface MultiImageItem {
942
- /** Stable ID for the overlay (auto-assigned on add). */
943
- id: string;
944
- /** Position and size in pixels, relative to the right page. */
945
- rect: ImageRect;
946
- }
947
- /** Options for {@link useMultiImageOverlay}. */
948
- interface UseMultiImageOverlayOptions {
949
- /** Default image width. @defaultValue 120 */
950
- defaultWidth?: number;
951
- /** Default image height. @defaultValue 160 */
952
- defaultHeight?: number;
953
- /** Default x. @defaultValue 80 */
954
- defaultX?: number;
955
- /** Default y. @defaultValue 100 */
956
- defaultY?: number;
957
- /** Margin around each image, in pixels. Defaults to the book's font size. */
958
- margin?: number;
959
- /** Called after every reflow caused by adding/removing/moving an image. */
960
- onUpdate?: (spread: SpreadResult) => void;
961
- }
962
- /** Return value of {@link useMultiImageOverlay}. */
963
- interface UseMultiImageOverlayReturn {
964
- /** Map of all images keyed by spread index. */
965
- imagesBySpread: Map<number, MultiImageItem[]>;
966
- /** Images on the current spread. */
967
- currentImages: MultiImageItem[];
968
- /** Whether any spread has at least one image. */
969
- hasImages: boolean;
970
- /** Add a new image on the current spread. */
971
- addImage: (overrides?: Partial<ImageRect>) => MultiImageItem;
972
- /** Remove the image with the given id. */
973
- removeImage: (id: string) => void;
974
- /** Replace an image's rectangle. */
975
- updateImage: (id: string, rect: Partial<ImageRect>) => void;
976
- /** Remove every image (or only those on `spreadIdx` if given). */
977
- clearImages: (spreadIdx?: number) => void;
978
- /** Pointer-down handler for the overlay body (drag). */
979
- onOverlayPointerDown: (id: string, e: PointerEvent) => void;
980
- /** Pointer-down handler for the resize handle. */
981
- onResizePointerDown: (id: string, e: PointerEvent) => void;
982
- }
983
- /**
984
- * React hook that manages multiple draggable/resizable image overlays
985
- * per spread with automatic reflow via {@link ChapterLayout.setImages}.
986
- */
987
- declare function useMultiImageOverlay(layout: ChapterLayout | null, spreadIdx: number, options?: UseMultiImageOverlayOptions): UseMultiImageOverlayReturn;
988
-
989
1126
  /** Props for {@link MejiroSpread}. */
990
1127
  interface MejiroSpreadProps {
991
1128
  /** Spread data to render. */
@@ -1008,9 +1145,17 @@ interface MejiroSpreadProps {
1008
1145
  rightHeader?: PageHeaderData;
1009
1146
  /** Header data for the left page. */
1010
1147
  leftHeader?: PageHeaderData;
1011
- /** Image overlays on the current spread. */
1148
+ /**
1149
+ * Image overlays on the current spread, relative to the right page. With
1150
+ * {@link MejiroSpreadProps.singlePage}, only those whose centre lies on the
1151
+ * page shown are drawn.
1152
+ */
1012
1153
  images?: MultiImageItem[];
1013
- /** Force slot-mode rendering on both pages. */
1154
+ /**
1155
+ * Force slot-mode rendering on both pages. When omitted, each page falls
1156
+ * through to {@link MejiroPageView}'s automatic choice: slot mode for pages
1157
+ * with images, native `writing-mode: vertical-rl` otherwise.
1158
+ */
1014
1159
  slotMode?: boolean;
1015
1160
  /** Custom renderer for per-page headers. */
1016
1161
  renderPageHeader?: (side: 'right' | 'left', header: PageHeaderData) => ReactNode;
@@ -1033,23 +1178,38 @@ interface MejiroSpreadProps {
1033
1178
  * enables pointer-drag selection on the page content area.
1034
1179
  */
1035
1180
  anchorAtCoord?: (x: number, y: number) => InChapterAnchor | null;
1181
+ /**
1182
+ * Zero-based index of the spread being rendered. Rectangles passed through
1183
+ * {@link MejiroSpreadProps.selectionRects} carry spread-local coordinates,
1184
+ * so this is what scopes them to this spread. When omitted, every supplied
1185
+ * rectangle is painted.
1186
+ */
1187
+ spreadIdx?: number;
1036
1188
  /**
1037
1189
  * Selection rectangles to render as a highlight overlay. Compute via
1038
- * {@link ChapterLayout.selectionRects}. Entries with `spreadIdx` other than
1039
- * the current spread are ignored.
1190
+ * {@link ChapterLayout.selectionRects}. Entries whose `spreadIdx` differs
1191
+ * from {@link MejiroSpreadProps.spreadIdx} are ignored. An entry may carry
1192
+ * a `color` that becomes that rectangle's fill.
1040
1193
  */
1041
- selectionRects?: readonly AnchorRect[];
1194
+ selectionRects?: readonly (AnchorRect & {
1195
+ color?: string;
1196
+ })[];
1042
1197
  /**
1043
1198
  * Called when the user drags-selects text on the spread.
1044
1199
  * Called with `null` on a single-click (caret) where start equals end.
1045
1200
  */
1046
1201
  onSelectionChange?: (range: AnchorRange | null) => void;
1047
1202
  /**
1048
- * Hide the left page and render only the right page (centered). Use this
1049
- * for portrait viewports or when a reader explicitly opts into single-page
1050
- * mode.
1203
+ * Render only one page of the spread (centered), chosen by
1204
+ * {@link MejiroSpreadProps.singleSide}. Use this for portrait viewports or
1205
+ * when a reader explicitly opts into single-page mode.
1051
1206
  */
1052
1207
  singlePage?: boolean;
1208
+ /**
1209
+ * Page of the spread shown when {@link MejiroSpreadProps.singlePage} is set
1210
+ * (`useSpread` reports it as `singleSide`). @defaultValue 'right'
1211
+ */
1212
+ singleSide?: 'right' | 'left';
1053
1213
  /**
1054
1214
  * Called when the user makes a quick swipe gesture on the spread.
1055
1215
  * `direction === 'next'` means the user swiped from right to left (the
@@ -1060,10 +1220,11 @@ interface MejiroSpreadProps {
1060
1220
  onSurfaceTap?: () => void;
1061
1221
  }
1062
1222
  /**
1063
- * Renders a two-page spread with the book frame, page chrome, navigation
1064
- * zones, and image overlays. Used inside `mejiro-reader-surface`.
1223
+ * Renders a two-page spread (or one page of it in single-page mode) with the
1224
+ * book frame, page chrome, navigation zones, and image overlays. Used inside
1225
+ * `mejiro-reader-surface`.
1065
1226
  */
1066
- declare function MejiroSpread({ spread, pageWidth, pageHeight, contentHeight, fontFamily, fontSize, lineSpacing, turning, rightHeader, leftHeader, images, renderPageHeader, indicator, onPrev, onNext, onImagePointerDown, onImageResizePointerDown, onImageClose, anchorAtCoord, selectionRects, onSelectionChange, singlePage, onSwipe, onSurfaceTap, }: MejiroSpreadProps): ReactNode;
1227
+ declare function MejiroSpread({ spread, pageWidth, pageHeight, contentHeight, fontFamily, fontSize, lineSpacing, turning, rightHeader, leftHeader, images, slotMode, renderPageHeader, indicator, onPrev, onNext, onImagePointerDown, onImageResizePointerDown, onImageClose, anchorAtCoord, spreadIdx, selectionRects, onSelectionChange, singlePage, singleSide, onSwipe, onSurfaceTap, }: MejiroSpreadProps): ReactNode;
1067
1228
 
1068
1229
  /** Props for {@link MejiroStats}. */
1069
1230
  interface MejiroStatsProps {
@@ -1093,9 +1254,9 @@ interface MejiroTocProps {
1093
1254
  currentAnchor?: ReadingAnchor | null;
1094
1255
  /** Show a search input that filters chapter titles. @defaultValue false */
1095
1256
  searchable?: boolean;
1096
- /** Heading displayed above the list. @defaultValue 'Contents' */
1257
+ /** Heading displayed above the list. Defaults to the active message catalog's `tocTitle`. */
1097
1258
  title?: string;
1098
- /** Placeholder shown in the search input. @defaultValue 'Search chapters…' */
1259
+ /** Placeholder shown in the search input. Defaults to the active message catalog's `tocSearchPlaceholder`. */
1099
1260
  searchPlaceholder?: string;
1100
1261
  /** Called when the user picks a chapter. */
1101
1262
  onSelect?: (chapter: number) => void;
@@ -1116,6 +1277,8 @@ interface UseAnnotationsOptions {
1116
1277
  /**
1117
1278
  * Storage backend. Defaults to `window.localStorage` when available.
1118
1279
  * SSR consumers can omit this and the hook will fall back to in-memory.
1280
+ * The latest reference is always used, so an object literal recreated on
1281
+ * every render is safe — only `key` triggers a re-hydration.
1119
1282
  */
1120
1283
  storage?: AnnotationsStorage;
1121
1284
  /** Throttle ms between writes. @defaultValue 250 */
@@ -1173,17 +1336,20 @@ interface UseChapterLayoutOptions {
1173
1336
  */
1174
1337
  pageGeometry?: () => ComputePageSizeOptions | undefined;
1175
1338
  /**
1176
- * Capture the current reading position from the outgoing layout, just before
1177
- * a **reflow** (non-blank) re-layout replaces it. The returned anchor is
1178
- * exposed via {@link UseChapterLayoutReturn.pendingRestore} and should be
1179
- * applied once the new layout commits. Return `null` to skip preservation.
1180
- * Never called for blank (content-change) re-layouts.
1181
- *
1182
- * A reflow yields a brand-new {@link ChapterLayout} object, which resets any
1183
- * downstream spread index to 0; capturing here and restoring after keeps the
1184
- * reader on the same passage across resizes and font / option changes.
1339
+ * Capture the reading position from the outgoing layout, just before a
1340
+ * **reflow** (non-blank) re-layout replaces it. The anchor is held in
1341
+ * `pendingRestore` until the new layout is in place, then handed to
1342
+ * `restorePosition` when one is given. Return `null` to skip preservation.
1343
+ * Never called for blank (content-change) re-layouts, which start at spread 0.
1185
1344
  */
1186
1345
  capturePosition?: (layout: ChapterLayout) => InChapterAnchor | null;
1346
+ /**
1347
+ * Apply an anchor captured by `capturePosition` to the new layout, e.g. by
1348
+ * locating it and jumping to its spread. Called once the new layout is in
1349
+ * place — after it commits, before paint — and `pendingRestore` is cleared
1350
+ * first. Without it, consume `pendingRestore` yourself.
1351
+ */
1352
+ restorePosition?: (layout: ChapterLayout, position: InChapterAnchor) => void;
1187
1353
  }
1188
1354
  /** Options for {@link UseChapterLayoutReturn.recompute}. */
1189
1355
  interface RecomputeOptions {
@@ -1197,8 +1363,11 @@ interface RecomputeOptions {
1197
1363
  }
1198
1364
  /** Page dimensions returned by {@link MejiroBook.computePageSize}. */
1199
1365
  interface PageDimensions {
1366
+ /** Width of one page, in CSS pixels. */
1200
1367
  pageWidth: number;
1368
+ /** Height of one page, in CSS pixels. */
1201
1369
  pageHeight: number;
1370
+ /** Height of the text area inside a page, in CSS pixels. */
1202
1371
  contentHeight: number;
1203
1372
  }
1204
1373
  /** Return value of {@link useChapterLayout}. */
@@ -1216,11 +1385,17 @@ interface UseChapterLayoutReturn {
1216
1385
  /** Force a fresh layout computation. */
1217
1386
  recompute: (opts?: RecomputeOptions) => Promise<void>;
1218
1387
  /**
1219
- * Anchor captured before the most recent reflow re-layout, awaiting
1220
- * restoration into the new {@link layout}. Consume it in a layout effect keyed
1221
- * on `layout` (after any index reset) and clear it back to `null`.
1388
+ * Anchor captured by `capturePosition` before the most recent reflow,
1389
+ * awaiting restoration into the new layout. `restorePosition`, when given,
1390
+ * consumes it; otherwise read it once the new layout is in place and set it
1391
+ * back to `null`.
1392
+ *
1393
+ * Declared as a `MutableRefObject` because consumers are expected to write to
1394
+ * it — `@types/react@18` models `RefObject.current` as read-only, so a
1395
+ * `RefObject` here would make the documented recipe fail to compile on the
1396
+ * lower end of the supported peer range.
1222
1397
  */
1223
- pendingRestore: RefObject<InChapterAnchor | null>;
1398
+ pendingRestore: MutableRefObject<InChapterAnchor | null>;
1224
1399
  }
1225
1400
  /**
1226
1401
  * React hook that lays out the currently-selected chapter and re-flows when the
@@ -1232,13 +1407,16 @@ interface UseChapterLayoutReturn {
1232
1407
  * mounted before its container had a final box is still sized correctly on
1233
1408
  * first paint), and later size changes trigger a debounced **full re-layout**.
1234
1409
  *
1235
- * A full re-layout — rather than a `ChapterLayout.resize()` fast-path — is used
1236
- * for size changes on purpose: the fast-path only stretches `pageWidth` and does
1237
- * not re-paginate, leaving sparse, half-empty pages after a non-trivial size
1238
- * delta. Because a full re-layout yields a new {@link ChapterLayout} object
1239
- * (resetting any downstream spread index to 0), the reading position is
1240
- * preserved across reflows via {@link UseChapterLayoutOptions.capturePosition}
1241
- * and {@link UseChapterLayoutReturn.pendingRestore}.
1410
+ * Size and option changes lay the chapter out again rather than calling
1411
+ * `ChapterLayout.resize()`, so page geometry is re-derived from the surface and
1412
+ * the book's current options. The book replays the line-breaking hints it
1413
+ * already derived for the chapter, so a reflow never re-runs the analyzer.
1414
+ * Because each re-layout yields a new {@link ChapterLayout} object (resetting
1415
+ * any downstream spread index to 0), the reading position is carried across
1416
+ * reflows by {@link UseChapterLayoutOptions.capturePosition},
1417
+ * {@link UseChapterLayoutOptions.restorePosition} and
1418
+ * {@link UseChapterLayoutReturn.pendingRestore}, identically in the Vue
1419
+ * composable.
1242
1420
  *
1243
1421
  * @param book - The book instance to lay out with.
1244
1422
  * @param epub - The current parsed EPUB.
@@ -1248,10 +1426,7 @@ interface UseChapterLayoutReturn {
1248
1426
  */
1249
1427
  declare function useChapterLayout(book: MejiroBook, epub: EpubBook | null, chapterIndex: number, surface: RefObject<HTMLElement | null>, options?: UseChapterLayoutOptions): UseChapterLayoutReturn;
1250
1428
 
1251
- interface EditableEpubSelection {
1252
- chapter: number;
1253
- paragraph: number;
1254
- }
1429
+ /** Options for {@link useEditableEpub}. */
1255
1430
  interface UseEditableEpubOptions {
1256
1431
  /** URL fetched and loaded on mount. */
1257
1432
  defaultUrl?: string;
@@ -1261,32 +1436,64 @@ interface UseEditableEpubOptions {
1261
1436
  onError?: (error: Error) => void;
1262
1437
  /** Called after export completes. */
1263
1438
  onExport?: (buffer: ArrayBuffer) => void;
1439
+ /**
1440
+ * Archive resource limits applied while opening an EPUB. Raise them for
1441
+ * trusted, image-heavy books; tighten them for a public drop zone. Omitted
1442
+ * fields keep their `DEFAULT_EPUB_PARSE_LIMITS` value.
1443
+ */
1444
+ limits?: Partial<EpubParseLimits>;
1445
+ /**
1446
+ * Resolves URL-only images into bytes when {@link UseEditableEpubReturn.exportEpub}
1447
+ * packages the book. An `assetResolver` passed to `exportEpub` itself wins.
1448
+ */
1449
+ assetResolver?: AssetResolver;
1264
1450
  }
1451
+ /** Return value of {@link useEditableEpub}. */
1265
1452
  interface UseEditableEpubReturn {
1453
+ /** Loaded editor, or `null` before any load. */
1266
1454
  editor: EditableEpub | null;
1455
+ /** The editor's live document, or `null` before any load. */
1267
1456
  book: EditableEpubBook | null;
1457
+ /** Snapshot of `book` re-cloned on every edit, for feeding a preview reader. */
1268
1458
  previewBook: EditableEpubBook | null;
1459
+ /** Whether a load is in progress. */
1269
1460
  loading: boolean;
1461
+ /** Whether an export is in progress. */
1270
1462
  exporting: boolean;
1463
+ /** Last load error, if any. */
1271
1464
  error: Error | null;
1465
+ /** Counter bumped on every load, edit, undo and redo. */
1272
1466
  revision: number;
1467
+ /** Undo / redo availability, or `null` before any load. */
1273
1468
  history: {
1274
1469
  canUndo: boolean;
1275
1470
  canRedo: boolean;
1276
1471
  depth: number;
1277
1472
  redoDepth: number;
1278
1473
  } | null;
1474
+ /** Paragraph targeted by the editing commands. */
1279
1475
  selection: EditableEpubSelection;
1476
+ /** The paragraph at `selection`, or `null` when there is none. */
1280
1477
  selectedParagraph: AnnotatedParagraph | null;
1478
+ /** Moves the selection, clamped to the loaded book. */
1281
1479
  setSelection: (selection: EditableEpubSelection) => void;
1480
+ /** Loads an EPUB from an in-memory buffer. */
1282
1481
  loadBuffer: (buffer: ArrayBuffer) => Promise<EditableEpub | null>;
1482
+ /** Loads an EPUB from a {@link File}. */
1283
1483
  loadFile: (file: File) => Promise<EditableEpub | null>;
1484
+ /** Fetches and loads an EPUB; a non-2xx response is reported as an error. */
1284
1485
  loadUrl: (url: string) => Promise<EditableEpub | null>;
1486
+ /** Replaces the selected paragraph's text and, optionally, its inline annotations. */
1285
1487
  updateParagraph: (text: string, inlineAnnotations?: readonly InlineAnnotation[]) => void;
1488
+ /** Replaces the selected paragraph's inline annotations. */
1286
1489
  setInlineAnnotations: (inlineAnnotations: readonly InlineAnnotation[]) => void;
1490
+ /** Inserts an image into the selected chapter. */
1287
1491
  addImage: (image: AddImageInput | EditableEpubImage) => void;
1492
+ /** Reverts the last edit. Returns `false` when there is nothing to undo. */
1288
1493
  undo: () => boolean;
1494
+ /** Re-applies the last undone edit. Returns `false` when there is nothing to redo. */
1289
1495
  redo: () => boolean;
1496
+ /** Packages the edited document as an EPUB buffer. */
1290
1497
  exportEpub: (options?: EpubExportOptions) => Promise<ArrayBuffer | null>;
1291
1498
  }
1292
1499
  /** Headless editable-EPUB state for custom proofreading/editor UIs. */
@@ -1294,11 +1501,11 @@ declare function useEditableEpub(options?: UseEditableEpubOptions): UseEditableE
1294
1501
 
1295
1502
  /** Options for {@link useEpub}. */
1296
1503
  interface UseEpubOptions {
1297
- /** URL fetched on mount. A non-OK response is treated as "no default". */
1504
+ /** URL fetched on mount. */
1298
1505
  defaultUrl?: string;
1299
1506
  /** Called after a successful load. */
1300
1507
  onLoad?: (book: EpubBook) => void;
1301
- /** Called when a load fails. Non-OK URL responses are still treated as "no default". */
1508
+ /** Called when a load fails, including a non-2xx URL response. */
1302
1509
  onError?: (error: Error) => void;
1303
1510
  /**
1304
1511
  * Extra options merged into the `fetch` call when loading by URL. Useful
@@ -1311,6 +1518,12 @@ interface UseEpubOptions {
1311
1518
  * for hosts that already own an auth-aware HTTP client.
1312
1519
  */
1313
1520
  fetchEpub?: (url: string) => Promise<ArrayBuffer>;
1521
+ /**
1522
+ * Archive resource limits applied while opening an EPUB. Raise them for
1523
+ * trusted, image-heavy books; tighten them for a public drop zone. Omitted
1524
+ * fields keep their `DEFAULT_EPUB_PARSE_LIMITS` value.
1525
+ */
1526
+ limits?: Partial<EpubParseLimits>;
1314
1527
  }
1315
1528
  /** Return value of {@link useEpub}. */
1316
1529
  interface UseEpubReturn {
@@ -1335,45 +1548,104 @@ interface UseEpubReturn {
1335
1548
  */
1336
1549
  declare function useEpub(options?: UseEpubOptions): UseEpubReturn;
1337
1550
 
1551
+ /** One chapter of the manuscript draft the hook keeps in React state. */
1338
1552
  interface EpubProjectChapterDraft {
1553
+ /** Stable chapter identifier. */
1339
1554
  id: string;
1555
+ /** Chapter title. */
1340
1556
  title: string;
1557
+ /** Chapter body in the manuscript notation. */
1341
1558
  body: string;
1342
1559
  }
1560
+ /** Options for {@link useEpubProject}. */
1343
1561
  interface UseEpubProjectOptions {
1562
+ /** Initial package metadata, merged over the hook's Japanese defaults. */
1344
1563
  metadata?: Partial<EpubProjectMetadata>;
1564
+ /** Initial chapter drafts. A single generated chapter is used when empty. */
1345
1565
  chapters?: EpubProjectChapterDraft[];
1566
+ /** Preview rebuild debounce in milliseconds. @defaultValue 250 */
1346
1567
  debounceMs?: number;
1568
+ /**
1569
+ * Initial cover asset. Pass `{ href, url }` to keep the bytes remote until
1570
+ * export, or `{ href, data }` to embed them straight away.
1571
+ */
1572
+ cover?: EpubProjectAsset;
1573
+ /**
1574
+ * Initial non-cover assets (illustrations, extra stylesheets). Same
1575
+ * `data` / `url` choice as {@link UseEpubProjectOptions.cover}.
1576
+ */
1577
+ assets?: EpubProjectAsset[];
1347
1578
  /**
1348
1579
  * Resolves URL-only project assets into bytes when the preview or export
1349
- * pipeline materializes them. Forwarded to `project.export()`. Useful when
1350
- * cover / illustration assets are registered as remote URLs and you want
1351
- * the host (not the client) to provide auth headers.
1580
+ * pipeline materializes them. Forwarded to `project.export()`. Register the
1581
+ * URLs through {@link UseEpubProjectReturn.setCover} /
1582
+ * {@link UseEpubProjectReturn.setAssets} and let the host (not the client)
1583
+ * provide auth headers here.
1352
1584
  */
1353
1585
  assetResolver?: AssetResolver;
1586
+ /** Called with each successfully rebuilt preview book. */
1354
1587
  onPreview?: (book: EpubBook) => void;
1588
+ /** Called with the EPUB bytes produced by {@link UseEpubProjectReturn.exportEpub}. */
1355
1589
  onExport?: (buffer: ArrayBuffer) => void;
1356
1590
  /** Creates the default title for a generated chapter. */
1357
1591
  defaultChapterTitle?: (index: number) => string;
1358
1592
  /** Creates the default body for a generated chapter. */
1359
1593
  defaultChapterBody?: (index: number) => string;
1360
1594
  }
1595
+ /** State and actions returned by {@link useEpubProject}. */
1361
1596
  interface UseEpubProjectReturn {
1597
+ /** Current book metadata. */
1362
1598
  metadata: EpubProjectMetadata;
1599
+ /** Current chapter drafts, in reading order. */
1363
1600
  chapters: EpubProjectChapterDraft[];
1601
+ /** Index of the chapter being edited. */
1364
1602
  selectedChapter: number;
1603
+ /** The chapter at `selectedChapter`, or `null` when there is none. */
1365
1604
  currentChapter: EpubProjectChapterDraft | null;
1605
+ /** Current cover asset, or `null` when the project has no cover. */
1606
+ cover: EpubProjectAsset | null;
1607
+ /** Current non-cover assets, in registration order. */
1608
+ assets: EpubProjectAsset[];
1609
+ /** Parsed EPUB built from the current project, refreshed after each debounced change. */
1366
1610
  previewBook: EpubBook | null;
1611
+ /** Last preview build failure, if any. */
1367
1612
  previewError: Error | null;
1613
+ /** Whether a preview build is pending or running. */
1368
1614
  previewing: boolean;
1615
+ /** Merges `patch` into the metadata. */
1369
1616
  setMetadata: (patch: Partial<EpubProjectMetadata>) => void;
1617
+ /** Replaces every chapter; an empty list becomes one generated chapter. */
1370
1618
  setChapters: (chapters: EpubProjectChapterDraft[]) => void;
1619
+ /** Selects a chapter, clamped to the chapter range. */
1371
1620
  setSelectedChapter: (index: number) => void;
1621
+ /**
1622
+ * Replaces the cover asset, or drops it when passed `null`. The new cover is
1623
+ * reflected by both the debounced preview and {@link UseEpubProjectReturn.exportEpub}.
1624
+ */
1625
+ setCover: (asset: EpubProjectAsset | null) => void;
1626
+ /**
1627
+ * Replaces the non-cover asset list. Assets are registered on every rebuilt
1628
+ * project, so URL-only entries reach `assetResolver` at export time.
1629
+ */
1630
+ setAssets: (assets: EpubProjectAsset[]) => void;
1631
+ /** Merges `patch` into the chapter at `index`. */
1372
1632
  patchChapter: (index: number, patch: Partial<EpubProjectChapterDraft>) => void;
1633
+ /** Appends a chapter (generated defaults fill omitted fields) and selects it. */
1373
1634
  addChapter: (chapter?: Partial<EpubProjectChapterDraft>) => void;
1635
+ /**
1636
+ * Removes the chapter at `index` (the selected one by default); the last chapter is never
1637
+ * removed.
1638
+ */
1374
1639
  removeChapter: (index?: number) => void;
1640
+ /**
1641
+ * Moves a chapter from `from` to `to`. An out-of-range `from` selects no
1642
+ * chapter and leaves the list untouched; `to` is clamped to the list bounds —
1643
+ * the same contract as `EpubProject.reorderChapters()`.
1644
+ */
1375
1645
  reorderChapters: (from: number, to: number) => void;
1646
+ /** Builds an `EpubProject` from the current state. */
1376
1647
  buildProject: () => EpubProject;
1648
+ /** Packages the current project as an EPUB buffer. */
1377
1649
  exportEpub: () => Promise<ArrayBuffer>;
1378
1650
  }
1379
1651
  /** Headless manuscript-to-EPUB project state for custom authoring UIs. */
@@ -1401,14 +1673,24 @@ interface UseManuscriptDraftOptions<TAutosave = ManuscriptEditorChapter[]> {
1401
1673
  }
1402
1674
  /** Return value of {@link useManuscriptDraft}. */
1403
1675
  interface UseManuscriptDraftReturn {
1676
+ /** Current chapters, in reading order. */
1404
1677
  chapters: ManuscriptEditorChapter[];
1405
1678
  /** Index of the chapter currently being edited. */
1406
1679
  selected: number;
1680
+ /** Selects a chapter, clamped to the chapter range. */
1407
1681
  setSelected(index: number): void;
1682
+ /**
1683
+ * Replaces every chapter; an empty list becomes one generated chapter. The
1684
+ * selected chapter is kept by id when it survives.
1685
+ */
1408
1686
  setChapters(chapters: ManuscriptEditorChapter[]): void;
1687
+ /** Merges `patch` into the chapter at `index`. */
1409
1688
  patchChapter(index: number, patch: Partial<ManuscriptEditorChapter>): void;
1689
+ /** Appends a chapter (generated defaults fill omitted fields) and selects it. */
1410
1690
  addChapter(chapter?: Partial<ManuscriptEditorChapter>): void;
1691
+ /** Removes the chapter at `index`; the last remaining chapter is never removed. */
1411
1692
  removeChapter(index: number): void;
1693
+ /** Moves the chapter at `from` to `to`, keeping the same chapter selected. */
1412
1694
  reorderChapters(from: number, to: number): void;
1413
1695
  /** Last autosave failure, if any. */
1414
1696
  autosaveError: Error | null;
@@ -1432,11 +1714,39 @@ interface UseManuscriptLayoutOptions {
1432
1714
  enableResize?: boolean;
1433
1715
  /** Debounce window (ms) applied to size-triggered re-flows. @defaultValue 120 */
1434
1716
  resizeDebounce?: number;
1717
+ /**
1718
+ * Capture the reading position from the outgoing layout, just before a
1719
+ * **reflow** (non-blank) re-layout replaces it. The anchor is held in
1720
+ * `pendingRestore` until the new layout is in place, then handed to
1721
+ * `restorePosition` when one is given. Return `null` to skip preservation.
1722
+ * Never called for blank (content-change) re-layouts, which start at spread 0.
1723
+ */
1724
+ capturePosition?: (layout: ChapterLayout) => InChapterAnchor | null;
1725
+ /**
1726
+ * Apply an anchor captured by `capturePosition` to the new layout, e.g. by
1727
+ * locating it and jumping to its spread. Called once the new layout is in
1728
+ * place — after it commits, before paint — and `pendingRestore` is cleared
1729
+ * first. Without it, consume `pendingRestore` yourself.
1730
+ */
1731
+ restorePosition?: (layout: ChapterLayout, position: InChapterAnchor) => void;
1732
+ }
1733
+ /** Options for {@link UseManuscriptLayoutReturn.recompute}. */
1734
+ interface ManuscriptRecomputeOptions {
1735
+ /**
1736
+ * Blank the current layout while the new one is computed. Use for content
1737
+ * changes (chapter swaps); skip for size changes so the previous spread stays
1738
+ * visible until the re-flow completes (no flicker).
1739
+ * @defaultValue true
1740
+ */
1741
+ blank?: boolean;
1435
1742
  }
1436
1743
  /** Page dimensions returned by {@link MejiroBook.computePageSize}. */
1437
1744
  interface ManuscriptPageDimensions {
1745
+ /** Width of one page, in CSS pixels. */
1438
1746
  pageWidth: number;
1747
+ /** Height of one page, in CSS pixels. */
1439
1748
  pageHeight: number;
1749
+ /** Height of the text area inside a page, in CSS pixels. */
1440
1750
  contentHeight: number;
1441
1751
  }
1442
1752
  /** Return value of {@link useManuscriptLayout}. */
@@ -1452,7 +1762,14 @@ interface UseManuscriptLayoutReturn {
1452
1762
  /** Most recent layout time (ms). */
1453
1763
  elapsedMs: number;
1454
1764
  /** Force a fresh layout computation. */
1455
- recompute: () => Promise<void>;
1765
+ recompute: (opts?: ManuscriptRecomputeOptions) => Promise<void>;
1766
+ /**
1767
+ * Anchor captured by `capturePosition` before the most recent reflow,
1768
+ * awaiting restoration into the new layout. `restorePosition`, when given,
1769
+ * consumes it; otherwise read it once the new layout is in place and set it
1770
+ * back to `null`.
1771
+ */
1772
+ pendingRestore: MutableRefObject<InChapterAnchor | null>;
1456
1773
  }
1457
1774
  /**
1458
1775
  * React hook that lays out a single manuscript chapter directly, skipping the
@@ -1465,9 +1782,37 @@ interface UseManuscriptLayoutReturn {
1465
1782
  * Re-layouts whenever `chapter`, `dialect`, or `book` change. The surface is
1466
1783
  * observed with {@link ResizeObserver}; size changes trigger a full re-layout
1467
1784
  * so pagination stays correct after non-trivial container changes.
1785
+ *
1786
+ * A size-driven re-layout keeps the previous layout on screen while the new one
1787
+ * is computed (no blank flash) and yields a new {@link ChapterLayout} object,
1788
+ * which resets any downstream spread index to 0; the reading position is
1789
+ * preserved across such reflows via
1790
+ * {@link UseManuscriptLayoutOptions.capturePosition},
1791
+ * {@link UseManuscriptLayoutOptions.restorePosition} and
1792
+ * {@link UseManuscriptLayoutReturn.pendingRestore}, identically in the Vue
1793
+ * composable.
1468
1794
  */
1469
1795
  declare function useManuscriptLayout(book: MejiroBook, chapter: ManuscriptChapter | null, surface: RefObject<HTMLElement | null>, options?: UseManuscriptLayoutOptions): UseManuscriptLayoutReturn;
1470
1796
 
1797
+ /** Options for {@link useMejiroBook}. */
1798
+ interface UseMejiroBookOptions {
1799
+ /**
1800
+ * Coalescing window (ms) applied before a change reaches the underlying
1801
+ * {@link MejiroBook}. The exposed snapshot is always updated synchronously so
1802
+ * controlled settings UI stays responsive; only the book application — and the
1803
+ * font load it may trigger — is debounced, so dragging a continuous control
1804
+ * results in a single re-measurement. `0` applies immediately.
1805
+ * @defaultValue 0
1806
+ */
1807
+ debounceMs?: number;
1808
+ /**
1809
+ * Called when applying options to the book fails. When supplied, failures are
1810
+ * reported here and the promise returned by
1811
+ * {@link UseMejiroBookReturn.setOptions} resolves instead of rejecting, so
1812
+ * fire-and-forget callers cannot leave an unhandled rejection behind.
1813
+ */
1814
+ onError?: (error: Error) => void;
1815
+ }
1471
1816
  /** Return value of {@link useMejiroBook}. */
1472
1817
  interface UseMejiroBookReturn {
1473
1818
  /** The managed {@link MejiroBook} instance. Stable across renders. */
@@ -1475,9 +1820,10 @@ interface UseMejiroBookReturn {
1475
1820
  /** Reactive snapshot of the current options. */
1476
1821
  options: Readonly<BookOptions>;
1477
1822
  /**
1478
- * Update options on the underlying book and the snapshot. The returned
1479
- * promise resolves once {@link MejiroBook.setOptions} has propagated
1480
- * font / size changes (re-measurement runs lazily inside that call).
1823
+ * Update options on the underlying book and the snapshot. The snapshot is
1824
+ * updated synchronously; the returned promise resolves once
1825
+ * {@link MejiroBook.setOptions} has propagated font / size changes (which
1826
+ * complete only after the font has loaded).
1481
1827
  */
1482
1828
  setOptions: (next: Partial<BookOptions>) => Promise<void>;
1483
1829
  }
@@ -1486,8 +1832,11 @@ interface UseMejiroBookReturn {
1486
1832
  * options as React state. The book is created once on mount; subsequent
1487
1833
  * option changes must go through {@link UseMejiroBookReturn.setOptions}
1488
1834
  * (e.g. via the `MejiroReader` imperative handle).
1835
+ *
1836
+ * @param initial - Initial book options (passed to the {@link MejiroBook} constructor).
1837
+ * @param options - Behavior overrides (debouncing, error reporting).
1489
1838
  */
1490
- declare function useMejiroBook(initial: BookOptions): UseMejiroBookReturn;
1839
+ declare function useMejiroBook(initial: BookOptions, options?: UseMejiroBookOptions): UseMejiroBookReturn;
1491
1840
 
1492
1841
  /** Minimal storage interface required by {@link useReadingPosition}. */
1493
1842
  type ReadingPositionStorage = MejiroStorage;
@@ -1527,9 +1876,10 @@ interface UseReadingPositionReturn {
1527
1876
  * const { position, save } = useReadingPosition({ key: `mejiro:${bookId}` });
1528
1877
  * const reader = useRef<MejiroReaderHandle>(null);
1529
1878
  *
1879
+ * // Restore once per mount: depending on `position` would re-run after every save().
1530
1880
  * useEffect(() => {
1531
1881
  * if (position) reader.current?.goToAnchor(position);
1532
- * }, [position]);
1882
+ * }, []);
1533
1883
  *
1534
1884
  * useEffect(() => {
1535
1885
  * const off = reader.current?.subscribe('spreadChanged', () => {
@@ -1552,33 +1902,53 @@ interface UseSpreadOptions {
1552
1902
  enableKeyboard?: boolean;
1553
1903
  /** Page-turn animation duration in ms. @defaultValue 180 */
1554
1904
  turnDuration?: number;
1905
+ /**
1906
+ * Show one page at a time: the navigation index then counts pages instead
1907
+ * of two-page spreads. Toggling it converts the index so the page on
1908
+ * screen stays visible. @defaultValue false
1909
+ */
1910
+ single?: boolean;
1555
1911
  /** Called when the spread index changes (after the turn animation midpoint). */
1556
1912
  onChange?: (spreadIdx: number) => void;
1557
1913
  }
1558
1914
  /** Return value of {@link useSpread}. */
1559
1915
  interface UseSpreadReturn {
1560
- /** Current spread index. */
1916
+ /** Current navigation index: a page index in single mode, a spread index otherwise. */
1561
1917
  spreadIdx: number;
1562
- /** Current spread result, or `null` until the layout is ready. */
1918
+ /** Layout spread holding the visible page(s), or `null` until the layout is ready. */
1563
1919
  spread: SpreadResult | null;
1564
- /** Total number of pages. */
1920
+ /** First page shown, in reading order. */
1921
+ firstPage: number;
1922
+ /** Index of {@link UseSpreadReturn.spread} in the layout (`ChapterLayout.getSpread`). */
1923
+ layoutSpreadIdx: number;
1924
+ /** Side of {@link UseSpreadReturn.spread} shown in single mode; `null` in double mode. */
1925
+ singleSide: 'right' | 'left' | null;
1926
+ /** Total number of pages, as of {@link UseSpreadReturn.spread}. */
1565
1927
  totalPages: number;
1566
- /** Total number of two-page spreads. */
1928
+ /** Number of navigation positions: pages in single mode, two-page spreads otherwise. */
1567
1929
  totalSpreads: number;
1568
1930
  /** Whether the turn animation is currently in flight. */
1569
1931
  turning: boolean;
1570
- /** Advance one spread forward. */
1932
+ /** Advance one position (page or spread) forward. */
1571
1933
  next: () => void;
1572
- /** Go back one spread. */
1934
+ /** Go back one position. */
1573
1935
  prev: () => void;
1574
- /** Jump to an arbitrary spread index (clamped). */
1936
+ /** Jump to an arbitrary navigation index (clamped). */
1575
1937
  goTo: (index: number) => void;
1576
1938
  /**
1577
- * Set the spread index immediately, with no page-turn animation, clamped to
1578
- * `[0, totalSpreads − 1]`. Use to restore a reading position after a reflow
1939
+ * Set the navigation index immediately, with no page-turn animation, clamped
1940
+ * to `[0, totalSpreads − 1]`. Use to restore a reading position after a reflow
1579
1941
  * re-layout (where an animated {@link goTo} would briefly flash spread 0).
1580
1942
  */
1581
1943
  setSpread: (index: number) => void;
1944
+ /** Navigation index that shows the given page index. */
1945
+ indexOfPage: (pageIdx: number) => number;
1946
+ /**
1947
+ * Anchor at the start of the text shown at navigation index `index`. A page an
1948
+ * image blocks entirely holds no text, so the anchor then comes from the next
1949
+ * page that does, even past `index`; `null` when no page from there on holds text.
1950
+ */
1951
+ anchorAt: (index: number) => InChapterAnchor | null;
1582
1952
  /** Manually refresh `spread` from `layout` at the current index. */
1583
1953
  refresh: () => void;
1584
1954
  }
@@ -1588,4 +1958,4 @@ interface UseSpreadReturn {
1588
1958
  */
1589
1959
  declare function useSpread(layout: ChapterLayout | null, options?: UseSpreadOptions): UseSpreadReturn;
1590
1960
 
1591
- export { type AnnotationsStorage, type EditableEpubSelection, type EpubProjectChapterDraft, type ImageRect, type ManuscriptEditorChapter, type ManuscriptPageDimensions, type ManuscriptPreviewProps, MejiroChapterNav, type MejiroChapterNavMode, type MejiroChapterNavProps, type MejiroChapterNavVariant, MejiroDropZone, type MejiroDropZoneProps, MejiroEditor, type MejiroEditorProps, type MejiroExportPolicy, MejiroI18nProvider, MejiroImageOverlay, type MejiroImageOverlayProps, MejiroManuscriptEditor, type MejiroManuscriptEditorProps, MejiroNotationHighlighter, type MejiroNotationHighlighterProps, MejiroPage, MejiroPageIndicator, type MejiroPageIndicatorProps, type MejiroPageProps, MejiroPageView, type MejiroPageViewProps, MejiroReader, type MejiroReaderControlledProps, type MejiroReaderEventMap, type MejiroReaderFileProps, type MejiroReaderFit, type MejiroReaderHandle, type MejiroReaderMode, type MejiroReaderProps, type MejiroReaderSettingsSlot, type MejiroReaderUrlProps, MejiroScrollView, type MejiroScrollViewProps, MejiroSelectionLayer, type MejiroSelectionLayerProps, MejiroSettingsPanel, type MejiroSettingsPanelProps, MejiroShelf, type MejiroShelfProps, MejiroSpread, type MejiroSpreadMode, type MejiroSpreadProps, MejiroStats, type MejiroStatsProps, type MejiroTheme, type MejiroThemeName, MejiroToc, type MejiroTocProps, type MultiImageItem, type PageDimensions, type PageNumberDisplay, type ReadingPosition, type ReadingPositionStorage, type UseAnnotationsOptions, type UseAnnotationsReturn, type UseChapterLayoutOptions, type UseChapterLayoutReturn, type UseEditableEpubOptions, type UseEditableEpubReturn, type UseEpubOptions, type UseEpubProjectOptions, type UseEpubProjectReturn, type UseEpubReturn, type UseI18nOptions, type UseImageOverlayOptions, type UseImageOverlayReturn, type UseLibraryOptions, type UseLibraryReturn, type UseManuscriptDraftOptions, type UseManuscriptDraftReturn, type UseManuscriptLayoutOptions, type UseManuscriptLayoutReturn, type UseMejiroBookReturn, type UseMultiImageOverlayOptions, type UseMultiImageOverlayReturn, type UseReadingPositionOptions, type UseReadingPositionReturn, type UseSpreadOptions, type UseSpreadReturn, type VolumeInfo, format, resolveMessages, useAnnotations, useChapterLayout, useEditableEpub, useEpub, useEpubProject, useI18n, useImageOverlay, useLibrary, useManuscriptDraft, useManuscriptLayout, useMejiroBook, useMultiImageOverlay, useReadingPosition, useSpread };
1961
+ export { type AnnotationsStorage, type EpubProjectChapterDraft, type ImageRect, type ManuscriptAutosaveDraft, type ManuscriptEditorChapter, type ManuscriptPageDimensions, type ManuscriptPreviewProps, type ManuscriptRecomputeOptions, MejiroChapterNav, type MejiroChapterNavMode, type MejiroChapterNavProps, type MejiroChapterNavVariant, MejiroDropZone, type MejiroDropZoneProps, MejiroEditor, type MejiroEditorProps, type MejiroExportPolicy, MejiroI18nProvider, MejiroImageOverlay, type MejiroImageOverlayProps, MejiroManuscriptEditor, type MejiroManuscriptEditorProps, MejiroNotationHighlighter, type MejiroNotationHighlighterProps, MejiroPage, MejiroPageIndicator, type MejiroPageIndicatorProps, type MejiroPageProps, MejiroPageView, type MejiroPageViewProps, MejiroReader, type MejiroReaderCommonProps, type MejiroReaderControlledProps, type MejiroReaderEventMap, type MejiroReaderFileProps, type MejiroReaderFit, type MejiroReaderHandle, type MejiroReaderManuscriptProps, type MejiroReaderMode, type MejiroReaderProps, type MejiroReaderSettingsSlot, type MejiroReaderUrlProps, MejiroScrollView, type MejiroScrollViewProps, MejiroSelectionLayer, type MejiroSelectionLayerProps, MejiroSettingsPanel, type MejiroSettingsPanelProps, MejiroShelf, type MejiroShelfProps, MejiroSpread, type MejiroSpreadMode, type MejiroSpreadProps, MejiroStats, type MejiroStatsProps, type MejiroTheme, type MejiroThemeName, MejiroToc, type MejiroTocProps, type MultiImageItem, type PageDimensions, type PageNumberDisplay, type ReadingPosition, type ReadingPositionStorage, type RecomputeOptions, type UseAnnotationsOptions, type UseAnnotationsReturn, type UseChapterLayoutOptions, type UseChapterLayoutReturn, type UseEditableEpubOptions, type UseEditableEpubReturn, type UseEpubOptions, type UseEpubProjectOptions, type UseEpubProjectReturn, type UseEpubReturn, type UseI18nOptions, type UseImageOverlayOptions, type UseImageOverlayReturn, type UseLibraryOptions, type UseLibraryReturn, type UseManuscriptDraftOptions, type UseManuscriptDraftReturn, type UseManuscriptLayoutOptions, type UseManuscriptLayoutReturn, type UseMejiroBookOptions, type UseMejiroBookReturn, type UseMultiImageOverlayOptions, type UseMultiImageOverlayReturn, type UseReadingPositionOptions, type UseReadingPositionReturn, type UseSpreadOptions, type UseSpreadReturn, type VolumeInfo, format, resolveMessages, useAnnotations, useChapterLayout, useEditableEpub, useEpub, useEpubProject, useI18n, useImageOverlay, useLibrary, useManuscriptDraft, useManuscriptLayout, useMejiroBook, useMultiImageOverlay, useReadingPosition, useSpread };