ratatui_ruby 0.3.1 → 0.5.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 (350) hide show
  1. checksums.yaml +4 -4
  2. data/.builds/ruby-3.2.yml +14 -12
  3. data/.builds/ruby-3.3.yml +14 -12
  4. data/.builds/ruby-3.4.yml +14 -12
  5. data/.builds/ruby-4.0.0.yml +14 -12
  6. data/AGENTS.md +89 -132
  7. data/CHANGELOG.md +223 -1
  8. data/README.md +23 -16
  9. data/REUSE.toml +20 -0
  10. data/doc/application_architecture.md +176 -0
  11. data/doc/application_testing.md +17 -10
  12. data/doc/contributors/design/ruby_frontend.md +11 -7
  13. data/doc/contributors/developing_examples.md +261 -0
  14. data/doc/contributors/documentation_style.md +104 -0
  15. data/doc/contributors/dwim_dx.md +366 -0
  16. data/doc/contributors/index.md +2 -0
  17. data/doc/custom.css +14 -0
  18. data/doc/event_handling.md +125 -0
  19. data/doc/images/app_all_events.png +0 -0
  20. data/doc/images/app_analytics.png +0 -0
  21. data/doc/images/app_color_picker.png +0 -0
  22. data/doc/images/app_custom_widget.png +0 -0
  23. data/doc/images/app_login_form.png +0 -0
  24. data/doc/images/app_map_demo.png +0 -0
  25. data/doc/images/app_mouse_events.png +0 -0
  26. data/doc/images/app_table_select.png +0 -0
  27. data/doc/images/verify_quickstart_dsl.png +0 -0
  28. data/doc/images/verify_quickstart_layout.png +0 -0
  29. data/doc/images/verify_quickstart_lifecycle.png +0 -0
  30. data/doc/images/verify_readme_usage.png +0 -0
  31. data/doc/images/widget_barchart_demo.png +0 -0
  32. data/doc/images/widget_block_padding.png +0 -0
  33. data/doc/images/widget_block_titles.png +0 -0
  34. data/doc/images/widget_box_demo.png +0 -0
  35. data/doc/images/widget_calendar_demo.png +0 -0
  36. data/doc/images/widget_cell_demo.png +0 -0
  37. data/doc/images/widget_chart_demo.png +0 -0
  38. data/doc/images/widget_gauge_demo.png +0 -0
  39. data/doc/images/widget_layout_split.png +0 -0
  40. data/doc/images/widget_line_gauge_demo.png +0 -0
  41. data/doc/images/widget_list_demo.png +0 -0
  42. data/doc/images/widget_list_styles.png +0 -0
  43. data/doc/images/widget_popup_demo.png +0 -0
  44. data/doc/images/widget_ratatui_logo_demo.png +0 -0
  45. data/doc/images/widget_ratatui_mascot_demo.png +0 -0
  46. data/doc/images/widget_rect.png +0 -0
  47. data/doc/images/widget_render.png +0 -0
  48. data/doc/images/widget_rich_text.png +0 -0
  49. data/doc/images/widget_scroll_text.png +0 -0
  50. data/doc/images/widget_scrollbar_demo.png +0 -0
  51. data/doc/images/widget_sparkline_demo.png +0 -0
  52. data/doc/images/widget_style_colors.png +0 -0
  53. data/doc/images/widget_table_flex.png +0 -0
  54. data/doc/images/widget_tabs_demo.png +0 -0
  55. data/doc/index.md +1 -0
  56. data/doc/interactive_design.md +116 -0
  57. data/doc/quickstart.md +186 -84
  58. data/examples/app_all_events/README.md +81 -0
  59. data/examples/app_all_events/app.rb +93 -0
  60. data/examples/app_all_events/model/event_color_cycle.rb +41 -0
  61. data/examples/app_all_events/model/event_entry.rb +75 -0
  62. data/examples/app_all_events/model/events.rb +180 -0
  63. data/examples/app_all_events/model/highlight.rb +57 -0
  64. data/examples/app_all_events/model/timestamp.rb +54 -0
  65. data/examples/app_all_events/test/snapshots/after_focus_lost.txt +24 -0
  66. data/examples/app_all_events/test/snapshots/after_focus_regained.txt +24 -0
  67. data/examples/app_all_events/test/snapshots/after_horizontal_resize.txt +24 -0
  68. data/examples/app_all_events/test/snapshots/after_key_a.txt +24 -0
  69. data/examples/app_all_events/test/snapshots/after_key_ctrl_x.txt +24 -0
  70. data/examples/app_all_events/test/snapshots/after_mouse_click.txt +24 -0
  71. data/examples/app_all_events/test/snapshots/after_mouse_drag.txt +24 -0
  72. data/examples/app_all_events/test/snapshots/after_multiple_events.txt +24 -0
  73. data/examples/app_all_events/test/snapshots/after_paste.txt +24 -0
  74. data/examples/app_all_events/test/snapshots/after_resize.txt +24 -0
  75. data/examples/app_all_events/test/snapshots/after_right_click.txt +24 -0
  76. data/examples/app_all_events/test/snapshots/after_vertical_resize.txt +24 -0
  77. data/examples/app_all_events/test/snapshots/initial_state.txt +24 -0
  78. data/examples/app_all_events/view/app_view.rb +78 -0
  79. data/examples/app_all_events/view/controls_view.rb +50 -0
  80. data/examples/app_all_events/view/counts_view.rb +55 -0
  81. data/examples/app_all_events/view/live_view.rb +69 -0
  82. data/examples/app_all_events/view/log_view.rb +60 -0
  83. data/{lib/ratatui_ruby/output.rb → examples/app_all_events/view.rb} +1 -1
  84. data/examples/app_all_events/view_state.rb +42 -0
  85. data/examples/app_color_picker/README.md +94 -0
  86. data/examples/app_color_picker/app.rb +112 -0
  87. data/examples/app_color_picker/clipboard.rb +84 -0
  88. data/examples/app_color_picker/color.rb +191 -0
  89. data/examples/app_color_picker/copy_dialog.rb +170 -0
  90. data/examples/app_color_picker/harmony.rb +56 -0
  91. data/examples/app_color_picker/input.rb +142 -0
  92. data/examples/app_color_picker/palette.rb +80 -0
  93. data/examples/app_color_picker/scene.rb +201 -0
  94. data/examples/app_login_form/app.rb +108 -0
  95. data/examples/app_map_demo/app.rb +93 -0
  96. data/examples/app_table_select/app.rb +201 -0
  97. data/examples/verify_quickstart_dsl/app.rb +45 -0
  98. data/examples/verify_quickstart_layout/app.rb +69 -0
  99. data/examples/verify_quickstart_lifecycle/app.rb +48 -0
  100. data/examples/verify_readme_usage/app.rb +34 -0
  101. data/examples/widget_barchart_demo/app.rb +238 -0
  102. data/examples/widget_block_padding/app.rb +67 -0
  103. data/examples/widget_block_titles/app.rb +69 -0
  104. data/examples/widget_box_demo/app.rb +250 -0
  105. data/examples/widget_calendar_demo/app.rb +109 -0
  106. data/examples/widget_cell_demo/app.rb +104 -0
  107. data/examples/widget_chart_demo/app.rb +213 -0
  108. data/examples/widget_gauge_demo/app.rb +212 -0
  109. data/examples/widget_layout_split/app.rb +246 -0
  110. data/examples/widget_line_gauge_demo/app.rb +217 -0
  111. data/examples/widget_list_demo/app.rb +382 -0
  112. data/examples/widget_list_styles/app.rb +141 -0
  113. data/examples/widget_popup_demo/app.rb +104 -0
  114. data/examples/widget_ratatui_logo_demo/app.rb +103 -0
  115. data/examples/widget_ratatui_mascot_demo/app.rb +93 -0
  116. data/examples/widget_rect/app.rb +205 -0
  117. data/examples/widget_render/app.rb +184 -0
  118. data/examples/widget_rich_text/app.rb +137 -0
  119. data/examples/widget_scroll_text/app.rb +108 -0
  120. data/examples/widget_scrollbar_demo/app.rb +153 -0
  121. data/examples/widget_sparkline_demo/app.rb +274 -0
  122. data/examples/widget_style_colors/app.rb +102 -0
  123. data/examples/widget_table_flex/app.rb +95 -0
  124. data/examples/widget_tabs_demo/app.rb +167 -0
  125. data/ext/ratatui_ruby/Cargo.lock +889 -115
  126. data/ext/ratatui_ruby/Cargo.toml +4 -3
  127. data/ext/ratatui_ruby/clippy.toml +7 -0
  128. data/ext/ratatui_ruby/extconf.rb +7 -0
  129. data/ext/ratatui_ruby/src/events.rs +293 -219
  130. data/ext/ratatui_ruby/src/frame.rs +115 -0
  131. data/ext/ratatui_ruby/src/lib.rs +105 -24
  132. data/ext/ratatui_ruby/src/rendering.rs +94 -10
  133. data/ext/ratatui_ruby/src/style.rs +357 -93
  134. data/ext/ratatui_ruby/src/terminal.rs +121 -31
  135. data/ext/ratatui_ruby/src/text.rs +178 -0
  136. data/ext/ratatui_ruby/src/widgets/barchart.rs +99 -24
  137. data/ext/ratatui_ruby/src/widgets/block.rs +32 -3
  138. data/ext/ratatui_ruby/src/widgets/calendar.rs +45 -44
  139. data/ext/ratatui_ruby/src/widgets/canvas.rs +44 -9
  140. data/ext/ratatui_ruby/src/widgets/chart.rs +79 -27
  141. data/ext/ratatui_ruby/src/widgets/clear.rs +3 -1
  142. data/ext/ratatui_ruby/src/widgets/gauge.rs +11 -4
  143. data/ext/ratatui_ruby/src/widgets/layout.rs +223 -15
  144. data/ext/ratatui_ruby/src/widgets/line_gauge.rs +92 -0
  145. data/ext/ratatui_ruby/src/widgets/list.rs +114 -11
  146. data/ext/ratatui_ruby/src/widgets/mod.rs +3 -0
  147. data/ext/ratatui_ruby/src/widgets/overlay.rs +4 -2
  148. data/ext/ratatui_ruby/src/widgets/paragraph.rs +35 -13
  149. data/ext/ratatui_ruby/src/widgets/ratatui_logo.rs +40 -0
  150. data/ext/ratatui_ruby/src/widgets/ratatui_mascot.rs +51 -0
  151. data/ext/ratatui_ruby/src/widgets/scrollbar.rs +61 -7
  152. data/ext/ratatui_ruby/src/widgets/sparkline.rs +73 -6
  153. data/ext/ratatui_ruby/src/widgets/table.rs +177 -64
  154. data/ext/ratatui_ruby/src/widgets/tabs.rs +105 -5
  155. data/lib/ratatui_ruby/cell.rb +166 -0
  156. data/lib/ratatui_ruby/event/focus_gained.rb +49 -0
  157. data/lib/ratatui_ruby/event/focus_lost.rb +50 -0
  158. data/lib/ratatui_ruby/event/key.rb +211 -0
  159. data/lib/ratatui_ruby/event/mouse.rb +124 -0
  160. data/lib/ratatui_ruby/event/none.rb +43 -0
  161. data/lib/ratatui_ruby/event/paste.rb +71 -0
  162. data/lib/ratatui_ruby/event/resize.rb +80 -0
  163. data/lib/ratatui_ruby/event.rb +131 -0
  164. data/lib/ratatui_ruby/frame.rb +87 -0
  165. data/lib/ratatui_ruby/schema/bar_chart/bar.rb +45 -0
  166. data/lib/ratatui_ruby/schema/bar_chart/bar_group.rb +23 -0
  167. data/lib/ratatui_ruby/schema/bar_chart.rb +226 -17
  168. data/lib/ratatui_ruby/schema/block.rb +178 -11
  169. data/lib/ratatui_ruby/schema/calendar.rb +70 -14
  170. data/lib/ratatui_ruby/schema/canvas.rb +213 -46
  171. data/lib/ratatui_ruby/schema/center.rb +46 -8
  172. data/lib/ratatui_ruby/schema/chart.rb +134 -32
  173. data/lib/ratatui_ruby/schema/clear.rb +22 -53
  174. data/lib/ratatui_ruby/schema/constraint.rb +72 -12
  175. data/lib/ratatui_ruby/schema/cursor.rb +23 -5
  176. data/lib/ratatui_ruby/schema/draw.rb +53 -0
  177. data/lib/ratatui_ruby/schema/gauge.rb +56 -12
  178. data/lib/ratatui_ruby/schema/layout.rb +91 -9
  179. data/lib/ratatui_ruby/schema/line_gauge.rb +78 -0
  180. data/lib/ratatui_ruby/schema/list.rb +92 -16
  181. data/lib/ratatui_ruby/schema/overlay.rb +29 -3
  182. data/lib/ratatui_ruby/schema/paragraph.rb +82 -25
  183. data/lib/ratatui_ruby/schema/ratatui_logo.rb +29 -0
  184. data/lib/ratatui_ruby/schema/ratatui_mascot.rb +34 -0
  185. data/lib/ratatui_ruby/schema/rect.rb +59 -10
  186. data/lib/ratatui_ruby/schema/scrollbar.rb +127 -19
  187. data/lib/ratatui_ruby/schema/shape/label.rb +66 -0
  188. data/lib/ratatui_ruby/schema/sparkline.rb +120 -12
  189. data/lib/ratatui_ruby/schema/style.rb +39 -11
  190. data/lib/ratatui_ruby/schema/table.rb +109 -18
  191. data/lib/ratatui_ruby/schema/tabs.rb +71 -10
  192. data/lib/ratatui_ruby/schema/text.rb +90 -0
  193. data/lib/ratatui_ruby/session/autodoc.rb +417 -0
  194. data/lib/ratatui_ruby/session.rb +163 -0
  195. data/lib/ratatui_ruby/test_helper.rb +322 -13
  196. data/lib/ratatui_ruby/version.rb +1 -1
  197. data/lib/ratatui_ruby.rb +184 -38
  198. data/sig/examples/app_all_events/app.rbs +11 -0
  199. data/sig/examples/app_all_events/model/event_entry.rbs +16 -0
  200. data/sig/examples/app_all_events/model/events.rbs +15 -0
  201. data/sig/examples/app_all_events/model/timestamp.rbs +11 -0
  202. data/sig/examples/app_all_events/view/app_view.rbs +8 -0
  203. data/sig/examples/app_all_events/view/controls_view.rbs +6 -0
  204. data/sig/examples/app_all_events/view/counts_view.rbs +6 -0
  205. data/sig/examples/app_all_events/view/live_view.rbs +6 -0
  206. data/sig/examples/app_all_events/view/log_view.rbs +6 -0
  207. data/sig/examples/app_all_events/view.rbs +8 -0
  208. data/sig/examples/app_all_events/view_state.rbs +15 -0
  209. data/sig/examples/app_color_picker/app.rbs +12 -0
  210. data/sig/examples/app_login_form/app.rbs +11 -0
  211. data/sig/examples/app_map_demo/app.rbs +11 -0
  212. data/sig/examples/app_table_select/app.rbs +11 -0
  213. data/sig/examples/verify_quickstart_dsl/app.rbs +11 -0
  214. data/sig/examples/verify_quickstart_lifecycle/app.rbs +11 -0
  215. data/sig/examples/verify_readme_usage/app.rbs +11 -0
  216. data/sig/examples/widget_block_padding/app.rbs +11 -0
  217. data/sig/examples/widget_block_titles/app.rbs +11 -0
  218. data/sig/examples/widget_box_demo/app.rbs +11 -0
  219. data/sig/examples/widget_calendar_demo/app.rbs +11 -0
  220. data/sig/examples/widget_cell_demo/app.rbs +11 -0
  221. data/sig/examples/widget_chart_demo/app.rbs +11 -0
  222. data/sig/examples/widget_gauge_demo/app.rbs +11 -0
  223. data/sig/examples/widget_layout_split/app.rbs +10 -0
  224. data/sig/examples/widget_line_gauge_demo/app.rbs +11 -0
  225. data/sig/examples/widget_list_demo/app.rbs +12 -0
  226. data/sig/examples/widget_list_styles/app.rbs +11 -0
  227. data/sig/examples/widget_popup_demo/app.rbs +11 -0
  228. data/sig/examples/widget_ratatui_logo_demo/app.rbs +11 -0
  229. data/sig/examples/widget_ratatui_mascot_demo/app.rbs +11 -0
  230. data/sig/examples/widget_rect/app.rbs +12 -0
  231. data/sig/examples/widget_render/app.rbs +10 -0
  232. data/sig/examples/widget_rich_text/app.rbs +11 -0
  233. data/sig/examples/widget_scroll_text/app.rbs +11 -0
  234. data/sig/examples/widget_scrollbar_demo/app.rbs +11 -0
  235. data/sig/examples/widget_sparkline_demo/app.rbs +10 -0
  236. data/sig/examples/widget_style_colors/app.rbs +14 -0
  237. data/sig/examples/widget_table_flex/app.rbs +11 -0
  238. data/sig/ratatui_ruby/event.rbs +69 -0
  239. data/sig/ratatui_ruby/frame.rbs +9 -0
  240. data/sig/ratatui_ruby/ratatui_ruby.rbs +5 -3
  241. data/sig/ratatui_ruby/schema/bar_chart/bar.rbs +16 -0
  242. data/sig/ratatui_ruby/schema/bar_chart/bar_group.rbs +13 -0
  243. data/sig/ratatui_ruby/schema/bar_chart.rbs +20 -2
  244. data/sig/ratatui_ruby/schema/block.rbs +5 -4
  245. data/sig/ratatui_ruby/schema/calendar.rbs +6 -2
  246. data/sig/ratatui_ruby/schema/canvas.rbs +52 -39
  247. data/sig/ratatui_ruby/schema/center.rbs +3 -3
  248. data/sig/ratatui_ruby/schema/chart.rbs +8 -5
  249. data/sig/ratatui_ruby/schema/constraint.rbs +8 -5
  250. data/sig/ratatui_ruby/schema/cursor.rbs +1 -1
  251. data/sig/ratatui_ruby/schema/draw.rbs +27 -0
  252. data/sig/ratatui_ruby/schema/gauge.rbs +4 -2
  253. data/sig/ratatui_ruby/schema/layout.rbs +11 -1
  254. data/sig/ratatui_ruby/schema/line_gauge.rbs +16 -0
  255. data/sig/ratatui_ruby/schema/list.rbs +5 -1
  256. data/sig/ratatui_ruby/schema/paragraph.rbs +4 -1
  257. data/sig/ratatui_ruby/schema/ratatui_logo.rbs +8 -0
  258. data/sig/ratatui_ruby/{buffer.rbs → schema/ratatui_mascot.rbs} +4 -3
  259. data/sig/ratatui_ruby/schema/rect.rbs +2 -1
  260. data/sig/ratatui_ruby/schema/scrollbar.rbs +18 -2
  261. data/sig/ratatui_ruby/schema/sparkline.rbs +6 -2
  262. data/sig/ratatui_ruby/schema/table.rbs +8 -1
  263. data/sig/ratatui_ruby/schema/tabs.rbs +5 -1
  264. data/sig/ratatui_ruby/schema/text.rbs +22 -0
  265. data/sig/ratatui_ruby/session.rbs +94 -0
  266. data/tasks/autodoc/inventory.rb +61 -0
  267. data/tasks/autodoc/member.rb +56 -0
  268. data/tasks/autodoc/name.rb +19 -0
  269. data/tasks/autodoc/notice.rb +26 -0
  270. data/tasks/autodoc/rbs.rb +38 -0
  271. data/tasks/autodoc/rdoc.rb +45 -0
  272. data/tasks/autodoc.rake +47 -0
  273. data/tasks/bump/history.rb +2 -2
  274. data/tasks/doc.rake +600 -6
  275. data/tasks/example_viewer.html.erb +172 -0
  276. data/tasks/lint.rake +8 -4
  277. data/tasks/resources/build.yml.erb +13 -11
  278. data/tasks/resources/index.html.erb +6 -0
  279. data/tasks/sourcehut.rake +4 -4
  280. data/tasks/terminal_preview/app_screenshot.rb +33 -0
  281. data/tasks/terminal_preview/crash_report.rb +52 -0
  282. data/tasks/terminal_preview/example_app.rb +25 -0
  283. data/tasks/terminal_preview/launcher_script.rb +46 -0
  284. data/tasks/terminal_preview/preview_collection.rb +58 -0
  285. data/tasks/terminal_preview/preview_timing.rb +22 -0
  286. data/tasks/terminal_preview/safety_confirmation.rb +56 -0
  287. data/tasks/terminal_preview/saved_screenshot.rb +53 -0
  288. data/tasks/terminal_preview/system_appearance.rb +11 -0
  289. data/tasks/terminal_preview/terminal_window.rb +136 -0
  290. data/tasks/terminal_preview/window_id.rb +14 -0
  291. data/tasks/terminal_preview.rake +28 -0
  292. data/tasks/test.rake +2 -2
  293. data/tasks/website/index_page.rb +3 -3
  294. data/tasks/website/version.rb +10 -10
  295. data/tasks/website/version_menu.rb +10 -12
  296. data/tasks/website/versioned_documentation.rb +49 -17
  297. data/tasks/website/website.rb +6 -8
  298. data/tasks/website.rake +4 -4
  299. metadata +206 -54
  300. data/LICENSES/BSD-2-Clause.txt +0 -9
  301. data/doc/images/examples-analytics.rb.png +0 -0
  302. data/doc/images/examples-box_demo.rb.png +0 -0
  303. data/doc/images/examples-calendar_demo.rb.png +0 -0
  304. data/doc/images/examples-chart_demo.rb.png +0 -0
  305. data/doc/images/examples-custom_widget.rb.png +0 -0
  306. data/doc/images/examples-dashboard.rb.png +0 -0
  307. data/doc/images/examples-list_styles.rb.png +0 -0
  308. data/doc/images/examples-login_form.rb.png +0 -0
  309. data/doc/images/examples-map_demo.rb.png +0 -0
  310. data/doc/images/examples-mouse_events.rb.png +0 -0
  311. data/doc/images/examples-popup_demo.rb.gif +0 -0
  312. data/doc/images/examples-quickstart_lifecycle.rb.png +0 -0
  313. data/doc/images/examples-scroll_text.rb.png +0 -0
  314. data/doc/images/examples-scrollbar_demo.rb.png +0 -0
  315. data/doc/images/examples-stock_ticker.rb.png +0 -0
  316. data/doc/images/examples-system_monitor.rb.png +0 -0
  317. data/doc/images/examples-table_select.rb.png +0 -0
  318. data/examples/analytics.rb +0 -88
  319. data/examples/box_demo.rb +0 -71
  320. data/examples/calendar_demo.rb +0 -55
  321. data/examples/chart_demo.rb +0 -84
  322. data/examples/custom_widget.rb +0 -43
  323. data/examples/dashboard.rb +0 -72
  324. data/examples/list_styles.rb +0 -66
  325. data/examples/login_form.rb +0 -115
  326. data/examples/map_demo.rb +0 -58
  327. data/examples/mouse_events.rb +0 -95
  328. data/examples/popup_demo.rb +0 -105
  329. data/examples/quickstart_dsl.rb +0 -30
  330. data/examples/quickstart_lifecycle.rb +0 -40
  331. data/examples/readme_usage.rb +0 -21
  332. data/examples/scroll_text.rb +0 -74
  333. data/examples/scrollbar_demo.rb +0 -75
  334. data/examples/stock_ticker.rb +0 -93
  335. data/examples/system_monitor.rb +0 -94
  336. data/examples/table_select.rb +0 -70
  337. data/examples/test_analytics.rb +0 -65
  338. data/examples/test_box_demo.rb +0 -38
  339. data/examples/test_calendar_demo.rb +0 -66
  340. data/examples/test_dashboard.rb +0 -38
  341. data/examples/test_list_styles.rb +0 -61
  342. data/examples/test_login_form.rb +0 -63
  343. data/examples/test_map_demo.rb +0 -100
  344. data/examples/test_popup_demo.rb +0 -62
  345. data/examples/test_scroll_text.rb +0 -130
  346. data/examples/test_stock_ticker.rb +0 -39
  347. data/examples/test_system_monitor.rb +0 -40
  348. data/examples/test_table_select.rb +0 -37
  349. data/ext/ratatui_ruby/src/buffer.rs +0 -54
  350. data/lib/ratatui_ruby/dsl.rb +0 -64
@@ -4,26 +4,54 @@
4
4
  # SPDX-License-Identifier: AGPL-3.0-or-later
5
5
 
6
6
  module RatatuiRuby
7
- # A value object that defines colors and modifiers for text or widgets.
7
+ # Defines colors and text modifiers.
8
8
  #
9
- # [fg] The foreground color (e.g., +:red+, +"#ff0000"+).
10
- # [bg] The background color (e.g., +:black+, +"#000000"+).
11
- # [modifiers] An array of symbols representing text modifiers:
12
- # [+:bold+, +:italic+, +:dim+, +:reversed+, +:underlined+, +:slow_blink+, +:rapid_blink+, +:crossed_out+, +:hidden+]
9
+ # The terminal is traditionally monochrome, but efficient interfaces use color to convey meaning.
10
+ # Red for errors. Green for success. Bold for headers.
11
+ #
12
+ # This value object encapsulates those choices. It applies foreground and background colors. It adds effects like italics or blinking.
13
+ #
14
+ # Use it to theme your application or highlight critical data.
15
+ #
16
+ # === Examples
17
+ #
18
+ # # Standard colors
19
+ # Style.new(fg: :red, bg: :white, modifiers: [:bold])
20
+ #
21
+ # # Hex colors
22
+ # Style.new(fg: "#ff00ff")
13
23
  class Style < Data.define(:fg, :bg, :modifiers)
24
+ ##
25
+ # :attr_reader: fg
26
+ # Foreground color.
27
+ #
28
+ # Symbol (<tt>:red</tt>) or Hex String (<tt>"#ffffff"</tt>).
29
+
30
+ ##
31
+ # :attr_reader: bg
32
+ # Background color.
33
+ #
34
+ # Symbol (<tt>:black</tt>) or Hex String (<tt>"#000000"</tt>).
35
+
36
+ ##
37
+ # :attr_reader: modifiers
38
+ # Text effects.
39
+ #
40
+ # Array of symbols: <tt>:bold</tt>, <tt>:dim</tt>, <tt>:italic</tt>, <tt>:underlined</tt>,
41
+ # <tt>:slow_blink</tt>, <tt>:rapid_blink</tt>, <tt>:reversed</tt>, <tt>:hidden</tt>, <tt>:crossed_out</tt>.
42
+
14
43
  # Creates a new Style.
15
44
  #
16
- # [fg] The foreground color (e.g., "red", "#ff0000").
17
- # [bg] The background color (e.g., "black", "#000000").
18
- # [modifiers] An array of symbols representing text modifiers.
45
+ # [fg] Color (Symbol/String).
46
+ # [bg] Color (Symbol/String).
47
+ # [modifiers] Array of Symbols.
19
48
  def initialize(fg: nil, bg: nil, modifiers: [])
20
49
  super
21
50
  end
22
51
 
23
- # Returns a default style with no colors or modifiers.
52
+ # Returns an empty style.
24
53
  #
25
- # Style.default
26
- # # => #<RatatuiRuby::Style fg=nil, bg=nil, modifiers=[]>
54
+ # Use this as a baseline to prevent style inheritance issues or when no styling is required.
27
55
  def self.default
28
56
  new
29
57
  end
@@ -4,27 +4,118 @@
4
4
  # SPDX-License-Identifier: AGPL-3.0-or-later
5
5
 
6
6
  module RatatuiRuby
7
- # A widget that displays data in a grid with rows and columns.
7
+ # Displays structured data in rows and columns.
8
8
  #
9
- # [header] An array of strings or Paragraphs representing the header row.
10
- # [rows] An array of arrays of strings or Paragraphs representing the data rows.
11
- # [widths] An array of Constraint objects defining column widths.
12
- # [highlight_style] The style for the selected row.
13
- # [highlight_symbol] The symbol to display in front of the selected row.
14
- # [selected_row] The index of the currently selected row, or nil if none.
15
- # [block] An optional Block widget to wrap the table.
16
- class Table < Data.define(:header, :rows, :widths, :highlight_style, :highlight_symbol, :selected_row, :block)
9
+ # Data is often multidimensional. You need to show relationships between fields (Name, Age, ID).
10
+ # Aligning columns manually in a monospaced environment is painful and error-prone.
11
+ #
12
+ # This widget creates a grid. It enforces column widths using constraints. It renders headers, rows, and footers aligned perfectly.
13
+ #
14
+ # Use it to display database records, logs, or file lists.
15
+ #
16
+ # {rdoc-image:/doc/images/widget_table_flex.png}[link:/examples/widget_table_flex/app_rb.html]
17
+ #
18
+ # === Example
19
+ #
20
+ # Run the interactive demo from the terminal:
21
+ #
22
+ # ruby examples/widget_table_flex/app.rb
23
+ class Table < Data.define(:header, :rows, :widths, :highlight_style, :highlight_symbol, :highlight_spacing, :column_highlight_style, :cell_highlight_style, :selected_row, :selected_column, :block, :footer, :flex, :style, :column_spacing)
24
+ ##
25
+ # :attr_reader: header
26
+ # Header row content (Array of Strings).
27
+
28
+ ##
29
+ # :attr_reader: rows
30
+ # Data rows (Array of Arrays of Strings).
31
+
32
+ ##
33
+ # :attr_reader: widths
34
+ # Column width constraints (Array of Constraint).
35
+
36
+ ##
37
+ # :attr_reader: highlight_style
38
+ # Style for the selected row.
39
+
40
+ ##
41
+ # :attr_reader: highlight_symbol
42
+ # Symbol for the selected row.
43
+
44
+ ##
45
+ # :attr_reader: highlight_spacing
46
+ # When to show the highlight symbol column (:always, :when_selected, :never).
47
+
48
+ ##
49
+ # :attr_reader: column_highlight_style
50
+ # Style for the selected column.
51
+
52
+ ##
53
+ # :attr_reader: cell_highlight_style
54
+ # Style for the selected cell (intersection of row and column).
55
+
56
+ ##
57
+ # :attr_reader: selected_row
58
+ # Index of the selected row (Integer or nil).
59
+
60
+ ##
61
+ # :attr_reader: selected_column
62
+ # Index of the selected column (Integer or nil).
63
+
64
+ ##
65
+ # :attr_reader: block
66
+ # Optional wrapping block.
67
+
68
+ ##
69
+ # :attr_reader: footer
70
+ # Footer row content (Array of Strings).
71
+
72
+ ##
73
+ # :attr_reader: flex
74
+ # Flex mode for column distribution.
75
+
76
+ ##
77
+ # :attr_reader: style
78
+ # Base style for the entire table.
79
+
80
+ ##
81
+ # :attr_reader: column_spacing
82
+ # Spacing between columns (Integer, default 1).
83
+
17
84
  # Creates a new Table.
18
85
  #
19
- # [header] An array of strings or Paragraphs representing the header row.
20
- # [rows] An array of arrays of strings or Paragraphs representing the data rows.
21
- # [widths] An array of Constraint objects defining column widths.
22
- # [highlight_style] The style for the selected row.
23
- # [highlight_symbol] The symbol to display in front of the selected row.
24
- # [selected_row] The index of the currently selected row, or nil if none.
25
- # [block] An optional Block widget to wrap the table.
26
- def initialize(header: nil, rows: [], widths: [], highlight_style: nil, highlight_symbol: "> ", selected_row: nil, block: nil)
27
- super
86
+ # [header] Array of strings/paragraphs.
87
+ # [rows] 2D Array of strings/paragraphs.
88
+ # [widths] Array of Constraints.
89
+ # [highlight_style] Style object.
90
+ # [highlight_symbol] String.
91
+ # [highlight_spacing] Symbol (optional, default: <tt>:when_selected</tt>).
92
+ # [column_highlight_style] Style object.
93
+ # [cell_highlight_style] Style object.
94
+ # [selected_row] Integer (nullable).
95
+ # [selected_column] Integer (nullable).
96
+ # [block] Block (optional).
97
+ # [footer] Array of strings/paragraphs (optional).
98
+ # [flex] Symbol (optional, default: <tt>:legacy</tt>).
99
+ # [style] Style object or Hash (optional).
100
+ # [column_spacing] Integer (optional, default: 1).
101
+ def initialize(header: nil, rows: [], widths: [], highlight_style: nil, highlight_symbol: "> ", highlight_spacing: :when_selected, column_highlight_style: nil, cell_highlight_style: nil, selected_row: nil, selected_column: nil, block: nil, footer: nil, flex: :legacy, style: nil, column_spacing: 1)
102
+ super(
103
+ header:,
104
+ rows:,
105
+ widths:,
106
+ highlight_style:,
107
+ highlight_symbol:,
108
+ highlight_spacing:,
109
+ column_highlight_style:,
110
+ cell_highlight_style:,
111
+ selected_row: selected_row.nil? ? nil : Integer(selected_row),
112
+ selected_column: selected_column.nil? ? nil : Integer(selected_column),
113
+ block:,
114
+ footer:,
115
+ flex:,
116
+ style:,
117
+ column_spacing: Integer(column_spacing)
118
+ )
28
119
  end
29
120
  end
30
121
  end
@@ -4,19 +4,80 @@
4
4
  # SPDX-License-Identifier: AGPL-3.0-or-later
5
5
 
6
6
  module RatatuiRuby
7
- # A widget that displays a set of tabs, one of which is selected.
7
+ # Displays a tab bar for navigation.
8
8
  #
9
- # [titles] Array of strings or lines to display as tab titles.
10
- # [selected_index] The index of the currently selected tab.
11
- # [block] Optional block widget to wrap the tabs.
12
- class Tabs < Data.define(:titles, :selected_index, :block)
9
+ # Screen real estate is limited. You cannot show everything at once. Segregating content into views is necessary for complex apps.
10
+ #
11
+ # This widget separates dimensions. It displays a row of titles, indicating which view is active.
12
+ #
13
+ # Use it at the top of your interface to switch between major modes or contexts.
14
+ #
15
+ # {rdoc-image:/doc/images/widget_tabs_demo.png}[link:/examples/widget_tabs_demo/app_rb.html]
16
+ #
17
+ # === Example
18
+ #
19
+ # Run the interactive demo from the terminal:
20
+ #
21
+ # ruby examples/widget_tabs_demo/app.rb
22
+ class Tabs < Data.define(:titles, :selected_index, :block, :divider, :highlight_style, :style, :padding_left, :padding_right)
23
+ ##
24
+ # :attr_reader: titles
25
+ # Tab titles (Array of Strings).
26
+
27
+ ##
28
+ # :attr_reader: selected_index
29
+ # Index of the active tab.
30
+
31
+ ##
32
+ # :attr_reader: block
33
+ # Optional wrapping block.
34
+
35
+ ##
36
+ # :attr_reader: divider
37
+ # Separator string between tabs.
38
+
39
+ ##
40
+ # :attr_reader: highlight_style
41
+ # Style for the selected tab title.
42
+
43
+ ##
44
+ # :attr_reader: style
45
+ # Base style for the tabs area.
46
+
47
+ ##
48
+ # :attr_reader: padding_left
49
+ # Left padding for the tabs area (Integer, default: 0).
50
+
51
+ ##
52
+ # :attr_reader: padding_right
53
+ # Right padding for the tabs area (Integer, default: 0).
54
+
13
55
  # Creates a new Tabs widget.
14
56
  #
15
- # [titles] Array of strings or lines to display as tab titles.
16
- # [selected_index] The index of the currently selected tab.
17
- # [block] Optional block widget to wrap the tabs.
18
- def initialize(titles: [], selected_index: 0, block: nil)
19
- super
57
+ # [titles] Array of Strings/Lines.
58
+ # [selected_index] Integer (default: 0).
59
+ # [block] Block (optional).
60
+ # [divider] String (optional).
61
+ # [highlight_style] Style (optional).
62
+ # [style] Style (optional).
63
+ # [padding_left] Integer (default: 0).
64
+ # [padding_right] Integer (default: 0).
65
+ def initialize(titles: [], selected_index: 0, block: nil, divider: nil, highlight_style: nil, style: nil, padding_left: 0, padding_right: 0)
66
+ super(
67
+ titles:,
68
+ selected_index: Integer(selected_index),
69
+ block:,
70
+ divider:,
71
+ highlight_style:,
72
+ style:,
73
+ padding_left: Integer(padding_left),
74
+ padding_right: Integer(padding_right)
75
+ )
76
+ end
77
+
78
+ # Returns the total width of the tabs.
79
+ def width
80
+ RatatuiRuby._tabs_width(self)
20
81
  end
21
82
  end
22
83
  end
@@ -0,0 +1,90 @@
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
+ module RatatuiRuby
7
+ # Namespace for rich text components (Span and Line).
8
+ # Distinct from canvas shapes and other Line usages.
9
+ module Text
10
+ # A styled string fragment.
11
+ #
12
+ # Text is rarely uniform. You need to bold a keyword, colorize an error, or dim a timestamp.
13
+ #
14
+ # This class attaches style to content. It pairs a string with visual attributes.
15
+ #
16
+ # combine spans into a {Line} to create rich text.
17
+ #
18
+ # === Examples
19
+ #
20
+ # Text::Span.new(content: "Error", style: Style.new(fg: :red, modifiers: [:bold]))
21
+ class Span < Data.define(:content, :style)
22
+ ##
23
+ # :attr_reader: content
24
+ # The text content.
25
+
26
+ ##
27
+ # :attr_reader: style
28
+ # The style to apply.
29
+
30
+ # Creates a new Span.
31
+ #
32
+ # [content] String.
33
+ # [style] Style object (optional).
34
+ def initialize(content:, style: nil)
35
+ super
36
+ end
37
+
38
+ # Concise helper for styling.
39
+ #
40
+ # Text::Span.styled("Bold", Style.new(modifiers: [:bold]))
41
+ def self.styled(content, style = nil)
42
+ new(content:, style:)
43
+ end
44
+ end
45
+
46
+ # A sequence of styled spans.
47
+ #
48
+ # Words form sentences. Spans form lines.
49
+ #
50
+ # This class composes multiple {Span} objects into a single horizontal row of text.
51
+ # It handles the layout of rich text fragments within the flow of a paragraph.
52
+ #
53
+ # Use it to build multi-colored headers, status messages, or log entries.
54
+ #
55
+ # === Examples
56
+ #
57
+ # Text::Line.new(
58
+ # spans: [
59
+ # Text::Span.styled("User: ", Style.new(modifiers: [:bold])),
60
+ # Text::Span.styled("kerrick", Style.new(fg: :blue))
61
+ # ]
62
+ # )
63
+ class Line < Data.define(:spans, :alignment)
64
+ ##
65
+ # :attr_reader: spans
66
+ # Array of Span objects.
67
+
68
+ ##
69
+ # :attr_reader: alignment
70
+ # Alignment within the container.
71
+ #
72
+ # <tt>:left</tt>, <tt>:center</tt>, or <tt>:right</tt>.
73
+
74
+ # Creates a new Line.
75
+ #
76
+ # [spans] Array of Span objects (or Strings).
77
+ # [alignment] Symbol (optional).
78
+ def initialize(spans: [], alignment: nil)
79
+ super
80
+ end
81
+
82
+ # Creates a simple line from a string.
83
+ #
84
+ # Text::Line.from_string("Hello")
85
+ def self.from_string(content, alignment: nil)
86
+ new(spans: [Span.new(content:, style: nil)], alignment:)
87
+ end
88
+ end
89
+ end
90
+ end