ratatui_ruby 0.10.2 → 1.0.0.pre.beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ratatui_ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.2
4
+ version: 1.0.0.pre.beta.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kerrick Long
@@ -24,19 +24,19 @@ dependencies:
24
24
  - !ruby/object:Gem::Version
25
25
  version: '0.9'
26
26
  - !ruby/object:Gem::Dependency
27
- name: ostruct
27
+ name: rexml
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - "~>"
31
31
  - !ruby/object:Gem::Version
32
- version: '0.6'
32
+ version: '3.4'
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: '0.6'
39
+ version: '3.4'
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: rake-compiler
42
42
  requirement: !ruby/object:Gem::Requirement
@@ -93,8 +93,309 @@ dependencies:
93
93
  - - ">="
94
94
  - !ruby/object:Gem::Version
95
95
  version: '1.0'
96
- description: ratatui_ruby is a wrapper for the Ratatui Rust crate <https://ratatui.rs>.
97
- It allows you to cook up Terminal User Interfaces in Ruby.
96
+ description: |2-
97
+
98
+ == Terminal UIs, the Ruby Way
99
+
100
+ RatatuiRuby[https://rubygems.org/gems/ratatui_ruby] is a RubyGem built on
101
+ Ratatui[https://ratatui.rs], a leading TUI library written in
102
+ Rust[https://rust-lang.org]. You get native performance with the joy of Ruby.
103
+
104
+ gem install ratatui_ruby
105
+
106
+ {rdoc-image:https://ratatui-ruby.dev/hero.gif}[https://www.ratatui-ruby.dev/docs/v0.10/examples/app_cli_rich_moments/README_md.html]
107
+
108
+ === Rich Moments
109
+
110
+ Add a spinner, a progress bar, or an inline menu to your CLI script. No
111
+ full-screen takeover. Your terminal history stays intact.
112
+
113
+ ==== Inline Viewports
114
+
115
+ Standard TUIs erase themselves on exit. Your carefully formatted CLI output
116
+ disappears. Users lose their scrollback.
117
+
118
+ <b>Inline viewports</b> solve this. They occupy a fixed number of lines, render
119
+ rich UI, then leave the output in place when done.
120
+
121
+ Perfect for spinners, menus, progress indicators—any brief moment of richness.
122
+
123
+ require "ratatui_ruby"
124
+
125
+ RatatuiRuby.run(viewport: :inline, height: 1) do |tui|
126
+ until connected?
127
+ status = tui.paragraph(text: "\#{spin} Connecting...")
128
+ tui.draw { |frame| frame.render_widget(status, frame.area) }
129
+ end
130
+ end
131
+
132
+ === Build Something Real
133
+
134
+ Full-screen applications with {keyboard and mouse input}[https://www.ratatui-ruby.dev/docs/v0.10/examples/app_all_events/README_md.html]. The managed loop
135
+ sets up the terminal and restores it on exit, even after crashes.
136
+
137
+ RatatuiRuby.run do |tui|
138
+ loop do
139
+ tui.draw do |frame|
140
+ frame.render_widget(
141
+ tui.paragraph(text: "Hello, RatatuiRuby!", alignment: :center),
142
+ frame.area
143
+ )
144
+ end
145
+
146
+ case tui.poll_event
147
+ in { type: :key, code: "q" } then break
148
+ else nil
149
+ end
150
+ end
151
+ end
152
+
153
+ ==== Widgets included:
154
+
155
+ [Layout]
156
+ {Block}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_block/README_md.html],
157
+ {Center}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_center/README_md.html],
158
+ {Clear (Popup, Modal)}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_popup/README_md.html],
159
+ {Layout (Split, Grid)}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_layout_split/README_md.html],
160
+ {Overlay}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_overlay/README_md.html]
161
+ [Data]
162
+ {Bar Chart}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_barchart/README_md.html],
163
+ {Chart}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_chart/README_md.html],
164
+ {Gauge}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_gauge/README_md.html],
165
+ {Line Gauge}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_line_gauge/README_md.html],
166
+ {Sparkline}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_sparkline/README_md.html],
167
+ {Table}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_table/README_md.html]
168
+ [Text]
169
+ {Cell}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_cell/README_md.html],
170
+ {List}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_list/README_md.html],
171
+ {Rich Text (Line, Span)}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_rich_text/README_md.html],
172
+ {Scrollbar (Scroll)}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_scrollbar/README_md.html],
173
+ {Tabs}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_tabs/README_md.html]
174
+ [Graphics]
175
+ {Calendar}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_calendar/README_md.html],
176
+ {Canvas}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_canvas/README_md.html],
177
+ {Map (World Map)}[https://www.ratatui-ruby.dev/docs/v0.10/examples/widget_map/README_md.html]
178
+
179
+ Need something else? {Build custom widgets}[https://www.ratatui-ruby.dev/docs/v0.10/doc/concepts/custom_widgets_md.html] in Ruby!
180
+
181
+
182
+ ---
183
+
184
+ === Testing Built In
185
+
186
+ TUI testing is tedious. You need a headless terminal, event injection,
187
+ snapshot comparisons, and style assertions. RatatuiRuby bundles all of it.
188
+
189
+ require "ratatui_ruby/test_helper"
190
+
191
+ class TestColorPicker < Minitest::Test
192
+ include RatatuiRuby::TestHelper
193
+
194
+ def test_swatch_widget
195
+ with_test_terminal(10, 3) do
196
+ RatatuiRuby.draw do |frame|
197
+ frame.render_widget(Swatch.new(:red), frame.area)
198
+ end
199
+ assert_cell_style 2, 1, char: "█", bg: :red
200
+ end
201
+ end
202
+ end
203
+
204
+ ==== What's inside:
205
+
206
+ - <b>Headless terminal</b> — No real TTY needed
207
+ - <b>Snapshots</b> — Plain text and rich (ANSI colors)
208
+ - <b>Event injection</b> — Keys, mouse, paste, resize
209
+ - <b>Style assertions</b> — Color, bold, underline at any cell
210
+ - <b>Test doubles</b> — Mock frames and stub rects
211
+ - <b>UPDATE_SNAPSHOTS=1</b> — Regenerate baselines in one command
212
+
213
+
214
+ ---
215
+
216
+ ==== Inline Menu Example
217
+
218
+ require "ratatui_ruby"
219
+
220
+ # This example renders an inline menu. Arrow keys select, enter confirms.
221
+ # The menu appears in-place, preserving scrollback. When the user chooses,
222
+ # the TUI closes and the script continues with the selected value.
223
+ class RadioMenu
224
+ CHOICES = ["Production", "Staging", "Development"] # ASCII strings are universally supported.
225
+ PREFIXES = { active: "●", inactive: "○" } # Some terminals may not support Unicode.
226
+ CONTROLS = "↑/↓: Select | Enter: Choose | Ctrl+C: Cancel" # Let users know what keys you handle.
227
+ TITLES = ["Select Environment", # The default title position is top left.
228
+ { content: CONTROLS, # Multiple titles can save space.
229
+ position: :bottom, # Titles go on the top or bottom,
230
+ alignment: :right }] # aligned left, right, or center
231
+
232
+ def call # This method blocks until a choice is made.
233
+ RatatuiRuby.run(viewport: :inline, height: 5) do |tui| # RatauiRuby.run manages the terminal.
234
+ @tui = tui # The TUI instance is safe to store.
235
+ show_menu until chosen? # You can use any loop keyword you like.
236
+ end # `run` won't return until your block does,
237
+ RadioMenu::CHOICES[@choice] # so you can use it synchronously.
238
+ end
239
+ # Classes like RadioMenu are convenient for
240
+ private # CLI authors to offer "rich moments."
241
+
242
+ def show_menu = @tui.draw do |frame| # RatatuiRuby gives you low-level access.
243
+ widget = @tui.paragraph( # But the TUI facade makes it easy to use.
244
+ text: menu_items, # Text can be spans, lines, or paragraphs.
245
+ block: @tui.block(borders: :all, titles: TITLES) # Blocks give you boxes and titles, and hold
246
+ ) # one or more widgets. We only use one here,
247
+ frame.render_widget(widget, frame.area) # but "area" lets you compose sub-views.
248
+ end
249
+
250
+ def chosen? # You are responsible for handling input.
251
+ interaction = @tui.poll_event # Every frame, you receive an event object:
252
+ return choose if interaction.enter? # Key, Mouse, Resize, Paste, FocusGained,
253
+ # FocusLost, or None objects. They come with
254
+ move_by(-1) if interaction.up? # predicates, support pattern matching, and
255
+ move_by(1) if interaction.down? # can be inspected for properties directly.
256
+ quit! if interaction.ctrl_c? # Your application must handle every input,
257
+ false # even interrupts and other exit patterns.
258
+ end
259
+
260
+ def choose # Here, the loop is about to exit, and the
261
+ prepare_next_line # block will return. The inline viewport
262
+ @choice # will be torn down and the terminal will
263
+ end # be restored, but you are responsible for
264
+ # positioning the cursor.
265
+ def prepare_next_line # To ensure the next output is on a new
266
+ area = @tui.viewport_area # line, query the viewport area and move
267
+ RatatuiRuby.cursor_position = [0, area.y + area.height] # the cursor to the start of the last line.
268
+ puts # Then print a newline.
269
+ end
270
+
271
+ def quit! # All of your familiar Ruby control flow
272
+ prepare_next_line # keywords work as expected, so we can
273
+ exit 0 # use them to leave the TUI.
274
+ end
275
+
276
+ def move_by(line_count) # You are in full control of your UX, so
277
+ @choice = (@choice + line_count) % CHOICES.size # you can implement any logic you need:
278
+ end # Would you "wrap around" here, or not?
279
+ #
280
+ def menu_items = CHOICES.map.with_index do |choice, i| # Notably, RatatuiRuby has no concept of
281
+ "\#{prefix_for(i)} \#{choice}" # "menus" or "radio buttons". You are in
282
+ end # full control, but it also means you must
283
+ def prefix_for(choice_index) # implement the logic yourself. For larger
284
+ return PREFIXES[:active] if choice_index == @choice # applications, consider using Rooibos,
285
+ PREFIXES[:inactive] # an MVU framework built with RatatuiRuby.
286
+ end # Or, use the upcoming ratatui-ruby-kit,
287
+ # our object-oriented component library.
288
+ def initialize = @choice = 0 # However, those are both optional, and
289
+ end # designed for full-screen Terminal UIs.
290
+ # RatatuiRuby will always give you the most
291
+ choice = RadioMenu.new.call # control, and is enough for "rich CLI
292
+ puts "You chose \#{choice}!" # moments" like this one.
293
+
294
+ ---
295
+
296
+ === Full App Solutions
297
+
298
+ RatatuiRuby renders. For complex applications, add a framework that manages
299
+ state and composition.
300
+
301
+ ==== Rooibos[https://git.sr.ht/~kerrick/rooibos] (Framework)
302
+
303
+ Model-View-Update architecture. Inspired by Elm, Bubble Tea, and React +
304
+ Redux. Your UI is a pure function of state.
305
+
306
+ - Functional programming with MVU
307
+ - Commands work off the main thread
308
+ - Messages, not callbacks, drive updates
309
+
310
+ ==== {Kit}[https://sr.ht/~kerrick/ratatui_ruby/#chapter-3-the-object-path--kit] (Coming Soon)
311
+
312
+ Component-based architecture. Encapsulate state, input handling, and
313
+ rendering in reusable pieces.
314
+
315
+ - OOP with stateful components
316
+ - Separate UI state from domain logic
317
+ - Built-in focus management & click handling
318
+
319
+ Both use the same widget library and rendering engine. Pick the paradigm
320
+ that fits your brain.
321
+
322
+
323
+ ---
324
+
325
+ === Why RatatuiRuby?
326
+
327
+ Ruby deserves world-class terminal user interfaces. TUI developers deserve
328
+ a world-class language.
329
+
330
+ RatatuiRuby wraps Rust's Ratatui via native extension. The Rust library
331
+ handles rendering. Your Ruby code handles design.
332
+
333
+ >>>
334
+ "Text UIs are seeing a renaissance with many new TUI libraries popping up.
335
+ The Ratatui bindings have proven to be full featured and stable."
336
+
337
+ — {Mike Perham}[https://www.mikeperham.com/], creator of
338
+ Sidekiq[https://sidekiq.org/] and Faktory[https://contribsys.com/faktory/]
339
+
340
+ ==== Why Rust? Why Ruby?
341
+
342
+ Rust excels at low-level rendering. Ruby excels at expressing domain logic
343
+ and UI. RatatuiRuby puts each language where it performs best.
344
+
345
+ ==== Versus CharmRuby
346
+
347
+ CharmRuby[https://charm-ruby.dev/] wraps Charm's Go libraries. Both projects
348
+ give Ruby developers TUI options.
349
+
350
+ [Integration]
351
+ CharmRuby: Two runtimes, one process.
352
+ RatatuiRuby: Native extension in Rust.
353
+ [Runtime]
354
+ CharmRuby: Go + Ruby (competing).
355
+ RatatuiRuby: Ruby (Rust has no runtime).
356
+ [Memory]
357
+ CharmRuby: Two uncoordinated GCs.
358
+ RatatuiRuby: One Garbage Collector.
359
+ [Style]
360
+ CharmRuby: The Elm Architecture (TEA).
361
+ RatatuiRuby: TEA, OOP, or Imperative.
362
+
363
+
364
+ ---
365
+
366
+ === Links
367
+
368
+ [Get Started]
369
+ {Quickstart}[https://www.ratatui-ruby.dev/docs/v0.10/doc/getting_started/quickstart_md.html],
370
+ {Examples}[https://www.ratatui-ruby.dev/docs/v0.10/examples/app_cli_rich_moments/README_md.html],
371
+ {API Reference}[https://www.ratatui-ruby.dev/docs/v0.10/],
372
+ {Guides}[https://www.ratatui-ruby.dev/docs/v0.10/doc/index_md.html]
373
+ [Ecosystem]
374
+ Rooibos[https://git.sr.ht/~kerrick/rooibos],
375
+ {Kit}[https://sr.ht/~kerrick/ratatui_ruby/#chapter-3-the-object-path--kit] (Planned),
376
+ {Framework}[https://sr.ht/~kerrick/ratatui_ruby/#chapter-5-the-framework] (Planned),
377
+ {UI Widgets}[https://sr.ht/~kerrick/ratatui_ruby/#chapter-6-licensing] (Planned)
378
+ [Community]
379
+ {Discuss and Chat}[https://lists.sr.ht/~kerrick/ratatui_ruby-discuss],
380
+ {Announcements}[https://lists.sr.ht/~kerrick/ratatui_ruby-announce],
381
+ {Development}[https://lists.sr.ht/~kerrick/ratatui_ruby-devel],
382
+ {Bug Tracker}[https://todo.sr.ht/~kerrick/ratatui_ruby]
383
+ [Contribute]
384
+ {Contributing Guide}[https://man.sr.ht/~kerrick/ratatui_ruby/contributing.md],
385
+ {Code of Conduct}[https://man.sr.ht/~kerrick/ratatui_ruby/code_of_conduct.md],
386
+ {Project History}[https://man.sr.ht/~kerrick/ratatui_ruby/history/index.md],
387
+ {Pull Requests}[https://lists.sr.ht/~kerrick/ratatui_ruby-devel/patches]
388
+
389
+
390
+ ---
391
+
392
+ [Website] https://www.ratatui-ruby.dev
393
+ [Source] https://git.sr.ht/~kerrick/ratatui_ruby
394
+ [RubyGems] https://rubygems.org/gems/ratatui_ruby
395
+ [Upstream] https://ratatui.rs
396
+ [Build Status] https://builds.sr.ht/~kerrick/ratatui_ruby
397
+
398
+ © 2026 Kerrick Long · Library: LGPL-3.0-or-later · Website: CC-BY-NC-ND-4.0 · Snippets: MIT-0
98
399
  email:
99
400
  - me@kerricklong.com
100
401
  executables:
@@ -119,6 +420,7 @@ files:
119
420
  - LICENSES/MIT-0.txt
120
421
  - LICENSES/MIT.txt
121
422
  - README.md
423
+ - README.rdoc
122
424
  - REUSE.toml
123
425
  - Rakefile
124
426
  - Steepfile
@@ -229,6 +531,12 @@ files:
229
531
  - examples/verify_quickstart_lifecycle/app.rb
230
532
  - examples/verify_readme_usage/README.md
231
533
  - examples/verify_readme_usage/app.rb
534
+ - examples/verify_website_managed/README.md
535
+ - examples/verify_website_managed/app.rb
536
+ - examples/verify_website_menu/README.md
537
+ - examples/verify_website_menu/app.rb
538
+ - examples/verify_website_spinner/README.md
539
+ - examples/verify_website_spinner/app.rb
232
540
  - examples/widget_barchart/README.md
233
541
  - examples/widget_barchart/app.rb
234
542
  - examples/widget_block/README.md