@libraz/mejiro-react 0.5.0 → 0.7.0
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.
- package/README.md +11 -0
- package/dist/index.d.ts +350 -373
- package/dist/index.js +853 -721
- package/package.json +7 -6
package/dist/index.d.ts
CHANGED
|
@@ -1,139 +1,12 @@
|
|
|
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
3
|
import * as react from 'react';
|
|
2
4
|
import { ReactNode, CSSProperties, PointerEvent, TextareaHTMLAttributes, RefObject } from 'react';
|
|
3
5
|
import { EpubBook, AssetResolver, EditableEpub, ManuscriptDialect, EpubChapter, EditableEpubBook, AnnotatedParagraph, AddImageInput, EditableEpubImage, EpubExportOptions, EpubProjectMetadata, EpubProject } from '@libraz/mejiro/epub';
|
|
4
|
-
import {
|
|
6
|
+
import { ChapterLayout, SpreadResult, BookOptions, ComputePageSizeOptions, InChapterAnchor, ReadingAnchor, ManuscriptChapter, PageResult, AnchorRect, AnchorRange, MejiroBook } from '@libraz/mejiro/book';
|
|
5
7
|
import { RenderPage } from '@libraz/mejiro/render';
|
|
6
8
|
import { FontFamily, InlineAnnotation } from '@libraz/mejiro/browser';
|
|
7
9
|
|
|
8
|
-
/** All UI strings rendered by the bundled React components. */
|
|
9
|
-
interface MejiroMessages {
|
|
10
|
-
/** Logo subtitle. */
|
|
11
|
-
readonly logoSubtitle: string;
|
|
12
|
-
/** Header "Open" button label. */
|
|
13
|
-
readonly openButton: string;
|
|
14
|
-
/** Header "Settings" button label. */
|
|
15
|
-
readonly settingsButton: string;
|
|
16
|
-
/** Header "Image" overlay button label. */
|
|
17
|
-
readonly imageButton: string;
|
|
18
|
-
/** ARIA label for removing an image overlay. */
|
|
19
|
-
readonly imageRemoveButton: string;
|
|
20
|
-
/** Loading-state body text. */
|
|
21
|
-
readonly loading: string;
|
|
22
|
-
/** ARIA label for the previous-spread nav zone. */
|
|
23
|
-
readonly prevSpread: string;
|
|
24
|
-
/** ARIA label for the next-spread nav zone. */
|
|
25
|
-
readonly nextSpread: string;
|
|
26
|
-
/** Settings panel group title — Font. */
|
|
27
|
-
readonly settingsFont: string;
|
|
28
|
-
/** Settings panel font-size label. */
|
|
29
|
-
readonly settingsSize: string;
|
|
30
|
-
/** Settings panel "decrease font size" button. */
|
|
31
|
-
readonly settingsSizeDown: string;
|
|
32
|
-
/** Settings panel "increase font size" button. */
|
|
33
|
-
readonly settingsSizeUp: string;
|
|
34
|
-
/** Settings panel group title — Layout. */
|
|
35
|
-
readonly settingsLayout: string;
|
|
36
|
-
/** Settings panel kinsoku label. */
|
|
37
|
-
readonly settingsKinsoku: string;
|
|
38
|
-
/** Settings panel hanging-punctuation label. */
|
|
39
|
-
readonly settingsHanging: string;
|
|
40
|
-
/** Settings panel line-spacing label. */
|
|
41
|
-
readonly settingsLineSpacing: string;
|
|
42
|
-
/** Settings panel "strict" kinsoku option. */
|
|
43
|
-
readonly settingsStrict: string;
|
|
44
|
-
/** Settings panel "loose" kinsoku option. */
|
|
45
|
-
readonly settingsLoose: string;
|
|
46
|
-
/** Settings panel "on" toggle option. */
|
|
47
|
-
readonly toggleOn: string;
|
|
48
|
-
/** Settings panel "off" toggle option. */
|
|
49
|
-
readonly toggleOff: string;
|
|
50
|
-
/** Drop zone primary text. */
|
|
51
|
-
readonly dropZoneTitle: string;
|
|
52
|
-
/** Drop zone secondary hint. */
|
|
53
|
-
readonly dropZoneHint: string;
|
|
54
|
-
/** TOC heading. */
|
|
55
|
-
readonly tocTitle: string;
|
|
56
|
-
/** TOC search placeholder. */
|
|
57
|
-
readonly tocSearchPlaceholder: string;
|
|
58
|
-
/** TOC empty-results template. Placeholder `{query}` is replaced. */
|
|
59
|
-
readonly tocEmpty: string;
|
|
60
|
-
/** Shelf heading. */
|
|
61
|
-
readonly shelfTitle: string;
|
|
62
|
-
/** Generic chapter-N template. Placeholder `{n}` is replaced. */
|
|
63
|
-
readonly chapterN: string;
|
|
64
|
-
/** Aria-live announcement template. Placeholders: `{spread}`, `{total}`. */
|
|
65
|
-
readonly spreadAnnouncement: string;
|
|
66
|
-
/** Embedded EPUB editor preview subtitle. */
|
|
67
|
-
readonly editorPreviewSubtitle: string;
|
|
68
|
-
/** EPUB editor panel title. */
|
|
69
|
-
readonly editorTitle: string;
|
|
70
|
-
/** EPUB editor empty-state title. */
|
|
71
|
-
readonly editorNoBookLoaded: string;
|
|
72
|
-
/** EPUB editor paragraph list section label. */
|
|
73
|
-
readonly editorParagraphs: string;
|
|
74
|
-
/** EPUB editor proofread section label. */
|
|
75
|
-
readonly editorProofread: string;
|
|
76
|
-
/** EPUB editor apply-text button label. */
|
|
77
|
-
readonly editorApplyText: string;
|
|
78
|
-
/** EPUB editor ruby section label. */
|
|
79
|
-
readonly editorRuby: string;
|
|
80
|
-
/** EPUB editor ruby usage hint. */
|
|
81
|
-
readonly editorRubyHint: string;
|
|
82
|
-
/** EPUB editor ruby selected-range template. Placeholders: `{start}`, `{end}`, `{count}`. */
|
|
83
|
-
readonly editorRubyRange: string;
|
|
84
|
-
/** EPUB editor ruby input placeholder. */
|
|
85
|
-
readonly editorRubyPlaceholder: string;
|
|
86
|
-
/** EPUB editor apply-ruby button label. */
|
|
87
|
-
readonly editorApplyRuby: string;
|
|
88
|
-
/** EPUB editor image section label. */
|
|
89
|
-
readonly editorImages: string;
|
|
90
|
-
/** EPUB editor insert-image button label. */
|
|
91
|
-
readonly editorInsertImageAfterParagraph: string;
|
|
92
|
-
/** EPUB editor export button label. */
|
|
93
|
-
readonly editorExportEpub: string;
|
|
94
|
-
/** Manuscript editor preview subtitle. */
|
|
95
|
-
readonly manuscriptPreviewSubtitle: string;
|
|
96
|
-
/** Manuscript editor panel title. */
|
|
97
|
-
readonly manuscriptTitle: string;
|
|
98
|
-
/** Manuscript editor ruby notation hint. */
|
|
99
|
-
readonly manuscriptRubyHint: string;
|
|
100
|
-
/** Manuscript editor metadata section label. */
|
|
101
|
-
readonly manuscriptMetadata: string;
|
|
102
|
-
/** Manuscript editor chapters section label. */
|
|
103
|
-
readonly manuscriptChapters: string;
|
|
104
|
-
/** Manuscript editor draft section label. */
|
|
105
|
-
readonly manuscriptDraft: string;
|
|
106
|
-
/** Manuscript editor cover chooser label. */
|
|
107
|
-
readonly manuscriptChooseCoverImage: string;
|
|
108
|
-
/** Manuscript editor default book title. */
|
|
109
|
-
readonly manuscriptDefaultTitle: string;
|
|
110
|
-
/** Manuscript editor default chapter title template. Placeholder `{n}` is replaced. */
|
|
111
|
-
readonly manuscriptDefaultChapterTitle: string;
|
|
112
|
-
/** Manuscript editor default draft body. */
|
|
113
|
-
readonly manuscriptDefaultBody: string;
|
|
114
|
-
/** Generic untitled fallback. */
|
|
115
|
-
readonly untitled: string;
|
|
116
|
-
/** Manuscript editor add-chapter button label. */
|
|
117
|
-
readonly manuscriptAddChapter: string;
|
|
118
|
-
/** Manuscript editor remove-chapter button label. */
|
|
119
|
-
readonly manuscriptRemove: string;
|
|
120
|
-
/** Manuscript editor emphasis-dots button label. */
|
|
121
|
-
readonly manuscriptEmphasisDots: string;
|
|
122
|
-
/** Manuscript editor tate-chu-yoko button label. */
|
|
123
|
-
readonly manuscriptTcy: string;
|
|
124
|
-
/** Manuscript editor emphasis button label. */
|
|
125
|
-
readonly manuscriptEm: string;
|
|
126
|
-
/** Manuscript editor strong button label. */
|
|
127
|
-
readonly manuscriptStrong: string;
|
|
128
|
-
/** ARIA label for the chapter drag handle. Placeholders: `{title}`. */
|
|
129
|
-
readonly manuscriptReorderHandle: string;
|
|
130
|
-
}
|
|
131
|
-
/** Built-in English catalog (the default). */
|
|
132
|
-
declare const enMessages: MejiroMessages;
|
|
133
|
-
/** Built-in Japanese catalog. */
|
|
134
|
-
declare const jaMessages: MejiroMessages;
|
|
135
|
-
/** Built-in locale identifiers. */
|
|
136
|
-
type MejiroLocale = 'en' | 'ja';
|
|
137
10
|
/** Provider that scopes a message catalog to its descendants. */
|
|
138
11
|
declare function MejiroI18nProvider({ locale, messages, children, }: {
|
|
139
12
|
locale?: MejiroLocale;
|
|
@@ -200,15 +73,6 @@ interface MejiroDropZoneProps {
|
|
|
200
73
|
*/
|
|
201
74
|
declare function MejiroDropZone({ accept, validateFile, onFile, children, className, style, }: MejiroDropZoneProps): ReactNode;
|
|
202
75
|
|
|
203
|
-
/** A font choice shown in the settings panel. */
|
|
204
|
-
interface FontChoice {
|
|
205
|
-
/** CSS `font-family` value applied to the book. */
|
|
206
|
-
value: string;
|
|
207
|
-
/** Human-readable label. */
|
|
208
|
-
label: string;
|
|
209
|
-
}
|
|
210
|
-
/** Subset of {@link BookOptions} editable from the panel. */
|
|
211
|
-
type EditableSettings = Pick<BookOptions, 'fontFamily' | 'fontSize' | 'lineSpacing' | 'mode' | 'enableHanging'>;
|
|
212
76
|
/** Props for {@link MejiroSettingsPanel}. */
|
|
213
77
|
interface MejiroSettingsPanelProps {
|
|
214
78
|
/** Whether the panel is expanded. */
|
|
@@ -382,177 +246,6 @@ interface MejiroImageOverlayProps {
|
|
|
382
246
|
*/
|
|
383
247
|
declare function MejiroImageOverlay({ rect, label, onOverlayPointerDown, onResizePointerDown, onClose, }: MejiroImageOverlayProps): ReactNode;
|
|
384
248
|
|
|
385
|
-
interface ManuscriptEditorChapter {
|
|
386
|
-
id: string;
|
|
387
|
-
title: string;
|
|
388
|
-
body: string;
|
|
389
|
-
}
|
|
390
|
-
/**
|
|
391
|
-
* Subset of {@link MejiroReader} props that the manuscript editor passes
|
|
392
|
-
* through to the live preview. Properties driven by the editor itself
|
|
393
|
-
* (`manuscript`, `fonts`, `chapter`, `onChapterChange`) are ignored if
|
|
394
|
-
* supplied here.
|
|
395
|
-
*/
|
|
396
|
-
interface ManuscriptPreviewProps {
|
|
397
|
-
subtitle?: string;
|
|
398
|
-
title?: string;
|
|
399
|
-
chapterNavMode?: 'select' | 'panel' | 'both' | 'none';
|
|
400
|
-
enableHeader?: boolean;
|
|
401
|
-
enableChapterNav?: boolean;
|
|
402
|
-
enableSettings?: boolean;
|
|
403
|
-
enableStats?: boolean;
|
|
404
|
-
enableKeyboard?: boolean;
|
|
405
|
-
enablePageIndicator?: boolean;
|
|
406
|
-
/**
|
|
407
|
-
* Toggle the surface-tap chrome-hide behavior of the embedded reader.
|
|
408
|
-
* Defaults to `false` here (the editor's preview is part of a side-by-side
|
|
409
|
-
* authoring workflow where tap-to-hide would surprise the author). Set
|
|
410
|
-
* to `true` to demo the fullscreen-reader behavior.
|
|
411
|
-
*/
|
|
412
|
-
enableSurfaceTap?: boolean;
|
|
413
|
-
bare?: boolean;
|
|
414
|
-
}
|
|
415
|
-
interface MejiroManuscriptEditorProps {
|
|
416
|
-
/** Font choices passed to the preview reader. */
|
|
417
|
-
fonts?: FontChoice[];
|
|
418
|
-
/**
|
|
419
|
-
* Title. When `onTitleChange` is supplied, this is the controlled value
|
|
420
|
-
* (changes propagate from parent to the input). Otherwise it is the
|
|
421
|
-
* initial value and the editor manages its own title state.
|
|
422
|
-
*/
|
|
423
|
-
title?: string;
|
|
424
|
-
/** Called whenever the title input changes. Enables controlled mode. */
|
|
425
|
-
onTitleChange?: (title: string) => void;
|
|
426
|
-
/**
|
|
427
|
-
* Author. Controlled when `onAuthorChange` is supplied; otherwise treated
|
|
428
|
-
* as the initial value.
|
|
429
|
-
*/
|
|
430
|
-
author?: string;
|
|
431
|
-
/** Called whenever the author input changes. Enables controlled mode. */
|
|
432
|
-
onAuthorChange?: (author: string) => void;
|
|
433
|
-
/**
|
|
434
|
-
* Cover image. Controlled when `onCoverChange` is supplied; otherwise
|
|
435
|
-
* treated as the initial cover. Setting `null` clears the cover.
|
|
436
|
-
*/
|
|
437
|
-
cover?: File | null;
|
|
438
|
-
/** Called whenever the cover changes. Enables controlled mode. */
|
|
439
|
-
onCoverChange?: (cover: File | null) => void;
|
|
440
|
-
/** Initial chapters. */
|
|
441
|
-
chapters?: ManuscriptEditorChapter[];
|
|
442
|
-
/**
|
|
443
|
-
* Called whenever the chapter draft settles (debounced by
|
|
444
|
-
* {@link MejiroManuscriptEditorProps.autosaveDelay}). Use to persist drafts
|
|
445
|
-
* to localStorage, IndexedDB, or upload to a server.
|
|
446
|
-
*/
|
|
447
|
-
onAutosave?: (chapters: ManuscriptEditorChapter[]) => void | Promise<void>;
|
|
448
|
-
/** Autosave debounce in milliseconds. @defaultValue 800 */
|
|
449
|
-
autosaveDelay?: number;
|
|
450
|
-
/**
|
|
451
|
-
* Props forwarded to the embedded {@link MejiroReader} preview. Lets
|
|
452
|
-
* hosts customize subtitle / chapterNavMode / etc.; `manuscript`, `fonts`,
|
|
453
|
-
* `chapter`, and `onChapterChange` remain driven by the editor.
|
|
454
|
-
*/
|
|
455
|
-
previewProps?: ManuscriptPreviewProps;
|
|
456
|
-
/**
|
|
457
|
-
* Resolves URL-only project assets (e.g. covers/illustrations registered as
|
|
458
|
-
* `{ url, ... }`) into bytes at export time. Forwarded to `project.export()`
|
|
459
|
-
* so authors can register signed-URL references without holding raw bytes
|
|
460
|
-
* client-side until publish.
|
|
461
|
-
*/
|
|
462
|
-
assetResolver?: AssetResolver;
|
|
463
|
-
/** Called after export completes. */
|
|
464
|
-
onExport?: (buffer: ArrayBuffer) => void;
|
|
465
|
-
}
|
|
466
|
-
/** Manuscript-to-EPUB editor for author drafts from posting sites. */
|
|
467
|
-
declare function MejiroManuscriptEditor({ fonts, title: titleProp, onTitleChange, author: authorProp, onAuthorChange, cover: coverProp, onCoverChange, chapters: initialChapters, onAutosave, autosaveDelay, previewProps, assetResolver, onExport, }: MejiroManuscriptEditorProps): ReactNode;
|
|
468
|
-
|
|
469
|
-
/** Props for {@link MejiroNotationHighlighter}. */
|
|
470
|
-
interface MejiroNotationHighlighterProps extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'value' | 'onChange'> {
|
|
471
|
-
/** Source manuscript text. */
|
|
472
|
-
value: string;
|
|
473
|
-
/** Called whenever the textarea content changes. */
|
|
474
|
-
onChange: (next: string) => void;
|
|
475
|
-
/** Manuscript notation dialect. @defaultValue `'mejiro'` */
|
|
476
|
-
dialect?: ManuscriptDialect;
|
|
477
|
-
/** Class applied to the wrapper element. */
|
|
478
|
-
wrapperClassName?: string;
|
|
479
|
-
/** Inline style on the wrapper element. */
|
|
480
|
-
wrapperStyle?: CSSProperties;
|
|
481
|
-
}
|
|
482
|
-
/**
|
|
483
|
-
* Textarea with a notation-highlight overlay. The overlay sits *behind* the
|
|
484
|
-
* textarea and tints the background of manuscript notation tokens (ruby,
|
|
485
|
-
* emphasis dots, tate-chu-yoko, em / strong, links, footnotes) so authors can
|
|
486
|
-
* see at a glance which characters carry notation.
|
|
487
|
-
*
|
|
488
|
-
* The textarea is fully interactive; selection, undo / redo, and the
|
|
489
|
-
* browser-native caret are unaffected. Notation kinds are exposed via
|
|
490
|
-
* `data-token` attributes on the overlay spans so hosts can restyle them via
|
|
491
|
-
* CSS (`.mejiro-notation-token[data-token="ruby"]` etc.).
|
|
492
|
-
*/
|
|
493
|
-
declare const MejiroNotationHighlighter: react.ForwardRefExoticComponent<MejiroNotationHighlighterProps & react.RefAttributes<HTMLTextAreaElement>>;
|
|
494
|
-
|
|
495
|
-
/** Props for the MejiroPage component. */
|
|
496
|
-
interface MejiroPageProps {
|
|
497
|
-
/** Render page data from `buildRenderPage()`. */
|
|
498
|
-
page: RenderPage;
|
|
499
|
-
/** Additional CSS class name for the root element. */
|
|
500
|
-
className?: string;
|
|
501
|
-
/** Additional inline styles for the root element. */
|
|
502
|
-
style?: CSSProperties;
|
|
503
|
-
}
|
|
504
|
-
/**
|
|
505
|
-
* Renders a mejiro page with vertical text layout.
|
|
506
|
-
*
|
|
507
|
-
* Converts a `RenderPage` data structure into DOM elements using
|
|
508
|
-
* `mejiro-` prefixed CSS classes for layout.
|
|
509
|
-
*/
|
|
510
|
-
declare function MejiroPage({ page, className, style }: MejiroPageProps): ReactNode;
|
|
511
|
-
|
|
512
|
-
/** Props for {@link MejiroPageIndicator}. */
|
|
513
|
-
interface MejiroPageIndicatorProps {
|
|
514
|
-
/** Current spread (1-based). */
|
|
515
|
-
current: number;
|
|
516
|
-
/** Total number of spreads. */
|
|
517
|
-
total: number;
|
|
518
|
-
}
|
|
519
|
-
/** Displays "current / total" spread position under the book. */
|
|
520
|
-
declare function MejiroPageIndicator({ current, total }: MejiroPageIndicatorProps): ReactNode;
|
|
521
|
-
|
|
522
|
-
/** Props for the MejiroPageView component. */
|
|
523
|
-
interface MejiroPageViewProps {
|
|
524
|
-
/** Page result from {@link ChapterLayout.getSpread} or {@link ChapterLayout.getPage}. */
|
|
525
|
-
result: PageResult;
|
|
526
|
-
/** CSS font family for slot-based rendering (used when images are present). */
|
|
527
|
-
fontFamily?: FontFamily;
|
|
528
|
-
/** Line spacing multiplier for slot-based rendering (used when images are present). */
|
|
529
|
-
lineSpacing?: number;
|
|
530
|
-
/**
|
|
531
|
-
* Force slot-based rendering even when `result.hasImages` is false.
|
|
532
|
-
* Set to `true` when the layout has images on any spread, so that
|
|
533
|
-
* all pages use consistent slot-based rendering.
|
|
534
|
-
*/
|
|
535
|
-
slotMode?: boolean;
|
|
536
|
-
/** Additional CSS class name for the root element. */
|
|
537
|
-
className?: string;
|
|
538
|
-
/** Additional inline styles for the root element. */
|
|
539
|
-
style?: CSSProperties;
|
|
540
|
-
}
|
|
541
|
-
/**
|
|
542
|
-
* Renders a page from a {@link PageResult}.
|
|
543
|
-
*
|
|
544
|
-
* Automatically selects the rendering strategy:
|
|
545
|
-
* - **Normal mode** (no images): Uses CSS `writing-mode: vertical-rl` via `<MejiroPage>`.
|
|
546
|
-
* - **Slot mode** (images present): Uses absolute-positioned columns with per-line sizing.
|
|
547
|
-
*
|
|
548
|
-
* @example
|
|
549
|
-
* ```tsx
|
|
550
|
-
* const spread = layout.getSpread(0);
|
|
551
|
-
* <MejiroPageView result={spread.right} fontFamily="serif" lineSpacing={1.8} />
|
|
552
|
-
* ```
|
|
553
|
-
*/
|
|
554
|
-
declare function MejiroPageView({ result, fontFamily, lineSpacing, slotMode, className, style, }: MejiroPageViewProps): ReactNode;
|
|
555
|
-
|
|
556
249
|
type MejiroChapterNavMode = 'select' | 'panel' | 'both' | 'none';
|
|
557
250
|
/**
|
|
558
251
|
* Reading-flow mode for {@link MejiroReader}.
|
|
@@ -567,6 +260,22 @@ type MejiroReaderMode = 'paginated' | 'scroll';
|
|
|
567
260
|
* - `auto` — switch based on the surface aspect ratio (single when portrait).
|
|
568
261
|
*/
|
|
569
262
|
type MejiroSpreadMode = 'double' | 'single' | 'auto';
|
|
263
|
+
/**
|
|
264
|
+
* Which page of a spread prints its page number: `'both'` (right = odd,
|
|
265
|
+
* left = even), only `'right'`, only `'left'`, or `'none'`.
|
|
266
|
+
*/
|
|
267
|
+
type PageNumberDisplay = 'both' | 'right' | 'left' | 'none';
|
|
268
|
+
/**
|
|
269
|
+
* How the reader sizes itself inside its container.
|
|
270
|
+
* - `fill` — fill the container's given height; the spread is fitted inside it,
|
|
271
|
+
* letterboxing if the box aspect doesn't match the spread (the default; the
|
|
272
|
+
* host must give the reader a height).
|
|
273
|
+
* - `width` — self-size from width: the reader derives its own height from its
|
|
274
|
+
* measured width and the page aspect ratio, so the spread fills exactly with
|
|
275
|
+
* no letterbox and the host needs no height/aspect magic numbers. The host
|
|
276
|
+
* only constrains the width.
|
|
277
|
+
*/
|
|
278
|
+
type MejiroReaderFit = 'fill' | 'width';
|
|
570
279
|
/** Built-in reader theme presets. */
|
|
571
280
|
type MejiroThemeName = 'light' | 'dark' | 'sepia' | 'high-contrast' | 'auto';
|
|
572
281
|
/**
|
|
@@ -656,6 +365,23 @@ interface MejiroReaderHandle {
|
|
|
656
365
|
*/
|
|
657
366
|
subscribe<E extends keyof MejiroReaderEventMap>(event: E, listener: MejiroReaderEventMap[E]): () => void;
|
|
658
367
|
}
|
|
368
|
+
/**
|
|
369
|
+
* Context passed to a {@link MejiroReaderCommonProps.renderSettings} render prop.
|
|
370
|
+
*
|
|
371
|
+
* Lets a host replace the built-in settings controls with its own UI while
|
|
372
|
+
* keeping the panel chrome and its open/close accordion. All fields are wired
|
|
373
|
+
* to the live reader.
|
|
374
|
+
*/
|
|
375
|
+
interface MejiroReaderSettingsSlot {
|
|
376
|
+
/** Current effective settings (font, size, line spacing, kinsoku, hanging). */
|
|
377
|
+
settings: EditableSettings;
|
|
378
|
+
/** Applies a partial settings change and re-flows the chapter. */
|
|
379
|
+
update: (partial: Partial<BookOptions>) => void;
|
|
380
|
+
/** Whether the settings panel is currently open. */
|
|
381
|
+
open: boolean;
|
|
382
|
+
/** Toggles the settings panel open/closed (same as the header button). */
|
|
383
|
+
toggle: () => void;
|
|
384
|
+
}
|
|
659
385
|
/** Props shared across every {@link MejiroReader} source mode. */
|
|
660
386
|
interface MejiroReaderCommonProps {
|
|
661
387
|
/**
|
|
@@ -667,7 +393,16 @@ interface MejiroReaderCommonProps {
|
|
|
667
393
|
* { ...DEFAULT_BOOK_OPTIONS, fontFamily: '"Noto Serif JP"', fontSize: 18 }
|
|
668
394
|
* ```
|
|
669
395
|
*/
|
|
670
|
-
options?: BookOptions
|
|
396
|
+
options?: Partial<BookOptions>;
|
|
397
|
+
/**
|
|
398
|
+
* Page-geometry overrides forwarded to `MejiroBook.computePageSize`. Use to
|
|
399
|
+
* tune how the spread is sized inside the surface — most usefully to shrink
|
|
400
|
+
* the reserved margins so the pages fill their frame, e.g.
|
|
401
|
+
* `pageGeometry={{ gutterOffset: 0, headerOffset: 0 }}`. Also accepts
|
|
402
|
+
* `aspect`, `minWidth`, `minHeight`, `maxHeight`, and inner `padding`; omitted
|
|
403
|
+
* fields fall back to the built-in defaults.
|
|
404
|
+
*/
|
|
405
|
+
pageGeometry?: ComputePageSizeOptions;
|
|
671
406
|
/** Font choices for the settings panel. */
|
|
672
407
|
fonts?: FontChoice[];
|
|
673
408
|
/**
|
|
@@ -699,6 +434,16 @@ interface MejiroReaderCommonProps {
|
|
|
699
434
|
* only the right page; `auto` flips to `single` for portrait viewports.
|
|
700
435
|
*/
|
|
701
436
|
spreadMode?: MejiroSpreadMode;
|
|
437
|
+
/**
|
|
438
|
+
* How the reader sizes itself in its container. `fill` (default) fills the
|
|
439
|
+
* container height and letterboxes the spread; `width` makes the reader
|
|
440
|
+
* self-size — it derives its height from its width and the page aspect, so an
|
|
441
|
+
* embedding host only has to constrain the width (no height/aspect magic
|
|
442
|
+
* numbers, no letterbox). In `width` mode the reserved `gutterOffset` /
|
|
443
|
+
* `headerOffset` default to 0 so the spread fills edge-to-edge; override via
|
|
444
|
+
* {@link MejiroReaderProps.pageGeometry} if you still want them. @defaultValue 'fill'
|
|
445
|
+
*/
|
|
446
|
+
fit?: MejiroReaderFit;
|
|
702
447
|
/**
|
|
703
448
|
* Enable surface-tap chrome toggling. Tapping the center of the spread
|
|
704
449
|
* (away from buttons) hides the header and chapter panel; tapping again
|
|
@@ -769,6 +514,15 @@ interface MejiroReaderCommonProps {
|
|
|
769
514
|
chapterNavMode?: MejiroChapterNavMode;
|
|
770
515
|
/** Show the settings panel toggle. @defaultValue `!bare` */
|
|
771
516
|
enableSettings?: boolean;
|
|
517
|
+
/**
|
|
518
|
+
* Replaces the built-in settings controls with custom UI while keeping the
|
|
519
|
+
* panel chrome and its open/close accordion. Receives a
|
|
520
|
+
* {@link MejiroReaderSettingsSlot} wired to the live reader, so a host can
|
|
521
|
+
* build its own settings form without a parallel `options` shadow. The header
|
|
522
|
+
* "Settings" button still toggles the panel. `enableSettings` remains the
|
|
523
|
+
* on/off switch.
|
|
524
|
+
*/
|
|
525
|
+
renderSettings?: (slot: MejiroReaderSettingsSlot) => ReactNode;
|
|
772
526
|
/** Show the image-overlay editing/demo button. @defaultValue false */
|
|
773
527
|
enableImageOverlay?: boolean;
|
|
774
528
|
/** Show the stats line. @defaultValue `!bare` */
|
|
@@ -777,6 +531,14 @@ interface MejiroReaderCommonProps {
|
|
|
777
531
|
enableKeyboard?: boolean;
|
|
778
532
|
/** Show the "n / total" indicator. @defaultValue `!bare` */
|
|
779
533
|
enablePageIndicator?: boolean;
|
|
534
|
+
/**
|
|
535
|
+
* Which page of a spread shows its page number in the running head.
|
|
536
|
+
* `'both'` numbers each page (right = odd, left = even), `'right'` /
|
|
537
|
+
* `'left'` number only that side, `'none'` hides them (the
|
|
538
|
+
* {@link MejiroReaderProps.enablePageIndicator} "n / total" badge is
|
|
539
|
+
* independent). @defaultValue 'both'
|
|
540
|
+
*/
|
|
541
|
+
pageNumbers?: PageNumberDisplay;
|
|
780
542
|
/**
|
|
781
543
|
* Reader-side annotations to render as highlights. Each annotation whose
|
|
782
544
|
* `chapter` matches the current chapter is converted to spread-local
|
|
@@ -863,6 +625,190 @@ interface MejiroReaderManuscriptProps extends MejiroReaderCommonProps {
|
|
|
863
625
|
type MejiroReaderProps = MejiroReaderControlledProps | MejiroReaderUrlProps | MejiroReaderFileProps | MejiroReaderManuscriptProps;
|
|
864
626
|
declare const MejiroReader: react.ForwardRefExoticComponent<MejiroReaderProps & react.RefAttributes<MejiroReaderHandle>>;
|
|
865
627
|
|
|
628
|
+
interface ManuscriptEditorChapter {
|
|
629
|
+
id: string;
|
|
630
|
+
title: string;
|
|
631
|
+
body: string;
|
|
632
|
+
}
|
|
633
|
+
/** Autosave payload emitted by {@link MejiroManuscriptEditor}. */
|
|
634
|
+
interface ManuscriptAutosaveDraft {
|
|
635
|
+
title: string;
|
|
636
|
+
author: string;
|
|
637
|
+
cover: File | null;
|
|
638
|
+
chapters: ManuscriptEditorChapter[];
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Subset of {@link MejiroReader} props that the manuscript editor passes
|
|
642
|
+
* through to the live preview. Properties driven by the editor itself
|
|
643
|
+
* (`manuscript`, `fonts`, `chapter`, `onChapterChange`) are ignored if
|
|
644
|
+
* supplied here.
|
|
645
|
+
*/
|
|
646
|
+
interface ManuscriptPreviewProps {
|
|
647
|
+
subtitle?: string;
|
|
648
|
+
title?: string;
|
|
649
|
+
chapterNavMode?: 'select' | 'panel' | 'both' | 'none';
|
|
650
|
+
enableHeader?: boolean;
|
|
651
|
+
enableChapterNav?: boolean;
|
|
652
|
+
enableSettings?: boolean;
|
|
653
|
+
enableStats?: boolean;
|
|
654
|
+
enableKeyboard?: boolean;
|
|
655
|
+
enablePageIndicator?: boolean;
|
|
656
|
+
/** Book options forwarded to the embedded reader preview. */
|
|
657
|
+
options?: Partial<BookOptions>;
|
|
658
|
+
/** Theme forwarded to the embedded reader preview. */
|
|
659
|
+
theme?: MejiroTheme;
|
|
660
|
+
/** Custom settings controls forwarded to the embedded reader preview. */
|
|
661
|
+
renderSettings?: (slot: MejiroReaderSettingsSlot) => ReactNode;
|
|
662
|
+
/**
|
|
663
|
+
* Toggle the surface-tap chrome-hide behavior of the embedded reader.
|
|
664
|
+
* Defaults to `false` here (the editor's preview is part of a side-by-side
|
|
665
|
+
* authoring workflow where tap-to-hide would surprise the author). Set
|
|
666
|
+
* to `true` to demo the fullscreen-reader behavior.
|
|
667
|
+
*/
|
|
668
|
+
enableSurfaceTap?: boolean;
|
|
669
|
+
bare?: boolean;
|
|
670
|
+
}
|
|
671
|
+
interface MejiroManuscriptEditorProps {
|
|
672
|
+
/** Font choices passed to the preview reader. */
|
|
673
|
+
fonts?: FontChoice[];
|
|
674
|
+
/**
|
|
675
|
+
* Title. When `onTitleChange` is supplied, this is the controlled value
|
|
676
|
+
* (changes propagate from parent to the input). Otherwise it is the
|
|
677
|
+
* initial value and the editor manages its own title state.
|
|
678
|
+
*/
|
|
679
|
+
title?: string;
|
|
680
|
+
/** Called whenever the title input changes. Enables controlled mode. */
|
|
681
|
+
onTitleChange?: (title: string) => void;
|
|
682
|
+
/**
|
|
683
|
+
* Author. Controlled when `onAuthorChange` is supplied; otherwise treated
|
|
684
|
+
* as the initial value.
|
|
685
|
+
*/
|
|
686
|
+
author?: string;
|
|
687
|
+
/** Called whenever the author input changes. Enables controlled mode. */
|
|
688
|
+
onAuthorChange?: (author: string) => void;
|
|
689
|
+
/**
|
|
690
|
+
* Cover image. Controlled when `onCoverChange` is supplied; otherwise
|
|
691
|
+
* treated as the initial cover. Setting `null` clears the cover.
|
|
692
|
+
*/
|
|
693
|
+
cover?: File | null;
|
|
694
|
+
/** Called whenever the cover changes. Enables controlled mode. */
|
|
695
|
+
onCoverChange?: (cover: File | null) => void;
|
|
696
|
+
/** Initial chapters. */
|
|
697
|
+
chapters?: ManuscriptEditorChapter[];
|
|
698
|
+
/**
|
|
699
|
+
* Called whenever the chapter draft settles (debounced by
|
|
700
|
+
* {@link MejiroManuscriptEditorProps.autosaveDelay}). Use to persist drafts
|
|
701
|
+
* to localStorage, IndexedDB, or upload to a server.
|
|
702
|
+
*/
|
|
703
|
+
onAutosave?: (draft: ManuscriptAutosaveDraft) => void | Promise<void>;
|
|
704
|
+
/** Autosave debounce in milliseconds. @defaultValue 800 */
|
|
705
|
+
autosaveDelay?: number;
|
|
706
|
+
/**
|
|
707
|
+
* Props forwarded to the embedded {@link MejiroReader} preview. Lets
|
|
708
|
+
* hosts customize subtitle / chapterNavMode / etc.; `manuscript`, `fonts`,
|
|
709
|
+
* `chapter`, and `onChapterChange` remain driven by the editor.
|
|
710
|
+
*/
|
|
711
|
+
previewProps?: ManuscriptPreviewProps;
|
|
712
|
+
/**
|
|
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.
|
|
717
|
+
*/
|
|
718
|
+
assetResolver?: AssetResolver;
|
|
719
|
+
/** Called after export completes. */
|
|
720
|
+
onExport?: (buffer: ArrayBuffer) => void;
|
|
721
|
+
}
|
|
722
|
+
/** 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;
|
|
724
|
+
|
|
725
|
+
/** Props for {@link MejiroNotationHighlighter}. */
|
|
726
|
+
interface MejiroNotationHighlighterProps extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'value' | 'onChange'> {
|
|
727
|
+
/** Source manuscript text. */
|
|
728
|
+
value: string;
|
|
729
|
+
/** Called whenever the textarea content changes. */
|
|
730
|
+
onChange: (next: string) => void;
|
|
731
|
+
/** Manuscript notation dialect. @defaultValue `'mejiro'` */
|
|
732
|
+
dialect?: ManuscriptDialect;
|
|
733
|
+
/** Class applied to the wrapper element. */
|
|
734
|
+
wrapperClassName?: string;
|
|
735
|
+
/** Inline style on the wrapper element. */
|
|
736
|
+
wrapperStyle?: CSSProperties;
|
|
737
|
+
}
|
|
738
|
+
/**
|
|
739
|
+
* Textarea with a notation-highlight overlay. The overlay sits *behind* the
|
|
740
|
+
* textarea and tints the background of manuscript notation tokens (ruby,
|
|
741
|
+
* emphasis dots, tate-chu-yoko, em / strong, links, footnotes) so authors can
|
|
742
|
+
* see at a glance which characters carry notation.
|
|
743
|
+
*
|
|
744
|
+
* The textarea is fully interactive; selection, undo / redo, and the
|
|
745
|
+
* browser-native caret are unaffected. Notation kinds are exposed via
|
|
746
|
+
* `data-token` attributes on the overlay spans so hosts can restyle them via
|
|
747
|
+
* CSS (`.mejiro-notation-token[data-token="ruby"]` etc.).
|
|
748
|
+
*/
|
|
749
|
+
declare const MejiroNotationHighlighter: react.ForwardRefExoticComponent<MejiroNotationHighlighterProps & react.RefAttributes<HTMLTextAreaElement>>;
|
|
750
|
+
|
|
751
|
+
/** Props for the MejiroPage component. */
|
|
752
|
+
interface MejiroPageProps {
|
|
753
|
+
/** Render page data from `buildRenderPage()`. */
|
|
754
|
+
page: RenderPage;
|
|
755
|
+
/** Additional CSS class name for the root element. */
|
|
756
|
+
className?: string;
|
|
757
|
+
/** Additional inline styles for the root element. */
|
|
758
|
+
style?: CSSProperties;
|
|
759
|
+
}
|
|
760
|
+
/**
|
|
761
|
+
* Renders a mejiro page with vertical text layout.
|
|
762
|
+
*
|
|
763
|
+
* Converts a `RenderPage` data structure into DOM elements using
|
|
764
|
+
* `mejiro-` prefixed CSS classes for layout.
|
|
765
|
+
*/
|
|
766
|
+
declare function MejiroPage({ page, className, style }: MejiroPageProps): ReactNode;
|
|
767
|
+
|
|
768
|
+
/** Props for {@link MejiroPageIndicator}. */
|
|
769
|
+
interface MejiroPageIndicatorProps {
|
|
770
|
+
/** Current spread (1-based). */
|
|
771
|
+
current: number;
|
|
772
|
+
/** Total number of spreads. */
|
|
773
|
+
total: number;
|
|
774
|
+
}
|
|
775
|
+
/** Displays "current / total" spread position under the book. */
|
|
776
|
+
declare function MejiroPageIndicator({ current, total }: MejiroPageIndicatorProps): ReactNode;
|
|
777
|
+
|
|
778
|
+
/** Props for the MejiroPageView component. */
|
|
779
|
+
interface MejiroPageViewProps {
|
|
780
|
+
/** Page result from {@link ChapterLayout.getSpread} or {@link ChapterLayout.getPage}. */
|
|
781
|
+
result: PageResult;
|
|
782
|
+
/** CSS font family for slot-based rendering (used when images are present). */
|
|
783
|
+
fontFamily?: FontFamily;
|
|
784
|
+
/** Line spacing multiplier for slot-based rendering (used when images are present). */
|
|
785
|
+
lineSpacing?: number;
|
|
786
|
+
/**
|
|
787
|
+
* Force slot-based rendering even when `result.hasImages` is false.
|
|
788
|
+
* Set to `true` when the layout has images on any spread, so that
|
|
789
|
+
* all pages use consistent slot-based rendering.
|
|
790
|
+
*/
|
|
791
|
+
slotMode?: boolean;
|
|
792
|
+
/** Additional CSS class name for the root element. */
|
|
793
|
+
className?: string;
|
|
794
|
+
/** Additional inline styles for the root element. */
|
|
795
|
+
style?: CSSProperties;
|
|
796
|
+
}
|
|
797
|
+
/**
|
|
798
|
+
* Renders a page from a {@link PageResult}.
|
|
799
|
+
*
|
|
800
|
+
* Automatically selects the rendering strategy:
|
|
801
|
+
* - **Normal mode** (no images): Uses CSS `writing-mode: vertical-rl` via `<MejiroPage>`.
|
|
802
|
+
* - **Slot mode** (images present): Uses absolute-positioned columns with per-line sizing.
|
|
803
|
+
*
|
|
804
|
+
* @example
|
|
805
|
+
* ```tsx
|
|
806
|
+
* const spread = layout.getSpread(0);
|
|
807
|
+
* <MejiroPageView result={spread.right} fontFamily="serif" lineSpacing={1.8} />
|
|
808
|
+
* ```
|
|
809
|
+
*/
|
|
810
|
+
declare function MejiroPageView({ result, fontFamily, lineSpacing, slotMode, className, style, }: MejiroPageViewProps): ReactNode;
|
|
811
|
+
|
|
866
812
|
/** Props for {@link MejiroScrollView}. */
|
|
867
813
|
interface MejiroScrollViewProps {
|
|
868
814
|
/** Layout containing the pages to render. */
|
|
@@ -885,7 +831,7 @@ interface MejiroScrollViewProps {
|
|
|
885
831
|
* Visible page index reported to the parent as the user scrolls. The page
|
|
886
832
|
* with the largest intersection with the viewport is treated as visible.
|
|
887
833
|
*/
|
|
888
|
-
onVisiblePageChange?: (pageIdx: number) => void;
|
|
834
|
+
onVisiblePageChange?: (pageIdx: number, source: 'user' | 'programmatic') => void;
|
|
889
835
|
/**
|
|
890
836
|
* Target page to scroll into view. When set, the view scrolls so that the
|
|
891
837
|
* matching page sits at the top of the scroll container.
|
|
@@ -1040,13 +986,6 @@ interface UseMultiImageOverlayReturn {
|
|
|
1040
986
|
*/
|
|
1041
987
|
declare function useMultiImageOverlay(layout: ChapterLayout | null, spreadIdx: number, options?: UseMultiImageOverlayOptions): UseMultiImageOverlayReturn;
|
|
1042
988
|
|
|
1043
|
-
/** Per-page header data. */
|
|
1044
|
-
interface PageHeaderData {
|
|
1045
|
-
/** Running title (left-aligned). */
|
|
1046
|
-
title?: string;
|
|
1047
|
-
/** Page number (right-aligned). `null` hides it. */
|
|
1048
|
-
pageNumber?: number | null;
|
|
1049
|
-
}
|
|
1050
989
|
/** Props for {@link MejiroSpread}. */
|
|
1051
990
|
interface MejiroSpreadProps {
|
|
1052
991
|
/** Spread data to render. */
|
|
@@ -1168,34 +1107,8 @@ interface MejiroTocProps {
|
|
|
1168
1107
|
*/
|
|
1169
1108
|
declare function MejiroToc({ epub, currentAnchor, searchable, title, searchPlaceholder, onSelect, }: MejiroTocProps): ReactNode;
|
|
1170
1109
|
|
|
1171
|
-
/**
|
|
1172
|
-
* A user-authored annotation on a book — a half-open range of in-chapter
|
|
1173
|
-
* anchors plus optional metadata (color, note). Pair with the `annotations`
|
|
1174
|
-
* prop on {@link MejiroReader} to render highlights, or with `goToAnchor` to
|
|
1175
|
-
* implement bookmarks.
|
|
1176
|
-
*/
|
|
1177
|
-
interface Annotation {
|
|
1178
|
-
/** Stable identifier. Auto-generated when omitted from {@link useAnnotations.add}. */
|
|
1179
|
-
id: string;
|
|
1180
|
-
/** Chapter the annotation lives in. */
|
|
1181
|
-
chapter: number;
|
|
1182
|
-
/** Range start (inclusive). */
|
|
1183
|
-
start: InChapterAnchor;
|
|
1184
|
-
/** Range end (exclusive). Equal to `start` for caret-style bookmarks. */
|
|
1185
|
-
end: InChapterAnchor;
|
|
1186
|
-
/** Free-form color identifier (e.g. `'yellow'`, `'#ffd166'`). */
|
|
1187
|
-
color?: string;
|
|
1188
|
-
/** Optional note text attached to the annotation. */
|
|
1189
|
-
note?: string;
|
|
1190
|
-
/** Unix epoch ms. Auto-set on {@link useAnnotations.add} when omitted. */
|
|
1191
|
-
createdAt?: number;
|
|
1192
|
-
}
|
|
1193
1110
|
/** Minimal storage interface required by {@link useAnnotations}. */
|
|
1194
|
-
|
|
1195
|
-
getItem(key: string): string | null;
|
|
1196
|
-
setItem(key: string, value: string): void;
|
|
1197
|
-
removeItem(key: string): void;
|
|
1198
|
-
}
|
|
1111
|
+
type AnnotationsStorage = MejiroStorage;
|
|
1199
1112
|
/** Options for {@link useAnnotations}. */
|
|
1200
1113
|
interface UseAnnotationsOptions {
|
|
1201
1114
|
/** Storage key — usually scoped per-book (e.g. `mejiro:annotations:${bookId}`). */
|
|
@@ -1248,10 +1161,39 @@ declare function useAnnotations(options: UseAnnotationsOptions): UseAnnotationsR
|
|
|
1248
1161
|
|
|
1249
1162
|
/** Options for {@link useChapterLayout}. */
|
|
1250
1163
|
interface UseChapterLayoutOptions {
|
|
1251
|
-
/**
|
|
1164
|
+
/** Observe the surface element for size changes and re-flow. @defaultValue true */
|
|
1252
1165
|
enableResize?: boolean;
|
|
1253
|
-
/** Debounce window (ms)
|
|
1166
|
+
/** Debounce window (ms) applied to size-triggered re-flows. @defaultValue 120 */
|
|
1254
1167
|
resizeDebounce?: number;
|
|
1168
|
+
/**
|
|
1169
|
+
* Resolver for page-geometry overrides forwarded to
|
|
1170
|
+
* {@link MejiroBook.computePageSize} — e.g. to shrink the reserved
|
|
1171
|
+
* `gutterOffset` / `headerOffset` so the pages fill their frame. Called on
|
|
1172
|
+
* every (re)layout so it may return a value that changes over time.
|
|
1173
|
+
*/
|
|
1174
|
+
pageGeometry?: () => ComputePageSizeOptions | undefined;
|
|
1175
|
+
/**
|
|
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.
|
|
1185
|
+
*/
|
|
1186
|
+
capturePosition?: (layout: ChapterLayout) => InChapterAnchor | null;
|
|
1187
|
+
}
|
|
1188
|
+
/** Options for {@link UseChapterLayoutReturn.recompute}. */
|
|
1189
|
+
interface RecomputeOptions {
|
|
1190
|
+
/**
|
|
1191
|
+
* Blank the current layout while the new one is computed. Use for content
|
|
1192
|
+
* changes (chapter / book swaps); skip for size or option changes so the
|
|
1193
|
+
* previous spread stays visible until the re-flow completes (no flicker).
|
|
1194
|
+
* @defaultValue true
|
|
1195
|
+
*/
|
|
1196
|
+
blank?: boolean;
|
|
1255
1197
|
}
|
|
1256
1198
|
/** Page dimensions returned by {@link MejiroBook.computePageSize}. */
|
|
1257
1199
|
interface PageDimensions {
|
|
@@ -1272,14 +1214,37 @@ interface UseChapterLayoutReturn {
|
|
|
1272
1214
|
/** Most recent layout time (ms). */
|
|
1273
1215
|
elapsedMs: number;
|
|
1274
1216
|
/** Force a fresh layout computation. */
|
|
1275
|
-
recompute: () => Promise<void>;
|
|
1217
|
+
recompute: (opts?: RecomputeOptions) => Promise<void>;
|
|
1218
|
+
/**
|
|
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`.
|
|
1222
|
+
*/
|
|
1223
|
+
pendingRestore: RefObject<InChapterAnchor | null>;
|
|
1276
1224
|
}
|
|
1277
1225
|
/**
|
|
1278
|
-
* React hook that lays out the currently-selected chapter and re-flows
|
|
1226
|
+
* React hook that lays out the currently-selected chapter and re-flows when the
|
|
1227
|
+
* surface resizes.
|
|
1228
|
+
*
|
|
1229
|
+
* Re-layouts whenever `book`, `epub`, or `chapterIndex` change, against the
|
|
1230
|
+
* dimensions of `surface`. The `surface` element is observed with a
|
|
1231
|
+
* {@link ResizeObserver}: the first observation runs immediately (so a reader
|
|
1232
|
+
* mounted before its container had a final box is still sized correctly on
|
|
1233
|
+
* first paint), and later size changes trigger a debounced **full re-layout**.
|
|
1279
1234
|
*
|
|
1280
|
-
*
|
|
1281
|
-
*
|
|
1282
|
-
*
|
|
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}.
|
|
1242
|
+
*
|
|
1243
|
+
* @param book - The book instance to lay out with.
|
|
1244
|
+
* @param epub - The current parsed EPUB.
|
|
1245
|
+
* @param chapterIndex - Zero-based chapter index to lay out.
|
|
1246
|
+
* @param surface - DOM ref for the reading surface used for page sizing.
|
|
1247
|
+
* @param options - Behavior overrides.
|
|
1283
1248
|
*/
|
|
1284
1249
|
declare function useChapterLayout(book: MejiroBook, epub: EpubBook | null, chapterIndex: number, surface: RefObject<HTMLElement | null>, options?: UseChapterLayoutOptions): UseChapterLayoutReturn;
|
|
1285
1250
|
|
|
@@ -1388,6 +1353,10 @@ interface UseEpubProjectOptions {
|
|
|
1388
1353
|
assetResolver?: AssetResolver;
|
|
1389
1354
|
onPreview?: (book: EpubBook) => void;
|
|
1390
1355
|
onExport?: (buffer: ArrayBuffer) => void;
|
|
1356
|
+
/** Creates the default title for a generated chapter. */
|
|
1357
|
+
defaultChapterTitle?: (index: number) => string;
|
|
1358
|
+
/** Creates the default body for a generated chapter. */
|
|
1359
|
+
defaultChapterBody?: (index: number) => string;
|
|
1391
1360
|
}
|
|
1392
1361
|
interface UseEpubProjectReturn {
|
|
1393
1362
|
metadata: EpubProjectMetadata;
|
|
@@ -1411,16 +1380,24 @@ interface UseEpubProjectReturn {
|
|
|
1411
1380
|
declare function useEpubProject(options?: UseEpubProjectOptions): UseEpubProjectReturn;
|
|
1412
1381
|
|
|
1413
1382
|
/** Options for {@link useManuscriptDraft}. */
|
|
1414
|
-
interface UseManuscriptDraftOptions {
|
|
1383
|
+
interface UseManuscriptDraftOptions<TAutosave = ManuscriptEditorChapter[]> {
|
|
1415
1384
|
/** Initial chapters. Defaults to a single empty chapter. */
|
|
1416
1385
|
initialChapters?: ManuscriptEditorChapter[];
|
|
1417
1386
|
/**
|
|
1418
1387
|
* Called when the draft changes (debounced). Use to persist to
|
|
1419
1388
|
* localStorage, IndexedDB, or upload to a server.
|
|
1420
1389
|
*/
|
|
1421
|
-
onAutosave?: (
|
|
1390
|
+
onAutosave?: (draft: TAutosave) => void | Promise<void>;
|
|
1391
|
+
/** Maps chapters to the autosave payload. Defaults to the chapter array. */
|
|
1392
|
+
autosavePayload?: (chapters: ManuscriptEditorChapter[]) => TAutosave;
|
|
1393
|
+
/** Extra key that triggers autosave when non-chapter metadata changes. */
|
|
1394
|
+
autosaveKey?: string;
|
|
1422
1395
|
/** Debounce delay in milliseconds. @defaultValue 800 */
|
|
1423
1396
|
autosaveDelay?: number;
|
|
1397
|
+
/** Creates the default title for a generated chapter. */
|
|
1398
|
+
defaultChapterTitle?: (index: number) => string;
|
|
1399
|
+
/** Creates the default body for a generated chapter. */
|
|
1400
|
+
defaultChapterBody?: (index: number) => string;
|
|
1424
1401
|
}
|
|
1425
1402
|
/** Return value of {@link useManuscriptDraft}. */
|
|
1426
1403
|
interface UseManuscriptDraftReturn {
|
|
@@ -1433,6 +1410,10 @@ interface UseManuscriptDraftReturn {
|
|
|
1433
1410
|
addChapter(chapter?: Partial<ManuscriptEditorChapter>): void;
|
|
1434
1411
|
removeChapter(index: number): void;
|
|
1435
1412
|
reorderChapters(from: number, to: number): void;
|
|
1413
|
+
/** Last autosave failure, if any. */
|
|
1414
|
+
autosaveError: Error | null;
|
|
1415
|
+
/** Immediately saves the latest dirty draft, if one exists. */
|
|
1416
|
+
flushAutosave(): void;
|
|
1436
1417
|
}
|
|
1437
1418
|
/**
|
|
1438
1419
|
* Reactive store for manuscript drafts.
|
|
@@ -1441,15 +1422,15 @@ interface UseManuscriptDraftReturn {
|
|
|
1441
1422
|
* patching individual chapters, plus a debounced autosave hook that fires
|
|
1442
1423
|
* `onAutosave` whenever the chapter list settles.
|
|
1443
1424
|
*/
|
|
1444
|
-
declare function useManuscriptDraft(options?: UseManuscriptDraftOptions): UseManuscriptDraftReturn;
|
|
1425
|
+
declare function useManuscriptDraft<TAutosave = ManuscriptEditorChapter[]>(options?: UseManuscriptDraftOptions<TAutosave>): UseManuscriptDraftReturn;
|
|
1445
1426
|
|
|
1446
1427
|
/** Options for {@link useManuscriptLayout}. */
|
|
1447
1428
|
interface UseManuscriptLayoutOptions {
|
|
1448
1429
|
/** Manuscript notation dialect. @defaultValue `'mejiro'` */
|
|
1449
1430
|
dialect?: ManuscriptDialect;
|
|
1450
|
-
/**
|
|
1431
|
+
/** Observe the surface element for size changes and re-flow. @defaultValue true */
|
|
1451
1432
|
enableResize?: boolean;
|
|
1452
|
-
/** Debounce window (ms)
|
|
1433
|
+
/** Debounce window (ms) applied to size-triggered re-flows. @defaultValue 120 */
|
|
1453
1434
|
resizeDebounce?: number;
|
|
1454
1435
|
}
|
|
1455
1436
|
/** Page dimensions returned by {@link MejiroBook.computePageSize}. */
|
|
@@ -1481,9 +1462,9 @@ interface UseManuscriptLayoutReturn {
|
|
|
1481
1462
|
* {@link useManuscriptDraft} for the chapter array and feed the resulting
|
|
1482
1463
|
* {@link ChapterLayout} into {@link MejiroSpread} or {@link MejiroScrollView}.
|
|
1483
1464
|
*
|
|
1484
|
-
* Re-layouts whenever `chapter`, `dialect`, or `book` change.
|
|
1485
|
-
*
|
|
1486
|
-
*
|
|
1465
|
+
* Re-layouts whenever `chapter`, `dialect`, or `book` change. The surface is
|
|
1466
|
+
* observed with {@link ResizeObserver}; size changes trigger a full re-layout
|
|
1467
|
+
* so pagination stays correct after non-trivial container changes.
|
|
1487
1468
|
*/
|
|
1488
1469
|
declare function useManuscriptLayout(book: MejiroBook, chapter: ManuscriptChapter | null, surface: RefObject<HTMLElement | null>, options?: UseManuscriptLayoutOptions): UseManuscriptLayoutReturn;
|
|
1489
1470
|
|
|
@@ -1508,18 +1489,8 @@ interface UseMejiroBookReturn {
|
|
|
1508
1489
|
*/
|
|
1509
1490
|
declare function useMejiroBook(initial: BookOptions): UseMejiroBookReturn;
|
|
1510
1491
|
|
|
1511
|
-
/**
|
|
1512
|
-
* Persisted reading position. Anchor-shaped — pair with
|
|
1513
|
-
* {@link MejiroReaderHandle.goToAnchor} to restore the user's exact location
|
|
1514
|
-
* even after a reflow that invalidates spread indices.
|
|
1515
|
-
*/
|
|
1516
|
-
type ReadingPositionValue = ReadingAnchor;
|
|
1517
1492
|
/** Minimal storage interface required by {@link useReadingPosition}. */
|
|
1518
|
-
|
|
1519
|
-
getItem(key: string): string | null;
|
|
1520
|
-
setItem(key: string, value: string): void;
|
|
1521
|
-
removeItem(key: string): void;
|
|
1522
|
-
}
|
|
1493
|
+
type ReadingPositionStorage = MejiroStorage;
|
|
1523
1494
|
/** Options for {@link useReadingPosition}. */
|
|
1524
1495
|
interface UseReadingPositionOptions {
|
|
1525
1496
|
/** Storage key — usually scoped per-book (e.g. `mejiro:position:${bookId}`). */
|
|
@@ -1602,6 +1573,12 @@ interface UseSpreadReturn {
|
|
|
1602
1573
|
prev: () => void;
|
|
1603
1574
|
/** Jump to an arbitrary spread index (clamped). */
|
|
1604
1575
|
goTo: (index: number) => void;
|
|
1576
|
+
/**
|
|
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
|
|
1579
|
+
* re-layout (where an animated {@link goTo} would briefly flash spread 0).
|
|
1580
|
+
*/
|
|
1581
|
+
setSpread: (index: number) => void;
|
|
1605
1582
|
/** Manually refresh `spread` from `layout` at the current index. */
|
|
1606
1583
|
refresh: () => void;
|
|
1607
1584
|
}
|
|
@@ -1611,4 +1588,4 @@ interface UseSpreadReturn {
|
|
|
1611
1588
|
*/
|
|
1612
1589
|
declare function useSpread(layout: ChapterLayout | null, options?: UseSpreadOptions): UseSpreadReturn;
|
|
1613
1590
|
|
|
1614
|
-
export { type
|
|
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 };
|