ratatui_ruby 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (441) hide show
  1. checksums.yaml +4 -4
  2. data/.builds/ruby-3.2.yml +1 -1
  3. data/.builds/ruby-3.3.yml +1 -1
  4. data/.builds/ruby-3.4.yml +1 -1
  5. data/.builds/ruby-4.0.0.yml +1 -1
  6. data/AGENTS.md +98 -176
  7. data/CHANGELOG.md +80 -6
  8. data/README.md +19 -7
  9. data/REUSE.toml +15 -0
  10. data/doc/application_architecture.md +179 -45
  11. data/doc/application_testing.md +80 -32
  12. data/doc/contributors/design/ruby_frontend.md +48 -8
  13. data/doc/contributors/design/rust_backend.md +1 -0
  14. data/doc/contributors/developing_examples.md +191 -48
  15. data/doc/contributors/documentation_style.md +7 -0
  16. data/doc/contributors/examples_audit/p1_high.md +21 -0
  17. data/doc/contributors/examples_audit/p2_moderate.md +81 -0
  18. data/doc/contributors/examples_audit.md +41 -0
  19. data/doc/contributors/index.md +2 -0
  20. data/doc/event_handling.md +21 -7
  21. data/doc/images/app_all_events.png +0 -0
  22. data/doc/images/app_color_picker.png +0 -0
  23. data/doc/images/app_login_form.png +0 -0
  24. data/doc/images/app_stateful_interaction.png +0 -0
  25. data/doc/images/verify_quickstart_dsl.png +0 -0
  26. data/doc/images/verify_quickstart_layout.png +0 -0
  27. data/doc/images/verify_quickstart_lifecycle.png +0 -0
  28. data/doc/images/verify_readme_usage.png +0 -0
  29. data/doc/images/widget_barchart_demo.png +0 -0
  30. data/doc/images/widget_block_demo.png +0 -0
  31. data/doc/images/widget_box_demo.png +0 -0
  32. data/doc/images/widget_calendar_demo.png +0 -0
  33. data/doc/images/widget_canvas_demo.png +0 -0
  34. data/doc/images/widget_cell_demo.png +0 -0
  35. data/doc/images/widget_center_demo.png +0 -0
  36. data/doc/images/widget_chart_demo.png +0 -0
  37. data/doc/images/widget_gauge_demo.png +0 -0
  38. data/doc/images/widget_layout_split.png +0 -0
  39. data/doc/images/widget_line_gauge_demo.png +0 -0
  40. data/doc/images/widget_list_demo.png +0 -0
  41. data/doc/images/widget_overlay_demo.png +0 -0
  42. data/doc/images/widget_ratatui_logo_demo.png +0 -0
  43. data/doc/images/widget_ratatui_mascot_demo.png +0 -0
  44. data/doc/images/widget_render.png +0 -0
  45. data/doc/images/widget_rich_text.png +0 -0
  46. data/doc/images/widget_scroll_text.png +0 -0
  47. data/doc/images/widget_scrollbar_demo.png +0 -0
  48. data/doc/images/widget_sparkline_demo.png +0 -0
  49. data/doc/images/widget_style_colors.png +0 -0
  50. data/doc/images/widget_table_demo.png +0 -0
  51. data/doc/images/widget_table_flex.png +0 -0
  52. data/doc/images/widget_tabs_demo.png +0 -0
  53. data/doc/images/widget_text_width.png +0 -0
  54. data/doc/interactive_design.md +25 -30
  55. data/doc/quickstart.md +150 -130
  56. data/doc/terminal_limitations.md +92 -0
  57. data/examples/app_all_events/README.md +99 -0
  58. data/examples/app_all_events/app.rb +96 -0
  59. data/examples/app_all_events/model/app_model.rb +157 -0
  60. data/examples/app_all_events/model/event_color_cycle.rb +41 -0
  61. data/examples/app_all_events/model/event_entry.rb +92 -0
  62. data/examples/app_all_events/model/msg.rb +37 -0
  63. data/examples/app_all_events/model/timestamp.rb +54 -0
  64. data/examples/app_all_events/update.rb +73 -0
  65. data/examples/app_all_events/view/app_view.rb +78 -0
  66. data/examples/app_all_events/view/controls_view.rb +52 -0
  67. data/examples/app_all_events/view/counts_view.rb +59 -0
  68. data/examples/app_all_events/view/live_view.rb +70 -0
  69. data/examples/app_all_events/view/log_view.rb +55 -0
  70. data/examples/app_all_events/view.rb +7 -0
  71. data/examples/app_color_picker/README.md +134 -0
  72. data/examples/app_color_picker/app.rb +74 -0
  73. data/examples/app_color_picker/clipboard.rb +84 -0
  74. data/examples/app_color_picker/color.rb +191 -0
  75. data/examples/app_color_picker/controls.rb +90 -0
  76. data/examples/app_color_picker/copy_dialog.rb +166 -0
  77. data/examples/app_color_picker/export_pane.rb +126 -0
  78. data/examples/app_color_picker/harmony.rb +56 -0
  79. data/examples/app_color_picker/input.rb +174 -0
  80. data/examples/app_color_picker/main_container.rb +178 -0
  81. data/examples/app_color_picker/palette.rb +109 -0
  82. data/examples/app_login_form/README.md +47 -0
  83. data/examples/{login_form → app_login_form}/app.rb +38 -42
  84. data/examples/app_stateful_interaction/README.md +31 -0
  85. data/examples/app_stateful_interaction/app.rb +272 -0
  86. data/examples/timeout_demo.rb +43 -0
  87. data/examples/verify_quickstart_dsl/README.md +48 -0
  88. data/examples/{quickstart_dsl → verify_quickstart_dsl}/app.rb +17 -6
  89. data/examples/verify_quickstart_layout/README.md +71 -0
  90. data/examples/verify_quickstart_layout/app.rb +71 -0
  91. data/examples/verify_quickstart_lifecycle/README.md +56 -0
  92. data/examples/verify_quickstart_lifecycle/app.rb +54 -0
  93. data/examples/verify_readme_usage/README.md +43 -0
  94. data/examples/verify_readme_usage/app.rb +40 -0
  95. data/examples/widget_barchart_demo/README.md +49 -0
  96. data/examples/widget_barchart_demo/app.rb +238 -0
  97. data/examples/widget_block_demo/README.md +34 -0
  98. data/examples/widget_block_demo/app.rb +256 -0
  99. data/examples/widget_box_demo/README.md +45 -0
  100. data/examples/{box_demo → widget_box_demo}/app.rb +99 -65
  101. data/examples/widget_calendar_demo/README.md +39 -0
  102. data/examples/widget_calendar_demo/app.rb +109 -0
  103. data/examples/widget_canvas_demo/README.md +27 -0
  104. data/examples/widget_canvas_demo/app.rb +123 -0
  105. data/examples/widget_cell_demo/README.md +36 -0
  106. data/examples/widget_cell_demo/app.rb +111 -0
  107. data/examples/widget_center_demo/README.md +29 -0
  108. data/examples/widget_center_demo/app.rb +116 -0
  109. data/examples/widget_chart_demo/README.md +41 -0
  110. data/examples/widget_chart_demo/app.rb +218 -0
  111. data/examples/widget_gauge_demo/README.md +41 -0
  112. data/examples/widget_gauge_demo/app.rb +212 -0
  113. data/examples/widget_layout_split/README.md +44 -0
  114. data/examples/widget_layout_split/app.rb +246 -0
  115. data/examples/widget_line_gauge_demo/README.md +41 -0
  116. data/examples/widget_line_gauge_demo/app.rb +217 -0
  117. data/examples/widget_list_demo/README.md +49 -0
  118. data/examples/widget_list_demo/app.rb +366 -0
  119. data/examples/widget_map_demo/README.md +39 -0
  120. data/examples/{map_demo → widget_map_demo}/app.rb +24 -21
  121. data/examples/widget_overlay_demo/app.rb +248 -0
  122. data/examples/widget_popup_demo/README.md +36 -0
  123. data/examples/widget_popup_demo/app.rb +104 -0
  124. data/examples/widget_ratatui_logo_demo/README.md +34 -0
  125. data/examples/widget_ratatui_logo_demo/app.rb +103 -0
  126. data/examples/widget_ratatui_mascot_demo/README.md +34 -0
  127. data/examples/widget_ratatui_mascot_demo/app.rb +93 -0
  128. data/examples/widget_rect/README.md +38 -0
  129. data/examples/widget_rect/app.rb +205 -0
  130. data/examples/widget_render/README.md +37 -0
  131. data/examples/widget_render/app.rb +184 -0
  132. data/examples/widget_rich_text/README.md +35 -0
  133. data/examples/widget_rich_text/app.rb +166 -0
  134. data/examples/widget_scroll_text/README.md +37 -0
  135. data/examples/widget_scroll_text/app.rb +107 -0
  136. data/examples/widget_scrollbar_demo/README.md +37 -0
  137. data/examples/widget_scrollbar_demo/app.rb +153 -0
  138. data/examples/widget_sparkline_demo/README.md +42 -0
  139. data/examples/widget_sparkline_demo/app.rb +275 -0
  140. data/examples/widget_style_colors/README.md +34 -0
  141. data/examples/widget_style_colors/app.rb +19 -21
  142. data/examples/widget_table_demo/README.md +48 -0
  143. data/examples/widget_table_demo/app.rb +239 -0
  144. data/examples/widget_tabs_demo/README.md +41 -0
  145. data/examples/widget_tabs_demo/app.rb +181 -0
  146. data/examples/widget_text_width/README.md +35 -0
  147. data/examples/widget_text_width/app.rb +106 -0
  148. data/ext/ratatui_ruby/Cargo.lock +11 -4
  149. data/ext/ratatui_ruby/Cargo.toml +2 -1
  150. data/ext/ratatui_ruby/src/events.rs +359 -62
  151. data/ext/ratatui_ruby/src/frame.rs +227 -0
  152. data/ext/ratatui_ruby/src/lib.rs +110 -27
  153. data/ext/ratatui_ruby/src/rendering.rs +8 -4
  154. data/ext/ratatui_ruby/src/string_width.rs +101 -0
  155. data/ext/ratatui_ruby/src/style.rs +138 -57
  156. data/ext/ratatui_ruby/src/terminal.rs +42 -22
  157. data/ext/ratatui_ruby/src/text.rs +14 -7
  158. data/ext/ratatui_ruby/src/widgets/barchart.rs +74 -54
  159. data/ext/ratatui_ruby/src/widgets/block.rs +7 -6
  160. data/ext/ratatui_ruby/src/widgets/canvas.rs +21 -3
  161. data/ext/ratatui_ruby/src/widgets/chart.rs +20 -10
  162. data/ext/ratatui_ruby/src/widgets/gauge.rs +9 -2
  163. data/ext/ratatui_ruby/src/widgets/layout.rs +9 -4
  164. data/ext/ratatui_ruby/src/widgets/line_gauge.rs +9 -2
  165. data/ext/ratatui_ruby/src/widgets/list.rs +211 -12
  166. data/ext/ratatui_ruby/src/widgets/list_state.rs +137 -0
  167. data/ext/ratatui_ruby/src/widgets/mod.rs +3 -0
  168. data/ext/ratatui_ruby/src/widgets/overlay.rs +2 -1
  169. data/ext/ratatui_ruby/src/widgets/paragraph.rs +1 -1
  170. data/ext/ratatui_ruby/src/widgets/ratatui_logo.rs +19 -8
  171. data/ext/ratatui_ruby/src/widgets/ratatui_mascot.rs +17 -10
  172. data/ext/ratatui_ruby/src/widgets/scrollbar.rs +97 -3
  173. data/ext/ratatui_ruby/src/widgets/scrollbar_state.rs +169 -0
  174. data/ext/ratatui_ruby/src/widgets/sparkline.rs +14 -11
  175. data/ext/ratatui_ruby/src/widgets/table.rs +121 -5
  176. data/ext/ratatui_ruby/src/widgets/table_state.rs +121 -0
  177. data/ext/ratatui_ruby/src/widgets/tabs.rs +11 -11
  178. data/lib/ratatui_ruby/cell.rb +7 -7
  179. data/lib/ratatui_ruby/event/key/character.rb +35 -0
  180. data/lib/ratatui_ruby/event/key/media.rb +44 -0
  181. data/lib/ratatui_ruby/event/key/modifier.rb +95 -0
  182. data/lib/ratatui_ruby/event/key/navigation.rb +55 -0
  183. data/lib/ratatui_ruby/event/key/system.rb +45 -0
  184. data/lib/ratatui_ruby/event/key.rb +112 -52
  185. data/lib/ratatui_ruby/event/mouse.rb +3 -3
  186. data/lib/ratatui_ruby/event/none.rb +43 -0
  187. data/lib/ratatui_ruby/event/paste.rb +1 -1
  188. data/lib/ratatui_ruby/event.rb +56 -4
  189. data/lib/ratatui_ruby/frame.rb +183 -0
  190. data/lib/ratatui_ruby/list_state.rb +88 -0
  191. data/lib/ratatui_ruby/schema/bar_chart/bar.rb +13 -13
  192. data/lib/ratatui_ruby/schema/bar_chart/bar_group.rb +1 -5
  193. data/lib/ratatui_ruby/schema/bar_chart.rb +217 -217
  194. data/lib/ratatui_ruby/schema/block.rb +163 -168
  195. data/lib/ratatui_ruby/schema/calendar.rb +66 -67
  196. data/lib/ratatui_ruby/schema/canvas.rb +63 -63
  197. data/lib/ratatui_ruby/schema/center.rb +46 -46
  198. data/lib/ratatui_ruby/schema/chart.rb +135 -143
  199. data/lib/ratatui_ruby/schema/clear.rb +42 -42
  200. data/lib/ratatui_ruby/schema/constraint.rb +76 -76
  201. data/lib/ratatui_ruby/schema/cursor.rb +30 -25
  202. data/lib/ratatui_ruby/schema/gauge.rb +54 -52
  203. data/lib/ratatui_ruby/schema/layout.rb +87 -87
  204. data/lib/ratatui_ruby/schema/line_gauge.rb +62 -62
  205. data/lib/ratatui_ruby/schema/list.rb +103 -80
  206. data/lib/ratatui_ruby/schema/list_item.rb +41 -0
  207. data/lib/ratatui_ruby/schema/overlay.rb +31 -31
  208. data/lib/ratatui_ruby/schema/paragraph.rb +80 -80
  209. data/lib/ratatui_ruby/schema/ratatui_logo.rb +10 -6
  210. data/lib/ratatui_ruby/schema/ratatui_mascot.rb +10 -5
  211. data/lib/ratatui_ruby/schema/rect.rb +99 -56
  212. data/lib/ratatui_ruby/schema/scrollbar.rb +119 -119
  213. data/lib/ratatui_ruby/schema/shape/label.rb +1 -1
  214. data/lib/ratatui_ruby/schema/sparkline.rb +111 -110
  215. data/lib/ratatui_ruby/schema/style.rb +66 -46
  216. data/lib/ratatui_ruby/schema/table.rb +126 -115
  217. data/lib/ratatui_ruby/schema/tabs.rb +66 -67
  218. data/lib/ratatui_ruby/schema/text.rb +69 -1
  219. data/lib/ratatui_ruby/scrollbar_state.rb +112 -0
  220. data/lib/ratatui_ruby/session/autodoc.rb +482 -0
  221. data/lib/ratatui_ruby/session.rb +55 -23
  222. data/lib/ratatui_ruby/table_state.rb +90 -0
  223. data/lib/ratatui_ruby/test_helper/event_injection.rb +169 -0
  224. data/lib/ratatui_ruby/test_helper/snapshot.rb +390 -0
  225. data/lib/ratatui_ruby/test_helper/style_assertions.rb +351 -0
  226. data/lib/ratatui_ruby/test_helper/terminal.rb +127 -0
  227. data/lib/ratatui_ruby/test_helper/test_doubles.rb +68 -0
  228. data/lib/ratatui_ruby/test_helper.rb +66 -193
  229. data/lib/ratatui_ruby/version.rb +1 -1
  230. data/lib/ratatui_ruby.rb +100 -51
  231. data/{examples/sparkline_demo → sig/examples/app_all_events}/app.rbs +3 -2
  232. data/sig/examples/app_all_events/model/event_entry.rbs +16 -0
  233. data/sig/examples/app_all_events/model/events.rbs +15 -0
  234. data/sig/examples/app_all_events/model/timestamp.rbs +11 -0
  235. data/sig/examples/app_all_events/view/app_view.rbs +8 -0
  236. data/sig/examples/app_all_events/view/controls_view.rbs +6 -0
  237. data/sig/examples/app_all_events/view/counts_view.rbs +6 -0
  238. data/sig/examples/app_all_events/view/live_view.rbs +6 -0
  239. data/sig/examples/app_all_events/view/log_view.rbs +6 -0
  240. data/sig/examples/app_all_events/view.rbs +8 -0
  241. data/sig/examples/app_all_events/view_state.rbs +15 -0
  242. data/{examples/list_demo → sig/examples/app_color_picker}/app.rbs +2 -2
  243. data/sig/examples/app_login_form/app.rbs +11 -0
  244. data/sig/examples/app_stateful_interaction/app.rbs +33 -0
  245. data/sig/examples/verify_quickstart_dsl/app.rbs +11 -0
  246. data/sig/examples/verify_quickstart_lifecycle/app.rbs +11 -0
  247. data/sig/examples/verify_readme_usage/app.rbs +11 -0
  248. data/sig/examples/widget_block_demo/app.rbs +32 -0
  249. data/sig/examples/widget_box_demo/app.rbs +11 -0
  250. data/sig/examples/widget_calendar_demo/app.rbs +11 -0
  251. data/sig/examples/widget_cell_demo/app.rbs +11 -0
  252. data/sig/examples/widget_chart_demo/app.rbs +11 -0
  253. data/{examples/gauge_demo → sig/examples/widget_gauge_demo}/app.rbs +4 -0
  254. data/sig/examples/widget_layout_split/app.rbs +10 -0
  255. data/sig/examples/widget_line_gauge_demo/app.rbs +11 -0
  256. data/sig/examples/widget_list_demo/app.rbs +12 -0
  257. data/sig/examples/widget_map_demo/app.rbs +11 -0
  258. data/sig/examples/widget_popup_demo/app.rbs +11 -0
  259. data/sig/examples/widget_ratatui_logo_demo/app.rbs +11 -0
  260. data/sig/examples/widget_ratatui_mascot_demo/app.rbs +11 -0
  261. data/sig/examples/widget_rect/app.rbs +12 -0
  262. data/sig/examples/widget_render/app.rbs +10 -0
  263. data/sig/examples/widget_rich_text/app.rbs +11 -0
  264. data/sig/examples/widget_scroll_text/app.rbs +11 -0
  265. data/sig/examples/widget_scrollbar_demo/app.rbs +11 -0
  266. data/sig/examples/widget_sparkline_demo/app.rbs +10 -0
  267. data/{examples → sig/examples}/widget_style_colors/app.rbs +1 -1
  268. data/sig/examples/widget_table_demo/app.rbs +11 -0
  269. data/sig/examples/widget_text_width/app.rbs +10 -0
  270. data/sig/ratatui_ruby/event.rbs +11 -1
  271. data/sig/ratatui_ruby/frame.rbs +11 -0
  272. data/sig/ratatui_ruby/list_state.rbs +13 -0
  273. data/sig/ratatui_ruby/ratatui_ruby.rbs +5 -4
  274. data/sig/ratatui_ruby/schema/bar_chart/bar.rbs +3 -3
  275. data/sig/ratatui_ruby/schema/draw.rbs +4 -0
  276. data/sig/ratatui_ruby/schema/gauge.rbs +2 -2
  277. data/sig/ratatui_ruby/schema/layout.rbs +1 -1
  278. data/sig/ratatui_ruby/schema/line_gauge.rbs +2 -2
  279. data/sig/ratatui_ruby/schema/list.rbs +4 -2
  280. data/sig/ratatui_ruby/schema/list_item.rbs +10 -0
  281. data/sig/ratatui_ruby/schema/rect.rbs +3 -0
  282. data/sig/ratatui_ruby/schema/style.rbs +3 -3
  283. data/sig/ratatui_ruby/schema/table.rbs +3 -1
  284. data/sig/ratatui_ruby/schema/text.rbs +8 -6
  285. data/sig/ratatui_ruby/scrollbar_state.rbs +18 -0
  286. data/sig/ratatui_ruby/session.rbs +107 -0
  287. data/sig/ratatui_ruby/table_state.rbs +15 -0
  288. data/sig/ratatui_ruby/test_helper/event_injection.rbs +16 -0
  289. data/sig/ratatui_ruby/test_helper/snapshot.rbs +12 -0
  290. data/sig/ratatui_ruby/test_helper/style_assertions.rbs +64 -0
  291. data/sig/ratatui_ruby/test_helper/terminal.rbs +14 -0
  292. data/sig/ratatui_ruby/test_helper/test_doubles.rbs +22 -0
  293. data/sig/ratatui_ruby/test_helper.rbs +5 -4
  294. data/tasks/autodoc/examples.rb +79 -0
  295. data/tasks/autodoc/inventory.rb +63 -0
  296. data/tasks/autodoc/member.rb +56 -0
  297. data/tasks/autodoc/name.rb +19 -0
  298. data/tasks/autodoc/notice.rb +26 -0
  299. data/tasks/autodoc/rbs.rb +38 -0
  300. data/tasks/autodoc/rdoc.rb +45 -0
  301. data/tasks/autodoc.rake +53 -0
  302. data/tasks/bump/changelog.rb +3 -3
  303. data/tasks/bump/history.rb +2 -2
  304. data/tasks/bump/links.rb +67 -0
  305. data/tasks/doc.rake +600 -6
  306. data/tasks/example_viewer.html.erb +172 -0
  307. data/tasks/lint.rake +8 -4
  308. data/tasks/resources/index.html.erb +6 -0
  309. data/tasks/sourcehut.rake +70 -30
  310. data/tasks/terminal_preview/app_screenshot.rb +14 -6
  311. data/tasks/terminal_preview/crash_report.rb +7 -9
  312. data/tasks/terminal_preview/launcher_script.rb +4 -6
  313. data/tasks/terminal_preview/preview_collection.rb +4 -6
  314. data/tasks/terminal_preview/safety_confirmation.rb +3 -5
  315. data/tasks/terminal_preview/saved_screenshot.rb +10 -11
  316. data/tasks/terminal_preview/terminal_window.rb +7 -9
  317. data/tasks/test.rake +1 -1
  318. data/tasks/website/index_page.rb +3 -3
  319. data/tasks/website/version.rb +10 -10
  320. data/tasks/website/version_menu.rb +10 -12
  321. data/tasks/website/versioned_documentation.rb +49 -17
  322. data/tasks/website/website.rb +6 -8
  323. data/tasks/website.rake +4 -4
  324. metadata +232 -127
  325. data/LICENSES/BSD-2-Clause.txt +0 -9
  326. data/doc/contributors/better_dx.md +0 -543
  327. data/doc/contributors/example_analysis.md +0 -82
  328. data/doc/images/all_events.png +0 -0
  329. data/doc/images/block_padding.png +0 -0
  330. data/doc/images/block_titles.png +0 -0
  331. data/doc/images/box_demo.png +0 -0
  332. data/doc/images/calendar_demo.png +0 -0
  333. data/doc/images/cell_demo.png +0 -0
  334. data/doc/images/chart_demo.png +0 -0
  335. data/doc/images/flex_layout.png +0 -0
  336. data/doc/images/gauge_demo.png +0 -0
  337. data/doc/images/line_gauge_demo.png +0 -0
  338. data/doc/images/list_demo.png +0 -0
  339. data/doc/images/list_styles.png +0 -0
  340. data/doc/images/login_form.png +0 -0
  341. data/doc/images/quickstart_dsl.png +0 -0
  342. data/doc/images/quickstart_lifecycle.png +0 -0
  343. data/doc/images/readme_usage.png +0 -0
  344. data/doc/images/rich_text.png +0 -0
  345. data/doc/images/scroll_text.png +0 -0
  346. data/doc/images/scrollbar_demo.png +0 -0
  347. data/doc/images/sparkline_demo.png +0 -0
  348. data/doc/images/table_flex.png +0 -0
  349. data/doc/images/table_select.png +0 -0
  350. data/examples/all_events/app.rb +0 -169
  351. data/examples/all_events/app.rbs +0 -7
  352. data/examples/all_events/test_app.rb +0 -139
  353. data/examples/analytics/app.rb +0 -258
  354. data/examples/analytics/app.rbs +0 -7
  355. data/examples/analytics/test_app.rb +0 -132
  356. data/examples/block_padding/app.rb +0 -63
  357. data/examples/block_padding/app.rbs +0 -7
  358. data/examples/block_padding/test_app.rb +0 -31
  359. data/examples/block_titles/app.rb +0 -61
  360. data/examples/block_titles/app.rbs +0 -7
  361. data/examples/block_titles/test_app.rb +0 -34
  362. data/examples/box_demo/app.rbs +0 -7
  363. data/examples/box_demo/test_app.rb +0 -88
  364. data/examples/calendar_demo/app.rb +0 -101
  365. data/examples/calendar_demo/app.rbs +0 -7
  366. data/examples/calendar_demo/test_app.rb +0 -108
  367. data/examples/cell_demo/app.rb +0 -108
  368. data/examples/cell_demo/app.rbs +0 -7
  369. data/examples/cell_demo/test_app.rb +0 -36
  370. data/examples/chart_demo/app.rb +0 -203
  371. data/examples/chart_demo/app.rbs +0 -7
  372. data/examples/chart_demo/test_app.rb +0 -102
  373. data/examples/custom_widget/app.rb +0 -51
  374. data/examples/custom_widget/app.rbs +0 -7
  375. data/examples/custom_widget/test_app.rb +0 -30
  376. data/examples/flex_layout/app.rb +0 -156
  377. data/examples/flex_layout/app.rbs +0 -7
  378. data/examples/flex_layout/test_app.rb +0 -65
  379. data/examples/gauge_demo/app.rb +0 -182
  380. data/examples/gauge_demo/test_app.rb +0 -120
  381. data/examples/hit_test/app.rb +0 -175
  382. data/examples/hit_test/app.rbs +0 -7
  383. data/examples/hit_test/test_app.rb +0 -102
  384. data/examples/line_gauge_demo/app.rb +0 -190
  385. data/examples/line_gauge_demo/app.rbs +0 -7
  386. data/examples/line_gauge_demo/test_app.rb +0 -129
  387. data/examples/list_demo/app.rb +0 -253
  388. data/examples/list_demo/test_app.rb +0 -237
  389. data/examples/list_styles/app.rb +0 -140
  390. data/examples/list_styles/app.rbs +0 -7
  391. data/examples/list_styles/test_app.rb +0 -157
  392. data/examples/login_form/app.rbs +0 -7
  393. data/examples/login_form/test_app.rb +0 -51
  394. data/examples/map_demo/app.rbs +0 -7
  395. data/examples/map_demo/test_app.rb +0 -149
  396. data/examples/mouse_events/app.rb +0 -97
  397. data/examples/mouse_events/app.rbs +0 -7
  398. data/examples/mouse_events/test_app.rb +0 -53
  399. data/examples/popup_demo/app.rb +0 -103
  400. data/examples/popup_demo/app.rbs +0 -7
  401. data/examples/popup_demo/test_app.rb +0 -54
  402. data/examples/quickstart_dsl/app.rbs +0 -7
  403. data/examples/quickstart_dsl/test_app.rb +0 -29
  404. data/examples/quickstart_lifecycle/app.rb +0 -39
  405. data/examples/quickstart_lifecycle/app.rbs +0 -7
  406. data/examples/quickstart_lifecycle/test_app.rb +0 -29
  407. data/examples/ratatui_logo_demo/app.rb +0 -79
  408. data/examples/ratatui_logo_demo/app.rbs +0 -7
  409. data/examples/ratatui_logo_demo/test_app.rb +0 -51
  410. data/examples/ratatui_mascot_demo/app.rb +0 -84
  411. data/examples/ratatui_mascot_demo/app.rbs +0 -7
  412. data/examples/ratatui_mascot_demo/test_app.rb +0 -47
  413. data/examples/readme_usage/app.rb +0 -29
  414. data/examples/readme_usage/app.rbs +0 -7
  415. data/examples/readme_usage/test_app.rb +0 -29
  416. data/examples/rich_text/app.rb +0 -141
  417. data/examples/rich_text/app.rbs +0 -7
  418. data/examples/rich_text/test_app.rb +0 -166
  419. data/examples/scroll_text/app.rb +0 -103
  420. data/examples/scroll_text/app.rbs +0 -7
  421. data/examples/scroll_text/test_app.rb +0 -110
  422. data/examples/scrollbar_demo/app.rb +0 -143
  423. data/examples/scrollbar_demo/app.rbs +0 -7
  424. data/examples/scrollbar_demo/test_app.rb +0 -77
  425. data/examples/sparkline_demo/app.rb +0 -240
  426. data/examples/sparkline_demo/test_app.rb +0 -107
  427. data/examples/table_flex/app.rb +0 -65
  428. data/examples/table_flex/app.rbs +0 -7
  429. data/examples/table_flex/test_app.rb +0 -36
  430. data/examples/table_select/app.rb +0 -198
  431. data/examples/table_select/app.rbs +0 -7
  432. data/examples/table_select/test_app.rb +0 -180
  433. data/examples/widget_style_colors/test_app.rb +0 -48
  434. data/tasks/bump/comparison_links.rb +0 -41
  435. /data/doc/images/{analytics.png → app_analytics.png} +0 -0
  436. /data/doc/images/{custom_widget.png → app_custom_widget.png} +0 -0
  437. /data/doc/images/{mouse_events.png → app_mouse_events.png} +0 -0
  438. /data/doc/images/{map_demo.png → widget_map_demo.png} +0 -0
  439. /data/doc/images/{popup_demo.png → widget_popup_demo.png} +0 -0
  440. /data/doc/images/{hit_test.png → widget_rect.png} +0 -0
  441. /data/{doc/images/ratatui_logo_demo.png → exe/.gitkeep} +0 -0
@@ -1,51 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
4
- require "ratatui_ruby"
5
- require "ratatui_ruby/test_helper"
6
- require "minitest/autorun"
7
- require_relative "app"
8
-
9
- class TestRatatuiLogoDemoApp < Minitest::Test
10
- include RatatuiRuby::TestHelper
11
-
12
- def setup
13
- @app = RatatuiLogoDemoApp.new
14
- end
15
-
16
- def test_initial_render
17
- with_test_terminal do
18
- inject_key(:q)
19
- @app.run
20
-
21
- content = buffer_content.join("\n")
22
-
23
- # Verify the logo is rendered.
24
- # The Ratatui logo usually contains "ratatui" text or similar shapes.
25
- # Since we can't easily match the exact ASCII art in a cross-platform/version way without brittleness,
26
- # we verify that the center of the screen is NOT empty.
27
-
28
- # The logo is centered.
29
- center_x = 40
30
- center_y = 10
31
- RatatuiRuby.get_cell_at(center_x, center_y)
32
-
33
- # It might not be exactly at 40, 10, but the logo is large enough that checking a region is safe.
34
- # Or simpler: verify the buffer contains non-whitespace lines in the middle.
35
-
36
- # Checking for "Controls" proves the app rendered.
37
- assert_includes content, "Controls"
38
- assert_includes content, "Quit"
39
-
40
- # Capture the "visual" presence of the logo by ensuring the buffer isn't just known text + whitespace.
41
- # The logo uses unicode block characters or specific letters.
42
- # Let's check for a known character from the logo if possible, or just significant non-whitespace count.
43
- refute_empty content.gsub(/\s+/, ""), "Buffer should not be empty"
44
-
45
- # We know the controls text. Let's ensure there is MORE text than just controls.
46
- controls_length = "Controls".length + "q: Quit".length + 20 # aprox buffer
47
- non_whitespace_count = content.gsub(/\s/, "").length
48
- assert non_whitespace_count > controls_length, "Should render more than just controls (the logo)"
49
- end
50
- end
51
- end
@@ -1,84 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
- # SPDX-License-Identifier: CC-BY-SA-4.0
5
-
6
- $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
7
- require "ratatui_ruby"
8
-
9
- class RatatuiMascotDemoApp
10
- def initialize
11
- @show_block = true
12
- end
13
-
14
- def run
15
- RatatuiRuby.run do |tui|
16
- loop do
17
- render(tui)
18
- break if handle_input(tui) == :quit
19
- end
20
- end
21
- end
22
-
23
- private
24
-
25
- def render(tui)
26
- # Layout: Top (Mascot), Bottom (Controls)
27
- # Mascot Widget
28
- block = if @show_block
29
- tui.block(
30
- title: "Ratatui Mascot",
31
- borders: [:all],
32
- border_type: :rounded,
33
- border_style: { fg: :green }
34
- )
35
- end
36
-
37
- mascot = tui.ratatui_mascot(block: block)
38
-
39
- # Controls
40
- controls_text = [
41
- tui.text_span(content: "q", style: tui.style(modifiers: [:bold, :underlined])),
42
- tui.text_span(content: " Quit"),
43
- tui.text_span(content: " "),
44
- tui.text_span(content: "b", style: tui.style(modifiers: [:bold, :underlined])),
45
- tui.text_span(content: " Toggle Block #{@show_block ? '(On)' : '(Off)'}")
46
- ]
47
-
48
- controls_paragraph = tui.paragraph(
49
- text: tui.text_line(spans: controls_text),
50
- block: tui.block(borders: [:top], title: "Controls")
51
- )
52
-
53
- # Layout: Top (Mascot), Bottom (Controls)
54
- layout = tui.layout(
55
- direction: :vertical,
56
- constraints: [
57
- RatatuiRuby::Constraint.fill(1),
58
- RatatuiRuby::Constraint.length(4)
59
- ],
60
- children: [
61
- mascot,
62
- controls_paragraph
63
- ]
64
- )
65
-
66
- tui.draw(layout)
67
- end
68
-
69
- def handle_input(tui)
70
- event = tui.poll_event
71
- return unless event
72
-
73
- if event.key?
74
- case event.char
75
- when "q" then return :quit
76
- when "b" then @show_block = !@show_block
77
- end
78
- elsif event.ctrl_c?
79
- return :quit
80
- end
81
- end
82
- end
83
-
84
- RatatuiMascotDemoApp.new.run if __FILE__ == $PROGRAM_NAME
@@ -1,7 +0,0 @@
1
- class RatatuiMascotDemoApp
2
- # @public
3
- def self.new: () -> RatatuiMascotDemoApp
4
-
5
- # @public
6
- def run: () -> void
7
- end
@@ -1,47 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
- # SPDX-License-Identifier: AGPL-3.0-or-later
5
-
6
- $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
7
- require "ratatui_ruby"
8
- require "ratatui_ruby/test_helper"
9
- require "minitest/autorun"
10
- require_relative "app"
11
-
12
- class TestRatatuiMascotDemoApp < Minitest::Test
13
- include RatatuiRuby::TestHelper
14
-
15
- def setup
16
- @app = RatatuiMascotDemoApp.new
17
- end
18
-
19
- def test_initial_render
20
- with_test_terminal do
21
- inject_key(:q)
22
- @app.run
23
-
24
- content = buffer_content.join("\n")
25
- assert_includes content, "Ratatui Mascot" # Title implying block is on
26
- assert_includes content, "Toggle Block (On)"
27
- # Mascot contains block characters
28
- assert_includes content, "█"
29
- end
30
- end
31
-
32
- def test_toggle_block
33
- with_test_terminal do
34
- inject_key("b")
35
- inject_key(:q)
36
- @app.run
37
-
38
- content = buffer_content.join("\n")
39
- assert_includes content, "Toggle Block (Off)"
40
- # Title should be gone if block is gone (unless internal rendering keeps it, but our logic removes the block)
41
- # Wait, if block is nil, no border/title.
42
- refute_includes content, "Ratatui Mascot"
43
- # Mascot should still be there
44
- assert_includes content, "█"
45
- end
46
- end
47
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
- # SPDX-License-Identifier: AGPL-3.0-or-later
5
-
6
- $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
7
-
8
- require "ratatui_ruby"
9
- class ReadmeUsageApp
10
- def run
11
- RatatuiRuby.run do |tui|
12
- loop do
13
- tui.draw \
14
- tui.paragraph \
15
- text: "Hello, Ratatui! Press 'q' to quit.",
16
- alignment: :center,
17
- block: tui.block(
18
- title: "My Ruby TUI App",
19
- borders: [:all],
20
- border_color: "cyan"
21
- )
22
- event = tui.poll_event
23
- break if event == "q" || event == :ctrl_c
24
- end
25
- end
26
- end
27
- end
28
-
29
- ReadmeUsageApp.new.run if __FILE__ == $PROGRAM_NAME
@@ -1,7 +0,0 @@
1
- class ReadmeUsageApp
2
- # @public
3
- def self.new: () -> ReadmeUsageApp
4
-
5
- # @public
6
- def run: () -> void
7
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
- # SPDX-License-Identifier: AGPL-3.0-or-later
5
-
6
- $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
7
- require "ratatui_ruby"
8
- require "ratatui_ruby/test_helper"
9
- require "minitest/autorun"
10
- require_relative "app"
11
-
12
- class TestReadmeUsage < Minitest::Test
13
- include RatatuiRuby::TestHelper
14
-
15
- def setup
16
- @app = ReadmeUsageApp.new
17
- end
18
-
19
- def test_render
20
- with_test_terminal do
21
- inject_key(:q)
22
- @app.run
23
-
24
- content = buffer_content.join("\n")
25
- assert_includes content, "Hello, Ratatui!"
26
- assert_includes content, "My Ruby TUI App"
27
- end
28
- end
29
- end
@@ -1,141 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
- # SPDX-License-Identifier: AGPL-3.0-or-later
5
-
6
- $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
7
- require "ratatui_ruby"
8
-
9
- # Rich Text Example
10
- # Demonstrates the Span and Line objects for styling individual words
11
- # within a block of text.
12
- class RichTextApp
13
- def initialize
14
- @scroll_pos = 0
15
- end
16
-
17
- def run
18
- RatatuiRuby.run do
19
- loop do
20
- render
21
- event = handle_input
22
- break if event == :quit
23
- sleep 0.05
24
- end
25
- end
26
- end
27
-
28
- private
29
-
30
- def render
31
- RatatuiRuby.draw(
32
- RatatuiRuby::Layout.new(
33
- direction: :vertical,
34
- constraints: [
35
- RatatuiRuby::Constraint.percentage(50),
36
- RatatuiRuby::Constraint.percentage(50)
37
- ],
38
- children: [
39
- simple_text_line_example,
40
- complex_example
41
- ]
42
- )
43
- )
44
- end
45
-
46
- def simple_text_line_example
47
- # Example 1: A line with mixed styles
48
- RatatuiRuby::Paragraph.new(
49
- text: RatatuiRuby::Text::Line.new(
50
- spans: [
51
- RatatuiRuby::Text::Span.new(
52
- content: "Normal text, ",
53
- style: nil
54
- ),
55
- RatatuiRuby::Text::Span.new(
56
- content: "Bold Text",
57
- style: RatatuiRuby::Style.new(modifiers: [:bold])
58
- ),
59
- RatatuiRuby::Text::Span.new(
60
- content: ", ",
61
- style: nil
62
- ),
63
- RatatuiRuby::Text::Span.new(
64
- content: "Italic Text",
65
- style: RatatuiRuby::Style.new(modifiers: [:italic])
66
- ),
67
- RatatuiRuby::Text::Span.new(
68
- content: ", ",
69
- style: nil
70
- ),
71
- RatatuiRuby::Text::Span.new(
72
- content: "Red Text",
73
- style: RatatuiRuby::Style.new(fg: :red)
74
- ),
75
- RatatuiRuby::Text::Span.new(
76
- content: ".",
77
- style: nil
78
- )
79
- ]
80
- ),
81
- block: RatatuiRuby::Block.new(
82
- title: "Simple Rich Text",
83
- borders: [:all]
84
- )
85
- )
86
- end
87
-
88
- def complex_example
89
- # Example 2: Multiple lines with different styles
90
- RatatuiRuby::Paragraph.new(
91
- text: [
92
- RatatuiRuby::Text::Line.new(
93
- spans: [
94
- RatatuiRuby::Text::Span.new(content: "✓ ", style: RatatuiRuby::Style.new(fg: :green, modifiers: [:bold])),
95
- RatatuiRuby::Text::Span.new(content: "Feature Complete", style: nil),
96
- RatatuiRuby::Text::Span.new(content: " - All tests passing", style: RatatuiRuby::Style.new(fg: :gray))
97
- ]
98
- ),
99
- RatatuiRuby::Text::Line.new(
100
- spans: [
101
- RatatuiRuby::Text::Span.new(content: "⚠ ", style: RatatuiRuby::Style.new(fg: :yellow, modifiers: [:bold])),
102
- RatatuiRuby::Text::Span.new(content: "Warning", style: nil),
103
- RatatuiRuby::Text::Span.new(content: " - Documentation pending", style: RatatuiRuby::Style.new(fg: :gray))
104
- ]
105
- ),
106
- RatatuiRuby::Text::Line.new(
107
- spans: [
108
- RatatuiRuby::Text::Span.new(content: "✗ ", style: RatatuiRuby::Style.new(fg: :red, modifiers: [:bold])),
109
- RatatuiRuby::Text::Span.new(content: "Not Started", style: nil),
110
- RatatuiRuby::Text::Span.new(content: " - Performance benchmarks", style: RatatuiRuby::Style.new(fg: :gray))
111
- ]
112
- ),
113
- RatatuiRuby::Text::Line.new(spans: []),
114
- RatatuiRuby::Text::Line.new(
115
- spans: [
116
- RatatuiRuby::Text::Span.new(content: "Press ", style: nil),
117
- RatatuiRuby::Text::Span.new(content: "Q", style: RatatuiRuby::Style.new(modifiers: [:bold])),
118
- RatatuiRuby::Text::Span.new(content: " to quit", style: nil)
119
- ]
120
- )
121
- ],
122
- block: RatatuiRuby::Block.new(
123
- title: "Status Report",
124
- borders: [:all]
125
- )
126
- )
127
- end
128
-
129
- def handle_input
130
- event = RatatuiRuby.poll_event
131
- return nil unless event
132
-
133
- return :quit if event == "q" || event == :esc || event == :ctrl_c
134
-
135
- nil
136
- end
137
- end
138
-
139
- if __FILE__ == $0
140
- RichTextApp.new.run
141
- end
@@ -1,7 +0,0 @@
1
- class RichTextApp
2
- # @public
3
- def self.new: () -> RichTextApp
4
-
5
- # @public
6
- def run: () -> void
7
- end
@@ -1,166 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
- # SPDX-License-Identifier: AGPL-3.0-or-later
5
-
6
- $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
7
- require "ratatui_ruby"
8
- require "test_helper"
9
- require_relative "app"
10
-
11
- class TestRichTextApp < Minitest::Test
12
- include RatatuiRuby::TestHelper
13
-
14
- include RatatuiRuby::TestHelper
15
-
16
- def test_simple_span
17
- span = RatatuiRuby::Text::Span.new(content: "hello", style: nil)
18
- assert_equal "hello", span.content
19
- assert_nil span.style
20
- end
21
-
22
- def test_styled_span
23
- style = RatatuiRuby::Style.new(fg: :red, modifiers: [:bold])
24
- span = RatatuiRuby::Text::Span.new(content: "error", style:)
25
- assert_equal "error", span.content
26
- assert_equal style, span.style
27
- end
28
-
29
- def test_span_styled_helper
30
- style = RatatuiRuby::Style.new(modifiers: [:italic])
31
- span = RatatuiRuby::Text::Span.styled("italic text", style)
32
- assert_equal "italic text", span.content
33
- assert_equal style, span.style
34
- end
35
-
36
- def test_span_styled_helper_without_style
37
- span = RatatuiRuby::Text::Span.styled("plain")
38
- assert_equal "plain", span.content
39
- assert_nil span.style
40
- end
41
-
42
- def test_simple_line
43
- spans = [
44
- RatatuiRuby::Text::Span.new(content: "hello", style: nil),
45
- RatatuiRuby::Text::Span.new(content: " world", style: nil)
46
- ]
47
- line = RatatuiRuby::Text::Line.new(spans:)
48
- assert_equal spans, line.spans
49
- assert_nil line.alignment
50
- end
51
-
52
- def test_line_with_alignment
53
- spans = [RatatuiRuby::Text::Span.new(content: "centered", style: nil)]
54
- line = RatatuiRuby::Text::Line.new(spans:, alignment: :center)
55
- assert_equal :center, line.alignment
56
- end
57
-
58
- def test_line_from_string
59
- line = RatatuiRuby::Text::Line.from_string("test content")
60
- assert_equal 1, line.spans.length
61
- assert_equal "test content", line.spans[0].content
62
- assert_nil line.spans[0].style
63
- end
64
-
65
- def test_line_from_string_with_alignment
66
- line = RatatuiRuby::Text::Line.from_string("right aligned", alignment: :right)
67
- assert_equal :right, line.alignment
68
- end
69
-
70
- def test_paragraph_with_string
71
- para = RatatuiRuby::Paragraph.new(text: "simple text")
72
- assert_equal "simple text", para.text
73
- end
74
-
75
- def test_paragraph_with_span
76
- span = RatatuiRuby::Text::Span.new(content: "bold", style: RatatuiRuby::Style.new(modifiers: [:bold]))
77
- para = RatatuiRuby::Paragraph.new(text: span)
78
- assert_equal span, para.text
79
- end
80
-
81
- def test_paragraph_with_line
82
- line = RatatuiRuby::Text::Line.new(
83
- spans: [
84
- RatatuiRuby::Text::Span.new(content: "hello ", style: nil),
85
- RatatuiRuby::Text::Span.new(content: "world", style: RatatuiRuby::Style.new(fg: :green))
86
- ]
87
- )
88
- para = RatatuiRuby::Paragraph.new(text: line)
89
- assert_equal line, para.text
90
- end
91
-
92
- def test_paragraph_with_multiple_lines
93
- lines = [
94
- RatatuiRuby::Text::Line.new(
95
- spans: [RatatuiRuby::Text::Span.new(content: "line 1", style: nil)]
96
- ),
97
- RatatuiRuby::Text::Line.new(
98
- spans: [RatatuiRuby::Text::Span.new(content: "line 2", style: RatatuiRuby::Style.new(fg: :red))]
99
- )
100
- ]
101
- para = RatatuiRuby::Paragraph.new(text: lines)
102
- assert_equal lines, para.text
103
- end
104
-
105
- def test_paragraph_renders_with_rich_text
106
- with_test_terminal do
107
- # Test that a paragraph with rich text can be rendered without error
108
- line = RatatuiRuby::Text::Line.new(
109
- spans: [
110
- RatatuiRuby::Text::Span.new(content: "normal ", style: nil),
111
- RatatuiRuby::Text::Span.new(content: "bold", style: RatatuiRuby::Style.new(modifiers: [:bold])),
112
- RatatuiRuby::Text::Span.new(content: " text", style: nil)
113
- ]
114
- )
115
- para = RatatuiRuby::Paragraph.new(
116
- text: line,
117
- block: RatatuiRuby::Block.new(title: "Test", borders: [:all])
118
- )
119
- # Should not raise an error when rendering
120
- RatatuiRuby.draw(para)
121
- end
122
- end
123
-
124
- def test_paragraph_renders_multiple_rich_lines
125
- with_test_terminal do
126
- lines = [
127
- RatatuiRuby::Text::Line.new(
128
- spans: [
129
- RatatuiRuby::Text::Span.new(content: "✓ ", style: RatatuiRuby::Style.new(fg: :green, modifiers: [:bold])),
130
- RatatuiRuby::Text::Span.new(content: "Complete", style: nil)
131
- ]
132
- ),
133
- RatatuiRuby::Text::Line.new(
134
- spans: [
135
- RatatuiRuby::Text::Span.new(content: "✗ ", style: RatatuiRuby::Style.new(fg: :red, modifiers: [:bold])),
136
- RatatuiRuby::Text::Span.new(content: "Failed", style: nil)
137
- ]
138
- )
139
- ]
140
- para = RatatuiRuby::Paragraph.new(text: lines)
141
- # Should not raise an error when rendering
142
- RatatuiRuby.draw(para)
143
- end
144
- end
145
- end
146
-
147
- require_relative "app"
148
-
149
- class TestRichTextApp < Minitest::Test
150
- include RatatuiRuby::TestHelper
151
-
152
- include RatatuiRuby::TestHelper
153
-
154
- def test_app_runs
155
- with_test_terminal do
156
- inject_key(:q)
157
- RichTextApp.new.run
158
-
159
- assert buffer_content.any? { |line| line.include?("Simple Rich Text") }
160
- assert buffer_content.any? { |line| line.include?("Status Report") }
161
- end
162
- end
163
- end
164
-
165
-
166
-
@@ -1,103 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: AGPL-3.0-or-later
6
-
7
- $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
8
- require "ratatui_ruby"
9
-
10
- # Demo: Scrollable Paragraph
11
- # Shows how to scroll through long text content using arrow keys
12
- class ScrollTextApp
13
- def initialize
14
- @scroll_x = 0
15
- @scroll_y = 0
16
-
17
- @lines = (1..100).map { |i| "Line #{i}: This is a long line of text that can be scrolled horizontally" }
18
- @hotkey_style = RatatuiRuby::Style.new(modifiers: [:bold, :underlined])
19
- end
20
-
21
- def run
22
- RatatuiRuby.run do
23
- loop do
24
- draw
25
- break if handle_input == :quit
26
- end
27
- end
28
- end
29
-
30
- def render
31
- draw
32
- end
33
-
34
- def handle_input
35
- case RatatuiRuby.poll_event
36
- in {type: :key, code: "q"} | {type: :key, code: "c", modifiers: ["ctrl"]}
37
- :quit
38
- in type: :key, code: "up"
39
- @scroll_y = [@scroll_y - 1, 0].max
40
- in type: :key, code: "down"
41
- @scroll_y = [@scroll_y + 1, @lines.length].min
42
- in type: :key, code: "left"
43
- @scroll_x = [@scroll_x - 1, 0].max
44
- in type: :key, code: "right"
45
- @scroll_x = [@scroll_x + 1, 100].min
46
- else
47
- nil
48
- end
49
- end
50
-
51
- private
52
-
53
- def draw
54
- text = @lines.join("\n")
55
-
56
- # Main content
57
- main_paragraph = RatatuiRuby::Paragraph.new(
58
- text: text,
59
- scroll: [@scroll_y, @scroll_x],
60
- block: RatatuiRuby::Block.new(
61
- title: "Scrollable Text (#{text.lines.count} lines)",
62
- borders: [:all]
63
- )
64
- )
65
-
66
- # Bottom control panel
67
- control_panel = RatatuiRuby::Block.new(
68
- title: "Controls",
69
- borders: [:all],
70
- children: [
71
- RatatuiRuby::Paragraph.new(
72
- text: [
73
- RatatuiRuby::Text::Line.new(spans: [
74
- RatatuiRuby::Text::Span.new(content: "NAVIGATION (Size: #{main_paragraph.line_count(65535)}x#{main_paragraph.line_width})", style: RatatuiRuby::Style.new(modifiers: [:bold]))
75
- ]),
76
- RatatuiRuby::Text::Line.new(spans: [
77
- RatatuiRuby::Text::Span.new(content: "↑/↓", style: @hotkey_style),
78
- RatatuiRuby::Text::Span.new(content: ": Vert Scroll (#{@scroll_y}/#{main_paragraph.line_count(65535)}) "),
79
- RatatuiRuby::Text::Span.new(content: "←/→", style: @hotkey_style),
80
- RatatuiRuby::Text::Span.new(content: ": Horz Scroll (#{@scroll_x}/#{main_paragraph.line_width}) "),
81
- RatatuiRuby::Text::Span.new(content: "q", style: @hotkey_style),
82
- RatatuiRuby::Text::Span.new(content: ": Quit")
83
- ])
84
- ]
85
- )
86
- ]
87
- )
88
-
89
- # Vertical Layout
90
- layout = RatatuiRuby::Layout.new(
91
- direction: :vertical,
92
- constraints: [
93
- RatatuiRuby::Constraint.fill(1),
94
- RatatuiRuby::Constraint.length(5),
95
- ],
96
- children: [main_paragraph, control_panel]
97
- )
98
-
99
- RatatuiRuby.draw(layout)
100
- end
101
- end
102
-
103
- ScrollTextApp.new.run if __FILE__ == $PROGRAM_NAME
@@ -1,7 +0,0 @@
1
- class ScrollTextApp
2
- # @public
3
- def self.new: () -> ScrollTextApp
4
-
5
- # @public
6
- def run: () -> void
7
- end