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
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
2
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
3
|
+
|
|
4
|
+
module RatatuiRuby
|
|
5
|
+
class TUI
|
|
6
|
+
module WidgetFactories
|
|
7
|
+
def block: (**top) -> Widgets::Block
|
|
8
|
+
def paragraph: (**top) -> Widgets::Paragraph
|
|
9
|
+
def list: (**top) -> Widgets::List
|
|
10
|
+
def list_item: (**top) -> Widgets::ListItem
|
|
11
|
+
def table: (**top) -> Widgets::Table
|
|
12
|
+
def row: (**top) -> Widgets::Row
|
|
13
|
+
def table_row: (**top) -> Widgets::Row
|
|
14
|
+
def table_cell: (**top) -> Widgets::Cell
|
|
15
|
+
def tabs: (**top) -> Widgets::Tabs
|
|
16
|
+
def gauge: (**top) -> Widgets::Gauge
|
|
17
|
+
def line_gauge: (**top) -> Widgets::LineGauge
|
|
18
|
+
def sparkline: (**top) -> Widgets::Sparkline
|
|
19
|
+
def bar_chart: (**top) -> Widgets::BarChart
|
|
20
|
+
def bar: (**top) -> Widgets::BarChart::Bar
|
|
21
|
+
def bar_group: (**top) -> Widgets::BarChart::BarGroup
|
|
22
|
+
def bar_chart_bar: (**top) -> Widgets::BarChart::Bar
|
|
23
|
+
def bar_chart_bar_group: (**top) -> Widgets::BarChart::BarGroup
|
|
24
|
+
def chart: (**top) -> Widgets::Chart
|
|
25
|
+
def dataset: (**top) -> Widgets::Dataset
|
|
26
|
+
def axis: (**top) -> Widgets::Axis
|
|
27
|
+
def scrollbar: (**top) -> Widgets::Scrollbar
|
|
28
|
+
def calendar: (**top) -> Widgets::Calendar
|
|
29
|
+
def canvas: (**top) -> Widgets::Canvas
|
|
30
|
+
def clear: (**top) -> Widgets::Clear
|
|
31
|
+
def cursor: (**top) -> Widgets::Cursor
|
|
32
|
+
def overlay: (**top) -> Widgets::Overlay
|
|
33
|
+
def center: (**top) -> Widgets::Center
|
|
34
|
+
def ratatui_logo: (**top) -> Widgets::RatatuiLogo
|
|
35
|
+
def ratatui_mascot: (**top) -> Widgets::RatatuiMascot
|
|
36
|
+
def shape_label: (**top) -> Widgets::Shape::Label
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
2
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
3
|
+
|
|
4
|
+
module RatatuiRuby
|
|
5
|
+
# Terminal User Interface facade providing a concise DSL for building TUI applications.
|
|
6
|
+
#
|
|
7
|
+
# Combines all factory mixins to provide convenient access to widgets, layouts,
|
|
8
|
+
# styles, and terminal operations without verbose class name qualification.
|
|
9
|
+
class TUI
|
|
10
|
+
include Core
|
|
11
|
+
include LayoutFactories
|
|
12
|
+
include StyleFactories
|
|
13
|
+
include WidgetFactories
|
|
14
|
+
include TextFactories
|
|
15
|
+
include StateFactories
|
|
16
|
+
include CanvasFactories
|
|
17
|
+
include BufferFactories
|
|
18
|
+
end
|
|
19
|
+
end
|
data/tasks/autodoc.rake
CHANGED
|
@@ -3,45 +3,11 @@
|
|
|
3
3
|
# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
4
4
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
5
5
|
|
|
6
|
-
require_relative "autodoc/inventory"
|
|
7
|
-
require_relative "autodoc/notice"
|
|
8
|
-
require_relative "autodoc/rbs"
|
|
9
|
-
require_relative "autodoc/rdoc"
|
|
10
6
|
require_relative "autodoc/examples"
|
|
11
7
|
|
|
12
8
|
namespace :autodoc do
|
|
13
9
|
desc "Update all automatically generated documentation"
|
|
14
|
-
task all: [:
|
|
15
|
-
|
|
16
|
-
desc "Update all automatically generated RBS signatures"
|
|
17
|
-
task rbs: ["rbs:session"]
|
|
18
|
-
|
|
19
|
-
desc "Update all automatically generated RDoc files"
|
|
20
|
-
task rdoc: ["rdoc:session"]
|
|
21
|
-
|
|
22
|
-
namespace :rbs do
|
|
23
|
-
desc "Generate RBS for RatatuiRuby::Session"
|
|
24
|
-
task :session do
|
|
25
|
-
require_relative "../lib/ratatui_ruby"
|
|
26
|
-
|
|
27
|
-
Autodoc::Rbs.new(
|
|
28
|
-
path: File.expand_path("../sig/ratatui_ruby/session.rbs", __dir__),
|
|
29
|
-
notice: Autodoc::Notice.new("autodoc:rbs:session")
|
|
30
|
-
).write(Autodoc::Inventory.new)
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
namespace :rdoc do
|
|
35
|
-
desc "Generate RDoc autodoc for RatatuiRuby::Session"
|
|
36
|
-
task :session do
|
|
37
|
-
require_relative "../lib/ratatui_ruby"
|
|
38
|
-
|
|
39
|
-
Autodoc::Rdoc.new(
|
|
40
|
-
path: File.expand_path("../lib/ratatui_ruby/session/autodoc.rb", __dir__),
|
|
41
|
-
notice: Autodoc::Notice.new("autodoc:rdoc:session")
|
|
42
|
-
).write(Autodoc::Inventory.new)
|
|
43
|
-
end
|
|
44
|
-
end
|
|
10
|
+
task all: [:examples]
|
|
45
11
|
|
|
46
12
|
desc "Sync code snippets in example READMEs with source files"
|
|
47
13
|
task :examples do
|
data/tasks/sourcehut.rake
CHANGED
|
@@ -65,7 +65,10 @@ namespace :sourcehut do
|
|
|
65
65
|
# This renders a commit SHA that can be pushed to a branch head
|
|
66
66
|
commit_sha = `git rev-parse #{tag_name}^{}`.strip
|
|
67
67
|
|
|
68
|
-
#
|
|
68
|
+
# Update local stable branch to match
|
|
69
|
+
sh "git branch -f stable #{commit_sha}"
|
|
70
|
+
|
|
71
|
+
# Push the commit to remote stable branch
|
|
69
72
|
# This creates 'stable' if it doesn't exist, or fast-forwards it.
|
|
70
73
|
sh "git push origin #{commit_sha}:stable"
|
|
71
74
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ratatui_ruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kerrick Long
|
|
@@ -107,24 +107,21 @@ files:
|
|
|
107
107
|
- Rakefile
|
|
108
108
|
- doc/application_architecture.md
|
|
109
109
|
- doc/application_testing.md
|
|
110
|
+
- doc/contributors/architectural_overhaul/chat_conversations.md
|
|
111
|
+
- doc/contributors/architectural_overhaul/implementation_plan.md
|
|
112
|
+
- doc/contributors/architectural_overhaul/task.md
|
|
110
113
|
- doc/contributors/design.md
|
|
111
114
|
- doc/contributors/design/ruby_frontend.md
|
|
112
115
|
- doc/contributors/design/rust_backend.md
|
|
113
116
|
- doc/contributors/developing_examples.md
|
|
114
117
|
- doc/contributors/documentation_style.md
|
|
115
|
-
- doc/contributors/dwim_dx.md
|
|
116
|
-
- doc/contributors/examples_audit.md
|
|
117
|
-
- doc/contributors/examples_audit/p1_high.md
|
|
118
|
-
- doc/contributors/examples_audit/p2_moderate.md
|
|
119
118
|
- doc/contributors/index.md
|
|
119
|
+
- doc/contributors/v1.0.0_blockers.md
|
|
120
120
|
- doc/custom.css
|
|
121
121
|
- doc/event_handling.md
|
|
122
122
|
- doc/images/app_all_events.png
|
|
123
|
-
- doc/images/app_analytics.png
|
|
124
123
|
- doc/images/app_color_picker.png
|
|
125
|
-
- doc/images/app_custom_widget.png
|
|
126
124
|
- doc/images/app_login_form.png
|
|
127
|
-
- doc/images/app_mouse_events.png
|
|
128
125
|
- doc/images/app_stateful_interaction.png
|
|
129
126
|
- doc/images/verify_quickstart_dsl.png
|
|
130
127
|
- doc/images/verify_quickstart_layout.png
|
|
@@ -155,13 +152,14 @@ files:
|
|
|
155
152
|
- doc/images/widget_sparkline_demo.png
|
|
156
153
|
- doc/images/widget_style_colors.png
|
|
157
154
|
- doc/images/widget_table_demo.png
|
|
158
|
-
- doc/images/widget_table_flex.png
|
|
159
155
|
- doc/images/widget_tabs_demo.png
|
|
160
156
|
- doc/images/widget_text_width.png
|
|
161
157
|
- doc/index.md
|
|
162
158
|
- doc/interactive_design.md
|
|
163
159
|
- doc/quickstart.md
|
|
164
160
|
- doc/terminal_limitations.md
|
|
161
|
+
- doc/v0.7.0_migration.md
|
|
162
|
+
- doc/why.md
|
|
165
163
|
- examples/app_all_events/README.md
|
|
166
164
|
- examples/app_all_events/app.rb
|
|
167
165
|
- examples/app_all_events/model/app_model.rb
|
|
@@ -226,6 +224,7 @@ files:
|
|
|
226
224
|
- examples/widget_list_demo/app.rb
|
|
227
225
|
- examples/widget_map_demo/README.md
|
|
228
226
|
- examples/widget_map_demo/app.rb
|
|
227
|
+
- examples/widget_overlay_demo/README.md
|
|
229
228
|
- examples/widget_overlay_demo/app.rb
|
|
230
229
|
- examples/widget_popup_demo/README.md
|
|
231
230
|
- examples/widget_popup_demo/app.rb
|
|
@@ -293,6 +292,8 @@ files:
|
|
|
293
292
|
- ext/ratatui_ruby/src/widgets/table_state.rs
|
|
294
293
|
- ext/ratatui_ruby/src/widgets/tabs.rs
|
|
295
294
|
- lib/ratatui_ruby.rb
|
|
295
|
+
- lib/ratatui_ruby/buffer.rb
|
|
296
|
+
- lib/ratatui_ruby/buffer/cell.rb
|
|
296
297
|
- lib/ratatui_ruby/cell.rb
|
|
297
298
|
- lib/ratatui_ruby/event.rb
|
|
298
299
|
- lib/ratatui_ruby/event/focus_gained.rb
|
|
@@ -308,6 +309,10 @@ files:
|
|
|
308
309
|
- lib/ratatui_ruby/event/paste.rb
|
|
309
310
|
- lib/ratatui_ruby/event/resize.rb
|
|
310
311
|
- lib/ratatui_ruby/frame.rb
|
|
312
|
+
- lib/ratatui_ruby/layout.rb
|
|
313
|
+
- lib/ratatui_ruby/layout/constraint.rb
|
|
314
|
+
- lib/ratatui_ruby/layout/layout.rb
|
|
315
|
+
- lib/ratatui_ruby/layout/rect.rb
|
|
311
316
|
- lib/ratatui_ruby/list_state.rb
|
|
312
317
|
- lib/ratatui_ruby/schema/bar_chart.rb
|
|
313
318
|
- lib/ratatui_ruby/schema/bar_chart/bar.rb
|
|
@@ -331,6 +336,7 @@ files:
|
|
|
331
336
|
- lib/ratatui_ruby/schema/ratatui_logo.rb
|
|
332
337
|
- lib/ratatui_ruby/schema/ratatui_mascot.rb
|
|
333
338
|
- lib/ratatui_ruby/schema/rect.rb
|
|
339
|
+
- lib/ratatui_ruby/schema/row.rb
|
|
334
340
|
- lib/ratatui_ruby/schema/scrollbar.rb
|
|
335
341
|
- lib/ratatui_ruby/schema/shape/label.rb
|
|
336
342
|
- lib/ratatui_ruby/schema/sparkline.rb
|
|
@@ -339,8 +345,8 @@ files:
|
|
|
339
345
|
- lib/ratatui_ruby/schema/tabs.rb
|
|
340
346
|
- lib/ratatui_ruby/schema/text.rb
|
|
341
347
|
- lib/ratatui_ruby/scrollbar_state.rb
|
|
342
|
-
- lib/ratatui_ruby/
|
|
343
|
-
- lib/ratatui_ruby/
|
|
348
|
+
- lib/ratatui_ruby/style.rb
|
|
349
|
+
- lib/ratatui_ruby/style/style.rb
|
|
344
350
|
- lib/ratatui_ruby/table_state.rb
|
|
345
351
|
- lib/ratatui_ruby/test_helper.rb
|
|
346
352
|
- lib/ratatui_ruby/test_helper/event_injection.rb
|
|
@@ -348,7 +354,42 @@ files:
|
|
|
348
354
|
- lib/ratatui_ruby/test_helper/style_assertions.rb
|
|
349
355
|
- lib/ratatui_ruby/test_helper/terminal.rb
|
|
350
356
|
- lib/ratatui_ruby/test_helper/test_doubles.rb
|
|
357
|
+
- lib/ratatui_ruby/tui.rb
|
|
358
|
+
- lib/ratatui_ruby/tui/buffer_factories.rb
|
|
359
|
+
- lib/ratatui_ruby/tui/canvas_factories.rb
|
|
360
|
+
- lib/ratatui_ruby/tui/core.rb
|
|
361
|
+
- lib/ratatui_ruby/tui/layout_factories.rb
|
|
362
|
+
- lib/ratatui_ruby/tui/state_factories.rb
|
|
363
|
+
- lib/ratatui_ruby/tui/style_factories.rb
|
|
364
|
+
- lib/ratatui_ruby/tui/text_factories.rb
|
|
365
|
+
- lib/ratatui_ruby/tui/widget_factories.rb
|
|
351
366
|
- lib/ratatui_ruby/version.rb
|
|
367
|
+
- lib/ratatui_ruby/widgets.rb
|
|
368
|
+
- lib/ratatui_ruby/widgets/bar_chart.rb
|
|
369
|
+
- lib/ratatui_ruby/widgets/bar_chart/bar.rb
|
|
370
|
+
- lib/ratatui_ruby/widgets/bar_chart/bar_group.rb
|
|
371
|
+
- lib/ratatui_ruby/widgets/block.rb
|
|
372
|
+
- lib/ratatui_ruby/widgets/calendar.rb
|
|
373
|
+
- lib/ratatui_ruby/widgets/canvas.rb
|
|
374
|
+
- lib/ratatui_ruby/widgets/cell.rb
|
|
375
|
+
- lib/ratatui_ruby/widgets/center.rb
|
|
376
|
+
- lib/ratatui_ruby/widgets/chart.rb
|
|
377
|
+
- lib/ratatui_ruby/widgets/clear.rb
|
|
378
|
+
- lib/ratatui_ruby/widgets/cursor.rb
|
|
379
|
+
- lib/ratatui_ruby/widgets/gauge.rb
|
|
380
|
+
- lib/ratatui_ruby/widgets/line_gauge.rb
|
|
381
|
+
- lib/ratatui_ruby/widgets/list.rb
|
|
382
|
+
- lib/ratatui_ruby/widgets/list_item.rb
|
|
383
|
+
- lib/ratatui_ruby/widgets/overlay.rb
|
|
384
|
+
- lib/ratatui_ruby/widgets/paragraph.rb
|
|
385
|
+
- lib/ratatui_ruby/widgets/ratatui_logo.rb
|
|
386
|
+
- lib/ratatui_ruby/widgets/ratatui_mascot.rb
|
|
387
|
+
- lib/ratatui_ruby/widgets/row.rb
|
|
388
|
+
- lib/ratatui_ruby/widgets/scrollbar.rb
|
|
389
|
+
- lib/ratatui_ruby/widgets/shape/label.rb
|
|
390
|
+
- lib/ratatui_ruby/widgets/sparkline.rb
|
|
391
|
+
- lib/ratatui_ruby/widgets/table.rb
|
|
392
|
+
- lib/ratatui_ruby/widgets/tabs.rb
|
|
352
393
|
- mise.toml
|
|
353
394
|
- sig/examples/app_all_events/app.rbs
|
|
354
395
|
- sig/examples/app_all_events/model/event_entry.rbs
|
|
@@ -414,6 +455,7 @@ files:
|
|
|
414
455
|
- sig/ratatui_ruby/schema/ratatui_logo.rbs
|
|
415
456
|
- sig/ratatui_ruby/schema/ratatui_mascot.rbs
|
|
416
457
|
- sig/ratatui_ruby/schema/rect.rbs
|
|
458
|
+
- sig/ratatui_ruby/schema/row.rbs
|
|
417
459
|
- sig/ratatui_ruby/schema/scrollbar.rbs
|
|
418
460
|
- sig/ratatui_ruby/schema/sparkline.rbs
|
|
419
461
|
- sig/ratatui_ruby/schema/style.rbs
|
|
@@ -429,15 +471,20 @@ files:
|
|
|
429
471
|
- sig/ratatui_ruby/test_helper/style_assertions.rbs
|
|
430
472
|
- sig/ratatui_ruby/test_helper/terminal.rbs
|
|
431
473
|
- sig/ratatui_ruby/test_helper/test_doubles.rbs
|
|
474
|
+
- sig/ratatui_ruby/tui.rbs
|
|
475
|
+
- sig/ratatui_ruby/tui/buffer_factories.rbs
|
|
476
|
+
- sig/ratatui_ruby/tui/canvas_factories.rbs
|
|
477
|
+
- sig/ratatui_ruby/tui/core.rbs
|
|
478
|
+
- sig/ratatui_ruby/tui/layout_factories.rbs
|
|
479
|
+
- sig/ratatui_ruby/tui/state_factories.rbs
|
|
480
|
+
- sig/ratatui_ruby/tui/style_factories.rbs
|
|
481
|
+
- sig/ratatui_ruby/tui/text_factories.rbs
|
|
482
|
+
- sig/ratatui_ruby/tui/widget_factories.rbs
|
|
432
483
|
- sig/ratatui_ruby/version.rbs
|
|
433
484
|
- tasks/autodoc.rake
|
|
434
485
|
- tasks/autodoc/examples.rb
|
|
435
|
-
- tasks/autodoc/inventory.rb
|
|
436
486
|
- tasks/autodoc/member.rb
|
|
437
487
|
- tasks/autodoc/name.rb
|
|
438
|
-
- tasks/autodoc/notice.rb
|
|
439
|
-
- tasks/autodoc/rbs.rb
|
|
440
|
-
- tasks/autodoc/rdoc.rb
|
|
441
488
|
- tasks/bump.rake
|
|
442
489
|
- tasks/bump/cargo_lockfile.rb
|
|
443
490
|
- tasks/bump/changelog.rb
|
data/doc/contributors/dwim_dx.md
DELETED
|
@@ -1,366 +0,0 @@
|
|
|
1
|
-
<!-- SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com> -->
|
|
2
|
-
<!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
|
|
3
|
-
|
|
4
|
-
# DWIM / DX Improvements for Application Developers
|
|
5
|
-
|
|
6
|
-
## Problem Statement
|
|
7
|
-
|
|
8
|
-
Ruby's philosophy of "Do What I Mean" (DWIM) and human-centric design should extend to ratatui_ruby's API. Currently, app developers encounter friction points that force them to remember non-obvious conventions, use overly verbose code, or pattern-match when simple predicates would suffice.
|
|
9
|
-
|
|
10
|
-
This proposal identifies DX issues across the widget API and suggests improvements that maintain backward compatibility while providing ergonomic alternatives.
|
|
11
|
-
|
|
12
|
-
## DX Issues Identified
|
|
13
|
-
|
|
14
|
-
### 1. Confusing Event Method Names
|
|
15
|
-
|
|
16
|
-
**Current problem**: `event.char` doesn't exist, but `event.code` returns things like `"enter"`, `"ctrl"`, not just characters.
|
|
17
|
-
|
|
18
|
-
**What users expect**:
|
|
19
|
-
- `event.char` should return the printable character (matching the name)
|
|
20
|
-
- `event.ctrl_c?`, `event.enter?`, etc. should work for all key combinations
|
|
21
|
-
- `event.key?`, `event.mouse?` predicates exist but only for broad categories
|
|
22
|
-
|
|
23
|
-
**Solution implemented**: Added `char` method and dynamic predicates via `method_missing`. See `lib/ratatui_ruby/event/key.rb`.
|
|
24
|
-
|
|
25
|
-
### 2. Dual Parameter APIs Without Predicates
|
|
26
|
-
|
|
27
|
-
**Current problem**: Widgets accept both forms but no convenience methods to query the state:
|
|
28
|
-
|
|
29
|
-
```ruby
|
|
30
|
-
# Both work, but which one does the widget store?
|
|
31
|
-
gauge1 = Gauge.new(ratio: 0.75)
|
|
32
|
-
gauge2 = Gauge.new(percent: 75)
|
|
33
|
-
gauge1.ratio # Works
|
|
34
|
-
gauge1.percent # Does NOT exist
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
Similarly with List and Table:
|
|
38
|
-
```ruby
|
|
39
|
-
list.selected_index = 2 # Works
|
|
40
|
-
list.selected? # Does NOT exist
|
|
41
|
-
list.is_selected? # Does NOT exist
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
**Affected widgets**:
|
|
45
|
-
- `Gauge` (ratio vs percent)
|
|
46
|
-
- `LineGauge` (ratio vs percent)
|
|
47
|
-
- `List` (selected_index with no query methods)
|
|
48
|
-
- `Table` (selected_row and selected_column with no query methods)
|
|
49
|
-
|
|
50
|
-
**Suggested solutions**:
|
|
51
|
-
|
|
52
|
-
For `Gauge` and `LineGauge`:
|
|
53
|
-
```ruby
|
|
54
|
-
# Add convenience predicates
|
|
55
|
-
gauge.percent # => 75 (coerced from ratio internally)
|
|
56
|
-
gauge.percent = 50 # => Updates ratio to 0.5
|
|
57
|
-
|
|
58
|
-
# Or provide explicit accessors
|
|
59
|
-
gauge.as_percent # => 75
|
|
60
|
-
gauge.as_ratio # => 0.75
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
For `List` and `Table`:
|
|
64
|
-
```ruby
|
|
65
|
-
list.selected? # => true if selected_index is not nil
|
|
66
|
-
list.selection # => 2 (alias for selected_index)
|
|
67
|
-
list.selected_item # => "Item 3"
|
|
68
|
-
|
|
69
|
-
table.selected_row? # => true if selected_row is not nil
|
|
70
|
-
table.selected_cell? # => true if both row and column selected
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
### 3. Symbol Constants for Enum Values
|
|
74
|
-
|
|
75
|
-
**Current problem**: Magic symbol values scattered across code:
|
|
76
|
-
|
|
77
|
-
```ruby
|
|
78
|
-
list = List.new(
|
|
79
|
-
highlight_spacing: :when_selected, # What are the other options?
|
|
80
|
-
direction: :top_to_bottom, # Is :bottom_to_top valid?
|
|
81
|
-
)
|
|
82
|
-
|
|
83
|
-
layout = Layout.new(
|
|
84
|
-
flex: :legacy # What does "legacy" mean?
|
|
85
|
-
)
|
|
86
|
-
|
|
87
|
-
gauge = Gauge.new(
|
|
88
|
-
use_unicode: true # Unclear what ASCII fallback looks like
|
|
89
|
-
)
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
Users must consult docs or source code to discover valid options.
|
|
93
|
-
|
|
94
|
-
**Suggested solution**: Add constants to widget classes:
|
|
95
|
-
|
|
96
|
-
```ruby
|
|
97
|
-
class List < Data
|
|
98
|
-
# Highlight spacing modes
|
|
99
|
-
HIGHLIGHT_ALWAYS = :always
|
|
100
|
-
HIGHLIGHT_WHEN_SELECTED = :when_selected
|
|
101
|
-
HIGHLIGHT_NEVER = :never
|
|
102
|
-
|
|
103
|
-
# Direction modes
|
|
104
|
-
DIRECTION_TOP_TO_BOTTOM = :top_to_bottom
|
|
105
|
-
DIRECTION_BOTTOM_TO_TOP = :bottom_to_top
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
list = List.new(
|
|
109
|
-
highlight_spacing: List::HIGHLIGHT_WHEN_SELECTED,
|
|
110
|
-
direction: List::DIRECTION_TOP_TO_BOTTOM,
|
|
111
|
-
)
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
Benefits:
|
|
115
|
-
- IDE autocomplete shows valid options
|
|
116
|
-
- Self-documenting code
|
|
117
|
-
- Typos caught at runtime (symbol vs constant)
|
|
118
|
-
- Easy to grep for where these modes are used
|
|
119
|
-
|
|
120
|
-
Affected widgets and their enum values:
|
|
121
|
-
- `List`: `highlight_spacing` (:always, :when_selected, :never), `direction` (:top_to_bottom, :bottom_to_top)
|
|
122
|
-
- `Table`: `highlight_spacing` (same as List), `flex` (:legacy, :default, :fill)
|
|
123
|
-
- `Layout`: `direction` (:vertical, :horizontal), `flex` (:legacy, :default, :fill)
|
|
124
|
-
- `Gauge`/`LineGauge`: `use_unicode` (boolean, but could have MODE_UNICODE, MODE_ASCII)
|
|
125
|
-
- `Paragraph`: `alignment` (:left, :center, :right)
|
|
126
|
-
- `Block`: `border_type` (:plain, :rounded, :double, :thick)
|
|
127
|
-
- `Canvas`: `marker` (:braille, :dots, :half_block, :sextant, :octant)
|
|
128
|
-
|
|
129
|
-
### 4. Inconsistent Style APIs
|
|
130
|
-
|
|
131
|
-
**Current problem**: Different widgets accept styles differently:
|
|
132
|
-
|
|
133
|
-
```ruby
|
|
134
|
-
# Table accepts both
|
|
135
|
-
table = Table.new(style: Style.new(fg: :blue))
|
|
136
|
-
table = Table.new(style: { fg: :blue }) # Hash shorthand
|
|
137
|
-
|
|
138
|
-
# But Paragraph doesn't
|
|
139
|
-
paragraph = Paragraph.new(text: "hi", style: Style.new(fg: :blue))
|
|
140
|
-
paragraph = Paragraph.new(text: "hi", style: { fg: :blue }) # Works but undocumented
|
|
141
|
-
|
|
142
|
-
# And Gauge has separate properties
|
|
143
|
-
gauge = Gauge.new(style: Style.new(fg: :blue), gauge_style: Style.new(fg: :green))
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
**Suggested solution**: Standardize style handling across all widgets:
|
|
147
|
-
|
|
148
|
-
1. All widgets should accept `Style` objects and `Hash` shorthand
|
|
149
|
-
2. Document this clearly in each widget
|
|
150
|
-
3. Add a convenience constructor:
|
|
151
|
-
|
|
152
|
-
```ruby
|
|
153
|
-
class Style
|
|
154
|
-
def self.with(fg: nil, bg: nil, modifiers: [])
|
|
155
|
-
Style.new(fg: fg, bg: bg, modifiers: modifiers)
|
|
156
|
-
end
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
# Cleaner than always spelling out keyword args
|
|
160
|
-
paragraph = Paragraph.new(text: "hi", style: Style.with(fg: :blue))
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
### 5. Missing State Query Predicates
|
|
164
|
-
|
|
165
|
-
**Current problem**: Widgets store state but provide no query methods:
|
|
166
|
-
|
|
167
|
-
```ruby
|
|
168
|
-
list.selected_index = 0
|
|
169
|
-
|
|
170
|
-
# To check if something is selected, must do:
|
|
171
|
-
if list.selected_index&.nonzero? # Awkward
|
|
172
|
-
if list.selected_index.nil? == false # Confusing
|
|
173
|
-
|
|
174
|
-
# Should be:
|
|
175
|
-
list.selected? # => true
|
|
176
|
-
list.empty? # => false (for items array)
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
**Suggested solution**: Add predicates to state-holding widgets:
|
|
180
|
-
|
|
181
|
-
```ruby
|
|
182
|
-
# List
|
|
183
|
-
list.selected? # => !selected_index.nil?
|
|
184
|
-
list.empty? # => items.empty?
|
|
185
|
-
list.selection # => selected_index (alias)
|
|
186
|
-
list.selected_item # => items[selected_index] (convenience)
|
|
187
|
-
|
|
188
|
-
# Table
|
|
189
|
-
table.selected_row? # => !selected_row.nil?
|
|
190
|
-
table.selected_cell? # => !selected_row.nil? && !selected_column.nil?
|
|
191
|
-
table.empty? # => rows.empty?
|
|
192
|
-
|
|
193
|
-
# Gauge
|
|
194
|
-
gauge.filled? # => ratio > 0
|
|
195
|
-
gauge.complete? # => ratio >= 1.0
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
### 6. Magic Numeric Coercions
|
|
199
|
-
|
|
200
|
-
**Current problem**: Widgets accept `Numeric` but silently coerce:
|
|
201
|
-
|
|
202
|
-
```ruby
|
|
203
|
-
# These all work, but behavior is undocumented
|
|
204
|
-
list = List.new(selected_index: "2") # Coerced to 2
|
|
205
|
-
list = List.new(selected_index: 2.7) # Coerced to 2
|
|
206
|
-
list = List.new(selected_index: 2.0) # Coerced to 2
|
|
207
|
-
|
|
208
|
-
gauge = Gauge.new(percent: 150) # Should clamp?
|
|
209
|
-
gauge = Gauge.new(ratio: 1.5) # Should clamp?
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
**Suggested solution**:
|
|
213
|
-
|
|
214
|
-
1. Document coercion rules explicitly in RDoc
|
|
215
|
-
2. Add validation and raise on invalid inputs:
|
|
216
|
-
|
|
217
|
-
```ruby
|
|
218
|
-
def initialize(percent: nil, ...)
|
|
219
|
-
if percent
|
|
220
|
-
raise ArgumentError, "percent must be 0..100, got #{percent}" unless percent.between?(0, 100)
|
|
221
|
-
ratio = Float(percent) / 100.0
|
|
222
|
-
end
|
|
223
|
-
end
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
3. Provide clear error messages:
|
|
227
|
-
```ruby
|
|
228
|
-
gauge = Gauge.new(percent: 150)
|
|
229
|
-
# => ArgumentError: percent must be between 0 and 100 (got 150)
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
## Implementation Strategy
|
|
233
|
-
|
|
234
|
-
### Phase 1: Event Improvements (DONE)
|
|
235
|
-
- [x] Add `char` method to Key event
|
|
236
|
-
- [x] Implement dynamic predicates via `method_missing`
|
|
237
|
-
- [x] Update examples to use new API
|
|
238
|
-
|
|
239
|
-
### Phase 2: State Query Predicates
|
|
240
|
-
- [ ] Add predicates to `List` (selected?, empty?, selected_item)
|
|
241
|
-
- [ ] Add predicates to `Table` (selected_row?, selected_cell?, empty?)
|
|
242
|
-
- [ ] Add predicates to `Gauge` (filled?, complete?)
|
|
243
|
-
- [ ] Tests for all new predicates
|
|
244
|
-
|
|
245
|
-
### Phase 3: Symbol Constants
|
|
246
|
-
- [ ] Add enum constants to `List`, `Table`, `Layout`
|
|
247
|
-
- [ ] Add enum constants to `Gauge`, `LineGauge`, `Paragraph`, `Block`
|
|
248
|
-
- [ ] Update all examples to use constants
|
|
249
|
-
- [ ] Document constants in RDoc
|
|
250
|
-
|
|
251
|
-
### Phase 4: Style Consistency
|
|
252
|
-
- [ ] Standardize `Hash` shorthand support across all widgets
|
|
253
|
-
- [ ] Add `Style.with(fg:, bg:, modifiers:)` convenience constructor
|
|
254
|
-
- [ ] Update `.rbs` files to reflect HashStyle support
|
|
255
|
-
- [ ] Document in style guide
|
|
256
|
-
|
|
257
|
-
### Phase 5: Numeric Coercion Validation
|
|
258
|
-
- [ ] Add validation to `Gauge`, `LineGauge`, `List`, `Table`
|
|
259
|
-
- [ ] Raise `ArgumentError` on out-of-range values
|
|
260
|
-
- [ ] Provide clear error messages
|
|
261
|
-
- [ ] Update tests
|
|
262
|
-
|
|
263
|
-
### Phase 6: Convenience Accessors
|
|
264
|
-
- [ ] Add `percent` to `Gauge` and `LineGauge`
|
|
265
|
-
- [ ] Add `selection` alias to `List` and `Table`
|
|
266
|
-
- [ ] Add `selected_item` to `List`
|
|
267
|
-
- [ ] Tests and documentation
|
|
268
|
-
|
|
269
|
-
## Example: Before and After
|
|
270
|
-
|
|
271
|
-
### Before (Confusing)
|
|
272
|
-
```ruby
|
|
273
|
-
class GameApp
|
|
274
|
-
def initialize
|
|
275
|
-
@menu = List.new(
|
|
276
|
-
items: ["Start Game", "Load Game", "Options", "Quit"],
|
|
277
|
-
selected_index: 0,
|
|
278
|
-
highlight_spacing: :when_selected, # What's valid here?
|
|
279
|
-
direction: :top_to_bottom
|
|
280
|
-
)
|
|
281
|
-
end
|
|
282
|
-
|
|
283
|
-
def handle_input(event)
|
|
284
|
-
case event
|
|
285
|
-
when :ctrl_c
|
|
286
|
-
exit
|
|
287
|
-
when :up
|
|
288
|
-
if @menu.selected_index && @menu.selected_index > 0
|
|
289
|
-
@menu = @menu.with(selected_index: @menu.selected_index - 1)
|
|
290
|
-
end
|
|
291
|
-
end
|
|
292
|
-
end
|
|
293
|
-
|
|
294
|
-
def render(tui)
|
|
295
|
-
tui.draw(@menu)
|
|
296
|
-
end
|
|
297
|
-
end
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
### After (DWIM)
|
|
301
|
-
```ruby
|
|
302
|
-
class GameApp
|
|
303
|
-
def initialize
|
|
304
|
-
@menu = List.new(
|
|
305
|
-
items: ["Start Game", "Load Game", "Options", "Quit"],
|
|
306
|
-
selected_index: 0,
|
|
307
|
-
highlight_spacing: List::HIGHLIGHT_WHEN_SELECTED, # IDE autocomplete!
|
|
308
|
-
direction: List::DIRECTION_TOP_TO_BOTTOM
|
|
309
|
-
)
|
|
310
|
-
end
|
|
311
|
-
|
|
312
|
-
def handle_input(event)
|
|
313
|
-
return if event.ctrl_c? # Dynamic predicate!
|
|
314
|
-
|
|
315
|
-
if event.up?
|
|
316
|
-
move_menu_up if @menu.selected? # State predicate!
|
|
317
|
-
end
|
|
318
|
-
end
|
|
319
|
-
|
|
320
|
-
def move_menu_up
|
|
321
|
-
index = @menu.selected_index
|
|
322
|
-
return if index == 0
|
|
323
|
-
@menu = @menu.with(selected_index: index - 1)
|
|
324
|
-
end
|
|
325
|
-
|
|
326
|
-
def render(tui)
|
|
327
|
-
tui.draw(@menu)
|
|
328
|
-
end
|
|
329
|
-
end
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
## Migration Path
|
|
333
|
-
|
|
334
|
-
All changes are backward compatible (additive):
|
|
335
|
-
- Existing code using symbols continues to work
|
|
336
|
-
- New constants coexist with symbols
|
|
337
|
-
- New predicates don't change existing behavior
|
|
338
|
-
- New methods are additions, not replacements
|
|
339
|
-
|
|
340
|
-
Apps can migrate at their own pace:
|
|
341
|
-
```ruby
|
|
342
|
-
# Old style still works
|
|
343
|
-
list = List.new(highlight_spacing: :when_selected)
|
|
344
|
-
|
|
345
|
-
# New style also works
|
|
346
|
-
list = List.new(highlight_spacing: List::HIGHLIGHT_WHEN_SELECTED)
|
|
347
|
-
|
|
348
|
-
# Mix and match
|
|
349
|
-
if list.selected? # New predicate
|
|
350
|
-
puts list.selected_index # Old accessor
|
|
351
|
-
end
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
## Metrics for Success
|
|
355
|
-
|
|
356
|
-
1. **Discoverability**: New developers can find valid options via IDE autocomplete
|
|
357
|
-
2. **Clarity**: Code self-documents valid states and modes
|
|
358
|
-
3. **Type safety**: Constants and predicates provide type checking
|
|
359
|
-
4. **Error feedback**: Invalid inputs raise with helpful messages
|
|
360
|
-
5. **Backward compatibility**: Zero breaking changes, all existing code works
|
|
361
|
-
|
|
362
|
-
## Related Issues
|
|
363
|
-
|
|
364
|
-
- AGENTS.md requirement: All examples must have tests verifying behavior
|
|
365
|
-
- Example improvements: Apply constants and predicates to all example code
|
|
366
|
-
- Documentation: Update style guide with DWIM principles
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
3
|
-
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
4
|
-
-->
|
|
5
|
-
|
|
6
|
-
# Priority 1: High (Polish & Ecosystem)
|
|
7
|
-
|
|
8
|
-
Important for v1.0.0 quality and ecosystem goals. Not blocking release, but recommended before ship.
|
|
9
|
-
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## 1. Ensure All Widgets Have Examples
|
|
13
|
-
|
|
14
|
-
**Status:** Done
|
|
15
|
-
|
|
16
|
-
Verified that all widget types shipped with ratatui_ruby have at least one example showing how to use them.
|
|
17
|
-
|
|
18
|
-
**Action:**
|
|
19
|
-
- [x] Check widget manifest against example inventory
|
|
20
|
-
- [x] Create `widget_canvas_demo`, `widget_center_demo`, and `widget_overlay_demo`
|
|
21
|
-
|