Skip to content

fix: do not scan custom wrappers for GleamView.Line - #8

Merged
RamboWasReal merged 1 commit into
cursor/improvements-audit-6a43from
cursor/fix-line-scan-regression-e278
Aug 27, 2026
Merged

fix: do not scan custom wrappers for GleamView.Line#8
RamboWasReal merged 1 commit into
cursor/improvements-audit-6a43from
cursor/fix-line-scan-regression-e278

Conversation

@RamboWasReal

Copy link
Copy Markdown
Owner

Summary

Regression fix for #7 (cursor/improvements-audit-6a43).

scanLineChildren walked every component's props.children. That is too broad: a parent GleamView entered Line mode (plain View, no block shimmer) when GleamView.Line appeared in a custom wrapper's children even if those Lines:

  • bind to a nested GleamView (nearest-ancestor contract), or
  • are never mounted (hidden tab/panel, etc.).

On main, only direct children and Fragments were inspected; custom wrappers used registerLine after mount. First-render detection is kept for the documented case (<View> / Fragment). Custom components are left to registration.

Repro (before this fix, on #7)

function SkeletonCard({ children }) {
  return <GleamView testID="inner" loading>{children}</GleamView>;
}

<GleamView testID="outer" loading>
  <SkeletonCard>
    <GleamView.Line><Text>Title</Text></GleamView.Line>
  </SkeletonCard>
</GleamView>

Expected (main + docs): outer stays a native shimmer; Line binds to inner.
Actual on #7: outer became a plain View (loading undefined) — parent shimmer gone.

What changed

  • Recurse only through React.Fragment and View
  • Tests for nested-GleamView composition, unmounted Line children, View vs custom wrappers
  • README / CHANGELOG wording aligned with that scope

No native iOS/Android changes. No new JS dependencies.

Verification

  • yarn test — 100 passed
  • yarn typecheck
  • yarn lint
  • yarn prepare

Residual risks on #7 (not fixed here — not regressions vs main)

  • useReduceMotion() starts false, then flips async → NativeGleamView remounts to static View (ref churn; onTransitionEnd not on the static path)
  • Line-mode parent accessibilityState is applied then overwritten by {...viewProps} (busy is still set on Lines)
  • gleamAccessibilityState forces busy: true while loading, including over a caller busy: false
Open in Web Open in Cursor 

Recursive Line detection walked every component's children, so a parent
GleamView entered Line mode when those Lines actually belonged to a nested
GleamView (or were never mounted). Only View and Fragment are transparent
for first-render detection; custom wrappers still register after mount.

Co-authored-by: David Boutin <RamboWasReal@users.noreply.github.com>
@RamboWasReal
RamboWasReal marked this pull request as ready for review August 27, 2026 17:16
@RamboWasReal
RamboWasReal merged commit 04e31da into cursor/improvements-audit-6a43 Aug 27, 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.

2 participants