Overview
Problem
When imageColor is undefined in a MenuAction, processColor(undefined) returns a transparent color (0,0,0,0). This transparent color is then applied as a tint to menu icons using withTintColor(), making the icons completely invisible.
Solution
Check if the color's alpha component is greater than 0 before applying the tint. This prevents transparent colors from being applied, allowing icons to display with their default appearance when imageColor is not provided.
Changes Made
File: ios/Shared/RCTMenuItem.swift
Before:
if let imageColor = details["imageColor"] {
self.image = self.image?.withTintColor(RCTConvert.uiColor(imageColor), renderingMode: .alwaysOriginal)
}
After:
if let imageColor = details["imageColor"] {
let uiColor = RCTConvert.uiColor(imageColor)
// Only apply tint if color is valid and not transparent (alpha > 0)
// processColor(undefined) returns transparent color (0,0,0,0) which makes icons invisible
if let color = uiColor {
var red: CGFloat = 0
var green: CGFloat = 0
var blue: CGFloat = 0
var alpha: CGFloat = 0
if color.getRed(&red, green: &green, blue: &blue, alpha: &alpha) && alpha > 0 {
self.image = self.image?.withTintColor(color, renderingMode: .alwaysOriginal)
}
}
}
Test Plan
Prerequisites
- Create a React Native app or use an existing one
- Install
@react-native-menu/menu package
- Build and run on iOS device or simulator (iOS 13+)
Test Case 1: Menu Icons Without imageColor (Primary Test)
This is the main bug fix - icons should be visible when imageColor is undefined
Test Code:
import { MenuView } from '@react-native-menu/menu';
function TestMenu() {
return (
<MenuView
actions={[
{
id: 'action1',
title: 'Action with icon (no imageColor)',
image: 'heart', // SF Symbol name
// imageColor is undefined - this is the bug case
},
{
id: 'action2',
title: 'Another action',
image: 'star',
// imageColor is undefined
},
]}
onPressAction={(e) => console.log(e.nativeEvent.event)}>
<Pressable>
<Text>Open Menu</Text>
</Pressable>
</MenuView>
);
}
Expected Results:
- ✅ Icons are visible in the menu (heart and star icons appear)
- ✅ Icons display with their default system color
- ✅ Icons are not transparent or invisible
- ✅ Menu items are fully functional
Before Fix:
- ❌ Icons would be invisible/transparent
- ❌ Only empty space would appear where icons should be
Test Case 2: Menu Icons With Valid imageColor
Ensure the fix doesn't break existing functionality
Test Code:
import { MenuView } from '@react-native-menu/menu';
import { processColor } from 'react-native';
function TestMenuWithColor() {
return (
<MenuView
actions={[
{
id: 'action1',
title: 'Action with red icon',
image: 'heart',
imageColor: processColor('red'), // Valid color
},
{
id: 'action2',
title: 'Action with blue icon',
image: 'star',
imageColor: processColor('#007AFF'), // Valid color
},
]}
onPressAction={(e) => console.log(e.nativeEvent.event)}>
<Pressable>
<Text>Open Menu</Text>
</Pressable>
</MenuView>
);
}
Expected Results:
- ✅ Icons are visible and tinted with the specified colors
- ✅ First icon appears in red
- ✅ Second icon appears in blue
- ✅ Tinting works correctly (no regression)
Test Case 3: Menu Icons With Transparent Color
Edge case: explicitly passing transparent color
Test Code:
import { MenuView } from '@react-native-menu/menu';
import { processColor } from 'react-native';
function TestMenuWithTransparent() {
return (
<MenuView
actions={[
{
id: 'action1',
title: 'Action with transparent color',
image: 'heart',
imageColor: processColor('rgba(0,0,0,0)'), // Explicitly transparent
},
]}
onPressAction={(e) => console.log(e.nativeEvent.event)}>
<Pressable>
<Text>Open Menu</Text>
</Pressable>
</MenuView>
);
}
Expected Results:
- ✅ Icon is visible with default system color (tint is not applied)
- ✅ Icon does not become invisible
- ✅ Menu item functions normally
Test Case 4: Menu Without Icons
Regression test: ensure menus without icons still work
Test Code:
import { MenuView } from '@react-native-menu/menu';
function TestMenuNoIcons() {
return (
<MenuView
actions={[
{
id: 'action1',
title: 'Action without icon',
},
{
id: 'action2',
title: 'Another action',
},
]}
onPressAction={(e) => console.log(e.nativeEvent.event)}>
<Pressable>
<Text>Open Menu</Text>
</Pressable>
</MenuView>
);
}
Expected Results:
- ✅ Menu displays correctly without icons
- ✅ No crashes or errors
- ✅ Menu items are functional
Test Case 5: Menu With Subactions
Regression test: ensure subactions work correctly
Test Code:
import { MenuView } from '@react-native-menu/menu';
function TestMenuWithSubactions() {
return (
<MenuView
actions={[
{
id: 'parent',
title: 'Parent Action',
image: 'folder', // No imageColor
subactions: [
{
id: 'child1',
title: 'Child 1',
image: 'doc', // No imageColor
},
{
id: 'child2',
title: 'Child 2',
image: 'doc.text', // No imageColor
},
],
},
]}
onPressAction={(e) => console.log(e.nativeEvent.event)}>
<Pressable>
<Text>Open Menu</Text>
</Pressable>
</MenuView>
);
}
Expected Results:
- ✅ Parent icon is visible
- ✅ Child icons are visible in submenu
- ✅ Submenu opens and closes correctly
- ✅ All actions are functional
Test Case 6: Mixed Menu (Some with imageColor, Some without)
Test Code:
import { MenuView } from '@react-native-menu/menu';
import { processColor } from 'react-native';
function TestMixedMenu() {
return (
<MenuView
actions={[
{
id: 'action1',
title: 'Default icon (no color)',
image: 'heart',
// No imageColor
},
{
id: 'action2',
title: 'Colored icon',
image: 'star',
imageColor: processColor('red'),
},
{
id: 'action3',
title: 'Another default icon',
image: 'trash',
// No imageColor
},
]}
onPressAction={(e) => console.log(e.nativeEvent.event)}>
<Pressable>
<Text>Open Menu</Text>
</Pressable>
</MenuView>
);
}
Expected Results:
- ✅ First icon (heart) is visible with default color
- ✅ Second icon (star) is visible and tinted red
- ✅ Third icon (trash) is visible with default color
- ✅ All icons display correctly
Uh oh!
There was an error while loading. Please reload this page.
Overview
Problem
When
imageColorisundefinedin aMenuAction,processColor(undefined)returns a transparent color(0,0,0,0). This transparent color is then applied as a tint to menu icons usingwithTintColor(), making the icons completely invisible.Solution
Check if the color's alpha component is greater than 0 before applying the tint. This prevents transparent colors from being applied, allowing icons to display with their default appearance when
imageColoris not provided.Changes Made
File:
ios/Shared/RCTMenuItem.swiftBefore:
After:
Test Plan
Prerequisites
@react-native-menu/menupackageTest Case 1: Menu Icons Without imageColor (Primary Test)
This is the main bug fix - icons should be visible when imageColor is undefined
Test Code:
Expected Results:
Before Fix:
Test Case 2: Menu Icons With Valid imageColor
Ensure the fix doesn't break existing functionality
Test Code:
Expected Results:
Test Case 3: Menu Icons With Transparent Color
Edge case: explicitly passing transparent color
Test Code:
Expected Results:
Test Case 4: Menu Without Icons
Regression test: ensure menus without icons still work
Test Code:
Expected Results:
Test Case 5: Menu With Subactions
Regression test: ensure subactions work correctly
Test Code:
Expected Results:
Test Case 6: Mixed Menu (Some with imageColor, Some without)
Test Code:
Expected Results: