Skip to content

Fix component logic and layout issues#39

Open
truongnat wants to merge 1 commit into
developfrom
fix/rnui-improvements-8189875729362001993
Open

Fix component logic and layout issues#39
truongnat wants to merge 1 commit into
developfrom
fix/rnui-improvements-8189875729362001993

Conversation

@truongnat

@truongnat truongnat commented Apr 4, 2026

Copy link
Copy Markdown
Owner

Resolves multiple logical errors and layout issues across RNUI components including Marquee, AnimatedList, and SegmentedControl, aligning with stability improvements from the codebase audit.


PR created automatically by Jules for task 8189875729362001993 started by @truongnat


🔧 This PR fixes critical component logic and layout issues across three RNUI components (AnimatedList, Marquee, and SegmentedControl) by replacing fragile timing-based approaches with deterministic layout-driven solutions. The changes eliminate race conditions, improve rendering stability, and add proper fallback mechanisms for component recycling.

🔍 Detailed Analysis

Key Changes

  • AnimatedList: Added default keyExtractor fallback to prevent item recycling issues when data lacks proper identifiers
  • Marquee Component: Replaced unreliable setTimeout/measure pattern with deterministic onLayout hooks for container and content sizing
  • SegmentedControl: Fixed layout flash by ensuring both segmentWidth and containerWidth are available before showing indicator
  • Dependencies: Added @shopify/flash-list v2.3.1 and updated tsup to v8.5.1 across workspaces

Technical Implementation

sequenceDiagram
    participant App as Application
    participant AL as AnimatedList
    participant M as Marquee
    participant SC as SegmentedControl
    
    App->>AL: Render with data
    AL->>AL: Apply keyExtractor fallback
    Note over AL: item?.id || item?.key || String(index)
    
    App->>M: Mount Marquee
    M->>M: onLayout (container)
    M->>M: onLayout (content)
    M->>M: Start animation when both sizes available
    Note over M: Eliminates setTimeout race condition
    
    App->>SC: Render SegmentedControl
    SC->>SC: Wait for segmentWidth AND containerWidth
    SC->>SC: Show indicator only when both ready
    Note over SC: Prevents layout flash
Loading

Impact

  • Stability Improvement: Eliminates race conditions in Marquee component by using layout events instead of arbitrary timeouts
  • Performance Enhancement: Prevents unnecessary re-renders and layout flashes in SegmentedControl
  • Data Integrity: Ensures proper item recycling in AnimatedList through robust key extraction
  • Maintainability: Replaces fragile measurement patterns with deterministic layout-driven approaches

Created with Palmier


Summary by cubic

Fixes logic and layout issues in Marquee, AnimatedList, and SegmentedControl to remove flicker, recycling glitches, and unreliable animations. Improves stability by using deterministic layout measurements and safer defaults.

  • Bug Fixes

    • Marquee: Replace timeout/measure with onLayout; cache container/content sizes; start/resume only when sizes are known; cancel animations on unmount.
    • AnimatedList: Add default keyExtractor (item.id || item.key || String(index)) to avoid recycling issues with @shopify/flash-list.
    • SegmentedControl: Show indicator only when both segmentWidth and containerWidth are ready to prevent layout flash.
  • Dependencies

    • Add @shopify/flash-list to the workspace.

Written for commit 043d54f. Summary will update on new commits.

- AnimatedList: add default keyExtractor fallback to prevent recycling issues
- SegmentedControl: fix layout flash by waiting for containerWidth
- Marquee: replace fragile setTimeout/measure with deterministic onLayout hooks

Co-authored-by: truongnat <87919564+truongnat@users.noreply.github.com>
@google-labs-jules

Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@vercel

vercel Bot commented Apr 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
rnui-docs Ready Ready Preview, Comment Apr 4, 2026 0:45am

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

1 issue found across 9 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/ui/src/components/AnimatedList/AnimatedList.tsx">

<violation number="1" location="packages/ui/src/components/AnimatedList/AnimatedList.tsx:108">
P2: Use nullish coalescing for key fallback so valid falsy IDs (e.g. 0) are not replaced by index-based keys.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

ref={ref}
data={data}
renderItem={(info: any) => <AnimatedCell {...info} />}
keyExtractor={(item: any, index: number) => item?.id || item?.key || String(index)}

@cubic-dev-ai cubic-dev-ai Bot Apr 4, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: Use nullish coalescing for key fallback so valid falsy IDs (e.g. 0) are not replaced by index-based keys.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/ui/src/components/AnimatedList/AnimatedList.tsx, line 108:

<comment>Use nullish coalescing for key fallback so valid falsy IDs (e.g. 0) are not replaced by index-based keys.</comment>

<file context>
@@ -105,6 +105,7 @@ function AnimatedListInner<T>(
             ref={ref}
             data={data}
             renderItem={(info: any) => <AnimatedCell {...info} />}
+            keyExtractor={(item: any, index: number) => item?.id || item?.key || String(index)}
             {...flashListProps}
             contentContainerStyle={useMemo(() => [
</file context>
Suggested change
keyExtractor={(item: any, index: number) => item?.id || item?.key || String(index)}
keyExtractor={(item: any, index: number) => String(item?.id ?? item?.key ?? index)}
Fix with Cubic

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