From 79a617bc5c0f4dee8ea413cfb0c1b9d965c1966a Mon Sep 17 00:00:00 2001 From: Dustin Kelley Date: Fri, 15 May 2026 11:40:28 -0500 Subject: [PATCH] feat(ui): add onFootnotePress callback to BibleCard Expose optional onFootnotePress on BibleCardProps and pass through to BibleTextView so hosts can handle footnotes externally (e.g. RN sheet). Co-authored-by: Cursor --- .changeset/bible-card-footnote-press.md | 4 ++ .../ui/src/components/bible-card.test.tsx | 49 ++++++++++++++++++- packages/ui/src/components/bible-card.tsx | 5 +- 3 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 .changeset/bible-card-footnote-press.md diff --git a/.changeset/bible-card-footnote-press.md b/.changeset/bible-card-footnote-press.md new file mode 100644 index 00000000..cdee58bd --- /dev/null +++ b/.changeset/bible-card-footnote-press.md @@ -0,0 +1,4 @@ +--- +"@youversion/platform-react-ui": patch +--- +Add optional `onFootnotePress` callback to `BibleCard` for custom footnote handling (same pattern as `BibleReader`). diff --git a/packages/ui/src/components/bible-card.test.tsx b/packages/ui/src/components/bible-card.test.tsx index abc86d42..453652be 100644 --- a/packages/ui/src/components/bible-card.test.tsx +++ b/packages/ui/src/components/bible-card.test.tsx @@ -2,8 +2,10 @@ * @vitest-environment jsdom */ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; -import { render, act, within } from '@testing-library/react'; +import { render, act, within, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import { BibleCard } from './bible-card'; +import type { FootnoteData } from './verse'; import { usePassage, useVersion, useTheme } from '@youversion/platform-react-hooks'; import type { BiblePassage, BibleVersion } from '@youversion/platform-core'; @@ -119,3 +121,48 @@ describe('BibleCard - Delayed spinner', () => { ); }); }); + +describe('BibleCard - onFootnotePress callback', () => { + const mockPassageWithFootnote: BiblePassage = { + id: 'JHN.1', + content: `
5The light shines1:5 Or understood.
`, + reference: 'JHN.1', + }; + + beforeEach(() => { + vi.mocked(useTheme).mockReturnValue('light'); + vi.mocked(useVersion).mockReturnValue({ + version: mockVersion, + loading: false, + error: null, + refetch: vi.fn(), + }); + vi.mocked(usePassage).mockReturnValue({ + passage: mockPassageWithFootnote, + loading: false, + error: null, + refetch: vi.fn(), + }); + }); + + it('should call onFootnotePress when provided via BibleCard', async () => { + const onFootnotePress = vi.fn(); + + const { container } = render( + , + ); + + const button = await waitFor(() => { + const btn = container.querySelector('[data-verse-footnote="5"] button'); + expect(btn).not.toBeNull(); + return btn as HTMLButtonElement; + }); + + await userEvent.click(button); + + expect(onFootnotePress).toHaveBeenCalledTimes(1); + const data = onFootnotePress.mock.calls[0]![0] as FootnoteData; + expect(data.verseNum).toBe('5'); + expect(data.reference).toBe('JHN.1'); + }); +}); diff --git a/packages/ui/src/components/bible-card.tsx b/packages/ui/src/components/bible-card.tsx index fd47f71f..c68f9503 100644 --- a/packages/ui/src/components/bible-card.tsx +++ b/packages/ui/src/components/bible-card.tsx @@ -1,5 +1,5 @@ import { usePassage, useVersion, useTheme } from '@youversion/platform-react-hooks'; -import { BibleTextView } from './verse'; +import { BibleTextView, type FootnoteData } from './verse'; import { BibleAppLogoLockup } from './bible-app-logo-lockup'; import { BibleVersionPicker } from './bible-version-picker'; import { Button } from './ui/button'; @@ -32,6 +32,7 @@ export type BibleCardProps = { versionId: number; background?: 'light' | 'dark'; showVersionPicker?: boolean; + onFootnotePress?: (data: FootnoteData) => void; }; function BibleCardHeaderError(): React.ReactNode { @@ -116,6 +117,7 @@ export function BibleCard({ versionId, background, showVersionPicker = false, + onFootnotePress, }: BibleCardProps): React.ReactNode { const [versionNum, setVersionNum] = useState(versionId); const { version } = useVersion(versionNum); @@ -177,6 +179,7 @@ export function BibleCard({ loading: passageLoading, error: passageError, }} + onFootnotePress={onFootnotePress} />