Skip to content

YPE-1337: Add footnotes to the Bible book intro chapters#172

Merged
cameronapak merged 5 commits intomainfrom
cp/YPE-1337-react-sdk-bible-reader-add-footnotes-support-for-the-introduction-chapters
Feb 25, 2026
Merged

YPE-1337: Add footnotes to the Bible book intro chapters#172
cameronapak merged 5 commits intomainfrom
cp/YPE-1337-react-sdk-bible-reader-add-footnotes-support-for-the-introduction-chapters

Conversation

@cameronapak
Copy link
Collaborator

@cameronapak cameronapak commented Feb 25, 2026

https://lifechurch.atlassian.net/browse/YPE-1337

Click to watch 1 min overview demo

GIF demo

CleanShot 2026-02-25 at 11 32 21

Summary

Bible introduction chapters (e.g. JOS.INTRO in TPT) contain footnotes but have no verse markers. The existing footnote pipeline was entirely verse-keyed, so intro footnotes were silently skipped.

You can see a footnote on a Bible book intro chapter when visiting https://www.bible.com/bible/1849/JOS.INTRO1

Changes

  • verse-html-utils.tsextractNotesFromWrappedHtml() now collects orphaned footnotes and keys them as "intro-0", "intro-1", etc. replaceFootnotesWithAnchors() uses matching synthetic keys instead of skipping.
  • verse.tsxVerseFootnoteButton conditionally hides the verse reference label and verse text preview for intro footnotes.
  • Tests — 7 unit tests for the transform pipeline, 2 component tests for rendering, and a Storybook integration test on the JoshuaIntroChapter story.

How to verify

  1. Run pnpm test — all 561 tests pass
  2. Open Storybook → JoshuaIntroChapter story → footnote icons appear inline, clicking shows popover with note content and no verse reference

This commit introduces support for rendering footnotes found in intro
chapters (chapters without explicit verse numbers).

Previously, footnotes were only processed if they were associated with a
specific verse number. This change ensures that orphaned footnotes
within introductory HTML are correctly identified, processed, and
rendered as interactive footnote
Removes extraneous assertions from tests and cleans up internal
@chatgpt-codex-connector
Copy link

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@changeset-bot
Copy link

changeset-bot bot commented Feb 25, 2026

🦋 Changeset detected

Latest commit: 2189370

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 4 packages
Name Type
@youversion/platform-react-ui Patch
@youversion/platform-core Patch
@youversion/platform-react-hooks Patch
nextjs Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@cameronapak cameronapak self-assigned this Feb 25, 2026
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 25, 2026

Greptile Summary

This PR implements footnote support for Bible book intro chapters (e.g., JOS.INTRO in TPT). Intro chapters contain footnotes but lack verse markers, so the existing verse-keyed footnote pipeline silently skipped them.

The implementation uses a single-pass key assignment strategy where assignFootnoteKeys() assigns stable keys to all footnotes in document order—verse-bound footnotes get their verse number, while orphaned (intro) footnotes get synthetic keys like intro-0, intro-1, etc. Both extraction and anchor replacement read from the same key attribute, ensuring consistency.

The VerseNotes type gains a hasVerseContext boolean flag that tracks whether a footnote has an associated verse wrapper. The VerseFootnoteButton component uses this flag to conditionally hide the verse reference header and verse text preview in the popover for intro footnotes, preventing users from seeing synthetic keys like "Joshua :intro-0".

Testing: 7 unit tests for the transform pipeline, 2 component tests for rendering behavior, and a Storybook integration test on the JoshuaIntroChapter story. All tests are comprehensive and verify correct behavior for intro-only, verse-only, and mixed scenarios, including edge cases like spacing when footnotes are removed.

Code quality: The implementation is clean, well-documented, and follows existing patterns. The two-phase extraction approach (clone for data extraction, then mutate real DOM) is preserved. No breaking changes to the public API.

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The implementation is well-designed with comprehensive test coverage (7 unit tests, 2 component tests, 1 integration test). The single-pass key assignment strategy is clean and efficient. The changes are isolated to the footnote handling pipeline with no breaking changes to the public API. The conditional rendering approach using hasVerseContext prevents synthetic keys from being exposed to users. All edge cases (mixed intro/verse content, spacing logic) are properly tested.
  • No files require special attention

Important Files Changed

Filename Overview
packages/ui/src/lib/verse-html-utils.ts Adds assignFootnoteKeys() to assign stable keys to footnotes (verse number or synthetic intro-N), updates extractNotesFromWrappedHtml() to handle orphaned footnotes, and adds hasVerseContext flag to VerseNotes type. Logic is sound and well-tested.
packages/ui/src/lib/verse-html-utils.test.ts New test file with 7 comprehensive unit tests covering intro footnote key assignment, content extraction, anchor creation, mixed intro/verse scenarios, and spacing logic. All test cases are thorough and well-structured.
packages/ui/src/components/verse.tsx Conditionally hides verse reference and verse text in footnote popover when hasVerseContext is false (intro footnotes). Simple, clean change that prevents synthetic keys like intro-0 from being displayed to users.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Raw Bible HTML with footnotes] --> B[wrapVerseContent]
    B --> C{Has verse markers?}
    C -->|Yes| D[Wrap in .yv-v span with v attribute]
    C -->|No| E[Intro chapter - no wrapping]
    D --> F[assignFootnoteKeys]
    E --> F
    F --> G{Footnote has .yv-v ancestor?}
    G -->|Yes| H[Assign verse number as key]
    G -->|No| I[Assign synthetic intro-N key]
    H --> J[extractNotesFromWrappedHtml]
    I --> J
    J --> K[Group footnotes by key]
    K --> L{Has verse wrapper?}
    L -->|Yes| M[Build verseHtml + set hasVerseContext=true]
    L -->|No| N[Set verseHtml='' + hasVerseContext=false]
    M --> O[replaceFootnotesWithAnchors]
    N --> O
    O --> P[Create span with data-verse-footnote=key]
    P --> Q[React Portal to VerseFootnoteButton]
    Q --> R{hasVerseContext?}
    R -->|Yes| S[Show verse reference + verse text + notes]
    R -->|No| T[Show notes only - hide synthetic key]
Loading

Last reviewed commit: 19e5eb3

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

@cameronapak
Copy link
Collaborator Author

@greptileai, please re-review. I've made some updates

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

Copy link
Collaborator

@camrun91 camrun91 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@cameronapak cameronapak merged commit a7100fd into main Feb 25, 2026
5 of 7 checks passed
@cameronapak cameronapak deleted the cp/YPE-1337-react-sdk-bible-reader-add-footnotes-support-for-the-introduction-chapters branch February 25, 2026 17:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants