ratatui_ruby 0.3.0 → 0.4.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.
Files changed (302) hide show
  1. checksums.yaml +4 -4
  2. data/.builds/ruby-3.2.yml +15 -13
  3. data/.builds/ruby-3.3.yml +15 -13
  4. data/.builds/ruby-3.4.yml +15 -13
  5. data/.builds/ruby-4.0.0.yml +18 -17
  6. data/AGENTS.md +85 -37
  7. data/CHANGELOG.md +193 -1
  8. data/README.md +19 -17
  9. data/REUSE.toml +0 -5
  10. data/doc/application_architecture.md +116 -0
  11. data/doc/application_testing.md +12 -7
  12. data/doc/contributors/better_dx.md +543 -0
  13. data/doc/contributors/design/ruby_frontend.md +1 -1
  14. data/doc/contributors/developing_examples.md +203 -0
  15. data/doc/contributors/documentation_style.md +97 -0
  16. data/doc/contributors/dwim_dx.md +366 -0
  17. data/doc/contributors/example_analysis.md +82 -0
  18. data/doc/custom.css +14 -0
  19. data/doc/event_handling.md +119 -0
  20. data/doc/images/all_events.png +0 -0
  21. data/doc/images/analytics.png +0 -0
  22. data/doc/images/block_padding.png +0 -0
  23. data/doc/images/block_titles.png +0 -0
  24. data/doc/images/box_demo.png +0 -0
  25. data/doc/images/calendar_demo.png +0 -0
  26. data/doc/images/cell_demo.png +0 -0
  27. data/doc/images/chart_demo.png +0 -0
  28. data/doc/images/custom_widget.png +0 -0
  29. data/doc/images/flex_layout.png +0 -0
  30. data/doc/images/gauge_demo.png +0 -0
  31. data/doc/images/hit_test.png +0 -0
  32. data/doc/images/line_gauge_demo.png +0 -0
  33. data/doc/images/list_demo.png +0 -0
  34. data/doc/images/list_styles.png +0 -0
  35. data/doc/images/login_form.png +0 -0
  36. data/doc/images/map_demo.png +0 -0
  37. data/doc/images/mouse_events.png +0 -0
  38. data/doc/images/popup_demo.png +0 -0
  39. data/doc/images/quickstart_dsl.png +0 -0
  40. data/doc/images/quickstart_lifecycle.png +0 -0
  41. data/doc/images/ratatui_logo_demo.png +0 -0
  42. data/doc/images/readme_usage.png +0 -0
  43. data/doc/images/rich_text.png +0 -0
  44. data/doc/images/scroll_text.png +0 -0
  45. data/doc/images/scrollbar_demo.png +0 -0
  46. data/doc/images/sparkline_demo.png +0 -0
  47. data/doc/images/table_flex.png +0 -0
  48. data/doc/images/table_select.png +0 -0
  49. data/doc/images/widget_style_colors.png +0 -0
  50. data/doc/index.md +1 -0
  51. data/doc/interactive_design.md +121 -0
  52. data/doc/quickstart.md +147 -72
  53. data/examples/all_events/app.rb +169 -0
  54. data/examples/all_events/app.rbs +7 -0
  55. data/examples/all_events/test_app.rb +139 -0
  56. data/examples/analytics/app.rb +258 -0
  57. data/examples/analytics/app.rbs +7 -0
  58. data/examples/analytics/test_app.rb +132 -0
  59. data/examples/block_padding/app.rb +63 -0
  60. data/examples/block_padding/app.rbs +7 -0
  61. data/examples/block_padding/test_app.rb +31 -0
  62. data/examples/block_titles/app.rb +61 -0
  63. data/examples/block_titles/app.rbs +7 -0
  64. data/examples/block_titles/test_app.rb +34 -0
  65. data/examples/box_demo/app.rb +216 -0
  66. data/examples/box_demo/app.rbs +7 -0
  67. data/examples/box_demo/test_app.rb +88 -0
  68. data/examples/calendar_demo/app.rb +101 -0
  69. data/examples/calendar_demo/app.rbs +7 -0
  70. data/examples/calendar_demo/test_app.rb +108 -0
  71. data/examples/cell_demo/app.rb +108 -0
  72. data/examples/cell_demo/app.rbs +7 -0
  73. data/examples/cell_demo/test_app.rb +36 -0
  74. data/examples/chart_demo/app.rb +203 -0
  75. data/examples/chart_demo/app.rbs +7 -0
  76. data/examples/chart_demo/test_app.rb +102 -0
  77. data/examples/custom_widget/app.rb +51 -0
  78. data/examples/custom_widget/app.rbs +7 -0
  79. data/examples/custom_widget/test_app.rb +30 -0
  80. data/examples/flex_layout/app.rb +156 -0
  81. data/examples/flex_layout/app.rbs +7 -0
  82. data/examples/flex_layout/test_app.rb +65 -0
  83. data/examples/gauge_demo/app.rb +182 -0
  84. data/examples/gauge_demo/app.rbs +7 -0
  85. data/examples/gauge_demo/test_app.rb +120 -0
  86. data/examples/hit_test/app.rb +175 -0
  87. data/examples/hit_test/app.rbs +7 -0
  88. data/examples/hit_test/test_app.rb +102 -0
  89. data/examples/line_gauge_demo/app.rb +190 -0
  90. data/examples/line_gauge_demo/app.rbs +7 -0
  91. data/examples/line_gauge_demo/test_app.rb +129 -0
  92. data/examples/list_demo/app.rb +253 -0
  93. data/examples/list_demo/app.rbs +12 -0
  94. data/examples/list_demo/test_app.rb +237 -0
  95. data/examples/list_styles/app.rb +140 -0
  96. data/examples/list_styles/app.rbs +7 -0
  97. data/examples/list_styles/test_app.rb +157 -0
  98. data/examples/{login_form.rb → login_form/app.rb} +12 -16
  99. data/examples/login_form/app.rbs +7 -0
  100. data/examples/login_form/test_app.rb +51 -0
  101. data/examples/map_demo/app.rb +90 -0
  102. data/examples/map_demo/app.rbs +7 -0
  103. data/examples/map_demo/test_app.rb +149 -0
  104. data/examples/{mouse_events.rb → mouse_events/app.rb} +29 -27
  105. data/examples/mouse_events/app.rbs +7 -0
  106. data/examples/mouse_events/test_app.rb +53 -0
  107. data/examples/{popup_demo.rb → popup_demo/app.rb} +15 -17
  108. data/examples/popup_demo/app.rbs +7 -0
  109. data/examples/{test_popup_demo.rb → popup_demo/test_app.rb} +18 -26
  110. data/examples/quickstart_dsl/app.rb +36 -0
  111. data/examples/quickstart_dsl/app.rbs +7 -0
  112. data/examples/quickstart_dsl/test_app.rb +29 -0
  113. data/examples/quickstart_lifecycle/app.rb +39 -0
  114. data/examples/quickstart_lifecycle/app.rbs +7 -0
  115. data/examples/quickstart_lifecycle/test_app.rb +29 -0
  116. data/examples/ratatui_logo_demo/app.rb +79 -0
  117. data/examples/ratatui_logo_demo/app.rbs +7 -0
  118. data/examples/ratatui_logo_demo/test_app.rb +51 -0
  119. data/examples/ratatui_mascot_demo/app.rb +84 -0
  120. data/examples/ratatui_mascot_demo/app.rbs +7 -0
  121. data/examples/ratatui_mascot_demo/test_app.rb +47 -0
  122. data/examples/readme_usage/app.rb +29 -0
  123. data/examples/readme_usage/app.rbs +7 -0
  124. data/examples/readme_usage/test_app.rb +29 -0
  125. data/examples/rich_text/app.rb +141 -0
  126. data/examples/rich_text/app.rbs +7 -0
  127. data/examples/rich_text/test_app.rb +166 -0
  128. data/examples/scroll_text/app.rb +103 -0
  129. data/examples/scroll_text/app.rbs +7 -0
  130. data/examples/scroll_text/test_app.rb +110 -0
  131. data/examples/scrollbar_demo/app.rb +143 -0
  132. data/examples/scrollbar_demo/app.rbs +7 -0
  133. data/examples/scrollbar_demo/test_app.rb +77 -0
  134. data/examples/sparkline_demo/app.rb +240 -0
  135. data/examples/sparkline_demo/app.rbs +10 -0
  136. data/examples/sparkline_demo/test_app.rb +107 -0
  137. data/examples/table_flex/app.rb +65 -0
  138. data/examples/table_flex/app.rbs +7 -0
  139. data/examples/table_flex/test_app.rb +36 -0
  140. data/examples/table_select/app.rb +198 -0
  141. data/examples/table_select/app.rbs +7 -0
  142. data/examples/table_select/test_app.rb +180 -0
  143. data/examples/widget_style_colors/app.rb +104 -0
  144. data/examples/widget_style_colors/app.rbs +14 -0
  145. data/examples/widget_style_colors/test_app.rb +48 -0
  146. data/ext/ratatui_ruby/Cargo.lock +889 -115
  147. data/ext/ratatui_ruby/Cargo.toml +4 -3
  148. data/ext/ratatui_ruby/clippy.toml +7 -0
  149. data/ext/ratatui_ruby/extconf.rb +7 -0
  150. data/ext/ratatui_ruby/src/events.rs +218 -229
  151. data/ext/ratatui_ruby/src/lib.rs +38 -10
  152. data/ext/ratatui_ruby/src/rendering.rs +91 -10
  153. data/ext/ratatui_ruby/src/style.rs +281 -98
  154. data/ext/ratatui_ruby/src/terminal.rs +119 -25
  155. data/ext/ratatui_ruby/src/text.rs +171 -0
  156. data/ext/ratatui_ruby/src/widgets/barchart.rs +97 -24
  157. data/ext/ratatui_ruby/src/widgets/block.rs +31 -3
  158. data/ext/ratatui_ruby/src/widgets/calendar.rs +45 -44
  159. data/ext/ratatui_ruby/src/widgets/canvas.rs +46 -29
  160. data/ext/ratatui_ruby/src/widgets/chart.rs +69 -27
  161. data/ext/ratatui_ruby/src/widgets/clear.rs +3 -1
  162. data/ext/ratatui_ruby/src/widgets/gauge.rs +11 -4
  163. data/ext/ratatui_ruby/src/widgets/layout.rs +218 -15
  164. data/ext/ratatui_ruby/src/widgets/line_gauge.rs +92 -0
  165. data/ext/ratatui_ruby/src/widgets/list.rs +91 -11
  166. data/ext/ratatui_ruby/src/widgets/mod.rs +3 -0
  167. data/ext/ratatui_ruby/src/widgets/overlay.rs +3 -2
  168. data/ext/ratatui_ruby/src/widgets/paragraph.rs +35 -13
  169. data/ext/ratatui_ruby/src/widgets/ratatui_logo.rs +29 -0
  170. data/ext/ratatui_ruby/src/widgets/ratatui_mascot.rs +44 -0
  171. data/ext/ratatui_ruby/src/widgets/scrollbar.rs +59 -7
  172. data/ext/ratatui_ruby/src/widgets/sparkline.rs +70 -6
  173. data/ext/ratatui_ruby/src/widgets/table.rs +173 -64
  174. data/ext/ratatui_ruby/src/widgets/tabs.rs +105 -5
  175. data/lib/ratatui_ruby/cell.rb +166 -0
  176. data/lib/ratatui_ruby/event/focus_gained.rb +49 -0
  177. data/lib/ratatui_ruby/event/focus_lost.rb +50 -0
  178. data/lib/ratatui_ruby/event/key.rb +211 -0
  179. data/lib/ratatui_ruby/event/mouse.rb +124 -0
  180. data/lib/ratatui_ruby/event/paste.rb +71 -0
  181. data/lib/ratatui_ruby/event/resize.rb +80 -0
  182. data/lib/ratatui_ruby/event.rb +79 -0
  183. data/lib/ratatui_ruby/schema/bar_chart/bar.rb +45 -0
  184. data/lib/ratatui_ruby/schema/bar_chart/bar_group.rb +27 -0
  185. data/lib/ratatui_ruby/schema/bar_chart.rb +228 -19
  186. data/lib/ratatui_ruby/schema/block.rb +186 -14
  187. data/lib/ratatui_ruby/schema/calendar.rb +74 -17
  188. data/lib/ratatui_ruby/schema/canvas.rb +215 -48
  189. data/lib/ratatui_ruby/schema/center.rb +49 -11
  190. data/lib/ratatui_ruby/schema/chart.rb +151 -41
  191. data/lib/ratatui_ruby/schema/clear.rb +41 -72
  192. data/lib/ratatui_ruby/schema/constraint.rb +82 -22
  193. data/lib/ratatui_ruby/schema/cursor.rb +27 -9
  194. data/lib/ratatui_ruby/schema/draw.rb +53 -0
  195. data/lib/ratatui_ruby/schema/gauge.rb +59 -15
  196. data/lib/ratatui_ruby/schema/layout.rb +95 -13
  197. data/lib/ratatui_ruby/schema/line_gauge.rb +78 -0
  198. data/lib/ratatui_ruby/schema/list.rb +93 -19
  199. data/lib/ratatui_ruby/schema/overlay.rb +34 -8
  200. data/lib/ratatui_ruby/schema/paragraph.rb +87 -30
  201. data/lib/ratatui_ruby/schema/ratatui_logo.rb +25 -0
  202. data/lib/ratatui_ruby/schema/ratatui_mascot.rb +29 -0
  203. data/lib/ratatui_ruby/schema/rect.rb +64 -15
  204. data/lib/ratatui_ruby/schema/scrollbar.rb +132 -24
  205. data/lib/ratatui_ruby/schema/shape/label.rb +66 -0
  206. data/lib/ratatui_ruby/schema/sparkline.rb +122 -15
  207. data/lib/ratatui_ruby/schema/style.rb +49 -21
  208. data/lib/ratatui_ruby/schema/table.rb +119 -21
  209. data/lib/ratatui_ruby/schema/tabs.rb +75 -13
  210. data/lib/ratatui_ruby/schema/text.rb +90 -0
  211. data/lib/ratatui_ruby/session.rb +146 -0
  212. data/lib/ratatui_ruby/test_helper.rb +156 -13
  213. data/lib/ratatui_ruby/version.rb +1 -1
  214. data/lib/ratatui_ruby.rb +143 -23
  215. data/mise.toml +1 -1
  216. data/sig/ratatui_ruby/event.rbs +69 -0
  217. data/sig/ratatui_ruby/ratatui_ruby.rbs +2 -1
  218. data/sig/ratatui_ruby/schema/bar_chart/bar.rbs +16 -0
  219. data/sig/ratatui_ruby/schema/bar_chart/bar_group.rbs +13 -0
  220. data/sig/ratatui_ruby/schema/bar_chart.rbs +20 -2
  221. data/sig/ratatui_ruby/schema/block.rbs +5 -4
  222. data/sig/ratatui_ruby/schema/calendar.rbs +6 -2
  223. data/sig/ratatui_ruby/schema/canvas.rbs +52 -39
  224. data/sig/ratatui_ruby/schema/center.rbs +3 -3
  225. data/sig/ratatui_ruby/schema/chart.rbs +8 -5
  226. data/sig/ratatui_ruby/schema/constraint.rbs +8 -5
  227. data/sig/ratatui_ruby/schema/cursor.rbs +1 -1
  228. data/sig/ratatui_ruby/schema/draw.rbs +23 -0
  229. data/sig/ratatui_ruby/schema/gauge.rbs +4 -2
  230. data/sig/ratatui_ruby/schema/layout.rbs +11 -1
  231. data/sig/ratatui_ruby/schema/line_gauge.rbs +16 -0
  232. data/sig/ratatui_ruby/schema/list.rbs +5 -1
  233. data/sig/ratatui_ruby/schema/paragraph.rbs +4 -1
  234. data/{lib/ratatui_ruby/output.rb → sig/ratatui_ruby/schema/ratatui_logo.rbs} +3 -2
  235. data/sig/ratatui_ruby/{buffer.rbs → schema/ratatui_mascot.rbs} +4 -3
  236. data/sig/ratatui_ruby/schema/rect.rbs +2 -1
  237. data/sig/ratatui_ruby/schema/scrollbar.rbs +18 -2
  238. data/sig/ratatui_ruby/schema/sparkline.rbs +6 -2
  239. data/sig/ratatui_ruby/schema/table.rbs +8 -1
  240. data/sig/ratatui_ruby/schema/tabs.rbs +5 -1
  241. data/sig/ratatui_ruby/schema/text.rbs +22 -0
  242. data/tasks/resources/build.yml.erb +13 -24
  243. data/tasks/terminal_preview/app_screenshot.rb +35 -0
  244. data/tasks/terminal_preview/crash_report.rb +54 -0
  245. data/tasks/terminal_preview/example_app.rb +25 -0
  246. data/tasks/terminal_preview/launcher_script.rb +48 -0
  247. data/tasks/terminal_preview/preview_collection.rb +60 -0
  248. data/tasks/terminal_preview/preview_timing.rb +22 -0
  249. data/tasks/terminal_preview/safety_confirmation.rb +58 -0
  250. data/tasks/terminal_preview/saved_screenshot.rb +55 -0
  251. data/tasks/terminal_preview/system_appearance.rb +11 -0
  252. data/tasks/terminal_preview/terminal_window.rb +138 -0
  253. data/tasks/terminal_preview/window_id.rb +14 -0
  254. data/tasks/terminal_preview.rake +28 -0
  255. data/tasks/test.rake +1 -1
  256. metadata +175 -54
  257. data/doc/images/examples-analytics.rb.png +0 -0
  258. data/doc/images/examples-box_demo.rb.png +0 -0
  259. data/doc/images/examples-calendar_demo.rb.png +0 -0
  260. data/doc/images/examples-chart_demo.rb.png +0 -0
  261. data/doc/images/examples-custom_widget.rb.png +0 -0
  262. data/doc/images/examples-dashboard.rb.png +0 -0
  263. data/doc/images/examples-list_styles.rb.png +0 -0
  264. data/doc/images/examples-login_form.rb.png +0 -0
  265. data/doc/images/examples-map_demo.rb.png +0 -0
  266. data/doc/images/examples-mouse_events.rb.png +0 -0
  267. data/doc/images/examples-popup_demo.rb.gif +0 -0
  268. data/doc/images/examples-quickstart_lifecycle.rb.png +0 -0
  269. data/doc/images/examples-scroll_text.rb.png +0 -0
  270. data/doc/images/examples-scrollbar_demo.rb.png +0 -0
  271. data/doc/images/examples-stock_ticker.rb.png +0 -0
  272. data/doc/images/examples-system_monitor.rb.png +0 -0
  273. data/doc/images/examples-table_select.rb.png +0 -0
  274. data/examples/analytics.rb +0 -88
  275. data/examples/box_demo.rb +0 -71
  276. data/examples/calendar_demo.rb +0 -55
  277. data/examples/chart_demo.rb +0 -84
  278. data/examples/custom_widget.rb +0 -43
  279. data/examples/dashboard.rb +0 -72
  280. data/examples/list_styles.rb +0 -66
  281. data/examples/map_demo.rb +0 -58
  282. data/examples/quickstart_dsl.rb +0 -30
  283. data/examples/quickstart_lifecycle.rb +0 -40
  284. data/examples/readme_usage.rb +0 -21
  285. data/examples/scroll_text.rb +0 -74
  286. data/examples/scrollbar_demo.rb +0 -75
  287. data/examples/stock_ticker.rb +0 -93
  288. data/examples/system_monitor.rb +0 -94
  289. data/examples/table_select.rb +0 -70
  290. data/examples/test_analytics.rb +0 -65
  291. data/examples/test_box_demo.rb +0 -38
  292. data/examples/test_calendar_demo.rb +0 -66
  293. data/examples/test_dashboard.rb +0 -38
  294. data/examples/test_list_styles.rb +0 -61
  295. data/examples/test_login_form.rb +0 -63
  296. data/examples/test_map_demo.rb +0 -100
  297. data/examples/test_scroll_text.rb +0 -130
  298. data/examples/test_stock_ticker.rb +0 -39
  299. data/examples/test_system_monitor.rb +0 -40
  300. data/examples/test_table_select.rb +0 -37
  301. data/ext/ratatui_ruby/src/buffer.rs +0 -54
  302. data/lib/ratatui_ruby/dsl.rb +0 -64
data/README.md CHANGED
@@ -9,7 +9,7 @@ builds.sr.ht status](https://builds.sr.ht/~kerrick/ratatui_ruby.svg)](https://bu
9
9
  License](https://img.shields.io/badge/dynamic/regex?url=https%3A%2F%2Fgit.sr.ht%2F~kerrick%2Fratatui_ruby%2Fblob%2Fmain%2Fratatui_ruby.gemspec&search=spec%5C.license%20%3D%20%22(.*)%22&replace=%241&label=License&color=a2c93e)](https://spdx.org/licenses/AGPL-3.0-or-later.html) [![
10
10
  Gem Total Downloads](https://img.shields.io/gem/dt/ratatui_ruby)](https://rubygems.org/gems/ratatui_ruby) [![
11
11
  Gem Version](https://img.shields.io/gem/v/ratatui_ruby)](https://rubygems.org/gems/ratatui_ruby) [![
12
- Ratatui Version](https://img.shields.io/badge/dynamic/toml?url=https%3A%2F%2Fgit.sr.ht%2F~kerrick%2Fratatui_ruby%2Fblob%2Fmain%2Fext%2Fratatui_ruby%2FCargo.toml&query=%24.dependencies.ratatui.version&prefix=v&logo=ratatui&label=Ratatui)](https://crates.io/crates/ratatui/0.26.3) [![
12
+ Ratatui Version](https://img.shields.io/badge/dynamic/toml?url=https%3A%2F%2Fgit.sr.ht%2F~kerrick%2Fratatui_ruby%2Fblob%2Fmain%2Fext%2Fratatui_ruby%2FCargo.toml&query=%24.dependencies.ratatui.version&prefix=v&logo=ratatui&label=Ratatui)](https://crates.io/crates/ratatui/0.30) [![
13
13
  Mailing List: Discussion](https://img.shields.io/badge/mailing_list-discussion-5865F2.svg?logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNmZmZmZmYiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBjbGFzcz0iaWNvbiBpY29uLXRhYmxlciBpY29ucy10YWJsZXItb3V0bGluZSBpY29uLXRhYmxlci1tYWlsIj48cGF0aCBzdHJva2U9Im5vbmUiIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz48cGF0aCBkPSJNMyA3YTIgMiAwIDAgMSAyIC0yaDE0YTIgMiAwIDAgMSAyIDJ2MTBhMiAyIDAgMCAxIC0yIDJoLTE0YTIgMiAwIDAgMSAtMiAtMnYtMTB6IiAvPjxwYXRoIGQ9Ik0zIDdsOSA2bDkgLTYiIC8+PC9zdmc+Cg==)](https://lists.sr.ht/~kerrick/ratatui_ruby-discuss) [![
14
14
  Mailing List: Development](https://img.shields.io/badge/mailing_list-development-4954d5.svg?logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNmZmZmZmYiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBjbGFzcz0iaWNvbiBpY29uLXRhYmxlciBpY29ucy10YWJsZXItb3V0bGluZSBpY29uLXRhYmxlci1tYWlsIj48cGF0aCBzdHJva2U9Im5vbmUiIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz48cGF0aCBkPSJNMyA3YTIgMiAwIDAgMSAyIC0yaDE0YTIgMiAwIDAgMSAyIDJ2MTBhMiAyIDAgMCAxIC0yIDJoLTE0YTIgMiAwIDAgMSAtMiAtMnYtMTB6IiAvPjxwYXRoIGQ9Ik0zIDdsOSA2bDkgLTYiIC8+PC9zdmc+Cg==)](https://lists.sr.ht/~kerrick/ratatui_ruby-devel) [![
15
15
  Mailing List: Announcements](https://img.shields.io/badge/mailing_list-announcements-3b44ac.svg?logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNmZmZmZmYiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBjbGFzcz0iaWNvbiBpY29uLXRhYmxlciBpY29ucy10YWJsZXItb3V0bGluZSBpY29uLXRhYmxlci1tYWlsIj48cGF0aCBzdHJva2U9Im5vbmUiIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz48cGF0aCBkPSJNMyA3YTIgMiAwIDAgMSAyIC0yaDE0YTIgMiAwIDAgMSAyIDJ2MTBhMiAyIDAgMCAxIC0yIDJoLTE0YTIgMiAwIDAgMSAtMiAtMnYtMTB6IiAvPjxwYXRoIGQ9Ik0zIDdsOSA2bDkgLTYiIC8+PC9zdmc+Cg==)](https://lists.sr.ht/~kerrick/ratatui_ruby-announce)
@@ -21,7 +21,7 @@ Mailing List: Announcements](https://img.shields.io/badge/mailing_list-announcem
21
21
  **ratatui_ruby** is a community wrapper that is not affiliated with [the Ratatui team](https://github.com/orgs/ratatui/people).
22
22
 
23
23
  > [!WARNING]
24
- > **ratatui_ruby** is currently in an early stage of development. Use at your own risk.
24
+ > **ratatui_ruby** is currently in **BETA**. The API may change between minor versions.
25
25
 
26
26
  Please join the **announce** mailing list at https://lists.sr.ht/~kerrick/ratatui_ruby-announce to stay up-to-date on new releases and announcements.
27
27
 
@@ -34,8 +34,8 @@ Please join the **announce** mailing list at https://lists.sr.ht/~kerrick/ratatu
34
34
  - x86_64 (AMD, Intel) and ARM (Apple Silicon, Raspberry Pi).
35
35
 
36
36
  We support the latest minor version of every
37
- [non-eol Ruby version](https://www.ruby-lang.org/en/downloads/branches/).
38
- Support for Ruby 4 is coming soon.
37
+ [non-eol Ruby version](https://www.ruby-lang.org/en/downloads/branches/),
38
+ including Ruby 4.
39
39
 
40
40
 
41
41
  ## Installation
@@ -65,22 +65,24 @@ gem install ratatui_ruby
65
65
 
66
66
  ```ruby
67
67
  require "ratatui_ruby"
68
- RatatuiRuby.main_loop do |tui|
69
- tui.draw \
70
- tui.paragraph \
71
- text: "Hello, Ratatui! Press 'q' to quit.",
72
- align: :center,
73
- block: tui.block(
74
- title: "My Ruby TUI App",
75
- borders: [:all],
76
- border_color: "cyan"
77
- )
78
- event = tui.poll_event
79
- break if event && event[:type] == :key && event[:code] == "q"
68
+ RatatuiRuby.run do |tui|
69
+ loop do
70
+ tui.draw \
71
+ tui.paragraph \
72
+ text: "Hello, Ratatui! Press 'q' to quit.",
73
+ alignment: :center,
74
+ block: tui.block(
75
+ title: "My Ruby TUI App",
76
+ borders: [:all],
77
+ border_color: "cyan"
78
+ )
79
+ event = tui.poll_event
80
+ break if event == "q" || event == :ctrl_c
81
+ end
80
82
  end
81
83
  ```
82
84
 
83
- For a full tutorial, see [the Quickstart](./doc/quickstart.md).
85
+ For a full tutorial, see [the Quickstart](./doc/quickstart.md). For an explanation of the application architecture, see [Application Architecture](./doc/application_architecture.md).
84
86
 
85
87
 
86
88
  ## Documentation
data/REUSE.toml CHANGED
@@ -1,10 +1,5 @@
1
1
  version = 1
2
2
 
3
- [[annotations]]
4
- path = '.ruby-version'
5
- SPDX-FileCopyrightText = "2025 Kerrick Long <me@kerricklong.com>"
6
- SPDX-License-Identifier = "CC0-1.0"
7
-
8
3
  [[annotations]]
9
4
  path = 'Gemfile.lock'
10
5
  SPDX-FileCopyrightText = "2025 Kerrick Long <me@kerricklong.com>"
@@ -0,0 +1,116 @@
1
+ # Core Concepts
2
+
3
+ This guide explains the core concepts and patterns available in `ratatui_ruby` for structuring your terminal applications.
4
+
5
+ ## 1. Lifecycle Management
6
+
7
+ Managing the terminal state is critical. You must enter "alternate screen" and "raw mode" on startup, and **always** restore the terminal on exit (even on errors), otherwise the user's terminal will be left in a broken state.
8
+
9
+ ### `RatatuiRuby.run` (Recommended)
10
+
11
+ The `run` method acts as a **Context Manager**. It handles the initialization and restoration for you, ensuring the terminal is always restored even if your code raises an exception. We recommend using `run` for all applications, as it provides a safe sandbox for your TUI.
12
+
13
+ ```ruby
14
+ RatatuiRuby.run do |tui|
15
+ loop do
16
+ # Your code here
17
+ tui.draw(...)
18
+ end
19
+ end
20
+ # Terminal is restored here
21
+ ```
22
+
23
+ ### Manual Management (Advanced)
24
+
25
+ You can manage this manually if you need granular control, but use `ensure` blocks!
26
+
27
+ ```ruby
28
+ RatatuiRuby.init_terminal
29
+ begin
30
+ # Your code here
31
+ RatatuiRuby.draw(...)
32
+ ensure
33
+ RatatuiRuby.restore_terminal
34
+ end
35
+ ```
36
+
37
+ ## 2. API Convenience
38
+
39
+ ### Session API (Recommended)
40
+
41
+ The block yielded by `run` is a `RatatuiRuby::Session` instance (`tui`).
42
+ It provides factory methods for every widget class (converting snake_case to CamelCase) and aliases for module functions.
43
+
44
+ **Why use it?** It significantly reduces verbosity and repeated `RatatuiRuby::` namespacing, making the UI tree structure easier to read.
45
+
46
+ ```ruby
47
+ RatatuiRuby.run do |tui|
48
+ loop do
49
+ layout = tui.layout(
50
+ direction: :horizontal,
51
+ constraints: [
52
+ RatatuiRuby::Constraint.length(20),
53
+ RatatuiRuby::Constraint.min(0)
54
+ ],
55
+ children: [
56
+ tui.paragraph(
57
+ text: tui.text_line(spans: [
58
+ tui.text_span(content: "Side", style: tui.style(fg: :blue)),
59
+ tui.text_span(content: "bar")
60
+ ]),
61
+ block: tui.block(borders: [:all], title: "Nav")
62
+ ),
63
+ tui.paragraph(
64
+ text: "Main Content",
65
+ style: tui.style(fg: :green),
66
+ block: tui.block(borders: [:all], title: "Content")
67
+ )
68
+ ]
69
+ )
70
+
71
+ tui.draw(layout)
72
+
73
+ event = tui.poll_event
74
+ break if event == "q" || event == :ctrl_c
75
+ end
76
+ end
77
+ ```
78
+
79
+ ### Raw API
80
+
81
+ You can always use the raw module methods and classes directly. This is useful if you are building your own abstractions or prefer explicit class instantiation.
82
+
83
+ **Comparison:** Notice how much more verbose the same UI definition is.
84
+
85
+ ```ruby
86
+ RatatuiRuby.run do
87
+ loop do
88
+ layout = RatatuiRuby::Layout.new(
89
+ direction: :horizontal,
90
+ constraints: [
91
+ RatatuiRuby::Constraint.length(20),
92
+ RatatuiRuby::Constraint.min(0)
93
+ ],
94
+ children: [
95
+ RatatuiRuby::Paragraph.new(
96
+ text: RatatuiRuby::Text::Line.new(spans: [
97
+ RatatuiRuby::Text::Span.new(content: "Side", style: RatatuiRuby::Style.new(fg: :blue)),
98
+ RatatuiRuby::Text::Span.new(content: "bar")
99
+ ]),
100
+ block: RatatuiRuby::Block.new(borders: [:all], title: "Nav")
101
+ ),
102
+ RatatuiRuby::Paragraph.new(
103
+ text: "Main Content",
104
+ style: RatatuiRuby::Style.new(fg: :green),
105
+ block: RatatuiRuby::Block.new(borders: [:all], title: "Content")
106
+ )
107
+ ]
108
+ )
109
+
110
+ RatatuiRuby.draw(layout)
111
+
112
+ event = RatatuiRuby.poll_event
113
+ break if event == "q" || event == :ctrl_c
114
+ end
115
+ end
116
+ ```
@@ -44,8 +44,8 @@ Wrap your test assertions in `with_test_terminal`. This sets up a temporary, in-
44
44
 
45
45
  ```ruby
46
46
  def test_rendering
47
- # Create a 80x24 terminal
48
- with_test_terminal(80, 24) do
47
+ # Uses default 80x24 terminal
48
+ with_test_terminal do
49
49
  # 1. Instantiate your app/component
50
50
  widget = RatatuiRuby::Paragraph.new(text: "Hello World")
51
51
 
@@ -82,13 +82,18 @@ assert_equal 2, pos[:y]
82
82
 
83
83
  Injects a mock event into the event queue. This is the preferred way to simulate user input instead of stubbing `poll_event`.
84
84
 
85
+ > [!IMPORTANT]
86
+ > You must call `inject_event` inside a `with_test_terminal` block. Calling it outside leads to race conditions where events are flushed before the application starts.
87
+
85
88
  ```ruby
86
- # Simulate 'q' key press
87
- inject_event("key", { code: "q" })
89
+ with_test_terminal do
90
+ # Simulate 'q' key press
91
+ inject_event("key", { code: "q" })
88
92
 
89
- # Now poll_event will return the 'q' key event
90
- event = RatatuiRuby.poll_event
91
- assert_equal "q", event[:code]
93
+ # Now poll_event will return the 'q' key event
94
+ event = RatatuiRuby.poll_event
95
+ assert_equal "q", event.code
96
+ end
92
97
  ```
93
98
 
94
99
  ## Example