Welcome to the final chapter of our design system tutorial!
In the previous chapter, Status & Feedback Elements, we learned how to communicate the state of the application (loading, success, failure) to the user.
Now, we face the final challenge of the Command Line Interface (CLI): Discoverability.
In a web app, users know what to do because they see buttons like "Save" or "Cancel." In a terminal, there are no buttons. A user might stare at your screen thinking, "How do I exit? Do I press Esc? Ctrl+C? Q?"
In this chapter, we will build Keyboard Interaction Hints. These are small, standardized text elementsβusually placed at the bottom of the screenβthat teach the user how to control your application.
Imagine playing a new video game. If the game doesn't tell you that "A is Jump" and "B is Attack," you will just mash buttons randomly and get frustrated.
Your CLI tool is the same.
The Solution:
We use a standardized component called <KeyboardShortcutHint>. It formats the key (e.g., "Enter") and the action (e.g., "Save") in a way that is easy to read but visually quiet (dimmed).
Let's imagine we have built a file viewer. We want a footer bar that tells the user their options.
We want to communicate:
We will use our hint component to render these instructions clearly.
There are three simple parts to a hint:
Ctrl+C, Enter, β).Quit, Select, Scroll).KeyboardShortcutHintLet's look at how to use this component in your views.
The component takes two main props: shortcut and action.
import { KeyboardShortcutHint } from './design-system';
// Renders: "q to quit"
<KeyboardShortcutHint
shortcut="q"
action="quit"
/>
By default, the text is standard color. To make it look like a "hint," we usually wrap it in a text container with dimColor. This concept relies on Theme-Aware Primitives.
import { Text } from 'ink';
// Renders a subtle gray hint
<Text dimColor>
<KeyboardShortcutHint shortcut="Esc" action="cancel" />
</Text>
Sometimes, you want the key to stand out more than the action. We can use the bold prop.
// Renders: "Enter to confirm" (where 'Enter' is bold white)
<Text dimColor>
<KeyboardShortcutHint
shortcut="Enter"
action="confirm"
bold
/>
</Text>
Usually, you have more than one command. We can place them side-by-side using a layout box (often called a "Byline" in our system).
import { Box, Text } from 'ink';
<Box gap={2}>
<Text dimColor>
<KeyboardShortcutHint shortcut="β/β" action="navigate" />
</Text>
<Text dimColor>
<KeyboardShortcutHint shortcut="Enter" action="select" />
</Text>
</Box>
Output Visualization:
β/β to navigate Enter to select
The logic here is purely visual. The component takes your strings and assembles them into a localized format.
( ) or bold text.
Let's look at the source code for KeyboardShortcutHint.tsx. It is a functional stateless component.
We define exactly what we need to render the hint.
// KeyboardShortcutHint.tsx
type Props = {
shortcut: string; // e.g. "Enter"
action: string; // e.g. "submit"
parens?: boolean; // Should we wrap in ( )?
bold?: boolean; // Should the key be bold?
};
First, we decide how to render the shortcut part. If bold is true, we wrap it in a Text component.
// Inside the component function
const shortcutText = bold ? (
<Text bold>{shortcut}</Text>
) : (
shortcut
);
Beginner Note: We store the result in a variable shortcutText. This variable might hold a simple string 'x' or a complex React Element <Text bold>x</Text>. React handles both perfectly.
Finally, we combine the parts. We check the parens prop to see if we need to add brackets.
// Inside the component function
if (parens) {
return (
<Text>({shortcutText} to {action})</Text>
);
}
// Standard render
return (
<Text>{shortcutText} to {action}</Text>
);
Why is this separate?
You might wonder, "Why not just type this manually?"
By creating a component, we ensure that the word "to" is always consistent. We ensure spacing is always consistent. If we ever want to change the format to key: action (e.g., "Enter: Confirm") in the future, we only have to change this one file, and the entire app updates.
Congratulations! You have completed the Design System Tutorial.
You have built a complete UI kit for your CLI application:
With these tools, you can build terminal applications that don't just "work"βthey feel professional, cohesive, and user-friendly.
Go forth and build beautiful CLIs!
Generated by Code IQ