ratatui_ruby 0.9.1 → 0.10.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 (268) 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 +2 -1
  7. data/CHANGELOG.md +113 -0
  8. data/README.md +17 -0
  9. data/REUSE.toml +5 -0
  10. data/Rakefile +1 -1
  11. data/Steepfile +49 -0
  12. data/doc/concepts/debugging.md +401 -0
  13. data/doc/getting_started/quickstart.md +8 -3
  14. data/doc/images/app_all_events.png +0 -0
  15. data/doc/images/app_color_picker.png +0 -0
  16. data/doc/images/app_debugging_showcase.gif +0 -0
  17. data/doc/images/app_debugging_showcase.png +0 -0
  18. data/doc/images/app_login_form.png +0 -0
  19. data/doc/images/app_stateful_interaction.png +0 -0
  20. data/doc/images/verify_quickstart_dsl.png +0 -0
  21. data/doc/images/verify_quickstart_layout.png +0 -0
  22. data/doc/images/verify_quickstart_lifecycle.png +0 -0
  23. data/doc/images/verify_readme_usage.png +0 -0
  24. data/doc/images/widget_barchart.png +0 -0
  25. data/doc/images/widget_block.png +0 -0
  26. data/doc/images/widget_box.png +0 -0
  27. data/doc/images/widget_calendar.png +0 -0
  28. data/doc/images/widget_canvas.png +0 -0
  29. data/doc/images/widget_cell.png +0 -0
  30. data/doc/images/widget_center.png +0 -0
  31. data/doc/images/widget_chart.png +0 -0
  32. data/doc/images/widget_gauge.png +0 -0
  33. data/doc/images/widget_layout_split.png +0 -0
  34. data/doc/images/widget_line_gauge.png +0 -0
  35. data/doc/images/widget_list.png +0 -0
  36. data/doc/images/widget_map.png +0 -0
  37. data/doc/images/widget_overlay.png +0 -0
  38. data/doc/images/widget_popup.png +0 -0
  39. data/doc/images/widget_ratatui_logo.png +0 -0
  40. data/doc/images/widget_ratatui_mascot.png +0 -0
  41. data/doc/images/widget_rect.png +0 -0
  42. data/doc/images/widget_render.png +0 -0
  43. data/doc/images/widget_rich_text.png +0 -0
  44. data/doc/images/widget_scroll_text.png +0 -0
  45. data/doc/images/widget_scrollbar.png +0 -0
  46. data/doc/images/widget_sparkline.png +0 -0
  47. data/doc/images/widget_style_colors.png +0 -0
  48. data/doc/images/widget_table.png +0 -0
  49. data/doc/images/widget_tabs.png +0 -0
  50. data/doc/images/widget_text_width.png +0 -0
  51. data/doc/troubleshooting/async.md +4 -0
  52. data/examples/app_debugging_showcase/README.md +119 -0
  53. data/examples/app_debugging_showcase/app.rb +318 -0
  54. data/examples/widget_canvas/app.rb +19 -14
  55. data/examples/widget_gauge/app.rb +18 -3
  56. data/examples/widget_layout_split/app.rb +10 -4
  57. data/examples/widget_list/app.rb +22 -6
  58. data/examples/widget_rect/app.rb +7 -6
  59. data/examples/widget_rich_text/app.rb +62 -37
  60. data/examples/widget_style_colors/app.rb +26 -47
  61. data/examples/widget_table/app.rb +28 -5
  62. data/examples/widget_text_width/app.rb +6 -4
  63. data/ext/ratatui_ruby/Cargo.lock +48 -1
  64. data/ext/ratatui_ruby/Cargo.toml +6 -2
  65. data/ext/ratatui_ruby/src/color.rs +82 -0
  66. data/ext/ratatui_ruby/src/errors.rs +28 -0
  67. data/ext/ratatui_ruby/src/events.rs +15 -14
  68. data/ext/ratatui_ruby/src/lib.rs +56 -0
  69. data/ext/ratatui_ruby/src/rendering.rs +3 -1
  70. data/ext/ratatui_ruby/src/style.rs +48 -21
  71. data/ext/ratatui_ruby/src/terminal.rs +40 -9
  72. data/ext/ratatui_ruby/src/text.rs +21 -9
  73. data/ext/ratatui_ruby/src/widgets/chart.rs +2 -1
  74. data/ext/ratatui_ruby/src/widgets/layout.rs +90 -2
  75. data/ext/ratatui_ruby/src/widgets/list.rs +6 -5
  76. data/ext/ratatui_ruby/src/widgets/overlay.rs +2 -1
  77. data/ext/ratatui_ruby/src/widgets/table.rs +7 -6
  78. data/ext/ratatui_ruby/src/widgets/table_state.rs +55 -0
  79. data/ext/ratatui_ruby/src/widgets/tabs.rs +3 -2
  80. data/lib/ratatui_ruby/buffer/cell.rb +25 -15
  81. data/lib/ratatui_ruby/buffer.rb +134 -2
  82. data/lib/ratatui_ruby/cell.rb +13 -5
  83. data/lib/ratatui_ruby/debug.rb +215 -0
  84. data/lib/ratatui_ruby/event/key.rb +3 -2
  85. data/lib/ratatui_ruby/event.rb +1 -1
  86. data/lib/ratatui_ruby/layout/constraint.rb +49 -0
  87. data/lib/ratatui_ruby/layout/layout.rb +119 -13
  88. data/lib/ratatui_ruby/layout/position.rb +55 -0
  89. data/lib/ratatui_ruby/layout/rect.rb +188 -0
  90. data/lib/ratatui_ruby/layout/size.rb +55 -0
  91. data/lib/ratatui_ruby/layout.rb +4 -0
  92. data/lib/ratatui_ruby/style/color.rb +149 -0
  93. data/lib/ratatui_ruby/style/style.rb +51 -4
  94. data/lib/ratatui_ruby/style.rb +2 -0
  95. data/lib/ratatui_ruby/symbols.rb +435 -0
  96. data/lib/ratatui_ruby/synthetic_events.rb +1 -1
  97. data/lib/ratatui_ruby/table_state.rb +51 -0
  98. data/lib/ratatui_ruby/terminal_lifecycle.rb +2 -1
  99. data/lib/ratatui_ruby/test_helper/event_injection.rb +6 -1
  100. data/lib/ratatui_ruby/test_helper.rb +9 -0
  101. data/lib/ratatui_ruby/text/line.rb +245 -0
  102. data/lib/ratatui_ruby/text/span.rb +158 -0
  103. data/lib/ratatui_ruby/text.rb +99 -0
  104. data/lib/ratatui_ruby/tui/canvas_factories.rb +103 -0
  105. data/lib/ratatui_ruby/tui/core.rb +13 -2
  106. data/lib/ratatui_ruby/tui/layout_factories.rb +50 -3
  107. data/lib/ratatui_ruby/tui/state_factories.rb +42 -0
  108. data/lib/ratatui_ruby/tui/text_factories.rb +40 -0
  109. data/lib/ratatui_ruby/tui/widget_factories.rb +135 -60
  110. data/lib/ratatui_ruby/tui.rb +22 -1
  111. data/lib/ratatui_ruby/version.rb +1 -1
  112. data/lib/ratatui_ruby/widgets/bar_chart/bar.rb +2 -0
  113. data/lib/ratatui_ruby/widgets/bar_chart/bar_group.rb +2 -0
  114. data/lib/ratatui_ruby/widgets/bar_chart.rb +30 -20
  115. data/lib/ratatui_ruby/widgets/block.rb +14 -6
  116. data/lib/ratatui_ruby/widgets/calendar.rb +2 -0
  117. data/lib/ratatui_ruby/widgets/canvas.rb +56 -0
  118. data/lib/ratatui_ruby/widgets/cell.rb +2 -0
  119. data/lib/ratatui_ruby/widgets/center.rb +2 -0
  120. data/lib/ratatui_ruby/widgets/chart.rb +6 -0
  121. data/lib/ratatui_ruby/widgets/clear.rb +2 -0
  122. data/lib/ratatui_ruby/widgets/coerceable_widget.rb +77 -0
  123. data/lib/ratatui_ruby/widgets/cursor.rb +2 -0
  124. data/lib/ratatui_ruby/widgets/gauge.rb +61 -3
  125. data/lib/ratatui_ruby/widgets/line_gauge.rb +66 -4
  126. data/lib/ratatui_ruby/widgets/list.rb +87 -3
  127. data/lib/ratatui_ruby/widgets/list_item.rb +2 -0
  128. data/lib/ratatui_ruby/widgets/overlay.rb +2 -0
  129. data/lib/ratatui_ruby/widgets/paragraph.rb +4 -0
  130. data/lib/ratatui_ruby/widgets/ratatui_logo.rb +2 -0
  131. data/lib/ratatui_ruby/widgets/ratatui_mascot.rb +2 -0
  132. data/lib/ratatui_ruby/widgets/row.rb +45 -0
  133. data/lib/ratatui_ruby/widgets/scrollbar.rb +2 -0
  134. data/lib/ratatui_ruby/widgets/shape/label.rb +2 -0
  135. data/lib/ratatui_ruby/widgets/sparkline.rb +21 -13
  136. data/lib/ratatui_ruby/widgets/table.rb +13 -3
  137. data/lib/ratatui_ruby/widgets/tabs.rb +6 -4
  138. data/lib/ratatui_ruby/widgets.rb +1 -0
  139. data/lib/ratatui_ruby.rb +42 -11
  140. data/sig/examples/app_all_events/model/app_model.rbs +23 -0
  141. data/sig/examples/app_all_events/model/event_entry.rbs +15 -8
  142. data/sig/examples/app_all_events/model/timestamp.rbs +1 -1
  143. data/sig/examples/app_all_events/view.rbs +1 -1
  144. data/sig/examples/app_stateful_interaction/app.rbs +5 -5
  145. data/sig/examples/widget_block_demo/app.rbs +6 -6
  146. data/sig/manifest.yaml +5 -0
  147. data/sig/patches/data.rbs +26 -0
  148. data/sig/patches/debugger__.rbs +8 -0
  149. data/sig/ratatui_ruby/buffer/cell.rbs +46 -0
  150. data/sig/ratatui_ruby/buffer.rbs +18 -0
  151. data/sig/ratatui_ruby/cell.rbs +44 -0
  152. data/sig/ratatui_ruby/clear.rbs +18 -0
  153. data/sig/ratatui_ruby/constraint.rbs +26 -0
  154. data/sig/ratatui_ruby/debug.rbs +45 -0
  155. data/sig/ratatui_ruby/draw.rbs +30 -0
  156. data/sig/ratatui_ruby/event.rbs +68 -8
  157. data/sig/ratatui_ruby/frame.rbs +4 -4
  158. data/sig/ratatui_ruby/interfaces.rbs +25 -0
  159. data/sig/ratatui_ruby/layout/constraint.rbs +39 -0
  160. data/sig/ratatui_ruby/layout/layout.rbs +45 -0
  161. data/sig/ratatui_ruby/layout/position.rbs +18 -0
  162. data/sig/ratatui_ruby/layout/rect.rbs +64 -0
  163. data/sig/ratatui_ruby/layout/size.rbs +18 -0
  164. data/sig/ratatui_ruby/output_guard.rbs +23 -0
  165. data/sig/ratatui_ruby/ratatui_ruby.rbs +84 -5
  166. data/sig/ratatui_ruby/rect.rbs +17 -0
  167. data/sig/ratatui_ruby/style/color.rbs +22 -0
  168. data/sig/ratatui_ruby/style/style.rbs +29 -0
  169. data/sig/ratatui_ruby/symbols.rbs +141 -0
  170. data/sig/ratatui_ruby/synthetic_events.rbs +21 -0
  171. data/sig/ratatui_ruby/table_state.rbs +6 -0
  172. data/sig/ratatui_ruby/terminal_lifecycle.rbs +31 -0
  173. data/sig/ratatui_ruby/test_helper/event_injection.rbs +2 -2
  174. data/sig/ratatui_ruby/test_helper/snapshot.rbs +22 -3
  175. data/sig/ratatui_ruby/test_helper/style_assertions.rbs +8 -1
  176. data/sig/ratatui_ruby/test_helper/test_doubles.rbs +7 -3
  177. data/sig/ratatui_ruby/text/line.rbs +27 -0
  178. data/sig/ratatui_ruby/text/span.rbs +23 -0
  179. data/sig/ratatui_ruby/text.rbs +12 -0
  180. data/sig/ratatui_ruby/tui/buffer_factories.rbs +1 -1
  181. data/sig/ratatui_ruby/tui/canvas_factories.rbs +23 -5
  182. data/sig/ratatui_ruby/tui/core.rbs +2 -2
  183. data/sig/ratatui_ruby/tui/layout_factories.rbs +16 -2
  184. data/sig/ratatui_ruby/tui/state_factories.rbs +8 -3
  185. data/sig/ratatui_ruby/tui/style_factories.rbs +3 -1
  186. data/sig/ratatui_ruby/tui/text_factories.rbs +7 -4
  187. data/sig/ratatui_ruby/tui/widget_factories.rbs +123 -30
  188. data/sig/ratatui_ruby/widgets/bar_chart.rbs +95 -0
  189. data/sig/ratatui_ruby/widgets/block.rbs +51 -0
  190. data/sig/ratatui_ruby/widgets/calendar.rbs +45 -0
  191. data/sig/ratatui_ruby/widgets/canvas.rbs +95 -0
  192. data/sig/ratatui_ruby/widgets/chart.rbs +91 -0
  193. data/sig/ratatui_ruby/widgets/coerceable_widget.rbs +26 -0
  194. data/sig/ratatui_ruby/widgets/gauge.rbs +44 -0
  195. data/sig/ratatui_ruby/widgets/line_gauge.rbs +48 -0
  196. data/sig/ratatui_ruby/widgets/list.rbs +63 -0
  197. data/sig/ratatui_ruby/widgets/misc.rbs +158 -0
  198. data/sig/ratatui_ruby/widgets/paragraph.rbs +45 -0
  199. data/sig/ratatui_ruby/widgets/row.rbs +43 -0
  200. data/sig/ratatui_ruby/widgets/scrollbar.rbs +53 -0
  201. data/sig/ratatui_ruby/widgets/shape/label.rbs +37 -0
  202. data/sig/ratatui_ruby/widgets/sparkline.rbs +45 -0
  203. data/sig/ratatui_ruby/widgets/table.rbs +78 -0
  204. data/sig/ratatui_ruby/widgets/tabs.rbs +44 -0
  205. data/sig/ratatui_ruby/{schema/list_item.rbs → widgets.rbs} +4 -4
  206. data/tasks/steep.rake +11 -0
  207. metadata +80 -63
  208. data/doc/contributors/v1.0.0_blockers.md +0 -870
  209. data/doc/troubleshooting/debugging.md +0 -101
  210. data/lib/ratatui_ruby/schema/bar_chart/bar.rb +0 -47
  211. data/lib/ratatui_ruby/schema/bar_chart/bar_group.rb +0 -25
  212. data/lib/ratatui_ruby/schema/bar_chart.rb +0 -287
  213. data/lib/ratatui_ruby/schema/block.rb +0 -198
  214. data/lib/ratatui_ruby/schema/calendar.rb +0 -84
  215. data/lib/ratatui_ruby/schema/canvas.rb +0 -239
  216. data/lib/ratatui_ruby/schema/center.rb +0 -67
  217. data/lib/ratatui_ruby/schema/chart.rb +0 -159
  218. data/lib/ratatui_ruby/schema/clear.rb +0 -62
  219. data/lib/ratatui_ruby/schema/constraint.rb +0 -151
  220. data/lib/ratatui_ruby/schema/cursor.rb +0 -50
  221. data/lib/ratatui_ruby/schema/gauge.rb +0 -72
  222. data/lib/ratatui_ruby/schema/layout.rb +0 -122
  223. data/lib/ratatui_ruby/schema/line_gauge.rb +0 -80
  224. data/lib/ratatui_ruby/schema/list.rb +0 -135
  225. data/lib/ratatui_ruby/schema/list_item.rb +0 -51
  226. data/lib/ratatui_ruby/schema/overlay.rb +0 -51
  227. data/lib/ratatui_ruby/schema/paragraph.rb +0 -107
  228. data/lib/ratatui_ruby/schema/ratatui_logo.rb +0 -31
  229. data/lib/ratatui_ruby/schema/ratatui_mascot.rb +0 -36
  230. data/lib/ratatui_ruby/schema/rect.rb +0 -174
  231. data/lib/ratatui_ruby/schema/row.rb +0 -76
  232. data/lib/ratatui_ruby/schema/scrollbar.rb +0 -143
  233. data/lib/ratatui_ruby/schema/shape/label.rb +0 -76
  234. data/lib/ratatui_ruby/schema/sparkline.rb +0 -142
  235. data/lib/ratatui_ruby/schema/style.rb +0 -97
  236. data/lib/ratatui_ruby/schema/table.rb +0 -141
  237. data/lib/ratatui_ruby/schema/tabs.rb +0 -85
  238. data/lib/ratatui_ruby/schema/text.rb +0 -217
  239. data/sig/examples/app_all_events/model/events.rbs +0 -15
  240. data/sig/examples/app_all_events/view_state.rbs +0 -21
  241. data/sig/ratatui_ruby/schema/bar_chart/bar.rbs +0 -22
  242. data/sig/ratatui_ruby/schema/bar_chart/bar_group.rbs +0 -19
  243. data/sig/ratatui_ruby/schema/bar_chart.rbs +0 -38
  244. data/sig/ratatui_ruby/schema/block.rbs +0 -18
  245. data/sig/ratatui_ruby/schema/calendar.rbs +0 -23
  246. data/sig/ratatui_ruby/schema/canvas.rbs +0 -81
  247. data/sig/ratatui_ruby/schema/center.rbs +0 -17
  248. data/sig/ratatui_ruby/schema/chart.rbs +0 -39
  249. data/sig/ratatui_ruby/schema/constraint.rbs +0 -30
  250. data/sig/ratatui_ruby/schema/cursor.rbs +0 -16
  251. data/sig/ratatui_ruby/schema/draw.rbs +0 -33
  252. data/sig/ratatui_ruby/schema/gauge.rbs +0 -23
  253. data/sig/ratatui_ruby/schema/layout.rbs +0 -27
  254. data/sig/ratatui_ruby/schema/line_gauge.rbs +0 -24
  255. data/sig/ratatui_ruby/schema/list.rbs +0 -28
  256. data/sig/ratatui_ruby/schema/overlay.rbs +0 -15
  257. data/sig/ratatui_ruby/schema/paragraph.rbs +0 -20
  258. data/sig/ratatui_ruby/schema/ratatui_logo.rbs +0 -14
  259. data/sig/ratatui_ruby/schema/ratatui_mascot.rbs +0 -17
  260. data/sig/ratatui_ruby/schema/rect.rbs +0 -48
  261. data/sig/ratatui_ruby/schema/row.rbs +0 -28
  262. data/sig/ratatui_ruby/schema/scrollbar.rbs +0 -42
  263. data/sig/ratatui_ruby/schema/sparkline.rbs +0 -22
  264. data/sig/ratatui_ruby/schema/style.rbs +0 -19
  265. data/sig/ratatui_ruby/schema/table.rbs +0 -32
  266. data/sig/ratatui_ruby/schema/tabs.rbs +0 -21
  267. data/sig/ratatui_ruby/schema/text.rbs +0 -31
  268. /data/lib/ratatui_ruby/{schema/draw.rb → draw.rb} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c543e8590fa79c457dac22abc8c39fc2264026079196ff7d0afc1d083c9cf013
4
- data.tar.gz: 8c044e43009f8ede9c66274809aacae1c7e66a503157afc6756c4890b50d899c
3
+ metadata.gz: 5e12255e203dd3005db171f1c2062095644a5602b3384a1a820252f84f926abe
4
+ data.tar.gz: eefb8e9f9e5c4549eff00c36c4789ab7e13dbb508f7fb3edae86977eacdc17f5
5
5
  SHA512:
6
- metadata.gz: dfd4c34a23e0af4dcb47c9520bae94db94cb7587f37b11662668e8f6f7e7a3148aeb0fb66ed66cb47f51898fc42da496ce50cec46ea1b286c3bcfcbe5dc43e41
7
- data.tar.gz: 19871c4b3ec78afc30fc004f019b6b0ff246654ffbbe6dafb7e92cd5d1b3c4b1294ed3e836c47b70fb094dad3f5aa7927dd2b23a6cf458d571f5248fa5b0b934
6
+ metadata.gz: 5cb1c1695d98e23db66e938e2f8525d148d2a0076520312d62f17aacfe437c116b35477dc9c670b8e0a452831ca2e6a34684feac38d928a988430f49795f4534
7
+ data.tar.gz: e3c222831be6b4812f41bfbffe15024508a587769df0cbf5f1b5a65f7ac19c0010dbab7ffcafe7d669c41817a6bb2475d2437522d587f13f8f79c07338d6ba9d
data/.builds/ruby-3.2.yml CHANGED
@@ -16,7 +16,7 @@ packages:
16
16
  - clang
17
17
  - git
18
18
  artifacts:
19
- - ratatui_ruby/pkg/ratatui_ruby-0.9.1.gem
19
+ - ratatui_ruby/pkg/ratatui_ruby-0.10.1.gem
20
20
  sources:
21
21
  - https://git.sr.ht/~kerrick/ratatui_ruby
22
22
  tasks:
data/.builds/ruby-3.3.yml CHANGED
@@ -16,7 +16,7 @@ packages:
16
16
  - clang
17
17
  - git
18
18
  artifacts:
19
- - ratatui_ruby/pkg/ratatui_ruby-0.9.1.gem
19
+ - ratatui_ruby/pkg/ratatui_ruby-0.10.1.gem
20
20
  sources:
21
21
  - https://git.sr.ht/~kerrick/ratatui_ruby
22
22
  tasks:
data/.builds/ruby-3.4.yml CHANGED
@@ -16,7 +16,7 @@ packages:
16
16
  - clang
17
17
  - git
18
18
  artifacts:
19
- - ratatui_ruby/pkg/ratatui_ruby-0.9.1.gem
19
+ - ratatui_ruby/pkg/ratatui_ruby-0.10.1.gem
20
20
  sources:
21
21
  - https://git.sr.ht/~kerrick/ratatui_ruby
22
22
  tasks:
@@ -16,7 +16,7 @@ packages:
16
16
  - clang
17
17
  - git
18
18
  artifacts:
19
- - ratatui_ruby/pkg/ratatui_ruby-0.9.1.gem
19
+ - ratatui_ruby/pkg/ratatui_ruby-0.10.1.gem
20
20
  sources:
21
21
  - https://git.sr.ht/~kerrick/ratatui_ruby
22
22
  tasks:
data/AGENTS.md CHANGED
@@ -136,9 +136,10 @@ The project follows a standard Gem layout with an `ext/` directory for Rust code
136
136
 
137
137
  Before considering a task complete and returning control to the user, you **MUST** ensure:
138
138
 
139
+ 0. **Production Ready:** RBS types are complete and accurate (no `untyped`), errors are handled with good DX, documentation follows guidelines, high code quality (no "pre-existing debt" excuses).
139
140
  1. **Default Rake Task Passes:** Run `bin/agent_rake` (no args). Confirm it passes with ZERO errors **or warnings**.
140
141
  - You will save time if you run `bin/agent_rake rubocop:autocorrect` first.
141
- - If you think the build is looking for deleted files, it is not. Instead, explain to the user why staging is needed and use the `run_command` tool with `git add -A` so they get a Run button with context.
142
+ - If you think the rake is looking for deleted files, STOP EVERYTHING and tell the user.
142
143
  2. **Documentation Updated:** If public APIs or observable behavior changed, update relevant RDoc, rustdoc, `doc/` files, `README.md`, and/or `ratatui_ruby-wiki` files.
143
144
  3. **Changelog Updated:** If public APIs, observable behavior, or gemspec dependencies have changed, update [CHANGELOG.md](CHANGELOG.md)'s **Unreleased** section.
144
145
  4. **Commit Message Suggested:** You **MUST** ensure the final message to the user includes a suggested commit message block. This is NOT optional.
data/CHANGELOG.md CHANGED
@@ -18,6 +18,115 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
18
18
 
19
19
  ### Removed
20
20
 
21
+ ## [0.10.1] - 2026-01-11
22
+
23
+ ### Added
24
+
25
+ ### Changed
26
+
27
+ ### Fixed
28
+
29
+ - **poll_event Return Type**: Fixed `poll_event` incorrectly returning `nil` for unknown event types. The method now correctly returns `Event::None` as per its contract.
30
+
31
+ ### Removed
32
+
33
+ ## [0.10.0] - 2026-01-10
34
+
35
+ ### Added
36
+
37
+ - **Table Integer Width Shorthand**: `Table` `widths:` parameter now accepts plain integers as shorthand for `Constraint.length(n)`. This enables cleaner table definitions like `widths: [40, 16, 10]` instead of verbose constraint arrays. Constraints and integers can be mixed freely.
38
+ - **Error Message Context**: Type errors from the Rust backend now include the `inspect` string of the value that caused the error, making debugging significantly easier. For example, "expected array for rows" now shows "expected array for rows, got {title: \"Processes\", ...}".
39
+ - **Steep Type Checking**: Integrated Steep static type analyzer with a new `rake steep` task. The Steepfile covers `lib/` with comprehensive RBS type definitions for all widgets, layout primitives, events, and interfaces.
40
+ - **RBS Type Definitions**: Added 50+ RBS signature files in `sig/ratatui_ruby/` covering all widget classes, core interfaces (`_RectLike`, `_ToS`), type aliases (`style_input`, `widget`), and a `Data.define` patch for `super()` call compatibility.
41
+ - **Duck Typing Documentation**: New `test/test_duck_typing.rb` documents that `Layout.split` accepts any object responding to `x`, `y`, `width`, `height` (Struct, Data.define, custom classes), not just `Rect`.
42
+ - **Debug Mode**: New `RatatuiRuby::Debug` module controls Rust backtrace visibility for easier debugging. Activate via:
43
+ - `RUST_BACKTRACE=1` — Rust backtraces only
44
+ - `RR_DEBUG=1` — full debug mode (backtraces + future Ruby-side features)
45
+ - `include RatatuiRuby::TestHelper` — auto-enables debug mode in tests
46
+ - `RatatuiRuby.debug_mode!` — programmatic activation
47
+ - **Debug.test_panic!**: New method that intentionally triggers a Rust panic, allowing developers to verify their backtrace setup is working correctly before encountering a real bug.
48
+ - **Deferred Panic Backtraces**: Rust backtraces during TUI sessions are now stored and printed after terminal restoration, preventing output from being lost on the alternate screen. Previously, panic output in raw terminal mode was invisible.
49
+ - **Remote Debugging**: Debug mode now integrates with Ruby's `debug` gem for remote debugging. `RR_DEBUG=1` stops at startup and waits for debugger attachment. `RatatuiRuby.debug_mode!` continues running in nonstop mode. Attach from another terminal with `rdbg --attach`.
50
+ - **Debug.suppress_debug_mode**: New block method temporarily suppresses Ruby-side debug checks within its block. Rust backtraces remain enabled. Useful for testing production behavior in debug mode environments.
51
+ - **DWIM Hash Coercion**: All widget factory methods now accept both `tui.table(hash)` and `tui.table(**hash)` calling styles. When a bare Hash is passed as the first positional argument, it is automatically splatted into keyword arguments. Unknown keys are silently ignored in production mode; in debug mode (`RR_DEBUG=1`), they raise `ArgumentError` for early typo detection.
52
+ - **Ratatui-Aligned Text Methods**: New methods on `Text::Span` and `Text::Line` matching Ratatui's API for style manipulation:
53
+ - `Span#width` — display width in terminal cells (unicode-aware)
54
+ - `Span.raw(content)` — factory for unstyled spans
55
+ - `Span#patch_style(style)` — merge style onto existing style
56
+ - `Span#reset_style` — clear all styling
57
+ - `Line#left_aligned`, `Line#centered`, `Line#right_aligned` — fluent alignment setters
58
+ - `Line#push_span(span)` — append span (returns new Line, immutable)
59
+ - `Line#patch_style(style)`, `Line#reset_style` — style manipulation for all spans
60
+ - **List Query Methods**: New methods on `List` matching Ratatui's API:
61
+ - `List#len` — number of items (with Ruby aliases `length`, `size`)
62
+ - **TableState Navigation Methods**: New methods on `TableState` matching Ratatui's API for column navigation:
63
+ - `selected_cell` — returns `[row, column]` tuple when both are selected
64
+ - `with_selected_cell(cell)` — constructor to create state with both row and column selected
65
+ - `select_next_column` — select the next column (or first if none selected)
66
+ - `select_previous_column` — select the previous column (saturates at 0)
67
+ - `select_first_column` — select column 0
68
+ - `select_last_column` — select the last column (clamped during rendering)
69
+ - **Buffer Query Methods**: New module methods on `Buffer` matching Ratatui's API for buffer inspection:
70
+ - `Buffer.content` — returns all cells as an array
71
+ - `Buffer.get(x, y)` — returns the Cell at the specified position
72
+ - `Buffer.index_of(x, y)` — converts position to linear buffer index
73
+ - `Buffer.pos_of(index)` — converts linear index to position coordinates
74
+ - **Rect Conversion Methods**: New methods on `Rect` for extracting geometry components:
75
+ - `Rect#as_position` — returns a `Position` object containing x and y coordinates
76
+ - `Rect#as_size` — returns a `Size` object containing width and height
77
+ - **Position and Size Classes**: New layout primitives matching Ratatui's API:
78
+ - `Layout::Position` — represents terminal coordinates (x, y)
79
+ - `Layout::Size` — represents terminal dimensions (width, height)
80
+ - **Constraint#apply**: Computes the constrained size for a given available space. For example, `Constraint.percentage(50).apply(100)` returns `50`. Also aliased as `call` for proc-like invocation (`constraint.(100)`).
81
+ - **Color Module**: New `Style::Color` module with constructors matching Ratatui's API:
82
+ - `Color.from_u32(0xRRGGBB)` — creates a color from a hex integer (aliased as `Color.hex`)
83
+ - `Color.from_hsl(h, s, l)` — creates a color from HSL values (aliased as `Color.hsl`)
84
+ - **Ruby-Idiomatic Aliases**: All new APIs include shorter, more Ruby-ish aliases following TIMTOWTDI:
85
+ - `Rect#position` (alias for `as_position`), `Rect#size` (alias for `as_size`)
86
+ - `Buffer[x, y]` (alias for `Buffer.get`)
87
+ - `Constraint#call` (alias for `apply`, enables `constraint.(n)` syntax)
88
+ - **Layout Margin and Spacing**: `Layout` now supports `margin:` and `spacing:` parameters for edge insets and gaps between segments, matching Ratatui's Layout API.
89
+ - **Layout.split_with_spacers**: New class method returns both content segments and spacer Rects, enabling custom rendering of dividers or separators between layout sections.
90
+ - **Canvas#get_point**: Converts canvas coordinates to normalized [0.0, 1.0] grid coordinates for hit testing. Returns `nil` for out-of-bounds coordinates. Also aliased as `point` and `[]` for Ruby-idiomatic access.
91
+ - **Row#enable_strikethrough**: Returns a new Row with `:crossed_out` modifier for indicating cancelled or deleted items. Also aliased as `strikethrough`. Note: Strikethrough (SGR 9) is not supported by all terminals; macOS Terminal.app notably lacks support while Kitty, iTerm2, Alacritty, and WezTerm render it correctly.
92
+ - **Rect Geometry Methods**: New methods on `Rect` for geometry manipulation:
93
+ - `Rect#outer(margin)` — expands a rectangle by a margin (inverse of `inner`)
94
+ - `Rect#resize(size)` — changes dimensions while preserving top-left position
95
+ - `Rect#centered_horizontally(constraint)` — centers horizontally using Layout
96
+ - `Rect#centered_vertically(constraint)` — centers vertically using Layout
97
+ - `Rect#centered(h, v)` — centers on both axes
98
+ - **TUI Shape Aliases (DWIM)**: Canvas shape factories now have terse and bidirectional aliases:
99
+ - Terse: `circle()`, `point()`, `map()`, `label()` (shorter forms of `shape_*`)
100
+ - Bidirectional: `circle_shape()`, `point_shape()`, `rectangle_shape()`, `map_shape()`, `label_shape()` (same as `shape_*`)
101
+ - Note: Terse `rectangle` is intentionally excluded to avoid confusion with `Layout::Rect`; use `shape_rectangle()` or `rectangle_shape()`.
102
+ - **TUI `item` Alias**: `tui.item(...)` is now an alias for `tui.list_item(...)`, providing a terser API when building lists.
103
+ - **Gauge and LineGauge `percent`**: Both widgets now have a `percent` reader that returns the ratio as an integer percentage (0-100). `LineGauge` also now accepts a `percent:` constructor parameter matching `Gauge`.
104
+ - **List#selected_item**: Returns the item at the selected index (or nil if nothing is selected).
105
+ - **Style `underline_color`**: New optional parameter for `Style` that sets a distinct underline color independent of the foreground color. Useful for styling like "white text with red underline". Terminals must support the underline color extension (SGR 58).
106
+ - **Style `remove_modifiers`**: New optional parameter for `Style` that explicitly removes modifiers when styles are patched/inherited. Corresponds to Ratatui's `sub_modifier` field. Use it to prevent inherited bold, italic, or other modifiers from propagating.
107
+ - **Symbols::Shade Constants**: New `RatatuiRuby::Symbols::Shade` module exposes Ratatui's shade block characters as named constants: `EMPTY` (" "), `LIGHT` ("░"), `MEDIUM` ("▒"), `DARK` ("▓"), `FULL` ("█"). Use them for gradients, density fills, or custom progress indicators.
108
+ - **Symbols::Line Constants and Sets**: New `RatatuiRuby::Symbols::Line` module exposes Ratatui's box-drawing characters with 36 individual constants (VERTICAL, HORIZONTAL, corners, T-junctions, cross) and 4 predefined sets: `NORMAL` (standard corners), `ROUNDED` (rounded corners), `DOUBLE` (double-line), `THICK` (heavy lines). Use them for custom borders or drawing.
109
+ - **Symbols::Bar Constants and Sets**: New `RatatuiRuby::Symbols::Bar` module exposes Ratatui's vertical bar characters (lower blocks) with 8 individual constants and 2 predefined sets: `NINE_LEVELS` (full resolution) and `THREE_LEVELS` (simplified). Used by Sparkline widget.
110
+ - **Symbols::Block Constants and Sets**: New `RatatuiRuby::Symbols::Block` module exposes Ratatui's horizontal block characters (left blocks) with 8 individual constants and 2 predefined sets: `NINE_LEVELS` (full resolution) and `THREE_LEVELS` (simplified). Used by Gauge widget.
111
+ - **Symbols::Scrollbar Sets**: New `RatatuiRuby::Symbols::Scrollbar` module exposes 4 predefined scrollbar symbol sets: `VERTICAL`, `DOUBLE_VERTICAL`, `HORIZONTAL`, `DOUBLE_HORIZONTAL`. Each set contains `track`, `thumb`, `begin_char`, and `end_char` symbols.
112
+ - **Cell `underline_color`**: `Buffer::Cell` and top-level `Cell` now expose `underline_color` attribute for introspecting styled underline colors during testing.
113
+
114
+ ### Changed
115
+
116
+ - **`tui.draw` Argument Validation (Breaking)**: `tui.draw` now validates its arguments. Calling `draw` with neither a tree nor a block raises `ArgumentError`, as does calling it with both. Previously this produced undefined behavior.
117
+ - **`Layout.split` Stricter Type Checking (Breaking)**: `Layout.split` now rejects invalid `area` arguments with a clear `ArgumentError` instead of silently misbehaving. Objects must be a `Rect`, `Hash` with `:x/:y/:width/:height` keys, or respond to all four geometry methods.
118
+ - **Schema Directory Removed (Breaking)**: The legacy `lib/ratatui_ruby/schema/` directory has been removed. All widget classes now live exclusively in their proper namespaces (`Widgets::`, `Layout::`, `Text::`, etc.). Direct usage like `RatatuiRuby::Paragraph` (without `Widgets::`) is no longer supported. Use `RatatuiRuby::Widgets::Paragraph` or the TUI facade (`tui.paragraph`).
119
+ - **Buffer::Cell Modifiers (Breaking)**: `Buffer::Cell#modifiers` and `Cell#modifiers` now return an array of `Symbol`s (e.g., `[:bold, :italic]`) instead of `String`s. This unifies the API, as `Style` modifiers were already symbols. Code expecting strings (e.g. `cell.modifiers.include?("bold")`) must be updated to use symbols. This changes behavior established in v0.9.1.
120
+
121
+ ### Fixed
122
+
123
+ - **Tabs Padding Coercion**: `Tabs` `padding_left` and `padding_right` now correctly coerce duck-typed integer values (objects responding to `to_int`/`to_i`) via `Integer()`. Previously these parameters were passed through without coercion, inconsistent with other integer parameters. `Text::Line` values are still accepted as-is for styled padding.
124
+
125
+ ### Removed
126
+
127
+ - **NullIO Re-export (Breaking)**: Removed `RatatuiRuby::NullIO` constant. Use `RatatuiRuby::OutputGuard::NullIO` if you were relying on this internal class.
128
+ - **Legacy Media Keys (Breaking)**: Removed support for legacy unprefixed media keys (e.g. `play`, `stop`) in event parsing. You must now use the canonical `media_`-prefixed keys (e.g. `media_play`, `media_stop`). The `play?`/`stop?` predicates still work for both, checking the correct canonical codes.
129
+
21
130
  ## [0.9.1] - 2026-01-08
22
131
 
23
132
  ### Added
@@ -515,6 +624,10 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
515
624
  - **Testing Support**: Included `RatatuiRuby::TestHelper` and RSpec integration to make testing your TUI applications possible.
516
625
 
517
626
  [Unreleased]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/HEAD
627
+ [0.10.1]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v0.10.1
628
+ [0.10.1]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v0.10.1
629
+ [0.10.1]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v0.10.1
630
+ [0.10.0]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v0.10.0
518
631
  [0.9.1]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v0.9.1
519
632
  [0.9.0]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v0.9.0
520
633
  [0.8.0]: https://git.sr.ht/~kerrick/ratatui_ruby/refs/v0.8.0
data/README.md CHANGED
@@ -27,6 +27,23 @@ Mailing List: Announcements](https://img.shields.io/badge/mailing_list-announcem
27
27
 
28
28
  Please join the **announce** mailing list at https://lists.sr.ht/~kerrick/ratatui_ruby-announce to stay up-to-date on new releases and announcements. See the [`trunk` branch](https://git.sr.ht/~kerrick/ratatui_ruby/tree/trunk) for pre-release updates.
29
29
 
30
+ ---
31
+
32
+ ## Quick Links
33
+
34
+ ### The Ecosystem
35
+
36
+ **RatatuiRuby:** [Core engine](https://git.sr.ht/~kerrick/ratatui_ruby) • **Tea:** [MVU architecture](https://git.sr.ht/~kerrick/ratatui_ruby-tea) • **Kit:** [Component architecture](https://git.sr.ht/~kerrick/ratatui_ruby-kit) (Planned) • **DSL:** [Glimmer syntax](https://sr.ht/~kerrick/ratatui_ruby/#chapter-4-the-syntax) (Planned) • **Framework:** [Omakase framework](https://git.sr.ht/~kerrick/ratatui_ruby-framework) (Planned) • **UI:** [Polished widgets](https://git.sr.ht/~kerrick/ratatui_ruby-ui) (Planned) • **UI Pro:** [More polished widgets](https://sr.ht/~kerrick/ratatui_ruby#chapter-6-licensing) (Planned)
37
+
38
+ ### For App Developers
39
+
40
+ **Get Started:** [Quickstart](https://git.sr.ht/~kerrick/ratatui_ruby/tree/stable/item/doc/getting_started/quickstart.md) • [Examples](https://git.sr.ht/~kerrick/ratatui_ruby/tree/stable/item/examples) ⸺ **Stay Informed:** [Announce List](https://lists.sr.ht/~kerrick/ratatui_ruby-announce) • [FAQ](https://man.sr.ht/~kerrick/ratatui_ruby/troubleshooting.md) ⸺ **Reach Out:** [Discuss List](https://lists.sr.ht/~kerrick/ratatui_ruby-discuss) • [Bug Tracker](https://todo.sr.ht/~kerrick/ratatui_ruby)
41
+
42
+ ### For Contributors
43
+
44
+ **Get Started:** [Contributing Guide](https://man.sr.ht/~kerrick/ratatui_ruby/contributing.md) • [Code of Conduct](https://man.sr.ht/~kerrick/ratatui_ruby/code_of_conduct.md) ⸺ **Stay Informed:** [Announce List](https://lists.sr.ht/~kerrick/ratatui_ruby-announce) • [Project History](https://man.sr.ht/~kerrick/ratatui_ruby/history/index.md) ⸺ **Reach Out:** [Development List](https://lists.sr.ht/~kerrick/ratatui_ruby-devel) • [Bug Tracker](https://todo.sr.ht/~kerrick/ratatui_ruby)
45
+
46
+ ---
30
47
 
31
48
  ## Compatibility
32
49
 
data/REUSE.toml CHANGED
@@ -16,6 +16,11 @@ path = 'doc/images/*.png'
16
16
  SPDX-FileCopyrightText = "2025 Kerrick Long <me@kerricklong.com>"
17
17
  SPDX-License-Identifier = "CC-BY-SA-4.0"
18
18
 
19
+ [[annotations]]
20
+ path = 'doc/images/*.gif'
21
+ SPDX-FileCopyrightText = "2025 Kerrick Long <me@kerricklong.com>"
22
+ SPDX-License-Identifier = "CC-BY-SA-4.0"
23
+
19
24
  [[annotations]]
20
25
  path = 'test/fixtures/*.txt'
21
26
  SPDX-FileCopyrightText = "2025 Kerrick Long <me@kerricklong.com>"
data/Rakefile CHANGED
@@ -8,4 +8,4 @@ require "bundler/gem_tasks"
8
8
  # Import all tasks from the tasks/ directory
9
9
  Dir.glob("tasks/*.rake").each { |r| import r }
10
10
 
11
- task default: %w[lint:fix sourcehut test lint license:new]
11
+ task default: %w[lint:fix sourcehut test lint license:new steep]
data/Steepfile ADDED
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
4
+ # SPDX-License-Identifier: AGPL-3.0-or-later
5
+
6
+ target :lib do
7
+ signature "sig"
8
+ check "lib"
9
+
10
+ # Legacy schema/ files pending migration - exclude from checking
11
+ # Only schema/text.rb and schema/draw.rb are loaded by the main gem
12
+ # See doc/contributors/v1.0.0_blockers.md
13
+ ignore "lib/ratatui_ruby/schema/bar_chart.rb"
14
+ ignore "lib/ratatui_ruby/schema/bar_chart/"
15
+ ignore "lib/ratatui_ruby/schema/block.rb"
16
+ ignore "lib/ratatui_ruby/schema/calendar.rb"
17
+ ignore "lib/ratatui_ruby/schema/canvas.rb"
18
+ ignore "lib/ratatui_ruby/schema/center.rb"
19
+ ignore "lib/ratatui_ruby/schema/chart.rb"
20
+ ignore "lib/ratatui_ruby/schema/clear.rb"
21
+ ignore "lib/ratatui_ruby/schema/constraint.rb"
22
+ ignore "lib/ratatui_ruby/schema/cursor.rb"
23
+ ignore "lib/ratatui_ruby/schema/gauge.rb"
24
+ ignore "lib/ratatui_ruby/schema/layout.rb"
25
+ ignore "lib/ratatui_ruby/schema/line_gauge.rb"
26
+ ignore "lib/ratatui_ruby/schema/list.rb"
27
+ ignore "lib/ratatui_ruby/schema/list_item.rb"
28
+ ignore "lib/ratatui_ruby/schema/overlay.rb"
29
+ ignore "lib/ratatui_ruby/schema/paragraph.rb"
30
+ ignore "lib/ratatui_ruby/schema/ratatui_logo.rb"
31
+ ignore "lib/ratatui_ruby/schema/ratatui_mascot.rb"
32
+ ignore "lib/ratatui_ruby/schema/rect.rb"
33
+ ignore "lib/ratatui_ruby/schema/row.rb"
34
+ ignore "lib/ratatui_ruby/schema/scrollbar.rb"
35
+ ignore "lib/ratatui_ruby/schema/shape/"
36
+ ignore "lib/ratatui_ruby/schema/sparkline.rb"
37
+ ignore "lib/ratatui_ruby/schema/style.rb"
38
+ ignore "lib/ratatui_ruby/schema/table.rb"
39
+ ignore "lib/ratatui_ruby/schema/tabs.rb"
40
+
41
+ # ClassMethods mixin pattern cannot be typed in RBS
42
+ # (self in ClassMethods refers to the including Class)
43
+ ignore "lib/ratatui_ruby/widgets/coerceable_widget.rb"
44
+
45
+ library "pathname"
46
+ library "fileutils"
47
+ library "minitest"
48
+ library "date"
49
+ end