diff --git a/apps/mobile-app/app/(tabs)/_layout.tsx b/apps/mobile-app/app/(tabs)/_layout.tsx
index 0695c815b..4af3abc74 100644
--- a/apps/mobile-app/app/(tabs)/_layout.tsx
+++ b/apps/mobile-app/app/(tabs)/_layout.tsx
@@ -3,6 +3,7 @@ import React, { useEffect } from 'react';
import { Platform, StyleSheet, View } from 'react-native';
import { IconSymbol } from '@/components/ui/IconSymbol';
+import { IconSymbolName } from '@/components/ui/IconSymbolName';
import TabBarBackground from '@/components/ui/TabBarBackground';
import { useColors } from '@/hooks/useColorScheme';
import { useAuth } from '@/context/AuthContext';
@@ -94,7 +95,7 @@ export default function TabLayout() : React.ReactNode {
/**
* Icon for the credentials tab.
*/
- tabBarIcon: ({ color }) => ,
+ tabBarIcon: ({ color }) => ,
}}
/>
,
+ tabBarIcon: ({ color }) => ,
}}
/>
(
-
+
{Platform.OS === 'ios' && authContext.shouldShowIosAutofillReminder && (
1
diff --git a/apps/mobile-app/app/(tabs)/emails/[id].tsx b/apps/mobile-app/app/(tabs)/emails/[id].tsx
index 9d2950274..a924041cf 100644
--- a/apps/mobile-app/app/(tabs)/emails/[id].tsx
+++ b/apps/mobile-app/app/(tabs)/emails/[id].tsx
@@ -13,6 +13,7 @@ import { ThemedText } from '@/components/themed/ThemedText';
import EncryptionUtility from '@/utils/EncryptionUtility';
import { useColors } from '@/hooks/useColorScheme';
import { IconSymbol } from '@/components/ui/IconSymbol';
+import { IconSymbolName } from '@/components/ui/IconSymbolName';
import emitter from '@/utils/EventEmitter';
import { ThemedView } from '@/components/themed/ThemedView';
@@ -384,7 +385,7 @@ export default function EmailDetailsScreen() : React.ReactNode {
{associatedCredential && (
<>
-
+
{associatedCredential.ServiceName}
diff --git a/apps/mobile-app/components/EmailCard.tsx b/apps/mobile-app/components/EmailCard.tsx
index 506f2c317..c93546fbf 100644
--- a/apps/mobile-app/components/EmailCard.tsx
+++ b/apps/mobile-app/components/EmailCard.tsx
@@ -8,6 +8,7 @@ import { MailboxEmail } from '@/utils/types/webapi/MailboxEmail';
import { useDb } from '@/context/DbContext';
import { Credential } from '@/utils/types/Credential';
import { IconSymbol } from '@/components/ui/IconSymbol';
+import { IconSymbolName } from '@/components/ui/IconSymbolName';
type EmailCardProps = {
email: MailboxEmail;
@@ -138,7 +139,7 @@ export function EmailCard({ email }: EmailCardProps) : React.ReactNode {
{associatedCredential && (
-
+
{associatedCredential.ServiceName}
diff --git a/apps/mobile-app/components/ui/IconSymbol.ios.tsx b/apps/mobile-app/components/ui/IconSymbol.ios.tsx
index 555085d9d..5df07a46b 100644
--- a/apps/mobile-app/components/ui/IconSymbol.ios.tsx
+++ b/apps/mobile-app/components/ui/IconSymbol.ios.tsx
@@ -1,8 +1,25 @@
-import { SymbolView, SymbolViewProps, SymbolWeight } from 'expo-symbols';
+import { SymbolView, SymbolWeight } from 'expo-symbols';
import { StyleProp, ViewStyle } from 'react-native';
+import { IconSymbolName } from './IconSymbolName';
/**
- * Icon symbol component.
+ * Mapping from IconSymbolName to SF Symbols names.
+ * This is the iOS-specific translation layer.
+ */
+const SF_SYMBOLS_MAPPING: Record = {
+ [IconSymbolName.Key]: 'key.fill',
+ [IconSymbolName.Envelope]: 'envelope.fill',
+ [IconSymbolName.Gear]: 'gear',
+ [IconSymbolName.House]: 'house.fill',
+ [IconSymbolName.Paperplane]: 'paperplane.fill',
+ [IconSymbolName.ChevronRight]: 'chevron.right',
+ [IconSymbolName.ChevronLeftRight]: 'chevron.left.forwardslash.chevron.right',
+};
+
+/**
+ * Icon symbol component for iOS.
+ * Uses native SF Symbols for optimal performance and consistency.
+ * Handles translation from IconSymbolName to SF Symbols names.
*/
export function IconSymbol({
name,
@@ -11,7 +28,7 @@ export function IconSymbol({
style,
weight = 'regular',
}: {
- name: SymbolViewProps['name'];
+ name: IconSymbolName;
size?: number;
color: string;
style?: StyleProp;
@@ -22,7 +39,7 @@ export function IconSymbol({
weight={weight}
tintColor={color}
resizeMode="scaleAspectFit"
- name={name}
+ name={SF_SYMBOLS_MAPPING[name]}
style={[
{
width: size,
diff --git a/apps/mobile-app/components/ui/IconSymbol.tsx b/apps/mobile-app/components/ui/IconSymbol.tsx
index 920b55b1e..411daf228 100644
--- a/apps/mobile-app/components/ui/IconSymbol.tsx
+++ b/apps/mobile-app/components/ui/IconSymbol.tsx
@@ -2,31 +2,28 @@
import MaterialIcons from '@expo/vector-icons/MaterialIcons';
import React from 'react';
-import { OpaqueColorValue, StyleProp, ViewStyle } from 'react-native';
+import { OpaqueColorValue, StyleProp, TextStyle } from 'react-native';
-// Add your SFSymbol to MaterialIcons mappings here.
-const MAPPING = {
- /*
- * See MaterialIcons here: https://icons.expo.fyi
- * See SF Symbols in the SF Symbols app on Mac.
- */
- 'house.fill': 'home',
- 'paperplane.fill': 'send',
- 'chevron.left.forwardslash.chevron.right': 'code',
- 'chevron.right': 'chevron-right',
-} as Partial<
- Record<
- import('expo-symbols').SymbolViewProps['name'],
- React.ComponentProps['name']
- >
->;
-
-export type IconSymbolName = keyof typeof MAPPING;
+import { IconSymbolName } from './IconSymbolName';
/**
- * An icon component that uses native SFSymbols on iOS, and MaterialIcons on Android and web. This ensures a consistent look across platforms, and optimal resource usage.
- *
- * Icon `name`s are based on SFSymbols and require manual mapping to MaterialIcons.
+ * Mapping from IconSymbolName to MaterialIcons names.
+ * This is the Android-specific translation layer.
+ */
+const MATERIAL_ICONS_MAPPING: Record['name']> = {
+ [IconSymbolName.Key]: 'key',
+ [IconSymbolName.Envelope]: 'mail',
+ [IconSymbolName.Gear]: 'settings',
+ [IconSymbolName.House]: 'home',
+ [IconSymbolName.Paperplane]: 'send',
+ [IconSymbolName.ChevronRight]: 'chevron-right',
+ [IconSymbolName.ChevronLeftRight]: 'code',
+};
+
+/**
+ * An icon component that uses MaterialIcons on Android and web.
+ * This ensures a consistent look across platforms, and optimal resource usage.
+ * Handles translation from IconSymbolName to MaterialIcons names.
*/
export function IconSymbol({
name,
@@ -37,7 +34,7 @@ export function IconSymbol({
name: IconSymbolName;
size?: number;
color: string | OpaqueColorValue;
- style?: StyleProp;
+ style?: StyleProp;
}): React.ReactNode {
- return ;
+ return ;
}
diff --git a/apps/mobile-app/components/ui/IconSymbolName.ts b/apps/mobile-app/components/ui/IconSymbolName.ts
new file mode 100644
index 000000000..572650791
--- /dev/null
+++ b/apps/mobile-app/components/ui/IconSymbolName.ts
@@ -0,0 +1,15 @@
+/**
+ * Enum representing all available icon names in the app.
+ * This provides type safety and consistency across platforms.
+ * The actual icon names for each platform are defined in their respective IconSymbol implementations.
+ */
+export enum IconSymbolName {
+ // Navigation icons
+ Key,
+ Envelope,
+ Gear,
+ House,
+ Paperplane,
+ ChevronRight,
+ ChevronLeftRight,
+}