Change Text Font with `figlet` inside a `react-blessed` Application
July 7, 2020
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.
- Bootstrap react-blessedApplication
- Add ESLint Rules to react-blessedApp
- Change text font with figlet
- Extract Component and Add useIntervalhook
- Fetch and display current weather with weather-js
- Extract custom hook to simplify data fetching
- Change text color with chalkandgradient-string
- Position and Align Text inside a <box>Element
- Make a Percentage Based Layout
- Layout Dashboard with react-blessed-contribGrid
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.
Tweet about this post and have it show up here!