Skip to content

feat(ui): add BibleChapterPicker.Content onSelect + BibleReader onChapterPickerPress#234

Merged
cameronapak merged 3 commits into
mainfrom
feat/chapter-picker-on-select-and-reader-context-threading
May 12, 2026
Merged

feat(ui): add BibleChapterPicker.Content onSelect + BibleReader onChapterPickerPress#234
cameronapak merged 3 commits into
mainfrom
feat/chapter-picker-on-select-and-reader-context-threading

Conversation

@cameronapak
Copy link
Copy Markdown
Collaborator

@cameronapak cameronapak commented May 11, 2026

When working on YPE-2194, we found the React Web SDK needed some additional updates to handle what we need for React Native Expo SDK for the BibleChapterPicker in the BibleReader component, so here's the PR for this!

This MUST be merged before https://github.com/youversion/platform-sdk-reactnative-expo/pull/10

Summary

Adds onSelect callback to BibleChapterPicker.Content and threads onChapterPickerPress through BibleReader.Root context to Toolbar. This enables React Native consumers to intercept chapter selection without using the default popover.

Changes

BibleChapterPicker

  • New BibleChapterPickerSelectData type: Pick<BibleChapterPickerPressData, 'book' | 'chapter' | 'versionId'>
  • New onSelect prop on BibleChapterPicker.Content — fires after internal state updates, before onRequestClose
  • Non-breaking: when onSelect is absent, default popover selection/close behavior is preserved

BibleReader

  • New onChapterPickerPress prop on Root — threaded through context to Toolbar
  • Toolbar passes it to BibleChapterPicker.Root, which suppresses the default popover and delegates to the consumer

Exports

  • BibleChapterPickerSelectData added to barrel (components/index.ts)

Tests

  • bible-chapter-picker.test.tsx: onSelect normal chapter, intro chapter, default popover preserved
  • bible-reader.test.tsx: onChapterPickerPress fires when chapter nav button clicked

Test plan

  • 92/92 existing tests pass
  • Manual: BibleReader with onChapterPickerPress suppresses default popover
  • Manual: BibleChapterPicker.Content onSelect fires with correct payload
  • Downstream: RN Expo SDK uses these hooks to open native sheet (see linked PR)

Downstream

This is a prerequisite for the React Native Expo chapter picker sheet integration.

Greptile Summary

This PR extends BibleChapterPicker.Content with an onSelect callback and threads onChapterPickerPress from BibleReader.Root through context to Toolbar, enabling React Native consumers to intercept chapter selection without triggering the default popover. A changeset file is included and the BibleChapterPickerSelectData type is exported from the barrel.

  • BibleChapterPickerSelectData is now a direct type alias of BibleChapterPickerPressData, exported from components/index.ts for consumer use.
  • onSelect fires synchronously in Content.handleChapterButtonClick after state setters are called (state commits on next render) and before onRequestClose; a data-testid=\"intro-chapter-button\" was added to the intro button to stabilise the new test.
  • onChapterPickerPress is plumbed from BibleReader.Root props → context → ToolbarBibleChapterPicker.Root, suppressing the default popover when present; the new BibleReader test verifies the callback fires and the popover stays hidden.

Confidence Score: 5/5

Safe to merge — the new props are strictly additive and the default popover path is unchanged.

All three changed behaviours (onSelect on Content, onChapterPickerPress threading through BibleReader, and the new exports) are opt-in with no side-effects on existing consumers. The changeset is present, tests cover the new paths including the intro-chapter flow, and the type alias simplification from the prior review round was applied.

No files require special attention.

Important Files Changed

Filename Overview
packages/ui/src/components/bible-chapter-picker.tsx Adds BibleChapterPickerSelectData type alias, onSelect prop on Content, and data-testid on the intro button; logic is correct and non-breaking.
packages/ui/src/components/bible-reader.tsx Threads onChapterPickerPress from Root props through context to Toolbar, correctly forwarded to BibleChapterPicker.Root.
packages/ui/src/components/bible-chapter-picker.test.tsx Three new test cases cover normal chapter onSelect, intro chapter onSelect, and default popover-close preservation; mock data keeps a single book so getByTestId is unambiguous.
packages/ui/src/components/bible-reader.test.tsx New test verifies onChapterPickerPress fires with correct payload when the chapter nav button is clicked and confirms the popover is not shown.
packages/ui/src/components/index.ts Exports BibleChapterPickerSelectData from the barrel; change is minimal and correct.
.changeset/chapter-picker-on-select-and-reader-context-threading.md Adds a minor changeset for @youversion/platform-react-ui, correctly describing the new public API additions.

Sequence Diagram

sequenceDiagram
    participant Consumer
    participant BibleReader.Root
    participant BibleReaderContext
    participant Toolbar
    participant BibleChapterPicker.Root
    participant BibleChapterPicker.Trigger
    participant BibleChapterPicker.Content

    Consumer->>BibleReader.Root: onChapterPickerPress prop
    BibleReader.Root->>BibleReaderContext: store onChapterPickerPress
    BibleReaderContext->>Toolbar: onChapterPickerPress (via context)
    Toolbar->>BibleChapterPicker.Root: onChapterPickerPress prop

    alt onChapterPickerPress provided
        BibleChapterPicker.Root->>BibleChapterPicker.Trigger: render as plain button (no Popover)
        Consumer->>BibleChapterPicker.Trigger: click
        BibleChapterPicker.Trigger->>Consumer: onChapterPickerPress
        Consumer->>BibleChapterPicker.Content: render explicitly with onSelect
        Consumer->>BibleChapterPicker.Content: user clicks chapter
        BibleChapterPicker.Content->>BibleChapterPicker.Content: setBook / setChapter / setSearchQuery
        BibleChapterPicker.Content->>Consumer: onSelect
        BibleChapterPicker.Content->>BibleChapterPicker.Content: onRequestClose?.()
    else no onChapterPickerPress (default)
        BibleChapterPicker.Root->>BibleChapterPicker.Root: wrap children in Popover
        Consumer->>BibleChapterPicker.Trigger: click (opens Popover)
        BibleChapterPicker.Root->>BibleChapterPicker.Content: auto-render inside PopoverContent
        Consumer->>BibleChapterPicker.Content: user clicks chapter
        BibleChapterPicker.Content->>BibleChapterPicker.Content: setBook / setChapter / setSearchQuery
        BibleChapterPicker.Content->>BibleChapterPicker.Root: onRequestClose → setIsPopoverOpen(false)
    end
Loading

Comments Outside Diff (1)

  1. packages/ui/src/components/bible-chapter-picker.tsx, line 197-212 (link)

    P2 onSelect unusable in default popover mode

    When onChapterPickerPress is absent, Root auto-renders Content inside PopoverContent and does not forward any onSelect to it. A consumer who also explicitly renders <BibleChapterPicker.Content onSelect={...} /> as a child will get two Content instances rendered simultaneously — the auto one (inside the popover, fires on click, closes the popover) and the explicit one (always visible, fires onSelect, but never receives onRequestClose). This API contract should be documented or guarded so that onSelect on an explicit Content is only valid when onChapterPickerPress is also provided on Root.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: packages/ui/src/components/bible-chapter-picker.tsx
    Line: 197-212
    
    Comment:
    **`onSelect` unusable in default popover mode**
    
    When `onChapterPickerPress` is absent, `Root` auto-renders `Content` inside `PopoverContent` and does not forward any `onSelect` to it. A consumer who also explicitly renders `<BibleChapterPicker.Content onSelect={...} />` as a child will get two `Content` instances rendered simultaneously — the auto one (inside the popover, fires on click, closes the popover) and the explicit one (always visible, fires `onSelect`, but never receives `onRequestClose`). This API contract should be documented or guarded so that `onSelect` on an explicit `Content` is only valid when `onChapterPickerPress` is also provided on `Root`.
    
    How can I resolve this? If you propose a fix, please make it concise.

    Fix in Claude Code Fix in Cursor

Reviews (3): Last reviewed commit: "fix(ui): address greptile review — simpl..." | Re-trigger Greptile

…pterPickerPress context threading

- Add BibleChapterPickerSelectData type and onSelect callback to Content
- Content fires onSelect after state updates, before onRequestClose
- Thread onChapterPickerPress through BibleReader.Root context to Toolbar
- Export BibleChapterPickerSelectData from barrel
- Tests: onSelect normal/intro chapters, default popover preserved, reader toolbar integration
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 11, 2026

🦋 Changeset detected

Latest commit: fa679e1

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 Minor
vite-react Patch
@youversion/platform-core Minor
@youversion/platform-react-hooks Minor

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

Comment thread packages/ui/src/components/bible-chapter-picker.tsx Outdated
Comment thread packages/ui/src/components/bible-chapter-picker.test.tsx Outdated
Comment thread packages/ui/src/components/index.ts
Copy link
Copy Markdown
Collaborator Author

@cameronapak cameronapak left a comment

Choose a reason for hiding this comment

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

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 3 additional findings.

Open in Devin Review

Copy link
Copy Markdown
Collaborator

@Dustin-Kelley Dustin-Kelley left a comment

Choose a reason for hiding this comment

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

🚀

@cameronapak cameronapak merged commit 0286f7f into main May 12, 2026
6 checks passed
@cameronapak cameronapak deleted the feat/chapter-picker-on-select-and-reader-context-threading branch May 12, 2026 15:44
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