bible-note 0.5.0 → 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.
@@ -1,6 +1,6 @@
1
1
  # BibleNote — development guide
2
2
 
3
- > Generated by `npm run pack` for **bible-note@0.5.0** from the hand-written topics in `knowledge/development/` and the package's own type declarations. Do not edit this file — edit the sources and re-run the pack. End-user help for the editor UI lives in `ui-rag.md` next to it.
3
+ > Generated by `npm run pack` for **bible-note@0.6.0** from the hand-written topics in `knowledge/development/` and the package's own type declarations. Do not edit this file — edit the sources and re-run the pack. End-user help for the editor UI lives in `ui-rag.md` next to it.
4
4
 
5
5
  ## Contents
6
6
 
@@ -233,11 +233,48 @@ tooltip when the element has no `title`; `shortcutKey` clicks the button from
233
233
  anywhere in the page and is shown in the tooltip. Give the button the
234
234
  `action-button` class to match the built-in ones.
235
235
 
236
+ ### Host buttons on the selected-text toolbar
237
+
238
+ The toolbar that pops up over selected text (Bold, Italic, …, Insert comment)
239
+ takes host buttons too. Here the editor renders the `<button>`, and `onClick`
240
+ receives the selection it was clicked on:
241
+
242
+ ```tsx
243
+ bibleNote.appendFloatingActionButton({
244
+ id: 'copy-selected-text',
245
+ description: 'Copy selected text', // tooltip and accessible name
246
+ children: <i className="bi bi-clipboard format" />,
247
+ onClick: async ({ selection }) => {
248
+ await navigator.clipboard.writeText(selection.text);
249
+ },
250
+ });
251
+ bibleNote.appendFloatingActionButton({
252
+ id: 'uppercase-selected-text',
253
+ description: 'Make selected text uppercase',
254
+ isHiddenWhenReadOnly: true,
255
+ children: <i className="bi bi-alphabet-uppercase format" />,
256
+ onClick: ({ selection, replaceText }) => {
257
+ replaceText(selection.text.toUpperCase());
258
+ },
259
+ });
260
+ bibleNote.removeFloatingActionButton('copy-selected-text');
261
+ ```
262
+
263
+ `selection` holds the plain `text`, the `html` Copy would produce, the `start`
264
+ and `end` points in document order, `isBackward`, and a copy of the DOM
265
+ `domRange`. `replaceText(text)` writes back into that captured range the way
266
+ `addText` inserts text, even after an `await`; it returns `false` and changes
267
+ nothing when the note is read-only or the range no longer holds
268
+ `selection.text`. `prepend…` places a button before Bold, `append…` after
269
+ Insert comment; re-adding an `id` replaces that button in place. The buttons
270
+ show in read-only mode unless `isHiddenWhenReadOnly` is set.
271
+
236
272
  ### Mounting without auto-mount
237
273
 
238
274
  `render` can be called any time after construction and again later — each call
239
275
  unmounts the previous root first. Call `unmount()` when the host view goes away;
240
- the instance keeps its props and footer buttons for the next `render`.
276
+ the instance keeps its props, footer buttons and selected-text toolbar
277
+ buttons for the next `render`.
241
278
 
242
279
  <a id="dev-datasets-and-lookup-managers"></a>
243
280
 
@@ -541,7 +578,10 @@ instance's `colorScheme` follows the Dark Mode switch.
541
578
  selected page size and opens the print dialog).
542
579
 
543
580
  Host buttons go before or after the built-in ones with
544
- `prependFooterActionButton` / `appendFooterActionButton`.
581
+ `prependFooterActionButton` / `appendFooterActionButton`. Buttons for the
582
+ toolbar over selected text use `prependFloatingActionButton` /
583
+ `appendFloatingActionButton`; their `onClick` receives the selection and a
584
+ `replaceText` that writes back into it.
545
585
 
546
586
  ### Electron: native file dialogs
547
587
 
@@ -596,7 +636,7 @@ This topic is for changing the editor itself, in its source repository.
596
636
  | -------------------------------------------- | -------------------------------------------------------------------------------------- |
597
637
  | `src/lib.ts` | the package's public entry — only re-exports; everything it reaches is library code |
598
638
  | `src/index.tsx` | the demo host (fetches datasets, wires every prop, mounts) — not part of the package |
599
- | `src/BibleNote.ts` | the `BibleNote` class: queued editor actions, footer buttons, colour scheme |
639
+ | `src/BibleNote.ts` | the `BibleNote` class: queued editor actions, host buttons, colour scheme |
600
640
  | `src/bibleNoteHelpers.tsx` | `BibleNoteProps`, the storage split, `renderEditor` |
601
641
  | `src/AppComp.tsx` | providers, storage hydration, the editor controller behind `BibleNote`'s methods |
602
642
  | `src/Editor.tsx` | the plugin tree, zoom and the full-view layout |
@@ -960,6 +1000,45 @@ removeFooterActionButton(id: string): boolean;
960
1000
 
961
1001
  Removes the host footer button with this `id`; `false` when there was none.
962
1002
 
1003
+ ##### `appendFloatingActionButton()`
1004
+
1005
+ ```ts
1006
+ appendFloatingActionButton(actionButton: BibleNoteFloatingActionButton): void;
1007
+ ```
1008
+
1009
+ Adds a host button to the floating toolbar that appears over selected
1010
+ text, after its built-in buttons (after Insert comment). Its `onClick`
1011
+ receives the selection — text, HTML and range — and can replace the
1012
+ selected text. A button whose `id` is already present is replaced in
1013
+ place, keeping its position.
1014
+
1015
+ ##### `prependFloatingActionButton()`
1016
+
1017
+ ```ts
1018
+ prependFloatingActionButton(actionButton: BibleNoteFloatingActionButton): void;
1019
+ ```
1020
+
1021
+ Adds a host button to the floating toolbar before its built-in buttons
1022
+ (before Bold), ahead of any prepended earlier. A button whose `id` is
1023
+ already present is replaced in place, keeping its position.
1024
+
1025
+ ##### `getFloatingActionButton()`
1026
+
1027
+ ```ts
1028
+ getFloatingActionButton(id: string): BibleNoteFloatingActionButton | null;
1029
+ ```
1030
+
1031
+ The host floating toolbar button with this `id`, or `null`.
1032
+
1033
+ ##### `removeFloatingActionButton()`
1034
+
1035
+ ```ts
1036
+ removeFloatingActionButton(id: string): boolean;
1037
+ ```
1038
+
1039
+ Removes the host floating toolbar button with this `id`; `false` when there
1040
+ was none.
1041
+
963
1042
  ##### `searchText()`
964
1043
 
965
1044
  ```ts
@@ -986,8 +1065,8 @@ ever mounted once.
986
1065
  unmount(): void;
987
1066
  ```
988
1067
 
989
- Unmounts the editor. The instance keeps its props and footer buttons and
990
- can be rendered again.
1068
+ Unmounts the editor. The instance keeps its props, footer buttons and
1069
+ floating toolbar buttons and can be rendered again.
991
1070
 
992
1071
  <a id="api-locationslookupmanager"></a>
993
1072
 
@@ -1444,6 +1523,64 @@ The editor's two colour schemes.
1444
1523
  type BibleNoteColorScheme = 'dark' | 'light';
1445
1524
  ```
1446
1525
 
1526
+ <a id="api-biblenotefloatingactionbutton"></a>
1527
+
1528
+ #### `BibleNoteFloatingActionButton`
1529
+
1530
+ A host-supplied button in the floating toolbar that appears over selected
1531
+ text — the bar with Bold, Italic, Underline, … and Insert comment.
1532
+
1533
+ Unlike a footer button, the editor renders the `<button>` itself, so it
1534
+ matches the built-in ones; `children` is only what goes inside it.
1535
+
1536
+ | Property | Type | Required | Description |
1537
+ | --- | --- | --- | --- |
1538
+ | `id` | `string` | yes | Unique per editor; adding a button with an existing id replaces it in place. |
1539
+ | `description` | `string` | yes | What the button does: its tooltip and its accessible name. |
1540
+ | `children` | `ReactNode` | yes | The content of the button, normally a Bootstrap icon given the `format` class so it is sized and tinted like the built-in icons: `<i className="bi bi-clipboard format" />`. |
1541
+ | `onClick` | `(event: BibleNoteFloatingActionButtonClickEvent) => void` | yes | Called on click with the selection the toolbar is showing for. Not called when the selection has collapsed to a caret by the time of the click. |
1542
+ | `isHiddenWhenReadOnly` | `boolean` | no | `true` shows the button only while the note can be edited, like the built-in formatting buttons. By default it shows in read-only mode too, like Insert comment — right for actions that only read the selection. |
1543
+
1544
+ <a id="api-biblenotefloatingactionbuttonclickevent"></a>
1545
+
1546
+ #### `BibleNoteFloatingActionButtonClickEvent`
1547
+
1548
+ What a floating action button's `onClick` receives.
1549
+
1550
+ ```ts
1551
+ type BibleNoteFloatingActionButtonClickEvent = Readonly<{
1552
+ /** The `id` of the button that was clicked. */
1553
+ id: string;
1554
+ /** The selection the button was clicked on. */
1555
+ selection: BibleNoteTextSelection;
1556
+ /**
1557
+ * Replaces the text of the captured selection with `text`, inserted the way
1558
+ * `BibleNote.addText` inserts it: as plain text, as if pasted, so the paste
1559
+ * rules apply and `\n` starts a new paragraph. An empty string deletes the
1560
+ * selected text. The selection is restored from `selection.start` and
1561
+ * `selection.end` first, so this still works after the user has clicked
1562
+ * elsewhere or after an `await`.
1563
+ *
1564
+ * Returns `false`, and changes nothing, when the note is read-only or when
1565
+ * that range no longer holds `selection.text` — because the note was edited
1566
+ * since the click, or the text was already replaced.
1567
+ */
1568
+ replaceText: (text: string) => boolean;
1569
+ /** The React click event of the button. */
1570
+ mouseEvent: ReactMouseEvent<HTMLButtonElement>;
1571
+ }>;
1572
+ ```
1573
+
1574
+ <a id="api-biblenotefloatingactionbuttons"></a>
1575
+
1576
+ #### `BibleNoteFloatingActionButtons`
1577
+
1578
+ The host floating toolbar buttons on each side of the built-in ones, in order.
1579
+
1580
+ ```ts
1581
+ type BibleNoteFloatingActionButtons = PlacedActionButtons<BibleNoteFloatingActionButton>;
1582
+ ```
1583
+
1447
1584
  <a id="api-biblenotefooteractionbutton"></a>
1448
1585
 
1449
1586
  #### `BibleNoteFooterActionButton`
@@ -1520,6 +1657,34 @@ Options for `BibleNote#render`.
1520
1657
  | `settings` | `ReactNode` | no | The settings panel to mount, normally `<BibleNoteSettings />`. Omit it and the editor has no settings panel. |
1521
1658
  | `settingsContainerElement` | `Element \| DocumentFragment` | no | Where to portal the `settings` panel. Without it the panel renders inside the editor's own layout. |
1522
1659
 
1660
+ <a id="api-biblenoteselectionpoint"></a>
1661
+
1662
+ #### `BibleNoteSelectionPoint`
1663
+
1664
+ A position in the open note, addressed the way the editor addresses it: a
1665
+ node, and an offset inside that node.
1666
+
1667
+ ```ts
1668
+ type BibleNoteSelectionPoint = Readonly<{
1669
+ /**
1670
+ * The editor's key for the node the point sits in. Keys identify nodes of
1671
+ * the note as it is open right now: they are not saved with `content`, and
1672
+ * they change when the note is loaded again.
1673
+ */
1674
+ key: string;
1675
+ /**
1676
+ * For a `'text'` point, the character offset inside that text node. For an
1677
+ * `'element'` point, the index of the child the point sits before.
1678
+ */
1679
+ offset: number;
1680
+ /**
1681
+ * `'text'` when `key` names a text node; `'element'` when it names an element
1682
+ * node such as a paragraph or a list item.
1683
+ */
1684
+ type: 'text' | 'element';
1685
+ }>;
1686
+ ```
1687
+
1523
1688
  <a id="api-biblenotesettingsprops"></a>
1524
1689
 
1525
1690
  #### `BibleNoteSettingsProps`
@@ -1546,6 +1711,45 @@ first renders; writes are fire-and-forget.
1546
1711
  | `getSetting` | `getSetting<T = unknown>(key: string): Promise<T \| null>` | yes | The value stored under `key`, or `null` when there is none. |
1547
1712
  | `deleteSetting` | `deleteSetting(key: string): Promise<void>` | yes | Removes `key`. |
1548
1713
 
1714
+ <a id="api-biblenotetextselection"></a>
1715
+
1716
+ #### `BibleNoteTextSelection`
1717
+
1718
+ The text selection a floating action button was clicked on. It is a snapshot
1719
+ taken at the click: it does not follow later edits or selection changes.
1720
+
1721
+ ```ts
1722
+ type BibleNoteTextSelection = Readonly<{
1723
+ /**
1724
+ * The selected text as plain text — what Copy puts on the clipboard as
1725
+ * `text/plain`. Paragraphs are separated by `\n`. Never empty: the toolbar
1726
+ * only appears over a selection that contains text.
1727
+ */
1728
+ text: string;
1729
+ /**
1730
+ * The selected content as HTML, formatting included — what Copy puts on the
1731
+ * clipboard as `text/html`.
1732
+ */
1733
+ html: string;
1734
+ /** Where the selection begins, in document order. */
1735
+ start: BibleNoteSelectionPoint;
1736
+ /** Where the selection ends, in document order. */
1737
+ end: BibleNoteSelectionPoint;
1738
+ /**
1739
+ * `true` when the user selected from the end back toward the start, so the
1740
+ * caret sits at `start`; `false` when the caret sits at `end`.
1741
+ */
1742
+ isBackward: boolean;
1743
+ /**
1744
+ * A copy of the browser's DOM `Range` for the selection, or `null` when the
1745
+ * browser had no selection inside the editor at the click. Use it to measure
1746
+ * the text on screen (`domRange.getBoundingClientRect()`); it stops matching
1747
+ * the page once the note changes.
1748
+ */
1749
+ domRange: Range | null;
1750
+ }>;
1751
+ ```
1752
+
1549
1753
  <a id="api-extrafontfamilyoption"></a>
1550
1754
 
1551
1755
  #### `ExtraFontFamilyOption`
@@ -1925,3 +2129,14 @@ A Bible verse as the host renders it: a title line plus the full text.
1925
2129
  | `title` | `string` | yes | The verse reference as displayed, e.g. `(KJV) Genesis 1:1`. |
1926
2130
  | `fullText` | `string` | yes | The title line followed by the verse lines, in the same shape the editor accepts when Bible text is pasted after `^`: `(KJV) Genesis 1:1\n(1): In the beginning…`. |
1927
2131
  | `style` | `CSSProperties` | no | Extra CSS for this verse's text, e.g. a font for a non-Latin version. |
2132
+
2133
+ #### `PlacedActionButtons`
2134
+
2135
+ Host buttons on each side of an editor's built-in buttons, in order.
2136
+
2137
+ ```ts
2138
+ type PlacedActionButtons<T> = Readonly<{
2139
+ before: ReadonlyArray<T>;
2140
+ after: ReadonlyArray<T>;
2141
+ }>;
2142
+ ```