Skip to content

fix(react-native): always assign checkout colors on setConfig - #597

Draft
kieran-osgood-shopify wants to merge 4 commits into
mainfrom
kieran-osgood/rn-reset-checkout-colors
Draft

fix(react-native): always assign checkout colors on setConfig#597
kieran-osgood-shopify wants to merge 4 commits into
mainfrom
kieran-osgood/rn-reset-checkout-colors

Conversation

@kieran-osgood-shopify

@kieran-osgood-shopify kieran-osgood-shopify commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

What am I fixing

  1. iOS: The automatic color scheme showed the background color of whichever explicit scheme ran last. light dark & storefront.
  2. When changing the system color scheme from light to dark on automatic, we'd be left in an inconsistent state with background color not adapting
  3. Sample app was incorrectly reading a value in a non reactive manner (Appearance.getColorScheme) - this meant that re-renders weren't triggered in App.tsx when system scheme changed, leaving stale UI

Simulator Screen Recording - iPhone 15 Pro - 2026-08-06 at 13.33.22.mov (uploaded via Graphite)

How

Cause Fix
The iOS bridge assigned a color only when setConfig supplied that key, this meant when configure was recalled with a null value, it keps the old value. ShopifyCheckoutKit.configuration is process wide, so an omitted key kept the previous value. The automatic and storefront branches of the sample send no colors.ios, so they inherited the last light or dark background. This behaviour came in with the v3 import and stayed latent, because the v3 sample always sent a static colors.ios block, including for automatic. setConfig now calls ShopifyCheckoutKit.configure one time and always assigns tintColor, backgroundColor and closeButtonTintColor. When the config omits a color, the bridge writes the value the host application held before React Native first configured the library. A private static let captures that value, so it survives a Metro reload.
        if let backgroundColorHex = iosConfig?["backgroundColor"] as? String {
            ShopifyCheckoutKit.configuration.backgroundColor = UIColor(hex: backgroundColorHex)
        }

After

 config.backgroundColor = iosConfig?["backgroundColor"].map(UIColor.init(hex:))
                ?? initialConfiguration.backgroundColor

This matches the Android bridge, which already rebuilds the whole appearance per call.

How to test

Review the test video above and perform similar steps, alternating the theme toggle in settings and opening checkout, we should retain good contrast and match theme for the background color of the webview, the header, the title, and the close icon.

You can toggle the shortcut on simulator (ios) with cmd+shift+A - android doesn't have a keyboard shortcut but you can find it in the system tray


Before you merge

Important

  • I've added tests to support my implementation
  • I have read and agree with the Contribution Guidelines
  • I have read and agree with the Code of Conduct
  • I've updated the relevant platform README (platforms/react-native/README.md)

🤖 Generated with Claude Code

@github-actions github-actions Bot added the #gsd:50662 Rebase Checkout Kit on UCP label Aug 6, 2026
@kieran-osgood-shopify
kieran-osgood-shopify force-pushed the kieran-osgood/07-16-featupdatereact-nativetousenewnativecolorschemeproperties branch from b190898 to caaee4a Compare August 6, 2026 13:04

kieran-osgood-shopify commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author


const updatedColors = getColors(
appConfig.colorScheme,
Appearance.getColorScheme(),

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.

this was a non-reactive value meaning it didn't trigger re-renders when system color scheme changed

@kieran-osgood-shopify
kieran-osgood-shopify changed the base branch from kieran-osgood/07-16-featupdatereact-nativetousenewnativecolorschemeproperties to graphite-base/597 August 6, 2026 13:12
@kieran-osgood-shopify
kieran-osgood-shopify force-pushed the kieran-osgood/rn-reset-checkout-colors branch from 486c85a to 76494fb Compare August 6, 2026 13:34
@kieran-osgood-shopify
kieran-osgood-shopify changed the base branch from graphite-base/597 to kieran-osgood/07-16-featupdatereact-nativetousenewnativecolorschemeproperties August 6, 2026 13:35
@kieran-osgood-shopify
kieran-osgood-shopify changed the base branch from kieran-osgood/07-16-featupdatereact-nativetousenewnativecolorschemeproperties to graphite-base/597 August 6, 2026 17:21
kieran-osgood-shopify and others added 4 commits August 6, 2026 19:14
The iOS bridge wrote a color only when `setConfig` supplied it. The
library configuration is process wide, so a call that omitted a color
kept the value from the previous call. An app that moved to the
automatic color scheme, which sends no `colors.ios`, therefore kept the
background color from the last explicit light or dark call.

The bridge now uses `ShopifyCheckoutKit.configure` one time and always
assigns `tintColor`, `backgroundColor` and `closeButtonTintColor`. When
the config omits a color, the bridge restores the value the host
application held before React Native first configured the library.

The sample also seeded the theme store without the app config store, so
`ThemeProvider` pinned the whole app appearance with
`Appearance.setColorScheme`. `useColorScheme` then stopped following the
operating system.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Assisted-By: devx/7d95f963-6589-404b-8a36-2fc413db8f1d
The sample sent a nested light and dark color map for the automatic
scheme on Android, and no map on iOS. The two platforms therefore
disagreed. The sample now sends no color overrides for automatic, so
each native SDK picks its own idiomatic colors.

`getCheckoutKitColors` holds that rule as a pure function next to the
other color helpers in `Theme.tsx`, so a unit test can cover it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Assisted-By: devx/7d95f963-6589-404b-8a36-2fc413db8f1d
`appearanceFor` gated the color override path on a check that requires
four top level color keys. The automatic scheme sends the nested
`{light, dark}` shape, so the check always failed and Android dropped
the overrides. `getColors` already uses the nested aware check, so the
outer gate is now removed and `getColors` decides alone.

An Android app that sends the automatic scheme with valid light and dark
colors now receives them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Assisted-By: devx/7d95f963-6589-404b-8a36-2fc413db8f1d
`checkoutKitConfigDefaults.colorScheme` held `light` while
`defaultAppConfig`, the `ThemeProvider` default value and the fallback at
the `ConfigProvider` call site all held `automatic`. The odd one out won,
because it feeds the `ConfigProvider` config prop.

The field is now gone, so the seed resolves to `automatic` through the
existing fallback. The spread at the `checkoutKitConfig` call site never
used the value, because the theme config always overrides `colorScheme`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Assisted-By: devx/7d95f963-6589-404b-8a36-2fc413db8f1d
@kieran-osgood-shopify
kieran-osgood-shopify force-pushed the kieran-osgood/rn-reset-checkout-colors branch from 368df42 to 9f18066 Compare August 6, 2026 18:20
@kieran-osgood-shopify
kieran-osgood-shopify changed the base branch from graphite-base/597 to main August 6, 2026 18:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

#gsd:50662 Rebase Checkout Kit on UCP

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant