Skip to content

feat: add horizontal slide animation to region selector#24911

Merged
georgewrmarshall merged 9 commits into
mainfrom
region-selector-animation
Jan 21, 2026
Merged

feat: add horizontal slide animation to region selector#24911
georgewrmarshall merged 9 commits into
mainfrom
region-selector-animation

Conversation

@georgewrmarshall
Copy link
Copy Markdown
Contributor

@georgewrmarshall georgewrmarshall commented Jan 19, 2026

Description

Implements a smooth horizontal slide animation for the region selector bottom sheet when drilling down from countries to states and navigating back. This improves the user experience by providing visual feedback that clearly communicates the hierarchical navigation relationship.

What is the reason for the change?
The region selector lacked animation when transitioning between country and state views, making the navigation feel abrupt and unclear to users.

What is the improvement/solution?

  • Replaced conditional rendering with a side-by-side horizontal container pattern where both country and state lists are always mounted
  • Implemented carousel-style horizontal slide animation using a single translateX value
  • Animation slides left (-screenWidth) when drilling down to states, and returns to origin when navigating back
  • 300ms animation duration with Easing.out provides smooth, polished transitions
  • Avoids previous absolute positioning issues that broke FlatList rendering

Changelog

CHANGELOG entry: Added smooth slide animation when selecting regions with states in buy/sell flows

Related issues

Fixes: https://consensyssoftware.atlassian.net/browse/MDP-300

Manual testing steps

```gherkin
Feature: Region selector slide animation

Scenario: user drills down from country to state
Given the app is on the Buy or Sell screen
And the region selector bottom sheet is opened

When user taps "United States of America" (or any country with states)
Then the view smoothly slides left to reveal the state list
And the animation takes 300ms with smooth easing
And the state list is fully visible and scrollable

Scenario: user navigates back from state to country view
Given the region selector is showing the state list

When user taps the back button
Then the view smoothly slides right back to the country list
And the animation takes 300ms with smooth easing

Scenario: user searches in both views
Given the region selector is open

When user searches for a region in country view
Then search results filter correctly

When user taps a country with states
And searches in the state view
Then state search results filter correctly

Scenario: animation performs smoothly
Given the region selector is open

When user rapidly switches between country and state views
Then animations are smooth without lag or visual glitches
And both lists render completely during animation
And no blank frames or overlap issues occur

```

Screenshots/Recordings

Before

No animation - region list would instantly switch between country and state views without visual transition.

region.animation.before720.mov

After

Smooth 300ms horizontal slide animation provides clear visual feedback for drill-down navigation.

region.animation.after72-.mov

Pre-merge author checklist

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Note

Introduces a side-by-side list layout with animated horizontal transitions for clearer navigation between country and state selection.

  • Uses react-native-reanimated with translateX and withTiming to slide between views; adds listContainerOuter/Inner, listPanel, and updated list styles
  • Mounts both FlatList panels simultaneously (countryListRef, stateListRef) and animates the container instead of conditionally rendering views
  • Splits search logic into countryFuseData/stateFuseData with respective countrySearchResults/stateSearchResults; maintains recommended-first sorting when no query
  • Refactors state handling (stateData, activeView, regionInTransit), updates back/close behavior, and keeps scroll-to-top on search changes
  • Replaces snapshot tests with behavioral tests covering rendering, search/clear, empty states, back navigation, state-level search, and recommended sorting

Written by Cursor Bugbot for commit e680c29. This will update automatically on new commits. Configure here.

@georgewrmarshall georgewrmarshall self-assigned this Jan 19, 2026
@github-actions
Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamaskbot metamaskbot added the team-design-system All issues relating to design system in Mobile label Jan 19, 2026
@georgewrmarshall georgewrmarshall changed the title feat: add horizontal slide animation to region selector modal feat: add horizontal slide animation to region selector Jan 19, 2026
georgewrmarshall and others added 8 commits January 20, 2026 13:10
Implement carousel-style horizontal slide animation when drilling down from countries to states in the region selector bottom sheet.

Changes:
- Replace conditional rendering with side-by-side horizontal container pattern
- Use single translateX animation value instead of separate values per list
- Both FlatLists always mounted for instant bidirectional animation
- Container slides left (-screenWidth) for state view, returns to origin for country view
- 300ms animation duration with Easing.out for smooth transitions

Technical improvements:
- Avoid absolute positioning issues that broke FlatList rendering
- Use overflow hidden on outer container to clip off-screen content
- Explicit height constraints ensure proper rendering
- Animation runs on UI thread via react-native-reanimated for 60fps performance

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…tion

Update component snapshots to reflect the new side-by-side container structure used for horizontal slide animation.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@georgewrmarshall georgewrmarshall force-pushed the region-selector-animation branch from 699c1f5 to 29089fa Compare January 20, 2026 21:10
@@ -1,11546 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removing snapshot as I don't think it adds any value here

Comment on lines 139 to 150
it('renders the modal with region list', () => {
const { toJSON } = render(RegionSelectorModal);
expect(toJSON()).toMatchSnapshot();
const { getByText, getByPlaceholderText } = render(RegionSelectorModal);

// Then all regions should be visible
expect(getByText('Portugal')).toBeOnTheScreen();
expect(getByText('France')).toBeOnTheScreen();
expect(getByText('Spain')).toBeOnTheScreen();
expect(getByText('United States of America')).toBeOnTheScreen();

// And the search field should be present
expect(getByPlaceholderText('Search by country')).toBeOnTheScreen();
});
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The tests for this component weren't asserting for what the tests were describing but instead just checking snapshots matched!?

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.

FWIW I think the snapshots are a valid way to test the UI here. Your assertions are fine too but the snapshots should cover it.

@georgewrmarshall georgewrmarshall marked this pull request as ready for review January 20, 2026 22:03
@georgewrmarshall georgewrmarshall requested a review from a team as a code owner January 20, 2026 22:03
@georgewrmarshall georgewrmarshall added team-design-system All issues relating to design system in Mobile and removed team-design-system All issues relating to design system in Mobile labels Jan 20, 2026
cursor[bot]

This comment was marked as outdated.

georgeweiler
georgeweiler previously approved these changes Jan 21, 2026
cursor[bot]

This comment was marked as outdated.

@georgewrmarshall georgewrmarshall force-pushed the region-selector-animation branch from 96ccdf8 to e680c29 Compare January 21, 2026 17:38
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokeRamps
  • Risk Level: low
  • AI Confidence: 85%
click to see 🤖 AI reasoning details

The changes are localized to the RegionSelectorModal component in the Ramp/Aggregator feature. The modifications include:

  1. Animation improvements: Added horizontal slide animation using react-native-reanimated for transitioning between country and state views
  2. Separate FlatLists: Changed from a single reused FlatList to two separate FlatLists (one for countries, one for states) with separate Fuse search instances
  3. Style updates: Added new container styles to support the animated two-panel layout
  4. Unit test updates: Replaced snapshot tests with explicit assertions and added new tests for state search and sorting

These are UI/UX improvements that don't change the core functionality of region selection. The changes are well-contained within the RegionSelectorModal component and its styles.

The SmokeRamps tag is appropriate because:

  • The region selector modal is used in the buy/sell crypto (ramps) flow
  • The offramp-token-amount.spec.ts test (tagged with SmokeRamps) exercises the ramps flow
  • Running this tag will verify that the ramps functionality still works correctly after the animation changes

The risk is low because:

  • Changes are purely UI/UX (animation and layout)
  • No changes to business logic or data handling
  • Unit tests have been updated and cover the new functionality
  • The component is self-contained within the Ramp feature

View GitHub Actions results

Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

@sonarqubecloud
Copy link
Copy Markdown

@georgewrmarshall georgewrmarshall added this pull request to the merge queue Jan 21, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jan 21, 2026
@georgewrmarshall georgewrmarshall added this pull request to the merge queue Jan 21, 2026
Merged via the queue into main with commit 4572630 Jan 21, 2026
92 checks passed
@georgewrmarshall georgewrmarshall deleted the region-selector-animation branch January 21, 2026 20:34
@github-actions github-actions Bot locked and limited conversation to collaborators Jan 21, 2026
@metamaskbot metamaskbot added the release-7.63.0 Issue or pull request that will be included in release 7.63.0 label Jan 21, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-7.63.0 Issue or pull request that will be included in release 7.63.0 size-M team-design-system All issues relating to design system in Mobile

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants