fix(ramps): fix Transak checkout background color mismatch — native flow (TMCU-1087)#33310
fix(ramps): fix Transak checkout background color mismatch — native flow (TMCU-1087)#33310georgewrmarshall wants to merge 6 commits into
Conversation
PR template — items to address before "Ready for review"Warnings — informational, address before merging:
See docs/readme/ready-for-review.md for the full Definition of Ready for Review. |
🧪 Flaky unit test detection✅ All previously detected unit test flakiness issues in this PR have been fixed. This check is informational only and does not block merging. |
…t (TMCU-1087) Use getElevatedSurfaceColor for Checkout WebView chrome so pure-black dark mode uses bg-alternative and light mode uses bg-default, matching MMDS BottomSheet elevated surfaces. When pure black is enabled, append Transak widget theme params to the buy URL before fetching the provider widget so the hosted checkout background matches the in-app sheet instead of Transak's default charcoal. Co-authored-by: George Marshall <georgewrmarshall@users.noreply.github.com>
c533290 to
39922f2
Compare
Set BottomSheet and WebView background to Transak-specific colors (#1a1a1a dark / #ffffff light) so the sheet matches the iframe content and eliminates the visible color mismatch on open.
|
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. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix prepared fixes for both issues found in the latest run.
- ✅ Fixed: Transak hex ignores pure black
- Replaced Transak hex backgrounds with getElevatedSurfaceColor/useElevatedSurface to respect pure black and match the widget.
- ✅ Fixed: Error sheet missing background class
- Added twClassName={transakBgClassName} to the error BottomSheet for consistent background styling.
Or push these changes by commenting:
@cursor push 1b97efb146
Preview (1b97efb146)
diff --git a/app/components/UI/Ramp/Views/Checkout/Checkout.styles.ts b/app/components/UI/Ramp/Views/Checkout/Checkout.styles.ts
--- a/app/components/UI/Ramp/Views/Checkout/Checkout.styles.ts
+++ b/app/components/UI/Ramp/Views/Checkout/Checkout.styles.ts
@@ -1,19 +1,15 @@
import { StyleSheet } from 'react-native';
-import { Theme, AppThemeKey } from '../../../../../util/theme/models';
-import { colors } from '../../../../../styles/common';
+import { Theme } from '../../../../../util/theme/models';
+import { getElevatedSurfaceColor } from '../../../../../util/theme/themeUtils';
-const styleSheet = (params: { theme: Theme }) => {
- const isDark = params.theme.themeAppearance === AppThemeKey.dark;
- return StyleSheet.create({
+const styleSheet = (params: { theme: Theme }) =>
+ StyleSheet.create({
headerWithoutPadding: {
paddingVertical: 0,
},
webview: {
- backgroundColor: isDark
- ? colors.transakBackgroundDark
- : colors.transakBackgroundLight,
+ backgroundColor: getElevatedSurfaceColor(params.theme),
},
});
-};
export default styleSheet;
diff --git a/app/components/UI/Ramp/Views/Checkout/Checkout.tsx b/app/components/UI/Ramp/Views/Checkout/Checkout.tsx
--- a/app/components/UI/Ramp/Views/Checkout/Checkout.tsx
+++ b/app/components/UI/Ramp/Views/Checkout/Checkout.tsx
@@ -44,9 +44,7 @@
} from '../../headless/headlessEntryNavigation';
import { useStyles } from '../../../../hooks/useStyles';
import styleSheet from './Checkout.styles';
-import { useTheme } from '../../../../../util/theme';
-import { AppThemeKey } from '../../../../../util/theme/models';
-import { colors } from '../../../../../styles/common';
+import { useElevatedSurface } from '../../../../../util/theme/themeUtils';
import Device from '../../../../../util/device';
import { shouldStartLoadWithRequest } from '../../../../../util/browser';
import { CHECKOUT_TEST_IDS } from './Checkout.testIds';
@@ -102,11 +100,7 @@
const navigation = useNavigation();
const params = useParams<CheckoutParams>();
const { styles } = useStyles(styleSheet, {});
- const { themeAppearance } = useTheme();
- const transakBgClassName =
- themeAppearance === AppThemeKey.dark
- ? `bg-[${colors.transakBackgroundDark}]`
- : `bg-[${colors.transakBackgroundLight}]`;
+ const transakBgClassName = useElevatedSurface();
const { addOrder, addPrecreatedOrder, getOrderFromCallback } =
useRampsOrders();
const { trackEvent, createEventBuilder } = useAnalytics();
@@ -669,6 +663,7 @@
goBack={navigation.goBack}
isFullscreen
keyboardAvoidingViewEnabled={false}
+ twClassName={transakBgClassName}
>
{sharedHeader}
<ScreenLayout>You can send follow-ups to the cloud agent here.
Reviewed by Cursor Bugbot for commit abb86f3. Configure here.
…eckout The ScreenLayout component has a hardcoded backgroundColor that was overriding the BottomSheet background, causing a white/grey flash in the error state of the Transak checkout flow.
The ErrorView component was setting backgroundColor: colors.background.default on its screen wrapper, which conflicted with the BottomSheet container background (especially in pure-black mode where the sheet uses bg-alternative). The container is always responsible for the surface color, so ErrorView should be transparent and inherit from its parent.
🔍 Smart E2E Test Selection
click to see 🤖 AI reasoning detailsE2E Test Selection:
All changes are scoped to the Ramp/Checkout UI and affect only the visual appearance of the Transak checkout flow. No functional logic, navigation, or shared infrastructure is modified. The SmokeMoney is the appropriate tag as it covers MetaMask Card and fiat on/off-ramp (ramps) flows, including the checkout experience. No other tags are needed since:
Performance Test Selection: |
| backgroundColor: params.theme.colors.background.default, | ||
| backgroundColor: isDark | ||
| ? colors.transakBackgroundDark | ||
| : colors.transakBackgroundLight, |
There was a problem hiding this comment.
Both the BottomSheet (twClassName) and the WebView (style.backgroundColor) need the same color for different reasons: twClassName sets the container surface so the native chrome matches the iframe, while the WebView background prevents a momentary flash of white or transparent content before Transak's page finishes loading. Centralising both in colors.transak* ensures they always agree.
| isInteractable={!Device.isAndroid()} | ||
| keyboardAvoidingViewEnabled={false} | ||
| twClassName={transakBgClassName} | ||
| > |
There was a problem hiding this comment.
Only the WebView BottomSheet gets the Transak background override — the error state intentionally keeps the default design-system surface (bg-alternative in pure-black, bg-default otherwise). Applying it to the error state would make MetaMask's own error UI appear on a non-standard background with no benefit.
| setError(''); | ||
| isRedirectionHandledRef.current = false; | ||
| lastLoadCompleteUrlRef.current = null; | ||
| loadUrlErrorsRef.current.clear(); |
There was a problem hiding this comment.
ScreenLayout seems more appropriate for pages and set backgroundColor: colors.background.default on its container, which overrode the BottomSheet's surface color and made the error state appear on the wrong background in pure-black mode. Rendering ErrorView directly inside BottomSheet lets the sheet's own surface show through correctly.
Before / After
| @@ -28,7 +28,6 @@ const createStyles = ( | |||
| flex: options?.asScreen ? 1 : undefined, | |||
| justifyContent: 'center', | |||
There was a problem hiding this comment.
Every call site renders ErrorView inside a container that already owns the surface color — either a BottomSheet or a ScreenLayout. Having ErrorView also paint a background caused a visual conflict in pure-black mode where the container surface (bg-alternative) differed from colors.background.default. Making the component transparent keeps the responsibility with the container.
Before / After
| // and outside our control. Used to match the BottomSheet surface so the | ||
| // checkout feels seamless. Update only if Transak changes their theme colors. | ||
| transakBackgroundDark: '#1a1a1a', | ||
| transakBackgroundLight: '#ffffff', |
|
|
Closing in favor of #33429 |









Description
Fixes the Transak checkout BottomSheet background color mismatch in the native unified buy flow (
app/components/UI/Ramp/Views/Checkout/). This was a pre-existing issue that became more visible after the pure-black BottomSheet change.The fix overrides the BottomSheet (
twClassName) and WebView (backgroundColor) to match Transak's iframe theme colors (#1a1a1adark /#fffffflight), sourced from new constants inapp/styles/common.ts, so the native chrome is seamless with the embedded checkout.The
ScreenLayoutwrapper was also removed from the error state — it was paintingcolors.background.defaultover the BottomSheet surface, causing a mismatch in pure-black mode. AndErrorView's own hardcoded background has been removed so the container (BottomSheet or ScreenLayout) is always responsible for the surface color.Changelog
CHANGELOG entry: null
Related issues
Fixes: TMCU-1087
Manual testing steps
Screenshots/Recordings
Before
After
Before
beforeios.mov
After
iOS
afterios.mov
Android
androidafter.mov
Pre-merge author checklist
Performance checks (if applicable)
trace()for usage andaddTokenfor an examplePre-merge reviewer checklist