ratatui_ruby 0.4.0 → 0.6.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 +98 -176
- data/CHANGELOG.md +80 -6
- data/README.md +19 -7
- data/REUSE.toml +15 -0
- data/doc/application_architecture.md +179 -45
- data/doc/application_testing.md +80 -32
- data/doc/contributors/design/ruby_frontend.md +48 -8
- data/doc/contributors/design/rust_backend.md +1 -0
- data/doc/contributors/developing_examples.md +191 -48
- data/doc/contributors/documentation_style.md +7 -0
- data/doc/contributors/examples_audit/p1_high.md +21 -0
- data/doc/contributors/examples_audit/p2_moderate.md +81 -0
- data/doc/contributors/examples_audit.md +41 -0
- data/doc/contributors/index.md +2 -0
- data/doc/event_handling.md +21 -7
- data/doc/images/app_all_events.png +0 -0
- data/doc/images/app_color_picker.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_demo.png +0 -0
- data/doc/images/widget_block_demo.png +0 -0
- data/doc/images/widget_box_demo.png +0 -0
- data/doc/images/widget_calendar_demo.png +0 -0
- data/doc/images/widget_canvas_demo.png +0 -0
- data/doc/images/widget_cell_demo.png +0 -0
- data/doc/images/widget_center_demo.png +0 -0
- data/doc/images/widget_chart_demo.png +0 -0
- data/doc/images/widget_gauge_demo.png +0 -0
- data/doc/images/widget_layout_split.png +0 -0
- data/doc/images/widget_line_gauge_demo.png +0 -0
- data/doc/images/widget_list_demo.png +0 -0
- data/doc/images/widget_overlay_demo.png +0 -0
- data/doc/images/widget_ratatui_logo_demo.png +0 -0
- data/doc/images/widget_ratatui_mascot_demo.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_demo.png +0 -0
- data/doc/images/widget_sparkline_demo.png +0 -0
- data/doc/images/widget_style_colors.png +0 -0
- data/doc/images/widget_table_demo.png +0 -0
- data/doc/images/widget_table_flex.png +0 -0
- data/doc/images/widget_tabs_demo.png +0 -0
- data/doc/images/widget_text_width.png +0 -0
- data/doc/interactive_design.md +25 -30
- data/doc/quickstart.md +150 -130
- data/doc/terminal_limitations.md +92 -0
- data/examples/app_all_events/README.md +99 -0
- data/examples/app_all_events/app.rb +96 -0
- data/examples/app_all_events/model/app_model.rb +157 -0
- data/examples/app_all_events/model/event_color_cycle.rb +41 -0
- data/examples/app_all_events/model/event_entry.rb +92 -0
- data/examples/app_all_events/model/msg.rb +37 -0
- data/examples/app_all_events/model/timestamp.rb +54 -0
- data/examples/app_all_events/update.rb +73 -0
- data/examples/app_all_events/view/app_view.rb +78 -0
- data/examples/app_all_events/view/controls_view.rb +52 -0
- data/examples/app_all_events/view/counts_view.rb +59 -0
- data/examples/app_all_events/view/live_view.rb +70 -0
- data/examples/app_all_events/view/log_view.rb +55 -0
- data/examples/app_all_events/view.rb +7 -0
- data/examples/app_color_picker/README.md +134 -0
- data/examples/app_color_picker/app.rb +74 -0
- data/examples/app_color_picker/clipboard.rb +84 -0
- data/examples/app_color_picker/color.rb +191 -0
- data/examples/app_color_picker/controls.rb +90 -0
- data/examples/app_color_picker/copy_dialog.rb +166 -0
- data/examples/app_color_picker/export_pane.rb +126 -0
- data/examples/app_color_picker/harmony.rb +56 -0
- data/examples/app_color_picker/input.rb +174 -0
- data/examples/app_color_picker/main_container.rb +178 -0
- data/examples/app_color_picker/palette.rb +109 -0
- data/examples/app_login_form/README.md +47 -0
- data/examples/{login_form → app_login_form}/app.rb +38 -42
- data/examples/app_stateful_interaction/README.md +31 -0
- data/examples/app_stateful_interaction/app.rb +272 -0
- data/examples/timeout_demo.rb +43 -0
- data/examples/verify_quickstart_dsl/README.md +48 -0
- data/examples/{quickstart_dsl → verify_quickstart_dsl}/app.rb +17 -6
- data/examples/verify_quickstart_layout/README.md +71 -0
- data/examples/verify_quickstart_layout/app.rb +71 -0
- data/examples/verify_quickstart_lifecycle/README.md +56 -0
- data/examples/verify_quickstart_lifecycle/app.rb +54 -0
- data/examples/verify_readme_usage/README.md +43 -0
- data/examples/verify_readme_usage/app.rb +40 -0
- data/examples/widget_barchart_demo/README.md +49 -0
- data/examples/widget_barchart_demo/app.rb +238 -0
- data/examples/widget_block_demo/README.md +34 -0
- data/examples/widget_block_demo/app.rb +256 -0
- data/examples/widget_box_demo/README.md +45 -0
- data/examples/{box_demo → widget_box_demo}/app.rb +99 -65
- data/examples/widget_calendar_demo/README.md +39 -0
- data/examples/widget_calendar_demo/app.rb +109 -0
- data/examples/widget_canvas_demo/README.md +27 -0
- data/examples/widget_canvas_demo/app.rb +123 -0
- data/examples/widget_cell_demo/README.md +36 -0
- data/examples/widget_cell_demo/app.rb +111 -0
- data/examples/widget_center_demo/README.md +29 -0
- data/examples/widget_center_demo/app.rb +116 -0
- data/examples/widget_chart_demo/README.md +41 -0
- data/examples/widget_chart_demo/app.rb +218 -0
- data/examples/widget_gauge_demo/README.md +41 -0
- data/examples/widget_gauge_demo/app.rb +212 -0
- data/examples/widget_layout_split/README.md +44 -0
- data/examples/widget_layout_split/app.rb +246 -0
- data/examples/widget_line_gauge_demo/README.md +41 -0
- data/examples/widget_line_gauge_demo/app.rb +217 -0
- data/examples/widget_list_demo/README.md +49 -0
- data/examples/widget_list_demo/app.rb +366 -0
- data/examples/widget_map_demo/README.md +39 -0
- data/examples/{map_demo → widget_map_demo}/app.rb +24 -21
- data/examples/widget_overlay_demo/app.rb +248 -0
- data/examples/widget_popup_demo/README.md +36 -0
- data/examples/widget_popup_demo/app.rb +104 -0
- data/examples/widget_ratatui_logo_demo/README.md +34 -0
- data/examples/widget_ratatui_logo_demo/app.rb +103 -0
- data/examples/widget_ratatui_mascot_demo/README.md +34 -0
- data/examples/widget_ratatui_mascot_demo/app.rb +93 -0
- data/examples/widget_rect/README.md +38 -0
- data/examples/widget_rect/app.rb +205 -0
- data/examples/widget_render/README.md +37 -0
- data/examples/widget_render/app.rb +184 -0
- data/examples/widget_rich_text/README.md +35 -0
- data/examples/widget_rich_text/app.rb +166 -0
- data/examples/widget_scroll_text/README.md +37 -0
- data/examples/widget_scroll_text/app.rb +107 -0
- data/examples/widget_scrollbar_demo/README.md +37 -0
- data/examples/widget_scrollbar_demo/app.rb +153 -0
- data/examples/widget_sparkline_demo/README.md +42 -0
- data/examples/widget_sparkline_demo/app.rb +275 -0
- data/examples/widget_style_colors/README.md +34 -0
- data/examples/widget_style_colors/app.rb +19 -21
- data/examples/widget_table_demo/README.md +48 -0
- data/examples/widget_table_demo/app.rb +239 -0
- data/examples/widget_tabs_demo/README.md +41 -0
- data/examples/widget_tabs_demo/app.rb +181 -0
- data/examples/widget_text_width/README.md +35 -0
- data/examples/widget_text_width/app.rb +106 -0
- data/ext/ratatui_ruby/Cargo.lock +11 -4
- data/ext/ratatui_ruby/Cargo.toml +2 -1
- data/ext/ratatui_ruby/src/events.rs +359 -62
- data/ext/ratatui_ruby/src/frame.rs +227 -0
- data/ext/ratatui_ruby/src/lib.rs +110 -27
- data/ext/ratatui_ruby/src/rendering.rs +8 -4
- data/ext/ratatui_ruby/src/string_width.rs +101 -0
- data/ext/ratatui_ruby/src/style.rs +138 -57
- data/ext/ratatui_ruby/src/terminal.rs +42 -22
- data/ext/ratatui_ruby/src/text.rs +14 -7
- data/ext/ratatui_ruby/src/widgets/barchart.rs +74 -54
- data/ext/ratatui_ruby/src/widgets/block.rs +7 -6
- data/ext/ratatui_ruby/src/widgets/canvas.rs +21 -3
- data/ext/ratatui_ruby/src/widgets/chart.rs +20 -10
- data/ext/ratatui_ruby/src/widgets/gauge.rs +9 -2
- data/ext/ratatui_ruby/src/widgets/layout.rs +9 -4
- data/ext/ratatui_ruby/src/widgets/line_gauge.rs +9 -2
- data/ext/ratatui_ruby/src/widgets/list.rs +211 -12
- data/ext/ratatui_ruby/src/widgets/list_state.rs +137 -0
- data/ext/ratatui_ruby/src/widgets/mod.rs +3 -0
- data/ext/ratatui_ruby/src/widgets/overlay.rs +2 -1
- data/ext/ratatui_ruby/src/widgets/paragraph.rs +1 -1
- data/ext/ratatui_ruby/src/widgets/ratatui_logo.rs +19 -8
- data/ext/ratatui_ruby/src/widgets/ratatui_mascot.rs +17 -10
- data/ext/ratatui_ruby/src/widgets/scrollbar.rs +97 -3
- data/ext/ratatui_ruby/src/widgets/scrollbar_state.rs +169 -0
- data/ext/ratatui_ruby/src/widgets/sparkline.rs +14 -11
- data/ext/ratatui_ruby/src/widgets/table.rs +121 -5
- data/ext/ratatui_ruby/src/widgets/table_state.rs +121 -0
- data/ext/ratatui_ruby/src/widgets/tabs.rs +11 -11
- data/lib/ratatui_ruby/cell.rb +7 -7
- data/lib/ratatui_ruby/event/key/character.rb +35 -0
- data/lib/ratatui_ruby/event/key/media.rb +44 -0
- data/lib/ratatui_ruby/event/key/modifier.rb +95 -0
- data/lib/ratatui_ruby/event/key/navigation.rb +55 -0
- data/lib/ratatui_ruby/event/key/system.rb +45 -0
- data/lib/ratatui_ruby/event/key.rb +112 -52
- data/lib/ratatui_ruby/event/mouse.rb +3 -3
- data/lib/ratatui_ruby/event/none.rb +43 -0
- data/lib/ratatui_ruby/event/paste.rb +1 -1
- data/lib/ratatui_ruby/event.rb +56 -4
- data/lib/ratatui_ruby/frame.rb +183 -0
- data/lib/ratatui_ruby/list_state.rb +88 -0
- data/lib/ratatui_ruby/schema/bar_chart/bar.rb +13 -13
- data/lib/ratatui_ruby/schema/bar_chart/bar_group.rb +1 -5
- data/lib/ratatui_ruby/schema/bar_chart.rb +217 -217
- data/lib/ratatui_ruby/schema/block.rb +163 -168
- data/lib/ratatui_ruby/schema/calendar.rb +66 -67
- data/lib/ratatui_ruby/schema/canvas.rb +63 -63
- data/lib/ratatui_ruby/schema/center.rb +46 -46
- data/lib/ratatui_ruby/schema/chart.rb +135 -143
- data/lib/ratatui_ruby/schema/clear.rb +42 -42
- data/lib/ratatui_ruby/schema/constraint.rb +76 -76
- data/lib/ratatui_ruby/schema/cursor.rb +30 -25
- data/lib/ratatui_ruby/schema/gauge.rb +54 -52
- data/lib/ratatui_ruby/schema/layout.rb +87 -87
- data/lib/ratatui_ruby/schema/line_gauge.rb +62 -62
- data/lib/ratatui_ruby/schema/list.rb +103 -80
- data/lib/ratatui_ruby/schema/list_item.rb +41 -0
- data/lib/ratatui_ruby/schema/overlay.rb +31 -31
- data/lib/ratatui_ruby/schema/paragraph.rb +80 -80
- data/lib/ratatui_ruby/schema/ratatui_logo.rb +10 -6
- data/lib/ratatui_ruby/schema/ratatui_mascot.rb +10 -5
- data/lib/ratatui_ruby/schema/rect.rb +99 -56
- data/lib/ratatui_ruby/schema/scrollbar.rb +119 -119
- data/lib/ratatui_ruby/schema/shape/label.rb +1 -1
- data/lib/ratatui_ruby/schema/sparkline.rb +111 -110
- data/lib/ratatui_ruby/schema/style.rb +66 -46
- data/lib/ratatui_ruby/schema/table.rb +126 -115
- data/lib/ratatui_ruby/schema/tabs.rb +66 -67
- data/lib/ratatui_ruby/schema/text.rb +69 -1
- data/lib/ratatui_ruby/scrollbar_state.rb +112 -0
- data/lib/ratatui_ruby/session/autodoc.rb +482 -0
- data/lib/ratatui_ruby/session.rb +55 -23
- data/lib/ratatui_ruby/table_state.rb +90 -0
- data/lib/ratatui_ruby/test_helper/event_injection.rb +169 -0
- data/lib/ratatui_ruby/test_helper/snapshot.rb +390 -0
- data/lib/ratatui_ruby/test_helper/style_assertions.rb +351 -0
- data/lib/ratatui_ruby/test_helper/terminal.rb +127 -0
- data/lib/ratatui_ruby/test_helper/test_doubles.rb +68 -0
- data/lib/ratatui_ruby/test_helper.rb +66 -193
- data/lib/ratatui_ruby/version.rb +1 -1
- data/lib/ratatui_ruby.rb +100 -51
- data/{examples/sparkline_demo → sig/examples/app_all_events}/app.rbs +3 -2
- data/sig/examples/app_all_events/model/event_entry.rbs +16 -0
- data/sig/examples/app_all_events/model/events.rbs +15 -0
- data/sig/examples/app_all_events/model/timestamp.rbs +11 -0
- data/sig/examples/app_all_events/view/app_view.rbs +8 -0
- data/sig/examples/app_all_events/view/controls_view.rbs +6 -0
- data/sig/examples/app_all_events/view/counts_view.rbs +6 -0
- data/sig/examples/app_all_events/view/live_view.rbs +6 -0
- data/sig/examples/app_all_events/view/log_view.rbs +6 -0
- data/sig/examples/app_all_events/view.rbs +8 -0
- data/sig/examples/app_all_events/view_state.rbs +15 -0
- data/{examples/list_demo → sig/examples/app_color_picker}/app.rbs +2 -2
- data/sig/examples/app_login_form/app.rbs +11 -0
- data/sig/examples/app_stateful_interaction/app.rbs +33 -0
- data/sig/examples/verify_quickstart_dsl/app.rbs +11 -0
- data/sig/examples/verify_quickstart_lifecycle/app.rbs +11 -0
- data/sig/examples/verify_readme_usage/app.rbs +11 -0
- data/sig/examples/widget_block_demo/app.rbs +32 -0
- data/sig/examples/widget_box_demo/app.rbs +11 -0
- data/sig/examples/widget_calendar_demo/app.rbs +11 -0
- data/sig/examples/widget_cell_demo/app.rbs +11 -0
- data/sig/examples/widget_chart_demo/app.rbs +11 -0
- data/{examples/gauge_demo → sig/examples/widget_gauge_demo}/app.rbs +4 -0
- data/sig/examples/widget_layout_split/app.rbs +10 -0
- data/sig/examples/widget_line_gauge_demo/app.rbs +11 -0
- data/sig/examples/widget_list_demo/app.rbs +12 -0
- data/sig/examples/widget_map_demo/app.rbs +11 -0
- data/sig/examples/widget_popup_demo/app.rbs +11 -0
- data/sig/examples/widget_ratatui_logo_demo/app.rbs +11 -0
- data/sig/examples/widget_ratatui_mascot_demo/app.rbs +11 -0
- data/sig/examples/widget_rect/app.rbs +12 -0
- data/sig/examples/widget_render/app.rbs +10 -0
- data/sig/examples/widget_rich_text/app.rbs +11 -0
- data/sig/examples/widget_scroll_text/app.rbs +11 -0
- data/sig/examples/widget_scrollbar_demo/app.rbs +11 -0
- data/sig/examples/widget_sparkline_demo/app.rbs +10 -0
- data/{examples → sig/examples}/widget_style_colors/app.rbs +1 -1
- data/sig/examples/widget_table_demo/app.rbs +11 -0
- data/sig/examples/widget_text_width/app.rbs +10 -0
- data/sig/ratatui_ruby/event.rbs +11 -1
- data/sig/ratatui_ruby/frame.rbs +11 -0
- data/sig/ratatui_ruby/list_state.rbs +13 -0
- data/sig/ratatui_ruby/ratatui_ruby.rbs +5 -4
- data/sig/ratatui_ruby/schema/bar_chart/bar.rbs +3 -3
- data/sig/ratatui_ruby/schema/draw.rbs +4 -0
- data/sig/ratatui_ruby/schema/gauge.rbs +2 -2
- data/sig/ratatui_ruby/schema/layout.rbs +1 -1
- data/sig/ratatui_ruby/schema/line_gauge.rbs +2 -2
- data/sig/ratatui_ruby/schema/list.rbs +4 -2
- data/sig/ratatui_ruby/schema/list_item.rbs +10 -0
- data/sig/ratatui_ruby/schema/rect.rbs +3 -0
- data/sig/ratatui_ruby/schema/style.rbs +3 -3
- data/sig/ratatui_ruby/schema/table.rbs +3 -1
- data/sig/ratatui_ruby/schema/text.rbs +8 -6
- data/sig/ratatui_ruby/scrollbar_state.rbs +18 -0
- data/sig/ratatui_ruby/session.rbs +107 -0
- data/sig/ratatui_ruby/table_state.rbs +15 -0
- data/sig/ratatui_ruby/test_helper/event_injection.rbs +16 -0
- data/sig/ratatui_ruby/test_helper/snapshot.rbs +12 -0
- data/sig/ratatui_ruby/test_helper/style_assertions.rbs +64 -0
- data/sig/ratatui_ruby/test_helper/terminal.rbs +14 -0
- data/sig/ratatui_ruby/test_helper/test_doubles.rbs +22 -0
- data/sig/ratatui_ruby/test_helper.rbs +5 -4
- data/tasks/autodoc/examples.rb +79 -0
- data/tasks/autodoc/inventory.rb +63 -0
- data/tasks/autodoc/member.rb +56 -0
- data/tasks/autodoc/name.rb +19 -0
- data/tasks/autodoc/notice.rb +26 -0
- data/tasks/autodoc/rbs.rb +38 -0
- data/tasks/autodoc/rdoc.rb +45 -0
- data/tasks/autodoc.rake +53 -0
- data/tasks/bump/changelog.rb +3 -3
- data/tasks/bump/history.rb +2 -2
- data/tasks/bump/links.rb +67 -0
- data/tasks/doc.rake +600 -6
- data/tasks/example_viewer.html.erb +172 -0
- data/tasks/lint.rake +8 -4
- data/tasks/resources/index.html.erb +6 -0
- data/tasks/sourcehut.rake +70 -30
- data/tasks/terminal_preview/app_screenshot.rb +14 -6
- data/tasks/terminal_preview/crash_report.rb +7 -9
- data/tasks/terminal_preview/launcher_script.rb +4 -6
- data/tasks/terminal_preview/preview_collection.rb +4 -6
- data/tasks/terminal_preview/safety_confirmation.rb +3 -5
- data/tasks/terminal_preview/saved_screenshot.rb +10 -11
- data/tasks/terminal_preview/terminal_window.rb +7 -9
- data/tasks/test.rake +1 -1
- data/tasks/website/index_page.rb +3 -3
- data/tasks/website/version.rb +10 -10
- data/tasks/website/version_menu.rb +10 -12
- data/tasks/website/versioned_documentation.rb +49 -17
- data/tasks/website/website.rb +6 -8
- data/tasks/website.rake +4 -4
- metadata +232 -127
- data/LICENSES/BSD-2-Clause.txt +0 -9
- data/doc/contributors/better_dx.md +0 -543
- data/doc/contributors/example_analysis.md +0 -82
- data/doc/images/all_events.png +0 -0
- data/doc/images/block_padding.png +0 -0
- data/doc/images/block_titles.png +0 -0
- data/doc/images/box_demo.png +0 -0
- data/doc/images/calendar_demo.png +0 -0
- data/doc/images/cell_demo.png +0 -0
- data/doc/images/chart_demo.png +0 -0
- data/doc/images/flex_layout.png +0 -0
- data/doc/images/gauge_demo.png +0 -0
- data/doc/images/line_gauge_demo.png +0 -0
- data/doc/images/list_demo.png +0 -0
- data/doc/images/list_styles.png +0 -0
- data/doc/images/login_form.png +0 -0
- data/doc/images/quickstart_dsl.png +0 -0
- data/doc/images/quickstart_lifecycle.png +0 -0
- data/doc/images/readme_usage.png +0 -0
- data/doc/images/rich_text.png +0 -0
- data/doc/images/scroll_text.png +0 -0
- data/doc/images/scrollbar_demo.png +0 -0
- data/doc/images/sparkline_demo.png +0 -0
- data/doc/images/table_flex.png +0 -0
- data/doc/images/table_select.png +0 -0
- data/examples/all_events/app.rb +0 -169
- data/examples/all_events/app.rbs +0 -7
- data/examples/all_events/test_app.rb +0 -139
- data/examples/analytics/app.rb +0 -258
- data/examples/analytics/app.rbs +0 -7
- data/examples/analytics/test_app.rb +0 -132
- data/examples/block_padding/app.rb +0 -63
- data/examples/block_padding/app.rbs +0 -7
- data/examples/block_padding/test_app.rb +0 -31
- data/examples/block_titles/app.rb +0 -61
- data/examples/block_titles/app.rbs +0 -7
- data/examples/block_titles/test_app.rb +0 -34
- data/examples/box_demo/app.rbs +0 -7
- data/examples/box_demo/test_app.rb +0 -88
- data/examples/calendar_demo/app.rb +0 -101
- data/examples/calendar_demo/app.rbs +0 -7
- data/examples/calendar_demo/test_app.rb +0 -108
- data/examples/cell_demo/app.rb +0 -108
- data/examples/cell_demo/app.rbs +0 -7
- data/examples/cell_demo/test_app.rb +0 -36
- data/examples/chart_demo/app.rb +0 -203
- data/examples/chart_demo/app.rbs +0 -7
- data/examples/chart_demo/test_app.rb +0 -102
- data/examples/custom_widget/app.rb +0 -51
- data/examples/custom_widget/app.rbs +0 -7
- data/examples/custom_widget/test_app.rb +0 -30
- data/examples/flex_layout/app.rb +0 -156
- data/examples/flex_layout/app.rbs +0 -7
- data/examples/flex_layout/test_app.rb +0 -65
- data/examples/gauge_demo/app.rb +0 -182
- data/examples/gauge_demo/test_app.rb +0 -120
- data/examples/hit_test/app.rb +0 -175
- data/examples/hit_test/app.rbs +0 -7
- data/examples/hit_test/test_app.rb +0 -102
- data/examples/line_gauge_demo/app.rb +0 -190
- data/examples/line_gauge_demo/app.rbs +0 -7
- data/examples/line_gauge_demo/test_app.rb +0 -129
- data/examples/list_demo/app.rb +0 -253
- data/examples/list_demo/test_app.rb +0 -237
- data/examples/list_styles/app.rb +0 -140
- data/examples/list_styles/app.rbs +0 -7
- data/examples/list_styles/test_app.rb +0 -157
- data/examples/login_form/app.rbs +0 -7
- data/examples/login_form/test_app.rb +0 -51
- data/examples/map_demo/app.rbs +0 -7
- data/examples/map_demo/test_app.rb +0 -149
- data/examples/mouse_events/app.rb +0 -97
- data/examples/mouse_events/app.rbs +0 -7
- data/examples/mouse_events/test_app.rb +0 -53
- data/examples/popup_demo/app.rb +0 -103
- data/examples/popup_demo/app.rbs +0 -7
- data/examples/popup_demo/test_app.rb +0 -54
- data/examples/quickstart_dsl/app.rbs +0 -7
- data/examples/quickstart_dsl/test_app.rb +0 -29
- data/examples/quickstart_lifecycle/app.rb +0 -39
- data/examples/quickstart_lifecycle/app.rbs +0 -7
- data/examples/quickstart_lifecycle/test_app.rb +0 -29
- data/examples/ratatui_logo_demo/app.rb +0 -79
- data/examples/ratatui_logo_demo/app.rbs +0 -7
- data/examples/ratatui_logo_demo/test_app.rb +0 -51
- data/examples/ratatui_mascot_demo/app.rb +0 -84
- data/examples/ratatui_mascot_demo/app.rbs +0 -7
- data/examples/ratatui_mascot_demo/test_app.rb +0 -47
- data/examples/readme_usage/app.rb +0 -29
- data/examples/readme_usage/app.rbs +0 -7
- data/examples/readme_usage/test_app.rb +0 -29
- data/examples/rich_text/app.rb +0 -141
- data/examples/rich_text/app.rbs +0 -7
- data/examples/rich_text/test_app.rb +0 -166
- data/examples/scroll_text/app.rb +0 -103
- data/examples/scroll_text/app.rbs +0 -7
- data/examples/scroll_text/test_app.rb +0 -110
- data/examples/scrollbar_demo/app.rb +0 -143
- data/examples/scrollbar_demo/app.rbs +0 -7
- data/examples/scrollbar_demo/test_app.rb +0 -77
- data/examples/sparkline_demo/app.rb +0 -240
- data/examples/sparkline_demo/test_app.rb +0 -107
- data/examples/table_flex/app.rb +0 -65
- data/examples/table_flex/app.rbs +0 -7
- data/examples/table_flex/test_app.rb +0 -36
- data/examples/table_select/app.rb +0 -198
- data/examples/table_select/app.rbs +0 -7
- data/examples/table_select/test_app.rb +0 -180
- data/examples/widget_style_colors/test_app.rb +0 -48
- data/tasks/bump/comparison_links.rb +0 -41
- /data/doc/images/{analytics.png → app_analytics.png} +0 -0
- /data/doc/images/{custom_widget.png → app_custom_widget.png} +0 -0
- /data/doc/images/{mouse_events.png → app_mouse_events.png} +0 -0
- /data/doc/images/{map_demo.png → widget_map_demo.png} +0 -0
- /data/doc/images/{popup_demo.png → widget_popup_demo.png} +0 -0
- /data/doc/images/{hit_test.png → widget_rect.png} +0 -0
- /data/{doc/images/ratatui_logo_demo.png → exe/.gitkeep} +0 -0
data/doc/interactive_design.md
CHANGED
|
@@ -21,10 +21,13 @@ Structure your event loop into three clear phases:
|
|
|
21
21
|
|
|
22
22
|
```ruby
|
|
23
23
|
def run
|
|
24
|
-
RatatuiRuby.run do
|
|
24
|
+
RatatuiRuby.run do |tui|
|
|
25
|
+
@tui = tui
|
|
25
26
|
loop do
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
@tui.draw do |frame|
|
|
28
|
+
calculate_layout(frame.area) # Phase 1: Geometry (once per frame)
|
|
29
|
+
render(frame) # Phase 2: Draw
|
|
30
|
+
end
|
|
28
31
|
break if handle_input == :quit # Phase 3: Input
|
|
29
32
|
end
|
|
30
33
|
end
|
|
@@ -33,29 +36,27 @@ end
|
|
|
33
36
|
|
|
34
37
|
**Phase 1: Layout Calculation**
|
|
35
38
|
|
|
36
|
-
Call this
|
|
39
|
+
Call this inside your `draw` block. It uses the current terminal area provided by the frame:
|
|
37
40
|
|
|
38
41
|
```ruby
|
|
39
|
-
def calculate_layout
|
|
40
|
-
full_area = RatatuiRuby::Rect.new(x: 0, y: 0, width: 80, height: 24)
|
|
41
|
-
|
|
42
|
+
def calculate_layout(area)
|
|
42
43
|
# Main area vs sidebar (70% / 30%)
|
|
43
|
-
main_area, @sidebar_area =
|
|
44
|
-
|
|
44
|
+
main_area, @sidebar_area = @tui.layout_split(
|
|
45
|
+
area,
|
|
45
46
|
direction: :horizontal,
|
|
46
47
|
constraints: [
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
@tui.constraint_percentage(70),
|
|
49
|
+
@tui.constraint_percentage(30),
|
|
49
50
|
]
|
|
50
51
|
)
|
|
51
52
|
|
|
52
53
|
# Within main area, left vs right panels
|
|
53
|
-
@left_rect, @right_rect =
|
|
54
|
+
@left_rect, @right_rect = @tui.layout_split(
|
|
54
55
|
main_area,
|
|
55
56
|
direction: :horizontal,
|
|
56
57
|
constraints: [
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
@tui.constraint_percentage(@left_ratio),
|
|
59
|
+
@tui.constraint_percentage(100 - @left_ratio)
|
|
59
60
|
]
|
|
60
61
|
)
|
|
61
62
|
end
|
|
@@ -66,10 +67,9 @@ end
|
|
|
66
67
|
Reuse the cached rects. Build and draw:
|
|
67
68
|
|
|
68
69
|
```ruby
|
|
69
|
-
def render
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
# ... draw ...
|
|
70
|
+
def render(frame)
|
|
71
|
+
frame.render_widget(build_widget(@left_rect), @left_rect)
|
|
72
|
+
frame.render_widget(build_widget(@right_rect), @right_rect)
|
|
73
73
|
end
|
|
74
74
|
```
|
|
75
75
|
|
|
@@ -80,7 +80,6 @@ Reuse the cached rects. Test clicks:
|
|
|
80
80
|
```ruby
|
|
81
81
|
def handle_input
|
|
82
82
|
event = RatatuiRuby.poll_event
|
|
83
|
-
return unless event
|
|
84
83
|
|
|
85
84
|
case event
|
|
86
85
|
in type: :mouse, kind: "down", x:, y:
|
|
@@ -104,18 +103,14 @@ end
|
|
|
104
103
|
|
|
105
104
|
## Layout.split
|
|
106
105
|
|
|
107
|
-
`Layout.split` computes layout geometry without rendering. It returns an array of `Rect` objects.
|
|
106
|
+
`Layout.split` computes layout geometry without rendering. It returns an array of `Rect` objects. While you can call `RatatuiRuby::Layout.split` directly, we recommend using the `Session` helper (`tui.layout_split`) for cleaner application code.
|
|
108
107
|
|
|
109
108
|
```ruby
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
left, right = rects
|
|
117
|
-
# left is a Rect describing the left 70% of the area
|
|
118
|
-
# right is a Rect describing the right 30% of the area
|
|
109
|
+
# Preferred (Session API)
|
|
110
|
+
left, right = tui.layout_split(area, constraints: [...])
|
|
111
|
+
|
|
112
|
+
# Manual (Core API)
|
|
113
|
+
left, right = RatatuiRuby::Layout.split(area, constraints: [...])
|
|
119
114
|
```
|
|
120
115
|
|
|
121
|
-
Use it to establish the single source of truth
|
|
116
|
+
Use it to establish the single source of truth inside your `draw` block. Store the results in instance variables and reuse them in both `render` and `handle_input`.
|
data/doc/quickstart.md
CHANGED
|
@@ -29,22 +29,22 @@ gem install ratatui_ruby
|
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
##
|
|
32
|
+
## Tutorials
|
|
33
|
+
|
|
34
|
+
### Basic Application
|
|
33
35
|
|
|
34
36
|
Here is a "Hello World" application that demonstrates the core lifecycle of a **ratatui_ruby** app.
|
|
35
37
|
|
|
38
|
+
<!-- SYNC:START:../examples/verify_quickstart_lifecycle/app.rb:main -->
|
|
36
39
|
```ruby
|
|
37
|
-
require "ratatui_ruby"
|
|
38
|
-
|
|
39
40
|
# 1. Initialize the terminal
|
|
40
41
|
RatatuiRuby.init_terminal
|
|
41
|
-
|
|
42
|
+
|
|
42
43
|
begin
|
|
43
44
|
# The Main Loop
|
|
44
45
|
loop do
|
|
45
46
|
# 2. Create your UI (Immediate Mode)
|
|
46
47
|
# We define a Paragraph widget inside a Block with a title and borders.
|
|
47
|
-
# Other widgets include RatatuiRuby::RatatuiMascot, RatatuiRuby::RatatuiLogo, etc.
|
|
48
48
|
view = RatatuiRuby::Paragraph.new(
|
|
49
49
|
text: "Hello, Ratatui! Press 'q' to quit.",
|
|
50
50
|
alignment: :center,
|
|
@@ -56,38 +56,43 @@ begin
|
|
|
56
56
|
style: { fg: "white" }
|
|
57
57
|
)
|
|
58
58
|
)
|
|
59
|
-
|
|
59
|
+
|
|
60
60
|
# 3. Draw the UI
|
|
61
|
-
RatatuiRuby.draw
|
|
62
|
-
|
|
61
|
+
RatatuiRuby.draw do |frame|
|
|
62
|
+
frame.render_widget(view, frame.area)
|
|
63
|
+
end
|
|
64
|
+
|
|
63
65
|
# 4. Poll for events
|
|
64
|
-
|
|
65
|
-
|
|
66
|
+
case RatatuiRuby.poll_event
|
|
67
|
+
in { type: :key, code: "q" } | { type: :key, code: "c", modifiers: ["ctrl"] }
|
|
68
|
+
break
|
|
69
|
+
else
|
|
70
|
+
nil
|
|
71
|
+
end
|
|
66
72
|
end
|
|
67
73
|
ensure
|
|
68
74
|
# 5. Restore the terminal to its original state
|
|
69
75
|
RatatuiRuby.restore_terminal
|
|
70
76
|
end
|
|
71
77
|
```
|
|
78
|
+
<!-- SYNC:END -->
|
|
72
79
|
|
|
73
|
-

|
|
74
81
|
|
|
75
|
-
|
|
82
|
+
#### How it works
|
|
76
83
|
|
|
77
84
|
1. **`RatatuiRuby.init_terminal`**: Enters raw mode and switches to the alternate screen.
|
|
78
|
-
2. **Immediate Mode UI**: On every iteration
|
|
79
|
-
3. **`RatatuiRuby.draw
|
|
80
|
-
4. **`RatatuiRuby.poll_event`**:
|
|
81
|
-
5. **`RatatuiRuby.restore_terminal`**:
|
|
85
|
+
2. **Immediate Mode UI**: On every iteration, describe your UI by creating `Data` objects (e.g., `Paragraph`, `Block`).
|
|
86
|
+
3. **`RatatuiRuby.draw { |frame| ... }`**: The block receives a `Frame` object as a canvas. Render widgets onto specific areas. Nothing is drawn until the block finishes, ensuring flicker-free updates.
|
|
87
|
+
4. **`RatatuiRuby.poll_event`**: Returns a typed `Event` object with predicates like `key?`, `mouse?`, `resize?`, etc. Returns `RatatuiRuby::Event::None` if no events are pending. Use predicates to check event type without pattern matching.
|
|
88
|
+
5. **`RatatuiRuby.restore_terminal`**: Essential for leaving raw mode and returning to the shell. Always wrap your loop in `begin...ensure` to guarantee this runs.
|
|
82
89
|
|
|
83
90
|
### Idiomatic Session
|
|
84
91
|
|
|
85
92
|
You can simplify your code by using `RatatuiRuby.run`. This method handles the terminal lifecycle for you, yielding a `Session` object with factory methods for widgets.
|
|
86
93
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
# 1. Initialize the terminal and ensure it is restored.
|
|
94
|
+
<!-- SYNC:START:../examples/verify_quickstart_dsl/app.rb:main -->
|
|
95
|
+
```ruby
|
|
91
96
|
RatatuiRuby.run do |tui|
|
|
92
97
|
loop do
|
|
93
98
|
# 2. Create your UI with methods instead of classes.
|
|
@@ -104,168 +109,183 @@ RatatuiRuby.run do |tui|
|
|
|
104
109
|
)
|
|
105
110
|
|
|
106
111
|
# 3. Use RatatuiRuby methods, too.
|
|
107
|
-
tui.draw
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
112
|
+
tui.draw do |frame|
|
|
113
|
+
frame.render_widget(view, frame.area)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# 4. Poll for events with pattern matching
|
|
117
|
+
case tui.poll_event
|
|
118
|
+
in { type: :key, code: "q" }
|
|
119
|
+
break
|
|
120
|
+
else
|
|
121
|
+
# Ignore other events
|
|
122
|
+
end
|
|
111
123
|
end
|
|
112
124
|
end
|
|
113
|
-
|
|
125
|
+
```
|
|
126
|
+
<!-- SYNC:END -->
|
|
114
127
|
|
|
115
128
|
#### How it works
|
|
116
129
|
|
|
117
130
|
1. **`RatatuiRuby.run`**: This context manager initializes the terminal before the block starts and ensures `restore_terminal` is called when the block exits (even if an error occurs).
|
|
118
131
|
2. **Widget Shorthand**: The block yields a `Session` object (here named `tui`). This object provides factory methods for every widget, allowing you to write `tui.paragraph(...)` instead of the more verbose `RatatuiRuby::Paragraph.new(...)`.
|
|
119
|
-
3. **Method Shorthand**: The session object also provides aliases for module functions of `RatatuiRuby`, allowing you to write `tui.draw(...)` instead of the more verbose `RatatuiRuby
|
|
132
|
+
3. **Method Shorthand**: The session object also provides aliases for module functions of `RatatuiRuby`, allowing you to write `tui.draw(...)` instead of the more verbose `RatatuiRuby.draw(...)`.
|
|
133
|
+
4. **Pattern Matching for Events**: Use `case...in` with pattern matching for elegant event dispatch. Always include an `else` clause at the end to catch unmatched event types (mouse, resize, paste, focus, etc.), otherwise Ruby raises `NoMatchingPatternError`.
|
|
120
134
|
|
|
121
135
|
For a deeper dive into the available application architectures (Manual vs Managed), see [Application Architecture](./application_architecture.md).
|
|
122
136
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
To see more complex layouts and widget usage, check out the `examples/` directory in the repository.
|
|
137
|
+
### Adding Layouts
|
|
126
138
|
|
|
127
|
-
|
|
139
|
+
Real-world applications often need to split the screen into multiple areas. `RatatuiRuby::Layout` lets you do this easily.
|
|
128
140
|
|
|
129
|
-
|
|
141
|
+
<!-- SYNC:START:../examples/verify_quickstart_layout/app.rb:main -->
|
|
142
|
+
```ruby
|
|
143
|
+
loop do
|
|
144
|
+
tui.draw do |frame|
|
|
145
|
+
# 1. Split the screen
|
|
146
|
+
top, bottom = tui.layout_split(
|
|
147
|
+
frame.area,
|
|
148
|
+
direction: :vertical,
|
|
149
|
+
constraints: [
|
|
150
|
+
tui.constraint_percentage(75),
|
|
151
|
+
tui.constraint_percentage(25),
|
|
152
|
+
]
|
|
153
|
+
)
|
|
130
154
|
|
|
131
|
-
|
|
155
|
+
# 2. Render Top Widget
|
|
156
|
+
frame.render_widget(
|
|
157
|
+
tui.paragraph(
|
|
158
|
+
text: "Hello, Ratatui!",
|
|
159
|
+
alignment: :center,
|
|
160
|
+
block: tui.block(title: "Content", borders: [:all], border_color: "cyan")
|
|
161
|
+
),
|
|
162
|
+
top
|
|
163
|
+
)
|
|
132
164
|
|
|
133
|
-
|
|
165
|
+
# 3. Render Bottom Widget with Styled Text
|
|
166
|
+
# We use a Line of Spans to style specific characters
|
|
167
|
+
text_line = tui.text_line(
|
|
168
|
+
spans: [
|
|
169
|
+
tui.text_span(content: "Press '"),
|
|
170
|
+
tui.text_span(
|
|
171
|
+
content: "q",
|
|
172
|
+
style: tui.style(modifiers: [:bold, :underlined])
|
|
173
|
+
),
|
|
174
|
+
tui.text_span(content: "' to quit."),
|
|
175
|
+
],
|
|
176
|
+
alignment: :center
|
|
177
|
+
)
|
|
134
178
|
|
|
135
|
-
|
|
179
|
+
frame.render_widget(
|
|
180
|
+
tui.paragraph(
|
|
181
|
+
text: text_line,
|
|
182
|
+
block: tui.block(title: "Controls", borders: [:all])
|
|
183
|
+
),
|
|
184
|
+
bottom
|
|
185
|
+
)
|
|
186
|
+
end
|
|
136
187
|
|
|
137
|
-
|
|
188
|
+
case tui.poll_event
|
|
189
|
+
in { type: :key, code: "q" }
|
|
190
|
+
break
|
|
191
|
+
else
|
|
192
|
+
# Ignore other events
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
```
|
|
196
|
+
<!-- SYNC:END -->
|
|
138
197
|
|
|
139
|
-
|
|
198
|
+
#### How it works
|
|
140
199
|
|
|
141
|
-
|
|
200
|
+
1. **`tui.layout_split` (`RatatuiRuby::Layout.split`)**: Takes an area (like `frame.area`) and splits it into multiple sub-areas based on constraints.
|
|
201
|
+
2. **`tui.constraint_*` (`RatatuiRuby::Constraint`)**: Defines how space is distributed (e.g., `percentage`, `length`, `min`, `max`).
|
|
202
|
+
3. **`Frame#render_widget(widget, rect)`**: You pass the specific area (like `top` or `bottom`) to render the widget into that exact region.
|
|
203
|
+
4. **`tui.text_span` (`RatatuiRuby::Text::Span`)**: Allows for rich styling within a single line of text.
|
|
142
204
|
|
|
143
|
-
|
|
205
|
+
## Examples
|
|
144
206
|
|
|
145
|
-
|
|
207
|
+
These examples showcase the full power of **ratatui_ruby**. You can find their source code in the [examples directory](../examples).
|
|
146
208
|
|
|
147
|
-
|
|
209
|
+
### Sample Applications
|
|
148
210
|
|
|
149
|
-
|
|
211
|
+
Full-featured examples demonstrating complex layouts and real-world TUI patterns.
|
|
150
212
|
|
|
151
|
-
### [Box Demo](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/box_demo/app.rb)
|
|
152
213
|
|
|
153
|
-
A simple demonstration of `Block` and `Paragraph` widgets, reacting to key presses to change colors, border types, border styles, and title styling. Features the new `border_style` parameter for applying colors and modifiers (bold, italic) to borders independently of the content background.
|
|
154
214
|
|
|
155
|
-
|
|
215
|
+
#### [All Events](../examples/app_all_events/app.rb)
|
|
156
216
|
|
|
157
|
-
|
|
217
|
+
Handling terminal events is unpredictable. Developers need to know exactly what the terminal sends for `Ctrl+C` or a mouse drag.
|
|
158
218
|
|
|
159
|
-
|
|
219
|
+
This app captures and visualizes every event—keys, mouse, resize, paste, and focus.
|
|
160
220
|
|
|
161
|
-
|
|
221
|
+
Use it to debug your input handling or verify terminal behavior.
|
|
162
222
|
|
|
163
|
-
|
|
223
|
+
**What you'll learn:**
|
|
164
224
|
|
|
165
|
-
|
|
225
|
+
* **Proto-TEA Architecture**: Implements unidirectional data flow (Model-View-Update) with immutable state and pure functions.
|
|
226
|
+
* **Event Handling**: Captures and distinguishes all input types, including modifiers (`Ctrl+C`) and focus changes.
|
|
227
|
+
* **Scalable Structure**: Organizes a non-trivial application into small, focused classes instead of a monolithic script.
|
|
166
228
|
|
|
167
|
-

|
|
168
230
|
|
|
169
|
-
|
|
231
|
+
#### [Color Picker](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/app_color_picker/app.rb)
|
|
170
232
|
|
|
171
|
-
|
|
233
|
+
Interactive tools require complex state. Mapping mouse clicks to widgets and handling modal dialogs creates messy code if handled in the main loop.
|
|
172
234
|
|
|
173
|
-
|
|
235
|
+
This app implements a full Color Picker using a "Proto-Kit (Component-Based)" pattern. Each component encapsulates its own rendering, state, and event handling.
|
|
174
236
|
|
|
175
|
-
|
|
237
|
+
Use it to build forms, editors, and mouse-driven tools.
|
|
176
238
|
|
|
177
|
-
|
|
239
|
+
**What you'll learn:**
|
|
178
240
|
|
|
179
|
-
|
|
241
|
+
* **Proto-Kit Architecture**: Self-contained components with `render(tui, frame, area)` and `handle_event(event)`.
|
|
242
|
+
* **Encapsulated Hit Testing**: Components cache their render area and check `contains?` internally.
|
|
243
|
+
* **Modal Dialogs**: Implements overlay patterns that intercept input via Chain of Responsibility.
|
|
180
244
|
|
|
181
|
-
|
|
245
|
+
#### [Custom Widget (Escape Hatch)](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/app_custom_widget/app.rb)
|
|
182
246
|
|
|
183
|
-
Demonstrates
|
|
247
|
+
Demonstrates how to define a custom widget in pure Ruby using the `render(area, buffer)` escape hatch for low-level drawing.
|
|
184
248
|
|
|
185
|
-

|
|
186
250
|
|
|
187
|
-
|
|
251
|
+
#### [Layout Split Demo](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/widget_layout_split/app.rb)
|
|
188
252
|
|
|
189
|
-
Demonstrates
|
|
253
|
+
Demonstrates `Layout.split` with interactive attribute cycling. Features hotkey controls For direction (vertical/horizontal), all 7 flex modes (legacy, start, center, end, space_between, space_around, space_evenly), and constraint types (fill, length, percentage, min, ratio).
|
|
190
254
|
|
|
191
|
-

|
|
192
256
|
|
|
193
|
-
|
|
257
|
+
#### [Login Form](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/app_login_form/app.rb)
|
|
194
258
|
|
|
195
259
|
Shows how to use `Overlay`, `Center`, and `Cursor` to build a modal login form with text input.
|
|
196
260
|
|
|
197
|
-

|
|
200
|
-
|
|
201
|
-
Exhibits the `Canvas` widget's power, rendering a world map with city labels, animated circles, and lines.
|
|
202
|
-
|
|
203
|
-

|
|
204
|
-
|
|
205
|
-
### [Mouse Events](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/mouse_events/app.rb)
|
|
206
|
-
|
|
207
|
-
Detailed plumbing of mouse events, including clicks, drags, and movement tracking.
|
|
208
|
-
|
|
209
|
-

|
|
210
|
-
|
|
211
|
-
### [Popup Demo](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/popup_demo/app.rb)
|
|
212
|
-
|
|
213
|
-
Demonstrates the `Clear` widget and how to prevent "style bleed" when rendering opaque popups over colored backgrounds.
|
|
214
|
-
|
|
215
|
-

|
|
216
|
-
|
|
217
|
-
### [Ratatui Logo Demo](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/ratatui_logo_demo/app.rb)
|
|
218
|
-
|
|
219
|
-
Demonstrates the `RatatuiLogo` widget.
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-

|
|
223
|
-
|
|
224
|
-
### [Rich Text](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/rich_text/app.rb)
|
|
225
|
-
|
|
226
|
-
Demonstrates `Text::Span` and `Text::Line` for creating styled text with inline formatting, enabling word-level control over colors and text modifiers.
|
|
227
|
-
|
|
228
|
-

|
|
229
|
-
|
|
230
|
-
### [Scrollbar Demo](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/scrollbar_demo/app.rb)
|
|
231
|
-
|
|
232
|
-
A demonstration of the `Scrollbar` widget, featuring mouse wheel scrolling and extensive customization of symbols and styles.
|
|
233
|
-
|
|
234
|
-

|
|
235
|
-
|
|
236
|
-
### [Scroll Text](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/scroll_text/app.rb)
|
|
237
|
-
|
|
238
|
-
Demonstrates the `Paragraph` widget's scroll functionality, allowing navigation through long text content using arrow keys for both horizontal and vertical scrolling.
|
|
239
|
-
|
|
240
|
-

|
|
241
|
-
|
|
242
|
-
### [Sparkline Demo](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/sparkline_demo/app.rb)
|
|
243
|
-
|
|
244
|
-
Demonstrates the `Sparkline` widget with interactive attribute cycling. Features multiple data sets with different patterns (steady growth, gaps, random, sawtooth, peaks), and explores all `Sparkline` options including direction, color, the new `absent_value_symbol` and `absent_value_style` parameters for distinguishing zero/absent values from low data, and the new `bar_set` parameter for custom bar characters.
|
|
245
|
-
|
|
246
|
-

|
|
247
|
-
|
|
248
|
-
### [Gauge Demo](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/gauge_demo/app.rb)
|
|
249
|
-
|
|
250
|
-
Demonstrates the `Gauge` widget with interactive attribute cycling. Features multiple gauge instances with customizable ratio, gauge color, background style, Unicode toggle, and label modes. The sidebar provides hotkey documentation for exploring all Gauge options, including the distinction between `style` (background) and `gauge_style` (filled bar).
|
|
251
|
-
|
|
252
|
-

|
|
253
|
-
|
|
254
|
-
### [Table Select](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/table_select/app.rb)
|
|
255
|
-
|
|
256
|
-
Demonstrates interactive row selection in the `Table` widget with keyboard navigation, highlighting selected rows with custom styles and symbols, applying a base style, and dynamically adjusting `column_spacing`. Also demonstrates `column_highlight_style` and the new `cell_highlight_style` for precise selection visualization.
|
|
261
|
+

|
|
257
262
|
|
|
258
|
-

|
|
259
263
|
|
|
260
|
-
### [Table Flex](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/table_flex/app.rb)
|
|
261
264
|
|
|
262
|
-
Demonstrates different flex modes in the `Table` widget, such as `:space_between` and `:space_around`, allowing for modern, responsive table layouts.
|
|
263
265
|
|
|
264
|
-

|
|
265
266
|
|
|
266
|
-
### [Widget Style Colors](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/widget_style_colors/app.rb)
|
|
267
267
|
|
|
268
|
-
|
|
268
|
+
### Widget Demos
|
|
269
269
|
|
|
270
|
-
|
|
270
|
+
These smaller, focused examples demonstrate specific widgets and their configuration options.
|
|
271
271
|
|
|
272
|
+
* [Bar Chart](../examples/widget_barchart_demo/app.rb)
|
|
273
|
+
* [Block (Interactive Demo)](../examples/widget_block_demo/app.rb)
|
|
274
|
+
* [Box (Block/Paragraph)](../examples/widget_box_demo/app.rb)
|
|
275
|
+
* [Calendar](../examples/widget_calendar_demo/app.rb)
|
|
276
|
+
* [Chart](../examples/widget_chart_demo/app.rb)
|
|
277
|
+
* [Gauge](../examples/widget_gauge_demo/app.rb)
|
|
278
|
+
* [Line Gauge](../examples/widget_line_gauge_demo/app.rb)
|
|
279
|
+
* [List](../examples/widget_list_demo/app.rb)
|
|
280
|
+
* [Map (Canvas)](../examples/widget_map_demo/app.rb)
|
|
281
|
+
* [Popup (Clear)](../examples/widget_popup_demo/app.rb)
|
|
282
|
+
* [Rect](../examples/widget_rect/app.rb)
|
|
283
|
+
* [Ratatui Logo](../examples/widget_ratatui_logo_demo/app.rb)
|
|
284
|
+
* [Ratatui Mascot](../examples/widget_ratatui_mascot_demo/app.rb)
|
|
285
|
+
* [Rich Text](../examples/widget_rich_text/app.rb)
|
|
286
|
+
* [Scrollbar](../examples/widget_scrollbar_demo/app.rb)
|
|
287
|
+
* [Scroll Text](../examples/widget_scroll_text/app.rb)
|
|
288
|
+
* [Sparkline](../examples/widget_sparkline_demo/app.rb)
|
|
289
|
+
* [Table (Selection)](../examples/widget_table_demo/app.rb)
|
|
290
|
+
* [Tabs](../examples/widget_tabs_demo/app.rb)
|
|
291
|
+
* [Widget Style Colors](../examples/widget_style_colors/app.rb)
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
3
|
+
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
4
|
+
-->
|
|
5
|
+
|
|
6
|
+
# Terminal Limitations
|
|
7
|
+
|
|
8
|
+
Some behaviors are outside the control of `ratatui_ruby`. This document explains common pitfalls that affect your application or your users, but cannot be fixed in the library.
|
|
9
|
+
|
|
10
|
+
## Keyboard Event Interception
|
|
11
|
+
|
|
12
|
+
### The Problem
|
|
13
|
+
|
|
14
|
+
Your application receives a key event, but the modifier flags are missing. You pressed Ctrl+PageUp, but the event shows `code="page_up"` with `modifiers=[]`.
|
|
15
|
+
|
|
16
|
+
### The Cause
|
|
17
|
+
|
|
18
|
+
Terminal emulators intercept certain key combinations for their own features. The key press never reaches your application—the terminal consumes it first.
|
|
19
|
+
|
|
20
|
+
Common culprits on macOS:
|
|
21
|
+
|
|
22
|
+
| Key Combination | Terminal Behavior |
|
|
23
|
+
|---------------------|--------------------------------------|
|
|
24
|
+
| Ctrl+PageUp/Down | Switch tabs (Terminal.app, iTerm2) |
|
|
25
|
+
| Ctrl+Tab | Switch tabs |
|
|
26
|
+
| Cmd+T / Cmd+N | New tab / New window |
|
|
27
|
+
| Cmd+C / Cmd+V | Copy / Paste (not Ctrl) |
|
|
28
|
+
|
|
29
|
+
Linux terminals vary widely. Windows Terminal and ConEmu have their own defaults.
|
|
30
|
+
|
|
31
|
+
### The Solution
|
|
32
|
+
|
|
33
|
+
1. **Test with different terminals.** Kitty, WezTerm, and Alacritty pass more key combinations through to applications by default. If a key works in Kitty but not Terminal.app, the terminal is the issue.
|
|
34
|
+
|
|
35
|
+
2. **Reconfigure your terminal.** Most terminal emulators let you unbind or remap default shortcuts in their settings.
|
|
36
|
+
|
|
37
|
+
3. **Use alternative key bindings.** If your users will run your application in various terminals, design your keybindings to avoid commonly intercepted combinations:
|
|
38
|
+
- Use Alt+PageUp instead of Ctrl+PageUp
|
|
39
|
+
- Use Ctrl+J/K instead of Ctrl+Up/Down
|
|
40
|
+
- Avoid Ctrl+Tab entirely
|
|
41
|
+
|
|
42
|
+
4. **Document requirements.** If your application depends on specific key combinations, document the terminal requirements for your users.
|
|
43
|
+
|
|
44
|
+
### Enhanced Keyboard Protocol
|
|
45
|
+
|
|
46
|
+
Some terminals support the [Kitty keyboard protocol](https://sw.kovidgoyal.net/kitty/keyboard-protocol/), which provides unambiguous key event reporting including:
|
|
47
|
+
|
|
48
|
+
- Individual modifier key events (LeftShift vs RightShift)
|
|
49
|
+
- Media keys (Play, Pause, Volume controls)
|
|
50
|
+
- Repeat and release events
|
|
51
|
+
|
|
52
|
+
Terminals with full protocol support:
|
|
53
|
+
- Kitty
|
|
54
|
+
- WezTerm
|
|
55
|
+
- Foot
|
|
56
|
+
- Alacritty (partial)
|
|
57
|
+
|
|
58
|
+
Standard terminals (Terminal.app, iTerm2, GNOME Terminal) do not support the enhanced protocol.
|
|
59
|
+
|
|
60
|
+
**RatatuiRuby Status:** The underlying library (crossterm) supports this protocol, but RatatuiRuby does not yet expose a way to enable it. The key code mappings for media keys and individual modifier keys exist, but they will only be received from terminals that enable the protocol by default. This is planned for a future release.
|
|
61
|
+
|
|
62
|
+
## Mouse Event Limitations
|
|
63
|
+
|
|
64
|
+
### The Problem
|
|
65
|
+
|
|
66
|
+
Mouse events work in some terminals but not others. Or they work, but only up to certain coordinates.
|
|
67
|
+
|
|
68
|
+
### The Cause
|
|
69
|
+
|
|
70
|
+
Mouse reporting requires terminal escape sequence support. Older terminals may not support:
|
|
71
|
+
|
|
72
|
+
- SGR mouse mode (coordinates > 223)
|
|
73
|
+
- Mouse motion tracking
|
|
74
|
+
- Button-event tracking
|
|
75
|
+
|
|
76
|
+
### The Solution
|
|
77
|
+
|
|
78
|
+
Ensure your terminal supports modern mouse modes. Most actively maintained terminals do. If running in a legacy environment, test mouse functionality and provide keyboard alternatives.
|
|
79
|
+
|
|
80
|
+
## Focus Events
|
|
81
|
+
|
|
82
|
+
### The Problem
|
|
83
|
+
|
|
84
|
+
`Event::FocusGained` and `Event::FocusLost` are never received.
|
|
85
|
+
|
|
86
|
+
### The Cause
|
|
87
|
+
|
|
88
|
+
Focus event reporting requires explicit terminal support and configuration. Some terminals don't support it at all.
|
|
89
|
+
|
|
90
|
+
### The Solution
|
|
91
|
+
|
|
92
|
+
Don't rely on focus events for critical functionality. Treat them as nice-to-have enhancements. If your application shows stale data when the user returns, periodically refresh instead of waiting for focus events.
|