typr — Terminal UI Toolkit
typr is a Ruby library for building interactive terminal-based user interfaces. It provides data-object based views and keyboard-driven interaction.
Features
Views
- Grid — sortable, filterable table with formatted columns, colors, and row selection
- Text — scrollable text viewer with word/line picking, search, and borders
- Browser — file-system directory browser with MIME type detection
- Stack, Space — layout containers for composing views
- Line — interactive prompt/input with colored questions and answers
Frontends
typr supports two rendering backends, selectable via require:
- Terminal (
require 'typr') — raw terminal IO, no dependencies beyond Ruby stdlib - Graphical (
require 'typr/graphical') — SDL2-based, for desktop GUI windows
All views work identically across frontends.
Keyboard interaction
Navigation uses hint numbers displayed next to selectable items — rows in grids, columns, or other elements. Press the number to select that item directly. When more items are visible than fit in one set of hints (1-9, 0), press Tab to cycle through hint groups. Arrow keys, Page Up/Down, Home/End work as expected. All keys are dispatched through a configurable keymap.
Installation
gem install typr
Or in your Gemfile:
gem 'typr', '~> 1.0'
Usage
Grid (table)
require 'typr'
Typr.init
@grid = Typr::Grid.new(
input: [
["Alice", 30, "engineer"],
["Bob", 25, "designer"],
["Carol", 35, "manager"]
],
header: ["Name", "Age", "Role"],
format: [:min, :right, :max],
colors: { columns: [:yellow, :cyan, :magenta] }
)
Typr.clear
@grid.draw
key = Typr.read(:key) # reads a single keypress
@grid.reset # reset grid to default view
Typr.exit
Text viewer
require 'typr'
Typr.init
@text = Typr::Text.new(
input: IO.popen(%w[cat /usr/share/dict/words]),
header: "Words",
top: 2, left: 0.1, right: 0.9, bottom: -4,
border: :round,
colors: { header: [:yellow, :grey30] }
)
Typr.clear
loop do
@text.draw
key = Typr.read(:key)
case key
when ?q then break
else @text.send(key) # spacebar scrolls, j/k move up/down, etc.
end
end
Typr.exit
Browser (file picker)
require 'typr'
Typr.init
@browser = Typr::Browser.new(
directory: "/tmp",
right: -1, bottom: -1,
colors: { hints: [:white, :black] }
)
selected = @browser.pick("/home") # interactive file picker, returns path
puts "You selected: #{selected}"
Typr.exit
Combined example (Grid + prompt line)
require 'typr'
class MyApp
include Typr
def initialize
Typr.init
@grid = Typr::Grid.new(
input: [
["Item A", 10, true],
["Item B", 5, false],
["Item C", 20, true]
],
header: ["Name", "Qty", "Active"],
format: [:max, :right, :min],
colors: { columns: [:yellow, :cyan, :green] }
)
@prompt = Typr::Line.new(
top: -1,
default: "(s)ort (f)ilter [esc] quit"
)
end
def run
Typr.clear
loop do
@grid.draw
@prompt.draw
key = Typr.read(:key)
case key
when ?s then @grid.sort_by(@prompt.ask("sort column": [@grid, :column]))
when ?f then @grid.add_filter(*@prompt.ask("filter column": [@grid, :column], with: :line))
when KEY_ESCAPE then break
end
end
end
def shutdown; Typr.exit; end
end
app = MyApp.new
begin
app.run
ensure
app.shutdown
end
API Reference
Typr.init / Typr.exit
Initialize and tear down the terminal UI. Always call these at the start and end of your program.
Typr.clear([scope])
Clears the full screen or a single line (:line).
Typr.read(type)
Reads input from the terminal. Types:
:key— a single keypress (returnsKEY_ESCAPE,?q, etc.):line— a full line of text input
Layout properties (all views)
top,bottom,left,right— placement. Integers for absolute offsets, floats (0-1) for relative sizing. Negative values position from the opposite edge. (bottom: -1= last row)
Grid options
| Option | Description |
|---|---|
input |
Array of arrays (data rows) |
header |
Column titles array |
format |
Per-column format: :min, :max, or a number for fixed width |
colors |
{ columns: [:yellow, :cyan], header: [:white, :black] } etc. |
sorted_by |
Column index the grid is sorted by (setter) |
filters |
Active filters array (getter) |
selected |
Selected row indices (getter/setter) |
.sort_by |
Sort the grid on a given column |
.select_rows / select_columns |
Multi-select via index picker |
Text options
| Option | Description |
|---|---|
input |
String or IO-like stream to display |
header |
Header bar text |
border |
Border style: :round, " ", etc. |
Browser options
| Option | Description |
|---|---|
directory |
Root directory to start browsing |
.pick(start_dir) |
Interactive file picker, returns the selected path |
License
MIT