ratatui_ruby 1.4.0-x86_64-linux

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 (292) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +15 -0
  3. data/LICENSES/AGPL-3.0-or-later.txt +661 -0
  4. data/LICENSES/CC-BY-SA-4.0.txt +427 -0
  5. data/LICENSES/CC0-1.0.txt +121 -0
  6. data/LICENSES/LGPL-3.0-or-later.txt +304 -0
  7. data/LICENSES/MIT-0.txt +16 -0
  8. data/LICENSES/MIT.txt +21 -0
  9. data/REUSE.toml +42 -0
  10. data/exe/.gitkeep +0 -0
  11. data/ext/ratatui_ruby/.cargo/config.toml +13 -0
  12. data/ext/ratatui_ruby/.gitignore +4 -0
  13. data/ext/ratatui_ruby/Cargo.lock +1737 -0
  14. data/ext/ratatui_ruby/Cargo.toml +24 -0
  15. data/ext/ratatui_ruby/clippy.toml +7 -0
  16. data/ext/ratatui_ruby/extconf.rb +21 -0
  17. data/ext/ratatui_ruby/src/color.rs +82 -0
  18. data/ext/ratatui_ruby/src/errors.rs +28 -0
  19. data/ext/ratatui_ruby/src/events.rs +700 -0
  20. data/ext/ratatui_ruby/src/frame.rs +241 -0
  21. data/ext/ratatui_ruby/src/lib.rs +343 -0
  22. data/ext/ratatui_ruby/src/lib_header.rs +11 -0
  23. data/ext/ratatui_ruby/src/rendering.rs +158 -0
  24. data/ext/ratatui_ruby/src/string_width.rs +101 -0
  25. data/ext/ratatui_ruby/src/style.rs +469 -0
  26. data/ext/ratatui_ruby/src/terminal/capabilities.rs +46 -0
  27. data/ext/ratatui_ruby/src/terminal/init.rs +233 -0
  28. data/ext/ratatui_ruby/src/terminal/mod.rs +42 -0
  29. data/ext/ratatui_ruby/src/terminal/mutations.rs +158 -0
  30. data/ext/ratatui_ruby/src/terminal/queries.rs +231 -0
  31. data/ext/ratatui_ruby/src/terminal/query.rs +400 -0
  32. data/ext/ratatui_ruby/src/terminal/storage.rs +109 -0
  33. data/ext/ratatui_ruby/src/terminal/wrapper.rs +16 -0
  34. data/ext/ratatui_ruby/src/text.rs +225 -0
  35. data/ext/ratatui_ruby/src/widgets/barchart.rs +169 -0
  36. data/ext/ratatui_ruby/src/widgets/block.rs +41 -0
  37. data/ext/ratatui_ruby/src/widgets/calendar.rs +84 -0
  38. data/ext/ratatui_ruby/src/widgets/canvas.rs +183 -0
  39. data/ext/ratatui_ruby/src/widgets/center.rs +79 -0
  40. data/ext/ratatui_ruby/src/widgets/chart.rs +222 -0
  41. data/ext/ratatui_ruby/src/widgets/clear.rs +39 -0
  42. data/ext/ratatui_ruby/src/widgets/cursor.rs +32 -0
  43. data/ext/ratatui_ruby/src/widgets/gauge.rs +65 -0
  44. data/ext/ratatui_ruby/src/widgets/layout.rs +379 -0
  45. data/ext/ratatui_ruby/src/widgets/line_gauge.rs +100 -0
  46. data/ext/ratatui_ruby/src/widgets/list.rs +378 -0
  47. data/ext/ratatui_ruby/src/widgets/list_state.rs +173 -0
  48. data/ext/ratatui_ruby/src/widgets/mod.rs +26 -0
  49. data/ext/ratatui_ruby/src/widgets/overlay.rs +24 -0
  50. data/ext/ratatui_ruby/src/widgets/paragraph.rs +87 -0
  51. data/ext/ratatui_ruby/src/widgets/ratatui_logo.rs +40 -0
  52. data/ext/ratatui_ruby/src/widgets/ratatui_mascot.rs +55 -0
  53. data/ext/ratatui_ruby/src/widgets/scrollbar.rs +214 -0
  54. data/ext/ratatui_ruby/src/widgets/scrollbar_state.rs +169 -0
  55. data/ext/ratatui_ruby/src/widgets/sparkline.rs +127 -0
  56. data/ext/ratatui_ruby/src/widgets/table.rs +415 -0
  57. data/ext/ratatui_ruby/src/widgets/table_state.rs +203 -0
  58. data/ext/ratatui_ruby/src/widgets/tabs.rs +194 -0
  59. data/lib/ratatui_ruby/backend/window_size.rb +50 -0
  60. data/lib/ratatui_ruby/backend.rb +59 -0
  61. data/lib/ratatui_ruby/buffer/cell.rb +212 -0
  62. data/lib/ratatui_ruby/buffer.rb +149 -0
  63. data/lib/ratatui_ruby/cell.rb +208 -0
  64. data/lib/ratatui_ruby/debug.rb +215 -0
  65. data/lib/ratatui_ruby/draw.rb +63 -0
  66. data/lib/ratatui_ruby/event/focus_gained.rb +125 -0
  67. data/lib/ratatui_ruby/event/focus_lost.rb +127 -0
  68. data/lib/ratatui_ruby/event/key/character.rb +53 -0
  69. data/lib/ratatui_ruby/event/key/dwim.rb +301 -0
  70. data/lib/ratatui_ruby/event/key/media.rb +46 -0
  71. data/lib/ratatui_ruby/event/key/modifier.rb +107 -0
  72. data/lib/ratatui_ruby/event/key/navigation.rb +72 -0
  73. data/lib/ratatui_ruby/event/key/system.rb +47 -0
  74. data/lib/ratatui_ruby/event/key.rb +479 -0
  75. data/lib/ratatui_ruby/event/mouse.rb +291 -0
  76. data/lib/ratatui_ruby/event/none.rb +53 -0
  77. data/lib/ratatui_ruby/event/paste.rb +130 -0
  78. data/lib/ratatui_ruby/event/resize.rb +221 -0
  79. data/lib/ratatui_ruby/event/sync.rb +52 -0
  80. data/lib/ratatui_ruby/event.rb +163 -0
  81. data/lib/ratatui_ruby/frame.rb +257 -0
  82. data/lib/ratatui_ruby/labs/a11y.rb +182 -0
  83. data/lib/ratatui_ruby/labs/frame_a11y_capture.rb +50 -0
  84. data/lib/ratatui_ruby/labs.rb +47 -0
  85. data/lib/ratatui_ruby/layout/alignment.rb +91 -0
  86. data/lib/ratatui_ruby/layout/constraint.rb +337 -0
  87. data/lib/ratatui_ruby/layout/layout.rb +258 -0
  88. data/lib/ratatui_ruby/layout/position.rb +81 -0
  89. data/lib/ratatui_ruby/layout/rect.rb +733 -0
  90. data/lib/ratatui_ruby/layout/size.rb +62 -0
  91. data/lib/ratatui_ruby/layout.rb +29 -0
  92. data/lib/ratatui_ruby/list_state.rb +201 -0
  93. data/lib/ratatui_ruby/output_guard.rb +171 -0
  94. data/lib/ratatui_ruby/ratatui_ruby.so +0 -0
  95. data/lib/ratatui_ruby/scrollbar_state.rb +122 -0
  96. data/lib/ratatui_ruby/style/color.rb +149 -0
  97. data/lib/ratatui_ruby/style/style.rb +147 -0
  98. data/lib/ratatui_ruby/style.rb +19 -0
  99. data/lib/ratatui_ruby/symbols.rb +435 -0
  100. data/lib/ratatui_ruby/synthetic_events.rb +106 -0
  101. data/lib/ratatui_ruby/table_state.rb +251 -0
  102. data/lib/ratatui_ruby/terminal/capabilities.rb +316 -0
  103. data/lib/ratatui_ruby/terminal/viewport.rb +80 -0
  104. data/lib/ratatui_ruby/terminal.rb +66 -0
  105. data/lib/ratatui_ruby/terminal_lifecycle.rb +303 -0
  106. data/lib/ratatui_ruby/terminal_lifecycle.rb.bak +197 -0
  107. data/lib/ratatui_ruby/test_helper/event_injection.rb +241 -0
  108. data/lib/ratatui_ruby/test_helper/global_state.rb +111 -0
  109. data/lib/ratatui_ruby/test_helper/snapshot.rb +568 -0
  110. data/lib/ratatui_ruby/test_helper/snapshots/axis_labels_alignment.ansi +24 -0
  111. data/lib/ratatui_ruby/test_helper/snapshots/axis_labels_alignment.txt +24 -0
  112. data/lib/ratatui_ruby/test_helper/snapshots/barchart_styled_label.ansi +5 -0
  113. data/lib/ratatui_ruby/test_helper/snapshots/barchart_styled_label.txt +5 -0
  114. data/lib/ratatui_ruby/test_helper/snapshots/chart_rendering.ansi +24 -0
  115. data/lib/ratatui_ruby/test_helper/snapshots/chart_rendering.txt +24 -0
  116. data/lib/ratatui_ruby/test_helper/snapshots/half_block_marker.ansi +12 -0
  117. data/lib/ratatui_ruby/test_helper/snapshots/half_block_marker.txt +12 -0
  118. data/lib/ratatui_ruby/test_helper/snapshots/legend_position_bottom.ansi +12 -0
  119. data/lib/ratatui_ruby/test_helper/snapshots/legend_position_bottom.txt +12 -0
  120. data/lib/ratatui_ruby/test_helper/snapshots/legend_position_left.ansi +12 -0
  121. data/lib/ratatui_ruby/test_helper/snapshots/legend_position_left.txt +12 -0
  122. data/lib/ratatui_ruby/test_helper/snapshots/legend_position_right.ansi +12 -0
  123. data/lib/ratatui_ruby/test_helper/snapshots/legend_position_right.txt +12 -0
  124. data/lib/ratatui_ruby/test_helper/snapshots/legend_position_top.ansi +12 -0
  125. data/lib/ratatui_ruby/test_helper/snapshots/legend_position_top.txt +12 -0
  126. data/lib/ratatui_ruby/test_helper/snapshots/my_snapshot.txt +1 -0
  127. data/lib/ratatui_ruby/test_helper/snapshots/styled_axis_title.ansi +10 -0
  128. data/lib/ratatui_ruby/test_helper/snapshots/styled_axis_title.txt +10 -0
  129. data/lib/ratatui_ruby/test_helper/snapshots/styled_dataset_name.ansi +10 -0
  130. data/lib/ratatui_ruby/test_helper/snapshots/styled_dataset_name.txt +10 -0
  131. data/lib/ratatui_ruby/test_helper/style_assertions.rb +449 -0
  132. data/lib/ratatui_ruby/test_helper/subprocess_timeout.rb +35 -0
  133. data/lib/ratatui_ruby/test_helper/terminal.rb +187 -0
  134. data/lib/ratatui_ruby/test_helper/test_doubles.rb +86 -0
  135. data/lib/ratatui_ruby/test_helper.rb +115 -0
  136. data/lib/ratatui_ruby/text/line.rb +245 -0
  137. data/lib/ratatui_ruby/text/span.rb +158 -0
  138. data/lib/ratatui_ruby/text.rb +99 -0
  139. data/lib/ratatui_ruby/tui/buffer_factories.rb +22 -0
  140. data/lib/ratatui_ruby/tui/canvas_factories.rb +149 -0
  141. data/lib/ratatui_ruby/tui/core.rb +67 -0
  142. data/lib/ratatui_ruby/tui/layout_factories.rb +153 -0
  143. data/lib/ratatui_ruby/tui/state_factories.rb +77 -0
  144. data/lib/ratatui_ruby/tui/style_factories.rb +22 -0
  145. data/lib/ratatui_ruby/tui/text_factories.rb +86 -0
  146. data/lib/ratatui_ruby/tui/widget_factories.rb +272 -0
  147. data/lib/ratatui_ruby/tui.rb +106 -0
  148. data/lib/ratatui_ruby/version.rb +12 -0
  149. data/lib/ratatui_ruby/widgets/bar_chart/bar.rb +51 -0
  150. data/lib/ratatui_ruby/widgets/bar_chart/bar_group.rb +29 -0
  151. data/lib/ratatui_ruby/widgets/bar_chart.rb +308 -0
  152. data/lib/ratatui_ruby/widgets/block.rb +266 -0
  153. data/lib/ratatui_ruby/widgets/calendar.rb +88 -0
  154. data/lib/ratatui_ruby/widgets/canvas.rb +297 -0
  155. data/lib/ratatui_ruby/widgets/cell.rb +59 -0
  156. data/lib/ratatui_ruby/widgets/center.rb +71 -0
  157. data/lib/ratatui_ruby/widgets/chart.rb +172 -0
  158. data/lib/ratatui_ruby/widgets/clear.rb +66 -0
  159. data/lib/ratatui_ruby/widgets/coerceable_widget.rb +77 -0
  160. data/lib/ratatui_ruby/widgets/cursor.rb +54 -0
  161. data/lib/ratatui_ruby/widgets/gauge.rb +146 -0
  162. data/lib/ratatui_ruby/widgets/line_gauge.rb +158 -0
  163. data/lib/ratatui_ruby/widgets/list.rb +252 -0
  164. data/lib/ratatui_ruby/widgets/list_item.rb +55 -0
  165. data/lib/ratatui_ruby/widgets/overlay.rb +55 -0
  166. data/lib/ratatui_ruby/widgets/paragraph.rb +113 -0
  167. data/lib/ratatui_ruby/widgets/ratatui_logo.rb +35 -0
  168. data/lib/ratatui_ruby/widgets/ratatui_mascot.rb +40 -0
  169. data/lib/ratatui_ruby/widgets/row.rb +123 -0
  170. data/lib/ratatui_ruby/widgets/scrollbar.rb +147 -0
  171. data/lib/ratatui_ruby/widgets/shape/label.rb +80 -0
  172. data/lib/ratatui_ruby/widgets/sparkline.rb +153 -0
  173. data/lib/ratatui_ruby/widgets/table.rb +213 -0
  174. data/lib/ratatui_ruby/widgets/tabs.rb +91 -0
  175. data/lib/ratatui_ruby/widgets.rb +43 -0
  176. data/lib/ratatui_ruby.rb +555 -0
  177. data/sig/examples/app_all_events/app.rbs +11 -0
  178. data/sig/examples/app_all_events/model/app_model.rbs +23 -0
  179. data/sig/examples/app_all_events/model/event_entry.rbs +23 -0
  180. data/sig/examples/app_all_events/model/timestamp.rbs +11 -0
  181. data/sig/examples/app_all_events/view/app_view.rbs +8 -0
  182. data/sig/examples/app_all_events/view/controls_view.rbs +6 -0
  183. data/sig/examples/app_all_events/view/counts_view.rbs +6 -0
  184. data/sig/examples/app_all_events/view/live_view.rbs +6 -0
  185. data/sig/examples/app_all_events/view/log_view.rbs +6 -0
  186. data/sig/examples/app_all_events/view.rbs +14 -0
  187. data/sig/examples/app_cli_rich_moments/app.rbs +12 -0
  188. data/sig/examples/app_color_picker/app.rbs +17 -0
  189. data/sig/examples/app_external_editor/app.rbs +12 -0
  190. data/sig/examples/app_login_form/app.rbs +11 -0
  191. data/sig/examples/app_stateful_interaction/app.rbs +39 -0
  192. data/sig/examples/verify_quickstart_dsl/app.rbs +17 -0
  193. data/sig/examples/verify_quickstart_lifecycle/app.rbs +17 -0
  194. data/sig/examples/verify_readme_usage/app.rbs +17 -0
  195. data/sig/examples/widget_block_demo/app.rbs +38 -0
  196. data/sig/examples/widget_box_demo/app.rbs +17 -0
  197. data/sig/examples/widget_calendar_demo/app.rbs +17 -0
  198. data/sig/examples/widget_cell_demo/app.rbs +17 -0
  199. data/sig/examples/widget_chart_demo/app.rbs +17 -0
  200. data/sig/examples/widget_gauge_demo/app.rbs +17 -0
  201. data/sig/examples/widget_layout_split/app.rbs +16 -0
  202. data/sig/examples/widget_line_gauge_demo/app.rbs +17 -0
  203. data/sig/examples/widget_list_demo/app.rbs +17 -0
  204. data/sig/examples/widget_map_demo/app.rbs +17 -0
  205. data/sig/examples/widget_popup_demo/app.rbs +17 -0
  206. data/sig/examples/widget_ratatui_logo_demo/app.rbs +17 -0
  207. data/sig/examples/widget_ratatui_mascot_demo/app.rbs +17 -0
  208. data/sig/examples/widget_rect/app.rbs +18 -0
  209. data/sig/examples/widget_render/app.rbs +16 -0
  210. data/sig/examples/widget_rich_text/app.rbs +17 -0
  211. data/sig/examples/widget_scroll_text/app.rbs +17 -0
  212. data/sig/examples/widget_scrollbar_demo/app.rbs +17 -0
  213. data/sig/examples/widget_sparkline_demo/app.rbs +16 -0
  214. data/sig/examples/widget_style_colors/app.rbs +20 -0
  215. data/sig/examples/widget_table_demo/app.rbs +17 -0
  216. data/sig/examples/widget_text_width/app.rbs +16 -0
  217. data/sig/generated/event_key_predicates.rbs +1348 -0
  218. data/sig/manifest.yaml +5 -0
  219. data/sig/patches/data.rbs +26 -0
  220. data/sig/patches/debugger__.rbs +8 -0
  221. data/sig/ratatui_ruby/backend/window_size.rbs +17 -0
  222. data/sig/ratatui_ruby/backend.rbs +12 -0
  223. data/sig/ratatui_ruby/buffer/cell.rbs +46 -0
  224. data/sig/ratatui_ruby/buffer.rbs +18 -0
  225. data/sig/ratatui_ruby/cell.rbs +44 -0
  226. data/sig/ratatui_ruby/clear.rbs +18 -0
  227. data/sig/ratatui_ruby/constraint.rbs +26 -0
  228. data/sig/ratatui_ruby/debug.rbs +45 -0
  229. data/sig/ratatui_ruby/draw.rbs +30 -0
  230. data/sig/ratatui_ruby/event.rbs +249 -0
  231. data/sig/ratatui_ruby/frame.rbs +23 -0
  232. data/sig/ratatui_ruby/interfaces.rbs +25 -0
  233. data/sig/ratatui_ruby/labs.rbs +90 -0
  234. data/sig/ratatui_ruby/layout/alignment.rbs +26 -0
  235. data/sig/ratatui_ruby/layout/constraint.rbs +39 -0
  236. data/sig/ratatui_ruby/layout/layout.rbs +45 -0
  237. data/sig/ratatui_ruby/layout/position.rbs +18 -0
  238. data/sig/ratatui_ruby/layout/rect.rbs +64 -0
  239. data/sig/ratatui_ruby/layout/size.rbs +18 -0
  240. data/sig/ratatui_ruby/list_state.rbs +23 -0
  241. data/sig/ratatui_ruby/output_guard.rbs +23 -0
  242. data/sig/ratatui_ruby/ratatui_ruby.rbs +113 -0
  243. data/sig/ratatui_ruby/rect.rbs +17 -0
  244. data/sig/ratatui_ruby/scrollbar_state.rbs +24 -0
  245. data/sig/ratatui_ruby/session.rbs +93 -0
  246. data/sig/ratatui_ruby/style/color.rbs +22 -0
  247. data/sig/ratatui_ruby/style/style.rbs +29 -0
  248. data/sig/ratatui_ruby/symbols.rbs +141 -0
  249. data/sig/ratatui_ruby/synthetic_events.rbs +24 -0
  250. data/sig/ratatui_ruby/table_state.rbs +27 -0
  251. data/sig/ratatui_ruby/terminal/capabilities.rbs +38 -0
  252. data/sig/ratatui_ruby/terminal/viewport.rbs +33 -0
  253. data/sig/ratatui_ruby/terminal_lifecycle.rbs +39 -0
  254. data/sig/ratatui_ruby/test_helper/event_injection.rbs +22 -0
  255. data/sig/ratatui_ruby/test_helper/snapshot.rbs +37 -0
  256. data/sig/ratatui_ruby/test_helper/style_assertions.rbs +77 -0
  257. data/sig/ratatui_ruby/test_helper/terminal.rbs +20 -0
  258. data/sig/ratatui_ruby/test_helper/test_doubles.rbs +32 -0
  259. data/sig/ratatui_ruby/test_helper.rbs +18 -0
  260. data/sig/ratatui_ruby/text/line.rbs +27 -0
  261. data/sig/ratatui_ruby/text/span.rbs +23 -0
  262. data/sig/ratatui_ruby/text.rbs +12 -0
  263. data/sig/ratatui_ruby/tui/buffer_factories.rbs +16 -0
  264. data/sig/ratatui_ruby/tui/canvas_factories.rbs +38 -0
  265. data/sig/ratatui_ruby/tui/core.rbs +23 -0
  266. data/sig/ratatui_ruby/tui/layout_factories.rbs +39 -0
  267. data/sig/ratatui_ruby/tui/state_factories.rbs +23 -0
  268. data/sig/ratatui_ruby/tui/style_factories.rbs +18 -0
  269. data/sig/ratatui_ruby/tui/text_factories.rbs +23 -0
  270. data/sig/ratatui_ruby/tui/widget_factories.rbs +138 -0
  271. data/sig/ratatui_ruby/tui.rbs +25 -0
  272. data/sig/ratatui_ruby/version.rbs +12 -0
  273. data/sig/ratatui_ruby/widgets/bar_chart.rbs +95 -0
  274. data/sig/ratatui_ruby/widgets/block.rbs +51 -0
  275. data/sig/ratatui_ruby/widgets/calendar.rbs +45 -0
  276. data/sig/ratatui_ruby/widgets/canvas.rbs +95 -0
  277. data/sig/ratatui_ruby/widgets/chart.rbs +91 -0
  278. data/sig/ratatui_ruby/widgets/coerceable_widget.rbs +26 -0
  279. data/sig/ratatui_ruby/widgets/gauge.rbs +44 -0
  280. data/sig/ratatui_ruby/widgets/line_gauge.rbs +48 -0
  281. data/sig/ratatui_ruby/widgets/list.rbs +63 -0
  282. data/sig/ratatui_ruby/widgets/misc.rbs +158 -0
  283. data/sig/ratatui_ruby/widgets/paragraph.rbs +45 -0
  284. data/sig/ratatui_ruby/widgets/row.rbs +43 -0
  285. data/sig/ratatui_ruby/widgets/scrollbar.rbs +53 -0
  286. data/sig/ratatui_ruby/widgets/shape/label.rbs +37 -0
  287. data/sig/ratatui_ruby/widgets/sparkline.rbs +45 -0
  288. data/sig/ratatui_ruby/widgets/table.rbs +78 -0
  289. data/sig/ratatui_ruby/widgets/tabs.rbs +44 -0
  290. data/sig/ratatui_ruby/widgets.rbs +16 -0
  291. data/vendor/goodcop/base.yml +1047 -0
  292. metadata +729 -0
@@ -0,0 +1,153 @@
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
+ module Widgets
10
+ # Displays high-density data in a compact row.
11
+ #
12
+ # Users need context. A single value ("90% CPU") tells you current status, but not the trend.
13
+ # Full charts take up too much room.
14
+ #
15
+ # This widget solves the density problem. It condenses history into a single line of variable-height blocks.
16
+ #
17
+ # Use it in dashboards, headers, or list items to providing trending data at a glance.
18
+ #
19
+ # {rdoc-image:/doc/images/widget_sparkline.png}[link:/examples/widget_sparkline/app_rb.html]
20
+ #
21
+ # === Example
22
+ #
23
+ # Run the interactive demo from the terminal:
24
+ #
25
+ # ruby examples/widget_sparkline/app.rb
26
+ class Sparkline < Data.define(:data, :max, :style, :block, :direction, :absent_value_symbol, :absent_value_style, :bar_set)
27
+ include CoerceableWidget
28
+
29
+ ##
30
+ # :attr_reader: data
31
+ # Array of integer values to plot.
32
+
33
+ ##
34
+ # :attr_reader: max
35
+ # Maximum value for scaling (optional).
36
+ #
37
+ # If nil, derived from data max.
38
+
39
+ ##
40
+ # :attr_reader: style
41
+ # Style for the bars.
42
+
43
+ ##
44
+ # :attr_reader: block
45
+ # Optional wrapping block.
46
+
47
+ ##
48
+ # :attr_reader: direction
49
+ # Direction to render data.
50
+ #
51
+ # Accepts +:left_to_right+ (default) or +:right_to_left+.
52
+ # Use +:right_to_left+ when new data should appear on the left.
53
+
54
+ ##
55
+ # :attr_reader: absent_value_symbol
56
+ # Character to render for absent (nil) values (optional).
57
+ #
58
+ # If nil, absent values are rendered with a space.
59
+
60
+ ##
61
+ # :attr_reader: absent_value_style
62
+ # Style for absent (nil) values (optional).
63
+
64
+ ##
65
+ # :attr_reader: bar_set
66
+ # Custom characters for the bars (optional).
67
+ #
68
+ # A Hash with keys defining the characters for the bars.
69
+ # Keys: <tt>:empty</tt>, <tt>:one_eighth</tt>, <tt>:one_quarter</tt>, <tt>:three_eighths</tt>, <tt>:half</tt>, <tt>:five_eighths</tt>, <tt>:three_quarters</tt>, <tt>:seven_eighths</tt>, <tt>:full</tt>.
70
+ #
71
+ # You can also use integers (0-8) as keys, where 0 is empty, 4 is half, and 8 is full.
72
+ #
73
+ # Alternatively, you can pass an Array of 9 strings, where index 0 is empty and index 8 is full.
74
+ #
75
+ # === Examples
76
+ #
77
+ #--
78
+ # SPDX-SnippetBegin
79
+ # SPDX-FileCopyrightText: 2026 Kerrick Long
80
+ # SPDX-License-Identifier: MIT-0
81
+ #++
82
+ # bar_set: {
83
+ # empty: " ",
84
+ # one_eighth: " ",
85
+ # one_quarter: "▂",
86
+ # three_eighths: "▃",
87
+ # half: "▄",
88
+ # five_eighths: "▅",
89
+ # three_quarters: "▆",
90
+ # seven_eighths: "▇",
91
+ # full: "█"
92
+ # }
93
+ #
94
+ # # Numeric keys (0-8)
95
+ # bar_set: {
96
+ # 0 => " ", 1 => " ", 2 => "▂", 3 => "▃", 4 => "▄", 5 => "▅", 6 => "▆", 7 => "▇", 8 => "█"
97
+ # }
98
+ #
99
+ # # Array (9 items)
100
+ # bar_set: [" ", " ", "▂", "▃", "▄", "▅", "▆", "▇", "█"]
101
+ #--
102
+ # SPDX-SnippetEnd
103
+ #++
104
+
105
+ BAR_KEYS = %i[empty one_eighth one_quarter three_eighths half five_eighths three_quarters seven_eighths full].freeze
106
+
107
+ # Creates a new Sparkline widget.
108
+ #
109
+ # [data] Array of Integers or nil. nil marks an absent value (distinct from 0).
110
+ # [max] Max value (optional).
111
+ # [style] Style (optional).
112
+ # [block] Block (optional).
113
+ # [direction] +:left_to_right+ or +:right_to_left+ (default: +:left_to_right+).
114
+ # [absent_value_symbol] Character for absent (nil) values (optional).
115
+ # [absent_value_style] Style for absent (nil) values (optional).
116
+ # [bar_set] Symbol, Hash, or Array of custom characters (optional).
117
+ # Symbols: <tt>:nine_levels</tt> (default gradient), <tt>:three_levels</tt> (simplified).
118
+ def initialize(data:, max: nil, style: nil, block: nil, direction: :left_to_right, absent_value_symbol: nil, absent_value_style: nil, bar_set: nil)
119
+ # Normalize bar_set to Hash[Symbol, String] if provided as Array or Hash
120
+ bar_set = case bar_set
121
+ when Symbol, nil
122
+ bar_set
123
+ when Array
124
+ # Convert Array to Hash using BAR_KEYS order
125
+ BAR_KEYS.zip(bar_set).to_h
126
+ when Hash
127
+ # @type var raw_hash: Hash[untyped, untyped]
128
+ raw_hash = bar_set.dup
129
+ normalized = {} #: Hash[Symbol, String]
130
+ # Normalize numeric keys (0-8) to symbolic keys
131
+ BAR_KEYS.each_with_index do |key, i|
132
+ val = raw_hash.delete(i) || raw_hash.delete(i.to_s) || raw_hash.delete(key)
133
+ normalized[key] = val.to_s if val
134
+ end
135
+ normalized
136
+ else
137
+ bar_set
138
+ end
139
+ coerced_data = data.map { |v| v.nil? ? nil : Integer(v) }
140
+ super(
141
+ data: coerced_data,
142
+ max: max.nil? ? nil : Integer(max),
143
+ style:,
144
+ block:,
145
+ direction:,
146
+ absent_value_symbol:,
147
+ absent_value_style:,
148
+ bar_set:
149
+ )
150
+ end
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,213 @@
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
+ module Widgets
10
+ # Displays structured data in rows and columns.
11
+ #
12
+ # Data is often multidimensional. You need to show relationships between fields (Name, Age, ID).
13
+ # Aligning columns manually in a monospaced environment is painful and error-prone.
14
+ #
15
+ # This widget creates a grid. It enforces column widths using constraints. It renders headers, rows, and footers aligned perfectly.
16
+ #
17
+ # Use it to display database records, logs, or file lists.
18
+ #
19
+ # {rdoc-image:/doc/images/widget_table.png}[link:/examples/widget_table/app_rb.html]
20
+ #
21
+ # === Example
22
+ #
23
+ # Run the interactive demo from the terminal:
24
+ #
25
+ # ruby examples/widget_table/app.rb
26
+ class Table < Data.define(:header, :rows, :widths, :row_highlight_style, :highlight_symbol, :highlight_spacing, :column_highlight_style, :cell_highlight_style, :selected_row, :selected_column, :offset, :block, :footer, :flex, :style, :column_spacing)
27
+ include CoerceableWidget
28
+
29
+ ##
30
+ # Highlight spacing: always show the spacing column.
31
+ HIGHLIGHT_ALWAYS = :always
32
+ ##
33
+ # Highlight spacing: show spacing only when a row is selected (default).
34
+ HIGHLIGHT_WHEN_SELECTED = :when_selected
35
+ ##
36
+ # Highlight spacing: never show the spacing column.
37
+ HIGHLIGHT_NEVER = :never
38
+
39
+ ##
40
+ # Flex: use legacy column sizing.
41
+ FLEX_LEGACY = :legacy
42
+ ##
43
+ # Flex: align columns to start.
44
+ FLEX_START = :start
45
+ ##
46
+ # Flex: center columns.
47
+ FLEX_CENTER = :center
48
+ ##
49
+ # Flex: align columns to end.
50
+ FLEX_END = :end
51
+ ##
52
+ # Flex: space between columns.
53
+ FLEX_SPACE_BETWEEN = :space_between
54
+ ##
55
+ # Flex: space around columns.
56
+ FLEX_SPACE_AROUND = :space_around
57
+ ##
58
+ # Flex: space evenly between columns.
59
+ FLEX_SPACE_EVENLY = :space_evenly
60
+
61
+ ##
62
+ # :attr_reader: header
63
+ # Header row content (Array of Strings, Text::Spans, Text::Lines, or Paragraphs).
64
+
65
+ ##
66
+ # :attr_reader: rows
67
+ # Data rows (Array of Arrays). Each cell can be String, Text::Span, Text::Line, Paragraph, or Cell.
68
+
69
+ ##
70
+ # :attr_reader: widths
71
+ # Column width constraints (Array of Constraint or Integer).
72
+ # Integers are automatically coerced to Constraint.length.
73
+
74
+ ##
75
+ # :attr_reader: row_highlight_style
76
+ # Style for the selected row.
77
+
78
+ ##
79
+ # :attr_reader: highlight_symbol
80
+ # Symbol for the selected row.
81
+
82
+ ##
83
+ # :attr_reader: highlight_spacing
84
+ # When to show the highlight symbol column (<tt>:always</tt>, <tt>:when_selected</tt>, <tt>:never</tt>).
85
+
86
+ ##
87
+ # :attr_reader: column_highlight_style
88
+ # Style for the selected column.
89
+
90
+ ##
91
+ # :attr_reader: cell_highlight_style
92
+ # Style for the selected cell (intersection of row and column).
93
+
94
+ ##
95
+ # :attr_reader: selected_row
96
+ # Index of the selected row (Integer or nil).
97
+
98
+ ##
99
+ # :attr_reader: selected_column
100
+ # Index of the selected column (Integer or nil).
101
+
102
+ ##
103
+ # :attr_reader: offset
104
+ # Scroll offset (Integer or nil).
105
+ #
106
+ # Controls the viewport's starting row position in the table.
107
+ #
108
+ # When +nil+ (default), Ratatui auto-scrolls to keep the selection visible ("natural scrolling").
109
+ #
110
+ # When set, forces the viewport to start at this row index. Use this for:
111
+ # - **Passive scrolling**: Scroll through a log table without selecting rows.
112
+ # - **Click-to-select math**: Calculate which row index corresponds to a click coordinate.
113
+ #
114
+ # *Important*: When both +offset+ and +selected_row+ are set, Ratatui may still adjust
115
+ # the viewport during rendering to ensure the selection stays visible. Set +selected_row+
116
+ # to +nil+ for fully manual scroll control.
117
+
118
+ ##
119
+ # :attr_reader: block
120
+ # Optional wrapping block.
121
+
122
+ ##
123
+ # :attr_reader: footer
124
+ # Footer row content (Array of Strings, Text::Spans, Text::Lines, or Paragraphs).
125
+
126
+ ##
127
+ # :attr_reader: flex
128
+ # Flex mode for column distribution.
129
+
130
+ ##
131
+ # :attr_reader: style
132
+ # Base style for the entire table.
133
+
134
+ ##
135
+ # :attr_reader: column_spacing
136
+ # Spacing between columns (Integer, default 1).
137
+
138
+ # Creates a new Table.
139
+ #
140
+ # [header] Array of strings, Text::Spans, Text::Lines, or paragraphs.
141
+ # [rows] 2D Array where each cell is String, Text::Span, Text::Line, Paragraph, or Cell.
142
+ # [widths] Array of Constraints or Integers (integers coerce to Constraint.length).
143
+ # [row_highlight_style] Style object.
144
+ # [highlight_symbol] String.
145
+ # [highlight_spacing] Symbol (optional, default: <tt>:when_selected</tt>).
146
+ # [column_highlight_style] Style object.
147
+ # [cell_highlight_style] Style object.
148
+ # [selected_row] Integer (nullable).
149
+ # [selected_column] Integer (nullable).
150
+ # [offset] Numeric (nullable, coerced to Integer). Forces scroll position when set.
151
+ # [block] Block (optional).
152
+ # [footer] Array of strings/paragraphs (optional).
153
+ # [flex] Symbol (optional, default: <tt>:legacy</tt>).
154
+ # [style] Style object or Hash (optional).
155
+ # [column_spacing] Integer (optional, default: 1).
156
+ def initialize(header: nil, rows: [], widths: [], row_highlight_style: nil, highlight_symbol: "> ", highlight_spacing: :when_selected, column_highlight_style: nil, cell_highlight_style: nil, selected_row: nil, selected_column: nil, offset: nil, block: nil, footer: nil, flex: :legacy, style: nil, column_spacing: 1)
157
+ coerced_widths = widths.map do |w|
158
+ w.is_a?(Integer) ? Layout::Constraint.length(w) : w
159
+ end
160
+
161
+ super(
162
+ header:,
163
+ rows:,
164
+ widths: coerced_widths,
165
+ row_highlight_style:,
166
+ highlight_symbol:,
167
+ highlight_spacing:,
168
+ column_highlight_style:,
169
+ cell_highlight_style:,
170
+ selected_row: selected_row.nil? ? nil : Integer(selected_row),
171
+ selected_column: selected_column.nil? ? nil : Integer(selected_column),
172
+ offset: offset.nil? ? nil : Integer(offset),
173
+ block:,
174
+ footer:,
175
+ flex:,
176
+ style:,
177
+ column_spacing: Integer(column_spacing)
178
+ )
179
+ end
180
+
181
+ # Returns true if a row is selected.
182
+ #
183
+ # @return [Boolean]
184
+ def row_selected?
185
+ !selected_row.nil?
186
+ end
187
+
188
+ # Returns true if a column is selected.
189
+ #
190
+ # @return [Boolean]
191
+ def column_selected?
192
+ !selected_column.nil?
193
+ end
194
+
195
+ # Returns true if both a row and column are selected (a cell is selected).
196
+ #
197
+ # @return [Boolean]
198
+ def cell_selected?
199
+ row_selected? && column_selected?
200
+ end
201
+
202
+ # Returns true if the table has no rows.
203
+ #
204
+ # @return [Boolean]
205
+ def empty?
206
+ rows.empty?
207
+ end
208
+
209
+ # NOTE: No 'selection' alias - it's ambiguous whether it returns a row or index.
210
+ # Use selected_row for the row index, selected_column for the column index.
211
+ end
212
+ end
213
+ end
@@ -0,0 +1,91 @@
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
+ module Widgets
10
+ # Displays a tab bar for navigation.
11
+ #
12
+ # Screen real estate is limited. You cannot show everything at once. Segregating content into views is necessary for complex apps.
13
+ #
14
+ # This widget separates dimensions. It displays a row of titles, indicating which view is active.
15
+ #
16
+ # Use it at the top of your interface to switch between major modes or contexts.
17
+ #
18
+ # {rdoc-image:/doc/images/widget_tabs.png}[link:/examples/widget_tabs/app_rb.html]
19
+ #
20
+ # === Example
21
+ #
22
+ # Run the interactive demo from the terminal:
23
+ #
24
+ # ruby examples/widget_tabs/app.rb
25
+ class Tabs < Data.define(:titles, :selected_index, :block, :divider, :highlight_style, :style, :padding_left, :padding_right)
26
+ include CoerceableWidget
27
+
28
+ ##
29
+ # :attr_reader: titles
30
+ # Tab titles (Array of Strings).
31
+
32
+ ##
33
+ # :attr_reader: selected_index
34
+ # Index of the active tab.
35
+
36
+ ##
37
+ # :attr_reader: block
38
+ # Optional wrapping block.
39
+
40
+ ##
41
+ # :attr_reader: divider
42
+ # Separator string between tabs.
43
+
44
+ ##
45
+ # :attr_reader: highlight_style
46
+ # Style for the selected tab title.
47
+
48
+ ##
49
+ # :attr_reader: style
50
+ # Base style for the tabs area.
51
+
52
+ ##
53
+ # :attr_reader: padding_left
54
+ # Left padding for the tabs area.
55
+ # Accepts Integer (number of spaces), String, or Line for styled content.
56
+
57
+ ##
58
+ # :attr_reader: padding_right
59
+ # Right padding for the tabs area.
60
+ # Accepts Integer (number of spaces), String, or Line for styled content.
61
+
62
+ # Creates a new Tabs widget.
63
+ #
64
+ # [titles] Array of Strings/Lines.
65
+ # [selected_index] Integer (default: 0).
66
+ # [block] Block (optional).
67
+ # [divider] String (optional).
68
+ # [highlight_style] Style (optional).
69
+ # [style] Style (optional).
70
+ # [padding_left] String, Line, or anything that responds to <tt>to_i</tt> (default: 0).
71
+ # [padding_right] String, Line, or anything that responds to <tt>to_i</tt> (default: 0).
72
+ def initialize(titles: [], selected_index: 0, block: nil, divider: nil, highlight_style: nil, style: nil, padding_left: 0, padding_right: 0)
73
+ super(
74
+ titles:,
75
+ selected_index: Integer(selected_index),
76
+ block:,
77
+ divider:,
78
+ highlight_style:,
79
+ style:,
80
+ padding_left: (padding_left.is_a?(Text::Line) || padding_left.is_a?(String)) ? padding_left : Integer(padding_left),
81
+ padding_right: (padding_right.is_a?(Text::Line) || padding_right.is_a?(String)) ? padding_right : Integer(padding_right)
82
+ )
83
+ end
84
+
85
+ # Returns the total width of the tabs.
86
+ def width
87
+ RatatuiRuby._tabs_width(self)
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,43 @@
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
+ # Widget classes for building terminal UIs.
10
+ #
11
+ # This module mirrors +ratatui::widgets+ and contains all renderable
12
+ # widget types: Block, Paragraph, List, Table, Gauge, Chart, etc.
13
+ module Widgets
14
+ end
15
+ end
16
+
17
+ # Core widgets
18
+ require_relative "widgets/coerceable_widget"
19
+ require_relative "widgets/block"
20
+ require_relative "widgets/paragraph"
21
+ require_relative "widgets/list"
22
+ require_relative "widgets/list_item"
23
+ require_relative "widgets/table"
24
+ require_relative "widgets/row"
25
+ require_relative "widgets/cell"
26
+ require_relative "widgets/tabs"
27
+ require_relative "widgets/gauge"
28
+ require_relative "widgets/line_gauge"
29
+ require_relative "widgets/sparkline"
30
+ require_relative "widgets/bar_chart"
31
+ require_relative "widgets/bar_chart/bar"
32
+ require_relative "widgets/bar_chart/bar_group"
33
+ require_relative "widgets/chart"
34
+ require_relative "widgets/scrollbar"
35
+ require_relative "widgets/calendar"
36
+ require_relative "widgets/canvas"
37
+ require_relative "widgets/clear"
38
+ require_relative "widgets/cursor"
39
+ require_relative "widgets/overlay"
40
+ require_relative "widgets/center"
41
+ require_relative "widgets/ratatui_logo"
42
+ require_relative "widgets/ratatui_mascot"
43
+ require_relative "widgets/shape/label"