ratatui_ruby 0.8.0 → 0.9.1

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 (355) hide show
  1. checksums.yaml +4 -4
  2. data/.builds/ruby-3.2.yml +2 -2
  3. data/.builds/ruby-3.3.yml +2 -2
  4. data/.builds/ruby-3.4.yml +2 -2
  5. data/.builds/ruby-4.0.0.yml +2 -2
  6. data/.pre-commit-config.yaml +1 -1
  7. data/AGENTS.md +3 -3
  8. data/CHANGELOG.md +77 -1
  9. data/LICENSES/LGPL-3.0-or-later.txt +304 -0
  10. data/LICENSES/MIT-0.txt +16 -0
  11. data/README.md +33 -5
  12. data/Rakefile +1 -1
  13. data/doc/concepts/application_architecture.md +44 -3
  14. data/doc/concepts/application_testing.md +43 -1
  15. data/doc/concepts/async.md +32 -2
  16. data/doc/concepts/custom_widgets.md +247 -0
  17. data/doc/concepts/event_handling.md +32 -3
  18. data/doc/concepts/interactive_design.md +32 -2
  19. data/doc/contributors/auditing/parity.md +7 -1
  20. data/doc/contributors/design/ruby_frontend.md +85 -1
  21. data/doc/contributors/design/rust_backend.md +67 -1
  22. data/doc/contributors/developing_examples.md +56 -2
  23. data/doc/contributors/documentation_style.md +20 -3
  24. data/doc/contributors/future_work.md +169 -0
  25. data/doc/contributors/index.md +1 -1
  26. data/doc/contributors/v1.0.0_blockers.md +19 -185
  27. data/doc/getting_started/quickstart.md +22 -4
  28. data/doc/getting_started/why.md +1 -1
  29. data/doc/index.md +2 -1
  30. data/doc/troubleshooting/debugging.md +32 -2
  31. data/doc/troubleshooting/terminal_limitations.md +8 -2
  32. data/doc/troubleshooting/tui_output.md +42 -0
  33. data/examples/app_all_events/README.md +14 -2
  34. data/examples/app_all_events/app.rb +1 -1
  35. data/examples/app_all_events/model/app_model.rb +1 -1
  36. data/examples/app_all_events/model/event_color_cycle.rb +1 -1
  37. data/examples/app_all_events/model/event_entry.rb +1 -1
  38. data/examples/app_all_events/model/msg.rb +1 -1
  39. data/examples/app_all_events/model/timestamp.rb +1 -1
  40. data/examples/app_all_events/update.rb +1 -1
  41. data/examples/app_all_events/view/app_view.rb +1 -1
  42. data/examples/app_all_events/view/controls_view.rb +1 -1
  43. data/examples/app_all_events/view/counts_view.rb +1 -1
  44. data/examples/app_all_events/view/live_view.rb +1 -1
  45. data/examples/app_all_events/view/log_view.rb +1 -1
  46. data/examples/app_all_events/view.rb +1 -1
  47. data/examples/app_color_picker/README.md +20 -2
  48. data/examples/app_color_picker/app.rb +1 -1
  49. data/examples/app_color_picker/clipboard.rb +1 -1
  50. data/examples/app_color_picker/color.rb +1 -1
  51. data/examples/app_color_picker/controls.rb +1 -1
  52. data/examples/app_color_picker/copy_dialog.rb +1 -1
  53. data/examples/app_color_picker/export_pane.rb +1 -1
  54. data/examples/app_color_picker/harmony.rb +1 -1
  55. data/examples/app_color_picker/input.rb +1 -1
  56. data/examples/app_color_picker/main_container.rb +1 -1
  57. data/examples/app_color_picker/palette.rb +1 -1
  58. data/examples/app_login_form/README.md +8 -2
  59. data/examples/app_login_form/app.rb +1 -1
  60. data/examples/app_stateful_interaction/README.md +2 -2
  61. data/examples/app_stateful_interaction/app.rb +71 -17
  62. data/examples/timeout_demo.rb +1 -1
  63. data/examples/verify_quickstart_dsl/README.md +6 -0
  64. data/examples/verify_quickstart_dsl/app.rb +3 -3
  65. data/examples/verify_quickstart_layout/README.md +6 -0
  66. data/examples/verify_quickstart_layout/app.rb +3 -3
  67. data/examples/verify_quickstart_lifecycle/README.md +6 -0
  68. data/examples/verify_quickstart_lifecycle/app.rb +3 -3
  69. data/examples/verify_readme_usage/README.md +6 -0
  70. data/examples/verify_readme_usage/app.rb +3 -3
  71. data/examples/widget_barchart/README.md +6 -0
  72. data/examples/widget_barchart/app.rb +2 -2
  73. data/examples/widget_block/README.md +7 -1
  74. data/examples/widget_block/app.rb +2 -2
  75. data/examples/widget_box/README.md +6 -0
  76. data/examples/widget_box/app.rb +9 -6
  77. data/examples/widget_calendar/README.md +6 -0
  78. data/examples/widget_calendar/app.rb +2 -2
  79. data/examples/widget_canvas/README.md +4 -0
  80. data/examples/widget_canvas/app.rb +2 -2
  81. data/examples/widget_cell/README.md +6 -0
  82. data/examples/widget_cell/app.rb +2 -3
  83. data/examples/widget_center/README.md +4 -0
  84. data/examples/widget_center/app.rb +2 -2
  85. data/examples/widget_chart/README.md +6 -0
  86. data/examples/widget_chart/app.rb +2 -2
  87. data/examples/widget_gauge/README.md +6 -0
  88. data/examples/widget_gauge/app.rb +2 -2
  89. data/examples/widget_layout_split/README.md +6 -0
  90. data/examples/widget_layout_split/app.rb +9 -3
  91. data/examples/widget_line_gauge/README.md +6 -0
  92. data/examples/widget_line_gauge/app.rb +2 -2
  93. data/examples/widget_list/README.md +6 -0
  94. data/examples/widget_list/app.rb +2 -2
  95. data/examples/widget_map/README.md +8 -2
  96. data/examples/widget_map/app.rb +2 -2
  97. data/examples/widget_overlay/README.md +7 -1
  98. data/examples/widget_overlay/app.rb +2 -2
  99. data/examples/widget_popup/README.md +6 -0
  100. data/examples/widget_popup/app.rb +2 -2
  101. data/examples/widget_ratatui_logo/README.md +6 -0
  102. data/examples/widget_ratatui_logo/app.rb +2 -3
  103. data/examples/widget_ratatui_mascot/README.md +6 -0
  104. data/examples/widget_ratatui_mascot/app.rb +2 -2
  105. data/examples/widget_rect/README.md +12 -0
  106. data/examples/widget_rect/app.rb +40 -26
  107. data/examples/widget_render/README.md +6 -0
  108. data/examples/widget_render/app.rb +2 -2
  109. data/examples/widget_render/app.rbs +41 -0
  110. data/examples/widget_rich_text/README.md +6 -0
  111. data/examples/widget_rich_text/app.rb +2 -2
  112. data/examples/widget_scroll_text/README.md +6 -0
  113. data/examples/widget_scroll_text/app.rb +2 -2
  114. data/examples/widget_scrollbar/README.md +6 -0
  115. data/examples/widget_scrollbar/app.rb +2 -2
  116. data/examples/widget_sparkline/README.md +6 -0
  117. data/examples/widget_sparkline/app.rb +2 -2
  118. data/examples/widget_style_colors/README.md +6 -0
  119. data/examples/widget_style_colors/app.rb +2 -2
  120. data/examples/widget_table/README.md +8 -2
  121. data/examples/widget_table/app.rb +2 -2
  122. data/examples/widget_tabs/README.md +6 -0
  123. data/examples/widget_tabs/app.rb +2 -2
  124. data/examples/widget_text_width/README.md +6 -0
  125. data/examples/widget_text_width/app.rb +4 -4
  126. data/ext/ratatui_ruby/Cargo.lock +1 -1
  127. data/ext/ratatui_ruby/Cargo.toml +1 -1
  128. data/ext/ratatui_ruby/extconf.rb +2 -2
  129. data/ext/ratatui_ruby/src/events.rs +1 -0
  130. data/ext/ratatui_ruby/src/rendering.rs +1 -1
  131. data/ext/ratatui_ruby/src/style.rs +0 -8
  132. data/ext/ratatui_ruby/src/widgets/chart.rs +0 -118
  133. data/ext/ratatui_ruby/src/widgets/list_state.rs +36 -0
  134. data/lib/ratatui_ruby/buffer/cell.rb +34 -2
  135. data/lib/ratatui_ruby/buffer.rb +2 -2
  136. data/lib/ratatui_ruby/cell.rb +34 -2
  137. data/lib/ratatui_ruby/event/focus_gained.rb +26 -2
  138. data/lib/ratatui_ruby/event/focus_lost.rb +26 -2
  139. data/lib/ratatui_ruby/event/key/character.rb +18 -2
  140. data/lib/ratatui_ruby/event/key/media.rb +2 -2
  141. data/lib/ratatui_ruby/event/key/modifier.rb +10 -2
  142. data/lib/ratatui_ruby/event/key/navigation.rb +2 -2
  143. data/lib/ratatui_ruby/event/key/system.rb +2 -2
  144. data/lib/ratatui_ruby/event/key.rb +114 -2
  145. data/lib/ratatui_ruby/event/mouse.rb +42 -2
  146. data/lib/ratatui_ruby/event/none.rb +10 -2
  147. data/lib/ratatui_ruby/event/paste.rb +34 -2
  148. data/lib/ratatui_ruby/event/resize.rb +34 -2
  149. data/lib/ratatui_ruby/event/sync.rb +52 -0
  150. data/lib/ratatui_ruby/event.rb +32 -2
  151. data/lib/ratatui_ruby/frame.rb +74 -2
  152. data/lib/ratatui_ruby/layout/constraint.rb +193 -2
  153. data/lib/ratatui_ruby/layout/layout.rb +47 -2
  154. data/lib/ratatui_ruby/layout/rect.rb +403 -2
  155. data/lib/ratatui_ruby/layout.rb +2 -2
  156. data/lib/ratatui_ruby/list_state.rb +113 -2
  157. data/lib/ratatui_ruby/output_guard.rb +26 -3
  158. data/lib/ratatui_ruby/schema/bar_chart/bar.rb +2 -2
  159. data/lib/ratatui_ruby/schema/bar_chart/bar_group.rb +2 -2
  160. data/lib/ratatui_ruby/schema/bar_chart.rb +50 -2
  161. data/lib/ratatui_ruby/schema/block.rb +21 -15
  162. data/lib/ratatui_ruby/schema/calendar.rb +2 -2
  163. data/lib/ratatui_ruby/schema/canvas.rb +10 -2
  164. data/lib/ratatui_ruby/schema/center.rb +10 -2
  165. data/lib/ratatui_ruby/schema/chart.rb +2 -28
  166. data/lib/ratatui_ruby/schema/clear.rb +10 -2
  167. data/lib/ratatui_ruby/schema/constraint.rb +58 -2
  168. data/lib/ratatui_ruby/schema/cursor.rb +10 -2
  169. data/lib/ratatui_ruby/schema/draw.rb +10 -2
  170. data/lib/ratatui_ruby/schema/gauge.rb +2 -2
  171. data/lib/ratatui_ruby/schema/layout.rb +18 -2
  172. data/lib/ratatui_ruby/schema/line_gauge.rb +2 -2
  173. data/lib/ratatui_ruby/schema/list.rb +10 -2
  174. data/lib/ratatui_ruby/schema/list_item.rb +10 -2
  175. data/lib/ratatui_ruby/schema/overlay.rb +10 -2
  176. data/lib/ratatui_ruby/schema/paragraph.rb +10 -2
  177. data/lib/ratatui_ruby/schema/ratatui_logo.rb +2 -2
  178. data/lib/ratatui_ruby/schema/ratatui_mascot.rb +2 -2
  179. data/lib/ratatui_ruby/schema/rect.rb +58 -2
  180. data/lib/ratatui_ruby/schema/row.rb +10 -2
  181. data/lib/ratatui_ruby/schema/scrollbar.rb +2 -2
  182. data/lib/ratatui_ruby/schema/shape/label.rb +10 -2
  183. data/lib/ratatui_ruby/schema/sparkline.rb +10 -2
  184. data/lib/ratatui_ruby/schema/style.rb +18 -2
  185. data/lib/ratatui_ruby/schema/table.rb +2 -2
  186. data/lib/ratatui_ruby/schema/tabs.rb +2 -2
  187. data/lib/ratatui_ruby/schema/text.rb +34 -2
  188. data/lib/ratatui_ruby/scrollbar_state.rb +10 -2
  189. data/lib/ratatui_ruby/style/style.rb +18 -2
  190. data/lib/ratatui_ruby/style.rb +2 -2
  191. data/lib/ratatui_ruby/synthetic_events.rb +86 -0
  192. data/lib/ratatui_ruby/table_state.rb +10 -2
  193. data/lib/ratatui_ruby/terminal_lifecycle.rb +18 -3
  194. data/lib/ratatui_ruby/test_helper/event_injection.rb +62 -2
  195. data/lib/ratatui_ruby/test_helper/snapshot.rb +74 -9
  196. data/lib/ratatui_ruby/test_helper/style_assertions.rb +98 -2
  197. data/lib/ratatui_ruby/test_helper/terminal.rb +50 -2
  198. data/lib/ratatui_ruby/test_helper/test_doubles.rb +18 -2
  199. data/lib/ratatui_ruby/test_helper.rb +10 -2
  200. data/lib/ratatui_ruby/tui/buffer_factories.rb +2 -2
  201. data/lib/ratatui_ruby/tui/canvas_factories.rb +2 -2
  202. data/lib/ratatui_ruby/tui/core.rb +2 -2
  203. data/lib/ratatui_ruby/tui/layout_factories.rb +32 -2
  204. data/lib/ratatui_ruby/tui/state_factories.rb +2 -2
  205. data/lib/ratatui_ruby/tui/style_factories.rb +2 -2
  206. data/lib/ratatui_ruby/tui/text_factories.rb +2 -2
  207. data/lib/ratatui_ruby/tui/widget_factories.rb +2 -2
  208. data/lib/ratatui_ruby/tui.rb +11 -3
  209. data/lib/ratatui_ruby/version.rb +3 -3
  210. data/lib/ratatui_ruby/widgets/bar_chart/bar.rb +2 -2
  211. data/lib/ratatui_ruby/widgets/bar_chart/bar_group.rb +2 -2
  212. data/lib/ratatui_ruby/widgets/bar_chart.rb +58 -2
  213. data/lib/ratatui_ruby/widgets/block.rb +37 -15
  214. data/lib/ratatui_ruby/widgets/calendar.rb +2 -2
  215. data/lib/ratatui_ruby/widgets/canvas.rb +10 -2
  216. data/lib/ratatui_ruby/widgets/cell.rb +10 -2
  217. data/lib/ratatui_ruby/widgets/center.rb +10 -2
  218. data/lib/ratatui_ruby/widgets/chart.rb +2 -28
  219. data/lib/ratatui_ruby/widgets/clear.rb +10 -2
  220. data/lib/ratatui_ruby/widgets/cursor.rb +10 -2
  221. data/lib/ratatui_ruby/widgets/gauge.rb +16 -2
  222. data/lib/ratatui_ruby/widgets/line_gauge.rb +16 -2
  223. data/lib/ratatui_ruby/widgets/list.rb +41 -2
  224. data/lib/ratatui_ruby/widgets/list_item.rb +10 -2
  225. data/lib/ratatui_ruby/widgets/overlay.rb +10 -2
  226. data/lib/ratatui_ruby/widgets/paragraph.rb +10 -2
  227. data/lib/ratatui_ruby/widgets/ratatui_logo.rb +2 -2
  228. data/lib/ratatui_ruby/widgets/ratatui_mascot.rb +2 -2
  229. data/lib/ratatui_ruby/widgets/row.rb +10 -2
  230. data/lib/ratatui_ruby/widgets/scrollbar.rb +2 -2
  231. data/lib/ratatui_ruby/widgets/shape/label.rb +10 -2
  232. data/lib/ratatui_ruby/widgets/sparkline.rb +10 -2
  233. data/lib/ratatui_ruby/widgets/table.rb +62 -2
  234. data/lib/ratatui_ruby/widgets/tabs.rb +2 -2
  235. data/lib/ratatui_ruby/widgets.rb +2 -2
  236. data/lib/ratatui_ruby.rb +101 -9
  237. data/sig/examples/app_all_events/view.rbs +7 -1
  238. data/sig/examples/app_all_events/view_state.rbs +7 -1
  239. data/sig/examples/app_color_picker/app.rbs +5 -0
  240. data/sig/examples/app_stateful_interaction/app.rbs +7 -1
  241. data/sig/examples/verify_quickstart_dsl/app.rbs +7 -1
  242. data/sig/examples/verify_quickstart_lifecycle/app.rbs +7 -1
  243. data/sig/examples/verify_readme_usage/app.rbs +7 -1
  244. data/sig/examples/widget_block_demo/app.rbs +6 -0
  245. data/sig/examples/widget_box_demo/app.rbs +7 -1
  246. data/sig/examples/widget_calendar_demo/app.rbs +7 -1
  247. data/sig/examples/widget_cell_demo/app.rbs +7 -1
  248. data/sig/examples/widget_chart_demo/app.rbs +7 -1
  249. data/sig/examples/widget_gauge_demo/app.rbs +7 -1
  250. data/sig/examples/widget_layout_split/app.rbs +7 -1
  251. data/sig/examples/widget_line_gauge_demo/app.rbs +7 -1
  252. data/sig/examples/widget_list_demo/app.rbs +5 -0
  253. data/sig/examples/widget_map_demo/app.rbs +7 -1
  254. data/sig/examples/widget_popup_demo/app.rbs +7 -1
  255. data/sig/examples/widget_ratatui_logo_demo/app.rbs +7 -1
  256. data/sig/examples/widget_ratatui_mascot_demo/app.rbs +7 -1
  257. data/sig/examples/widget_rect/app.rbs +7 -1
  258. data/sig/examples/widget_render/app.rbs +7 -1
  259. data/sig/examples/widget_rich_text/app.rbs +7 -1
  260. data/sig/examples/widget_scroll_text/app.rbs +7 -1
  261. data/sig/examples/widget_scrollbar_demo/app.rbs +7 -1
  262. data/sig/examples/widget_sparkline_demo/app.rbs +7 -1
  263. data/sig/examples/widget_style_colors/app.rbs +7 -1
  264. data/sig/examples/widget_table_demo/app.rbs +7 -1
  265. data/sig/examples/widget_text_width/app.rbs +7 -1
  266. data/sig/ratatui_ruby/event.rbs +7 -1
  267. data/sig/ratatui_ruby/frame.rbs +15 -3
  268. data/sig/ratatui_ruby/list_state.rbs +11 -1
  269. data/sig/ratatui_ruby/ratatui_ruby.rbs +8 -2
  270. data/sig/ratatui_ruby/schema/bar_chart/bar.rbs +7 -1
  271. data/sig/ratatui_ruby/schema/bar_chart/bar_group.rbs +6 -0
  272. data/sig/ratatui_ruby/schema/bar_chart.rbs +6 -0
  273. data/sig/ratatui_ruby/schema/block.rbs +7 -1
  274. data/sig/ratatui_ruby/schema/calendar.rbs +6 -0
  275. data/sig/ratatui_ruby/schema/canvas.rbs +6 -0
  276. data/sig/ratatui_ruby/schema/center.rbs +6 -0
  277. data/sig/ratatui_ruby/schema/chart.rbs +6 -9
  278. data/sig/ratatui_ruby/schema/constraint.rbs +14 -0
  279. data/sig/ratatui_ruby/schema/cursor.rbs +6 -0
  280. data/sig/ratatui_ruby/schema/draw.rbs +6 -0
  281. data/sig/ratatui_ruby/schema/gauge.rbs +9 -1
  282. data/sig/ratatui_ruby/schema/layout.rbs +6 -0
  283. data/sig/ratatui_ruby/schema/line_gauge.rbs +9 -1
  284. data/sig/ratatui_ruby/schema/list.rbs +9 -1
  285. data/sig/ratatui_ruby/schema/list_item.rbs +7 -1
  286. data/sig/ratatui_ruby/schema/overlay.rbs +6 -0
  287. data/sig/ratatui_ruby/schema/paragraph.rbs +6 -0
  288. data/sig/ratatui_ruby/schema/ratatui_logo.rbs +6 -0
  289. data/sig/ratatui_ruby/schema/ratatui_mascot.rbs +5 -0
  290. data/sig/ratatui_ruby/schema/rect.rbs +30 -0
  291. data/sig/ratatui_ruby/schema/row.rbs +7 -1
  292. data/sig/ratatui_ruby/schema/scrollbar.rbs +6 -0
  293. data/sig/ratatui_ruby/schema/sparkline.rbs +6 -0
  294. data/sig/ratatui_ruby/schema/style.rbs +7 -1
  295. data/sig/ratatui_ruby/schema/table.rbs +11 -1
  296. data/sig/ratatui_ruby/schema/tabs.rbs +6 -0
  297. data/sig/ratatui_ruby/schema/text.rbs +7 -1
  298. data/sig/ratatui_ruby/scrollbar_state.rbs +7 -1
  299. data/sig/ratatui_ruby/session.rbs +7 -1
  300. data/sig/ratatui_ruby/table_state.rbs +7 -1
  301. data/sig/ratatui_ruby/test_helper/event_injection.rbs +7 -1
  302. data/sig/ratatui_ruby/test_helper/snapshot.rbs +7 -1
  303. data/sig/ratatui_ruby/test_helper/style_assertions.rbs +7 -1
  304. data/sig/ratatui_ruby/test_helper/terminal.rbs +7 -1
  305. data/sig/ratatui_ruby/test_helper/test_doubles.rbs +7 -1
  306. data/sig/ratatui_ruby/test_helper.rbs +7 -1
  307. data/sig/ratatui_ruby/tui/buffer_factories.rbs +7 -1
  308. data/sig/ratatui_ruby/tui/canvas_factories.rbs +7 -1
  309. data/sig/ratatui_ruby/tui/core.rbs +7 -1
  310. data/sig/ratatui_ruby/tui/layout_factories.rbs +7 -1
  311. data/sig/ratatui_ruby/tui/state_factories.rbs +7 -1
  312. data/sig/ratatui_ruby/tui/style_factories.rbs +7 -1
  313. data/sig/ratatui_ruby/tui/text_factories.rbs +7 -1
  314. data/sig/ratatui_ruby/tui/widget_factories.rbs +7 -1
  315. data/sig/ratatui_ruby/tui.rbs +7 -1
  316. data/sig/ratatui_ruby/version.rbs +6 -0
  317. data/tasks/autodoc/examples.rb +1 -1
  318. data/tasks/autodoc/member.rb +1 -1
  319. data/tasks/autodoc/name.rb +1 -1
  320. data/tasks/bump/cargo_lockfile.rb +1 -1
  321. data/tasks/bump/changelog.rb +1 -1
  322. data/tasks/bump/header.rb +1 -1
  323. data/tasks/bump/history.rb +1 -1
  324. data/tasks/bump/links.rb +1 -1
  325. data/tasks/bump/manifest.rb +1 -1
  326. data/tasks/bump/ruby_gem.rb +1 -1
  327. data/tasks/bump/sem_ver.rb +1 -1
  328. data/tasks/bump/unreleased_section.rb +1 -1
  329. data/tasks/license/headers_md.rb +223 -0
  330. data/tasks/license/headers_rb.rb +210 -0
  331. data/tasks/license/license_utils.rb +130 -0
  332. data/tasks/license/snippets_md.rb +315 -0
  333. data/tasks/license/snippets_rdoc.rb +150 -0
  334. data/tasks/license.rake +91 -0
  335. data/tasks/rdoc_config.rb +1 -1
  336. data/tasks/resources/build.yml.erb +13 -7
  337. data/tasks/sourcehut.rake +3 -1
  338. data/tasks/terminal_preview/app_screenshot.rb +1 -1
  339. data/tasks/terminal_preview/crash_report.rb +1 -1
  340. data/tasks/terminal_preview/example_app.rb +1 -1
  341. data/tasks/terminal_preview/launcher_script.rb +1 -1
  342. data/tasks/terminal_preview/preview_collection.rb +1 -1
  343. data/tasks/terminal_preview/preview_timing.rb +1 -1
  344. data/tasks/terminal_preview/safety_confirmation.rb +1 -1
  345. data/tasks/terminal_preview/saved_screenshot.rb +1 -1
  346. data/tasks/terminal_preview/system_appearance.rb +1 -1
  347. data/tasks/terminal_preview/terminal_window.rb +1 -1
  348. data/tasks/terminal_preview/window_id.rb +1 -1
  349. data/tasks/website/index_page.rb +1 -1
  350. data/tasks/website/version.rb +1 -1
  351. data/tasks/website/version_menu.rb +1 -1
  352. data/tasks/website/versioned_documentation.rb +1 -1
  353. data/tasks/website/website.rb +1 -1
  354. metadata +15 -3
  355. data/doc/migration/v0_7_0.md +0 -236
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: AGPL-3.0-or-later
4
+ # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
+ # SPDX-License-Identifier: LGPL-3.0-or-later
6
6
  #++
7
7
 
8
8
  module RatatuiRuby
@@ -20,9 +20,17 @@ module RatatuiRuby
20
20
  #
21
21
  # === Example
22
22
  #
23
+ #--
24
+ # SPDX-SnippetBegin
25
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
26
+ # SPDX-License-Identifier: MIT-0
27
+ #++
23
28
  # if event.mouse? && event.down? && event.button == "left"
24
29
  # puts "Left click at #{event.x}, #{event.y}"
25
30
  # end
31
+ #--
32
+ # SPDX-SnippetEnd
33
+ #++
26
34
  class Mouse < Event
27
35
  # The kind of event (<tt>"down"</tt>, <tt>"up"</tt>, <tt>"drag"</tt>, <tt>"moved"</tt>, <tt>"scroll_up"</tt>, <tt>"scroll_down"</tt>).
28
36
  #
@@ -38,8 +46,16 @@ module RatatuiRuby
38
46
  attr_reader :y
39
47
  # The button pressed (<tt>"left"</tt>, <tt>"right"</tt>, <tt>"middle"</tt>, <tt>"none"</tt>).
40
48
  #
49
+ #--
50
+ # SPDX-SnippetBegin
51
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
52
+ # SPDX-License-Identifier: MIT-0
53
+ #++
41
54
  # puts event.button # => "left"
42
55
  #
56
+ #--
57
+ # SPDX-SnippetEnd
58
+ #++
43
59
  # Can be <tt>nil</tt>, which is treated as <tt>"none"</tt>.
44
60
  attr_reader :button
45
61
  # List of active modifiers.
@@ -49,9 +65,17 @@ module RatatuiRuby
49
65
 
50
66
  # Returns true for Mouse events.
51
67
  #
68
+ #--
69
+ # SPDX-SnippetBegin
70
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
71
+ # SPDX-License-Identifier: MIT-0
72
+ #++
52
73
  # event.mouse? # => true
53
74
  # event.key? # => false
54
75
  # event.resize? # => false
76
+ #--
77
+ # SPDX-SnippetEnd
78
+ #++
55
79
  def mouse?
56
80
  true
57
81
  end
@@ -98,19 +122,35 @@ module RatatuiRuby
98
122
 
99
123
  # Returns true if scroll wheel moved down.
100
124
  #
125
+ #--
126
+ # SPDX-SnippetBegin
127
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
128
+ # SPDX-License-Identifier: MIT-0
129
+ #++
101
130
  # if event.scroll_down?
102
131
  # scroll_offset += 1
103
132
  # end
133
+ #--
134
+ # SPDX-SnippetEnd
135
+ #++
104
136
  def scroll_down?
105
137
  @kind == "scroll_down"
106
138
  end
107
139
 
108
140
  # Deconstructs the event for pattern matching.
109
141
  #
142
+ #--
143
+ # SPDX-SnippetBegin
144
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
145
+ # SPDX-License-Identifier: MIT-0
146
+ #++
110
147
  # case event
111
148
  # in type: :mouse, kind: "down", x:, y:
112
149
  # puts "Click at #{x}, #{y}"
113
150
  # end
151
+ #--
152
+ # SPDX-SnippetEnd
153
+ #++
114
154
  def deconstruct_keys(keys)
115
155
  { type: :mouse, kind: @kind, x: @x, y: @y, button: @button, modifiers: @modifiers }
116
156
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: AGPL-3.0-or-later
4
+ # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
+ # SPDX-License-Identifier: LGPL-3.0-or-later
6
6
  #++
7
7
 
8
8
  module RatatuiRuby
@@ -23,10 +23,18 @@ module RatatuiRuby
23
23
  #
24
24
  # === Predicate Example
25
25
  #
26
+ #--
27
+ # SPDX-SnippetBegin
28
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
29
+ # SPDX-License-Identifier: MIT-0
30
+ #++
26
31
  # event = RatatuiRuby.poll_event
27
32
  # break if event.ctrl_c?
28
33
  # redraw if event.none?
29
34
  #
35
+ #--
36
+ # SPDX-SnippetEnd
37
+ #++
30
38
  # === Pattern Matching Example
31
39
  #
32
40
  # redraw if RatatuiRuby.poll_event in type: :none
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: AGPL-3.0-or-later
4
+ # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
+ # SPDX-License-Identifier: LGPL-3.0-or-later
6
6
  #++
7
7
 
8
8
  module RatatuiRuby
@@ -20,15 +20,31 @@ module RatatuiRuby
20
20
  # === Examples
21
21
  #
22
22
  # Using predicates:
23
+ #--
24
+ # SPDX-SnippetBegin
25
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
26
+ # SPDX-License-Identifier: MIT-0
27
+ #++
23
28
  # if event.paste?
24
29
  # puts "Pasted: #{event.content}"
25
30
  # end
26
31
  #
32
+ #--
33
+ # SPDX-SnippetEnd
34
+ #++
27
35
  # Using pattern matching:
36
+ #--
37
+ # SPDX-SnippetBegin
38
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
39
+ # SPDX-License-Identifier: MIT-0
40
+ #++
28
41
  # case event
29
42
  # in type: :paste, content:
30
43
  # puts "Pasted: #{content}"
31
44
  # end
45
+ #--
46
+ # SPDX-SnippetEnd
47
+ #++
32
48
  class Paste < Event
33
49
  # The pasted content.
34
50
  #
@@ -37,9 +53,17 @@ module RatatuiRuby
37
53
 
38
54
  # Returns true for Paste events.
39
55
  #
56
+ #--
57
+ # SPDX-SnippetBegin
58
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
59
+ # SPDX-License-Identifier: MIT-0
60
+ #++
40
61
  # event.paste? # => true
41
62
  # event.key? # => false
42
63
  # event.resize? # => false
64
+ #--
65
+ # SPDX-SnippetEnd
66
+ #++
43
67
  def paste?
44
68
  true
45
69
  end
@@ -54,10 +78,18 @@ module RatatuiRuby
54
78
 
55
79
  # Deconstructs the event for pattern matching.
56
80
  #
81
+ #--
82
+ # SPDX-SnippetBegin
83
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
84
+ # SPDX-License-Identifier: MIT-0
85
+ #++
57
86
  # case event
58
87
  # in type: :paste, content:
59
88
  # puts "User pasted: #{content}"
60
89
  # end
90
+ #--
91
+ # SPDX-SnippetEnd
92
+ #++
61
93
  def deconstruct_keys(keys)
62
94
  { type: :paste, content: @content }
63
95
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: AGPL-3.0-or-later
4
+ # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
+ # SPDX-License-Identifier: LGPL-3.0-or-later
6
6
  #++
7
7
 
8
8
  module RatatuiRuby
@@ -21,15 +21,31 @@ module RatatuiRuby
21
21
  # === Examples
22
22
  #
23
23
  # Using predicates:
24
+ #--
25
+ # SPDX-SnippetBegin
26
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
27
+ # SPDX-License-Identifier: MIT-0
28
+ #++
24
29
  # if event.resize?
25
30
  # puts "Resized to #{event.width}x#{event.height}"
26
31
  # end
27
32
  #
33
+ #--
34
+ # SPDX-SnippetEnd
35
+ #++
28
36
  # Using pattern matching:
37
+ #--
38
+ # SPDX-SnippetBegin
39
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
40
+ # SPDX-License-Identifier: MIT-0
41
+ #++
29
42
  # case event
30
43
  # in type: :resize, width:, height:
31
44
  # puts "Resized to #{width}x#{height}"
32
45
  # end
46
+ #--
47
+ # SPDX-SnippetEnd
48
+ #++
33
49
  class Resize < Event
34
50
  # New terminal width in columns.
35
51
  #
@@ -43,9 +59,17 @@ module RatatuiRuby
43
59
 
44
60
  # Returns true for Resize events.
45
61
  #
62
+ #--
63
+ # SPDX-SnippetBegin
64
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
65
+ # SPDX-License-Identifier: MIT-0
66
+ #++
46
67
  # event.resize? # => true
47
68
  # event.key? # => false
48
69
  # event.mouse? # => false
70
+ #--
71
+ # SPDX-SnippetEnd
72
+ #++
49
73
  def resize?
50
74
  true
51
75
  end
@@ -63,10 +87,18 @@ module RatatuiRuby
63
87
 
64
88
  # Deconstructs the event for pattern matching.
65
89
  #
90
+ #--
91
+ # SPDX-SnippetBegin
92
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
93
+ # SPDX-License-Identifier: MIT-0
94
+ #++
66
95
  # case event
67
96
  # in type: :resize, width:, height:
68
97
  # puts "Resized to #{width}x#{height}"
69
98
  # end
99
+ #--
100
+ # SPDX-SnippetEnd
101
+ #++
70
102
  def deconstruct_keys(keys)
71
103
  { type: :resize, width: @width, height: @height }
72
104
  end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ #--
4
+ # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
+ # SPDX-License-Identifier: LGPL-3.0-or-later
6
+ #++
7
+
8
+ module RatatuiRuby
9
+ class Event
10
+ # Synthetic event for synchronizing async operations in tests.
11
+ #
12
+ # Testing async behavior is tricky. You inject an event, but results arrive
13
+ # later. By the time you assert, the async work may not have completed.
14
+ #
15
+ # When a runtime (Tea, Kit) encounters this event, it should wait for all
16
+ # pending async operations to complete before processing the next event.
17
+ # This enables deterministic testing without changing production code paths.
18
+ #
19
+ # Inject this event between user actions and assertions to ensure async
20
+ # results have been processed:
21
+ #
22
+ # === Example
23
+ #
24
+ #--
25
+ # SPDX-SnippetBegin
26
+ # SPDX-FileCopyrightText: 2026 Kerrick Long
27
+ # SPDX-License-Identifier: MIT-0
28
+ #++
29
+ # inject_key("s") # Triggers async command
30
+ # inject_sync # Wait for command to complete
31
+ # inject_key(:q) # Quit after seeing results
32
+ # Tea.run(...)
33
+ # assert_snapshots("after_s_with_results")
34
+ #
35
+ #--
36
+ # SPDX-SnippetEnd
37
+ #++
38
+ # This is not "test mode"—it's a real event that runtimes handle.
39
+ # Production apps could use it too (e.g., "ensure saves complete before quit").
40
+ class Sync < Event
41
+ # Returns true for Sync events.
42
+ def sync?
43
+ true
44
+ end
45
+
46
+ # Deconstructs the event for pattern matching.
47
+ def deconstruct_keys(keys)
48
+ { type: :sync }
49
+ end
50
+ end
51
+ end
52
+ end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: AGPL-3.0-or-later
4
+ # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
+ # SPDX-License-Identifier: LGPL-3.0-or-later
6
6
  #++
7
7
 
8
8
  module RatatuiRuby
@@ -26,6 +26,11 @@ module RatatuiRuby
26
26
  # Use <tt>case...in</tt> to dispatch on every possible event type. This ensures
27
27
  # you handle every case without needing an +else+ clause:
28
28
  #
29
+ #--
30
+ # SPDX-SnippetBegin
31
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
32
+ # SPDX-License-Identifier: MIT-0
33
+ #++
29
34
  # case RatatuiRuby.poll_event
30
35
  # in { type: :key, code: "q" }
31
36
  # break
@@ -47,10 +52,18 @@ module RatatuiRuby
47
52
  # # Idle
48
53
  # end
49
54
  #
55
+ #--
56
+ # SPDX-SnippetEnd
57
+ #++
50
58
  # == Predicates
51
59
  #
52
60
  # Check event types with predicates without pattern matching:
53
61
  #
62
+ #--
63
+ # SPDX-SnippetBegin
64
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
65
+ # SPDX-License-Identifier: MIT-0
66
+ #++
54
67
  # event = RatatuiRuby.poll_event
55
68
  # if event.key?
56
69
  # puts "Key pressed"
@@ -59,6 +72,9 @@ module RatatuiRuby
59
72
  # elsif event.mouse?
60
73
  # puts "Mouse event"
61
74
  # end
75
+ #--
76
+ # SPDX-SnippetEnd
77
+ #++
62
78
  class Event
63
79
  # Returns true if this is a None event.
64
80
  def none?
@@ -95,6 +111,11 @@ module RatatuiRuby
95
111
  false
96
112
  end
97
113
 
114
+ # Returns true if this is a Sync event.
115
+ def sync?
116
+ false
117
+ end
118
+
98
119
  # Responds to dynamic predicate methods for key checks.
99
120
  # All non-Key events return false for any key predicate.
100
121
  def method_missing(name, *args, &block)
@@ -114,10 +135,18 @@ module RatatuiRuby
114
135
  #
115
136
  # Keys argument is unused but required by the protocol.
116
137
  #
138
+ #--
139
+ # SPDX-SnippetBegin
140
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
141
+ # SPDX-License-Identifier: MIT-0
142
+ #++
117
143
  # case event
118
144
  # in type: :key, code:
119
145
  # puts "Key: #{code}"
120
146
  # end
147
+ #--
148
+ # SPDX-SnippetEnd
149
+ #++
121
150
  def deconstruct_keys(keys)
122
151
  {}
123
152
  end
@@ -131,3 +160,4 @@ require_relative "event/resize"
131
160
  require_relative "event/paste"
132
161
  require_relative "event/focus_gained"
133
162
  require_relative "event/focus_lost"
163
+ require_relative "event/sync"
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: AGPL-3.0-or-later
4
+ # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
+ # SPDX-License-Identifier: LGPL-3.0-or-later
6
6
  #++
7
7
 
8
8
  module RatatuiRuby
@@ -30,13 +30,26 @@ module RatatuiRuby
30
30
  #
31
31
  # Basic usage with a single widget:
32
32
  #
33
+ #--
34
+ # SPDX-SnippetBegin
35
+ # SPDX-FileCopyrightText: 2026 Kerrick Long
36
+ # SPDX-License-Identifier: MIT-0
37
+ #++
33
38
  # RatatuiRuby.draw do |frame|
34
39
  # paragraph = RatatuiRuby::Widgets::Paragraph.new(text: "Hello, world!")
35
40
  # frame.render_widget(paragraph, frame.area)
36
41
  # end
37
42
  #
43
+ #--
44
+ # SPDX-SnippetEnd
45
+ #++
38
46
  # Using Layout.split for multi-region layouts:
39
47
  #
48
+ #--
49
+ # SPDX-SnippetBegin
50
+ # SPDX-FileCopyrightText: 2026 Kerrick Long
51
+ # SPDX-License-Identifier: MIT-0
52
+ #++
40
53
  # RatatuiRuby.draw do |frame|
41
54
  # sidebar, main = RatatuiRuby::Layout.split(
42
55
  # frame.area,
@@ -53,6 +66,9 @@ module RatatuiRuby
53
66
  # # Store rects for hit testing — no duplication!
54
67
  # @regions = { sidebar: sidebar, main: main }
55
68
  # end
69
+ #--
70
+ # SPDX-SnippetEnd
71
+ #++
56
72
  class Frame
57
73
  ##
58
74
  # :method: area
@@ -65,10 +81,18 @@ module RatatuiRuby
65
81
  #
66
82
  # === Example
67
83
  #
84
+ #--
85
+ # SPDX-SnippetBegin
86
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
87
+ # SPDX-License-Identifier: MIT-0
88
+ #++
68
89
  # RatatuiRuby.draw do |frame|
69
90
  # puts "Terminal size: #{frame.area.width}x#{frame.area.height}"
70
91
  # end
71
92
  #
93
+ #--
94
+ # SPDX-SnippetEnd
95
+ #++
72
96
  # (Native method implemented in Rust)
73
97
 
74
98
  ##
@@ -83,15 +107,31 @@ module RatatuiRuby
83
107
  # [widget]
84
108
  # The widget to render (Paragraph, Layout, List, Table, etc.).
85
109
  # [area]
110
+ #--
111
+ # SPDX-SnippetBegin
112
+ # SPDX-FileCopyrightText: 2025 Kerrick Long
113
+ # SPDX-License-Identifier: MIT-0
114
+ #++
86
115
  # A Rect specifying where to render the widget.
87
116
  #
117
+ #--
118
+ # SPDX-SnippetEnd
119
+ #++
88
120
  # === Example
89
121
  #
122
+ #--
123
+ # SPDX-SnippetBegin
124
+ # SPDX-FileCopyrightText: 2026 Kerrick Long
125
+ # SPDX-License-Identifier: MIT-0
126
+ #++
90
127
  # RatatuiRuby.draw do |frame|
91
128
  # para = RatatuiRuby::Widgets::Paragraph.new(text: "Content")
92
129
  # frame.render_widget(para, frame.area)
93
130
  # end
94
131
  #
132
+ #--
133
+ # SPDX-SnippetEnd
134
+ #++
95
135
  # (Native method implemented in Rust)
96
136
 
97
137
  ##
@@ -116,10 +156,23 @@ module RatatuiRuby
116
156
  # [area]
117
157
  # The Rect area to render into.
118
158
  # [state]
159
+ #--
160
+ # SPDX-SnippetBegin
161
+ # SPDX-FileCopyrightText: 2026 Kerrick Long
162
+ # SPDX-License-Identifier: MIT-0
163
+ #++
119
164
  # The mutable state object (Output) (e.g., RatatuiRuby::ListState).
120
165
  #
166
+ #--
167
+ # SPDX-SnippetEnd
168
+ #++
121
169
  # === Example
122
170
  #
171
+ #--
172
+ # SPDX-SnippetBegin
173
+ # SPDX-FileCopyrightText: 2026 Kerrick Long
174
+ # SPDX-License-Identifier: MIT-0
175
+ #++
123
176
  # # Initialize state once (outside the loop)
124
177
  # @list_state = RatatuiRuby::ListState.new
125
178
  #
@@ -131,6 +184,9 @@ module RatatuiRuby
131
184
  # # Read back the offset calculated by Ratatui
132
185
  # puts @list_state.offset
133
186
  #
187
+ #--
188
+ # SPDX-SnippetEnd
189
+ #++
134
190
  # (Native method implemented in Rust)
135
191
 
136
192
  ##
@@ -151,12 +207,25 @@ module RatatuiRuby
151
207
  # [x]
152
208
  # Column position (<tt>0</tt> = leftmost column).
153
209
  # [y]
210
+ #--
211
+ # SPDX-SnippetBegin
212
+ # SPDX-FileCopyrightText: 2026 Kerrick Long
213
+ # SPDX-License-Identifier: MIT-0
214
+ #++
154
215
  # Row position (<tt>0</tt> = topmost row).
155
216
  #
217
+ #--
218
+ # SPDX-SnippetEnd
219
+ #++
156
220
  # === Example
157
221
  #
158
222
  # Position the cursor at the end of typed text in a login form:
159
223
  #
224
+ #--
225
+ # SPDX-SnippetBegin
226
+ # SPDX-FileCopyrightText: 2026 Kerrick Long
227
+ # SPDX-License-Identifier: MIT-0
228
+ #++
160
229
  # PREFIX = "Username: [ "
161
230
  # username = "alice"
162
231
  #
@@ -175,6 +244,9 @@ module RatatuiRuby
175
244
  # frame.set_cursor_position(cursor_x, cursor_y)
176
245
  # end
177
246
  #
247
+ #--
248
+ # SPDX-SnippetEnd
249
+ #++
178
250
  # See also:
179
251
  # - {Component-based implementation using Frame API}[link:/examples/app_color_picker/app_rb.html]
180
252
  # - {Declarative implementation using Tree API}[link:/examples/app_login_form/app_rb.html]