Skip to content

fix(ios): skip imageColor tint when New-Arch defaults it to 0#1200

Open
smsfnxbtww-rgb wants to merge 1 commit into
react-native-menu:masterfrom
smsfnxbtww-rgb:fix/new-arch-image-color-default
Open

fix(ios): skip imageColor tint when New-Arch defaults it to 0#1200
smsfnxbtww-rgb wants to merge 1 commit into
react-native-menu:masterfrom
smsfnxbtww-rgb:fix/new-arch-image-color-default

Conversation

@smsfnxbtww-rgb
Copy link
Copy Markdown

Problem

Under React Native's New Architecture the codegen-generated
MenuViewActionsSubactionsStruct declares int imageColor{0} as
the default. The iOS new-arch bridge unconditionally forwards
imageColor to the Swift layer even when JS didn't pass one. The
Swift unwrap in ios/Shared/RCTMenuItem.swift
if let imageColor = details["imageColor"] { … } — therefore
always succeeds, and RCTConvert.uiColor(0) returns a fully
transparent UIColor. Every SF Symbol passed via image ends up
tinted with rgba(0,0,0,0) — invisible.

Reproduction

Any Expo SDK 55 / RN 0.83 app with New Arch enabled (the default)
on iOS 26+ that passes image without imageColor:

<MenuView
  actions={[{ id: 'share', title: 'Share', image: 'square.and.arrow.up' }]}
></MenuView>

Result: row reads "Share" with empty space where the symbol should
be.

Fix

Gate the tint on (imageColor as? Int) != 0. When the JS side
didn't pass imageColor, the New-Arch default of 0 is detected
and the tint is skipped — UIKit's automatic tinting takes over,
matching pre-bug behavior.

When the JS side explicitly passes imageColor: 0, the symbol is
still tinted with RCTConvert.uiColor(0) (transparent), same as
before. No behavior change for that case.

Confirmation

Verified end-to-end in a production app (Expo SDK 55 / RN 0.83 /
iOS 26.5 / iPhone 17 Pro Simulator) by applying the same diff as a
local patch-package patch. With the patch applied, every menu's
SF Symbols render correctly across the entire app (Compose FAB,
FilterMenu, DetailHeaderMenu, every detail-screen menu,
PublishActionBar, admin list + New / Filter menus).

The change is a one-line guard plus an inline comment explaining the
root cause; no test changes are included because the library
currently has no Swift-side unit tests for RCTMenuAction.init
that would exercise the bridge path. Happy to add one if maintainers
point at a preferred test location.

Related

Closes #1198. Refs #1034, #1002.

Under React Native's New Architecture the codegen-generated
MenuViewActionsSubactionsStruct declares `int imageColor{0}` as
the default. The iOS bridge unconditionally forwards it, so the
Swift unwrap `if let imageColor = details["imageColor"]` always
succeeds — and `RCTConvert.uiColor(0)` returns a fully transparent
UIColor. Result: every SF Symbol passed via `image` renders
invisible on iOS 26 + New Arch.

This guard checks the int value and skips the tint when it's the
default (0). When the JS side explicitly passes imageColor: 0,
the result is unchanged (transparent tint), so no observable
regression for that case.

Closes react-native-menu#1198. Refs react-native-menu#1034, react-native-menu#1002.
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.

Expo SDK55 no icon shown on Menu

1 participant