@libraz/mejiro-react 0.6.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.
Files changed (3) hide show
  1. package/dist/index.d.ts +216 -366
  2. package/dist/index.js +626 -663
  3. 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 { BookOptions, ChapterLayout, SpreadResult, PageResult, ComputePageSizeOptions, InChapterAnchor, ReadingAnchor, ManuscriptChapter, AnchorRect, AnchorRange, MejiroBook } from '@libraz/mejiro/book';
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}.
@@ -700,7 +393,7 @@ interface MejiroReaderCommonProps {
700
393
  * { ...DEFAULT_BOOK_OPTIONS, fontFamily: '"Noto Serif JP"', fontSize: 18 }
701
394
  * ```
702
395
  */
703
- options?: BookOptions;
396
+ options?: Partial<BookOptions>;
704
397
  /**
705
398
  * Page-geometry overrides forwarded to `MejiroBook.computePageSize`. Use to
706
399
  * tune how the spread is sized inside the surface — most usefully to shrink
@@ -932,6 +625,190 @@ interface MejiroReaderManuscriptProps extends MejiroReaderCommonProps {
932
625
  type MejiroReaderProps = MejiroReaderControlledProps | MejiroReaderUrlProps | MejiroReaderFileProps | MejiroReaderManuscriptProps;
933
626
  declare const MejiroReader: react.ForwardRefExoticComponent<MejiroReaderProps & react.RefAttributes<MejiroReaderHandle>>;
934
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
+
935
812
  /** Props for {@link MejiroScrollView}. */
936
813
  interface MejiroScrollViewProps {
937
814
  /** Layout containing the pages to render. */
@@ -954,7 +831,7 @@ interface MejiroScrollViewProps {
954
831
  * Visible page index reported to the parent as the user scrolls. The page
955
832
  * with the largest intersection with the viewport is treated as visible.
956
833
  */
957
- onVisiblePageChange?: (pageIdx: number) => void;
834
+ onVisiblePageChange?: (pageIdx: number, source: 'user' | 'programmatic') => void;
958
835
  /**
959
836
  * Target page to scroll into view. When set, the view scrolls so that the
960
837
  * matching page sits at the top of the scroll container.
@@ -1109,13 +986,6 @@ interface UseMultiImageOverlayReturn {
1109
986
  */
1110
987
  declare function useMultiImageOverlay(layout: ChapterLayout | null, spreadIdx: number, options?: UseMultiImageOverlayOptions): UseMultiImageOverlayReturn;
1111
988
 
1112
- /** Per-page header data. */
1113
- interface PageHeaderData {
1114
- /** Running title (left-aligned). */
1115
- title?: string;
1116
- /** Page number (right-aligned). `null` hides it. */
1117
- pageNumber?: number | null;
1118
- }
1119
989
  /** Props for {@link MejiroSpread}. */
1120
990
  interface MejiroSpreadProps {
1121
991
  /** Spread data to render. */
@@ -1237,34 +1107,8 @@ interface MejiroTocProps {
1237
1107
  */
1238
1108
  declare function MejiroToc({ epub, currentAnchor, searchable, title, searchPlaceholder, onSelect, }: MejiroTocProps): ReactNode;
1239
1109
 
1240
- /**
1241
- * A user-authored annotation on a book — a half-open range of in-chapter
1242
- * anchors plus optional metadata (color, note). Pair with the `annotations`
1243
- * prop on {@link MejiroReader} to render highlights, or with `goToAnchor` to
1244
- * implement bookmarks.
1245
- */
1246
- interface Annotation {
1247
- /** Stable identifier. Auto-generated when omitted from {@link useAnnotations.add}. */
1248
- id: string;
1249
- /** Chapter the annotation lives in. */
1250
- chapter: number;
1251
- /** Range start (inclusive). */
1252
- start: InChapterAnchor;
1253
- /** Range end (exclusive). Equal to `start` for caret-style bookmarks. */
1254
- end: InChapterAnchor;
1255
- /** Free-form color identifier (e.g. `'yellow'`, `'#ffd166'`). */
1256
- color?: string;
1257
- /** Optional note text attached to the annotation. */
1258
- note?: string;
1259
- /** Unix epoch ms. Auto-set on {@link useAnnotations.add} when omitted. */
1260
- createdAt?: number;
1261
- }
1262
1110
  /** Minimal storage interface required by {@link useAnnotations}. */
1263
- interface AnnotationsStorage {
1264
- getItem(key: string): string | null;
1265
- setItem(key: string, value: string): void;
1266
- removeItem(key: string): void;
1267
- }
1111
+ type AnnotationsStorage = MejiroStorage;
1268
1112
  /** Options for {@link useAnnotations}. */
1269
1113
  interface UseAnnotationsOptions {
1270
1114
  /** Storage key — usually scoped per-book (e.g. `mejiro:annotations:${bookId}`). */
@@ -1509,6 +1353,10 @@ interface UseEpubProjectOptions {
1509
1353
  assetResolver?: AssetResolver;
1510
1354
  onPreview?: (book: EpubBook) => void;
1511
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;
1512
1360
  }
1513
1361
  interface UseEpubProjectReturn {
1514
1362
  metadata: EpubProjectMetadata;
@@ -1532,16 +1380,24 @@ interface UseEpubProjectReturn {
1532
1380
  declare function useEpubProject(options?: UseEpubProjectOptions): UseEpubProjectReturn;
1533
1381
 
1534
1382
  /** Options for {@link useManuscriptDraft}. */
1535
- interface UseManuscriptDraftOptions {
1383
+ interface UseManuscriptDraftOptions<TAutosave = ManuscriptEditorChapter[]> {
1536
1384
  /** Initial chapters. Defaults to a single empty chapter. */
1537
1385
  initialChapters?: ManuscriptEditorChapter[];
1538
1386
  /**
1539
1387
  * Called when the draft changes (debounced). Use to persist to
1540
1388
  * localStorage, IndexedDB, or upload to a server.
1541
1389
  */
1542
- onAutosave?: (chapters: ManuscriptEditorChapter[]) => void | Promise<void>;
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;
1543
1395
  /** Debounce delay in milliseconds. @defaultValue 800 */
1544
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;
1545
1401
  }
1546
1402
  /** Return value of {@link useManuscriptDraft}. */
1547
1403
  interface UseManuscriptDraftReturn {
@@ -1554,6 +1410,10 @@ interface UseManuscriptDraftReturn {
1554
1410
  addChapter(chapter?: Partial<ManuscriptEditorChapter>): void;
1555
1411
  removeChapter(index: number): void;
1556
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;
1557
1417
  }
1558
1418
  /**
1559
1419
  * Reactive store for manuscript drafts.
@@ -1562,15 +1422,15 @@ interface UseManuscriptDraftReturn {
1562
1422
  * patching individual chapters, plus a debounced autosave hook that fires
1563
1423
  * `onAutosave` whenever the chapter list settles.
1564
1424
  */
1565
- declare function useManuscriptDraft(options?: UseManuscriptDraftOptions): UseManuscriptDraftReturn;
1425
+ declare function useManuscriptDraft<TAutosave = ManuscriptEditorChapter[]>(options?: UseManuscriptDraftOptions<TAutosave>): UseManuscriptDraftReturn;
1566
1426
 
1567
1427
  /** Options for {@link useManuscriptLayout}. */
1568
1428
  interface UseManuscriptLayoutOptions {
1569
1429
  /** Manuscript notation dialect. @defaultValue `'mejiro'` */
1570
1430
  dialect?: ManuscriptDialect;
1571
- /** Listen for `window.resize` and re-flow on resize. @defaultValue true */
1431
+ /** Observe the surface element for size changes and re-flow. @defaultValue true */
1572
1432
  enableResize?: boolean;
1573
- /** Debounce window (ms) for resize re-flows. @defaultValue 120 */
1433
+ /** Debounce window (ms) applied to size-triggered re-flows. @defaultValue 120 */
1574
1434
  resizeDebounce?: number;
1575
1435
  }
1576
1436
  /** Page dimensions returned by {@link MejiroBook.computePageSize}. */
@@ -1602,9 +1462,9 @@ interface UseManuscriptLayoutReturn {
1602
1462
  * {@link useManuscriptDraft} for the chapter array and feed the resulting
1603
1463
  * {@link ChapterLayout} into {@link MejiroSpread} or {@link MejiroScrollView}.
1604
1464
  *
1605
- * Re-layouts whenever `chapter`, `dialect`, or `book` change. On `window.resize`,
1606
- * page dimensions are recomputed and {@link ChapterLayout.resize} is called
1607
- * instead of a full re-layout.
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.
1608
1468
  */
1609
1469
  declare function useManuscriptLayout(book: MejiroBook, chapter: ManuscriptChapter | null, surface: RefObject<HTMLElement | null>, options?: UseManuscriptLayoutOptions): UseManuscriptLayoutReturn;
1610
1470
 
@@ -1629,18 +1489,8 @@ interface UseMejiroBookReturn {
1629
1489
  */
1630
1490
  declare function useMejiroBook(initial: BookOptions): UseMejiroBookReturn;
1631
1491
 
1632
- /**
1633
- * Persisted reading position. Anchor-shaped — pair with
1634
- * {@link MejiroReaderHandle.goToAnchor} to restore the user's exact location
1635
- * even after a reflow that invalidates spread indices.
1636
- */
1637
- type ReadingPositionValue = ReadingAnchor;
1638
1492
  /** Minimal storage interface required by {@link useReadingPosition}. */
1639
- interface ReadingPositionStorage {
1640
- getItem(key: string): string | null;
1641
- setItem(key: string, value: string): void;
1642
- removeItem(key: string): void;
1643
- }
1493
+ type ReadingPositionStorage = MejiroStorage;
1644
1494
  /** Options for {@link useReadingPosition}. */
1645
1495
  interface UseReadingPositionOptions {
1646
1496
  /** Storage key — usually scoped per-book (e.g. `mejiro:position:${bookId}`). */
@@ -1738,4 +1588,4 @@ interface UseSpreadReturn {
1738
1588
  */
1739
1589
  declare function useSpread(layout: ChapterLayout | null, options?: UseSpreadOptions): UseSpreadReturn;
1740
1590
 
1741
- export { type Annotation, type AnnotationsStorage, type EditableEpubSelection, type EditableSettings, type EpubProjectChapterDraft, type FontChoice, 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, type MejiroLocale, MejiroManuscriptEditor, type MejiroManuscriptEditorProps, type MejiroMessages, 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 PageHeaderData, type PageNumberDisplay, type ReadingPosition, type ReadingPositionStorage, type ReadingPositionValue, 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, enMessages, format, jaMessages, resolveMessages, useAnnotations, useChapterLayout, useEditableEpub, useEpub, useEpubProject, useI18n, useImageOverlay, useLibrary, useManuscriptDraft, useManuscriptLayout, useMejiroBook, useMultiImageOverlay, useReadingPosition, useSpread };
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 };