question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Little hack that I made

See original GitHub issue

Hey there. I just made this little code so I can keep all my fonts in a single file, and easily access and use them with Intellisense. I couldn’t find a way to avoid the duplicate writing of the font in import and in the useFontsArg (as this lib also requires). However, still a nice hack!

// A 'fonts.ts' file
import {
  NotoSans_400Regular,
  NotoSans_700Bold
} from '@expo-google-fonts/noto-sans';

import {
  Roboto_400Regular,
  Roboto_500Medium,
  Roboto_700Bold
} from '@expo-google-fonts/roboto';

export { useFonts } from 'expo-font';

export const useFontsArg = {
  NotoSans_400Regular,
  NotoSans_700Bold,
  Roboto_400Regular,
  Roboto_500Medium,
  Roboto_700Bold
};


type PropsToString<Obj> = {
  [K in keyof Obj]: string
}

export const fonts = { ...useFontsArg } as unknown as PropsToString<typeof useFontsArg>;
Object.keys(fonts).forEach((e: any) => (fonts as any)[e] = e );
// App.tsx
export default function App() {
  const [fontsLoaded] = useFonts(useFontsArg);

  if (!fontsLoaded)
    return <AppLoading/>;

  return <Text style={{fonts.Roboto_500Medium}}> Hey! </Text>` // Intellisense guides you! Yay!
}

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:3
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
brandtnewwwcommented, Sep 2, 2020

Thanks so much for sharing, @SrBrahma! I’m already using it 💪

The styles prop should be something like this: style={{ fontFamily: fonts.Roboto_500Medium }} though 👀

0reactions
SrBrahmacommented, Feb 7, 2022

The above had some errors. I made the function I said. It’s used like the following:

import { Platform } from 'react-native';
import { Entypo, MaterialCommunityIcons } from '@expo/vector-icons';
import * as Roboto from '@expo-google-fonts/roboto';

export const { F, Icons, useFonts } = createFontsToLoad({
  fontsToLoad: {
    ...Roboto,
  },
  iconsToLoad: {
    MaterialCommunityIcons,
    Entypo,
  },
  aliasesToSystemFonts: {
    monospace: Platform.OS === 'ios' ? 'Courier' : 'monospace',
  },
});

// On App init
const [loaded, error] = useFonts();

// Font usage
const styles = StyleSheet.create({
  text: {
    fontFamily: F.Roboto_500Medium // Type safe and smart! And loaded!
  },
  monoText: {
    fontFamily: F.monospace
  }
});

// Icon usage. Loaded and quick to switch to other icons!
const component = <Icons.MaterialCommunityIcons ... />
Source
// https://docs.expo.dev/guides/using-custom-fonts/
// I first shared it in here: https://github.com/expo/google-fonts/issues/6
// Aditional fontWeights and to be used on iOS
import { useFonts as expoUseFonts } from 'expo-font';



/** Prettify obj type */
type Id<T> = unknown & { [P in keyof T]: T[P] };

type FontsToLoad = Id<{
  useFonts?: any;
  __metadata__?: any;
  // [x in string]: any
}>;


type SystemAliases = Record<string, string>;
// Simplified version, so we don't need `@expo/vector-icons` pkg to `import { Icon } from '@expo/vector-icons/build/createIconSet'`.
type Icon = {font: Record<string, any>};
type Icons = Record<string, Icon>;

type OmitFontsMeta<F extends FontsToLoad> = Omit<F, '__metadata__' | 'useFonts'>;
/** Omits meta props and converts the other FontsToLoad props to string type. */
type FontsToLoadToFonts<F extends FontsToLoad> = {[K in keyof OmitFontsMeta<F>]: string};
/** @defaul */
type Fonts<F extends FontsToLoad, A extends SystemAliases> = Id<FontsToLoadToFonts<F> & A>;




type FontsToLoadProps<F extends FontsToLoad, I extends Icons, A extends SystemAliases> = {
  /** The fonts to be loaded.
   *
   * @example
   * ```ts
   * // Load whole family
   * import * as Roboto from '@expo-google-fonts/roboto'
   * // Load single font
   * import { Inter_900Black } from '@expo-google-fonts/inter';
   *
   * const { F, useFonts } = createFontsToLoad({
   *   fontsToLoad: {
   *     ...Roboto,
   *     Inter_900Black
   *   }
   * })
   * ```
   * */
  fontsToLoad: F;
  /** Your icons to be loaded/cached on useFonts.
   *
   * @example
   * ```ts
   * import { Entypo, MaterialCommunityIcons } from '@expo/vector-icons';
   *
   * const { I, useFonts } = createFontsToLoad({
   *   iconsToLoad: {
   *     Entypo
   *     MaterialCommunityIcons
   *   }
   * })
   * ```
  */
  iconsToLoad: I;
  /** Manual system fonts aliases to be added to Fonts.
   *
   * System fonts don't need to be loaded, this only adds the alias to Fonts.
   *
   * @example
   * ```ts
   * const { F } = createFontsToLoad({
   *   aliasesToSystemFonts: {
   *     monospace: Platform.OS === 'ios' ? 'Courier' : 'monospace',
   *   }
   * })
   * ```
   *
   *
  */
  aliasesToSystemFonts: A;
};

type FontsToLoadRtn<F extends FontsToLoad, I extends Icons, A extends SystemAliases> = {
  /** Short alias to `Fonts`.
   *
   * To be used in a style like `{fontFamily: F.Roboto_500Medium }` */
   F: Fonts<F, A>;
   /** To be used in a style like `{fontFamily: Fonts.Roboto_500Medium }` */
   Fonts: Fonts<F, A>;
   /** To be used just like the default useFonts(args), without the args. */
   useFonts: () => [fontsLoaded: boolean, error: Error | null];
   /** Short alias to `Icons`.
    *
    * Icons to be used via `<Icons.MaterialCommunityIcons/>`. */
   I: I;
   /** Icons to be used via `<Icons.MaterialCommunityIcons/>`. */
   Icons: I;
};

/** Instead of using the useFonts(fontsArg) hook to get the loaded state, use useMyFonts() on your App start. */
export function createFontsToLoad<F extends FontsToLoad, I extends Icons, A extends SystemAliases>({
  fontsToLoad,
  iconsToLoad,
  aliasesToSystemFonts,
}: FontsToLoadProps<F, I, A>): FontsToLoadRtn<F, I, A> {

  const fontsToLoadInternal = { ...fontsToLoad } as Id<Omit<typeof fontsToLoad, '__metadata__' | 'useFonts'>>;
  // Remove non-font stuff
  delete (fontsToLoadInternal as any).__metadata__;
  delete (fontsToLoadInternal as any).useFonts;

  const iconsFonts = Object.values(iconsToLoad)
    .reduce((obj, icon) => ({ ...obj, ...icon.font }), {} as Record<string, number>);

  const useFontsArg = {
    ...fontsToLoadInternal,
    ...iconsFonts,
  };

  const Fonts = {
    ...Object.fromEntries(Object.keys(fontsToLoadInternal).map((key) => [key, key])),
    ...aliasesToSystemFonts,
  } as Fonts<F, A>;

  const useFonts = () => expoUseFonts(useFontsArg);

  return {
    F: Fonts,
    Fonts,
    useFonts,
    I: iconsToLoad,
    Icons: iconsToLoad,
  };
}

~I am busy right now but eventually will turn it into a npm package. Or, I think it could be added to this lib or any other related Expo lib.~ Edit: It has been released! https://github.com/SrBrahma/expo-font-loader

Read more comments on GitHub >

github_iconTop Results From Across the Web

40+ SMART HACKS to fix little problems in your home
... hack 1:40 Cable hack 2:37 Wire hack 3:04 Brick idea 3:57 Howe to find a screw with magnet This video is made...
Read more >
7 Small Life Hacks That Make a Big Difference - YouTube
Life hacks are creative ways to make everyday tasks simpler. And for people living with multiple sclerosis (MS), simplicity is key.
Read more >
Birth To Death of Four Elements in Real Life by Ha Hack
She tries out little tiny hacks and miniature dollhouse crafts! She also makes money to buy rainbow friends and says yes to dolls...
Read more >
Useful LIFE HACKS that Actually Work - YouTube
Useful LIFE HACKS that Actually Work ! Trying out some do it yourself fun, girly life hacks ! ... Little Lia. Little Lia....
Read more >
Easiest little hack that makes your tv console look so ... - TikTok
432 Likes, TikTok video from Addie Lee (@addieleeh): "Easiest little hack that makes your tv console look so much cleaner #ikea # hack...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found