When building command-line interfaces (CLIs) with React and Ink, one of the key elements is often a menu or select component. While Ink’s ecosystem provides some great out-of-the-box components like ink-select-input
, there’s an outstanding feature that I found lacking: true support for a horizontal orientation. For games and other visually complex terminal applications, a horizontal list of options can save valuable vertical space and create a more natural user experience.
During the development of my text-based RPG, Potion Wars, screen real estate became a primary concern. The game relies heavily on menus and selectors for user input, but vertical lists quickly consume too many lines. By adopting a horizontal layout, I could place menus side-by-side, conserving vertical space and giving the UI more breathing room.
I dug into the existing solutions and discovered an older issue in the ink-select-input
repository calling for horizontal orientation support. Another developer, H3RSKO, created a fork called ink-select-input-horizontal
, but my testing revealed limitations and a few lingering bugs that made it less than ideal for my needs.
To address these issues, I decided to build my own component: ink-enhanced-select-input. This component extends the original idea of ink-select-input
but adds native support for an orientation
prop. With this prop, you can easily switch between a vertical list (the classic style) and a horizontal layout, opening the door to more creative CLI interfaces.
In addition, I’ve added various features and properties over time, as required by Potion Wars’ evolving mechanics:
vertical
or horizontal
for your layout.By developing this component alongside my game, I was able to battle-test it in a real environment, ensuring that it not only worked as expected, but also felt intuitive and stable.
Below are a number of gifs that demonstrate the ink-enhanced-select-input
in action within the tBlackjack
game.
Ink Enhanced Select Input is now published on NPM and available for anyone to integrate into their Ink-based CLIs. It works well, but I’m not stopping there. Here are a few things I’d love to explore in the future:
This project was born from the challenges I encountered and the feedback I received regarding existing solutions. Now that it’s open-source, I’m eager to hear from other developers utilizing Ink!
You can find the repository here on GitHub. Feel free to open issues, suggest enhancements, or submit pull requests!