Skip to content

feat(ui): add Bible Reader search - #396

Open
camrun91 wants to merge 22 commits into
mainfrom
cl/ype-5766_search_ui
Open

camrun91 wants to merge 22 commits into
mainfrom
cl/ype-5766_search_ui

Conversation

@camrun91

@camrun91 camrun91 commented Sep 11, 2026

Copy link
Copy Markdown
Collaborator

Important

This pull request was started by Cameron Llewellyn and passed onto Cameron Pak

Bible Reader search

Adds toolbar search with suggestions, browser-local recents, testament filters, verse previews, and navigation that centers the selected verse while dimming surrounding verses. Hosts can use useBibleSearch headlessly or override the toolbar action with onSearchPress.

Closes YPE-5766. Parent: YPE-5622.

UI views

Current Chromium captures using live API data. Filters expand as an accordion; reduced motion uses a fade.

Trending and recents Suggestions
Trending and recent searches Search suggestions before submission
Results Expanded filters
Verse results with collapsed filters Old Testament, New Testament, and Both filters
Dark mode Dark mode search results and expanded filters

Verification and remaining limitations

  • Full unit suite: 1,435 passed, 2 skipped. Chromium stories: 61 passed. Build/typecheck and lint passed.
  • Inspected live views, keyboard disclosure, reduced motion, and interrupted accordion transitions.
  • Some cross-testament searches hit an API pagination HTTP 400; this remains a retryable failure, not a false empty state. A pagination failure can still appear alongside the verse-preview spinner.
  • New labels use English fallbacks until upstream localization syncs.

RetriggerConfidence Score: 5/5

The PR appears safe to merge.

Summary

The PR adds Bible Reader search across the core API, React hooks, and UI, including suggestions, recents, testament filtering, paginated results, previews, navigation, and transient verse focus. It also completes the previously requested safety and localization fixes.

  • Centralizes bounded USFM reference parsing and rejects unsafe numeric ranges.
  • Adds an exclusive search-session state model with stale-response protection and pagination.
  • Adds accessible search UI, local recents, filters, previews, and selected-verse navigation.
  • Adds tests, styles, exports, release metadata, and CI/tooling updates.

Diagram

sequenceDiagram
  participant User
  participant SearchUI as BibleReaderSearch
  participant Hook as useBibleSearch
  participant Core as SearchClient
  participant Reader as BibleReaderNavigation

  User->>SearchUI: Enter or select query
  SearchUI->>Hook: submit query
  Hook->>Core: searchVerses(query, version, page token)
  Core-->>Hook: validated verse hits
  Hook-->>SearchUI: results and pagination state
  SearchUI->>Reader: navigate to selected USFM reference
  Reader-->>User: center and transiently focus verse
Loading

Reviews (13) · Last reviewed commit: "fix(ci): align release tooling manifests..."

@changeset-bot

changeset-bot Bot commented Sep 11, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 77aa9e6

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

Comment thread packages/core/src/usfm-reference.ts
Comment thread packages/ui/src/i18n/locales/en.json Outdated
Base automatically changed from cl/ype-5750_search_api to main September 14, 2026 16:08
Search hits and the structural validator both need the same chapter/verse
shape. parseUsfmReference owns that grammar so inverted ranges drop at
the boundary instead of leaking into the reader.
The PRD's suggestion-suppression, stale-page, and dedupe rules are
consequences of one SearchSession union plus a pure reducer, so the eight
phases can be proven without timers or network.
Headless hosts get one phase and five commands. Debounce, language-range
gating, and page commits stay inside the hook so UI never sees tokens or
TanStack Query.
Content can scroll and dim only after the destination chapter is on screen. A seq mailbox plus a hold timer keeps focus separate from verse selection.
Hosts get a zero-required-prop search dialog that talks to useBibleSearch and navigates through one Root-owned verse-focus mailbox. English keys land here so the UI can ship; platform-localization still owns the canonical source.
The public helpers and Reader search UI are new surface on core, hooks, and ui, so they ship as minors together.
The first keystroke after submit left the submitted lane while debounce still
held that query. Suggestions then re-fetched it and showed a spinner. Debounce
null while submitted, and skip queriesRequest until the new input settles.
The hold-clear scroll listener sat on the renderer root, which does not
scroll. Listen on the nearest overflow ancestor instead. Drop the unused
focusedVerses return. Content never read it.
@camrun91
camrun91 force-pushed the cl/ype-5766_search_ui branch from 1773708 to b29aaf2 Compare September 14, 2026 21:40
Widen useDebounce test props so null flush typechecks. Wait for the Reader
canvas before clicking Search. Revert human en.json edits and keep English
via t() defaultValue until platform-localization syncs bibleSearch* keys.
Comment thread packages/ui/src/i18n/locales/en.json
The previous CI fix copied en.json from the deleted search API tip, which still differed from main. That kept Locale Ownership red and broke version-picker and verse tests that assert main's English copy.
Unsafe integer endpoints stall `verse += 1` at 2^53 and oversized spans allocate huge arrays. Lock the intended rejection before the parser change.
Number.isInteger accepted 2^53 endpoints, so verse += 1 never advanced and search hits could hang. Reject non-safe integers and spans over 250 verses instead of expanding them.

@cameronapak cameronapak left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Review

YPE-5766

Summary

Standards: 0 must-fix. Spec: 10 must-fix. Primary concern: host navigation is unavailable and automatic scrolling clears selected-verse focus before arrival.

For Agents
  • CI: failing. Integration Tests reports 582 passing assertions and 11 unhandled rejections; the cause is not established. Other build, typecheck, lint, and unit-test checks pass.
  • Bot review: clear; earlier bot findings are resolved.
  • Event: REQUEST_CHANGES
  • HEAD: 9720ea4
  • Spec: the user-supplied artifact of the Search PRD, linked from parent YPE-5622.
  • Verification: 92 existing targeted Vitest tests passed. Three focused regression reproductions failed for result deduplication, stale suggestions, and wildcard fallback. Chromium confirmed automatic scrolling clears focus before arrival. Temporary reproduction fixtures were removed.

Written by Code Reviewer bot on behalf of Cam.

Comment thread packages/ui/src/components/bible-reader.tsx Outdated
Comment thread packages/ui/src/lib/use-transient-verse-focus.ts
Comment thread packages/hooks/src/internal/bible-search-session.ts
Comment thread packages/hooks/src/useBibleSearch.ts
Comment thread packages/ui/src/components/bible-reader-search.tsx
Comment thread packages/hooks/src/useBibleSearch.ts Outdated
Comment thread packages/ui/src/components/bible-reader-search.tsx Outdated
Comment thread packages/ui/src/components/bible-reader-search.tsx
Comment thread packages/hooks/src/internal/bible-search-session.ts Outdated
Comment thread packages/core/src/usfm-reference.ts
Comment thread .size-limit.js

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This change allows for us to be able to easily add Zod to the UI package

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.

3 participants