bible-note 0.4.7 → 0.6.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bible-note",
3
- "version": "0.4.7",
3
+ "version": "0.6.0",
4
4
  "description": "A Bible study tool for taking notes and organizing your thoughts.",
5
5
  "license": "MIT",
6
6
  "author": "raksa <eng.raksa@gmail.com>",
@@ -23,11 +23,14 @@
23
23
  "require": "./dist/bible-note.cjs"
24
24
  },
25
25
  "./styles.css": "./dist/bible-note.css",
26
+ "./knowledge/development.md": "./knowledge/development.md",
27
+ "./knowledge/ui-rag.md": "./knowledge/ui-rag.md",
26
28
  "./package.json": "./package.json"
27
29
  },
28
30
  "files": [
29
31
  "dist",
30
32
  "types",
33
+ "knowledge",
31
34
  "README.md",
32
35
  "LICENSE"
33
36
  ],
@@ -7,6 +7,7 @@
7
7
  */
8
8
  import type { LibraryItems } from './excalidrawTypes';
9
9
  import { type JSX, type ReactNode } from 'react';
10
+ import { type BibleNoteFloatingActionButtonControllerOwner } from './floatingActionButtons';
10
11
  import { type BibleNoteFooterActionButtonControllerOwner } from './footerActionButtons';
11
12
  import type { LocationsLookupManager, NamesLookupManager } from './LookupManager';
12
13
  import type { ExtraFontFamilyOption } from './utils/fontFamilyOptions';
@@ -23,6 +24,7 @@ type PlaygroundAppProps = {
23
24
  excalidrawLibraryItems?: LibraryItems;
24
25
  excalidrawLoadLibrariesFileList?: () => string[];
25
26
  excalidrawSaveLibrariesFile?: (librariesFile: string) => void;
27
+ floatingActionButtonController?: BibleNoteFloatingActionButtonControllerOwner;
26
28
  footerActionButtonController?: BibleNoteFooterActionButtonControllerOwner;
27
29
  isMinimize: boolean;
28
30
  isOnApp: boolean;
@@ -63,6 +65,6 @@ type BibleNoteEditorController = {
63
65
  export type BibleNoteEditorControllerOwner = {
64
66
  connectEditorController: (controller: BibleNoteEditorController) => () => void;
65
67
  };
66
- export declare function BibleNoteApp({ detectTextLanguage, editorController, editorExtraFontFamilies, excalidrawClearLibrariesFileList, excalidrawLibraryItems, excalidrawLoadLibrariesFileList, excalidrawSaveLibrariesFile, footerActionButtonController, isMinimize, isOnApp, print, resolveFilePath, revealFile, settings, settingsContainerElement, settingsController, stickyNoteExtraFontFamilies, shortToVerseData, verseFullTextToListShorts, changeBibleKey, }: PlaygroundAppProps): JSX.Element;
67
- export declare function AppComp({ detectTextLanguage, namesLookupManager, locationsLookupManager, editorController, editorExtraFontFamilies, excalidrawClearLibrariesFileList, excalidrawLibraryItems, excalidrawLoadLibrariesFileList, excalidrawSaveLibrariesFile, footerActionButtonController, print, resolveFilePath, revealFile, settings, settingsContainerElement, settingsController, stickyNoteExtraFontFamilies, storageManager, isMinimize, isOnApp, shortToVerseData, verseFullTextToListShorts, changeBibleKey, }: PlaygroundAppProps): JSX.Element;
68
+ export declare function BibleNoteApp({ detectTextLanguage, editorController, editorExtraFontFamilies, excalidrawClearLibrariesFileList, excalidrawLibraryItems, excalidrawLoadLibrariesFileList, excalidrawSaveLibrariesFile, floatingActionButtonController, footerActionButtonController, isMinimize, isOnApp, print, resolveFilePath, revealFile, settings, settingsContainerElement, settingsController, stickyNoteExtraFontFamilies, shortToVerseData, verseFullTextToListShorts, changeBibleKey, }: PlaygroundAppProps): JSX.Element;
69
+ export declare function AppComp({ detectTextLanguage, namesLookupManager, locationsLookupManager, editorController, editorExtraFontFamilies, excalidrawClearLibrariesFileList, excalidrawLibraryItems, excalidrawLoadLibrariesFileList, excalidrawSaveLibrariesFile, floatingActionButtonController, footerActionButtonController, print, resolveFilePath, revealFile, settings, settingsContainerElement, settingsController, stickyNoteExtraFontFamilies, storageManager, isMinimize, isOnApp, shortToVerseData, verseFullTextToListShorts, changeBibleKey, }: PlaygroundAppProps): JSX.Element;
68
70
  export {};
@@ -1,42 +1,121 @@
1
+ import type { BibleNoteFloatingActionButton } from './floatingActionButtons';
1
2
  import type { BibleNoteFooterActionButton } from './footerActionButtons';
2
3
  import type { BibleNoteColorScheme } from './params/colorScheme';
3
4
  import { type BibleNoteProps, type BibleNoteRenderOptions } from './bibleNoteHelpers';
5
+ export type { BibleNoteFloatingActionButton, BibleNoteFloatingActionButtonClickEvent, BibleNoteFloatingActionButtons, BibleNoteSelectionPoint, BibleNoteTextSelection, } from './floatingActionButtons';
4
6
  export type { BibleNoteFooterActionButton, BibleNoteFooterActionButtons, } from './footerActionButtons';
7
+ /**
8
+ * The BibleNote editor. Construct it with the host's datasets and storage
9
+ * callbacks, then {@link BibleNote.render | render} it into an element.
10
+ *
11
+ * Every editor-backed method (`content`, `addText`, `searchText`, …) can be
12
+ * called before `render`: writes are queued and applied once the editor has
13
+ * mounted, and reads return an empty value until then.
14
+ */
5
15
  declare class BibleNote {
16
+ /** The package version this bundle was built from. */
6
17
  static VERSION: string;
18
+ /** The props the instance was constructed with. */
7
19
  props: Readonly<BibleNoteProps>;
20
+ /**
21
+ * The colour scheme last applied — by {@link BibleNote.setColorScheme} or the
22
+ * settings panel's Dark Mode switch. Read it; change it with `setColorScheme`.
23
+ */
8
24
  colorScheme: BibleNoteColorScheme;
9
25
  private editorController;
10
26
  private pendingEditorActions;
11
27
  private pendingColorScheme;
12
28
  private readOnlyOverride;
13
29
  private footerActionButtonController;
14
- private footerActionButtons;
30
+ private readonly footerActionButtons;
31
+ private floatingActionButtonController;
32
+ private readonly floatingActionButtons;
15
33
  private root;
16
34
  private settingsController;
17
35
  private readonly editorControllerOwner;
18
36
  private readonly footerActionButtonControllerOwner;
37
+ private readonly floatingActionButtonControllerOwner;
19
38
  private readonly storageManager;
20
39
  private readonly settingsControllerOwner;
40
+ /** Creates the editor; nothing is rendered until `render` is called. */
21
41
  constructor(props: BibleNoteProps);
42
+ /**
43
+ * The note as a serialized Lexical editor state (a JSON string) — the same
44
+ * string `saveData` receives. Reads `''` until the editor has mounted.
45
+ * Assigning replaces the whole document; assigning `''` clears it.
46
+ */
22
47
  get content(): string;
23
48
  set content(value: string);
49
+ /**
50
+ * Whether the note is locked against editing. Assigning `true` forces
51
+ * read-only mode: the footer's lock turns into **Read-Only Mode Locked** and
52
+ * the user cannot unlock it. Assigning `false` releases that lock and makes
53
+ * the note editable.
54
+ */
24
55
  get isReadOnly(): boolean;
25
56
  set isReadOnly(value: boolean);
57
+ /**
58
+ * Whether the caret is in the editor right now: the window has focus, the
59
+ * editor is the active element, and the selection is a collapsed caret inside
60
+ * it. A host can use this to decide whether to send text to `addText`.
61
+ */
26
62
  getIsFocusing(): boolean;
63
+ /**
64
+ * Switches the editor between light and dark. Applies the body classes at
65
+ * once (see `applyBibleNoteColorScheme`) and keeps the settings panel's Dark
66
+ * Mode switch in step.
67
+ */
27
68
  setColorScheme(mode: BibleNoteColorScheme): void;
69
+ /**
70
+ * Inserts text at the caret, or at the end of the note when there is no
71
+ * selection, exactly as if the user had pasted it as plain text — so the
72
+ * paste rules apply: Bible text pasted right after a `^` becomes a verse
73
+ * mention. Ignored while the note is read-only or when `text` is empty.
74
+ */
28
75
  addText(text: string): void;
76
+ /**
77
+ * Adds a host button after the footer's built-in buttons. A button whose `id`
78
+ * is already present is replaced in place, keeping its position.
79
+ */
29
80
  appendFooterActionButton(actionButton: BibleNoteFooterActionButton): void;
81
+ /**
82
+ * Adds a host button before the footer's built-in buttons, ahead of any
83
+ * prepended earlier. A button whose `id` is already present is replaced in
84
+ * place, keeping its position.
85
+ */
30
86
  prependFooterActionButton(actionButton: BibleNoteFooterActionButton): void;
87
+ /** The host footer button with this `id`, or `null`. */
31
88
  getFooterActionButton(id: string): BibleNoteFooterActionButton | null;
89
+ /** Removes the host footer button with this `id`; `false` when there was none. */
32
90
  removeFooterActionButton(id: string): boolean;
33
- private setFooterActionButton;
34
- private getFooterActionButtonsSnapshot;
91
+ /**
92
+ * Adds a host button to the floating toolbar that appears over selected
93
+ * text, after its built-in buttons (after Insert comment). Its `onClick`
94
+ * receives the selection — text, HTML and range — and can replace the
95
+ * selected text. A button whose `id` is already present is replaced in
96
+ * place, keeping its position.
97
+ */
98
+ appendFloatingActionButton(actionButton: BibleNoteFloatingActionButton): void;
99
+ /**
100
+ * Adds a host button to the floating toolbar before its built-in buttons
101
+ * (before Bold), ahead of any prepended earlier. A button whose `id` is
102
+ * already present is replaced in place, keeping its position.
103
+ */
104
+ prependFloatingActionButton(actionButton: BibleNoteFloatingActionButton): void;
105
+ /** The host floating toolbar button with this `id`, or `null`. */
106
+ getFloatingActionButton(id: string): BibleNoteFloatingActionButton | null;
107
+ /**
108
+ * Removes the host floating toolbar button with this `id`; `false` when there
109
+ * was none.
110
+ */
111
+ removeFloatingActionButton(id: string): boolean;
35
112
  private syncFooterActionButtons;
113
+ private syncFloatingActionButtons;
36
114
  private runOrQueueEditorAction;
37
115
  private connectEditorController;
38
116
  private connectSettingsController;
39
117
  private connectFooterActionButtonController;
118
+ private connectFloatingActionButtonController;
40
119
  private syncColorSchemeFromSettings;
41
120
  /**
42
121
  * Drives the editor's find bar. A string opens the bar (or updates the query
@@ -44,7 +123,16 @@ declare class BibleNote {
44
123
  * like the other editor-backed methods.
45
124
  */
46
125
  searchText(query: string | null): void;
126
+ /**
127
+ * Mounts the editor into `containerElement` with its own React root.
128
+ * Rendering again unmounts the previous root first, so an instance is only
129
+ * ever mounted once.
130
+ */
47
131
  render(containerElement: HTMLElement, options?: BibleNoteRenderOptions): void;
132
+ /**
133
+ * Unmounts the editor. The instance keeps its props, footer buttons and
134
+ * floating toolbar buttons and can be rendered again.
135
+ */
48
136
  unmount(): void;
49
137
  /**
50
138
  * Every short verse reference (`GEN 1:1`) the given note content mentions, in
@@ -16,47 +16,72 @@ export { getLookupRecordValues, getMentionKjvName, normalizeMentionNameType, par
16
16
  * font does not cover; anything a `style` attribute accepts works.
17
17
  */
18
18
  export type LookupManagerStyle = CSSProperties;
19
+ /** Options for `searchNames` / `searchLocations`. */
19
20
  export type LookupSearchOptions = {
21
+ /** Language to search; falls back to `defaultLang` when absent or unknown. */
20
22
  lang?: string;
23
+ /** Maximum number of results; all matches when omitted. */
21
24
  limit?: number;
22
25
  };
26
+ /** Options for the `…Pagination` searches. */
23
27
  export type LookupPaginationOptions = {
28
+ /** Search text; empty or omitted lists every record in importance order. */
24
29
  query?: string;
30
+ /** Language to search; falls back to `defaultLang` when absent or unknown. */
25
31
  lang?: string;
32
+ /** 1-based page number, clamped to the available pages. Defaults to 1. */
26
33
  page?: number;
34
+ /** Records per page (at least 1). Defaults to 20. */
27
35
  pageSize?: number;
28
36
  };
37
+ /** One page of search results. */
29
38
  export type LookupPaginationResult<TRecord> = {
39
+ /** The language actually searched. */
30
40
  lang: string;
41
+ /** Matches across all pages. */
31
42
  totalRecords: number;
43
+ /** The page returned, after clamping. */
32
44
  page: number;
45
+ /** Number of pages; at least 1, even with no matches. */
33
46
  totalPages: number;
34
47
  pageSize: number;
48
+ /** This page's records. */
35
49
  records: Array<TRecord>;
36
50
  };
51
+ /** `LookupSearchOptions` plus a name-type filter. */
37
52
  export type NamesLookupSearchOptions = LookupSearchOptions & {
53
+ /** Only records of this type; applied before `limit`. */
38
54
  type?: MentionNameType;
39
55
  };
56
+ /** `LookupPaginationOptions` plus a name-type filter. */
40
57
  export type NamesLookupPaginationOptions = LookupPaginationOptions & {
58
+ /** Only records of this type. */
41
59
  type?: MentionNameType;
42
60
  };
61
+ /** How many records of one name type a dataset holds. */
43
62
  export type NameTypeCount = {
44
63
  type: MentionNameType;
45
64
  count: number;
46
65
  };
66
+ /** One language's name dataset, as `NamesLookupManager`'s constructor takes it. */
47
67
  export type NamesLookupManagerLangData = {
68
+ /** The normalized records (see `parseMentionNameMatches`). */
48
69
  records: ReadonlyArray<MentionNameMatch>;
49
70
  /** Short verse key (e.g. `"EXO 6:23"`) to the ids of the names it mentions. */
50
71
  versePersonsMap?: VerseRecordIdsMap;
51
72
  };
73
+ /** Name datasets keyed by language code, e.g. `{ en: …, km: … }`. */
52
74
  export type NamesLookupManagerDataMap = {
53
75
  [langCode: string]: NamesLookupManagerLangData;
54
76
  };
77
+ /** One language's location dataset, as `LocationsLookupManager`'s constructor takes it. */
55
78
  export type LocationsLookupManagerLangData = {
79
+ /** The normalized records (see `parseMentionLocationMatches`). */
56
80
  records: ReadonlyArray<MentionLocationMatch>;
57
81
  /** Short verse key (e.g. `"EXO 6:23"`) to the ids of the locations it mentions. */
58
82
  verseLocationsMap?: VerseRecordIdsMap;
59
83
  };
84
+ /** Location datasets keyed by language code, e.g. `{ en: …, km: … }`. */
60
85
  export type LocationsLookupManagerDataMap = {
61
86
  [langCode: string]: LocationsLookupManagerLangData;
62
87
  };
@@ -103,14 +128,24 @@ declare abstract class LookupManager<TRecord extends LookupRecordLike, TLangData
103
128
  */
104
129
  get style(): LookupManagerStyle | undefined;
105
130
  set style(style: LookupManagerStyle | undefined);
131
+ /**
132
+ * The language used when a call names none (or names one this manager does
133
+ * not hold). Assigning a language the data map lacks throws.
134
+ */
106
135
  get defaultLang(): string;
107
136
  set defaultLang(lang: string);
137
+ /** The language codes this manager holds data for. */
108
138
  get langs(): ReadonlyArray<string>;
109
139
  /** Total number of records in a language, ignoring any query. */
110
140
  getRecordCount(lang?: string): number;
111
141
  /** Every record in a language, in importance order. */
112
142
  getAllRecords(lang?: string): Array<TRecord>;
143
+ /** The record with this id (whitespace-trimmed), or `null`. */
113
144
  getRecordById(id: string, lang?: string): TRecord | null;
145
+ /**
146
+ * The records for these ids, in the order given; unknown and repeated ids
147
+ * are skipped.
148
+ */
114
149
  getRecordsByIds(ids: ReadonlyArray<string>, lang?: string): Array<TRecord>;
115
150
  /**
116
151
  * Every record carrying exactly this name. Names are not unique in the
@@ -135,8 +170,18 @@ declare abstract class LookupManager<TRecord extends LookupRecordLike, TLangData
135
170
  protected abstract getVerseRecordIds(langData: TLangData): VerseRecordIdsMap;
136
171
  private getRankedMatches;
137
172
  }
173
+ /**
174
+ * Owns the person/name dataset(s): ranked search, id and name lookup,
175
+ * pagination, name-type counts and verse → names lookup. Has no editor
176
+ * dependency, so a host can use it to build its own UI. Indexes are built
177
+ * lazily per language on first use.
178
+ */
138
179
  export declare class NamesLookupManager extends LookupManager<MentionNameMatch, NamesLookupManagerLangData> {
139
180
  private readonly nameTypeCounts;
181
+ /**
182
+ * Takes already-normalized records; prefer `fromRawDataset` for the generated
183
+ * dataset files. Throws when `dataMap` has no `defaultLang` entry.
184
+ */
140
185
  constructor(dataMap: NamesLookupManagerDataMap, defaultLang: string, style?: LookupManagerStyle);
141
186
  /**
142
187
  * Builds a manager straight from the generated dataset files, i.e. whatever
@@ -155,13 +200,31 @@ export declare class NamesLookupManager extends LookupManager<MentionNameMatch,
155
200
  getNameTypes(lang?: string): ReadonlyArray<NameTypeCount>;
156
201
  /** The name types present in the default language. */
157
202
  get nameTypes(): ReadonlyArray<NameTypeCount>;
203
+ /**
204
+ * Names matching `query`. Case-insensitive substring match against the name, the KJV English
205
+ * name (translated datasets) and the former name. Ranked exact, then prefix,
206
+ * then substring — the better of the two names counts — and by importance
207
+ * (`matterRange`, then alphabetical) within a tier. An empty query returns
208
+ * every record in importance order.
209
+ */
158
210
  searchNames(query: string, options?: NamesLookupSearchOptions): Array<MentionNameMatch>;
211
+ /** `searchNames`, one page at a time (20 records per page by default). */
159
212
  searchNamesPagination(options?: NamesLookupPaginationOptions): LookupPaginationResult<MentionNameMatch>;
160
213
  /** The names a short verse key (e.g. `"EXO 6:23"`) mentions. */
161
214
  searchByShortVerse(shortVerse: string, lang?: string): Array<MentionNameMatch>;
162
215
  protected getVerseRecordIds(langData: NamesLookupManagerLangData): VerseRecordIdsMap;
163
216
  }
217
+ /**
218
+ * Owns the place/location dataset(s): ranked search, id and name lookup,
219
+ * pagination and verse → locations lookup. Has no editor dependency, so a host
220
+ * can use it to build its own UI. Indexes are built lazily per language on
221
+ * first use.
222
+ */
164
223
  export declare class LocationsLookupManager extends LookupManager<MentionLocationMatch, LocationsLookupManagerLangData> {
224
+ /**
225
+ * Takes already-normalized records; prefer `fromRawDataset` for the generated
226
+ * dataset files. Throws when `dataMap` has no `defaultLang` entry.
227
+ */
165
228
  constructor(dataMap: LocationsLookupManagerDataMap, defaultLang: string, style?: LookupManagerStyle);
166
229
  /**
167
230
  * Builds a manager straight from the generated dataset files, i.e. whatever
@@ -174,7 +237,15 @@ export declare class LocationsLookupManager extends LookupManager<MentionLocatio
174
237
  }, defaultLang: string, style?: LookupManagerStyle): LocationsLookupManager;
175
238
  /** An empty manager, used wherever a host has not supplied a dataset yet. */
176
239
  static createEmpty(): LocationsLookupManager;
240
+ /**
241
+ * Locations matching `query`. Case-insensitive substring match against the name, the KJV English
242
+ * name (translated datasets) and the former name. Ranked exact, then prefix,
243
+ * then substring — the better of the two names counts — and by importance
244
+ * (`matterRange`, then alphabetical) within a tier. An empty query returns
245
+ * every record in importance order.
246
+ */
177
247
  searchLocations(query: string, options?: LookupSearchOptions): Array<MentionLocationMatch>;
248
+ /** `searchLocations`, one page at a time (20 records per page by default). */
178
249
  searchLocationsPagination(options?: LookupPaginationOptions): LookupPaginationResult<MentionLocationMatch>;
179
250
  /** The locations a short verse key (e.g. `"EXO 6:23"`) mentions. */
180
251
  searchByShortVerse(shortVerse: string, lang?: string): Array<MentionLocationMatch>;
@@ -0,0 +1,23 @@
1
+ /** Which side of an editor's built-in buttons a host button sits on. */
2
+ export type ActionButtonPlacement = 'before' | 'after';
3
+ /** Host buttons on each side of an editor's built-in buttons, in order. */
4
+ export type PlacedActionButtons<T> = Readonly<{
5
+ before: ReadonlyArray<T>;
6
+ after: ReadonlyArray<T>;
7
+ }>;
8
+ /**
9
+ * The host buttons of one button bar, split around its built-in buttons. Ids are
10
+ * unique across both sides: adding a button whose id is already present
11
+ * replaces that button in place, whatever placement is asked for.
12
+ */
13
+ export declare class ActionButtonList<T extends {
14
+ readonly id: string;
15
+ }> {
16
+ private before;
17
+ private after;
18
+ get(id: string): T | null;
19
+ set(actionButton: T, placement: ActionButtonPlacement): void;
20
+ /** Removes the button with this id; `false` when there was none. */
21
+ remove(id: string): boolean;
22
+ snapshot(): PlacedActionButtons<T>;
23
+ }
@@ -2,6 +2,7 @@ import type { CSSProperties, ReactNode } from 'react';
2
2
  import type { LibraryItems } from './excalidrawTypes';
3
3
  import type { Root } from 'react-dom/client';
4
4
  import type { BibleNoteEditorControllerOwner, BibleNoteSettingsControllerOwner } from './AppComp';
5
+ import type { BibleNoteFloatingActionButtonControllerOwner } from './floatingActionButtons';
5
6
  import type { BibleNoteFooterActionButtonControllerOwner } from './footerActionButtons';
6
7
  import type { BibleNoteColorScheme } from './params/colorScheme';
7
8
  import type { BibleNoteStorageManager } from './storageManager';
@@ -12,42 +13,148 @@ export type BibleNoteSettingsController = {
12
13
  setColorScheme: (mode: BibleNoteColorScheme) => void;
13
14
  };
14
15
  export type BibleNoteEditorController = Parameters<BibleNoteEditorControllerOwner['connectEditorController']>[0];
16
+ /** A Bible verse as the host renders it: a title line plus the full text. */
15
17
  type MentionedBibleDataType = {
18
+ /** The verse reference as displayed, e.g. `(KJV) Genesis 1:1`. */
16
19
  title: string;
20
+ /**
21
+ * The title line followed by the verse lines, in the same shape the editor
22
+ * accepts when Bible text is pasted after `^`:
23
+ * `(KJV) Genesis 1:1\n(1): In the beginning…`.
24
+ */
17
25
  fullText: string;
26
+ /** Extra CSS for this verse's text, e.g. a font for a non-Latin version. */
18
27
  style?: CSSProperties;
19
28
  };
29
+ /** Everything `new BibleNote(props)` needs from the host application. */
20
30
  export type BibleNoteProps = {
31
+ /**
32
+ * The person dataset behind `@` mentions, hover cards, the advanced panel
33
+ * and the lookup panel. Build it with `NamesLookupManager.fromRawDataset`.
34
+ */
21
35
  namesLookupManager: NamesLookupManager;
36
+ /**
37
+ * The place dataset behind `#` mentions, hover cards, the advanced panel and
38
+ * the lookup panel. Build it with `LocationsLookupManager.fromRawDataset`.
39
+ */
22
40
  locationsLookupManager: LocationsLookupManager;
41
+ /**
42
+ * Returns the language code of a piece of text (`'en'` for English). Used to
43
+ * pick a font for pasted Bible text and Excalidraw text: when it returns a
44
+ * code other than `'en'`, the editor switches to the first font in
45
+ * `editorExtraFontFamilies` registered for that language.
46
+ */
23
47
  getLangCode: (text: string) => string;
48
+ /**
49
+ * Fonts added to the toolbar's font menu and to Excalidraw, as
50
+ * `[fontFamily, languageCode]` pairs. The host must load the font faces
51
+ * itself; pass `[]` for the built-in fonts only.
52
+ */
24
53
  editorExtraFontFamilies: ReadonlyArray<ExtraFontFamilyOption>;
54
+ /** Extra Excalidraw library items, offered next to the bundled Christian library. */
25
55
  excalidrawLibraryItems?: LibraryItems;
56
+ /** Forgets every Excalidraw library file `excalidrawSaveLibrariesFile` stored. */
26
57
  excalidrawClearLibrariesFileList?: () => void;
58
+ /**
59
+ * Returns the Excalidraw library files saved earlier (each a serialized
60
+ * library JSON string); read each time the Excalidraw editor opens.
61
+ */
27
62
  excalidrawLoadLibrariesFileList?: () => string[];
63
+ /**
64
+ * Persists a library the user imported in Excalidraw (a serialized library
65
+ * JSON string) so `excalidrawLoadLibrariesFileList` can return it next time.
66
+ */
28
67
  excalidrawSaveLibrariesFile?: (librariesFile: string) => void;
68
+ /**
69
+ * Extra CSS font-family values offered in the sticky-note font picker, e.g.
70
+ * `'"Fasthand"'`. Pass `[]` for none.
71
+ */
29
72
  stickyNoteExtraFontFamilies: ReadonlyArray<string>;
73
+ /**
74
+ * Stores every piece of editor state except the note itself: settings,
75
+ * comments, read-only mode, zoom, panel state. `createBrowserStorageManager()`
76
+ * keeps them in `localStorage`. The keys it receives are listed in
77
+ * `BIBLE_NOTE_STORAGE_MANAGER_KEYS`.
78
+ */
30
79
  storageManager: BibleNoteStorageManager;
80
+ /**
81
+ * Saves the note: called with the serialized editor state (a JSON string) on
82
+ * every change to the document — the same string `BibleNote#content`
83
+ * returns. Called with `''` when the stored note could not be parsed and is
84
+ * discarded.
85
+ */
31
86
  saveData: (data: string) => Promise<void> | void;
87
+ /**
88
+ * Loads the note saved by `saveData`. Return `null` or `''` for an empty
89
+ * editor.
90
+ */
32
91
  loadData: () => Promise<string | null> | string | null;
92
+ /**
93
+ * Maps a media file the user dropped or picked to a path or URL to store in
94
+ * the note instead of embedding it as a data URL. Return `null` to fall back
95
+ * to embedding. In a browser there is usually no path to give; in Electron
96
+ * this is where a file's location on disk comes from.
97
+ */
33
98
  resolveFilePath?: FilePathResolver;
99
+ /**
100
+ * Shows a media file's location to the user (e.g. Electron's
101
+ * `shell.showItemInFolder`). When provided, a selected image, video, audio or
102
+ * PDF whose source is a local file path gets a reveal button.
103
+ */
34
104
  revealFile?: FileRevealer;
105
+ /**
106
+ * Replaces the footer Print button's built-in printing, which prints the note
107
+ * laid out at the selected page size.
108
+ */
35
109
  print?: () => void;
110
+ /**
111
+ * The editor is embedded in an app rather than a web page: hides the footer's
112
+ * **Share as Link** and **Convert From Markdown** buttons. Defaults to `false`.
113
+ */
36
114
  isOnApp?: boolean;
115
+ /**
116
+ * Compact footer: folds Import, Export and Editor Information into a
117
+ * **More actions** menu. Defaults to `false`.
118
+ */
37
119
  isMinimize?: boolean;
120
+ /**
121
+ * Resolves a short verse key (`GEN 1:1`) to its displayed title and text.
122
+ * Used for verse lists in mention panels and in the Word export's References
123
+ * appendix. Without it, those lists show the bare key.
124
+ */
38
125
  shortToVerseData?: (shortText: string) => Promise<MentionedBibleDataType | null>;
126
+ /**
127
+ * Lists the short verse keys a verse mention covers, given its full text.
128
+ * Enables the people and places mentioned in a verse, shown in that verse's
129
+ * advanced panel and in the Word export.
130
+ */
39
131
  verseFullTextToListShorts?: (fullText: string) => Promise<string[] | null>;
132
+ /**
133
+ * Offers the same verse in another Bible version. When provided, the version
134
+ * label in a verse's advanced panel becomes a button; resolve to the verse in
135
+ * the chosen version to open it in a new panel, or `null` to do nothing.
136
+ */
40
137
  changeBibleKey?: (event: React.MouseEvent<HTMLButtonElement>, verseFullText: string) => Promise<MentionedBibleDataType | null>;
41
138
  };
139
+ /** Options for `BibleNote#render`. */
42
140
  export type BibleNoteRenderOptions = {
141
+ /**
142
+ * The settings panel to mount, normally `<BibleNoteSettings />`. Omit it and
143
+ * the editor has no settings panel.
144
+ */
43
145
  settings?: ReactNode;
146
+ /**
147
+ * Where to portal the `settings` panel. Without it the panel renders inside
148
+ * the editor's own layout.
149
+ */
44
150
  settingsContainerElement?: Element | DocumentFragment;
45
151
  };
46
152
  export declare function createBibleNoteStorageManager({ loadData, saveData, storageManager, }: BibleNoteProps): BibleNoteStorageManager;
47
- export declare function renderEditor({ props, containerElement, editorControllerOwner, footerActionButtonControllerOwner, settingsControllerOwner, storageManager, }: {
153
+ export declare function renderEditor({ props, containerElement, editorControllerOwner, floatingActionButtonControllerOwner, footerActionButtonControllerOwner, settingsControllerOwner, storageManager, }: {
48
154
  props: BibleNoteProps;
49
155
  containerElement: HTMLElement;
50
156
  editorControllerOwner: BibleNoteEditorControllerOwner;
157
+ floatingActionButtonControllerOwner: BibleNoteFloatingActionButtonControllerOwner;
51
158
  footerActionButtonControllerOwner: BibleNoteFooterActionButtonControllerOwner;
52
159
  settingsControllerOwner: BibleNoteSettingsControllerOwner;
53
160
  storageManager: BibleNoteStorageManager;
@@ -1,3 +1,8 @@
1
+ /**
2
+ * The storage key of the note itself. The editor never hands this key to the
3
+ * host's `storageManager`: reads and writes of it go to `loadData` / `saveData`
4
+ * instead.
5
+ */
1
6
  export declare const EDITOR_STATE_LOCAL_STORAGE_KEY = "lexical-playground-editor-state";
2
7
  export declare const SHARED_EDITOR_STATE_QUERY_PARAM = "editor-state";
3
8
  export declare const SHARED_EDITOR_STATE_PASSWORD_PREFIX = "pwdecrypted:";
@@ -0,0 +1,118 @@
1
+ import type { MouseEvent as ReactMouseEvent, ReactNode } from 'react';
2
+ import type { PlacedActionButtons } from './actionButtonList';
3
+ /**
4
+ * A position in the open note, addressed the way the editor addresses it: a
5
+ * node, and an offset inside that node.
6
+ */
7
+ export type BibleNoteSelectionPoint = Readonly<{
8
+ /**
9
+ * The editor's key for the node the point sits in. Keys identify nodes of
10
+ * the note as it is open right now: they are not saved with `content`, and
11
+ * they change when the note is loaded again.
12
+ */
13
+ key: string;
14
+ /**
15
+ * For a `'text'` point, the character offset inside that text node. For an
16
+ * `'element'` point, the index of the child the point sits before.
17
+ */
18
+ offset: number;
19
+ /**
20
+ * `'text'` when `key` names a text node; `'element'` when it names an element
21
+ * node such as a paragraph or a list item.
22
+ */
23
+ type: 'text' | 'element';
24
+ }>;
25
+ /**
26
+ * The text selection a floating action button was clicked on. It is a snapshot
27
+ * taken at the click: it does not follow later edits or selection changes.
28
+ */
29
+ export type BibleNoteTextSelection = Readonly<{
30
+ /**
31
+ * The selected text as plain text — what Copy puts on the clipboard as
32
+ * `text/plain`. Paragraphs are separated by `\n`. Never empty: the toolbar
33
+ * only appears over a selection that contains text.
34
+ */
35
+ text: string;
36
+ /**
37
+ * The selected content as HTML, formatting included — what Copy puts on the
38
+ * clipboard as `text/html`.
39
+ */
40
+ html: string;
41
+ /** Where the selection begins, in document order. */
42
+ start: BibleNoteSelectionPoint;
43
+ /** Where the selection ends, in document order. */
44
+ end: BibleNoteSelectionPoint;
45
+ /**
46
+ * `true` when the user selected from the end back toward the start, so the
47
+ * caret sits at `start`; `false` when the caret sits at `end`.
48
+ */
49
+ isBackward: boolean;
50
+ /**
51
+ * A copy of the browser's DOM `Range` for the selection, or `null` when the
52
+ * browser had no selection inside the editor at the click. Use it to measure
53
+ * the text on screen (`domRange.getBoundingClientRect()`); it stops matching
54
+ * the page once the note changes.
55
+ */
56
+ domRange: Range | null;
57
+ }>;
58
+ /** What a floating action button's `onClick` receives. */
59
+ export type BibleNoteFloatingActionButtonClickEvent = Readonly<{
60
+ /** The `id` of the button that was clicked. */
61
+ id: string;
62
+ /** The selection the button was clicked on. */
63
+ selection: BibleNoteTextSelection;
64
+ /**
65
+ * Replaces the text of the captured selection with `text`, inserted the way
66
+ * `BibleNote.addText` inserts it: as plain text, as if pasted, so the paste
67
+ * rules apply and `\n` starts a new paragraph. An empty string deletes the
68
+ * selected text. The selection is restored from `selection.start` and
69
+ * `selection.end` first, so this still works after the user has clicked
70
+ * elsewhere or after an `await`.
71
+ *
72
+ * Returns `false`, and changes nothing, when the note is read-only or when
73
+ * that range no longer holds `selection.text` — because the note was edited
74
+ * since the click, or the text was already replaced.
75
+ */
76
+ replaceText: (text: string) => boolean;
77
+ /** The React click event of the button. */
78
+ mouseEvent: ReactMouseEvent<HTMLButtonElement>;
79
+ }>;
80
+ /**
81
+ * A host-supplied button in the floating toolbar that appears over selected
82
+ * text — the bar with Bold, Italic, Underline, … and Insert comment.
83
+ *
84
+ * Unlike a footer button, the editor renders the `<button>` itself, so it
85
+ * matches the built-in ones; `children` is only what goes inside it.
86
+ */
87
+ export type BibleNoteFloatingActionButton = {
88
+ /** Unique per editor; adding a button with an existing id replaces it in place. */
89
+ id: string;
90
+ /** What the button does: its tooltip and its accessible name. */
91
+ description: string;
92
+ /**
93
+ * The content of the button, normally a Bootstrap icon given the `format`
94
+ * class so it is sized and tinted like the built-in icons:
95
+ * `<i className="bi bi-clipboard format" />`.
96
+ */
97
+ children: ReactNode;
98
+ /**
99
+ * Called on click with the selection the toolbar is showing for. Not called
100
+ * when the selection has collapsed to a caret by the time of the click.
101
+ */
102
+ onClick: (event: BibleNoteFloatingActionButtonClickEvent) => void;
103
+ /**
104
+ * `true` shows the button only while the note can be edited, like the
105
+ * built-in formatting buttons. By default it shows in read-only mode too,
106
+ * like Insert comment — right for actions that only read the selection.
107
+ */
108
+ isHiddenWhenReadOnly?: boolean;
109
+ };
110
+ /** The host floating toolbar buttons on each side of the built-in ones, in order. */
111
+ export type BibleNoteFloatingActionButtons = PlacedActionButtons<BibleNoteFloatingActionButton>;
112
+ export type BibleNoteFloatingActionButtonController = {
113
+ setFloatingActionButtons: (actionButtons: BibleNoteFloatingActionButtons) => void;
114
+ };
115
+ export type BibleNoteFloatingActionButtonControllerOwner = {
116
+ connectFloatingActionButtonController: (controller: BibleNoteFloatingActionButtonController) => () => void;
117
+ };
118
+ export declare const EMPTY_BIBLE_NOTE_FLOATING_ACTION_BUTTONS: BibleNoteFloatingActionButtons;