Changelog
All notable changes to this project will be documented in this file. The format is based on Keep a Changelog. This project adheres to Semantic Versioning.
Unreleased
Added
Changed
Fixed
Removed
0.9.1 - 2026-01-08
Added
-
Constraint Batch Constructors:
Constraintnow provides batch factory methods matching upstream Ratatui for creating constraint arrays in a single call: -
from_lengths([10, 20, 10])— create multiple Length constraints -
from_percentages([25, 50, 25])— create multiple Percentage constraints -
from_mins([5, 10, 5])— create multiple Min constraints -
from_maxes([20, 30, 40])— create multiple Max constraints -
from_fills([1, 2, 1])— create multiple Fill constraints -
from_ratios([[1, 4], [2, 4], [1, 4]])— create multiple Ratio constraints -
Async Synchronization: New
Event::Syncevent andSyntheticEventsmodule enable deterministic testing of async behavior: -
Event::Sync— synthetic event that signals runtimes (Tea, Kit) to wait for pending async operations before continuing -
RatatuiRuby::SyntheticEvents— thread-safe Ruby-only queue for synthetic events; runtimes check this alongside native events -
inject_synctest helper — injects a Sync event for deterministic async testing
Changed
Fixed
Removed
0.9.0 - 2026-01-08
Added
-
State Query Predicates (DWIM DX): Widgets now provide ergonomic predicate methods for querying selection and completion state:
-
List#selected?— returns true if an item is selected -
List#empty?— returns true if the list has no items -
Table#row_selected?,Table#column_selected?,Table#cell_selected?— check selection state -
Table#empty?— returns true if the table has no rows -
Gauge#filled?,Gauge#complete?— check progress state (ratio > 0, ratio >= 1.0) -
LineGauge#filled?,LineGauge#complete?— same as Gauge -
Symbol Constants (DWIM DX): Widgets now expose constants for enum-style parameters, enabling IDE autocomplete and self-documenting code:
-
List::HIGHLIGHT_ALWAYS,HIGHLIGHT_WHEN_SELECTED,HIGHLIGHT_NEVER -
List::DIRECTION_TOP_TO_BOTTOM,DIRECTION_BOTTOM_TO_TOP -
Table::HIGHLIGHT_*— same as List -
Table::FLEX_LEGACY,FLEX_START,FLEX_CENTER,FLEX_END,FLEX_SPACE_BETWEEN,FLEX_SPACE_AROUND,FLEX_SPACE_EVENLY -
Layout::Layout::DIRECTION_VERTICAL,DIRECTION_HORIZONTAL -
Layout::Layout::FLEX_*— same as Table -
TUI API Aliases (DWIM DX): The TUI facade now provides CSS-inspired constraint aliases for cleaner layout code:
-
fixed(n)— alias forconstraint_length(n) -
percent(n)— alias forconstraint_percentage(n) -
flex(n)/fr(n)— aliases forconstraint_fill(n)(Flexbox/Grid-inspired) -
split(...)— alias forlayout_split(...) -
ListState Navigation Methods:
ListStatenow provides ergonomic navigation methods matching upstream Ratatui: -
select_next— select the next item (or first if nothing selected) -
select_previous— select the previous item (or last if nothing selected) -
select_first— jump to the first item -
select_last— jump to the last item -
Rect Methods:
Rectnow provides edge accessors, size queries, geometry transformations, and iterators from upstream Ratatui: -
left,right,top,bottom— edge coordinates -
area,empty?— size queries -
union(other),inner(margin),offset(dx, dy),clamp(bounds)— geometry transformations -
rows,columns,positions— iterators yielding slices or coordinates
Changed
-
License: Library code (
lib/,sig/) relicensed to LGPL-3.0-or-later for proprietary use. LGPL allows proprietary applications to link against the library while keeping library modifications open source. -
License: Documentation code snippets now use MIT-0, letting users copy example code without attribution requirements.
Fixed
Removed
-
assert_snapshot: Removed deprecated test helper. Useassert_plain_snapshotorassert_snapshotsinstead. -
Block#border_color: Removed deprecated parameter. Useborder_style: Style.new(fg: color)for equivalent functionality. -
LineChart: Removed deprecated widget. UseChartwithDataset.new(graph_type: :line)instead. Seeexamples/widget_chart/for usage.
0.8.0 - 2026-01-05
Added
-
Output Guard:
RatatuiRuby.guard_io { }temporarily replaces$stdoutand$stderrwith a null sink, preventing screen corruption from chatty gems. Active whenterminal_active?is true; warns if called outside a session (to catch mistakes); silent no-op in headless mode. -
Headless Mode:
RatatuiRuby.headless!enables batch/CLI mode for apps with--no-tuiflags. When headless,guard_iobecomes a silent no-op andinit_terminal/runraiseError::Invariant. This allows the same code to work in both TUI and non-TUI modes. -
Terminal Safety Hooks:
at_exitandSignal.traphandlers forINTandTERMautomatically restore the terminal if a session is active on unexpected exit. This prevents leaving the terminal in raw mode after Ctrl+C or process termination.
Changed
-
Double
init_terminalNow RaisesError::Invariant(Breaking) Callinginit_terminal,init_test_terminal, orrunwhile a TUI session is already active now raisesError::Invariant. Previously, this was undefined but silently “working” behavior that could cause terminal state corruption. If your code intentionally double-inits, callrestore_terminalfirst.
Fixed
Removed
0.7.4 - 2026-01-05
Added
-
Block Inner Area Calculation:
Block#inner(area)method computes the inner content area given an outerRect, accounting for borders and padding. Essential for layout calculations when you need to know usable space inside a block. -
Deferred Warnings During TUI Sessions: Experimental feature warnings (like
Paragraph#line_count) are now automatically queued during active TUI sessions and flushed to stderr afterrestore_terminal. This prevents warnings from corrupting the TUI display. See doc/troubleshooting/tui_output.md for details on handling terminal output during TUI sessions. -
Session State Tracking:
RatatuiRuby.terminal_active?indicates whether a TUI session is active. Callinginit_terminalorinit_test_terminalwhile a session is already active now raisesError::Invariant. -
Error::Invariant: New error class for state invariant violations (e.g., double-init). Distinct from
Error::Safety(lifetime violations) andError::Terminal(operational I/O failures).
Changed
Fixed
-
Direct Text Rendering:
Text::LineandText::Spancan now be rendered directly as widgets viaframe.render_widget(line, area)without wrapping in aParagraph. Previously, these text primitives were silently ignored when passed torender_widget. -
Text Line Alignment:
Text::Linealignment:parameter is now respected during rendering. Previously, the alignment was ignored and text always rendered left-aligned.
Removed
0.7.3 - 2026-01-04
Added
-
Symbol Shortcuts for
bar_set:SparklineandBarChartnow accept:nine_levels(full 9-character gradient) and:three_levels(simplified empty/half/full) as intuitive shortcuts instead of requiring custom character hashes. -
:half_blockMarker:ChartDatasetnow supports:half_blockmarker for higher resolution rendering using ▀ and ▄ characters. -
assert_snapshotsMethod:RatatuiRuby::TestHelper#assert_snapshots(plural) calls bothassert_plain_snapshotandassert_rich_snapshotwith the same name, generating both.txtand.ansifiles for documentation and display purposes. -
Edge-Center Legend Positions:
Chartlegend_positionnow accepts:top,:bottom,:left, and:rightin addition to the existing corner positions (:top_left,:top_right,:bottom_left,:bottom_right). -
:resetColor:Stylefgandbgnow accept:resetto explicitly clear any inherited foreground or background color, restoring the terminal’s default.
Changed
Deprecated
-
assert_snapshot: Useassert_snapshots(plural) instead, orassert_plain_snapshotif you only need plain text. The old method name lacked clarity about whether it captured plain text or styled ANSI output.
Fixed
Removed
0.7.2 - 2026-01-04
Added
-
Tabs
padding_leftandpadding_right: Now acceptInteger(for spaces),String, orText::Linefor styled padding content. Previously only acceptedInteger. Passing aLineobject allows colored or decorated padding.
Changed
Fixed
-
Styled Text Parsing: Fixed multiple widgets incorrectly rendering styled text objects as Ruby inspect strings (e.g.,
#<data RatatuiRuby::Text::Span...>) instead of their styled content: -
Tabsdivider: Now correctly rendersText::Spanobjects. -
Tablehighlight_symbol: Now correctly rendersText::Spanobjects. -
BarChartBarGrouplabel: Now correctly rendersText::Lineobjects. -
ChartAxistitle: Now correctly rendersText::Lineobjects. -
ChartAxislabels: Now correctly rendersText::Lineobjects. -
ChartDatasetname: Now correctly rendersText::Lineobjects.
Removed
0.7.1 - 2026-01-03
Added
Changed
Fixed
-
Block Title Styling:
Blocktitlecontentnow correctly rendersText::Lineobjects with styled spans. Previously, passing a styledLineas title content displayed its Ruby inspect representation (e.g.,#<data RatatuiRuby::Text::Line...>) instead of the styled text.
Removed
0.7.0 - 2026-01-03
[!WARNING] v0.7.0 contains significant breaking changes. See the Migration Guide for upgrade instructions.
Added
-
Rich Text in Table Cells:
Tablecells (rows, header, footer) now acceptText::SpanandText::Lineobjects for per-character styling, matching List widget capabilities. -
Row Wrapper: New
Widgets::Rowclass allows applying row-level styling (background color, style) and layout properties (height, top_margin, bottom_margin) to Table rows. Table rows can now be plain arrays orWidgets::Rowobjects. -
Cell Wrapper: New
Widgets::Cellclass wraps table cell content with optional cell-level styling. Distinct fromBuffer::Cellwhich is for buffer inspection. -
Line#width Method:
Text::Linenow has awidthinstance method that calculates the display width in terminal cells using unicode-aware measurement. Useful for layout calculations with rich text. -
render_rich_buffer: New
TestHelper::Snapshot#render_rich_buffermethod returns the terminal buffer as an ANSI-encoded string with escape codes for colors and modifiers. Useful for debugging, custom assertions, or programmatic inspection beyondassert_rich_snapshot.
Changed
-
Namespace Restructure (Breaking): Classes reorganized to match Ratatui’s module hierarchy. See Migration Guide for details:
-
(and all other widgets)
-
Session → TUI Rename (Breaking):
RatatuiRuby::Sessionrenamed toRatatuiRuby::TUIto better reflect its role as a facade/DSL. TheTUIclass now uses explicit factory methods (no metaprogramming) for improved IDE autocomplete support. -
Buffer::Cell vs Widgets::Cell (Breaking):
RatatuiRuby::Cell(buffer inspection) renamed toRatatuiRuby::Buffer::Cell. NewRatatuiRuby::Widgets::Celladded for table cell construction. -
Text::Line style field (Breaking):
Text::Linenow accepts astyle:parameter for line-level styling, matching Ratatui’sLinestruct which hasstyle,alignment, andspansfields. -
Table highlight_style → row_highlight_style (Breaking):
Tableparameterhighlight_style:renamed torow_highlight_style:to match Ratatui’s API naming convention.
Fixed
Removed
0.6.0 - 2026-01-03
Added
-
Rich Text Support:
List,Gauge,LineGauge, andBarChartwidgets now accept rich text objects (Text::Span,Text::Line) in addition to plain strings. This enables per-character styling, multi-colored labels, and complex text formatting matching Ratatui 0.30.0 capabilities. -
ListItem Wrapper: New
ListItemdata class allows applying row-level styling (background color) independent of text content.Listitems can now beString,Text::Span,Text::Line, orListItemobjects. -
Non-Blocking Event Polling:
RatatuiRuby.poll_eventnow accepts an optionaltimeout:parameter (Float seconds). Usetimeout: 0.0for non-blocking checks, ortimeout: 0.1for fixed timesteps. Defaults to0.016(16ms) to preserve existing behavior. -
Cursor Positioning:
Frame#set_cursor_position(x, y)sets the terminal’s hardware cursor position. Using this method is essential for input fields where the user expects visual feedback on their cursor location. -
Text Measurement:
RatatuiRuby::Text.width(string)calculates the display width of a string in terminal cells, correctly handling unicode including ASCII (1 cell), CJK full-width characters (2 cells), emoji (typically 2 cells), and zero-width combining marks (0 cells). This is essential for auto-sizing widgets and responsive layouts. Delegates to the same unicode-width logic that Ratatui uses internally. -
Scroll Offset Control:
ListandTablewidgets now accept an optionaloffsetparameter to control the viewport’s scroll position. Use this for passive scrolling (viewing without selection) or calculating click-to-item mappings. When combined with a selection, Ratatui’s natural scrolling may still adjust the viewport to keep the selection visible; set selection tonilfor fully manual scroll control. -
Rect Geometry Helpers:
Rect#intersects?(other)tests whether two rectangles overlap.Rect#intersection(other)returns the overlapping area as a newRect, ornilif disjoint. Essential for viewport clipping and hit testing in component architectures. -
Stateful Rendering:
Frame#render_stateful_widget(widget, area, state)renders widgets with mutable state objects (ListState,TableState,ScrollbarState). State objects persist across frames, enabling scroll offset read-back and selection tracking. Essential for mouse click-to-row hit testing. Precedence rule: State object properties override widget properties (selected_index,offset). -
Full Keyboard Support: Key events now recognize all keys supported by crossterm: function keys (
f1–f24), navigation (home,end,page_up,page_down,insert,delete), locks (caps_lock,scroll_lock,num_lock), system (print_screen,pause,menu), media controls (play,play_pause,track_next, etc.), and individual modifier keys (left_shift,right_control, etc.). Previously unmapped keys returned"unknown"; they now return propersnake_casestrings. -
Key Categories:
Event::Keynow has akindattribute (:standard,:function,:media,:modifier,:system) for logical grouping. Category predicates (media?,system?,function?,modifier?,standard?) enable clean event routing without string parsing. Theunmodified?method is an alias forstandard?. -
Smart Predicates (DWIM): Key predicates now “Do What I Mean” for media keys.
pause?returnstruefor both systempauseandmedia_pausekeys. For strict matching, usemedia_pause?or compareevent.codedirectly. This reduces boilerplate when responding to conceptual actions regardless of input method. -
Modifier Key Predicates: New methods
super?,hyper?, andmeta?check for these modifier keys. Platform aliases are provided forsuper?:command?/cmd?(macOS),win?(Windows), andtux?(Linux). These work for both modifier flags AND individual modifier key events (e.g.,left_super). Additionally,control?aliasesctrl?andoption?aliasesalt?. -
Navigation Aliases: Convenient predicate aliases for common keys:
return?for Enter,back?for Backspace,del?for Delete,ins?for Insert,escape?for Esc,pgup?/pageup?for Page Up,pgdn?/pagedown?for Page Down. The specialreverse_tab?predicate matches both theback_tabkey andshift+tabcombinations. -
Indexed Color Support:
Stylenow supportsIntegervalues forfgandbg, allowing use of the Xterm 256-color palette (0-255). This includes standard ANSI colors (0-15), the 6x6x6 color cube (16-231), and the grayscale ramp (232-255). -
Rich Snapshots:
RatatuiRuby::TestHelper#assert_rich_snapshotvalidates both content and styling by comparing against stored ANSI snapshots. This allows for visual regression testing that respects colors, bold, italics, and other terminal modifiers. -
Semantic Style Assertions: New testing helpers
assert_color(expected, x:, y:),assert_cell_style(x, y, **style), andassert_area_style(area, **style)allow precise verification of terminal cell attributes without full-screen snapshots. Punchy convenience aliases likeassert_fg/assert_bg,assert_bold,assert_italic,assert_underlined, and color-specific assertions (e.g.,assert_red,assert_bg_blue) provide a more natural API for common testing patterns. -
Buffer Debugging:
RatatuiRuby::TestHelper#print_bufferoutputs the current terminal state to STDOUT with full ANSI color support, making it easier to debug rendering issues during test execution.
Changed
-
Frozen Data Objects (Breaking): Events returned by
RatatuiRuby.poll_eventandCellobjects fromRatatuiRuby.get_cell_atare now deeply frozen for Ractor compatibility. Code that mutates these objects (e.g.,event.modifiers << "custom") must copy the data before modifying.Rectwas already frozen. Note:FrameandSessionare I/O handles with side effects and remain intentionally non-shareable. -
Semantic Exceptions (Breaking): Replaced generic
RuntimeErrorwithRatatuiRuby::Error::Terminalfor backend/terminal failures andRatatuiRuby::Error::Safetyfor API contract violations (like usingFrameoutsidedraw). This allows finer-grained error handling but breaks code explicitly rescuingRuntimeError.ArgumentErrorworks as before. -
Media Key Codes (Breaking): All media key codes now use a consistent
media_prefix:play→media_play,stop→media_stop,play_pause→media_play_pause, etc. Code comparing against literal media key strings must be updated. Use the Smart Predicates (play?,stop?) for backward-compatible behavior. -
Key#charReturn Value (Breaking):charnow returnsnilfor non-printable keys (previously returned""). Code relying onevent.char.empty?must change toevent.char.nil?or useevent.text?instead.
Fixed
-
Frame Safety: Calling methods on a
Framestored outside of adrawblock now correctly raises aRatatuiRuby::Error::Safety(subclass ofRatatuiRuby::Error) instead instead of causing undefined behavior or crashes. This ensures memory safety by preventing use-after-free scenarios with the underlying Rust frame.
Removed
0.5.0 - 2026-01-01
Added
Frame API
-
RatatuiRuby.draw { |frame| ... }: New block-based drawing API that yields aFrameobject for explicit widget placement. Enables hit testing without duplicating layout calculations. -
Frame#area: Returns the terminal area as aRect. -
Frame#render_widget(widget, rect): Renders a widget at a specific position. Works with all existing widgets andRectobjects.
Testing
-
RatatuiRuby::TestHelper#inject_mouse: comprehensive mouse event injection helper supporting coordinates, buttons, and modifiers. -
RatatuiRuby::TestHelper#inject_click: Helper for left-click events. -
RatatuiRuby::TestHelper#inject_right_click: Helper for right-click events. -
RatatuiRuby::TestHelper#inject_drag: Helper for mouse drag events. -
RatatuiRuby::TestHelper#assert_screen_matches: Assert that the current terminal content matches a stored golden snapshot.
Session API
-
Convenience Methods:
Sessionnow wraps class methods fromLayout,Constraint, and other schema classes as instance methods (e.g.,layout_splitdelegates toLayout.split,constraint_percentagetoConstraint.percentage). This enables a more fluent API inRatatuiRuby.runblocks.
Changed
Event System
-
Event::None(Breaking):RatatuiRuby.poll_eventnow returnsEvent::Noneinstead ofnilwhen no event is available. This null-object responds safely to all event predicates withfalse. Useevent.none?or pattern-match ontype: :none. Code usingwhile (event = poll_event)must change towhile (event = poll_event) && !event.none?.
Fixed
Session API
-
Missing Convenience Methods: Fixed
Sessionconvenience methods (e.g., bar_chart) being missed by replacing the manual list with automatic runtime introspection of theRatatuiRubymodule.
Removed
0.4.0 - 2025-12-30
Added
Hex Color Support
-
Style:
fgandbgparameters now accept hex color strings (e.g.,"#ff0000"for red). Requires a 24-bit true color capable terminal (Kitty, iTerm2, modern Terminal.app). Terminals without true color support will gracefully fall back to the closest ANSI color.
RatatuiMascot Widget
-
RatatuiMascot: New widget to display the Ratatui mascot (Ferris).
RatatuiLogo Widget
-
RatatuiLogo: New widget to display the Ratatui logo.
Duck-Typed Numeric Coercion
-
All numeric parameters now accept any object that responds to
to_f(for floats) orto_int/to_i(for integers). This provides idiomatic Ruby interoperability withBigDecimal,Rational, and custom numeric types. Uses Ruby’s built-inFloat()andInteger()Kernel methods for proper duck-type handling.
Paragraph Widget
-
alignment: Breaking Change: Renamedaligntoalignmentto match Ratatui 0.30 API.
Custom Widgets
-
Draw Command API: Custom widgets now return an array of
Drawcommands instead of writing to a buffer. UseRatatuiRuby::Draw.string(x, y, string, style)andRatatuiRuby::Draw.cell(x, y, cell)to create draw commands. This eliminates use-after-free bugs by keeping all pointers inside Rust while Ruby works with pure data objects. Breaking: Therendermethod signature changed fromrender(area, buffer)torender(area).
BarChart Widget
-
bar_set: Customize bar characters (digits, symbols, blocks). -
group_gap: Control spacing between groups in grouped bar charts. -
data: Now accepts an Array ofBarGroupobjects, enabling grouped bar charts. -
BarandBarGroup: New schema classes for defining grouped bar data.
Block Widget
-
border_type: Customize border style (:plain,:rounded,:double,:thick,:quadrant_inside,:quadrant_outside). -
border_set: Customize border characters (e.g., digits, symbols). -
border_style: Apply full style support (colors and modifiers) to borders. Takes precedence overborder_color. -
children: Declare child widgets within the block’s area for composable UI structures. -
Multiple
titles: Display multiple titles with individual alignment (:left,:center,:right) and vertical positioning (:top,:bottom). Each title supports its ownstyle. -
title_style: Base style applied to all titles. -
style: Base style applied to the entire block. -
padding: Directional padding via a single integer (uniform) or array of 4 integers ([left, right, top, bottom]). -
line_count(width): (Experimental) Calculate rendered lines (including borders/padding) for a given width. Delegates to Ratatui’s underlying unstableline_count. -
line_width: (Experimental) Calculate minimum width to avoid wrapping (including borders/padding). Delegates to Ratatui’s underlying unstableline_width.
Calendar Widget
-
events: Hash mappingDateobjects toStyleobjects for highlighting specific dates. -
show_month_header: Toggle month header visibility (defaults tofalse). Breaking: Previously always shown. -
show_weekdays_header: Toggle weekday names (Mon, Tue, etc.) visibility (defaults totrue). -
show_surrounding: OptionalStyleto display dates from adjacent months, ornilto hide them.
Chart Widget
-
legend_position: Position legend at:top_left,:top_right,:bottom_left, or:bottom_right(defaults to:top_right). -
hidden_legend_constraints: Array of twoConstraintobjects to hide the legend when chart area is too small. -
Axis:
labels_alignmentto control horizontal alignment (:left,:center,:right) of axis labels. -
Dataset:styleparameter replacescolor, enabling full styling (fg, bg, modifiers) for chart datasets. Breaking:colorparameter removed.
Gauge Widget
-
style: Base style applied to the entire gauge background. -
gauge_style: Style applied specifically to the filled bar. Breaking: Use this instead ofstyleif you want bar coloring;styleno longer defaults toStyle.default. -
percent: Convenience parameter alternative toratiofor initialization. -
use_unicode: Explicitly toggle between unicode blocks and ASCII rendering (defaults totrue).
LineGauge Widget
-
style: Base style applied to the entire gauge area.
List Widget
-
scroll_padding: Number of items to keep visible above and below the selected item during scrolling. -
repeat_highlight_symbol: Whentrue, repeat highlight symbol on each line of multi-line selections. -
highlight_spacing: Control selection column reservation (:always,:when_selected,:never). -
direction: List orientation (:top_to_bottomor:bottom_to_top).
Sparkline Widget
-
absent_value_symbolandabsent_value_style: Customize rendering ofnilvalues (distinct from0). -
direction: Rendering direction (:left_to_rightor:right_to_left). -
bar_set: Customize bar characters.
Table Widget
-
style: Base style applied to the entire table. -
column_spacing: Horizontal spacing between columns. -
footer: Summary rows at the bottom of the table. -
flex: Layout distribution mode (:legacy,:start,:center,:end,:space_between,:space_around,:space_evenly). -
highlight_spacing: Control selection column reservation (:always,:when_selected,:never). -
column_highlight_style: Style applied to the selected column. -
cell_highlight_style: Style applied to the selected cell (intersection of row and column). -
selected_column: Index of the selected column (Integer or nil). -
widths: Now support all constraint types (:max,:fill,:ratio) with full flexibility.
Tabs Widget
-
style: Base style applied to the entire tabs area. -
padding_leftandpadding_right: Horizontal padding around tab titles. -
width: Calculate total width of the tabs (including dividers/padding).
Canvas Widget
-
background_color: Set canvas background color. -
:half_blockmarker: Block-based rendering using half-height blocks. -
:quadrant,:sextant,:octantmarkers: High-resolution pseudo-pixel rendering. -
Shape::Label: Text labels at canvas coordinates with optional styling.
Scrollbar Widget
-
Full styling support:
thumb_style,track_symbol,track_style,begin_symbol,begin_style,end_symbol,end_style,style. -
All orientation variants:
:vertical_left,:vertical_right,:horizontal_top,:horizontal_bottom(:verticaland:horizontalremain as aliases).
Layout & Constraints
-
Constraint.ratio(numerator, denominator): Proportional constraints with explicit ratio. -
Constraint.fill(weight): Distribute remaining space proportionally. Use multipleFillto split space (e.g.,Fill(1)andFill(3)split 1:3). -
Constraint.max(value): Cap maximum size of a section. -
Layout.split(area, direction:, constraints:, flex:): Compute layout rectangles without rendering, enabling hit testing. -
Flex::SpaceEvenly: New layout mode forLayoutwidget. -
flexparameter: All layout options (:legacy,:start,:center,:end,:space_between,:space_around,:space_evenly).
Rich Text & Text Components
-
Text::SpanandText::Line: Styled text with inline formatting. Combine spans into lines with optional alignment. -
Shapemodule: Canvas shape primitives (Shape::Line,Shape::Circle,Shape::Rectangle,Shape::Point,Shape::Map) to avoid naming conflicts withText::Line.
Event System
-
Typed
EventAPI:RatatuiRuby.poll_eventreturns typed objects (Event::Key,Event::Mouse,Event::Resize,Event::Paste,Event::FocusGained,Event::FocusLost). -
Predicate methods:
key?,mouse?,ctrl?, etc. for cleaner event handling. -
Pattern matching support and discriminator pattern via
type:key in deconstruct_keys. -
Event::Resize: Terminal resize events withwidthandheightattributes. -
Event::Paste: Bracketed paste as atomic event withcontent:. -
Event::FocusGainedandEvent::FocusLost: Terminal focus changes. -
Event::Mouse.newacceptsnilforbuttonparameter (treated as"none").
Geometry & Hit Testing
-
Rect#contains?(x, y): Test whether a point is inside a rectangle. Essential for mouse click handlers. -
Layout.split: Enables calculating widget positions before rendering.
Testing
-
RatatuiRuby::TestHelper#inject_keys: Concise event injection helper. -
RatatuiRuby::TestHelper#get_celland assert_cell_style: Inspect terminal cell attributes (colors, characters). -
with_test_terminal: Default timeout of 2 seconds to prevent hanging tests. Breaking: Default size is now 80×24 (VT100 standard) instead of 20×10. -
Error on
inject_event/inject_keysoutsidewith_test_terminal: Prevents test hangs from race conditions. -
Value equality (
==) forEventobjects: Simplify assertions.
Lifecycle & Application Structure
-
RatatuiRuby.run: New context manager that initializes terminal, yields session, and restores on exit. Allows custom event loop control. -
Session class: Renamed from
DSLto better reflect its purpose as a managed terminal session with convenience methods. -
Focus and Bracketed Paste events: Enabled by default in
RatatuiRuby.runandRatatuiRuby.init_terminal(disable withfocus_events: falseorbracketed_paste: false).
Documentation & Examples
-
Cached Layout Pattern: Documented in
doc/interactive_design.md. Three-phase lifecycle pattern (calculate_layout,render,handle_input) solves layout duplication in immediate-mode UI. Foundation for Component architecture in Gem 1.5.
Changed
-
Calendar: Renamed
day_styletodefault_styleto match Ratatui 0.30 API. This is a breaking change. [Kerrick Long] -
Custom Widget
renderMethod (Breaking): Changed signature fromrender(area, buffer)torender(area), with render methods now returning an array ofDrawcommands instead of writing directly to a buffer. This change improves memory safety by eliminating use-after-free risks. -
Ratatui Upgraded to 0.30.0: Underlying
ratatuilibrary upgraded from 0.29, bringing modularized crates,no_stdsupport for embedded targets, and major widget/layout enhancements. Layout cache explicitly enabled for performance. -
Event API (Breaking):
RatatuiRuby.poll_eventreturns typedEventobjects instead of raw Hashes. Code usingevent[:type]must change toevent.key?,event.code, etc. -
RatatuiRuby.main_loop Removed (Breaking): Removed in favor of
RatatuiRuby.runfor more explicit lifecycle control. -
TestHelper Terminal Size (Breaking):
with_test_terminaldefaults to 80×24 instead of 20×10. -
Calendar Month Header Default (Breaking):
show_month_headerdefaults tofalse(previously always shown). Setshow_month_header: trueif relying on the old behavior. -
Gauge
styleDefault (Breaking): No longer defaults toStyle.default. Usegauge_stylefor bar coloring instead.
Fixed
-
Alpine Linux Support: Fixed gem installation failures on Alpine Linux (musl targets) by properly configuring
crate-typeto support static linking where dynamic linking is unsupported. -
Rust Safety: Convert
class.name()results to owned strings for proper GC safety with Magnus 0.8. -
Terminal Preview Detection: Detect staged changes correctly in preview generation.
0.3.1 - 2025-12-28
Added
-
Ruby 4 Support: Updated magnus FFI bindings to use the modern API for Ruby 4.0.0 compatibility.
0.3.0 - 2025-12-28
Added
-
Custom Widget API (Breaking): Custom widgets that define a
rendermethod now receive onlyarea(notbuffer) and must return an array ofDrawcommands. UseRatatuiRuby::Draw.string(x, y, string, style)andRatatuiRuby::Draw.cell(x, y, cell)instead ofbuffer.set_stringandbuffer.set_cell. This eliminates a class of use-after-free bugs by ensuring Ruby never holds pointers to Rust-owned memory. Widgets can now be unit tested by asserting on the returned array. -
The Escape Hatch (Ruby Render Callback): Added the ability to define custom widgets in pure Ruby by implementing a
render(area, buffer)method. TheBufferobject provides low-level drawing primitives likeset_string, allowing developers to create custom TUI components without writing Rust code. -
Clear Widget: Added the
Clearwidget, which resets the terminal buffer in the area it is rendered. This is essential for creating opaque popups and modals that prevent background styles from “bleeding” through transparent widgets. -
Interactive Table Selection: The
Tablewidget now supports row selection withselected_row,highlight_style, andhighlight_symbolparameters. This enables building interactive data grids and file explorers where users can navigate through rows using keyboard input. -
Scrollable Paragraphs: The
Paragraphwidget now supports ascrollparameter that accepts a(y, x)array to scroll content vertically and horizontally. This enables viewing long text content that exceeds the visible area, such as logs or documents. The parameter order matches ratatui’s convention. -
Enhanced Tabs Customization: The
Tabswidget now supportshighlight_stylefor the selected tab and a customizabledividerstring (defaulting to the standard pipe|). This allows for richer visual feedback in tabbed interfaces.
Changed
-
Center Widget: Removed the implicit
Clearcall from theCenterwidget.Centeris now a pure layout widget, requiring an explicitClearwidget if background clearing is desired. This restores correct behavior for transparent overlays.
0.2.0 - 2025-12-24
Added
-
DSL for Simpler Apps: Introduced
RatatuiRuby.main_loop, a new entrypoint that simplifies application structure when you don’t need control of the event loop or application lifecycle. -
Calendar Widget: Added the
Calendarwidget, allowing you to display monthly views and visualize date-based information. -
Generic Charts: Implemented the full
Chartwidget, which supersedes the now-deprecatedLineChartandBarChartwidgets, giving you more freedom to visualize data sets. -
Enhanced List Styling: You can now customize the appearance of selected items in a
Listusinghighlight_styleandhighlight_symbol. -
Broader Ruby Support: Added support for a wider range of Ruby versions: every non-EOL version. The latest preview of Ruby 4.0 is tested in CI, but not supported.
-
Dev Tools: Added internal Rake tasks for managing historical documentation and SemVer checks.
0.1.0 - 2025-12-22
Added
-
First Release: Initial public release of ratatui_ruby, bringing the power of the Rust ratatui library to Rubyists!
-
Core Widget Set: Includes a comprehensive suite of widgets to get you started:
-
Block,Borders, andParagraphfor basic content. -
ListandTablefor structured data. -
GaugeandSparklinefor progress and metrics. -
Tabsfor navigation. -
Canvasfor drawing shapes (Lines, Circles, Rectangles, Maps). -
Layout System: A flexible layout engine using
Flex,Layout, andConstraintsto build responsive interfaces that adapt to any terminal size. -
Forms & Layers: Primitives like
OverlayandCenterfor creating modal dialogs, plus aCursorwidget for text input interactions. -
Styling: Full support for
Ratatui‘s styling primitives, including modifiers and RGB/ANSI colors. -
Input Handling: Robust handling for both Keyboard and Mouse events.
-
Testing Support: Included
RatatuiRuby::TestHelperand RSpec integration to make testing your TUI applications possible.