Change Text Font with `figlet` inside a `react-blessed` Application

AvatarElijah Manor 4 months
479 words 3 min read
The above video is hosted on egghead.io.

This is the 3rd post in a series where we will be creating a developer dashboard in the terminal using react-blessed and react-blessed-contrib. For more information about the series and to take a sneak peak at what we're building, go to the 1st post in the series for more context.

  1. Bootstrap react-blessed Application
  2. Add ESLint Rules to react-blessed App
  3. Change text font with figlet
  4. Extract Component and Add useInterval hook
  5. Fetch and display current weather with weather-js
  6. Extract custom hook to simplify data fetching
  7. Change text color with chalk and gradient-string
  8. Position and Align Text inside a <box> Element
  9. Make a Percentage Based Layout
  10. Layout Dashboard with react-blessed-contrib Grid
... ~10 more lessons to come ...

NOTE: You can find the code for this project in GitHub and you watch the whole Build a Terminal Dashboard with React video series on egghead.io.

Application Before

The beginnings of our Terminal Dashboard is coming along, but it's a tad boring at the moment. It would be nice if we could spice things up by changing the font of the text.

Figlet

Since our application is in the Terminal and we aren't leveraging ReactDOM, we can't use standard CSS to adjust the font of our text. Using a module like figlet enables us to make some visually interesting choices by leveraging ASCII Art. To install figlet, we'll go to our terminal and type npm install figlet.

npm install figlet

Defining the List of Fonts

There are lots of fonts to choose from inside of figlet. You can adjust the kerning and even define your own font!

NOTE: For a list of fonts you can either browse the fonts folder on GitHub or you can console.log(figlet.fontsSync());

import figlet from 'figlet';

const FONTS = [
  'Straight',
  'ANSI Shadow',
  'Shimrod',
  'doom',
  'Big',
  'Ogre',
  'Small',
  'Standard',
  'Bigfig',
  'Mini',
  'Small Script',
  'Small Shadow',
];

Application Tweaks

The first bit of code keeps track of a fontIndex that starts at 0 and is incremented every second. This index will be used later to determine which font to use to render the time.

const [fontIndex, setFontIndex] = React.useState(0);
React.useEffect(() => {
  const timer = setTimeout(() => setFontIndex(fontIndex + 1), 1000);
  return () => clearTimeout(timer);
}, [fontIndex]);

Instead of combining date and time together, we'll split them out so that we can use a special font for the time value.

NOTE: We are using the Date.prototype.toLocaleString() API, which supports lots of locale options. If you've not used it before, it's definitely worth looking into.

const now = new Date();
const date = now.toLocaleString('en-US', {
  month: 'long',
  day: 'numeric',
  year: 'numeric',
});
const time = now.toLocaleString('en-US', {
  hour: '2-digit',
  minute: '2-digit',
  hour12: true,
});

The main change to the app with regards to figlet is to use the figlet.textSync method and pass along the font to use to generate the ASCII Art. In our case we'll take our FONTS array, grab our current fontIndex and mod that with the length of the FONTS array.

const time = figlet.textSync(
now.toLocaleString('en-US', { hour: '2-digit', minute: '2-digit', hour12: true, }),
{
font: FONTS[fontIndex % FONTS.length],
},
);

Application After

Now when we run our application we'll see the date and time render individually and each time the fontIndex is updated a new font will be used!

Conclusion

Adding figlet was a small change to our application thus far, but it's different enough to a standard ReactDOM application that I thought it was important to point it out.

Share article