Skip to content

YPE-2776 - Make it clear BibleReader is loading when changing chapters#258

Closed
cameronapak wants to merge 1 commit into
mainfrom
YPE-2776-react-sdk-components-bible-reader-show-loading-spinner-when-changing-chapters
Closed

YPE-2776 - Make it clear BibleReader is loading when changing chapters#258
cameronapak wants to merge 1 commit into
mainfrom
YPE-2776-react-sdk-components-bible-reader-show-loading-spinner-when-changing-chapters

Conversation

@cameronapak
Copy link
Copy Markdown
Collaborator

@cameronapak cameronapak commented Jun 4, 2026

PLEASE WATCH VIDEO DEMO

image

Reworked the chapter-change loading state in BibleTextView (packages/ui/src/components/verse.tsx). While the next chapter is fetching, the outgoing chapter's text now fades to 40% opacity in place behind a sticky, viewport-centered spinner, instead of pulsing the stale text. The opacity transition doubles as a fade-in for the incoming chapter.

This avoids the two bad alternatives: a bare spinner (flashes the layout empty then back) and the previous pulsing stale text (reads as active/confusing while the heading already shows the new chapter).

Touched areas: stale-while-revalidate render path, loading overlay, pointer-events/aria-busy placement, updated refetch loading test selector, changeset.

All 70 UI tests pass; typecheck and lint clean.

Completes YPE-2776

🤖 Generated with Claude Code

Greptile Summary

This PR replaces the animate-pulse stale-text loading indicator in BibleTextView with a fade-to-40%-opacity overlay and a sticky viewport-centered spinner, avoiding both the confusing active-stale-text appearance and the flash-of-empty-content a bare spinner would cause.

  • verse.tsx: The stale-while-revalidate render branch wraps the passage content in a transitioning opacity div (aria-busy, pointerEvents: none) and conditionally renders an absolute inset-0 overlay with a sticky spinner; the initial-load-with-no-content path is unchanged.
  • verse.test.tsx: The pointer-events test selector is updated from [data-yv-sdk] to [aria-busy=\"true\"] to match the new DOM structure.
  • .changeset/\u2026: Patch changeset added for @youversion/platform-react-ui.

Confidence Score: 3/5

The sticky spinner is invisible for any chapter taller than the viewport, defeating the overlay's main purpose on the chapters where it matters most.

The loading UX approach is well-structured, but top-1/2 resolves against the absolute overlay height (= full chapter text height) rather than the viewport. For long chapters like Psalm 119, this pins the spinner off-screen immediately, leaving users with only faded text and no visible loading indicator.

packages/ui/src/components/verse.tsx — the sticky spinner positioning at line 580

Important Files Changed

Filename Overview
packages/ui/src/components/verse.tsx Replaces animate-pulse stale-text with fade-to-40%-opacity + sticky spinner overlay; sticky top-1/2 is resolved against the absolute overlay height rather than the viewport, making the spinner invisible for chapters taller than the viewport
packages/ui/src/components/verse.test.tsx Selector in the pointer-events test updated from [data-yv-sdk] to [aria-busy="true"] to match the new DOM structure where aria-busy lives on the inner content wrapper
.changeset/bible-reader-chapter-loading-overlay.md Patch changeset added for @youversion/platform-react-ui with accurate description of the loading UX change

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[BibleTextView render] --> B{currentLoading AND no passage?}
    B -- Yes --> C[Initial load spinner\nfull-screen centered]
    B -- No --> D{currentError?}
    D -- Yes --> E[Error message]
    D -- No --> F[Outer div data-yv-sdk relative]
    F --> G[Inner content div aria-busy transition-opacity]
    G --> H{currentLoading?}
    H -- Yes --> I[opacity-40 pointerEvents none]
    H -- No --> J[opacity-100 normal]
    F --> K{currentLoading?}
    K -- Yes --> L[Overlay div absolute inset-0 pointer-events-none]
    L --> M[Sticky spinner div sticky top-1/2]
    M --> N[LoaderIcon size-8 animate-spin]
    K -- No --> O[null no overlay]
Loading

Fix All in Claude Code Fix All in Cursor Fix All in Codex

Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
packages/ui/src/components/verse.tsx:580-582
**Sticky spinner invisible on long chapters**

`yv:top-1/2` resolves `top: 50%` against the sticky element's *containing block* — the `absolute inset-0` overlay div — whose height equals the entire chapter text height. For any chapter taller than the viewport (e.g. Psalm 119, long Gospels), that threshold exceeds the viewport height, so `position: sticky` pins the spinner below the visible area immediately. Users see only the faded text with no visible loading indicator throughout the scroll.

`yv:top-[50vh]` fixes this — it resolves against the viewport height rather than the chapter height, keeping the spinner at the vertical midpoint of the visible area on chapters of any length.

```suggestion
            <div className="yv:sticky yv:top-[50vh] yv:flex yv:-translate-y-1/2 yv:justify-center">
```

Reviews (1): Last reviewed commit: "YPE-2776 - feat(ui): clarify BibleReader..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

Fade the outgoing chapter text in place behind a sticky, viewport-centered
spinner while the next chapter loads, instead of pulsing the stale text.
Avoids the layout flash a bare spinner would cause and the confusing
stale-but-active text. The opacity transition doubles as a fade-in for the
incoming chapter.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Jun 4, 2026

🦋 Changeset detected

Latest commit: e0881e5

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
vite-react Patch
@youversion/platform-core Patch
@youversion/platform-react-hooks 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 Jun 4, 2026
@cameronapak cameronapak requested a review from Dustin-Kelley June 4, 2026 17:53
Comment on lines +580 to +582
<div className="yv:sticky yv:top-1/2 yv:flex yv:-translate-y-1/2 yv:justify-center">
<LoaderIcon
className="yv:size-8 yv:animate-spin yv:text-muted-foreground"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Sticky spinner invisible on long chapters

yv:top-1/2 resolves top: 50% against the sticky element's containing block — the absolute inset-0 overlay div — whose height equals the entire chapter text height. For any chapter taller than the viewport (e.g. Psalm 119, long Gospels), that threshold exceeds the viewport height, so position: sticky pins the spinner below the visible area immediately. Users see only the faded text with no visible loading indicator throughout the scroll.

yv:top-[50vh] fixes this — it resolves against the viewport height rather than the chapter height, keeping the spinner at the vertical midpoint of the visible area on chapters of any length.

Suggested change
<div className="yv:sticky yv:top-1/2 yv:flex yv:-translate-y-1/2 yv:justify-center">
<LoaderIcon
className="yv:size-8 yv:animate-spin yv:text-muted-foreground"
<div className="yv:sticky yv:top-[50vh] yv:flex yv:-translate-y-1/2 yv:justify-center">
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/ui/src/components/verse.tsx
Line: 580-582

Comment:
**Sticky spinner invisible on long chapters**

`yv:top-1/2` resolves `top: 50%` against the sticky element's *containing block* — the `absolute inset-0` overlay div — whose height equals the entire chapter text height. For any chapter taller than the viewport (e.g. Psalm 119, long Gospels), that threshold exceeds the viewport height, so `position: sticky` pins the spinner below the visible area immediately. Users see only the faded text with no visible loading indicator throughout the scroll.

`yv:top-[50vh]` fixes this — it resolves against the viewport height rather than the chapter height, keeping the spinner at the vertical midpoint of the visible area on chapters of any length.

```suggestion
            <div className="yv:sticky yv:top-[50vh] yv:flex yv:-translate-y-1/2 yv:justify-center">
```

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code Fix in Cursor Fix in Codex

@cameronapak cameronapak closed this Jun 4, 2026
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.

1 participant