ratatui_ruby 1.0.0 → 1.0.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.
- checksums.yaml +4 -4
- data/ext/ratatui_ruby/Cargo.lock +1 -1
- data/ext/ratatui_ruby/Cargo.toml +1 -1
- data/lib/ratatui_ruby/version.rb +1 -1
- metadata +1 -232
- data/.builds/ruby-3.2.yml +0 -54
- data/.builds/ruby-3.3.yml +0 -54
- data/.builds/ruby-3.4.yml +0 -54
- data/.builds/ruby-4.0.0.yml +0 -54
- data/.pre-commit-config.yaml +0 -16
- data/.rubocop.yml +0 -10
- data/AGENTS.md +0 -146
- data/CHANGELOG.md +0 -710
- data/README.md +0 -187
- data/README.rdoc +0 -302
- data/Rakefile +0 -11
- data/Steepfile +0 -49
- data/doc/concepts/application_architecture.md +0 -321
- data/doc/concepts/application_testing.md +0 -193
- data/doc/concepts/async.md +0 -190
- data/doc/concepts/custom_widgets.md +0 -247
- data/doc/concepts/debugging.md +0 -401
- data/doc/concepts/event_handling.md +0 -162
- data/doc/concepts/interactive_design.md +0 -146
- data/doc/contributors/auditing/parity.md +0 -239
- data/doc/contributors/design/ruby_frontend.md +0 -420
- data/doc/contributors/design/rust_backend.md +0 -422
- data/doc/contributors/design.md +0 -11
- data/doc/contributors/developing_examples.md +0 -400
- data/doc/contributors/documentation_style.md +0 -121
- data/doc/contributors/index.md +0 -21
- data/doc/contributors/todo/align/api_completeness_audit-finished.md +0 -375
- data/doc/contributors/todo/align/api_completeness_audit-unfinished.md +0 -206
- data/doc/contributors/todo/align/terminal.md +0 -647
- data/doc/contributors/todo/future_work.md +0 -169
- data/doc/contributors/upstream_requests/tab_rects.md +0 -173
- data/doc/contributors/upstream_requests/title_rects.md +0 -132
- data/doc/custom.css +0 -22
- data/doc/getting_started/quickstart.md +0 -291
- data/doc/getting_started/why.md +0 -93
- data/doc/images/app_all_events.png +0 -0
- data/doc/images/app_cli_rich_moments.gif +0 -0
- data/doc/images/app_color_picker.png +0 -0
- data/doc/images/app_debugging_showcase.gif +0 -0
- data/doc/images/app_debugging_showcase.png +0 -0
- data/doc/images/app_login_form.png +0 -0
- data/doc/images/app_stateful_interaction.png +0 -0
- data/doc/images/verify_quickstart_dsl.png +0 -0
- data/doc/images/verify_quickstart_layout.png +0 -0
- data/doc/images/verify_quickstart_lifecycle.png +0 -0
- data/doc/images/verify_readme_usage.png +0 -0
- data/doc/images/widget_barchart.png +0 -0
- data/doc/images/widget_block.png +0 -0
- data/doc/images/widget_box.png +0 -0
- data/doc/images/widget_calendar.png +0 -0
- data/doc/images/widget_canvas.png +0 -0
- data/doc/images/widget_cell.png +0 -0
- data/doc/images/widget_center.png +0 -0
- data/doc/images/widget_chart.png +0 -0
- data/doc/images/widget_gauge.png +0 -0
- data/doc/images/widget_layout_split.png +0 -0
- data/doc/images/widget_line_gauge.png +0 -0
- data/doc/images/widget_list.png +0 -0
- data/doc/images/widget_map.png +0 -0
- data/doc/images/widget_overlay.png +0 -0
- data/doc/images/widget_popup.png +0 -0
- data/doc/images/widget_ratatui_logo.png +0 -0
- data/doc/images/widget_ratatui_mascot.png +0 -0
- data/doc/images/widget_rect.png +0 -0
- data/doc/images/widget_render.png +0 -0
- data/doc/images/widget_rich_text.png +0 -0
- data/doc/images/widget_scroll_text.png +0 -0
- data/doc/images/widget_scrollbar.png +0 -0
- data/doc/images/widget_sparkline.png +0 -0
- data/doc/images/widget_style_colors.png +0 -0
- data/doc/images/widget_table.png +0 -0
- data/doc/images/widget_tabs.png +0 -0
- data/doc/images/widget_text_width.png +0 -0
- data/doc/index.md +0 -39
- data/doc/troubleshooting/async.md +0 -4
- data/doc/troubleshooting/terminal_limitations.md +0 -131
- data/doc/troubleshooting/tui_output.md +0 -197
- data/examples/app_all_events/README.md +0 -114
- data/examples/app_all_events/app.rb +0 -98
- data/examples/app_all_events/model/app_model.rb +0 -159
- data/examples/app_all_events/model/event_color_cycle.rb +0 -43
- data/examples/app_all_events/model/event_entry.rb +0 -94
- data/examples/app_all_events/model/msg.rb +0 -39
- data/examples/app_all_events/model/timestamp.rb +0 -56
- data/examples/app_all_events/update.rb +0 -75
- data/examples/app_all_events/view/app_view.rb +0 -80
- data/examples/app_all_events/view/controls_view.rb +0 -54
- data/examples/app_all_events/view/counts_view.rb +0 -61
- data/examples/app_all_events/view/live_view.rb +0 -72
- data/examples/app_all_events/view/log_view.rb +0 -57
- data/examples/app_all_events/view.rb +0 -9
- data/examples/app_cli_rich_moments/README.md +0 -81
- data/examples/app_cli_rich_moments/app.rb +0 -189
- data/examples/app_color_picker/README.md +0 -156
- data/examples/app_color_picker/app.rb +0 -76
- data/examples/app_color_picker/clipboard.rb +0 -86
- data/examples/app_color_picker/color.rb +0 -193
- data/examples/app_color_picker/controls.rb +0 -92
- data/examples/app_color_picker/copy_dialog.rb +0 -168
- data/examples/app_color_picker/export_pane.rb +0 -128
- data/examples/app_color_picker/harmony.rb +0 -58
- data/examples/app_color_picker/input.rb +0 -176
- data/examples/app_color_picker/main_container.rb +0 -180
- data/examples/app_color_picker/palette.rb +0 -111
- data/examples/app_debugging_showcase/README.md +0 -119
- data/examples/app_debugging_showcase/app.rb +0 -318
- data/examples/app_login_form/README.md +0 -58
- data/examples/app_login_form/app.rb +0 -109
- data/examples/app_stateful_interaction/README.md +0 -35
- data/examples/app_stateful_interaction/app.rb +0 -328
- data/examples/timeout_demo.rb +0 -45
- data/examples/verify_quickstart_dsl/README.md +0 -55
- data/examples/verify_quickstart_dsl/app.rb +0 -49
- data/examples/verify_quickstart_layout/README.md +0 -77
- data/examples/verify_quickstart_layout/app.rb +0 -73
- data/examples/verify_quickstart_lifecycle/README.md +0 -68
- data/examples/verify_quickstart_lifecycle/app.rb +0 -62
- data/examples/verify_readme_usage/README.md +0 -49
- data/examples/verify_readme_usage/app.rb +0 -42
- data/examples/verify_website_managed/README.md +0 -48
- data/examples/verify_website_managed/app.rb +0 -36
- data/examples/verify_website_menu/README.md +0 -60
- data/examples/verify_website_menu/app.rb +0 -84
- data/examples/verify_website_spinner/README.md +0 -44
- data/examples/verify_website_spinner/app.rb +0 -34
- data/examples/widget_barchart/README.md +0 -58
- data/examples/widget_barchart/app.rb +0 -240
- data/examples/widget_block/README.md +0 -44
- data/examples/widget_block/app.rb +0 -258
- data/examples/widget_box/README.md +0 -54
- data/examples/widget_box/app.rb +0 -255
- data/examples/widget_calendar/README.md +0 -48
- data/examples/widget_calendar/app.rb +0 -115
- data/examples/widget_canvas/README.md +0 -31
- data/examples/widget_canvas/app.rb +0 -130
- data/examples/widget_cell/README.md +0 -45
- data/examples/widget_cell/app.rb +0 -112
- data/examples/widget_center/README.md +0 -33
- data/examples/widget_center/app.rb +0 -118
- data/examples/widget_chart/README.md +0 -50
- data/examples/widget_chart/app.rb +0 -220
- data/examples/widget_gauge/README.md +0 -50
- data/examples/widget_gauge/app.rb +0 -229
- data/examples/widget_layout_split/README.md +0 -53
- data/examples/widget_layout_split/app.rb +0 -260
- data/examples/widget_line_gauge/README.md +0 -50
- data/examples/widget_line_gauge/app.rb +0 -219
- data/examples/widget_list/README.md +0 -58
- data/examples/widget_list/app.rb +0 -384
- data/examples/widget_map/README.md +0 -48
- data/examples/widget_map/app.rb +0 -95
- data/examples/widget_overlay/README.md +0 -45
- data/examples/widget_overlay/app.rb +0 -250
- data/examples/widget_popup/README.md +0 -45
- data/examples/widget_popup/app.rb +0 -106
- data/examples/widget_ratatui_logo/README.md +0 -43
- data/examples/widget_ratatui_logo/app.rb +0 -104
- data/examples/widget_ratatui_mascot/README.md +0 -43
- data/examples/widget_ratatui_mascot/app.rb +0 -95
- data/examples/widget_rect/README.md +0 -53
- data/examples/widget_rect/app.rb +0 -222
- data/examples/widget_render/README.md +0 -46
- data/examples/widget_render/app.rb +0 -186
- data/examples/widget_render/app.rbs +0 -41
- data/examples/widget_rich_text/README.md +0 -44
- data/examples/widget_rich_text/app.rb +0 -193
- data/examples/widget_scroll_text/README.md +0 -46
- data/examples/widget_scroll_text/app.rb +0 -109
- data/examples/widget_scrollbar/README.md +0 -46
- data/examples/widget_scrollbar/app.rb +0 -155
- data/examples/widget_sparkline/README.md +0 -51
- data/examples/widget_sparkline/app.rb +0 -277
- data/examples/widget_style_colors/README.md +0 -43
- data/examples/widget_style_colors/app.rb +0 -83
- data/examples/widget_table/README.md +0 -57
- data/examples/widget_table/app.rb +0 -279
- data/examples/widget_tabs/README.md +0 -50
- data/examples/widget_tabs/app.rb +0 -183
- data/examples/widget_text_width/README.md +0 -44
- data/examples/widget_text_width/app.rb +0 -117
- data/migrate_to_buffer.rb +0 -145
- data/mise.toml +0 -8
- data/tasks/autodoc/examples.rb +0 -87
- data/tasks/autodoc/member.rb +0 -58
- data/tasks/autodoc/name.rb +0 -21
- data/tasks/autodoc.rake +0 -21
- data/tasks/bump/cargo_lockfile.rb +0 -21
- data/tasks/bump/changelog.rb +0 -47
- data/tasks/bump/header.rb +0 -32
- data/tasks/bump/history.rb +0 -32
- data/tasks/bump/links.rb +0 -69
- data/tasks/bump/manifest.rb +0 -33
- data/tasks/bump/ruby_gem.rb +0 -49
- data/tasks/bump/sem_ver.rb +0 -40
- data/tasks/bump/unreleased_section.rb +0 -56
- data/tasks/bump.rake +0 -51
- data/tasks/doc.rake +0 -887
- data/tasks/example_viewer.html.erb +0 -172
- data/tasks/extension.rake +0 -14
- data/tasks/license/headers_md.rb +0 -223
- data/tasks/license/headers_rb.rb +0 -210
- data/tasks/license/license_utils.rb +0 -130
- data/tasks/license/snippets_md.rb +0 -315
- data/tasks/license/snippets_rdoc.rb +0 -150
- data/tasks/license.rake +0 -91
- data/tasks/lint.rake +0 -170
- data/tasks/rdoc_config.rb +0 -29
- data/tasks/resources/build.yml.erb +0 -60
- data/tasks/resources/index.html.erb +0 -141
- data/tasks/resources/rubies.yml +0 -7
- data/tasks/sourcehut.rake +0 -110
- data/tasks/steep.rake +0 -11
- data/tasks/terminal_preview/app_screenshot.rb +0 -45
- data/tasks/terminal_preview/crash_report.rb +0 -54
- data/tasks/terminal_preview/example_app.rb +0 -27
- data/tasks/terminal_preview/launcher_script.rb +0 -48
- data/tasks/terminal_preview/preview_collection.rb +0 -60
- data/tasks/terminal_preview/preview_timing.rb +0 -24
- data/tasks/terminal_preview/safety_confirmation.rb +0 -58
- data/tasks/terminal_preview/saved_screenshot.rb +0 -56
- data/tasks/terminal_preview/system_appearance.rb +0 -13
- data/tasks/terminal_preview/terminal_window.rb +0 -138
- data/tasks/terminal_preview/window_id.rb +0 -16
- data/tasks/terminal_preview.rake +0 -30
- data/tasks/test.rake +0 -33
- data/tasks/website/index_page.rb +0 -30
- data/tasks/website/version.rb +0 -127
- data/tasks/website/version_menu.rb +0 -68
- data/tasks/website/versioned_documentation.rb +0 -83
- data/tasks/website/website.rb +0 -53
- data/tasks/website.rake +0 -28
data/CHANGELOG.md
DELETED
|
@@ -1,710 +0,0 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
3
|
-
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
4
|
-
-->
|
|
5
|
-
# Changelog
|
|
6
|
-
|
|
7
|
-
All notable changes to this project will be documented in this file.
|
|
8
|
-
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
9
|
-
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
10
|
-
|
|
11
|
-
## [Unreleased]
|
|
12
|
-
|
|
13
|
-
### Added
|
|
14
|
-
|
|
15
|
-
### Changed
|
|
16
|
-
|
|
17
|
-
### Fixed
|
|
18
|
-
|
|
19
|
-
### Removed
|
|
20
|
-
|
|
21
|
-
## [1.0.0] - 2026-01-25
|
|
22
|
-
This release is functionally equivalent to v0.10.3, with additional bug fixes.
|
|
23
|
-
The version bump signals the beginning of the 1.0 release series.
|
|
24
|
-
|
|
25
|
-
### Added
|
|
26
|
-
|
|
27
|
-
### Changed
|
|
28
|
-
|
|
29
|
-
### Fixed
|
|
30
|
-
- **back_tab? DWIM**: `back_tab?` and `backtab?` predicates now match events with code "back_tab" regardless of whether the shift modifier is explicitly present, since back_tab semantically implies shift.
|
|
31
|
-
- **Terminal Queries During Draw (Deadlock)**: Calling `viewport_area`, `terminal_size`, `get_cell_at`, `poll_event`, `get_cursor_position`, or `get_viewport_type` from inside a `draw()` block previously caused the application to freeze forever. The thread blocked on a Mutex. Ruby's `Timeout` could not interrupt it. The only recovery was `kill -9`. These reads now work via a snapshot captured before rendering.
|
|
32
|
-
- **Terminal Mutations During Draw (Deadlock)**: Calling `insert_before`, `set_cursor_position`, or `resize_terminal` from inside a `draw()` block previously caused the same silent freeze. These writes now raise `Error::Invariant` with a clear message.
|
|
33
|
-
- **Nested Draw Calls (Deadlock)**: Calling `draw()` from inside another `draw()` block previously froze the application. Nested draws now raise `Error::Invariant`.
|
|
34
|
-
- **Event Injection During Draw (Deadlock)**: Calling `inject_test_event` from inside a `draw()` block previously froze the application. Event injection now works correctly during draw.
|
|
35
|
-
- **TableState Row Navigation Methods**: Added missing row navigation methods (`select_next`, `select_previous`, `select_first`, `select_last`) that should have been included alongside the column navigation methods added in v0.10.0. These methods match `ListState`'s navigation API and are used in the `app_stateful_interaction` example.
|
|
36
|
-
|
|
37
|
-
## [0.10.3] - 2026-01-16
|
|
38
|
-
|
|
39
|
-
### Added
|
|
40
|
-
|
|
41
|
-
- **Rect Destructuring**: `Rect` objects now support array destructuring (implementation of `to_ary`), allowing intuitive assignment like `x, y, w, h = rect`.
|
|
42
|
-
- **Global State Test Helpers**: New `RatatuiRuby::TestHelper::GlobalState` module (automatically included in `TestHelper`) provides `with_argv` and `with_env` methods for safely testing code that reads `ARGV` or `ENV`.
|
|
43
|
-
|
|
44
|
-
### Changed
|
|
45
|
-
|
|
46
|
-
- **New Website**: RatatuiRuby now has a home on the world wide web at [www.ratatui-ruby.dev](https://www.ratatui-ruby.dev).
|
|
47
|
-
- **A New Way to Browse Examples**: You can now browse the source code of the example applications in our documentation site. See [AppAllEvents](https://www.ratatui-ruby.dev/docs/v0.10/examples/app_all_events/app_rb.html) for an example.
|
|
48
|
-
- **API Documentation on the Web**: RatatuiRuby's [extensive RDoc documentation is now available on the web](https://www.ratatui-ruby.dev/docs/v0.10/RatatuiRuby.html).
|
|
49
|
-
- **Guides on the Web**: RatatuiRuby's [in-depth guides are now available on the web](https://www.ratatui-ruby.dev/docs/v0.10/doc/index_md.html).
|
|
50
|
-
- **Versioned Examples, API Documentanion, and Guides**: API reference, guides, and examples are available on our website for current and past versions of ratatui_ruby, including the trunk version. Visit [www.ratatui-ruby.dev/docs](https://www.ratatui-ruby.dev/docs) to browse.
|
|
51
|
-
|
|
52
|
-
### Fixed
|
|
53
|
-
|
|
54
|
-
- **Dependency Problems**: Removed the unused `ostruct` dependency from the gemspec. Added `rexml` as an explicit dependency.
|
|
55
|
-
- **Lazy REXML Loading**: `RatatuiRuby::Labs::A11y` now requires `rexml` lazily, preventing it from slowing down startup for users not using accessibility features.
|
|
56
|
-
|
|
57
|
-
## [0.10.2] - 2026-01-14
|
|
58
|
-
|
|
59
|
-
### Added
|
|
60
|
-
|
|
61
|
-
- **Experimental Labs System**: New `RatatuiRuby::Labs` module for opt-in experimental features via `RR_LABS` environment variable. Check with `Labs.enabled?(:a11y)` or enable programmatically with `Labs.enable!(:a11y)`. _Labs are subject to change even between patch releases._
|
|
62
|
-
- **A11Y Widget Tree Export (Lab)**: When `RR_LABS=A11Y` is set, the widget tree is serialized to XML and written to `Dir.tmpdir/ratatui_a11y.xml` every frame. This exports semantic structure (`<Paragraph>`, `<List>`, etc.) for accessibility tooling integration. Access is through `RatatuiRuby::Labs::A11y.dump_widget_tree(widget)` or automatic via `RatatuiRuby.draw`.
|
|
63
|
-
- **Inline Viewport**: New `viewport:` parameter for `init_terminal` and `run` accepts `:inline` or `:fullscreen` (default). Inline viewports occupy a fixed number of lines at the terminal bottom, preserving scrollback history above. Pass `height:` to specify inline viewport height (default: 8 lines). Fullscreen viewports use the alternate screen as before.
|
|
64
|
-
- **Insert Before**: New `insert_before(height, widget)` method inserts content above an inline viewport into scrollback without disrupting the running TUI. Essential for logging status updates, progress messages, or diagnostic output while your inline TUI continues running. Only works with inline viewports; raises `Error::Invariant` in fullscreen mode.
|
|
65
|
-
- **Terminal Area Accessors**: New methods to query terminal and viewport dimensions:
|
|
66
|
-
- `terminal_area` / `get_terminal_size` — full terminal backend size (always full dimensions)
|
|
67
|
-
- `viewport_area` / `get_viewport_area` — current viewport rendering area (inline viewport height or full terminal in fullscreen)
|
|
68
|
-
- Aliases: `terminal_size`, `viewport_size`, `get_terminal_area`, `get_viewport_size`
|
|
69
|
-
- **Cursor Position Accessors**: New methods for querying and setting cursor position:
|
|
70
|
-
- `cursor_position` / `get_cursor_position` — returns current cursor position as `Layout::Position` or `[x, y]` array
|
|
71
|
-
- `cursor_position=` / `set_cursor_position` — sets cursor position from `Layout::Position`, array, or separate x/y arguments
|
|
72
|
-
- **Error::Internal Exception**: New exception class for framework bugs, distinct from user errors. If you encounter this, please report it as a framework bug.
|
|
73
|
-
|
|
74
|
-
### Changed
|
|
75
|
-
|
|
76
|
-
### Fixed
|
|
77
|
-
|
|
78
|
-
### Removed
|
|
79
|
-
|
|
80
|
-
## [0.10.1] - 2026-01-11
|
|
81
|
-
|
|
82
|
-
### Added
|
|
83
|
-
|
|
84
|
-
### Changed
|
|
85
|
-
|
|
86
|
-
### Fixed
|
|
87
|
-
|
|
88
|
-
- **poll_event Return Type**: Fixed `poll_event` incorrectly returning `nil` for unknown event types. The method now correctly returns `Event::None` as per its contract.
|
|
89
|
-
|
|
90
|
-
### Removed
|
|
91
|
-
|
|
92
|
-
## [0.10.0] - 2026-01-10
|
|
93
|
-
|
|
94
|
-
### Added
|
|
95
|
-
|
|
96
|
-
- **Table Integer Width Shorthand**: `Table` `widths:` parameter now accepts plain integers as shorthand for `Constraint.length(n)`. This enables cleaner table definitions like `widths: [40, 16, 10]` instead of verbose constraint arrays. Constraints and integers can be mixed freely.
|
|
97
|
-
- **Error Message Context**: Type errors from the Rust backend now include the `inspect` string of the value that caused the error, making debugging significantly easier. For example, "expected array for rows" now shows "expected array for rows, got {title: \"Processes\", ...}".
|
|
98
|
-
- **Steep Type Checking**: Integrated Steep static type analyzer with a new `rake steep` task. The Steepfile covers `lib/` with comprehensive RBS type definitions for all widgets, layout primitives, events, and interfaces.
|
|
99
|
-
- **RBS Type Definitions**: Added 50+ RBS signature files in `sig/ratatui_ruby/` covering all widget classes, core interfaces (`_RectLike`, `_ToS`), type aliases (`style_input`, `widget`), and a `Data.define` patch for `super()` call compatibility.
|
|
100
|
-
- **Duck Typing Documentation**: New `test/test_duck_typing.rb` documents that `Layout.split` accepts any object responding to `x`, `y`, `width`, `height` (Struct, Data.define, custom classes), not just `Rect`.
|
|
101
|
-
- **Debug Mode**: New `RatatuiRuby::Debug` module controls Rust backtrace visibility for easier debugging. Activate via:
|
|
102
|
-
- `RUST_BACKTRACE=1` — Rust backtraces only
|
|
103
|
-
- `RR_DEBUG=1` — full debug mode (backtraces + future Ruby-side features)
|
|
104
|
-
- `include RatatuiRuby::TestHelper` — auto-enables debug mode in tests
|
|
105
|
-
- `RatatuiRuby.debug_mode!` — programmatic activation
|
|
106
|
-
- **Debug.test_panic!**: New method that intentionally triggers a Rust panic, allowing developers to verify their backtrace setup is working correctly before encountering a real bug.
|
|
107
|
-
- **Deferred Panic Backtraces**: Rust backtraces during TUI sessions are now stored and printed after terminal restoration, preventing output from being lost on the alternate screen. Previously, panic output in raw terminal mode was invisible.
|
|
108
|
-
- **Remote Debugging**: Debug mode now integrates with Ruby's `debug` gem for remote debugging. `RR_DEBUG=1` stops at startup and waits for debugger attachment. `RatatuiRuby.debug_mode!` continues running in nonstop mode. Attach from another terminal with `rdbg --attach`.
|
|
109
|
-
- **Debug.suppress_debug_mode**: New block method temporarily suppresses Ruby-side debug checks within its block. Rust backtraces remain enabled. Useful for testing production behavior in debug mode environments.
|
|
110
|
-
- **DWIM Hash Coercion**: All widget factory methods now accept both `tui.table(hash)` and `tui.table(**hash)` calling styles. When a bare Hash is passed as the first positional argument, it is automatically splatted into keyword arguments. Unknown keys are silently ignored in production mode; in debug mode (`RR_DEBUG=1`), they raise `ArgumentError` for early typo detection.
|
|
111
|
-
- **Ratatui-Aligned Text Methods**: New methods on `Text::Span` and `Text::Line` matching Ratatui's API for style manipulation:
|
|
112
|
-
- `Span#width` — display width in terminal cells (unicode-aware)
|
|
113
|
-
- `Span.raw(content)` — factory for unstyled spans
|
|
114
|
-
- `Span#patch_style(style)` — merge style onto existing style
|
|
115
|
-
- `Span#reset_style` — clear all styling
|
|
116
|
-
- `Line#left_aligned`, `Line#centered`, `Line#right_aligned` — fluent alignment setters
|
|
117
|
-
- `Line#push_span(span)` — append span (returns new Line, immutable)
|
|
118
|
-
- `Line#patch_style(style)`, `Line#reset_style` — style manipulation for all spans
|
|
119
|
-
- **List Query Methods**: New methods on `List` matching Ratatui's API:
|
|
120
|
-
- `List#len` — number of items (with Ruby aliases `length`, `size`)
|
|
121
|
-
- **TableState Navigation Methods**: New methods on `TableState` matching Ratatui's API for column navigation:
|
|
122
|
-
- `selected_cell` — returns `[row, column]` tuple when both are selected
|
|
123
|
-
- `with_selected_cell(cell)` — constructor to create state with both row and column selected
|
|
124
|
-
- `select_next_column` — select the next column (or first if none selected)
|
|
125
|
-
- `select_previous_column` — select the previous column (saturates at 0)
|
|
126
|
-
- `select_first_column` — select column 0
|
|
127
|
-
- `select_last_column` — select the last column (clamped during rendering)
|
|
128
|
-
- **Buffer Query Methods**: New module methods on `Buffer` matching Ratatui's API for buffer inspection:
|
|
129
|
-
- `Buffer.content` — returns all cells as an array
|
|
130
|
-
- `Buffer.get(x, y)` — returns the Cell at the specified position
|
|
131
|
-
- `Buffer.index_of(x, y)` — converts position to linear buffer index
|
|
132
|
-
- `Buffer.pos_of(index)` — converts linear index to position coordinates
|
|
133
|
-
- **Rect Conversion Methods**: New methods on `Rect` for extracting geometry components:
|
|
134
|
-
- `Rect#as_position` — returns a `Position` object containing x and y coordinates
|
|
135
|
-
- `Rect#as_size` — returns a `Size` object containing width and height
|
|
136
|
-
- **Position and Size Classes**: New layout primitives matching Ratatui's API:
|
|
137
|
-
- `Layout::Position` — represents terminal coordinates (x, y)
|
|
138
|
-
- `Layout::Size` — represents terminal dimensions (width, height)
|
|
139
|
-
- **Constraint#apply**: Computes the constrained size for a given available space. For example, `Constraint.percentage(50).apply(100)` returns `50`. Also aliased as `call` for proc-like invocation (`constraint.(100)`).
|
|
140
|
-
- **Color Module**: New `Style::Color` module with constructors matching Ratatui's API:
|
|
141
|
-
- `Color.from_u32(0xRRGGBB)` — creates a color from a hex integer (aliased as `Color.hex`)
|
|
142
|
-
- `Color.from_hsl(h, s, l)` — creates a color from HSL values (aliased as `Color.hsl`)
|
|
143
|
-
- **Ruby-Idiomatic Aliases**: All new APIs include shorter, more Ruby-ish aliases following TIMTOWTDI:
|
|
144
|
-
- `Rect#position` (alias for `as_position`), `Rect#size` (alias for `as_size`)
|
|
145
|
-
- `Buffer[x, y]` (alias for `Buffer.get`)
|
|
146
|
-
- `Constraint#call` (alias for `apply`, enables `constraint.(n)` syntax)
|
|
147
|
-
- **Layout Margin and Spacing**: `Layout` now supports `margin:` and `spacing:` parameters for edge insets and gaps between segments, matching Ratatui's Layout API.
|
|
148
|
-
- **Layout.split_with_spacers**: New class method returns both content segments and spacer Rects, enabling custom rendering of dividers or separators between layout sections.
|
|
149
|
-
- **Canvas#get_point**: Converts canvas coordinates to normalized [0.0, 1.0] grid coordinates for hit testing. Returns `nil` for out-of-bounds coordinates. Also aliased as `point` and `[]` for Ruby-idiomatic access.
|
|
150
|
-
- **Row#enable_strikethrough**: Returns a new Row with `:crossed_out` modifier for indicating cancelled or deleted items. Also aliased as `strikethrough`. Note: Strikethrough (SGR 9) is not supported by all terminals; macOS Terminal.app notably lacks support while Kitty, iTerm2, Alacritty, and WezTerm render it correctly.
|
|
151
|
-
- **Rect Geometry Methods**: New methods on `Rect` for geometry manipulation:
|
|
152
|
-
- `Rect#outer(margin)` — expands a rectangle by a margin (inverse of `inner`)
|
|
153
|
-
- `Rect#resize(size)` — changes dimensions while preserving top-left position
|
|
154
|
-
- `Rect#centered_horizontally(constraint)` — centers horizontally using Layout
|
|
155
|
-
- `Rect#centered_vertically(constraint)` — centers vertically using Layout
|
|
156
|
-
- `Rect#centered(h, v)` — centers on both axes
|
|
157
|
-
- **TUI Shape Aliases (DWIM)**: Canvas shape factories now have terse and bidirectional aliases:
|
|
158
|
-
- Terse: `circle()`, `point()`, `map()`, `label()` (shorter forms of `shape_*`)
|
|
159
|
-
- Bidirectional: `circle_shape()`, `point_shape()`, `rectangle_shape()`, `map_shape()`, `label_shape()` (same as `shape_*`)
|
|
160
|
-
- Note: Terse `rectangle` is intentionally excluded to avoid confusion with `Layout::Rect`; use `shape_rectangle()` or `rectangle_shape()`.
|
|
161
|
-
- **TUI `item` Alias**: `tui.item(...)` is now an alias for `tui.list_item(...)`, providing a terser API when building lists.
|
|
162
|
-
- **Gauge and LineGauge `percent`**: Both widgets now have a `percent` reader that returns the ratio as an integer percentage (0-100). `LineGauge` also now accepts a `percent:` constructor parameter matching `Gauge`.
|
|
163
|
-
- **List#selected_item**: Returns the item at the selected index (or nil if nothing is selected).
|
|
164
|
-
- **Style `underline_color`**: New optional parameter for `Style` that sets a distinct underline color independent of the foreground color. Useful for styling like "white text with red underline". Terminals must support the underline color extension (SGR 58).
|
|
165
|
-
- **Style `remove_modifiers`**: New optional parameter for `Style` that explicitly removes modifiers when styles are patched/inherited. Corresponds to Ratatui's `sub_modifier` field. Use it to prevent inherited bold, italic, or other modifiers from propagating.
|
|
166
|
-
- **Symbols::Shade Constants**: New `RatatuiRuby::Symbols::Shade` module exposes Ratatui's shade block characters as named constants: `EMPTY` (" "), `LIGHT` ("░"), `MEDIUM` ("▒"), `DARK` ("▓"), `FULL` ("█"). Use them for gradients, density fills, or custom progress indicators.
|
|
167
|
-
- **Symbols::Line Constants and Sets**: New `RatatuiRuby::Symbols::Line` module exposes Ratatui's box-drawing characters with 36 individual constants (VERTICAL, HORIZONTAL, corners, T-junctions, cross) and 4 predefined sets: `NORMAL` (standard corners), `ROUNDED` (rounded corners), `DOUBLE` (double-line), `THICK` (heavy lines). Use them for custom borders or drawing.
|
|
168
|
-
- **Symbols::Bar Constants and Sets**: New `RatatuiRuby::Symbols::Bar` module exposes Ratatui's vertical bar characters (lower blocks) with 8 individual constants and 2 predefined sets: `NINE_LEVELS` (full resolution) and `THREE_LEVELS` (simplified). Used by Sparkline widget.
|
|
169
|
-
- **Symbols::Block Constants and Sets**: New `RatatuiRuby::Symbols::Block` module exposes Ratatui's horizontal block characters (left blocks) with 8 individual constants and 2 predefined sets: `NINE_LEVELS` (full resolution) and `THREE_LEVELS` (simplified). Used by Gauge widget.
|
|
170
|
-
- **Symbols::Scrollbar Sets**: New `RatatuiRuby::Symbols::Scrollbar` module exposes 4 predefined scrollbar symbol sets: `VERTICAL`, `DOUBLE_VERTICAL`, `HORIZONTAL`, `DOUBLE_HORIZONTAL`. Each set contains `track`, `thumb`, `begin_char`, and `end_char` symbols.
|
|
171
|
-
- **Cell `underline_color`**: `Buffer::Cell` and top-level `Cell` now expose `underline_color` attribute for introspecting styled underline colors during testing.
|
|
172
|
-
|
|
173
|
-
### Changed
|
|
174
|
-
|
|
175
|
-
- **`tui.draw` Argument Validation (Breaking)**: `tui.draw` now validates its arguments. Calling `draw` with neither a tree nor a block raises `ArgumentError`, as does calling it with both. Previously this produced undefined behavior.
|
|
176
|
-
- **`Layout.split` Stricter Type Checking (Breaking)**: `Layout.split` now rejects invalid `area` arguments with a clear `ArgumentError` instead of silently misbehaving. Objects must be a `Rect`, `Hash` with `:x/:y/:width/:height` keys, or respond to all four geometry methods.
|
|
177
|
-
- **Schema Directory Removed (Breaking)**: The legacy `lib/ratatui_ruby/schema/` directory has been removed. All widget classes now live exclusively in their proper namespaces (`Widgets::`, `Layout::`, `Text::`, etc.). Direct usage like `RatatuiRuby::Paragraph` (without `Widgets::`) is no longer supported. Use `RatatuiRuby::Widgets::Paragraph` or the TUI facade (`tui.paragraph`).
|
|
178
|
-
- **Buffer::Cell Modifiers (Breaking)**: `Buffer::Cell#modifiers` and `Cell#modifiers` now return an array of `Symbol`s (e.g., `[:bold, :italic]`) instead of `String`s. This unifies the API, as `Style` modifiers were already symbols. Code expecting strings (e.g. `cell.modifiers.include?("bold")`) must be updated to use symbols. This changes behavior established in v0.9.1.
|
|
179
|
-
|
|
180
|
-
### Fixed
|
|
181
|
-
|
|
182
|
-
- **Tabs Padding Coercion**: `Tabs` `padding_left` and `padding_right` now correctly coerce duck-typed integer values (objects responding to `to_int`/`to_i`) via `Integer()`. Previously these parameters were passed through without coercion, inconsistent with other integer parameters. `Text::Line` values are still accepted as-is for styled padding.
|
|
183
|
-
|
|
184
|
-
### Removed
|
|
185
|
-
|
|
186
|
-
- **NullIO Re-export (Breaking)**: Removed `RatatuiRuby::NullIO` constant. Use `RatatuiRuby::OutputGuard::NullIO` if you were relying on this internal class.
|
|
187
|
-
- **Legacy Media Keys (Breaking)**: Removed support for legacy unprefixed media keys (e.g. `play`, `stop`) in event parsing. You must now use the canonical `media_`-prefixed keys (e.g. `media_play`, `media_stop`). The `play?`/`stop?` predicates still work for both, checking the correct canonical codes.
|
|
188
|
-
|
|
189
|
-
## [0.9.1] - 2026-01-08
|
|
190
|
-
|
|
191
|
-
### Added
|
|
192
|
-
|
|
193
|
-
- **Constraint Batch Constructors**: `Constraint` now provides batch factory methods matching upstream Ratatui for creating constraint arrays in a single call:
|
|
194
|
-
- `from_lengths([10, 20, 10])` — create multiple Length constraints
|
|
195
|
-
- `from_percentages([25, 50, 25])` — create multiple Percentage constraints
|
|
196
|
-
- `from_mins([5, 10, 5])` — create multiple Min constraints
|
|
197
|
-
- `from_maxes([20, 30, 40])` — create multiple Max constraints
|
|
198
|
-
- `from_fills([1, 2, 1])` — create multiple Fill constraints
|
|
199
|
-
- `from_ratios([[1, 4], [2, 4], [1, 4]])` — create multiple Ratio constraints
|
|
200
|
-
|
|
201
|
-
- **Async Synchronization**: New `Event::Sync` event and `SyntheticEvents` module enable deterministic testing of async behavior:
|
|
202
|
-
- `Event::Sync` — synthetic event that signals runtimes (Tea, Kit) to wait for pending async operations before continuing
|
|
203
|
-
- `RatatuiRuby::SyntheticEvents` — thread-safe Ruby-only queue for synthetic events; runtimes check this alongside native events
|
|
204
|
-
- `inject_sync` test helper — injects a Sync event for deterministic async testing
|
|
205
|
-
|
|
206
|
-
### Changed
|
|
207
|
-
|
|
208
|
-
### Fixed
|
|
209
|
-
|
|
210
|
-
### Removed
|
|
211
|
-
|
|
212
|
-
## [0.9.0] - 2026-01-08
|
|
213
|
-
|
|
214
|
-
### Added
|
|
215
|
-
|
|
216
|
-
- **State Query Predicates (DWIM DX)**: Widgets now provide ergonomic predicate methods for querying selection and completion state:
|
|
217
|
-
- `List#selected?` — returns true if an item is selected
|
|
218
|
-
- `List#empty?` — returns true if the list has no items
|
|
219
|
-
- `Table#row_selected?`, `Table#column_selected?`, `Table#cell_selected?` — check selection state
|
|
220
|
-
- `Table#empty?` — returns true if the table has no rows
|
|
221
|
-
- `Gauge#filled?`, `Gauge#complete?` — check progress state (ratio > 0, ratio >= 1.0)
|
|
222
|
-
- `LineGauge#filled?`, `LineGauge#complete?` — same as Gauge
|
|
223
|
-
|
|
224
|
-
- **Symbol Constants (DWIM DX)**: Widgets now expose constants for enum-style parameters, enabling IDE autocomplete and self-documenting code:
|
|
225
|
-
- `List::HIGHLIGHT_ALWAYS`, `HIGHLIGHT_WHEN_SELECTED`, `HIGHLIGHT_NEVER`
|
|
226
|
-
- `List::DIRECTION_TOP_TO_BOTTOM`, `DIRECTION_BOTTOM_TO_TOP`
|
|
227
|
-
- `Table::HIGHLIGHT_*` — same as List
|
|
228
|
-
- `Table::FLEX_LEGACY`, `FLEX_START`, `FLEX_CENTER`, `FLEX_END`, `FLEX_SPACE_BETWEEN`, `FLEX_SPACE_AROUND`, `FLEX_SPACE_EVENLY`
|
|
229
|
-
- `Layout::Layout::DIRECTION_VERTICAL`, `DIRECTION_HORIZONTAL`
|
|
230
|
-
- `Layout::Layout::FLEX_*` — same as Table
|
|
231
|
-
|
|
232
|
-
- **TUI API Aliases (DWIM DX)**: The TUI facade now provides CSS-inspired constraint aliases for cleaner layout code:
|
|
233
|
-
- `fixed(n)` — alias for `constraint_length(n)`
|
|
234
|
-
- `percent(n)` — alias for `constraint_percentage(n)`
|
|
235
|
-
- `flex(n)` / `fr(n)` — aliases for `constraint_fill(n)` (Flexbox/Grid-inspired)
|
|
236
|
-
- `split(...)` — alias for `layout_split(...)`
|
|
237
|
-
|
|
238
|
-
- **ListState Navigation Methods**: `ListState` now provides ergonomic navigation methods matching upstream Ratatui:
|
|
239
|
-
- `select_next` — select the next item (or first if nothing selected)
|
|
240
|
-
- `select_previous` — select the previous item (or last if nothing selected)
|
|
241
|
-
- `select_first` — jump to the first item
|
|
242
|
-
- `select_last` — jump to the last item
|
|
243
|
-
|
|
244
|
-
- **Rect Methods**: `Rect` now provides edge accessors, size queries, geometry transformations, and iterators from upstream Ratatui:
|
|
245
|
-
- `left`, `right`, `top`, `bottom` — edge coordinates
|
|
246
|
-
- `area`, `empty?` — size queries
|
|
247
|
-
- `union(other)`, `inner(margin)`, `offset(dx, dy)`, `clamp(bounds)` — geometry transformations
|
|
248
|
-
- `rows`, `columns`, `positions` — iterators yielding slices or coordinates
|
|
249
|
-
|
|
250
|
-
### Changed
|
|
251
|
-
|
|
252
|
-
- **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.
|
|
253
|
-
- **License**: Documentation code snippets now use MIT-0, letting users copy example code without attribution requirements.
|
|
254
|
-
|
|
255
|
-
### Fixed
|
|
256
|
-
|
|
257
|
-
### Removed
|
|
258
|
-
|
|
259
|
-
- **`assert_snapshot`**: Removed deprecated test helper. Use `assert_plain_snapshot` or `assert_snapshots` instead.
|
|
260
|
-
- **`Block#border_color`**: Removed deprecated parameter. Use `border_style: Style.new(fg: color)` for equivalent functionality.
|
|
261
|
-
- **`LineChart`**: Removed deprecated widget. Use `Chart` with `Dataset.new(graph_type: :line)` instead. See `examples/widget_chart/` for usage.
|
|
262
|
-
|
|
263
|
-
## [0.8.0] - 2026-01-05
|
|
264
|
-
|
|
265
|
-
### Added
|
|
266
|
-
- **Output Guard**: `RatatuiRuby.guard_io { }` temporarily replaces `$stdout` and `$stderr` with a null sink, preventing screen corruption from chatty gems. Active when `terminal_active?` is true; warns if called outside a session (to catch mistakes); silent no-op in headless mode.
|
|
267
|
-
- **Headless Mode**: `RatatuiRuby.headless!` enables batch/CLI mode for apps with `--no-tui` flags. When headless, `guard_io` becomes a silent no-op and `init_terminal`/`run` raise `Error::Invariant`. This allows the same code to work in both TUI and non-TUI modes.
|
|
268
|
-
- **Terminal Safety Hooks**: `at_exit` and `Signal.trap` handlers for `INT` and `TERM` automatically 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.
|
|
269
|
-
|
|
270
|
-
### Changed
|
|
271
|
-
|
|
272
|
-
- **Double `init_terminal` Now Raises `Error::Invariant` (Breaking)** Calling `init_terminal`, `init_test_terminal`, or `run` while a TUI session is already active now raises `Error::Invariant`. Previously, this was undefined but silently "working" behavior that could cause terminal state corruption. If your code intentionally double-inits, call `restore_terminal` first.
|
|
273
|
-
|
|
274
|
-
### Fixed
|
|
275
|
-
|
|
276
|
-
### Removed
|
|
277
|
-
|
|
278
|
-
## [0.7.4] - 2026-01-05
|
|
279
|
-
|
|
280
|
-
### Added
|
|
281
|
-
|
|
282
|
-
- **Block Inner Area Calculation**: `Block#inner(area)` method computes the inner content area given an outer `Rect`, accounting for borders and padding. Essential for layout calculations when you need to know usable space inside a block.
|
|
283
|
-
- **Deferred Warnings During TUI Sessions**: Experimental feature warnings (like `Paragraph#line_count`) are now automatically queued during active TUI sessions and flushed to stderr after `restore_terminal`. This prevents warnings from corrupting the TUI display. See `doc/troubleshooting/tui_output.md` for details on handling terminal output during TUI sessions.
|
|
284
|
-
- **Session State Tracking**: `RatatuiRuby.terminal_active?` indicates whether a TUI session is active. Calling `init_terminal` or `init_test_terminal` while a session is already active now raises `Error::Invariant`.
|
|
285
|
-
- **Error::Invariant**: New error class for state invariant violations (e.g., double-init). Distinct from `Error::Safety` (lifetime violations) and `Error::Terminal` (operational I/O failures).
|
|
286
|
-
|
|
287
|
-
### Changed
|
|
288
|
-
|
|
289
|
-
### Fixed
|
|
290
|
-
|
|
291
|
-
- **Direct Text Rendering**: `Text::Line` and `Text::Span` can now be rendered directly as widgets via `frame.render_widget(line, area)` without wrapping in a `Paragraph`. Previously, these text primitives were silently ignored when passed to `render_widget`.
|
|
292
|
-
- **Text Line Alignment**: `Text::Line` `alignment:` parameter is now respected during rendering. Previously, the alignment was ignored and text always rendered left-aligned.
|
|
293
|
-
|
|
294
|
-
### Removed
|
|
295
|
-
|
|
296
|
-
## [0.7.3] - 2026-01-04
|
|
297
|
-
|
|
298
|
-
### Added
|
|
299
|
-
|
|
300
|
-
- **Symbol Shortcuts for `bar_set`**: `Sparkline` and `BarChart` now accept `:nine_levels` (full 9-character gradient) and `:three_levels` (simplified empty/half/full) as intuitive shortcuts instead of requiring custom character hashes.
|
|
301
|
-
- **`:half_block` Marker**: `Chart` `Dataset` now supports `:half_block` marker for higher resolution rendering using ▀ and ▄ characters.
|
|
302
|
-
- **`assert_snapshots` Method**: `RatatuiRuby::TestHelper#assert_snapshots` (plural) calls both `assert_plain_snapshot` and `assert_rich_snapshot` with the same name, generating both `.txt` and `.ansi` files for documentation and display purposes.
|
|
303
|
-
- **Edge-Center Legend Positions**: `Chart` `legend_position` now accepts `:top`, `:bottom`, `:left`, and `:right` in addition to the existing corner positions (`:top_left`, `:top_right`, `:bottom_left`, `:bottom_right`).
|
|
304
|
-
- **`:reset` Color**: `Style` `fg` and `bg` now accept `:reset` to explicitly clear any inherited foreground or background color, restoring the terminal's default.
|
|
305
|
-
|
|
306
|
-
### Changed
|
|
307
|
-
|
|
308
|
-
### Deprecated
|
|
309
|
-
|
|
310
|
-
- **`assert_snapshot`**: Use `assert_snapshots` (plural) instead, or `assert_plain_snapshot` if you only need plain text. The old method name lacked clarity about whether it captured plain text or styled ANSI output.
|
|
311
|
-
|
|
312
|
-
### Fixed
|
|
313
|
-
|
|
314
|
-
### Removed
|
|
315
|
-
|
|
316
|
-
## [0.7.2] - 2026-01-04
|
|
317
|
-
|
|
318
|
-
### Added
|
|
319
|
-
|
|
320
|
-
- **Tabs `padding_left` and `padding_right`**: Now accept `Integer` (for spaces), `String`, or `Text::Line` for styled padding content. Previously only accepted `Integer`. Passing a `Line` object allows colored or decorated padding.
|
|
321
|
-
|
|
322
|
-
### Changed
|
|
323
|
-
|
|
324
|
-
### Fixed
|
|
325
|
-
|
|
326
|
-
- **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:
|
|
327
|
-
- `Tabs` `divider`: Now correctly renders `Text::Span` objects.
|
|
328
|
-
- `Table` `highlight_symbol`: Now correctly renders `Text::Span` objects.
|
|
329
|
-
- `BarChart` `BarGroup` `label`: Now correctly renders `Text::Line` objects.
|
|
330
|
-
- `Chart` `Axis` `title`: Now correctly renders `Text::Line` objects.
|
|
331
|
-
- `Chart` `Axis` `labels`: Now correctly renders `Text::Line` objects.
|
|
332
|
-
- `Chart` `Dataset` `name`: Now correctly renders `Text::Line` objects.
|
|
333
|
-
|
|
334
|
-
### Removed
|
|
335
|
-
|
|
336
|
-
## [0.7.1] - 2026-01-03
|
|
337
|
-
|
|
338
|
-
### Added
|
|
339
|
-
|
|
340
|
-
### Changed
|
|
341
|
-
|
|
342
|
-
### Fixed
|
|
343
|
-
|
|
344
|
-
- **Block Title Styling**: `Block` title `content` now correctly renders `Text::Line` objects with styled spans. Previously, passing a styled `Line` as title content displayed its Ruby inspect representation (e.g., `#<data RatatuiRuby::Text::Line...>`) instead of the styled text.
|
|
345
|
-
|
|
346
|
-
### Removed
|
|
347
|
-
|
|
348
|
-
## [0.7.0] - 2026-01-03
|
|
349
|
-
|
|
350
|
-
> [!WARNING]
|
|
351
|
-
> v0.7.0 contains significant breaking changes. See the [Migration Guide](doc/v0.7.0_migration.md) for upgrade instructions.
|
|
352
|
-
|
|
353
|
-
### Added
|
|
354
|
-
|
|
355
|
-
- **Rich Text in Table Cells**: `Table` cells (rows, header, footer) now accept `Text::Span` and `Text::Line` objects for per-character styling, matching List widget capabilities.
|
|
356
|
-
- **Row Wrapper**: New `Widgets::Row` class 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 or `Widgets::Row` objects.
|
|
357
|
-
- **Cell Wrapper**: New `Widgets::Cell` class wraps table cell content with optional cell-level styling. Distinct from `Buffer::Cell` which is for buffer inspection.
|
|
358
|
-
- **Line#width Method**: `Text::Line` now has a `width` instance method that calculates the display width in terminal cells using unicode-aware measurement. Useful for layout calculations with rich text.
|
|
359
|
-
- **render_rich_buffer**: New `TestHelper::Snapshot#render_rich_buffer` method returns the terminal buffer as an ANSI-encoded string with escape codes for colors and modifiers. Useful for debugging, custom assertions, or programmatic inspection beyond `assert_rich_snapshot`.
|
|
360
|
-
|
|
361
|
-
### Changed
|
|
362
|
-
|
|
363
|
-
- **Namespace Restructure (Breaking)**: Classes reorganized to match Ratatui's module hierarchy. See [Migration Guide](doc/v0.7.0_migration.md) for details:
|
|
364
|
-
- `RatatuiRuby::Rect` → `RatatuiRuby::Layout::Rect`
|
|
365
|
-
- `RatatuiRuby::Constraint` → `RatatuiRuby::Layout::Constraint`
|
|
366
|
-
- `RatatuiRuby::Layout` → `RatatuiRuby::Layout::Layout`
|
|
367
|
-
- `RatatuiRuby::Style` → `RatatuiRuby::Style::Style`
|
|
368
|
-
- `RatatuiRuby::Paragraph` → `RatatuiRuby::Widgets::Paragraph`
|
|
369
|
-
- `RatatuiRuby::Block` → `RatatuiRuby::Widgets::Block`
|
|
370
|
-
- `RatatuiRuby::Table` → `RatatuiRuby::Widgets::Table`
|
|
371
|
-
- `RatatuiRuby::List` → `RatatuiRuby::Widgets::List`
|
|
372
|
-
- *(and all other widgets)*
|
|
373
|
-
- **Session → TUI Rename (Breaking)**: `RatatuiRuby::Session` renamed to `RatatuiRuby::TUI` to better reflect its role as a facade/DSL. The `TUI` class now uses explicit factory methods (no metaprogramming) for improved IDE autocomplete support.
|
|
374
|
-
- **Buffer::Cell vs Widgets::Cell (Breaking)**: `RatatuiRuby::Cell` (buffer inspection) renamed to `RatatuiRuby::Buffer::Cell`. New `RatatuiRuby::Widgets::Cell` added for table cell construction.
|
|
375
|
-
- **Text::Line style field (Breaking)**: `Text::Line` now accepts a `style:` parameter for line-level styling, matching Ratatui's `Line` struct which has `style`, `alignment`, and `spans` fields.
|
|
376
|
-
- **Table highlight_style → row_highlight_style (Breaking)**: `Table` parameter `highlight_style:` renamed to `row_highlight_style:` to match Ratatui's API naming convention.
|
|
377
|
-
|
|
378
|
-
### Fixed
|
|
379
|
-
|
|
380
|
-
### Removed
|
|
381
|
-
|
|
382
|
-
## [0.6.0] - 2026-01-03
|
|
383
|
-
|
|
384
|
-
### Added
|
|
385
|
-
|
|
386
|
-
- **Rich Text Support**: `List`, `Gauge`, `LineGauge`, and `BarChart` widgets 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.
|
|
387
|
-
- **ListItem Wrapper**: New `ListItem` data class allows applying row-level styling (background color) independent of text content. `List` items can now be `String`, `Text::Span`, `Text::Line`, or `ListItem` objects.
|
|
388
|
-
- **Non-Blocking Event Polling**: `RatatuiRuby.poll_event` now accepts an optional `timeout:` parameter (Float seconds). Use `timeout: 0.0` for non-blocking checks, or `timeout: 0.1` for fixed timesteps. Defaults to `0.016` (16ms) to preserve existing behavior.
|
|
389
|
-
- **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.
|
|
390
|
-
- **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.
|
|
391
|
-
- **Scroll Offset Control**: `List` and `Table` widgets now accept an optional `offset` parameter 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 to `nil` for fully manual scroll control.
|
|
392
|
-
- **Rect Geometry Helpers**: `Rect#intersects?(other)` tests whether two rectangles overlap. `Rect#intersection(other)` returns the overlapping area as a new `Rect`, or `nil` if disjoint. Essential for viewport clipping and hit testing in component architectures.
|
|
393
|
-
- **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`).
|
|
394
|
-
- **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 proper `snake_case` strings.
|
|
395
|
-
- **Key Categories**: `Event::Key` now has a `kind` attribute (`:standard`, `:function`, `:media`, `:modifier`, `:system`) for logical grouping. Category predicates (`media?`, `system?`, `function?`, `modifier?`, `standard?`) enable clean event routing without string parsing. The `unmodified?` method is an alias for `standard?`.
|
|
396
|
-
- **Smart Predicates (DWIM)**: Key predicates now "Do What I Mean" for media keys. `pause?` returns `true` for both system `pause` and `media_pause` keys. For strict matching, use `media_pause?` or compare `event.code` directly. This reduces boilerplate when responding to conceptual actions regardless of input method.
|
|
397
|
-
- **Modifier Key Predicates**: New methods `super?`, `hyper?`, and `meta?` check for these modifier keys. Platform aliases are provided for `super?`: `command?`/`cmd?` (macOS), `win?` (Windows), and `tux?` (Linux). These work for both modifier flags AND individual modifier key events (e.g., `left_super`). Additionally, `control?` aliases `ctrl?` and `option?` aliases `alt?`.
|
|
398
|
-
- **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 special `reverse_tab?` predicate matches both the `back_tab` key and `shift+tab` combinations.
|
|
399
|
-
- **Indexed Color Support**: `Style` now supports `Integer` values for `fg` and `bg`, 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).
|
|
400
|
-
- **Rich Snapshots**: `RatatuiRuby::TestHelper#assert_rich_snapshot` validates 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.
|
|
401
|
-
- **Semantic Style Assertions**: New testing helpers `assert_color(expected, x:, y:)`, `assert_cell_style(x, y, **style)`, and `assert_area_style(area, **style)` allow precise verification of terminal cell attributes without full-screen snapshots. Punchy convenience aliases like `assert_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.
|
|
402
|
-
- **Buffer Debugging**: `RatatuiRuby::TestHelper#print_buffer` outputs the current terminal state to STDOUT with full ANSI color support, making it easier to debug rendering issues during test execution.
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
### Changed
|
|
406
|
-
|
|
407
|
-
- **Frozen Data Objects (Breaking)**: Events returned by `RatatuiRuby.poll_event` and `Cell` objects from `RatatuiRuby.get_cell_at` are now deeply frozen for Ractor compatibility. Code that mutates these objects (e.g., `event.modifiers << "custom"`) must copy the data before modifying. `Rect` was already frozen. Note: `Frame` and `Session` are *I/O handles* with side effects and remain intentionally non-shareable.
|
|
408
|
-
- **Semantic Exceptions (Breaking)**: Replaced generic `RuntimeError` with `RatatuiRuby::Error::Terminal` for backend/terminal failures and `RatatuiRuby::Error::Safety` for API contract violations (like using `Frame` outside `draw`). This allows finer-grained error handling but breaks code explicitly rescuing `RuntimeError`. `ArgumentError` works as before.
|
|
409
|
-
- **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.
|
|
410
|
-
- **`Key#char` Return Value (Breaking)**: `char` now returns `nil` for non-printable keys (previously returned `""`). Code relying on `event.char.empty?` must change to `event.char.nil?` or use `event.text?` instead.
|
|
411
|
-
|
|
412
|
-
### Fixed
|
|
413
|
-
|
|
414
|
-
- **Frame Safety**: Calling methods on a `Frame` stored outside of a `draw` block now correctly raises a `RatatuiRuby::Error::Safety` (subclass of `RatatuiRuby::Error`) instead instead of causing undefined behavior or crashes. This ensures memory safety by preventing use-after-free scenarios with the underlying Rust frame.
|
|
415
|
-
|
|
416
|
-
### Removed
|
|
417
|
-
|
|
418
|
-
## [0.5.0] - 2026-01-01
|
|
419
|
-
|
|
420
|
-
### Added
|
|
421
|
-
|
|
422
|
-
#### Frame API
|
|
423
|
-
|
|
424
|
-
- **`RatatuiRuby.draw { |frame| ... }`**: New block-based drawing API that yields a `Frame` object for explicit widget placement. Enables hit testing without duplicating layout calculations.
|
|
425
|
-
- **`Frame#area`**: Returns the terminal area as a `Rect`.
|
|
426
|
-
- **`Frame#render_widget(widget, rect)`**: Renders a widget at a specific position. Works with all existing widgets and `Rect` objects.
|
|
427
|
-
|
|
428
|
-
#### Testing
|
|
429
|
-
|
|
430
|
-
- **`RatatuiRuby::TestHelper#inject_mouse`**: comprehensive mouse event injection helper supporting coordinates, buttons, and modifiers.
|
|
431
|
-
- **`RatatuiRuby::TestHelper#inject_click`**: Helper for left-click events.
|
|
432
|
-
- **`RatatuiRuby::TestHelper#inject_right_click`**: Helper for right-click events.
|
|
433
|
-
- **`RatatuiRuby::TestHelper#inject_drag`**: Helper for mouse drag events.
|
|
434
|
-
- **`RatatuiRuby::TestHelper#assert_screen_matches`**: Assert that the current terminal content matches a stored golden snapshot.
|
|
435
|
-
|
|
436
|
-
#### Session API
|
|
437
|
-
|
|
438
|
-
- **Convenience Methods**: `Session` now wraps class methods from `Layout`, `Constraint`, and other schema classes as instance methods (e.g., `layout_split` delegates to `Layout.split`, `constraint_percentage` to `Constraint.percentage`). This enables a more fluent API in `RatatuiRuby.run` blocks.
|
|
439
|
-
|
|
440
|
-
### Changed
|
|
441
|
-
|
|
442
|
-
#### Event System
|
|
443
|
-
|
|
444
|
-
- **`Event::None` (Breaking)**: `RatatuiRuby.poll_event` now returns `Event::None` instead of `nil` when no event is available. This null-object responds safely to all event predicates with `false`. Use `event.none?` or pattern-match on `type: :none`. Code using `while (event = poll_event)` must change to `while (event = poll_event) && !event.none?`.
|
|
445
|
-
|
|
446
|
-
### Fixed
|
|
447
|
-
|
|
448
|
-
#### Session API
|
|
449
|
-
|
|
450
|
-
- **Missing Convenience Methods**: Fixed `Session` convenience methods (e.g., `bar_chart`) being missed by replacing the manual list with automatic runtime introspection of the `RatatuiRuby` module.
|
|
451
|
-
|
|
452
|
-
### Removed
|
|
453
|
-
|
|
454
|
-
## [0.4.0] - 2025-12-30
|
|
455
|
-
|
|
456
|
-
### Added
|
|
457
|
-
|
|
458
|
-
#### Hex Color Support
|
|
459
|
-
|
|
460
|
-
- **Style**: `fg` and `bg` parameters 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.
|
|
461
|
-
|
|
462
|
-
#### RatatuiMascot Widget
|
|
463
|
-
|
|
464
|
-
- **RatatuiMascot**: New widget to display the Ratatui mascot (Ferris).
|
|
465
|
-
|
|
466
|
-
#### RatatuiLogo Widget
|
|
467
|
-
|
|
468
|
-
- **RatatuiLogo**: New widget to display the Ratatui logo.
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
#### Duck-Typed Numeric Coercion
|
|
472
|
-
|
|
473
|
-
- All numeric parameters now accept any object that responds to `to_f` (for floats) or `to_int`/`to_i` (for integers). This provides idiomatic Ruby interoperability with `BigDecimal`, `Rational`, and custom numeric types. Uses Ruby's built-in `Float()` and `Integer()` Kernel methods for proper duck-type handling.
|
|
474
|
-
|
|
475
|
-
#### Paragraph Widget
|
|
476
|
-
|
|
477
|
-
- `alignment`: **Breaking Change**: Renamed `align` to `alignment` to match Ratatui 0.30 API.
|
|
478
|
-
|
|
479
|
-
#### Custom Widgets
|
|
480
|
-
|
|
481
|
-
- **Draw Command API**: Custom widgets now return an array of `Draw` commands instead of writing to a buffer. Use `RatatuiRuby::Draw.string(x, y, string, style)` and `RatatuiRuby::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:** The `render` method signature changed from `render(area, buffer)` to `render(area)`.
|
|
482
|
-
|
|
483
|
-
#### BarChart Widget
|
|
484
|
-
|
|
485
|
-
- `bar_set`: Customize bar characters (digits, symbols, blocks).
|
|
486
|
-
- `group_gap`: Control spacing between groups in grouped bar charts.
|
|
487
|
-
- `data`: Now accepts an Array of `BarGroup` objects, enabling grouped bar charts.
|
|
488
|
-
- `Bar` and `BarGroup`: New schema classes for defining grouped bar data.
|
|
489
|
-
|
|
490
|
-
#### Block Widget
|
|
491
|
-
|
|
492
|
-
- `border_type`: Customize border style (`:plain`, `:rounded`, `:double`, `:thick`, `:quadrant_inside`, `:quadrant_outside`).
|
|
493
|
-
- `border_set`: Customize border characters (e.g., digits, symbols).
|
|
494
|
-
- `border_style`: Apply full style support (colors and modifiers) to borders. Takes precedence over `border_color`.
|
|
495
|
-
- `children`: Declare child widgets within the block's area for composable UI structures.
|
|
496
|
-
- Multiple `titles`: Display multiple titles with individual alignment (`:left`, `:center`, `:right`) and vertical positioning (`:top`, `:bottom`). Each title supports its own `style`.
|
|
497
|
-
- `title_style`: Base style applied to all titles.
|
|
498
|
-
- `style`: Base style applied to the entire block.
|
|
499
|
-
- `padding`: Directional padding via a single integer (uniform) or array of 4 integers (`[left, right, top, bottom]`).
|
|
500
|
-
- `line_count(width)`: **(Experimental)** Calculate rendered lines (including borders/padding) for a given width. Delegates to Ratatui's underlying unstable `line_count`.
|
|
501
|
-
- `line_width`: **(Experimental)** Calculate minimum width to avoid wrapping (including borders/padding). Delegates to Ratatui's underlying unstable `line_width`.
|
|
502
|
-
|
|
503
|
-
#### Calendar Widget
|
|
504
|
-
|
|
505
|
-
- `events`: Hash mapping `Date` objects to `Style` objects for highlighting specific dates.
|
|
506
|
-
- `show_month_header`: Toggle month header visibility (defaults to `false`). **Breaking:** Previously always shown.
|
|
507
|
-
- `show_weekdays_header`: Toggle weekday names (Mon, Tue, etc.) visibility (defaults to `true`).
|
|
508
|
-
- `show_surrounding`: Optional `Style` to display dates from adjacent months, or `nil` to hide them.
|
|
509
|
-
|
|
510
|
-
#### Chart Widget
|
|
511
|
-
|
|
512
|
-
- `legend_position`: Position legend at `:top_left`, `:top_right`, `:bottom_left`, or `:bottom_right` (defaults to `:top_right`).
|
|
513
|
-
- `hidden_legend_constraints`: Array of two `Constraint` objects to hide the legend when chart area is too small.
|
|
514
|
-
- **Axis**: `labels_alignment` to control horizontal alignment (`:left`, `:center`, `:right`) of axis labels.
|
|
515
|
-
- `Dataset`: `style` parameter replaces `color`, enabling full styling (fg, bg, modifiers) for chart datasets. **Breaking**: `color` parameter removed.
|
|
516
|
-
|
|
517
|
-
#### Gauge Widget
|
|
518
|
-
|
|
519
|
-
- `style`: Base style applied to the entire gauge background.
|
|
520
|
-
- `gauge_style`: Style applied specifically to the filled bar. **Breaking:** Use this instead of `style` if you want bar coloring; `style` no longer defaults to `Style.default`.
|
|
521
|
-
- `percent`: Convenience parameter alternative to `ratio` for initialization.
|
|
522
|
-
- `use_unicode`: Explicitly toggle between unicode blocks and ASCII rendering (defaults to `true`).
|
|
523
|
-
|
|
524
|
-
#### LineGauge Widget
|
|
525
|
-
|
|
526
|
-
- `style`: Base style applied to the entire gauge area.
|
|
527
|
-
|
|
528
|
-
#### List Widget
|
|
529
|
-
|
|
530
|
-
- `scroll_padding`: Number of items to keep visible above and below the selected item during scrolling.
|
|
531
|
-
- `repeat_highlight_symbol`: When `true`, repeat highlight symbol on each line of multi-line selections.
|
|
532
|
-
- `highlight_spacing`: Control selection column reservation (`:always`, `:when_selected`, `:never`).
|
|
533
|
-
- `direction`: List orientation (`:top_to_bottom` or `:bottom_to_top`).
|
|
534
|
-
|
|
535
|
-
#### Sparkline Widget
|
|
536
|
-
|
|
537
|
-
- `absent_value_symbol` and `absent_value_style`: Customize rendering of `nil` values (distinct from `0`).
|
|
538
|
-
- `direction`: Rendering direction (`:left_to_right` or `:right_to_left`).
|
|
539
|
-
- `bar_set`: Customize bar characters.
|
|
540
|
-
|
|
541
|
-
#### Table Widget
|
|
542
|
-
|
|
543
|
-
- `style`: Base style applied to the entire table.
|
|
544
|
-
- `column_spacing`: Horizontal spacing between columns.
|
|
545
|
-
- `footer`: Summary rows at the bottom of the table.
|
|
546
|
-
- `flex`: Layout distribution mode (`:legacy`, `:start`, `:center`, `:end`, `:space_between`, `:space_around`, `:space_evenly`).
|
|
547
|
-
- `highlight_spacing`: Control selection column reservation (`:always`, `:when_selected`, `:never`).
|
|
548
|
-
- `column_highlight_style`: Style applied to the selected column.
|
|
549
|
-
- `cell_highlight_style`: Style applied to the selected cell (intersection of row and column).
|
|
550
|
-
- `selected_column`: Index of the selected column (Integer or nil).
|
|
551
|
-
- `widths`: Now support all constraint types (`:max`, `:fill`, `:ratio`) with full flexibility.
|
|
552
|
-
|
|
553
|
-
#### Tabs Widget
|
|
554
|
-
|
|
555
|
-
- `style`: Base style applied to the entire tabs area.
|
|
556
|
-
- `padding_left` and `padding_right`: Horizontal padding around tab titles.
|
|
557
|
-
- `width`: Calculate total width of the tabs (including dividers/padding).
|
|
558
|
-
|
|
559
|
-
#### Canvas Widget
|
|
560
|
-
|
|
561
|
-
- `background_color`: Set canvas background color.
|
|
562
|
-
- `:half_block` marker: Block-based rendering using half-height blocks.
|
|
563
|
-
- `:quadrant`, `:sextant`, `:octant` markers: High-resolution pseudo-pixel rendering.
|
|
564
|
-
- `Shape::Label`: Text labels at canvas coordinates with optional styling.
|
|
565
|
-
|
|
566
|
-
#### Scrollbar Widget
|
|
567
|
-
|
|
568
|
-
- Full styling support: `thumb_style`, `track_symbol`, `track_style`, `begin_symbol`, `begin_style`, `end_symbol`, `end_style`, `style`.
|
|
569
|
-
- All orientation variants: `:vertical_left`, `:vertical_right`, `:horizontal_top`, `:horizontal_bottom` (`:vertical` and `:horizontal` remain as aliases).
|
|
570
|
-
|
|
571
|
-
#### Layout & Constraints
|
|
572
|
-
|
|
573
|
-
- `Constraint.ratio(numerator, denominator)`: Proportional constraints with explicit ratio.
|
|
574
|
-
- `Constraint.fill(weight)`: Distribute remaining space proportionally. Use multiple `Fill` to split space (e.g., `Fill(1)` and `Fill(3)` split 1:3).
|
|
575
|
-
- `Constraint.max(value)`: Cap maximum size of a section.
|
|
576
|
-
- `Layout.split(area, direction:, constraints:, flex:)`: Compute layout rectangles without rendering, enabling hit testing.
|
|
577
|
-
- `Flex::SpaceEvenly`: New layout mode for `Layout` widget.
|
|
578
|
-
- `flex` parameter: All layout options (`:legacy`, `:start`, `:center`, `:end`, `:space_between`, `:space_around`, `:space_evenly`).
|
|
579
|
-
|
|
580
|
-
#### Rich Text & Text Components
|
|
581
|
-
|
|
582
|
-
- `Text::Span` and `Text::Line`: Styled text with inline formatting. Combine spans into lines with optional alignment.
|
|
583
|
-
- `Shape` module: Canvas shape primitives (`Shape::Line`, `Shape::Circle`, `Shape::Rectangle`, `Shape::Point`, `Shape::Map`) to avoid naming conflicts with `Text::Line`.
|
|
584
|
-
|
|
585
|
-
#### Event System
|
|
586
|
-
|
|
587
|
-
- Typed `Event` API: `RatatuiRuby.poll_event` returns typed objects (`Event::Key`, `Event::Mouse`, `Event::Resize`, `Event::Paste`, `Event::FocusGained`, `Event::FocusLost`).
|
|
588
|
-
- Predicate methods: `key?`, `mouse?`, `ctrl?`, etc. for cleaner event handling.
|
|
589
|
-
- Pattern matching support and discriminator pattern via `type:` key in `#deconstruct_keys`.
|
|
590
|
-
- `Event::Resize`: Terminal resize events with `width` and `height` attributes.
|
|
591
|
-
- `Event::Paste`: Bracketed paste as atomic event with `content:`.
|
|
592
|
-
- `Event::FocusGained` and `Event::FocusLost`: Terminal focus changes.
|
|
593
|
-
- `Event::Mouse.new` accepts `nil` for `button` parameter (treated as `"none"`).
|
|
594
|
-
|
|
595
|
-
#### Geometry & Hit Testing
|
|
596
|
-
|
|
597
|
-
- `Rect#contains?(x, y)`: Test whether a point is inside a rectangle. Essential for mouse click handlers.
|
|
598
|
-
- `Layout.split`: Enables calculating widget positions before rendering.
|
|
599
|
-
|
|
600
|
-
#### Testing
|
|
601
|
-
|
|
602
|
-
- `RatatuiRuby::TestHelper#inject_keys`: Concise event injection helper.
|
|
603
|
-
- `RatatuiRuby::TestHelper#get_cell` and `#assert_cell_style`: Inspect terminal cell attributes (colors, characters).
|
|
604
|
-
- `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.
|
|
605
|
-
- Error on `inject_event`/`inject_keys` outside `with_test_terminal`: Prevents test hangs from race conditions.
|
|
606
|
-
- Value equality (`==`) for `Event` objects: Simplify assertions.
|
|
607
|
-
|
|
608
|
-
#### Lifecycle & Application Structure
|
|
609
|
-
|
|
610
|
-
- `RatatuiRuby.run`: New context manager that initializes terminal, yields session, and restores on exit. Allows custom event loop control.
|
|
611
|
-
- **Session** class: Renamed from `DSL` to better reflect its purpose as a managed terminal session with convenience methods.
|
|
612
|
-
- Focus and Bracketed Paste events: Enabled by default in `RatatuiRuby.run` and `RatatuiRuby.init_terminal` (disable with `focus_events: false` or `bracketed_paste: false`).
|
|
613
|
-
|
|
614
|
-
#### Documentation & Examples
|
|
615
|
-
|
|
616
|
-
- **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.
|
|
617
|
-
|
|
618
|
-
### Changed
|
|
619
|
-
|
|
620
|
-
- **Calendar:** Renamed `day_style` to `default_style` to match Ratatui 0.30 API. This is a breaking change. [Kerrick Long]
|
|
621
|
-
|
|
622
|
-
- **Custom Widget `render` Method (Breaking)**: Changed signature from `render(area, buffer)` to `render(area)`, with render methods now returning an array of `Draw` commands instead of writing directly to a buffer. This change improves memory safety by eliminating use-after-free risks.
|
|
623
|
-
- **Ratatui Upgraded to 0.30.0**: Underlying `ratatui` library upgraded from 0.29, bringing modularized crates, `no_std` support for embedded targets, and major widget/layout enhancements. Layout cache explicitly enabled for performance.
|
|
624
|
-
- **Event API (Breaking)**: `RatatuiRuby.poll_event` returns typed `Event` objects instead of raw Hashes. Code using `event[:type]` must change to `event.key?`, `event.code`, etc.
|
|
625
|
-
- **RatatuiRuby.main_loop Removed (Breaking)**: Removed in favor of `RatatuiRuby.run` for more explicit lifecycle control.
|
|
626
|
-
- **TestHelper Terminal Size (Breaking)**: `with_test_terminal` defaults to 80×24 instead of 20×10.
|
|
627
|
-
- **Calendar Month Header Default (Breaking)**: `show_month_header` defaults to `false` (previously always shown). Set `show_month_header: true` if relying on the old behavior.
|
|
628
|
-
- **Gauge `style` Default (Breaking)**: No longer defaults to `Style.default`. Use `gauge_style` for bar coloring instead.
|
|
629
|
-
|
|
630
|
-
### Fixed
|
|
631
|
-
|
|
632
|
-
- **Alpine Linux Support**: Fixed gem installation failures on Alpine Linux (musl targets) by properly configuring `crate-type` to support static linking where dynamic linking is unsupported.
|
|
633
|
-
- **Rust Safety**: Convert `class.name()` results to owned strings for proper GC safety with Magnus 0.8.
|
|
634
|
-
- **Terminal Preview Detection**: Detect staged changes correctly in preview generation.
|
|
635
|
-
|
|
636
|
-
## [0.3.1] - 2025-12-28
|
|
637
|
-
|
|
638
|
-
### Added
|
|
639
|
-
|
|
640
|
-
- **Ruby 4 Support**: Updated magnus FFI bindings to use the modern API for Ruby 4.0.0 compatibility.
|
|
641
|
-
|
|
642
|
-
## [0.3.0] - 2025-12-28
|
|
643
|
-
|
|
644
|
-
### Added
|
|
645
|
-
|
|
646
|
-
- **Custom Widget API (Breaking)**: Custom widgets that define a `render` method now receive only `area` (not `buffer`) and must return an array of `Draw` commands. Use `RatatuiRuby::Draw.string(x, y, string, style)` and `RatatuiRuby::Draw.cell(x, y, cell)` instead of `buffer.set_string` and `buffer.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.
|
|
647
|
-
- **The Escape Hatch (Ruby Render Callback)**: Added the ability to define custom widgets in pure Ruby by implementing a `render(area, buffer)` method. The `Buffer` object provides low-level drawing primitives like `set_string`, allowing developers to create custom TUI components without writing Rust code.
|
|
648
|
-
- **Clear Widget**: Added the `Clear` widget, 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.
|
|
649
|
-
- **Interactive Table Selection**: The `Table` widget now supports row selection with `selected_row`, `highlight_style`, and `highlight_symbol` parameters. This enables building interactive data grids and file explorers where users can navigate through rows using keyboard input.
|
|
650
|
-
- **Scrollable Paragraphs**: The `Paragraph` widget now supports a `scroll` parameter 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.
|
|
651
|
-
- **Enhanced Tabs Customization**: The `Tabs` widget now supports `highlight_style` for the selected tab and a customizable `divider` string (defaulting to the standard pipe `|`). This allows for richer visual feedback in tabbed interfaces.
|
|
652
|
-
|
|
653
|
-
### Changed
|
|
654
|
-
|
|
655
|
-
- **Center Widget**: Removed the implicit `Clear` call from the `Center` widget. `Center` is now a pure layout widget, requiring an explicit `Clear` widget if background clearing is desired. This restores correct behavior for transparent overlays.
|
|
656
|
-
|
|
657
|
-
## [0.2.0] - 2025-12-24
|
|
658
|
-
|
|
659
|
-
### Added
|
|
660
|
-
|
|
661
|
-
- **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.
|
|
662
|
-
- **Calendar Widget**: Added the `Calendar` widget, allowing you to display monthly views and visualize date-based information.
|
|
663
|
-
- **Generic Charts**: Implemented the full `Chart` widget, which supersedes the now-deprecated `LineChart` and `BarChart` widgets, giving you more freedom to visualize data sets.
|
|
664
|
-
- **Enhanced List Styling**: You can now customize the appearance of selected items in a `List` using `highlight_style` and `highlight_symbol`.
|
|
665
|
-
- **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.
|
|
666
|
-
- **Dev Tools**: Added internal Rake tasks for managing historical documentation and SemVer checks.
|
|
667
|
-
|
|
668
|
-
## [0.1.0] - 2025-12-22
|
|
669
|
-
|
|
670
|
-
### Added
|
|
671
|
-
|
|
672
|
-
- **First Release**: Initial public release of `ratatui_ruby`, bringing the power of the Rust [ratatui](https://github.com/ratatui-org/ratatui) library to Rubyists!
|
|
673
|
-
- **Core Widget Set**: Includes a comprehensive suite of widgets to get you started:
|
|
674
|
-
- `Block`, `Borders`, and `Paragraph` for basic content.
|
|
675
|
-
- `List` and `Table` for structured data.
|
|
676
|
-
- `Gauge` and `Sparkline` for progress and metrics.
|
|
677
|
-
- `Tabs` for navigation.
|
|
678
|
-
- `Canvas` for drawing shapes (Lines, Circles, Rectangles, Maps).
|
|
679
|
-
- **Layout System**: A flexible layout engine using `Flex`, `Layout`, and `Constraints` to build responsive interfaces that adapt to any terminal size.
|
|
680
|
-
- **Forms & Layers**: Primitives like `Overlay` and `Center` for creating modal dialogs, plus a `Cursor` widget for text input interactions.
|
|
681
|
-
- **Styling**: Full support for `Ratatui`'s styling primitives, including modifiers and RGB/ANSI colors.
|
|
682
|
-
- **Input Handling**: Robust handling for both Keyboard and Mouse events.
|
|
683
|
-
- **Testing Support**: Included `RatatuiRuby::TestHelper` and RSpec integration to make testing your TUI applications possible.
|
|
684
|
-
|
|
685
|
-
[Unreleased]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/HEAD
|
|
686
|
-
[1.0.0]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v1.0.0
|
|
687
|
-
[1.0.0-beta.3]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v1.0.0-beta.3
|
|
688
|
-
[1.0.0-beta.2]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v1.0.0-beta.2
|
|
689
|
-
[1.0.0-beta.1]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v1.0.0-beta.1
|
|
690
|
-
[0.10.3]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v0.10.3
|
|
691
|
-
[0.10.2]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v0.10.2
|
|
692
|
-
[0.10.1]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v0.10.1
|
|
693
|
-
[0.10.1]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v0.10.1
|
|
694
|
-
[0.10.1]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v0.10.1
|
|
695
|
-
[0.10.0]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v0.10.0
|
|
696
|
-
[0.9.1]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v0.9.1
|
|
697
|
-
[0.9.0]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v0.9.0
|
|
698
|
-
[0.8.0]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v0.8.0
|
|
699
|
-
[0.7.4]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v0.7.4
|
|
700
|
-
[0.7.3]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v0.7.3
|
|
701
|
-
[0.7.2]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v0.7.2
|
|
702
|
-
[0.7.1]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v0.7.1
|
|
703
|
-
[0.7.0]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v0.7.0
|
|
704
|
-
[0.6.0]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v0.6.0
|
|
705
|
-
[0.5.0]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v0.5.0
|
|
706
|
-
[0.4.0]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v0.4.0
|
|
707
|
-
[0.3.1]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v0.3.1
|
|
708
|
-
[0.3.0]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v0.3.0
|
|
709
|
-
[0.2.0]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v0.2.0
|
|
710
|
-
[0.1.0]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v0.1.0
|