react-native-sop-docs/04-design-integration/icons-fonts.md

6.4 KiB

Icons & Fonts

App Icon & Splash Screen

Generate App Icons

Using IconKitchen or manually:

  1. Android: Place icons in android/app/src/main/res/mipmap-*
  2. iOS: Use Xcode Asset Catalog in ios/SaayamApp/Images.xcassets

Android Icon Sizes:

  • mipmap-mdpi: 48x48px
  • mipmap-hdpi: 72x72px
  • mipmap-xhdpi: 96x96px
  • mipmap-xxhdpi: 144x144px
  • mipmap-xxxhdpi: 192x192px

iOS Icon Sizes:

  • iPhone: 60x60pt (120x120px, 180x180px)
  • iPad: 76x76pt (152x152px, 228x228px)
  • App Store: 1024x1024px

Splash Screen Setup

Install react-native-splash-screen:

yarn add react-native-splash-screen

Android Configuration:

  1. Create android/app/src/main/res/drawable/launch_screen.xml:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/primary_color" />
    <item
        android:width="200dp"
        android:height="200dp"
        android:drawable="@mipmap/launch_icon"
        android:gravity="center" />
</layer-list>
  1. Update android/app/src/main/res/values/styles.xml:
<resources>
    <style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
        <item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
    </style>
    
    <style name="SplashTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowBackground">@drawable/launch_screen</item>
    </style>
</resources>

iOS Configuration:

  1. Create LaunchScreen.storyboard in Xcode
  2. Add your logo and configure constraints

Custom Fonts

Font Installation

Add fonts to project:

  1. Create src/assets/fonts/ directory
  2. Add font files (.ttf, .otf)
  3. Configure for each platform

Android Configuration:

  1. Copy fonts to android/app/src/main/assets/fonts/
  2. Use font family name in styles

iOS Configuration:

  1. Add fonts to Xcode project
  2. Update ios/SaayamApp/Info.plist:
<key>UIAppFonts</key>
<array>
    <string>Montserrat-Regular.ttf</string>
    <string>Montserrat-Bold.ttf</string>
    <string>Montserrat-SemiBold.ttf</string>
</array>

Font Helper

// src/utils/fontHelper.ts
import {Platform} from 'react-native';

export const FontFamily = {
  regular: Platform.select({
    ios: 'Montserrat-Regular',
    android: 'Montserrat-Regular',
  }),
  medium: Platform.select({
    ios: 'Montserrat-Medium',
    android: 'Montserrat-Medium',
  }),
  semiBold: Platform.select({
    ios: 'Montserrat-SemiBold',
    android: 'Montserrat-SemiBold',
  }),
  bold: Platform.select({
    ios: 'Montserrat-Bold',
    android: 'Montserrat-Bold',
  }),
};

export const getFontFamily = (weight: 'regular' | 'medium' | 'semiBold' | 'bold' = 'regular'): string => {
  return FontFamily[weight] || FontFamily.regular;
};

Icon Font Generation

Using IcoMoon

  1. Visit IcoMoon.io
  2. Import SVG icons
  3. Generate font
  4. Download and integrate

IcoMoon Integration:

// src/config/iconFont.ts
import {createIconSetFromIcoMoon} from 'react-native-vector-icons/lib/create-icon-set-from-icomoon';
import icoMoonConfig from '../assets/fonts/selection.json';

export const CustomIcon = createIconSetFromIcoMoon(
  icoMoonConfig,
  'CustomIcons',
  'CustomIcons.ttf'
);

Custom Icon Component

// src/components/common/CustomIcon/CustomIcon.tsx
import React from 'react';
import {createIconSetFromIcoMoon} from 'react-native-vector-icons/lib/create-icon-set-from-icomoon';
import icoMoonConfig from '@assets/fonts/selection.json';

const IconFont = createIconSetFromIcoMoon(
  icoMoonConfig,
  'SaayamIcons',
  'SaayamIcons.ttf'
);

interface CustomIconProps {
  name: string;
  size?: number;
  color?: string;
  style?: any;
  onPress?: () => void;
}

export const CustomIcon: React.FC<CustomIconProps> = ({
  name,
  size = 24,
  color = '#000',
  style,
  onPress,
}) => {
  return (
    <IconFont
      name={name}
      size={size}
      color={color}
      style={style}
      onPress={onPress}
    />
  );
};

Icon Library Setup

// src/config/icons.ts
export const IconLibrary = {
  // Navigation icons
  home: 'home',
  profile: 'user',
  settings: 'settings',
  back: 'arrow-left',
  
  // Action icons
  add: 'plus',
  edit: 'edit',
  delete: 'trash',
  save: 'check',
  cancel: 'x',
  
  // Status icons
  success: 'check-circle',
  error: 'x-circle',
  warning: 'alert-triangle',
  info: 'info',
  
  // Social icons
  facebook: 'facebook',
  google: 'google',
  apple: 'apple',
  
  // Feature icons
  camera: 'camera',
  gallery: 'image',
  location: 'map-pin',
  notification: 'bell',
  search: 'search',
  filter: 'filter',
  share: 'share',
  favorite: 'heart',
  star: 'star',
};

export type IconName = keyof typeof IconLibrary;

Dynamic Icon Loading

// src/utils/iconLoader.ts
import {IconLibrary, IconName} from '@config/icons';

export class IconLoader {
  private static loadedIcons: Set<string> = new Set();

  static async preloadIcons(iconNames: IconName[]): Promise<void> {
    const promises = iconNames.map(async (iconName) => {
      if (!this.loadedIcons.has(iconName)) {
        // Preload icon font glyphs
        await this.loadIcon(iconName);
        this.loadedIcons.add(iconName);
      }
    });

    await Promise.all(promises);
  }

  private static async loadIcon(iconName: IconName): Promise<void> {
    // Implementation depends on your icon font setup
    return new Promise((resolve) => {
      // Simulate icon loading
      setTimeout(resolve, 10);
    });
  }

  static isIconLoaded(iconName: IconName): boolean {
    return this.loadedIcons.has(iconName);
  }
}

Font Size Scaling

// src/utils/fontScaling.ts
import {Dimensions, PixelRatio} from 'react-native';

const {width: SCREEN_WIDTH} = Dimensions.get('window');
const BASE_WIDTH = 375; // iPhone 6/7/8 width

export const fontSizer = (size: number): number => {
  const scale = SCREEN_WIDTH / BASE_WIDTH;
  const newSize = size * scale;
  
  // Ensure minimum readable size
  const minSize = size * 0.8;
  const maxSize = size * 1.2;
  
  return Math.max(minSize, Math.min(maxSize, Math.round(PixelRatio.roundToNearestPixel(newSize))));
};

export const FontSizes = {
  xs: fontSizer(10),
  sm: fontSizer(12),
  base: fontSizer(14),
  lg: fontSizer(16),
  xl: fontSizer(18),
  '2xl': fontSizer(20),
  '3xl': fontSizer(24),
  '4xl': fontSizer(28),
  '5xl': fontSizer(32),
};