ratatui_ruby 0.7.1 → 0.7.3
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 +12 -4
- data/CHANGELOG.md +49 -0
- data/README.md +7 -7
- data/Rakefile +1 -1
- data/doc/{application_architecture.md → concepts/application_architecture.md} +30 -0
- data/doc/{application_testing.md → concepts/application_testing.md} +4 -2
- data/doc/{event_handling.md → concepts/event_handling.md} +1 -1
- data/doc/contributors/auditing/parity.md +233 -0
- data/doc/contributors/developing_examples.md +10 -10
- data/doc/contributors/upstream_requests/tab_rects.md +173 -0
- data/doc/contributors/upstream_requests/title_rects.md +132 -0
- data/doc/contributors/v1.0.0_blockers.md +54 -747
- data/doc/{quickstart.md → getting_started/quickstart.md} +26 -26
- data/doc/{why.md → getting_started/why.md} +1 -1
- data/doc/index.md +23 -9
- data/doc/{terminal_limitations.md → troubleshooting/terminal_limitations.md} +33 -0
- data/doc/troubleshooting/tui_output.md +76 -0
- data/examples/app_all_events/README.md +1 -0
- data/examples/app_all_events/app.rb +2 -0
- data/examples/app_all_events/model/app_model.rb +2 -0
- data/examples/app_all_events/model/event_color_cycle.rb +2 -0
- data/examples/app_all_events/model/event_entry.rb +2 -0
- data/examples/app_all_events/model/msg.rb +2 -0
- data/examples/app_all_events/model/timestamp.rb +2 -0
- data/examples/app_all_events/update.rb +2 -0
- data/examples/app_all_events/view/app_view.rb +2 -0
- data/examples/app_all_events/view/controls_view.rb +2 -0
- data/examples/app_all_events/view/counts_view.rb +2 -0
- data/examples/app_all_events/view/live_view.rb +2 -0
- data/examples/app_all_events/view/log_view.rb +2 -0
- data/examples/app_all_events/view.rb +2 -0
- data/examples/app_color_picker/README.md +2 -0
- data/examples/app_color_picker/app.rb +2 -0
- data/examples/app_color_picker/clipboard.rb +2 -0
- data/examples/app_color_picker/color.rb +2 -0
- data/examples/app_color_picker/controls.rb +2 -0
- data/examples/app_color_picker/copy_dialog.rb +2 -0
- data/examples/app_color_picker/export_pane.rb +2 -0
- data/examples/app_color_picker/harmony.rb +2 -0
- data/examples/app_color_picker/input.rb +2 -0
- data/examples/app_color_picker/main_container.rb +2 -0
- data/examples/app_color_picker/palette.rb +2 -0
- data/examples/app_login_form/README.md +3 -0
- data/examples/app_login_form/app.rb +2 -0
- data/examples/app_stateful_interaction/README.md +2 -0
- data/examples/app_stateful_interaction/app.rb +2 -0
- data/examples/timeout_demo.rb +2 -0
- data/examples/verify_quickstart_dsl/README.md +2 -2
- data/examples/verify_quickstart_dsl/app.rb +2 -0
- data/examples/verify_quickstart_layout/README.md +2 -2
- data/examples/verify_quickstart_layout/app.rb +2 -0
- data/examples/verify_quickstart_lifecycle/README.md +2 -2
- data/examples/verify_quickstart_lifecycle/app.rb +2 -0
- data/examples/verify_readme_usage/app.rb +2 -0
- data/examples/{widget_barchart_demo → widget_barchart}/README.md +5 -3
- data/examples/{widget_barchart_demo → widget_barchart}/app.rb +7 -5
- data/examples/{widget_block_demo → widget_block}/README.md +5 -3
- data/examples/{widget_block_demo → widget_block}/app.rb +6 -4
- data/examples/{widget_box_demo → widget_box}/README.md +7 -4
- data/examples/{widget_box_demo → widget_box}/app.rb +7 -5
- data/examples/{widget_calendar_demo → widget_calendar}/README.md +6 -3
- data/examples/{widget_calendar_demo → widget_calendar}/app.rb +6 -4
- data/examples/{widget_canvas_demo → widget_canvas}/README.md +2 -2
- data/examples/{widget_canvas_demo → widget_canvas}/app.rb +6 -4
- data/examples/{widget_cell_demo → widget_cell}/README.md +6 -3
- data/examples/{widget_cell_demo → widget_cell}/app.rb +7 -5
- data/examples/{widget_center_demo → widget_center}/README.md +2 -2
- data/examples/{widget_center_demo → widget_center}/app.rb +6 -4
- data/examples/{widget_chart_demo → widget_chart}/README.md +7 -4
- data/examples/{widget_chart_demo → widget_chart}/app.rb +7 -5
- data/examples/{widget_gauge_demo → widget_gauge}/README.md +6 -3
- data/examples/{widget_gauge_demo → widget_gauge}/app.rb +7 -5
- data/examples/widget_layout_split/README.md +5 -2
- data/examples/widget_layout_split/app.rb +3 -1
- data/examples/{widget_line_gauge_demo → widget_line_gauge}/README.md +6 -3
- data/examples/{widget_line_gauge_demo → widget_line_gauge}/app.rb +7 -5
- data/examples/{widget_list_demo → widget_list}/README.md +7 -4
- data/examples/{widget_list_demo → widget_list}/app.rb +7 -5
- data/examples/{widget_map_demo → widget_map}/README.md +7 -4
- data/examples/{widget_map_demo → widget_map}/app.rb +4 -2
- data/examples/{widget_overlay_demo → widget_overlay}/README.md +6 -3
- data/examples/{widget_overlay_demo → widget_overlay}/app.rb +5 -3
- data/examples/{widget_popup_demo → widget_popup}/README.md +7 -4
- data/examples/{widget_popup_demo → widget_popup}/app.rb +6 -4
- data/examples/{widget_ratatui_logo_demo → widget_ratatui_logo}/README.md +6 -3
- data/examples/{widget_ratatui_logo_demo → widget_ratatui_logo}/app.rb +8 -6
- data/examples/{widget_ratatui_mascot_demo → widget_ratatui_mascot}/README.md +6 -3
- data/examples/{widget_ratatui_mascot_demo → widget_ratatui_mascot}/app.rb +6 -4
- data/examples/widget_rect/README.md +5 -2
- data/examples/widget_rect/app.rb +2 -0
- data/examples/widget_render/README.md +4 -1
- data/examples/widget_render/app.rb +2 -0
- data/examples/widget_rich_text/README.md +4 -1
- data/examples/widget_rich_text/app.rb +2 -0
- data/examples/widget_scroll_text/README.md +4 -1
- data/examples/widget_scroll_text/app.rb +3 -1
- data/examples/{widget_scrollbar_demo → widget_scrollbar}/README.md +7 -4
- data/examples/{widget_scrollbar_demo → widget_scrollbar}/app.rb +6 -4
- data/examples/{widget_sparkline_demo → widget_sparkline}/README.md +6 -3
- data/examples/{widget_sparkline_demo → widget_sparkline}/app.rb +7 -5
- data/examples/widget_style_colors/README.md +4 -1
- data/examples/widget_style_colors/app.rb +2 -0
- data/examples/{widget_table_demo → widget_table}/README.md +7 -4
- data/examples/{widget_table_demo → widget_table}/app.rb +4 -2
- data/examples/{widget_tabs_demo → widget_tabs}/README.md +6 -3
- data/examples/{widget_tabs_demo → widget_tabs}/app.rb +7 -5
- data/examples/widget_text_width/README.md +5 -2
- data/examples/widget_text_width/app.rb +2 -0
- data/exe/.gitkeep +0 -0
- data/ext/ratatui_ruby/Cargo.lock +1 -1
- data/ext/ratatui_ruby/Cargo.toml +1 -1
- data/ext/ratatui_ruby/extconf.rb +2 -0
- data/ext/ratatui_ruby/src/lib.rs +2 -2
- data/ext/ratatui_ruby/src/rendering.rs +9 -0
- data/ext/ratatui_ruby/src/style.rs +22 -2
- data/ext/ratatui_ruby/src/text.rs +26 -0
- data/ext/ratatui_ruby/src/widgets/barchart.rs +8 -6
- data/ext/ratatui_ruby/src/widgets/chart.rs +31 -4
- data/ext/ratatui_ruby/src/widgets/table.rs +13 -5
- data/ext/ratatui_ruby/src/widgets/tabs.rs +49 -9
- data/lib/ratatui_ruby/buffer/cell.rb +2 -0
- data/lib/ratatui_ruby/buffer.rb +2 -0
- data/lib/ratatui_ruby/cell.rb +2 -0
- data/lib/ratatui_ruby/event/focus_gained.rb +2 -0
- data/lib/ratatui_ruby/event/focus_lost.rb +2 -0
- data/lib/ratatui_ruby/event/key/character.rb +2 -0
- data/lib/ratatui_ruby/event/key/media.rb +2 -0
- data/lib/ratatui_ruby/event/key/modifier.rb +2 -0
- data/lib/ratatui_ruby/event/key/navigation.rb +2 -0
- data/lib/ratatui_ruby/event/key/system.rb +2 -0
- data/lib/ratatui_ruby/event/key.rb +2 -0
- data/lib/ratatui_ruby/event/mouse.rb +2 -0
- data/lib/ratatui_ruby/event/none.rb +2 -0
- data/lib/ratatui_ruby/event/paste.rb +2 -0
- data/lib/ratatui_ruby/event/resize.rb +2 -0
- data/lib/ratatui_ruby/event.rb +2 -0
- data/lib/ratatui_ruby/frame.rb +2 -0
- data/lib/ratatui_ruby/layout/constraint.rb +2 -0
- data/lib/ratatui_ruby/layout/layout.rb +2 -0
- data/lib/ratatui_ruby/layout/rect.rb +2 -0
- data/lib/ratatui_ruby/layout.rb +2 -0
- data/lib/ratatui_ruby/list_state.rb +2 -0
- data/lib/ratatui_ruby/schema/bar_chart/bar.rb +2 -0
- data/lib/ratatui_ruby/schema/bar_chart/bar_group.rb +2 -0
- data/lib/ratatui_ruby/schema/bar_chart.rb +4 -2
- data/lib/ratatui_ruby/schema/block.rb +4 -2
- data/lib/ratatui_ruby/schema/calendar.rb +4 -2
- data/lib/ratatui_ruby/schema/canvas.rb +2 -0
- data/lib/ratatui_ruby/schema/center.rb +2 -0
- data/lib/ratatui_ruby/schema/chart.rb +4 -2
- data/lib/ratatui_ruby/schema/clear.rb +2 -0
- data/lib/ratatui_ruby/schema/constraint.rb +2 -0
- data/lib/ratatui_ruby/schema/cursor.rb +2 -0
- data/lib/ratatui_ruby/schema/draw.rb +2 -0
- data/lib/ratatui_ruby/schema/gauge.rb +4 -2
- data/lib/ratatui_ruby/schema/layout.rb +2 -0
- data/lib/ratatui_ruby/schema/line_gauge.rb +4 -2
- data/lib/ratatui_ruby/schema/list.rb +3 -1
- data/lib/ratatui_ruby/schema/list_item.rb +2 -0
- data/lib/ratatui_ruby/schema/overlay.rb +2 -0
- data/lib/ratatui_ruby/schema/paragraph.rb +2 -0
- data/lib/ratatui_ruby/schema/ratatui_logo.rb +4 -2
- data/lib/ratatui_ruby/schema/ratatui_mascot.rb +4 -2
- data/lib/ratatui_ruby/schema/rect.rb +2 -0
- data/lib/ratatui_ruby/schema/row.rb +2 -0
- data/lib/ratatui_ruby/schema/scrollbar.rb +4 -2
- data/lib/ratatui_ruby/schema/shape/label.rb +2 -0
- data/lib/ratatui_ruby/schema/sparkline.rb +4 -2
- data/lib/ratatui_ruby/schema/style.rb +2 -0
- data/lib/ratatui_ruby/schema/table.rb +2 -0
- data/lib/ratatui_ruby/schema/tabs.rb +4 -2
- data/lib/ratatui_ruby/schema/text.rb +2 -0
- data/lib/ratatui_ruby/scrollbar_state.rb +2 -0
- data/lib/ratatui_ruby/style/style.rb +3 -0
- data/lib/ratatui_ruby/style.rb +2 -0
- data/lib/ratatui_ruby/table_state.rb +2 -0
- data/lib/ratatui_ruby/test_helper/event_injection.rb +2 -0
- data/lib/ratatui_ruby/test_helper/snapshot.rb +62 -21
- data/lib/ratatui_ruby/test_helper/snapshots/axis_labels_alignment.ansi +24 -0
- data/lib/ratatui_ruby/test_helper/snapshots/axis_labels_alignment.txt +24 -0
- data/lib/ratatui_ruby/test_helper/snapshots/barchart_styled_label.ansi +5 -0
- data/lib/ratatui_ruby/test_helper/snapshots/barchart_styled_label.txt +5 -0
- data/lib/ratatui_ruby/test_helper/snapshots/chart_rendering.ansi +24 -0
- data/lib/ratatui_ruby/test_helper/snapshots/chart_rendering.txt +24 -0
- data/lib/ratatui_ruby/test_helper/snapshots/half_block_marker.ansi +12 -0
- data/lib/ratatui_ruby/test_helper/snapshots/half_block_marker.txt +12 -0
- data/lib/ratatui_ruby/test_helper/snapshots/legend_position_bottom.ansi +12 -0
- data/lib/ratatui_ruby/test_helper/snapshots/legend_position_bottom.txt +12 -0
- data/lib/ratatui_ruby/test_helper/snapshots/legend_position_left.ansi +12 -0
- data/lib/ratatui_ruby/test_helper/snapshots/legend_position_left.txt +12 -0
- data/lib/ratatui_ruby/test_helper/snapshots/legend_position_right.ansi +12 -0
- data/lib/ratatui_ruby/test_helper/snapshots/legend_position_right.txt +12 -0
- data/lib/ratatui_ruby/test_helper/snapshots/legend_position_top.ansi +12 -0
- data/lib/ratatui_ruby/test_helper/snapshots/legend_position_top.txt +12 -0
- data/lib/ratatui_ruby/test_helper/snapshots/my_snapshot.txt +1 -0
- data/lib/ratatui_ruby/test_helper/snapshots/styled_axis_title.ansi +10 -0
- data/lib/ratatui_ruby/test_helper/snapshots/styled_axis_title.txt +10 -0
- data/lib/ratatui_ruby/test_helper/snapshots/styled_dataset_name.ansi +10 -0
- data/lib/ratatui_ruby/test_helper/snapshots/styled_dataset_name.txt +10 -0
- data/lib/ratatui_ruby/test_helper/style_assertions.rb +2 -0
- data/lib/ratatui_ruby/test_helper/terminal.rb +5 -0
- data/lib/ratatui_ruby/test_helper/test_doubles.rb +2 -0
- data/lib/ratatui_ruby/test_helper.rb +6 -4
- data/lib/ratatui_ruby/tui/buffer_factories.rb +2 -0
- data/lib/ratatui_ruby/tui/canvas_factories.rb +2 -0
- data/lib/ratatui_ruby/tui/core.rb +2 -0
- data/lib/ratatui_ruby/tui/layout_factories.rb +2 -0
- data/lib/ratatui_ruby/tui/state_factories.rb +2 -0
- data/lib/ratatui_ruby/tui/style_factories.rb +2 -0
- data/lib/ratatui_ruby/tui/text_factories.rb +2 -0
- data/lib/ratatui_ruby/tui/widget_factories.rb +2 -0
- data/lib/ratatui_ruby/tui.rb +2 -0
- data/lib/ratatui_ruby/version.rb +3 -1
- data/lib/ratatui_ruby/widgets/bar_chart/bar.rb +2 -0
- data/lib/ratatui_ruby/widgets/bar_chart/bar_group.rb +2 -0
- data/lib/ratatui_ruby/widgets/bar_chart.rb +7 -4
- data/lib/ratatui_ruby/widgets/block.rb +46 -2
- data/lib/ratatui_ruby/widgets/calendar.rb +4 -2
- data/lib/ratatui_ruby/widgets/canvas.rb +2 -0
- data/lib/ratatui_ruby/widgets/cell.rb +2 -0
- data/lib/ratatui_ruby/widgets/center.rb +2 -0
- data/lib/ratatui_ruby/widgets/chart.rb +13 -6
- data/lib/ratatui_ruby/widgets/clear.rb +2 -0
- data/lib/ratatui_ruby/widgets/cursor.rb +2 -0
- data/lib/ratatui_ruby/widgets/gauge.rb +4 -2
- data/lib/ratatui_ruby/widgets/line_gauge.rb +4 -2
- data/lib/ratatui_ruby/widgets/list.rb +3 -1
- data/lib/ratatui_ruby/widgets/list_item.rb +2 -0
- data/lib/ratatui_ruby/widgets/overlay.rb +2 -0
- data/lib/ratatui_ruby/widgets/paragraph.rb +2 -0
- data/lib/ratatui_ruby/widgets/ratatui_logo.rb +4 -2
- data/lib/ratatui_ruby/widgets/ratatui_mascot.rb +4 -2
- data/lib/ratatui_ruby/widgets/row.rb +2 -0
- data/lib/ratatui_ruby/widgets/scrollbar.rb +4 -2
- data/lib/ratatui_ruby/widgets/shape/label.rb +2 -0
- data/lib/ratatui_ruby/widgets/sparkline.rb +7 -4
- data/lib/ratatui_ruby/widgets/table.rb +2 -0
- data/lib/ratatui_ruby/widgets/tabs.rb +12 -8
- data/lib/ratatui_ruby/widgets.rb +2 -0
- data/lib/ratatui_ruby.rb +130 -9
- data/tasks/autodoc/examples.rb +2 -0
- data/tasks/autodoc/member.rb +2 -0
- data/tasks/autodoc/name.rb +2 -0
- data/tasks/autodoc.rake +2 -0
- data/tasks/bump/cargo_lockfile.rb +2 -0
- data/tasks/bump/changelog.rb +2 -0
- data/tasks/bump/header.rb +2 -0
- data/tasks/bump/history.rb +2 -0
- data/tasks/bump/links.rb +2 -0
- data/tasks/bump/manifest.rb +2 -0
- data/tasks/bump/ruby_gem.rb +2 -0
- data/tasks/bump/sem_ver.rb +2 -0
- data/tasks/bump/unreleased_section.rb +2 -0
- data/tasks/bump.rake +2 -0
- data/tasks/doc.rake +268 -0
- data/tasks/extension.rake +2 -0
- data/tasks/lint.rake +115 -0
- data/tasks/rdoc_config.rb +18 -4
- data/tasks/sourcehut.rake +2 -0
- data/tasks/terminal_preview/app_screenshot.rb +2 -0
- data/tasks/terminal_preview/crash_report.rb +2 -0
- data/tasks/terminal_preview/example_app.rb +2 -0
- data/tasks/terminal_preview/launcher_script.rb +2 -0
- data/tasks/terminal_preview/preview_collection.rb +2 -0
- data/tasks/terminal_preview/preview_timing.rb +2 -0
- data/tasks/terminal_preview/safety_confirmation.rb +2 -0
- data/tasks/terminal_preview/saved_screenshot.rb +2 -0
- data/tasks/terminal_preview/system_appearance.rb +2 -0
- data/tasks/terminal_preview/terminal_window.rb +2 -0
- data/tasks/terminal_preview/window_id.rb +2 -0
- data/tasks/terminal_preview.rake +2 -0
- data/tasks/test.rake +2 -0
- data/tasks/website/index_page.rb +2 -0
- data/tasks/website/version.rb +12 -2
- data/tasks/website/version_menu.rb +2 -0
- data/tasks/website/versioned_documentation.rb +2 -0
- data/tasks/website/website.rb +2 -0
- data/tasks/website.rake +2 -0
- metadata +97 -75
- data/doc/contributors/architectural_overhaul/chat_conversations.md +0 -4952
- data/doc/contributors/architectural_overhaul/implementation_plan.md +0 -60
- data/doc/contributors/architectural_overhaul/task.md +0 -37
- /data/doc/{async.md → concepts/async.md} +0 -0
- /data/doc/{interactive_design.md → concepts/interactive_design.md} +0 -0
- /data/doc/images/{widget_barchart_demo.png → widget_barchart.png} +0 -0
- /data/doc/images/{widget_block_demo.png → widget_block.png} +0 -0
- /data/doc/images/{widget_box_demo.png → widget_box.png} +0 -0
- /data/doc/images/{widget_calendar_demo.png → widget_calendar.png} +0 -0
- /data/doc/images/{widget_canvas_demo.png → widget_canvas.png} +0 -0
- /data/doc/images/{widget_cell_demo.png → widget_cell.png} +0 -0
- /data/doc/images/{widget_center_demo.png → widget_center.png} +0 -0
- /data/doc/images/{widget_chart_demo.png → widget_chart.png} +0 -0
- /data/doc/images/{widget_gauge_demo.png → widget_gauge.png} +0 -0
- /data/doc/images/{widget_line_gauge_demo.png → widget_line_gauge.png} +0 -0
- /data/doc/images/{widget_list_demo.png → widget_list.png} +0 -0
- /data/doc/images/{widget_map_demo.png → widget_map.png} +0 -0
- /data/doc/images/{widget_overlay_demo.png → widget_overlay.png} +0 -0
- /data/doc/images/{widget_popup_demo.png → widget_popup.png} +0 -0
- /data/doc/images/{widget_ratatui_logo_demo.png → widget_ratatui_logo.png} +0 -0
- /data/doc/images/{widget_ratatui_mascot_demo.png → widget_ratatui_mascot.png} +0 -0
- /data/doc/images/{widget_scrollbar_demo.png → widget_scrollbar.png} +0 -0
- /data/doc/images/{widget_sparkline_demo.png → widget_sparkline.png} +0 -0
- /data/doc/images/{widget_table_demo.png → widget_table.png} +0 -0
- /data/doc/images/{widget_tabs_demo.png → widget_tabs.png} +0 -0
- /data/doc/{v0.7.0_migration.md → migration/v0_7_0.md} +0 -0
- /data/doc/{debugging.md → troubleshooting/debugging.md} +0 -0
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
#--
|
|
3
4
|
# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
4
5
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
6
|
+
#++
|
|
5
7
|
|
|
6
8
|
$LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
|
7
9
|
require "bundler/setup"
|
|
@@ -18,7 +20,7 @@ PROCESSES = [
|
|
|
18
20
|
{ pid: 6789, name: "node", cpu: 18.9 },
|
|
19
21
|
].freeze
|
|
20
22
|
|
|
21
|
-
class
|
|
23
|
+
class WidgetTable
|
|
22
24
|
attr_reader :selected_index, :selected_col, :current_style_index, :column_spacing, :highlight_spacing, :column_highlight_style, :cell_highlight_style
|
|
23
25
|
|
|
24
26
|
HIGHLIGHT_SPACINGS = [
|
|
@@ -250,5 +252,5 @@ class WidgetTableDemo
|
|
|
250
252
|
end
|
|
251
253
|
|
|
252
254
|
if __FILE__ == $0
|
|
253
|
-
|
|
255
|
+
WidgetTable.new.run
|
|
254
256
|
end
|
|
@@ -5,7 +5,7 @@ SPDX-License-Identifier: CC-BY-SA-4.0
|
|
|
5
5
|
|
|
6
6
|
# Tabs Widget Example
|
|
7
7
|
|
|
8
|
-
[](app.rb)
|
|
9
9
|
|
|
10
10
|
Demonstrates view segregation with interactive navigation.
|
|
11
11
|
|
|
@@ -30,12 +30,15 @@ Screen real estate is limited. You cannot show everything at once. Tabs segregat
|
|
|
30
30
|
## Usage
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
|
-
ruby examples/
|
|
33
|
+
ruby examples/widget_tabs/app.rb
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
## Learning Outcomes
|
|
37
37
|
|
|
38
38
|
Use this example if you need to...
|
|
39
|
+
|
|
39
40
|
- Build a multi-pane dashboard.
|
|
40
41
|
- Create a "Settings" screen with different categories.
|
|
41
|
-
- Implement a "wizard" interface with steps.
|
|
42
|
+
- Implement a "wizard" interface with steps.
|
|
43
|
+
|
|
44
|
+
[Read the source code →](app.rb)
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
#--
|
|
3
4
|
# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
4
5
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
6
|
+
#++
|
|
5
7
|
|
|
6
8
|
$LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
|
7
9
|
require "ratatui_ruby"
|
|
@@ -19,10 +21,10 @@ require "faker"
|
|
|
19
21
|
#
|
|
20
22
|
# Run the demo from the terminal:
|
|
21
23
|
#
|
|
22
|
-
# ruby examples/
|
|
24
|
+
# ruby examples/widget_tabs/app.rb
|
|
23
25
|
#
|
|
24
|
-
# rdoc-image:/doc/images/
|
|
25
|
-
class
|
|
26
|
+
# rdoc-image:/doc/images/widget_tabs.png
|
|
27
|
+
class WidgetTabs
|
|
26
28
|
def initialize
|
|
27
29
|
@selected_tab = 0
|
|
28
30
|
@tabs = ["Revenue", "Traffic", "Errors", "Quarterly"]
|
|
@@ -93,7 +95,7 @@ class WidgetTabsDemo
|
|
|
93
95
|
tabs = @tui.tabs(
|
|
94
96
|
titles: @tabs,
|
|
95
97
|
selected_index: @selected_tab,
|
|
96
|
-
block: @tui.block(title: "Tabs
|
|
98
|
+
block: @tui.block(title: "Tabs", borders: [:all]),
|
|
97
99
|
divider: @dividers[@divider_index],
|
|
98
100
|
highlight_style: @highlight_styles[@highlight_style_index][:style],
|
|
99
101
|
style: @base_styles[@base_style_index][:style],
|
|
@@ -178,4 +180,4 @@ class WidgetTabsDemo
|
|
|
178
180
|
end
|
|
179
181
|
end
|
|
180
182
|
|
|
181
|
-
|
|
183
|
+
WidgetTabs.new.run if __FILE__ == $0
|
|
@@ -3,7 +3,7 @@ SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
|
3
3
|
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
4
4
|
-->
|
|
5
5
|
|
|
6
|
-
# Text Width Calculator
|
|
6
|
+
# Text Width (Unicode Width) Calculator
|
|
7
7
|
|
|
8
8
|
[](app.rb)
|
|
9
9
|
|
|
@@ -30,6 +30,9 @@ ruby examples/widget_text_width/app.rb
|
|
|
30
30
|
## Learning Outcomes
|
|
31
31
|
|
|
32
32
|
Use this example if you need to...
|
|
33
|
+
|
|
33
34
|
- Align text correctly in columns.
|
|
34
35
|
- Truncate strings that are too long for a widget.
|
|
35
|
-
- Build your own custom layout engine.
|
|
36
|
+
- Build your own custom layout engine.
|
|
37
|
+
|
|
38
|
+
[Read the source code →](app.rb)
|
data/exe/.gitkeep
CHANGED
|
File without changes
|
data/ext/ratatui_ruby/Cargo.lock
CHANGED
data/ext/ratatui_ruby/Cargo.toml
CHANGED
data/ext/ratatui_ruby/extconf.rb
CHANGED
data/ext/ratatui_ruby/src/lib.rs
CHANGED
|
@@ -121,7 +121,7 @@ fn init() -> Result<(), Error> {
|
|
|
121
121
|
let m = ruby.define_module("RatatuiRuby")?;
|
|
122
122
|
|
|
123
123
|
m.define_module_function("_init_terminal", function!(init_terminal, 2))?;
|
|
124
|
-
m.define_module_function("
|
|
124
|
+
m.define_module_function("_restore_terminal", function!(restore_terminal, 0))?;
|
|
125
125
|
m.define_module_function("_draw", function!(draw, -1))?;
|
|
126
126
|
|
|
127
127
|
// Register Frame class
|
|
@@ -147,7 +147,7 @@ fn init() -> Result<(), Error> {
|
|
|
147
147
|
|
|
148
148
|
// Test backend helpers
|
|
149
149
|
m.define_module_function(
|
|
150
|
-
"
|
|
150
|
+
"_init_test_terminal",
|
|
151
151
|
function!(terminal::init_test_terminal, 2),
|
|
152
152
|
)?;
|
|
153
153
|
m.define_module_function(
|
|
@@ -60,6 +60,15 @@ pub fn render_node(frame: &mut Frame, area: Rect, node: Value) -> Result<(), Err
|
|
|
60
60
|
"RatatuiRuby::Widgets::RatatuiMascot" => {
|
|
61
61
|
widgets::ratatui_mascot::render_ratatui_mascot(frame, area, node)?;
|
|
62
62
|
}
|
|
63
|
+
// Text primitives can also be rendered directly as widgets
|
|
64
|
+
"RatatuiRuby::Text::Line" => {
|
|
65
|
+
let line = crate::text::parse_line(node)?;
|
|
66
|
+
frame.render_widget(line, area);
|
|
67
|
+
}
|
|
68
|
+
"RatatuiRuby::Text::Span" => {
|
|
69
|
+
let span = crate::text::parse_span(node)?;
|
|
70
|
+
frame.render_widget(span, area);
|
|
71
|
+
}
|
|
63
72
|
_ => {}
|
|
64
73
|
}
|
|
65
74
|
Ok(())
|
|
@@ -171,8 +171,28 @@ pub fn parse_border_set<'a>(
|
|
|
171
171
|
|
|
172
172
|
pub fn parse_bar_set<'a>(set_val: Value, bump: &'a Bump) -> Result<symbols::bar::Set<'a>, Error> {
|
|
173
173
|
let ruby = magnus::Ruby::get().unwrap();
|
|
174
|
-
|
|
175
|
-
|
|
174
|
+
|
|
175
|
+
// Check if set_val is a symbol shortcut
|
|
176
|
+
if let Ok(sym) = magnus::Symbol::from_value(set_val)
|
|
177
|
+
.ok_or::<Error>(Error::new(ruby.exception_type_error(), ""))
|
|
178
|
+
{
|
|
179
|
+
let sym_str = sym.name().unwrap_or_default();
|
|
180
|
+
return match sym_str.as_ref() {
|
|
181
|
+
"nine_levels" => Ok(symbols::bar::NINE_LEVELS),
|
|
182
|
+
"three_levels" => Ok(symbols::bar::THREE_LEVELS),
|
|
183
|
+
_ => Err(Error::new(
|
|
184
|
+
ruby.exception_arg_error(),
|
|
185
|
+
format!("unknown bar_set symbol: :{sym_str}"),
|
|
186
|
+
)),
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
let hash = magnus::RHash::from_value(set_val).ok_or_else(|| {
|
|
191
|
+
Error::new(
|
|
192
|
+
ruby.exception_type_error(),
|
|
193
|
+
"expected symbol or hash for bar_set",
|
|
194
|
+
)
|
|
195
|
+
})?;
|
|
176
196
|
|
|
177
197
|
let get_char = |key: &str| -> Result<Option<&'a str>, Error> {
|
|
178
198
|
let mut val: Value = hash
|
|
@@ -133,6 +133,8 @@ pub fn parse_line(value: Value) -> Result<Line<'static>, Error> {
|
|
|
133
133
|
let spans_val: Value = value.funcall("spans", ())?;
|
|
134
134
|
// v0.7.0: Extract style from the Ruby Line
|
|
135
135
|
let style_val: Value = value.funcall("style", ())?;
|
|
136
|
+
// Extract alignment from the Ruby Line
|
|
137
|
+
let alignment_val: Value = value.funcall("alignment", ())?;
|
|
136
138
|
|
|
137
139
|
if spans_val.is_nil() {
|
|
138
140
|
return Ok(Line::from(""));
|
|
@@ -177,6 +179,30 @@ pub fn parse_line(value: Value) -> Result<Line<'static>, Error> {
|
|
|
177
179
|
line = line.style(parse_style(style_val)?);
|
|
178
180
|
}
|
|
179
181
|
|
|
182
|
+
// Apply alignment if present
|
|
183
|
+
if !alignment_val.is_nil() {
|
|
184
|
+
if let Ok(alignment_sym) = magnus::Symbol::try_convert(alignment_val) {
|
|
185
|
+
let alignment_str = alignment_sym.name().map_err(|e| {
|
|
186
|
+
Error::new(
|
|
187
|
+
ruby.exception_type_error(),
|
|
188
|
+
format!("Invalid alignment symbol: {e}"),
|
|
189
|
+
)
|
|
190
|
+
})?;
|
|
191
|
+
let alignment = match alignment_str.as_ref() {
|
|
192
|
+
"left" => ratatui::layout::Alignment::Left,
|
|
193
|
+
"center" => ratatui::layout::Alignment::Center,
|
|
194
|
+
"right" => ratatui::layout::Alignment::Right,
|
|
195
|
+
_ => {
|
|
196
|
+
return Err(Error::new(
|
|
197
|
+
ruby.exception_arg_error(),
|
|
198
|
+
format!("Invalid alignment: {alignment_str}. Valid values: :left, :center, :right"),
|
|
199
|
+
));
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
line = line.alignment(alignment);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
180
206
|
Ok(line)
|
|
181
207
|
}
|
|
182
208
|
|
|
@@ -48,12 +48,14 @@ pub fn render(frame: &mut Frame, area: Rect, node: Value) -> Result<(), Error> {
|
|
|
48
48
|
let group_obj: Value = array.entry(index)?;
|
|
49
49
|
|
|
50
50
|
let label_val: Value = group_obj.funcall("label", ())?;
|
|
51
|
-
let
|
|
52
|
-
|
|
51
|
+
let group_label: Line = if label_val.is_nil() {
|
|
52
|
+
Line::from("")
|
|
53
|
+
} else if let Ok(line) = parse_line(label_val) {
|
|
54
|
+
line
|
|
53
55
|
} else {
|
|
54
|
-
label_val.funcall("to_s", ())
|
|
56
|
+
let label_str: String = label_val.funcall("to_s", ())?;
|
|
57
|
+
Line::from(label_str)
|
|
55
58
|
};
|
|
56
|
-
let label_ref = bump.alloc_str(&label_str) as &str;
|
|
57
59
|
|
|
58
60
|
let bars_array: RArray = group_obj.funcall("bars", ())?;
|
|
59
61
|
let mut bars: Vec<Bar> = Vec::new();
|
|
@@ -110,8 +112,8 @@ pub fn render(frame: &mut Frame, area: Rect, node: Value) -> Result<(), Error> {
|
|
|
110
112
|
}
|
|
111
113
|
|
|
112
114
|
let mut group = BarGroup::new(bars);
|
|
113
|
-
if !
|
|
114
|
-
group = group.label(
|
|
115
|
+
if !group_label.spans.is_empty() {
|
|
116
|
+
group = group.label(group_label);
|
|
115
117
|
}
|
|
116
118
|
bar_chart = bar_chart.data(group);
|
|
117
119
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
3
3
|
|
|
4
4
|
use crate::style::{parse_block, parse_style};
|
|
5
|
+
use crate::text::parse_line;
|
|
5
6
|
use bumpalo::Bump;
|
|
6
7
|
use magnus::{prelude::*, Error, Symbol, Value};
|
|
7
8
|
use ratatui::{
|
|
@@ -12,6 +13,7 @@ use ratatui::{
|
|
|
12
13
|
Frame,
|
|
13
14
|
};
|
|
14
15
|
|
|
16
|
+
#[allow(clippy::too_many_lines)]
|
|
15
17
|
pub fn render(frame: &mut Frame, area: Rect, node: Value) -> Result<(), Error> {
|
|
16
18
|
let bump = Bump::new();
|
|
17
19
|
let ruby = magnus::Ruby::get().unwrap();
|
|
@@ -59,7 +61,13 @@ pub fn render(frame: &mut Frame, area: Rect, node: Value) -> Result<(), Error> {
|
|
|
59
61
|
let index = isize::try_from(i)
|
|
60
62
|
.map_err(|e| Error::new(ruby.exception_range_error(), e.to_string()))?;
|
|
61
63
|
let ds_val: Value = datasets_val.entry(index)?;
|
|
62
|
-
let
|
|
64
|
+
let name_val: Value = ds_val.funcall("name", ())?;
|
|
65
|
+
let name = if let Ok(line) = parse_line(name_val) {
|
|
66
|
+
line
|
|
67
|
+
} else {
|
|
68
|
+
let name_str: String = name_val.funcall("to_s", ())?;
|
|
69
|
+
ratatui::text::Line::from(name_str)
|
|
70
|
+
};
|
|
63
71
|
let marker_sym: Symbol = ds_val.funcall("marker", ())?;
|
|
64
72
|
let graph_type_sym: Symbol = ds_val.funcall("graph_type", ())?;
|
|
65
73
|
|
|
@@ -67,6 +75,7 @@ pub fn render(frame: &mut Frame, area: Rect, node: Value) -> Result<(), Error> {
|
|
|
67
75
|
"braille" => symbols::Marker::Braille,
|
|
68
76
|
"block" => symbols::Marker::Block,
|
|
69
77
|
"bar" => symbols::Marker::Bar,
|
|
78
|
+
"half_block" => symbols::Marker::HalfBlock,
|
|
70
79
|
_ => symbols::Marker::Dot,
|
|
71
80
|
};
|
|
72
81
|
|
|
@@ -107,8 +116,12 @@ pub fn render(frame: &mut Frame, area: Rect, node: Value) -> Result<(), Error> {
|
|
|
107
116
|
let pos_sym: Symbol = legend_position_val.funcall("to_sym", ())?;
|
|
108
117
|
let pos = match pos_sym.to_string().as_str() {
|
|
109
118
|
"top_left" => LegendPosition::TopLeft,
|
|
119
|
+
"top" => LegendPosition::Top,
|
|
110
120
|
"bottom_left" => LegendPosition::BottomLeft,
|
|
121
|
+
"bottom" => LegendPosition::Bottom,
|
|
111
122
|
"bottom_right" => LegendPosition::BottomRight,
|
|
123
|
+
"left" => LegendPosition::Left,
|
|
124
|
+
"right" => LegendPosition::Right,
|
|
112
125
|
_ => LegendPosition::TopRight,
|
|
113
126
|
};
|
|
114
127
|
chart = chart.legend_position(Some(pos));
|
|
@@ -132,7 +145,15 @@ pub fn render(frame: &mut Frame, area: Rect, node: Value) -> Result<(), Error> {
|
|
|
132
145
|
|
|
133
146
|
fn parse_axis(axis_val: Value) -> Result<Axis<'static>, Error> {
|
|
134
147
|
let ruby = magnus::Ruby::get().unwrap();
|
|
135
|
-
let
|
|
148
|
+
let title_val: Value = axis_val.funcall("title", ())?;
|
|
149
|
+
let title = if title_val.is_nil() {
|
|
150
|
+
ratatui::text::Line::from("")
|
|
151
|
+
} else if let Ok(line) = parse_line(title_val) {
|
|
152
|
+
line
|
|
153
|
+
} else {
|
|
154
|
+
let title_str: String = title_val.funcall("to_s", ())?;
|
|
155
|
+
ratatui::text::Line::from(title_str)
|
|
156
|
+
};
|
|
136
157
|
let bounds_val: magnus::RArray = axis_val.funcall("bounds", ())?;
|
|
137
158
|
let labels_val: magnus::RArray = axis_val.funcall("labels", ())?;
|
|
138
159
|
let style_val: Value = axis_val.funcall("style", ())?;
|
|
@@ -144,8 +165,14 @@ fn parse_axis(axis_val: Value) -> Result<Axis<'static>, Error> {
|
|
|
144
165
|
for i in 0..labels_val.len() {
|
|
145
166
|
let index = isize::try_from(i)
|
|
146
167
|
.map_err(|e| Error::new(ruby.exception_range_error(), e.to_string()))?;
|
|
147
|
-
let
|
|
148
|
-
|
|
168
|
+
let entry_val: Value = labels_val.entry(index)?;
|
|
169
|
+
let label = if let Ok(line) = parse_line(entry_val) {
|
|
170
|
+
line
|
|
171
|
+
} else {
|
|
172
|
+
let label_str: String = entry_val.funcall("to_s", ())?;
|
|
173
|
+
ratatui::text::Line::from(label_str)
|
|
174
|
+
};
|
|
175
|
+
labels.push(label);
|
|
149
176
|
}
|
|
150
177
|
|
|
151
178
|
let mut axis = Axis::default().title(title).bounds(bounds).labels(labels);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
3
3
|
|
|
4
4
|
use crate::style::{parse_block, parse_style};
|
|
5
|
-
use crate::text::{parse_line, parse_span};
|
|
5
|
+
use crate::text::{parse_line, parse_span, parse_text};
|
|
6
6
|
use crate::widgets::table_state::RubyTableState;
|
|
7
7
|
use bumpalo::Bump;
|
|
8
8
|
use magnus::{prelude::*, Error, Symbol, TryConvert, Value};
|
|
@@ -87,8 +87,12 @@ pub fn render(frame: &mut Frame, area: Rect, node: Value) -> Result<(), Error> {
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
if !highlight_symbol_val.is_nil() {
|
|
90
|
-
let
|
|
91
|
-
|
|
90
|
+
if let Ok(text) = parse_text(highlight_symbol_val) {
|
|
91
|
+
table = table.highlight_symbol(ratatui::text::Text::from(text));
|
|
92
|
+
} else {
|
|
93
|
+
let symbol: String = highlight_symbol_val.funcall("to_s", ())?;
|
|
94
|
+
table = table.highlight_symbol(symbol);
|
|
95
|
+
}
|
|
92
96
|
}
|
|
93
97
|
|
|
94
98
|
let style_val: Value = node.funcall("style", ())?;
|
|
@@ -207,8 +211,12 @@ pub fn render_stateful(
|
|
|
207
211
|
table = table.cell_highlight_style(parse_style(cell_highlight_style_val)?);
|
|
208
212
|
}
|
|
209
213
|
if !highlight_symbol_val.is_nil() {
|
|
210
|
-
let
|
|
211
|
-
|
|
214
|
+
if let Ok(text) = parse_text(highlight_symbol_val) {
|
|
215
|
+
table = table.highlight_symbol(ratatui::text::Text::from(text));
|
|
216
|
+
} else {
|
|
217
|
+
let symbol: String = highlight_symbol_val.funcall("to_s", ())?;
|
|
218
|
+
table = table.highlight_symbol(symbol);
|
|
219
|
+
}
|
|
212
220
|
}
|
|
213
221
|
if !style_val.is_nil() {
|
|
214
222
|
table = table.style(parse_style(style_val)?);
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
3
3
|
|
|
4
4
|
use crate::style::parse_block;
|
|
5
|
+
use crate::text::{parse_line, parse_span};
|
|
5
6
|
use bumpalo::Bump;
|
|
6
7
|
use magnus::{prelude::*, Error, Value};
|
|
7
8
|
use ratatui::{layout::Rect, text::Line, widgets::Tabs, Frame};
|
|
@@ -13,7 +14,39 @@ pub fn render(frame: &mut Frame, area: Rect, node: Value) -> Result<(), Error> {
|
|
|
13
14
|
Ok(())
|
|
14
15
|
}
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
/// Parses padding value with duck-typing support:
|
|
18
|
+
/// - Integer: generates that many spaces
|
|
19
|
+
/// - Line: uses styled Line directly
|
|
20
|
+
/// - Span: wraps in Line
|
|
21
|
+
/// - String or `to_s` responder: converts to Line
|
|
22
|
+
fn parse_padding(val: Value) -> Result<Line<'static>, Error> {
|
|
23
|
+
// Handle nil or zero
|
|
24
|
+
if val.is_nil() {
|
|
25
|
+
return Ok(Line::from(""));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Try as Integer first (most common case)
|
|
29
|
+
if let Ok(n) = usize::try_convert(val) {
|
|
30
|
+
if n == 0 {
|
|
31
|
+
return Ok(Line::from(""));
|
|
32
|
+
}
|
|
33
|
+
return Ok(Line::from(" ".repeat(n)));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Try to parse as Line
|
|
37
|
+
if let Ok(line) = parse_line(val) {
|
|
38
|
+
return Ok(line);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Try to parse as Span (wrap in Line)
|
|
42
|
+
if let Ok(span) = parse_span(val) {
|
|
43
|
+
return Ok(Line::from(vec![span]));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Fallback: call to_s and convert to Line
|
|
47
|
+
let s: String = val.funcall("to_s", ())?;
|
|
48
|
+
Ok(Line::from(s))
|
|
49
|
+
}
|
|
17
50
|
|
|
18
51
|
fn create_tabs(node: Value, bump: &Bump) -> Result<Tabs<'_>, Error> {
|
|
19
52
|
let ruby = magnus::Ruby::get().unwrap();
|
|
@@ -22,8 +55,8 @@ fn create_tabs(node: Value, bump: &Bump) -> Result<Tabs<'_>, Error> {
|
|
|
22
55
|
let block_val: Value = node.funcall("block", ())?;
|
|
23
56
|
let divider_val: Value = node.funcall("divider", ())?;
|
|
24
57
|
let highlight_style_val: Value = node.funcall("highlight_style", ())?;
|
|
25
|
-
let
|
|
26
|
-
let
|
|
58
|
+
let padding_left_val: Value = node.funcall("padding_left", ())?;
|
|
59
|
+
let padding_right_val: Value = node.funcall("padding_right", ())?;
|
|
27
60
|
|
|
28
61
|
let titles_array = magnus::RArray::from_value(titles_val)
|
|
29
62
|
.ok_or_else(|| Error::new(ruby.exception_type_error(), "expected array for titles"))?;
|
|
@@ -44,8 +77,12 @@ fn create_tabs(node: Value, bump: &Bump) -> Result<Tabs<'_>, Error> {
|
|
|
44
77
|
let mut tabs = Tabs::new(titles).select(selected_index);
|
|
45
78
|
|
|
46
79
|
if !divider_val.is_nil() {
|
|
47
|
-
let
|
|
48
|
-
|
|
80
|
+
if let Ok(span) = parse_span(divider_val) {
|
|
81
|
+
tabs = tabs.divider(span);
|
|
82
|
+
} else {
|
|
83
|
+
let divider: String = divider_val.funcall("to_s", ())?;
|
|
84
|
+
tabs = tabs.divider(divider);
|
|
85
|
+
}
|
|
49
86
|
}
|
|
50
87
|
|
|
51
88
|
if !highlight_style_val.is_nil() {
|
|
@@ -62,10 +99,11 @@ fn create_tabs(node: Value, bump: &Bump) -> Result<Tabs<'_>, Error> {
|
|
|
62
99
|
tabs = tabs.block(parse_block(block_val, bump)?);
|
|
63
100
|
}
|
|
64
101
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
102
|
+
// Handle duck-typed padding: Integer (spaces), String, Line, or anything with to_s
|
|
103
|
+
let left_padding = parse_padding(padding_left_val)?;
|
|
104
|
+
let right_padding = parse_padding(padding_right_val)?;
|
|
105
|
+
if !left_padding.spans.is_empty() || !right_padding.spans.is_empty() {
|
|
106
|
+
tabs = tabs.padding(left_padding, right_padding);
|
|
69
107
|
}
|
|
70
108
|
|
|
71
109
|
Ok(tabs)
|
|
@@ -101,6 +139,8 @@ pub fn width(node: Value) -> Result<usize, Error> {
|
|
|
101
139
|
if titles_count > 1 {
|
|
102
140
|
let divider_width = if divider_val.is_nil() {
|
|
103
141
|
1 // Default divider is "|"
|
|
142
|
+
} else if let Ok(span) = parse_span(divider_val) {
|
|
143
|
+
span.width()
|
|
104
144
|
} else {
|
|
105
145
|
let d: String = divider_val.funcall("to_s", ())?;
|
|
106
146
|
ratatui::text::Span::raw(d).width()
|
data/lib/ratatui_ruby/buffer.rb
CHANGED
data/lib/ratatui_ruby/cell.rb
CHANGED