ratatui_ruby 0.6.0 → 0.7.0
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/.builds/ruby-3.2.yml +1 -1
- data/.builds/ruby-3.3.yml +1 -1
- data/.builds/ruby-3.4.yml +1 -1
- data/.builds/ruby-4.0.0.yml +1 -1
- data/AGENTS.md +4 -4
- data/CHANGELOG.md +35 -0
- data/README.md +26 -1
- data/doc/application_architecture.md +16 -16
- data/doc/application_testing.md +1 -1
- data/doc/contributors/architectural_overhaul/chat_conversations.md +4952 -0
- data/doc/contributors/architectural_overhaul/implementation_plan.md +60 -0
- data/doc/contributors/architectural_overhaul/task.md +37 -0
- data/doc/contributors/design/ruby_frontend.md +277 -81
- data/doc/contributors/design/rust_backend.md +349 -55
- data/doc/contributors/developing_examples.md +5 -5
- data/doc/contributors/index.md +7 -5
- data/doc/contributors/v1.0.0_blockers.md +1729 -0
- data/doc/index.md +11 -6
- data/doc/interactive_design.md +2 -2
- data/doc/quickstart.md +66 -97
- data/doc/v0.7.0_migration.md +236 -0
- data/doc/why.md +93 -0
- data/examples/app_all_events/README.md +6 -4
- data/examples/app_all_events/app.rb +1 -1
- data/examples/app_all_events/model/app_model.rb +1 -1
- data/examples/app_all_events/model/msg.rb +1 -1
- data/examples/app_all_events/update.rb +1 -1
- data/examples/app_all_events/view/app_view.rb +1 -1
- data/examples/app_all_events/view/controls_view.rb +1 -1
- data/examples/app_all_events/view/counts_view.rb +1 -1
- data/examples/app_all_events/view/live_view.rb +1 -1
- data/examples/app_all_events/view/log_view.rb +1 -1
- data/examples/app_color_picker/README.md +7 -5
- data/examples/app_color_picker/app.rb +1 -1
- data/examples/app_login_form/README.md +2 -0
- data/examples/app_stateful_interaction/README.md +2 -0
- data/examples/app_stateful_interaction/app.rb +1 -1
- data/examples/verify_quickstart_dsl/README.md +4 -3
- data/examples/verify_quickstart_dsl/app.rb +1 -1
- data/examples/verify_quickstart_layout/README.md +1 -1
- data/examples/verify_quickstart_lifecycle/README.md +3 -3
- data/examples/verify_quickstart_lifecycle/app.rb +2 -2
- data/examples/verify_readme_usage/README.md +1 -1
- data/examples/widget_barchart_demo/README.md +2 -1
- data/examples/widget_block_demo/README.md +2 -0
- data/examples/widget_box_demo/README.md +3 -3
- data/examples/widget_calendar_demo/README.md +3 -3
- data/examples/widget_calendar_demo/app.rb +5 -1
- data/examples/widget_canvas_demo/README.md +3 -3
- data/examples/widget_cell_demo/README.md +3 -3
- data/examples/widget_center_demo/README.md +3 -3
- data/examples/widget_chart_demo/README.md +3 -3
- data/examples/widget_gauge_demo/README.md +3 -3
- data/examples/widget_layout_split/README.md +3 -3
- data/examples/widget_line_gauge_demo/README.md +3 -3
- data/examples/widget_list_demo/README.md +3 -3
- data/examples/widget_map_demo/README.md +3 -3
- data/examples/widget_map_demo/app.rb +2 -2
- data/examples/widget_overlay_demo/README.md +36 -0
- data/examples/widget_popup_demo/README.md +3 -3
- data/examples/widget_ratatui_logo_demo/README.md +3 -3
- data/examples/widget_ratatui_logo_demo/app.rb +1 -1
- data/examples/widget_ratatui_mascot_demo/README.md +3 -3
- data/examples/widget_rect/README.md +3 -3
- data/examples/widget_render/README.md +3 -3
- data/examples/widget_render/app.rb +3 -3
- data/examples/widget_rich_text/README.md +3 -3
- data/examples/widget_scroll_text/README.md +3 -3
- data/examples/widget_scrollbar_demo/README.md +3 -3
- data/examples/widget_sparkline_demo/README.md +3 -3
- data/examples/widget_style_colors/README.md +3 -3
- data/examples/widget_table_demo/README.md +3 -3
- data/examples/widget_table_demo/app.rb +19 -4
- data/examples/widget_tabs_demo/README.md +3 -3
- data/examples/widget_text_width/README.md +3 -3
- data/examples/widget_text_width/app.rb +8 -1
- data/ext/ratatui_ruby/Cargo.lock +1 -1
- data/ext/ratatui_ruby/Cargo.toml +1 -1
- data/ext/ratatui_ruby/src/frame.rs +6 -5
- data/ext/ratatui_ruby/src/lib.rs +3 -2
- data/ext/ratatui_ruby/src/rendering.rs +22 -21
- data/ext/ratatui_ruby/src/text.rs +12 -3
- data/ext/ratatui_ruby/src/widgets/canvas.rs +5 -5
- data/ext/ratatui_ruby/src/widgets/table.rs +81 -36
- data/lib/ratatui_ruby/buffer/cell.rb +168 -0
- data/lib/ratatui_ruby/buffer.rb +15 -0
- data/lib/ratatui_ruby/frame.rb +8 -8
- data/lib/ratatui_ruby/layout/constraint.rb +95 -0
- data/lib/ratatui_ruby/layout/layout.rb +106 -0
- data/lib/ratatui_ruby/layout/rect.rb +118 -0
- data/lib/ratatui_ruby/layout.rb +19 -0
- data/lib/ratatui_ruby/list_state.rb +2 -2
- data/lib/ratatui_ruby/schema/layout.rb +1 -1
- data/lib/ratatui_ruby/schema/row.rb +66 -0
- data/lib/ratatui_ruby/schema/table.rb +10 -10
- data/lib/ratatui_ruby/schema/text.rb +27 -2
- data/lib/ratatui_ruby/style/style.rb +81 -0
- data/lib/ratatui_ruby/style.rb +15 -0
- data/lib/ratatui_ruby/table_state.rb +1 -1
- data/lib/ratatui_ruby/test_helper/snapshot.rb +24 -0
- data/lib/ratatui_ruby/test_helper/style_assertions.rb +1 -1
- data/lib/ratatui_ruby/tui/buffer_factories.rb +20 -0
- data/lib/ratatui_ruby/tui/canvas_factories.rb +44 -0
- data/lib/ratatui_ruby/tui/core.rb +38 -0
- data/lib/ratatui_ruby/tui/layout_factories.rb +74 -0
- data/lib/ratatui_ruby/tui/state_factories.rb +33 -0
- data/lib/ratatui_ruby/tui/style_factories.rb +20 -0
- data/lib/ratatui_ruby/tui/text_factories.rb +44 -0
- data/lib/ratatui_ruby/tui/widget_factories.rb +195 -0
- data/lib/ratatui_ruby/tui.rb +75 -0
- data/lib/ratatui_ruby/version.rb +1 -1
- data/lib/ratatui_ruby/widgets/bar_chart/bar.rb +47 -0
- data/lib/ratatui_ruby/widgets/bar_chart/bar_group.rb +25 -0
- data/lib/ratatui_ruby/widgets/bar_chart.rb +239 -0
- data/lib/ratatui_ruby/widgets/block.rb +192 -0
- data/lib/ratatui_ruby/widgets/calendar.rb +84 -0
- data/lib/ratatui_ruby/widgets/canvas.rb +231 -0
- data/lib/ratatui_ruby/widgets/cell.rb +47 -0
- data/lib/ratatui_ruby/widgets/center.rb +59 -0
- data/lib/ratatui_ruby/widgets/chart.rb +185 -0
- data/lib/ratatui_ruby/widgets/clear.rb +54 -0
- data/lib/ratatui_ruby/widgets/cursor.rb +42 -0
- data/lib/ratatui_ruby/widgets/gauge.rb +72 -0
- data/lib/ratatui_ruby/widgets/line_gauge.rb +80 -0
- data/lib/ratatui_ruby/widgets/list.rb +127 -0
- data/lib/ratatui_ruby/widgets/list_item.rb +43 -0
- data/lib/ratatui_ruby/widgets/overlay.rb +43 -0
- data/lib/ratatui_ruby/widgets/paragraph.rb +99 -0
- data/lib/ratatui_ruby/widgets/ratatui_logo.rb +31 -0
- data/lib/ratatui_ruby/widgets/ratatui_mascot.rb +36 -0
- data/lib/ratatui_ruby/widgets/row.rb +68 -0
- data/lib/ratatui_ruby/widgets/scrollbar.rb +143 -0
- data/lib/ratatui_ruby/widgets/shape/label.rb +68 -0
- data/lib/ratatui_ruby/widgets/sparkline.rb +134 -0
- data/lib/ratatui_ruby/widgets/table.rb +141 -0
- data/lib/ratatui_ruby/widgets/tabs.rb +85 -0
- data/lib/ratatui_ruby/widgets.rb +40 -0
- data/lib/ratatui_ruby.rb +23 -39
- data/sig/examples/app_all_events/view.rbs +1 -1
- data/sig/examples/app_all_events/view_state.rbs +1 -1
- data/sig/ratatui_ruby/schema/row.rbs +22 -0
- data/sig/ratatui_ruby/schema/table.rbs +1 -1
- data/sig/ratatui_ruby/schema/text.rbs +1 -0
- data/sig/ratatui_ruby/session.rbs +29 -49
- data/sig/ratatui_ruby/tui/buffer_factories.rbs +10 -0
- data/sig/ratatui_ruby/tui/canvas_factories.rbs +14 -0
- data/sig/ratatui_ruby/tui/core.rbs +14 -0
- data/sig/ratatui_ruby/tui/layout_factories.rbs +19 -0
- data/sig/ratatui_ruby/tui/state_factories.rbs +12 -0
- data/sig/ratatui_ruby/tui/style_factories.rbs +10 -0
- data/sig/ratatui_ruby/tui/text_factories.rbs +14 -0
- data/sig/ratatui_ruby/tui/widget_factories.rbs +39 -0
- data/sig/ratatui_ruby/tui.rbs +19 -0
- data/tasks/autodoc.rake +1 -35
- data/tasks/sourcehut.rake +4 -1
- metadata +62 -15
- data/doc/contributors/dwim_dx.md +0 -366
- data/doc/contributors/examples_audit/p1_high.md +0 -21
- data/doc/contributors/examples_audit/p2_moderate.md +0 -81
- data/doc/contributors/examples_audit.md +0 -41
- data/doc/images/app_analytics.png +0 -0
- data/doc/images/app_custom_widget.png +0 -0
- data/doc/images/app_mouse_events.png +0 -0
- data/doc/images/widget_table_flex.png +0 -0
- data/lib/ratatui_ruby/session/autodoc.rb +0 -482
- data/lib/ratatui_ruby/session.rb +0 -178
- data/tasks/autodoc/inventory.rb +0 -63
- data/tasks/autodoc/notice.rb +0 -26
- data/tasks/autodoc/rbs.rb +0 -38
- data/tasks/autodoc/rdoc.rb +0 -45
|
@@ -9,7 +9,7 @@ require_relative "model/event_entry"
|
|
|
9
9
|
require_relative "model/timestamp"
|
|
10
10
|
require_relative "model/event_color_cycle"
|
|
11
11
|
|
|
12
|
-
# Pure update function for the
|
|
12
|
+
# Pure update function for the Model-View-Update architecture.
|
|
13
13
|
#
|
|
14
14
|
# Given a Msg and the current AppModel, returns the next AppModel.
|
|
15
15
|
# This function is pure: it does not mutate arguments, draw to the screen,
|
|
@@ -36,7 +36,7 @@ class View::App
|
|
|
36
36
|
# [model] AppModel containing all application data.
|
|
37
37
|
# [tui] RatatuiRuby instance.
|
|
38
38
|
# [frame] RatatuiRuby::Frame being rendered.
|
|
39
|
-
# [area] RatatuiRuby::Rect defining the total available space.
|
|
39
|
+
# [area] RatatuiRuby::Layout::Rect defining the total available space.
|
|
40
40
|
#
|
|
41
41
|
# === Example
|
|
42
42
|
#
|
|
@@ -24,7 +24,7 @@ class View::Controls
|
|
|
24
24
|
# [model] AppModel (unused, included for consistent interface).
|
|
25
25
|
# [tui] RatatuiRuby instance.
|
|
26
26
|
# [frame] RatatuiRuby::Frame being rendered.
|
|
27
|
-
# [area] RatatuiRuby::Rect defining the widget's bounds.
|
|
27
|
+
# [area] RatatuiRuby::Layout::Rect defining the widget's bounds.
|
|
28
28
|
#
|
|
29
29
|
# === Example
|
|
30
30
|
#
|
|
@@ -18,7 +18,7 @@ class View::Counts
|
|
|
18
18
|
# [model] AppModel containing event data.
|
|
19
19
|
# [tui] RatatuiRuby instance.
|
|
20
20
|
# [frame] RatatuiRuby::Frame being rendered.
|
|
21
|
-
# [area] RatatuiRuby::Rect defining the widget's bounds.
|
|
21
|
+
# [area] RatatuiRuby::Layout::Rect defining the widget's bounds.
|
|
22
22
|
def call(model, tui, frame, area)
|
|
23
23
|
dimmed_style = tui.style(fg: :dark_gray)
|
|
24
24
|
lit_style = tui.style(fg: :green, modifiers: [:bold])
|
|
@@ -24,7 +24,7 @@ class View::Live
|
|
|
24
24
|
# [model] AppModel containing event data.
|
|
25
25
|
# [tui] RatatuiRuby instance.
|
|
26
26
|
# [frame] RatatuiRuby::Frame being rendered.
|
|
27
|
-
# [area] RatatuiRuby::Rect defining the widget's bounds.
|
|
27
|
+
# [area] RatatuiRuby::Layout::Rect defining the widget's bounds.
|
|
28
28
|
#
|
|
29
29
|
# === Example
|
|
30
30
|
#
|
|
@@ -19,7 +19,7 @@ class View::Log
|
|
|
19
19
|
# [model] AppModel containing event data.
|
|
20
20
|
# [tui] RatatuiRuby instance.
|
|
21
21
|
# [frame] RatatuiRuby::Frame being rendered.
|
|
22
|
-
# [area] RatatuiRuby::Rect defining the widget's bounds.
|
|
22
|
+
# [area] RatatuiRuby::Layout::Rect defining the widget's bounds.
|
|
23
23
|
def call(model, tui, frame, area)
|
|
24
24
|
dimmed_style = tui.style(fg: :dark_gray)
|
|
25
25
|
border_color = model.focused ? :green : :gray
|
|
@@ -5,6 +5,8 @@ SPDX-License-Identifier: CC-BY-SA-4.0
|
|
|
5
5
|
|
|
6
6
|
# Color Picker Example
|
|
7
7
|
|
|
8
|
+
[](app.rb)
|
|
9
|
+
|
|
8
10
|
This example demonstrates how to build a **Feature-Rich Interactive Application** using `ratatui_ruby`.
|
|
9
11
|
|
|
10
12
|
It goes beyond simple widgets to show a complete, real-world architecture for handling:
|
|
@@ -13,7 +15,7 @@ It goes beyond simple widgets to show a complete, real-world architecture for ha
|
|
|
13
15
|
- **Dynamic Layouts**
|
|
14
16
|
- **Modal Dialogs**
|
|
15
17
|
|
|
16
|
-
## Architecture:
|
|
18
|
+
## Architecture: Component-Based
|
|
17
19
|
|
|
18
20
|
This app uses a **Strict Component-Based Architecture** where every UI element encapsulates its own **Rendering**, **State**, and **Event Handling**.
|
|
19
21
|
|
|
@@ -119,16 +121,16 @@ ruby examples/app_color_picker/app.rb
|
|
|
119
121
|
|
|
120
122
|
Complex applications require structured state habits. This Color Picker and the [App All Events](../app_all_events/README.md) example demonstrate two different approaches.
|
|
121
123
|
|
|
122
|
-
### The Tool Approach (Color Picker
|
|
124
|
+
### The Tool Approach (Color Picker)
|
|
123
125
|
|
|
124
126
|
Tools require interaction. Users click buttons and drag sliders. Components need to know where they exist on screen for hit testing. The Container orchestrates cross-component effects.
|
|
125
127
|
|
|
126
|
-
This example uses
|
|
128
|
+
This example uses a **Component-Based** pattern. Each component owns its own state, rendering, and event handling. The Container routes events and mediates communication.
|
|
127
129
|
|
|
128
130
|
Use this pattern for forms, editors, and mouse-driven tools.
|
|
129
131
|
|
|
130
|
-
### The Dashboard Approach (AppAllEvents
|
|
132
|
+
### The Dashboard Approach (AppAllEvents)
|
|
131
133
|
|
|
132
|
-
Dashboards display data. They rarely require complex mouse interaction.
|
|
134
|
+
Dashboards display data. They rarely require complex mouse interaction. Model-View-Update works best there. State is immutable. Logic is pure. Updates are predictable. This simplifies testing.
|
|
133
135
|
|
|
134
136
|
Use that pattern for logs, monitors, and data viewers.
|
|
@@ -19,7 +19,7 @@ require_relative "main_container"
|
|
|
19
19
|
#
|
|
20
20
|
# === Architecture
|
|
21
21
|
#
|
|
22
|
-
# This example uses
|
|
22
|
+
# This example uses a Component-Based pattern:
|
|
23
23
|
# - **Components**: Self-contained UI elements with `render`, `handle_event`, and optional `tick`
|
|
24
24
|
# - **Container**: Owns layout, delegates to children, routes events via Chain of Responsibility
|
|
25
25
|
# - **Mediator**: Container interprets symbolic signals (`:consumed`, `:submitted`) for cross-component effects
|
|
@@ -5,6 +5,8 @@ SPDX-License-Identifier: CC-BY-SA-4.0
|
|
|
5
5
|
|
|
6
6
|
# Login Form Example
|
|
7
7
|
|
|
8
|
+
[](app.rb)
|
|
9
|
+
|
|
8
10
|
Demonstrates how to create a modal overlay for user input.
|
|
9
11
|
|
|
10
12
|
Many applications need to block interaction with the main UI while collecting specific information, like a login prompt or confirmation dialog. Managing the z-index and input focus for these overlays can be tricky.
|
|
@@ -5,6 +5,8 @@ SPDX-License-Identifier: CC-BY-SA-4.0
|
|
|
5
5
|
|
|
6
6
|
# Stateful Interaction Example
|
|
7
7
|
|
|
8
|
+
[](app.rb)
|
|
9
|
+
|
|
8
10
|
This example demonstrates High-Fidelity Interaction using **Stateful Widget Rendering**.
|
|
9
11
|
|
|
10
12
|
It showcases a "Database Viewer" layout where:
|
|
@@ -161,7 +161,7 @@ class AppStatefulInteraction
|
|
|
161
161
|
borders: [:all],
|
|
162
162
|
border_style: is_active ? @style_active : @style_inactive
|
|
163
163
|
),
|
|
164
|
-
|
|
164
|
+
row_highlight_style: @style_highlight
|
|
165
165
|
)
|
|
166
166
|
|
|
167
167
|
frame.render_stateful_widget(table, area, @table_state)
|
|
@@ -5,14 +5,15 @@ SPDX-License-Identifier: CC-BY-SA-4.0
|
|
|
5
5
|
|
|
6
6
|
# Quickstart DSL Verification
|
|
7
7
|
|
|
8
|
-
Verifies the "
|
|
8
|
+
Verifies the "Simplified API" tutorial in the [Quickstart](../../doc/quickstart.md#simplified-api).
|
|
9
9
|
|
|
10
|
-
This example exists as a documentation regression test. It ensures the recommended
|
|
10
|
+
This example exists as a documentation regression test. It ensures the recommended TUI facade and managed lifecycle workflow remains functional.
|
|
11
11
|
|
|
12
12
|
## Usage
|
|
13
13
|
|
|
14
14
|
<!-- SYNC:START:app.rb:main -->
|
|
15
15
|
```ruby
|
|
16
|
+
# 1. Initialize the terminal, start the run loop, and ensure the terminal is restored.
|
|
16
17
|
RatatuiRuby.run do |tui|
|
|
17
18
|
loop do
|
|
18
19
|
# 2. Create your UI with methods instead of classes.
|
|
@@ -45,4 +46,4 @@ end
|
|
|
45
46
|
```
|
|
46
47
|
<!-- SYNC:END -->
|
|
47
48
|
|
|
48
|
-

|
|
49
|
+
[](../../doc/quickstart.md#simplified-api)
|
|
@@ -9,8 +9,8 @@ require "ratatui_ruby"
|
|
|
9
9
|
|
|
10
10
|
class VerifyQuickstartDsl
|
|
11
11
|
def run
|
|
12
|
-
# 1. Initialize the terminal, start the run loop, and ensure the terminal is restored.
|
|
13
12
|
# [SYNC:START:main]
|
|
13
|
+
# 1. Initialize the terminal, start the run loop, and ensure the terminal is restored.
|
|
14
14
|
RatatuiRuby.run do |tui|
|
|
15
15
|
loop do
|
|
16
16
|
# 2. Create your UI with methods instead of classes.
|
|
@@ -21,10 +21,10 @@ begin
|
|
|
21
21
|
loop do
|
|
22
22
|
# 2. Create your UI (Immediate Mode)
|
|
23
23
|
# We define a Paragraph widget inside a Block with a title and borders.
|
|
24
|
-
view = RatatuiRuby::Paragraph.new(
|
|
24
|
+
view = RatatuiRuby::Widgets::Paragraph.new(
|
|
25
25
|
text: "Hello, Ratatui! Press 'q' to quit.",
|
|
26
26
|
alignment: :center,
|
|
27
|
-
block: RatatuiRuby::Block.new(
|
|
27
|
+
block: RatatuiRuby::Widgets::Block.new(
|
|
28
28
|
title: "My Ruby TUI App",
|
|
29
29
|
title_alignment: :center,
|
|
30
30
|
borders: [:all],
|
|
@@ -53,4 +53,4 @@ end
|
|
|
53
53
|
```
|
|
54
54
|
<!-- SYNC:END -->
|
|
55
55
|
|
|
56
|
-

|
|
56
|
+
[](../../doc/quickstart.md#basic-application)
|
|
@@ -18,10 +18,10 @@ class VerifyQuickstartLifecycle
|
|
|
18
18
|
loop do
|
|
19
19
|
# 2. Create your UI (Immediate Mode)
|
|
20
20
|
# We define a Paragraph widget inside a Block with a title and borders.
|
|
21
|
-
view = RatatuiRuby::Paragraph.new(
|
|
21
|
+
view = RatatuiRuby::Widgets::Paragraph.new(
|
|
22
22
|
text: "Hello, Ratatui! Press 'q' to quit.",
|
|
23
23
|
alignment: :center,
|
|
24
|
-
block: RatatuiRuby::Block.new(
|
|
24
|
+
block: RatatuiRuby::Widgets::Block.new(
|
|
25
25
|
title: "My Ruby TUI App",
|
|
26
26
|
title_alignment: :center,
|
|
27
27
|
borders: [:all],
|
|
@@ -5,6 +5,8 @@ SPDX-License-Identifier: CC-BY-SA-4.0
|
|
|
5
5
|
|
|
6
6
|
# BarChart Widget Example
|
|
7
7
|
|
|
8
|
+
[](app.rb)
|
|
9
|
+
|
|
8
10
|
Visualizes categorical data with interactive attribute cycling.
|
|
9
11
|
|
|
10
12
|
Comparing magnitudes in raw tables requires mental arithmetic. Bar charts make these comparisons instant and intuitive.
|
|
@@ -46,4 +48,3 @@ Use this example if you need to...
|
|
|
46
48
|
- Create "stats" dashboards with compact visualizations.
|
|
47
49
|
- Understand how `RatatuiRuby::BarChart` handles different data structures.
|
|
48
50
|
|
|
49
|
-

|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
-->
|
|
5
5
|
# Block Widget Demo
|
|
6
6
|
|
|
7
|
+
[](app.rb)
|
|
8
|
+
|
|
7
9
|
This example demonstrates the versatile `Block` widget, which provides the visual container, borders, and titles for almost every other widget in `ratatui_ruby`.
|
|
8
10
|
|
|
9
11
|
## Key Concepts
|
|
@@ -5,6 +5,8 @@ SPDX-License-Identifier: CC-BY-SA-4.0
|
|
|
5
5
|
|
|
6
6
|
# Box (Block) Widget Example
|
|
7
7
|
|
|
8
|
+
[](app.rb)
|
|
9
|
+
|
|
8
10
|
Demonstrates visual container attributes with interactive cycling.
|
|
9
11
|
|
|
10
12
|
Widgets often float in a void. Without boundaries, interfaces become a chaotic mess of text. `Block` (often called a Box) provides the structure and visual hierarchy needed to organize information.
|
|
@@ -40,6 +42,4 @@ Use this example if you need to...
|
|
|
40
42
|
- Group related widgets together.
|
|
41
43
|
- Create distinct "panels" or "cards" in your UI.
|
|
42
44
|
- Style borders to indicate state (e.g., Red border for error state).
|
|
43
|
-
- Understand the difference between `style` (content) and `border_style` (frame).
|
|
44
|
-
|
|
45
|
-

|
|
45
|
+
- Understand the difference between `style` (content) and `border_style` (frame).
|
|
@@ -5,6 +5,8 @@ SPDX-License-Identifier: CC-BY-SA-4.0
|
|
|
5
5
|
|
|
6
6
|
# Calendar Widget Example
|
|
7
7
|
|
|
8
|
+
[](app.rb)
|
|
9
|
+
|
|
8
10
|
Demonstrates a monthly calendar with customizable headers and event highlighting.
|
|
9
11
|
|
|
10
12
|
Rendering dates in a grid involves complex calculations for leap years and weekday offsets. This widget handles that logic, letting you focus on displaying dates.
|
|
@@ -34,6 +36,4 @@ ruby examples/widget_calendar_demo/app.rb
|
|
|
34
36
|
Use this example if you need to...
|
|
35
37
|
- Display a date picker.
|
|
36
38
|
- Show a schedule or timeline view.
|
|
37
|
-
- Highlight specific dates (deadlines, holidays) on a calendar grid.
|
|
38
|
-
|
|
39
|
-

|
|
39
|
+
- Highlight specific dates (deadlines, holidays) on a calendar grid.
|
|
@@ -23,6 +23,10 @@ require "ratatui_ruby"
|
|
|
23
23
|
#
|
|
24
24
|
# rdoc-image:/doc/images/widget_calendar_demo.png
|
|
25
25
|
class WidgetCalendarDemo
|
|
26
|
+
def initialize(date: nil)
|
|
27
|
+
@date = date
|
|
28
|
+
end
|
|
29
|
+
|
|
26
30
|
def run
|
|
27
31
|
RatatuiRuby.run do |tui|
|
|
28
32
|
show_header = true
|
|
@@ -32,7 +36,7 @@ class WidgetCalendarDemo
|
|
|
32
36
|
hotkey_style = tui.style(modifiers: [:bold])
|
|
33
37
|
|
|
34
38
|
loop do
|
|
35
|
-
now = Time.now
|
|
39
|
+
now = @date || Time.now
|
|
36
40
|
surrounding_style = show_surrounding ? tui.style(fg: "gray", modifiers: [:dim]) : nil
|
|
37
41
|
|
|
38
42
|
events_map = if show_events
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
# Canvas Widget Demo
|
|
2
|
+
|
|
3
|
+
[](app.rb)
|
|
4
|
+
|
|
2
5
|
<!--
|
|
3
6
|
SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
4
7
|
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
@@ -19,9 +22,6 @@ This example demonstrates the `Canvas` widget, which provides a high-resolution
|
|
|
19
22
|
| `q` | Quit |
|
|
20
23
|
|
|
21
24
|
## Screenshot
|
|
22
|
-
|
|
23
|
-

|
|
24
|
-
|
|
25
25
|
## Source Code
|
|
26
26
|
|
|
27
27
|
- [app.rb](app.rb)
|
|
@@ -5,6 +5,8 @@ SPDX-License-Identifier: CC-BY-SA-4.0
|
|
|
5
5
|
|
|
6
6
|
# Cell Widget Example
|
|
7
7
|
|
|
8
|
+
[](app.rb)
|
|
9
|
+
|
|
8
10
|
Demonstrates using `Cell` objects for granular control over individual character grid units.
|
|
9
11
|
|
|
10
12
|
Sometimes you need to render specific characters with unique styles outside of standard widgets. The `Cell` primitive allows you to build custom widgets or inject styled content into Tables.
|
|
@@ -31,6 +33,4 @@ ruby examples/widget_cell_demo/app.rb
|
|
|
31
33
|
Use this example if you need to...
|
|
32
34
|
- Create a custom widget (like a game board or specialized graph).
|
|
33
35
|
- Style specific cells in a Table (e.g., Green "OK", Red "FAIL").
|
|
34
|
-
- Understand how to position content precisely with `Cell`.
|
|
35
|
-
|
|
36
|
-

|
|
36
|
+
- Understand how to position content precisely with `Cell`.
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
# Center Widget Demo
|
|
2
|
+
|
|
3
|
+
[](app.rb)
|
|
4
|
+
|
|
2
5
|
<!--
|
|
3
6
|
SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
4
7
|
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
@@ -21,9 +24,6 @@ This example demonstrates the `Center` widget, which positions a child widget in
|
|
|
21
24
|
| `q` | Quit |
|
|
22
25
|
|
|
23
26
|
## Screenshot
|
|
24
|
-
|
|
25
|
-

|
|
26
|
-
|
|
27
27
|
## Source Code
|
|
28
28
|
|
|
29
29
|
- [app.rb](app.rb)
|
|
@@ -5,6 +5,8 @@ SPDX-License-Identifier: CC-BY-SA-4.0
|
|
|
5
5
|
|
|
6
6
|
# Chart Widget Example
|
|
7
7
|
|
|
8
|
+
[](app.rb)
|
|
9
|
+
|
|
8
10
|
Demonstrates Cartesian plotting with interactive styling and configuration.
|
|
9
11
|
|
|
10
12
|
Trends and patterns are invisible in raw logs. Charts visualize X/Y datasets to reveal the story behind the data.
|
|
@@ -36,6 +38,4 @@ ruby examples/widget_chart_demo/app.rb
|
|
|
36
38
|
Use this example if you need to...
|
|
37
39
|
- Plot real-time data monitoring (CPU history, request latency).
|
|
38
40
|
- Visualize mathematical functions.
|
|
39
|
-
- Compare multiple datasets on the same axis.
|
|
40
|
-
|
|
41
|
-

|
|
41
|
+
- Compare multiple datasets on the same axis.
|
|
@@ -5,6 +5,8 @@ SPDX-License-Identifier: CC-BY-SA-4.0
|
|
|
5
5
|
|
|
6
6
|
# Gauge Widget Example
|
|
7
7
|
|
|
8
|
+
[](app.rb)
|
|
9
|
+
|
|
8
10
|
Demonstrates progress bars with interactive configuration.
|
|
9
11
|
|
|
10
12
|
Long-running tasks create anxiety. Users need to know the system is working. Gauges provide visual feedback on completion status.
|
|
@@ -36,6 +38,4 @@ ruby examples/widget_gauge_demo/app.rb
|
|
|
36
38
|
Use this example if you need to...
|
|
37
39
|
- Show download or upload progress.
|
|
38
40
|
- Visualize resource quotas (disk space, memory usage).
|
|
39
|
-
- Create "health bars" or status indicators.
|
|
40
|
-
|
|
41
|
-

|
|
41
|
+
- Create "health bars" or status indicators.
|
|
@@ -5,6 +5,8 @@ SPDX-License-Identifier: CC-BY-SA-4.0
|
|
|
5
5
|
|
|
6
6
|
# Layout Split Example
|
|
7
7
|
|
|
8
|
+
[](app.rb)
|
|
9
|
+
|
|
8
10
|
Demonstrates dynamic geometry management with constraints and flex modes.
|
|
9
11
|
|
|
10
12
|
Terminal screens vary in size. Hardcoded layouts break. `Layout.split` manages space dynamically, ensuring your interface adapts to any window dimension.
|
|
@@ -39,6 +41,4 @@ Use this example if you need to...
|
|
|
39
41
|
- Build responsive dashboards.
|
|
40
42
|
- Create 3-column layouts where the middle content fills remaining space.
|
|
41
43
|
- Center a modal dialog on the screen.
|
|
42
|
-
- Distribute buttons evenly across a control bar.
|
|
43
|
-
|
|
44
|
-

|
|
44
|
+
- Distribute buttons evenly across a control bar.
|
|
@@ -5,6 +5,8 @@ SPDX-License-Identifier: CC-BY-SA-4.0
|
|
|
5
5
|
|
|
6
6
|
# Line Gauge Widget Example
|
|
7
7
|
|
|
8
|
+
[](app.rb)
|
|
9
|
+
|
|
8
10
|
Demonstrates compact progress bars for constrained spaces.
|
|
9
11
|
|
|
10
12
|
Standard block gauges take up vertical space. Sometimes you only have one line to show status. The `LineGauge` provides a compact, high-density progress indicator.
|
|
@@ -36,6 +38,4 @@ ruby examples/widget_line_gauge_demo/app.rb
|
|
|
36
38
|
Use this example if you need to...
|
|
37
39
|
- Add a progress bar to a list item or table row.
|
|
38
40
|
- Create a status line at the bottom of the screen.
|
|
39
|
-
- Show multiple metrics (CPU, RAM, Net) in a compact list.
|
|
40
|
-
|
|
41
|
-

|
|
41
|
+
- Show multiple metrics (CPU, RAM, Net) in a compact list.
|
|
@@ -5,6 +5,8 @@ SPDX-License-Identifier: CC-BY-SA-4.0
|
|
|
5
5
|
|
|
6
6
|
# List Widget Example
|
|
7
7
|
|
|
8
|
+
[](app.rb)
|
|
9
|
+
|
|
8
10
|
Demonstrates a selectable list with extensive configuration options.
|
|
9
11
|
|
|
10
12
|
Lists are the workhorse of terminal interfaces. Managing selection state, scrolling windows, and highlight styles logic is complex. The `List` widget handles all of this.
|
|
@@ -44,6 +46,4 @@ Use this example if you need to...
|
|
|
44
46
|
- Create a file explorer.
|
|
45
47
|
- Build a navigation menu.
|
|
46
48
|
- Display a log where users can scroll back to read history.
|
|
47
|
-
- Implement "infinite select" behaviors.
|
|
48
|
-
|
|
49
|
-

|
|
49
|
+
- Implement "infinite select" behaviors.
|
|
@@ -5,6 +5,8 @@ SPDX-License-Identifier: CC-BY-SA-4.0
|
|
|
5
5
|
|
|
6
6
|
# Canvas Widget Example
|
|
7
7
|
|
|
8
|
+
[](app.rb)
|
|
9
|
+
|
|
8
10
|
Demonstrates drawing custom graphics and maps using the standard Braille and Block patterns.
|
|
9
11
|
|
|
10
12
|
Standard widgets are great for text, but sometimes you need to draw. The `Canvas` widget gives you a high-resolution coordinate system (x, y) to render shapes, lines, and data visualizations that go beyond the grid.
|
|
@@ -34,6 +36,4 @@ ruby examples/widget_map_demo/app.rb
|
|
|
34
36
|
Use this example if you need to...
|
|
35
37
|
- Render geographic data (World, USA, Europe).
|
|
36
38
|
- Overlay custom labels and markers on a map.
|
|
37
|
-
- Animate visual elements on top of a static background.
|
|
38
|
-
|
|
39
|
-

|
|
39
|
+
- Animate visual elements on top of a static background.
|
|
@@ -8,14 +8,14 @@ require "ratatui_ruby"
|
|
|
8
8
|
|
|
9
9
|
# An example of the Canvas widget showing a world map and animated shapes.
|
|
10
10
|
class WidgetMapDemo
|
|
11
|
-
include RatatuiRuby
|
|
11
|
+
include RatatuiRuby::Widgets
|
|
12
12
|
|
|
13
13
|
COLORS = [:black, :blue, :white, nil].freeze
|
|
14
14
|
MARKERS = [:braille, :half_block, :dot, :block, :bar, :quadrant, :sextant, :octant].freeze
|
|
15
15
|
|
|
16
16
|
# Returns a Canvas view for the map demo with the given circle radius.
|
|
17
17
|
#
|
|
18
|
-
# +tui+:: The RatatuiRuby::
|
|
18
|
+
# +tui+:: The RatatuiRuby::TUI instance.
|
|
19
19
|
# +radius+:: The radius of the animated circle.
|
|
20
20
|
# +marker+:: The marker type.
|
|
21
21
|
# +background_color+:: The background color of the canvas.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
3
|
+
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
4
|
+
-->
|
|
5
|
+
# Overlay Widget Demo
|
|
6
|
+
|
|
7
|
+
[](app.rb)
|
|
8
|
+
|
|
9
|
+
This example demonstrates the `Overlay` composition pattern for layering widgets with depth. Modals, notifications, and floating panels all require stacking widgets on top of each other.
|
|
10
|
+
|
|
11
|
+
## Key Concepts
|
|
12
|
+
|
|
13
|
+
- **Layer Composition:** Rendering widgets in order creates visual depth — later renders appear "on top."
|
|
14
|
+
- **Clear Widget:** Using `tui.clear` before rendering a modal erases the background, preventing content bleed-through.
|
|
15
|
+
- **Dynamic Layer Control:** Toggle the number of visible overlay layers at runtime.
|
|
16
|
+
- **Layer Ordering:** Swap which overlay appears in front to demonstrate z-ordering.
|
|
17
|
+
|
|
18
|
+
## Hotkeys
|
|
19
|
+
|
|
20
|
+
- `0`/`1`/`2`: Set number of visible overlay layers
|
|
21
|
+
- `space`: Swap overlay order (which modal is on top)
|
|
22
|
+
- `c`: Toggle Clear widget (on/off)
|
|
23
|
+
- `q`: Quit
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
ruby examples/widget_overlay_demo/app.rb
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Learning Outcomes
|
|
32
|
+
|
|
33
|
+
Use this example if you need to...
|
|
34
|
+
- Build modal dialogs or confirmation popups.
|
|
35
|
+
- Layer notifications over existing content.
|
|
36
|
+
- Understand the Clear widget's role in opaque overlays.
|
|
@@ -5,6 +5,8 @@ SPDX-License-Identifier: CC-BY-SA-4.0
|
|
|
5
5
|
|
|
6
6
|
# Popup (Clear) Widget Example
|
|
7
7
|
|
|
8
|
+
[](app.rb)
|
|
9
|
+
|
|
8
10
|
Demonstrates how to render opaque overlays on top of content.
|
|
9
11
|
|
|
10
12
|
Terminal renders are additive. If you draw a new widget over an old one, the background colors might mix if not handled correctly. The `Clear` widget resets the area to default (usually transparent/black) to ensure a clean canvas for popups.
|
|
@@ -31,6 +33,4 @@ ruby examples/widget_popup_demo/app.rb
|
|
|
31
33
|
Use this example if you need to...
|
|
32
34
|
- Create a modal dialog (Confirm, Alert, Form).
|
|
33
35
|
- Implement a dropdown menu that overlays other content.
|
|
34
|
-
- Fix visual artifacts where old text shows through new widgets.
|
|
35
|
-
|
|
36
|
-

|
|
36
|
+
- Fix visual artifacts where old text shows through new widgets.
|
|
@@ -5,6 +5,8 @@ SPDX-License-Identifier: CC-BY-SA-4.0
|
|
|
5
5
|
|
|
6
6
|
# Ratatui Logo Example
|
|
7
7
|
|
|
8
|
+
[](app.rb)
|
|
9
|
+
|
|
8
10
|
Demonstrates branding with the official logo widget.
|
|
9
11
|
|
|
10
12
|
A polished application often needs an "About" screen or a splash screen. This widget provides the standardized project branding.
|
|
@@ -29,6 +31,4 @@ ruby examples/widget_ratatui_logo_demo/app.rb
|
|
|
29
31
|
Use this example if you need to...
|
|
30
32
|
- Create a splash screen.
|
|
31
33
|
- Add an "About" modal to your application.
|
|
32
|
-
- See how to center a widget both vertically and horizontally.
|
|
33
|
-
|
|
34
|
-

|
|
34
|
+
- See how to center a widget both vertically and horizontally.
|
|
@@ -5,6 +5,8 @@ SPDX-License-Identifier: CC-BY-SA-4.0
|
|
|
5
5
|
|
|
6
6
|
# Ratatui Mascot Example
|
|
7
7
|
|
|
8
|
+
[](app.rb)
|
|
9
|
+
|
|
8
10
|
Demonstrates the project mascot widget for adding personality.
|
|
9
11
|
|
|
10
12
|
Interfaces can feel clinical. A friendly mascot adds charm and brand identity to your terminal application.
|
|
@@ -29,6 +31,4 @@ ruby examples/widget_ratatui_mascot_demo/app.rb
|
|
|
29
31
|
|
|
30
32
|
Use this example if you need to...
|
|
31
33
|
- Add visual flair to your UI.
|
|
32
|
-
- Create a friendly empty state or success screen.
|
|
33
|
-
|
|
34
|
-

|
|
34
|
+
- Create a friendly empty state or success screen.
|
|
@@ -5,6 +5,8 @@ SPDX-License-Identifier: CC-BY-SA-4.0
|
|
|
5
5
|
|
|
6
6
|
# Rect (Geometry) Widget Example
|
|
7
7
|
|
|
8
|
+
[](app.rb)
|
|
9
|
+
|
|
8
10
|
Demonstrates the Rect geometry primitive and hit-testing patterns.
|
|
9
11
|
|
|
10
12
|
TUI layouts are composed of rectangles. Understanding how to manipulate `Rect` objects, reuse them from the layout phase, and use them for mouse interaction is critical for building interactive apps.
|
|
@@ -33,6 +35,4 @@ ruby examples/widget_rect/app.rb
|
|
|
33
35
|
Use this example if you need to...
|
|
34
36
|
- Handle mouse clicks on specific buttons or areas.
|
|
35
37
|
- Create resizable panes (like a split pane in an IDE).
|
|
36
|
-
- Debug layout issues by inspecting Rect coordinates.
|
|
37
|
-
|
|
38
|
-

|
|
38
|
+
- Debug layout issues by inspecting Rect coordinates.
|
|
@@ -5,6 +5,8 @@ SPDX-License-Identifier: CC-BY-SA-4.0
|
|
|
5
5
|
|
|
6
6
|
# Render (Custom Widget) Example
|
|
7
7
|
|
|
8
|
+
[](app.rb)
|
|
9
|
+
|
|
8
10
|
Demonstrates how to build Custom Widgets using absolute coordinates.
|
|
9
11
|
|
|
10
12
|
Sometimes standard widgets aren't enough. You need to draw custom shapes, games, or graphs. This example shows how to implement the `render(area)` contract to draw anything you want while respecting layout boundaries.
|
|
@@ -32,6 +34,4 @@ ruby examples/widget_render/app.rb
|
|
|
32
34
|
Use this example if you need to...
|
|
33
35
|
- Build a game (Snake, Tetris) inside the terminal.
|
|
34
36
|
- Create a specialized visualization (Network topology graph).
|
|
35
|
-
- Draw custom UI elements not provided by the library.
|
|
36
|
-
|
|
37
|
-

|
|
37
|
+
- Draw custom UI elements not provided by the library.
|
|
@@ -21,7 +21,7 @@ class DiagonalWidget
|
|
|
21
21
|
area.x + i,
|
|
22
22
|
area.y + i,
|
|
23
23
|
"\\",
|
|
24
|
-
RatatuiRuby::Style.new(fg: :red, modifiers: [:bold])
|
|
24
|
+
RatatuiRuby::Style::Style.new(fg: :red, modifiers: [:bold])
|
|
25
25
|
)
|
|
26
26
|
end
|
|
27
27
|
end
|
|
@@ -47,7 +47,7 @@ class CheckerboardWidget
|
|
|
47
47
|
area.x + col,
|
|
48
48
|
area.y + row,
|
|
49
49
|
@char,
|
|
50
|
-
RatatuiRuby::Style.new(fg: :cyan)
|
|
50
|
+
RatatuiRuby::Style::Style.new(fg: :cyan)
|
|
51
51
|
)
|
|
52
52
|
end
|
|
53
53
|
end
|
|
@@ -63,7 +63,7 @@ end
|
|
|
63
63
|
class BorderWidget
|
|
64
64
|
def render(area)
|
|
65
65
|
result = []
|
|
66
|
-
style = RatatuiRuby::Style.new(fg: :green)
|
|
66
|
+
style = RatatuiRuby::Style::Style.new(fg: :green)
|
|
67
67
|
|
|
68
68
|
# Top and bottom
|
|
69
69
|
(0...area.width).each do |x| # rubocop:disable Lint/AmbiguousRange
|