ratatui_ruby 0.9.1 → 0.10.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 (267) 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 +98 -0
  8. data/REUSE.toml +5 -0
  9. data/Rakefile +1 -1
  10. data/Steepfile +49 -0
  11. data/doc/concepts/debugging.md +401 -0
  12. data/doc/getting_started/quickstart.md +8 -3
  13. data/doc/images/app_all_events.png +0 -0
  14. data/doc/images/app_color_picker.png +0 -0
  15. data/doc/images/app_debugging_showcase.gif +0 -0
  16. data/doc/images/app_debugging_showcase.png +0 -0
  17. data/doc/images/app_login_form.png +0 -0
  18. data/doc/images/app_stateful_interaction.png +0 -0
  19. data/doc/images/verify_quickstart_dsl.png +0 -0
  20. data/doc/images/verify_quickstart_layout.png +0 -0
  21. data/doc/images/verify_quickstart_lifecycle.png +0 -0
  22. data/doc/images/verify_readme_usage.png +0 -0
  23. data/doc/images/widget_barchart.png +0 -0
  24. data/doc/images/widget_block.png +0 -0
  25. data/doc/images/widget_box.png +0 -0
  26. data/doc/images/widget_calendar.png +0 -0
  27. data/doc/images/widget_canvas.png +0 -0
  28. data/doc/images/widget_cell.png +0 -0
  29. data/doc/images/widget_center.png +0 -0
  30. data/doc/images/widget_chart.png +0 -0
  31. data/doc/images/widget_gauge.png +0 -0
  32. data/doc/images/widget_layout_split.png +0 -0
  33. data/doc/images/widget_line_gauge.png +0 -0
  34. data/doc/images/widget_list.png +0 -0
  35. data/doc/images/widget_map.png +0 -0
  36. data/doc/images/widget_overlay.png +0 -0
  37. data/doc/images/widget_popup.png +0 -0
  38. data/doc/images/widget_ratatui_logo.png +0 -0
  39. data/doc/images/widget_ratatui_mascot.png +0 -0
  40. data/doc/images/widget_rect.png +0 -0
  41. data/doc/images/widget_render.png +0 -0
  42. data/doc/images/widget_rich_text.png +0 -0
  43. data/doc/images/widget_scroll_text.png +0 -0
  44. data/doc/images/widget_scrollbar.png +0 -0
  45. data/doc/images/widget_sparkline.png +0 -0
  46. data/doc/images/widget_style_colors.png +0 -0
  47. data/doc/images/widget_table.png +0 -0
  48. data/doc/images/widget_tabs.png +0 -0
  49. data/doc/images/widget_text_width.png +0 -0
  50. data/doc/troubleshooting/async.md +4 -0
  51. data/examples/app_debugging_showcase/README.md +119 -0
  52. data/examples/app_debugging_showcase/app.rb +318 -0
  53. data/examples/widget_canvas/app.rb +19 -14
  54. data/examples/widget_gauge/app.rb +18 -3
  55. data/examples/widget_layout_split/app.rb +10 -4
  56. data/examples/widget_list/app.rb +22 -6
  57. data/examples/widget_rect/app.rb +7 -6
  58. data/examples/widget_rich_text/app.rb +62 -37
  59. data/examples/widget_style_colors/app.rb +26 -47
  60. data/examples/widget_table/app.rb +28 -5
  61. data/examples/widget_text_width/app.rb +6 -4
  62. data/ext/ratatui_ruby/Cargo.lock +48 -1
  63. data/ext/ratatui_ruby/Cargo.toml +6 -2
  64. data/ext/ratatui_ruby/src/color.rs +82 -0
  65. data/ext/ratatui_ruby/src/errors.rs +28 -0
  66. data/ext/ratatui_ruby/src/events.rs +15 -14
  67. data/ext/ratatui_ruby/src/lib.rs +56 -0
  68. data/ext/ratatui_ruby/src/rendering.rs +3 -1
  69. data/ext/ratatui_ruby/src/style.rs +48 -21
  70. data/ext/ratatui_ruby/src/terminal.rs +40 -9
  71. data/ext/ratatui_ruby/src/text.rs +21 -9
  72. data/ext/ratatui_ruby/src/widgets/chart.rs +2 -1
  73. data/ext/ratatui_ruby/src/widgets/layout.rs +90 -2
  74. data/ext/ratatui_ruby/src/widgets/list.rs +6 -5
  75. data/ext/ratatui_ruby/src/widgets/overlay.rs +2 -1
  76. data/ext/ratatui_ruby/src/widgets/table.rs +7 -6
  77. data/ext/ratatui_ruby/src/widgets/table_state.rs +55 -0
  78. data/ext/ratatui_ruby/src/widgets/tabs.rs +3 -2
  79. data/lib/ratatui_ruby/buffer/cell.rb +25 -15
  80. data/lib/ratatui_ruby/buffer.rb +134 -2
  81. data/lib/ratatui_ruby/cell.rb +13 -5
  82. data/lib/ratatui_ruby/debug.rb +215 -0
  83. data/lib/ratatui_ruby/event/key.rb +3 -2
  84. data/lib/ratatui_ruby/event.rb +1 -1
  85. data/lib/ratatui_ruby/layout/constraint.rb +49 -0
  86. data/lib/ratatui_ruby/layout/layout.rb +119 -13
  87. data/lib/ratatui_ruby/layout/position.rb +55 -0
  88. data/lib/ratatui_ruby/layout/rect.rb +188 -0
  89. data/lib/ratatui_ruby/layout/size.rb +55 -0
  90. data/lib/ratatui_ruby/layout.rb +4 -0
  91. data/lib/ratatui_ruby/style/color.rb +149 -0
  92. data/lib/ratatui_ruby/style/style.rb +51 -4
  93. data/lib/ratatui_ruby/style.rb +2 -0
  94. data/lib/ratatui_ruby/symbols.rb +435 -0
  95. data/lib/ratatui_ruby/synthetic_events.rb +1 -1
  96. data/lib/ratatui_ruby/table_state.rb +51 -0
  97. data/lib/ratatui_ruby/terminal_lifecycle.rb +2 -1
  98. data/lib/ratatui_ruby/test_helper/event_injection.rb +6 -1
  99. data/lib/ratatui_ruby/test_helper.rb +9 -0
  100. data/lib/ratatui_ruby/text/line.rb +245 -0
  101. data/lib/ratatui_ruby/text/span.rb +158 -0
  102. data/lib/ratatui_ruby/text.rb +99 -0
  103. data/lib/ratatui_ruby/tui/canvas_factories.rb +103 -0
  104. data/lib/ratatui_ruby/tui/core.rb +13 -2
  105. data/lib/ratatui_ruby/tui/layout_factories.rb +50 -3
  106. data/lib/ratatui_ruby/tui/state_factories.rb +42 -0
  107. data/lib/ratatui_ruby/tui/text_factories.rb +40 -0
  108. data/lib/ratatui_ruby/tui/widget_factories.rb +135 -60
  109. data/lib/ratatui_ruby/tui.rb +22 -1
  110. data/lib/ratatui_ruby/version.rb +1 -1
  111. data/lib/ratatui_ruby/widgets/bar_chart/bar.rb +2 -0
  112. data/lib/ratatui_ruby/widgets/bar_chart/bar_group.rb +2 -0
  113. data/lib/ratatui_ruby/widgets/bar_chart.rb +30 -20
  114. data/lib/ratatui_ruby/widgets/block.rb +14 -6
  115. data/lib/ratatui_ruby/widgets/calendar.rb +2 -0
  116. data/lib/ratatui_ruby/widgets/canvas.rb +56 -0
  117. data/lib/ratatui_ruby/widgets/cell.rb +2 -0
  118. data/lib/ratatui_ruby/widgets/center.rb +2 -0
  119. data/lib/ratatui_ruby/widgets/chart.rb +6 -0
  120. data/lib/ratatui_ruby/widgets/clear.rb +2 -0
  121. data/lib/ratatui_ruby/widgets/coerceable_widget.rb +77 -0
  122. data/lib/ratatui_ruby/widgets/cursor.rb +2 -0
  123. data/lib/ratatui_ruby/widgets/gauge.rb +61 -3
  124. data/lib/ratatui_ruby/widgets/line_gauge.rb +66 -4
  125. data/lib/ratatui_ruby/widgets/list.rb +87 -3
  126. data/lib/ratatui_ruby/widgets/list_item.rb +2 -0
  127. data/lib/ratatui_ruby/widgets/overlay.rb +2 -0
  128. data/lib/ratatui_ruby/widgets/paragraph.rb +4 -0
  129. data/lib/ratatui_ruby/widgets/ratatui_logo.rb +2 -0
  130. data/lib/ratatui_ruby/widgets/ratatui_mascot.rb +2 -0
  131. data/lib/ratatui_ruby/widgets/row.rb +45 -0
  132. data/lib/ratatui_ruby/widgets/scrollbar.rb +2 -0
  133. data/lib/ratatui_ruby/widgets/shape/label.rb +2 -0
  134. data/lib/ratatui_ruby/widgets/sparkline.rb +21 -13
  135. data/lib/ratatui_ruby/widgets/table.rb +13 -3
  136. data/lib/ratatui_ruby/widgets/tabs.rb +6 -4
  137. data/lib/ratatui_ruby/widgets.rb +1 -0
  138. data/lib/ratatui_ruby.rb +40 -9
  139. data/sig/examples/app_all_events/model/app_model.rbs +23 -0
  140. data/sig/examples/app_all_events/model/event_entry.rbs +15 -8
  141. data/sig/examples/app_all_events/model/timestamp.rbs +1 -1
  142. data/sig/examples/app_all_events/view.rbs +1 -1
  143. data/sig/examples/app_stateful_interaction/app.rbs +5 -5
  144. data/sig/examples/widget_block_demo/app.rbs +6 -6
  145. data/sig/manifest.yaml +5 -0
  146. data/sig/patches/data.rbs +26 -0
  147. data/sig/patches/debugger__.rbs +8 -0
  148. data/sig/ratatui_ruby/buffer/cell.rbs +46 -0
  149. data/sig/ratatui_ruby/buffer.rbs +18 -0
  150. data/sig/ratatui_ruby/cell.rbs +44 -0
  151. data/sig/ratatui_ruby/clear.rbs +18 -0
  152. data/sig/ratatui_ruby/constraint.rbs +26 -0
  153. data/sig/ratatui_ruby/debug.rbs +45 -0
  154. data/sig/ratatui_ruby/draw.rbs +30 -0
  155. data/sig/ratatui_ruby/event.rbs +68 -8
  156. data/sig/ratatui_ruby/frame.rbs +4 -4
  157. data/sig/ratatui_ruby/interfaces.rbs +25 -0
  158. data/sig/ratatui_ruby/layout/constraint.rbs +39 -0
  159. data/sig/ratatui_ruby/layout/layout.rbs +45 -0
  160. data/sig/ratatui_ruby/layout/position.rbs +18 -0
  161. data/sig/ratatui_ruby/layout/rect.rbs +64 -0
  162. data/sig/ratatui_ruby/layout/size.rbs +18 -0
  163. data/sig/ratatui_ruby/output_guard.rbs +23 -0
  164. data/sig/ratatui_ruby/ratatui_ruby.rbs +83 -4
  165. data/sig/ratatui_ruby/rect.rbs +17 -0
  166. data/sig/ratatui_ruby/style/color.rbs +22 -0
  167. data/sig/ratatui_ruby/style/style.rbs +29 -0
  168. data/sig/ratatui_ruby/symbols.rbs +141 -0
  169. data/sig/ratatui_ruby/synthetic_events.rbs +21 -0
  170. data/sig/ratatui_ruby/table_state.rbs +6 -0
  171. data/sig/ratatui_ruby/terminal_lifecycle.rbs +31 -0
  172. data/sig/ratatui_ruby/test_helper/event_injection.rbs +2 -2
  173. data/sig/ratatui_ruby/test_helper/snapshot.rbs +22 -3
  174. data/sig/ratatui_ruby/test_helper/style_assertions.rbs +8 -1
  175. data/sig/ratatui_ruby/test_helper/test_doubles.rbs +7 -3
  176. data/sig/ratatui_ruby/text/line.rbs +27 -0
  177. data/sig/ratatui_ruby/text/span.rbs +23 -0
  178. data/sig/ratatui_ruby/text.rbs +12 -0
  179. data/sig/ratatui_ruby/tui/buffer_factories.rbs +1 -1
  180. data/sig/ratatui_ruby/tui/canvas_factories.rbs +23 -5
  181. data/sig/ratatui_ruby/tui/core.rbs +2 -2
  182. data/sig/ratatui_ruby/tui/layout_factories.rbs +16 -2
  183. data/sig/ratatui_ruby/tui/state_factories.rbs +8 -3
  184. data/sig/ratatui_ruby/tui/style_factories.rbs +3 -1
  185. data/sig/ratatui_ruby/tui/text_factories.rbs +7 -4
  186. data/sig/ratatui_ruby/tui/widget_factories.rbs +123 -30
  187. data/sig/ratatui_ruby/widgets/bar_chart.rbs +95 -0
  188. data/sig/ratatui_ruby/widgets/block.rbs +51 -0
  189. data/sig/ratatui_ruby/widgets/calendar.rbs +45 -0
  190. data/sig/ratatui_ruby/widgets/canvas.rbs +95 -0
  191. data/sig/ratatui_ruby/widgets/chart.rbs +91 -0
  192. data/sig/ratatui_ruby/widgets/coerceable_widget.rbs +26 -0
  193. data/sig/ratatui_ruby/widgets/gauge.rbs +44 -0
  194. data/sig/ratatui_ruby/widgets/line_gauge.rbs +48 -0
  195. data/sig/ratatui_ruby/widgets/list.rbs +63 -0
  196. data/sig/ratatui_ruby/widgets/misc.rbs +158 -0
  197. data/sig/ratatui_ruby/widgets/paragraph.rbs +45 -0
  198. data/sig/ratatui_ruby/widgets/row.rbs +43 -0
  199. data/sig/ratatui_ruby/widgets/scrollbar.rbs +53 -0
  200. data/sig/ratatui_ruby/widgets/shape/label.rbs +37 -0
  201. data/sig/ratatui_ruby/widgets/sparkline.rbs +45 -0
  202. data/sig/ratatui_ruby/widgets/table.rbs +78 -0
  203. data/sig/ratatui_ruby/widgets/tabs.rbs +44 -0
  204. data/sig/ratatui_ruby/{schema/list_item.rbs → widgets.rbs} +4 -4
  205. data/tasks/steep.rake +11 -0
  206. metadata +80 -63
  207. data/doc/contributors/v1.0.0_blockers.md +0 -870
  208. data/doc/troubleshooting/debugging.md +0 -101
  209. data/lib/ratatui_ruby/schema/bar_chart/bar.rb +0 -47
  210. data/lib/ratatui_ruby/schema/bar_chart/bar_group.rb +0 -25
  211. data/lib/ratatui_ruby/schema/bar_chart.rb +0 -287
  212. data/lib/ratatui_ruby/schema/block.rb +0 -198
  213. data/lib/ratatui_ruby/schema/calendar.rb +0 -84
  214. data/lib/ratatui_ruby/schema/canvas.rb +0 -239
  215. data/lib/ratatui_ruby/schema/center.rb +0 -67
  216. data/lib/ratatui_ruby/schema/chart.rb +0 -159
  217. data/lib/ratatui_ruby/schema/clear.rb +0 -62
  218. data/lib/ratatui_ruby/schema/constraint.rb +0 -151
  219. data/lib/ratatui_ruby/schema/cursor.rb +0 -50
  220. data/lib/ratatui_ruby/schema/gauge.rb +0 -72
  221. data/lib/ratatui_ruby/schema/layout.rb +0 -122
  222. data/lib/ratatui_ruby/schema/line_gauge.rb +0 -80
  223. data/lib/ratatui_ruby/schema/list.rb +0 -135
  224. data/lib/ratatui_ruby/schema/list_item.rb +0 -51
  225. data/lib/ratatui_ruby/schema/overlay.rb +0 -51
  226. data/lib/ratatui_ruby/schema/paragraph.rb +0 -107
  227. data/lib/ratatui_ruby/schema/ratatui_logo.rb +0 -31
  228. data/lib/ratatui_ruby/schema/ratatui_mascot.rb +0 -36
  229. data/lib/ratatui_ruby/schema/rect.rb +0 -174
  230. data/lib/ratatui_ruby/schema/row.rb +0 -76
  231. data/lib/ratatui_ruby/schema/scrollbar.rb +0 -143
  232. data/lib/ratatui_ruby/schema/shape/label.rb +0 -76
  233. data/lib/ratatui_ruby/schema/sparkline.rb +0 -142
  234. data/lib/ratatui_ruby/schema/style.rb +0 -97
  235. data/lib/ratatui_ruby/schema/table.rb +0 -141
  236. data/lib/ratatui_ruby/schema/tabs.rb +0 -85
  237. data/lib/ratatui_ruby/schema/text.rb +0 -217
  238. data/sig/examples/app_all_events/model/events.rbs +0 -15
  239. data/sig/examples/app_all_events/view_state.rbs +0 -21
  240. data/sig/ratatui_ruby/schema/bar_chart/bar.rbs +0 -22
  241. data/sig/ratatui_ruby/schema/bar_chart/bar_group.rbs +0 -19
  242. data/sig/ratatui_ruby/schema/bar_chart.rbs +0 -38
  243. data/sig/ratatui_ruby/schema/block.rbs +0 -18
  244. data/sig/ratatui_ruby/schema/calendar.rbs +0 -23
  245. data/sig/ratatui_ruby/schema/canvas.rbs +0 -81
  246. data/sig/ratatui_ruby/schema/center.rbs +0 -17
  247. data/sig/ratatui_ruby/schema/chart.rbs +0 -39
  248. data/sig/ratatui_ruby/schema/constraint.rbs +0 -30
  249. data/sig/ratatui_ruby/schema/cursor.rbs +0 -16
  250. data/sig/ratatui_ruby/schema/draw.rbs +0 -33
  251. data/sig/ratatui_ruby/schema/gauge.rbs +0 -23
  252. data/sig/ratatui_ruby/schema/layout.rbs +0 -27
  253. data/sig/ratatui_ruby/schema/line_gauge.rbs +0 -24
  254. data/sig/ratatui_ruby/schema/list.rbs +0 -28
  255. data/sig/ratatui_ruby/schema/overlay.rbs +0 -15
  256. data/sig/ratatui_ruby/schema/paragraph.rbs +0 -20
  257. data/sig/ratatui_ruby/schema/ratatui_logo.rbs +0 -14
  258. data/sig/ratatui_ruby/schema/ratatui_mascot.rbs +0 -17
  259. data/sig/ratatui_ruby/schema/rect.rbs +0 -48
  260. data/sig/ratatui_ruby/schema/row.rbs +0 -28
  261. data/sig/ratatui_ruby/schema/scrollbar.rbs +0 -42
  262. data/sig/ratatui_ruby/schema/sparkline.rbs +0 -22
  263. data/sig/ratatui_ruby/schema/style.rbs +0 -19
  264. data/sig/ratatui_ruby/schema/table.rbs +0 -32
  265. data/sig/ratatui_ruby/schema/tabs.rbs +0 -21
  266. data/sig/ratatui_ruby/schema/text.rbs +0 -31
  267. /data/lib/ratatui_ruby/{schema/draw.rb → draw.rb} +0 -0
@@ -9,37 +9,130 @@
9
9
 
10
10
  module RatatuiRuby
11
11
  class TUI
12
+ # Widget factory methods for TUI.
13
+ #
14
+ # All factory methods support DWIM hash coercion: both `tui.table(hash)` and
15
+ # `tui.table(**hash)` work identically.
12
16
  module WidgetFactories
13
- def block: (**top) -> Widgets::Block
14
- def paragraph: (**top) -> Widgets::Paragraph
15
- def list: (**top) -> Widgets::List
16
- def list_item: (**top) -> Widgets::ListItem
17
- def table: (**top) -> Widgets::Table
18
- def row: (**top) -> Widgets::Row
19
- def table_row: (**top) -> Widgets::Row
20
- def table_cell: (**top) -> Widgets::Cell
21
- def tabs: (**top) -> Widgets::Tabs
22
- def gauge: (**top) -> Widgets::Gauge
23
- def line_gauge: (**top) -> Widgets::LineGauge
24
- def sparkline: (**top) -> Widgets::Sparkline
25
- def bar_chart: (**top) -> Widgets::BarChart
26
- def bar: (**top) -> Widgets::BarChart::Bar
27
- def bar_group: (**top) -> Widgets::BarChart::BarGroup
28
- def bar_chart_bar: (**top) -> Widgets::BarChart::Bar
29
- def bar_chart_bar_group: (**top) -> Widgets::BarChart::BarGroup
30
- def chart: (**top) -> Widgets::Chart
31
- def dataset: (**top) -> Widgets::Dataset
32
- def axis: (**top) -> Widgets::Axis
33
- def scrollbar: (**top) -> Widgets::Scrollbar
34
- def calendar: (**top) -> Widgets::Calendar
35
- def canvas: (**top) -> Widgets::Canvas
36
- def clear: (**top) -> Widgets::Clear
37
- def cursor: (**top) -> Widgets::Cursor
38
- def overlay: (**top) -> Widgets::Overlay
39
- def center: (**top) -> Widgets::Center
40
- def ratatui_logo: (**top) -> Widgets::RatatuiLogo
41
- def ratatui_mascot: (**top) -> Widgets::RatatuiMascot
42
- def shape_label: (**top) -> Widgets::Shape::Label
17
+ # Widgets::Block
18
+ def block: (Widgets::block_options) -> Widgets::Block
19
+ | (?title: String?, ?titles: Array[title_entry], ?title_alignment: alignment?, ?title_style: style_input?, ?borders: Array[border_side], ?border_style: style_input?, ?border_type: border_type?, ?border_set: border_set_hash?, ?style: style_input?, ?padding: (_ToI | Array[_ToI]), ?children: Array[widget]) -> Widgets::Block
20
+
21
+ # Widgets::Paragraph
22
+ def paragraph: (Widgets::paragraph_options) -> Widgets::Paragraph
23
+ | (text: String, ?style: Style::Style?, ?fg: (String | Symbol)?, ?bg: (String | Symbol)?, ?block: Widgets::Block?, ?wrap: bool, ?alignment: Symbol, ?scroll: [_ToI, _ToI]) -> Widgets::Paragraph
24
+
25
+ # Widgets::List
26
+ def list: (Widgets::list_options) -> Widgets::List
27
+ | (?items: Array[String | Text::Span | Text::Line | Widgets::ListItem], ?selected_index: _ToI?, ?offset: _ToI?, ?style: Style::Style?, ?highlight_style: Style::Style?, ?highlight_symbol: String?, ?repeat_highlight_symbol: bool, ?highlight_spacing: Symbol, ?direction: Symbol, ?scroll_padding: _ToI?, ?block: Widgets::Block?) -> Widgets::List
28
+
29
+ # Widgets::ListItem
30
+ def list_item: (Widgets::list_item_options) -> Widgets::ListItem
31
+ | (content: String | Text::Span | Text::Line, ?style: Style::Style?) -> Widgets::ListItem
32
+
33
+ # DWIM alias for list_item (terse form for use in list context)
34
+ alias item list_item
35
+
36
+ # Widgets::Table
37
+ def table: (Widgets::table_options) -> Widgets::Table
38
+ | (?header: Array[String | Widgets::Paragraph]?, ?rows: Array[Array[String | Widgets::Paragraph | Style | _ToS]], ?widths: Array[Layout::Constraint | Integer], ?row_highlight_style: Style::Style?, ?highlight_symbol: String?, ?highlight_spacing: Symbol, ?column_highlight_style: Style::Style?, ?cell_highlight_style: Style::Style?, ?selected_row: _ToI?, ?selected_column: _ToI?, ?offset: _ToI?, ?block: Widgets::Block?, ?footer: Array[String | Widgets::Paragraph]?, ?flex: Symbol, ?style: style_input?, ?column_spacing: _ToI) -> Widgets::Table
39
+
40
+ # Widgets::Row
41
+ def row: (Widgets::row_options) -> Widgets::Row
42
+ | (cells: Array[String | Text::Span | Text::Line | Widgets::Paragraph | Widgets::Cell], ?style: Style::Style?, ?height: Integer?, ?top_margin: Integer?, ?bottom_margin: Integer?) -> Widgets::Row
43
+ def table_row: (Widgets::row_options) -> Widgets::Row
44
+ | (cells: Array[String | Text::Span | Text::Line | Widgets::Paragraph | Widgets::Cell], ?style: Style::Style?, ?height: Integer?, ?top_margin: Integer?, ?bottom_margin: Integer?) -> Widgets::Row
45
+
46
+ # Widgets::Cell
47
+ def table_cell: (Widgets::cell_options) -> Widgets::Cell
48
+ | (content: String | Text::Span | Text::Line | Widgets::Paragraph, ?style: Style::Style?) -> Widgets::Cell
49
+
50
+ # Widgets::Tabs
51
+ def tabs: (Widgets::tabs_options) -> Widgets::Tabs
52
+ | (?titles: Array[String | _ToS], ?selected_index: _ToI, ?block: Widgets::Block?, ?divider: String?, ?highlight_style: Style::Style?, ?style: Style::Style?, ?padding_left: (String | Text::Line | _ToI), ?padding_right: (String | Text::Line | _ToI)) -> Widgets::Tabs
53
+
54
+ # Widgets::Gauge
55
+ def gauge: (Widgets::gauge_options) -> Widgets::Gauge
56
+ | (?ratio: _ToF?, ?percent: _ToF?, ?label: String | Text::Span | nil, ?style: Style::Style?, ?gauge_style: Style::Style?, ?block: Widgets::Block?, ?use_unicode: bool) -> Widgets::Gauge
57
+
58
+ # Widgets::LineGauge
59
+ def line_gauge: (Widgets::line_gauge_options) -> Widgets::LineGauge
60
+ | (?ratio: _ToF, ?label: String | Text::Span | nil, ?style: Style::Style?, ?filled_style: Style::Style?, ?unfilled_style: Style::Style?, ?block: Widgets::Block?, ?filled_symbol: String, ?unfilled_symbol: String) -> Widgets::LineGauge
61
+
62
+ # Widgets::Sparkline
63
+ def sparkline: (Widgets::sparkline_options) -> Widgets::Sparkline
64
+ | (data: Array[_ToI?], ?max: _ToI?, ?style: Style::Style?, ?block: Widgets::Block?, ?direction: (:left_to_right | :right_to_left)?, ?absent_value_symbol: String?, ?absent_value_style: Style::Style?, ?bar_set: Hash[Symbol, String]?) -> Widgets::Sparkline
65
+
66
+ # Widgets::BarChart
67
+ def bar_chart: (Widgets::bar_chart_options) -> Widgets::BarChart
68
+ | (data: Hash[String | Symbol | _ToS, _ToI] | Array[Array[String | Symbol | _ToS | _ToI]] | Array[Widgets::BarChart::BarGroup], ?bar_width: _ToI, ?bar_gap: _ToI, ?group_gap: _ToI, ?max: _ToI?, ?style: Style::Style?, ?block: Widgets::Block?, ?direction: (:vertical | :horizontal), ?label_style: Style::Style?, ?value_style: Style::Style?, ?bar_set: Hash[Symbol, String]?) -> Widgets::BarChart
69
+
70
+ # Widgets::BarChart::Bar
71
+ def bar: (Widgets::bar_options) -> Widgets::BarChart::Bar
72
+ | (value: _ToI, ?label: String | Text::Span | Text::Line | nil, ?style: Style::Style?, ?value_style: Style::Style?, ?text_value: String | Text::Span | Text::Line | nil) -> Widgets::BarChart::Bar
73
+ def bar_chart_bar: (Widgets::bar_options) -> Widgets::BarChart::Bar
74
+ | (value: _ToI, ?label: String | Text::Span | Text::Line | nil, ?style: Style::Style?, ?value_style: Style::Style?, ?text_value: String | Text::Span | Text::Line | nil) -> Widgets::BarChart::Bar
75
+
76
+ # Widgets::BarChart::BarGroup
77
+ def bar_group: (Widgets::bar_group_options) -> Widgets::BarChart::BarGroup
78
+ | (label: String, bars: Array[Widgets::BarChart::Bar]) -> Widgets::BarChart::BarGroup
79
+ def bar_chart_bar_group: (Widgets::bar_group_options) -> Widgets::BarChart::BarGroup
80
+ | (label: String, bars: Array[Widgets::BarChart::Bar]) -> Widgets::BarChart::BarGroup
81
+
82
+ # Widgets::Chart
83
+ def chart: (Widgets::chart_options) -> Widgets::Chart
84
+ | (datasets: Array[Widgets::Dataset], x_axis: Widgets::Axis, y_axis: Widgets::Axis, ?block: Widgets::Block?, ?style: Style::Style?, ?legend_position: Symbol?, ?hidden_legend_constraints: Array[Layout::Constraint]) -> Widgets::Chart
85
+
86
+ # Widgets::Dataset
87
+ def dataset: (Widgets::dataset_options) -> Widgets::Dataset
88
+ | (name: String | Symbol, data: Array[[_ToF, _ToF]], ?style: Style::Style?, ?marker: Symbol, ?graph_type: Symbol) -> Widgets::Dataset
89
+
90
+ # Widgets::Axis
91
+ def axis: (Widgets::axis_options) -> Widgets::Axis
92
+ | (?title: String, ?bounds: [_ToF, _ToF], ?labels: Array[String], ?style: Style::Style?, ?labels_alignment: Symbol?) -> Widgets::Axis
93
+
94
+ # Widgets::Scrollbar
95
+ def scrollbar: (Widgets::scrollbar_options) -> Widgets::Scrollbar
96
+ | (content_length: _ToI, position: _ToI, ?orientation: Symbol, ?thumb_symbol: String, ?thumb_style: Style::Style?, ?track_symbol: String?, ?track_style: Style::Style?, ?begin_symbol: String?, ?begin_style: Style::Style?, ?end_symbol: String?, ?end_style: Style::Style?, ?style: Style::Style?, ?block: Widgets::Block?) -> Widgets::Scrollbar
97
+
98
+ # Widgets::Calendar
99
+ def calendar: (Widgets::calendar_options) -> Widgets::Calendar
100
+ | (year: _ToI, month: _ToI, ?events: Hash[date_key, Style], ?default_style: Style::Style?, ?header_style: Style::Style?, ?block: Widgets::Block?, ?show_weekdays_header: bool, ?show_surrounding: Style::Style?, ?show_month_header: bool) -> Widgets::Calendar
101
+
102
+ # Widgets::Canvas
103
+ def canvas: (Widgets::canvas_options) -> Widgets::Canvas
104
+ | (?shapes: Array[Widgets::Shape::Line | Widgets::Shape::Rectangle | Widgets::Shape::Circle | Widgets::Shape::Map | Widgets::Shape::Label | Widgets::Shape::Point], ?x_bounds: Array[_ToF], ?y_bounds: Array[_ToF], ?marker: Symbol, ?block: Widgets::Block?, ?background_color: (String | Symbol)?) -> Widgets::Canvas
105
+
106
+ # Widgets::Clear
107
+ def clear: (Widgets::clear_options) -> Widgets::Clear
108
+ | (?block: Widgets::Block?) -> Widgets::Clear
109
+
110
+ # Widgets::Cursor
111
+ def cursor: (Widgets::cursor_options) -> Widgets::Cursor
112
+ | (x: _ToI, y: _ToI) -> Widgets::Cursor
113
+
114
+ # Widgets::Overlay
115
+ def overlay: (Widgets::overlay_options) -> Widgets::Overlay
116
+ | (?layers: Array[widget]) -> Widgets::Overlay
117
+
118
+ # Widgets::Center
119
+ def center: (Widgets::center_options) -> Widgets::Center
120
+ | (child: widget, ?width_percent: _ToF, ?height_percent: _ToF) -> Widgets::Center
121
+
122
+ # Widgets::RatatuiLogo
123
+ def ratatui_logo: (Widgets::ratatui_logo_options) -> Widgets::RatatuiLogo
124
+ | () -> Widgets::RatatuiLogo
125
+
126
+ # Widgets::RatatuiMascot
127
+ def ratatui_mascot: (Widgets::ratatui_mascot_options) -> Widgets::RatatuiMascot
128
+ | (?block: Widgets::Block?) -> Widgets::RatatuiMascot
129
+
130
+ # Widgets::Shape::Label
131
+ def shape_label: (Widgets::Shape::label_options) -> Widgets::Shape::Label
132
+ | (x: _ToF, y: _ToF, text: String | Text::Line, ?style: Style::Style?) -> Widgets::Shape::Label
133
+
134
+ # Widget dispatcher (TIMTOWTDI pattern)
135
+ def widget: (Symbol, ?untyped, **untyped) -> untyped
43
136
  end
44
137
  end
45
138
  end
@@ -0,0 +1,95 @@
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
+ # SPDX-License-Identifier: AGPL-3.0-or-later
9
+
10
+ module RatatuiRuby
11
+ module Widgets
12
+ # Options hash type for BarChart constructor arguments.
13
+ type bar_chart_options = {
14
+ ?data: Hash[String | Symbol | _ToS, _ToI] | Array[Array[String | Symbol | _ToS | _ToI]] | Array[BarChart::BarGroup],
15
+ ?bar_width: _ToI,
16
+ ?bar_gap: _ToI,
17
+ ?group_gap: _ToI,
18
+ ?max: _ToI?,
19
+ ?style: Style::Style?,
20
+ ?block: Widgets::Block?,
21
+ ?direction: (:vertical | :horizontal),
22
+ ?label_style: Style::Style?,
23
+ ?value_style: Style::Style?,
24
+ ?bar_set: Hash[Symbol, String]?
25
+ }
26
+
27
+ # Options hash type for BarChart::Bar constructor arguments.
28
+ type bar_options = {
29
+ ?value: _ToI,
30
+ ?label: String | Text::Span | Text::Line | nil,
31
+ ?style: Style::Style?,
32
+ ?value_style: Style::Style?,
33
+ ?text_value: String | Text::Span | Text::Line | nil
34
+ }
35
+
36
+ # Options hash type for BarChart::BarGroup constructor arguments.
37
+ type bar_group_options = {
38
+ ?label: String,
39
+ ?bars: Array[BarChart::Bar]
40
+ }
41
+
42
+ class BarChart < Data
43
+ BAR_KEYS: Array[Symbol]
44
+
45
+ attr_reader data: Array[BarChart::BarGroup]
46
+ attr_reader bar_width: Integer
47
+ attr_reader bar_gap: Integer
48
+ attr_reader group_gap: Integer
49
+ attr_reader max: Integer?
50
+ attr_reader style: Style::Style?
51
+ attr_reader block: Widgets::Block?
52
+ attr_reader direction: (:vertical | :horizontal)
53
+ attr_reader label_style: Style::Style?
54
+ attr_reader value_style: Style::Style?
55
+ attr_reader bar_set: Hash[Symbol, String]?
56
+
57
+ include CoerceableWidget
58
+
59
+ def self.coerce_args: (bar_chart_options first, ?bar_chart_options kwargs) -> BarChart
60
+ | (nil first, bar_chart_options kwargs) -> BarChart
61
+
62
+ def self.new: (data: Hash[String | Symbol | _ToS, _ToI] | Array[Array[String | Symbol | _ToS | _ToI]] | Array[BarChart::BarGroup], ?bar_width: _ToI, ?bar_gap: _ToI, ?group_gap: _ToI, ?max: _ToI?, ?style: Style::Style?, ?block: Widgets::Block?, ?direction: (:vertical | :horizontal), ?label_style: Style::Style?, ?value_style: Style::Style?, ?bar_set: Hash[Symbol, String]?) -> BarChart
63
+ def initialize: (data: Hash[String | Symbol | _ToS, _ToI] | Array[Array[String | Symbol | _ToS | _ToI]] | Array[BarChart::BarGroup], ?bar_width: _ToI, ?bar_gap: _ToI, ?group_gap: _ToI, ?max: _ToI?, ?style: Style::Style?, ?block: Widgets::Block?, ?direction: (:vertical | :horizontal), ?label_style: Style::Style?, ?value_style: Style::Style?, ?bar_set: Hash[Symbol, String]?) -> void
64
+
65
+ class Bar < Data
66
+ attr_reader value: Integer
67
+ attr_reader label: (String | Text::Span | Text::Line)?
68
+ attr_reader style: Style::Style?
69
+ attr_reader value_style: Style::Style?
70
+ attr_reader text_value: (String | Text::Span | Text::Line)?
71
+
72
+ include CoerceableWidget
73
+
74
+ def self.coerce_args: (bar_options first, ?bar_options kwargs) -> Bar
75
+ | (nil first, bar_options kwargs) -> Bar
76
+
77
+ def self.new: (value: _ToI, ?label: String | Text::Span | Text::Line | nil, ?style: Style::Style?, ?value_style: Style::Style?, ?text_value: String | Text::Span | Text::Line | nil) -> Bar
78
+ def initialize: (value: _ToI, ?label: String | Text::Span | Text::Line | nil, ?style: Style::Style?, ?value_style: Style::Style?, ?text_value: String | Text::Span | Text::Line | nil) -> void
79
+ end
80
+
81
+ class BarGroup < Data
82
+ attr_reader label: String
83
+ attr_reader bars: Array[BarChart::Bar]
84
+
85
+ include CoerceableWidget
86
+
87
+ def self.coerce_args: (bar_group_options first, ?bar_group_options kwargs) -> BarGroup
88
+ | (nil first, bar_group_options kwargs) -> BarGroup
89
+
90
+ def self.new: (label: String, bars: Array[BarChart::Bar]) -> BarGroup
91
+ def initialize: (label: String, bars: Array[BarChart::Bar]) -> void
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,51 @@
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
+ # SPDX-License-Identifier: AGPL-3.0-or-later
9
+
10
+ module RatatuiRuby
11
+ module Widgets
12
+ # Options hash type for Block constructor arguments.
13
+ type block_options = {
14
+ ?title: String?,
15
+ ?titles: Array[title_entry],
16
+ ?title_alignment: alignment?,
17
+ ?title_style: style_input?,
18
+ ?borders: Array[border_side],
19
+ ?border_style: style_input?,
20
+ ?border_type: border_type?,
21
+ ?border_set: border_set_hash?,
22
+ ?style: style_input?,
23
+ ?padding: (_ToI | Array[_ToI]),
24
+ ?children: Array[widget]
25
+ }
26
+
27
+ class Block < Data
28
+ attr_reader title: String?
29
+ attr_reader titles: Array[title_entry]
30
+ attr_reader title_alignment: alignment?
31
+ attr_reader title_style: style_input?
32
+ attr_reader borders: Array[border_side]
33
+ attr_reader border_style: style_input?
34
+ attr_reader border_type: border_type?
35
+ attr_reader border_set: border_set_hash?
36
+ attr_reader style: style_input?
37
+ attr_reader padding: (Integer | Array[Integer])
38
+ attr_reader children: Array[widget]
39
+
40
+ include CoerceableWidget
41
+
42
+ def self.coerce_args: (block_options first, ?block_options kwargs) -> Block
43
+ | (nil first, block_options kwargs) -> Block
44
+
45
+ def self.new: (?title: String?, ?titles: Array[title_entry], ?title_alignment: alignment?, ?title_style: style_input?, ?borders: Array[border_side], ?border_style: style_input?, ?border_type: border_type?, ?border_set: border_set_hash?, ?style: style_input?, ?padding: (_ToI | Array[_ToI]), ?children: Array[widget]) -> Block
46
+ def initialize: (?title: String?, ?titles: Array[title_entry], ?title_alignment: alignment?, ?title_style: style_input?, ?borders: Array[border_side], ?border_style: style_input?, ?border_type: border_type?, ?border_set: border_set_hash?, ?style: style_input?, ?padding: (_ToI | Array[_ToI]), ?children: Array[widget]) -> void
47
+
48
+ def inner: (Layout::Rect area) -> Layout::Rect
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,45 @@
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
+ # SPDX-License-Identifier: AGPL-3.0-or-later
9
+
10
+ module RatatuiRuby
11
+ module Widgets
12
+ # Options hash type for Calendar constructor arguments.
13
+ type calendar_options = {
14
+ ?year: _ToI,
15
+ ?month: _ToI,
16
+ ?events: Hash[date_key, Style],
17
+ ?default_style: Style::Style?,
18
+ ?header_style: Style::Style?,
19
+ ?block: Widgets::Block?,
20
+ ?show_weekdays_header: bool,
21
+ ?show_surrounding: Style::Style?,
22
+ ?show_month_header: bool
23
+ }
24
+
25
+ class Calendar < Data
26
+ attr_reader year: Integer
27
+ attr_reader month: Integer
28
+ attr_reader events: Hash[date_key, Style]
29
+ attr_reader default_style: Style::Style?
30
+ attr_reader header_style: Style::Style?
31
+ attr_reader block: Widgets::Block?
32
+ attr_reader show_weekdays_header: bool
33
+ attr_reader show_surrounding: Style::Style?
34
+ attr_reader show_month_header: bool
35
+
36
+ include CoerceableWidget
37
+
38
+ def self.coerce_args: (calendar_options first, ?calendar_options kwargs) -> Calendar
39
+ | (nil first, calendar_options kwargs) -> Calendar
40
+
41
+ def self.new: (year: _ToI, month: _ToI, ?events: Hash[date_key, Style], ?default_style: Style::Style?, ?header_style: Style::Style?, ?block: Widgets::Block?, ?show_weekdays_header: bool, ?show_surrounding: Style::Style?, ?show_month_header: bool) -> Calendar
42
+ def initialize: (year: _ToI, month: _ToI, ?events: Hash[date_key, Style], ?default_style: Style::Style?, ?header_style: Style::Style?, ?block: Widgets::Block?, ?show_weekdays_header: bool, ?show_surrounding: Style::Style?, ?show_month_header: bool) -> void
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,95 @@
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
+ # SPDX-License-Identifier: AGPL-3.0-or-later
9
+
10
+ module RatatuiRuby
11
+ module Widgets
12
+ # Options hash type for Canvas constructor arguments.
13
+ type canvas_options = {
14
+ ?shapes: Array[Shape::Line | Shape::Rectangle | Shape::Circle | Shape::Map | Shape::Label | Shape::Point],
15
+ ?x_bounds: Array[_ToF],
16
+ ?y_bounds: Array[_ToF],
17
+ ?marker: Symbol,
18
+ ?block: Widgets::Block?,
19
+ ?background_color: (String | Symbol)?
20
+ }
21
+
22
+ class Canvas < Data
23
+ attr_reader shapes: Array[Shape::Line | Shape::Rectangle | Shape::Circle | Shape::Map | Shape::Label | Shape::Point]
24
+ attr_reader x_bounds: Array[Float]
25
+ attr_reader y_bounds: Array[Float]
26
+ attr_reader marker: Symbol
27
+ attr_reader block: Widgets::Block?
28
+ attr_reader background_color: (String | Symbol)?
29
+
30
+ include CoerceableWidget
31
+
32
+ def self.coerce_args: (canvas_options first, ?canvas_options kwargs) -> Canvas
33
+ | (nil first, canvas_options kwargs) -> Canvas
34
+
35
+ def self.new: (?shapes: Array[Shape::Line | Shape::Rectangle | Shape::Circle | Shape::Map | Shape::Label | Shape::Point], ?x_bounds: Array[_ToF], ?y_bounds: Array[_ToF], ?marker: Symbol, ?block: Widgets::Block?, ?background_color: (String | Symbol)?) -> Canvas
36
+ def initialize: (?shapes: Array[Shape::Line | Shape::Rectangle | Shape::Circle | Shape::Map | Shape::Label | Shape::Point], ?x_bounds: Array[_ToF], ?y_bounds: Array[_ToF], ?marker: Symbol, ?block: Widgets::Block?, ?background_color: (String | Symbol)?) -> void
37
+
38
+ # Converts canvas coordinates to normalized grid coordinates.
39
+ # Returns [normalized_x, normalized_y] or nil if out of bounds.
40
+ def get_point: (_ToF x, _ToF y) -> Array[Float]?
41
+ alias point get_point
42
+ alias [] get_point
43
+ end
44
+
45
+ module Shape
46
+ class Point < Data
47
+ attr_reader x: Float
48
+ attr_reader y: Float
49
+
50
+ def self.new: (x: _ToF, y: _ToF) -> Point
51
+ def initialize: (x: _ToF, y: _ToF) -> void
52
+ end
53
+
54
+ class Line < Data
55
+ attr_reader x1: Float
56
+ attr_reader y1: Float
57
+ attr_reader x2: Float
58
+ attr_reader y2: Float
59
+ attr_reader color: (String | Symbol)
60
+
61
+ def self.new: (x1: _ToF, y1: _ToF, x2: _ToF, y2: _ToF, color: (String | Symbol)) -> Line
62
+ def initialize: (x1: _ToF, y1: _ToF, x2: _ToF, y2: _ToF, color: (String | Symbol)) -> void
63
+ end
64
+
65
+ class Rectangle < Data
66
+ attr_reader x: Float
67
+ attr_reader y: Float
68
+ attr_reader width: Float
69
+ attr_reader height: Float
70
+ attr_reader color: (String | Symbol)
71
+
72
+ def self.new: (x: _ToF, y: _ToF, width: _ToF, height: _ToF, color: (String | Symbol)) -> Rectangle
73
+ def initialize: (x: _ToF, y: _ToF, width: _ToF, height: _ToF, color: (String | Symbol)) -> void
74
+ end
75
+
76
+ class Circle < Data
77
+ attr_reader x: Float
78
+ attr_reader y: Float
79
+ attr_reader radius: Float
80
+ attr_reader color: (String | Symbol)
81
+
82
+ def self.new: (x: _ToF, y: _ToF, radius: _ToF, color: (String | Symbol)) -> Circle
83
+ def initialize: (x: _ToF, y: _ToF, radius: _ToF, color: (String | Symbol)) -> void
84
+ end
85
+
86
+ class Map < Data
87
+ attr_reader color: (String | Symbol)
88
+ attr_reader resolution: Symbol
89
+
90
+ def self.new: (?color: (String | Symbol), ?resolution: Symbol) -> Map
91
+ def initialize: (?color: (String | Symbol), ?resolution: Symbol) -> void
92
+ end
93
+ end
94
+ end
95
+ 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
+ # SPDX-License-Identifier: AGPL-3.0-or-later
9
+
10
+ module RatatuiRuby
11
+ module Widgets
12
+ # Options hash type for Chart constructor arguments.
13
+ type chart_options = {
14
+ ?datasets: Array[Dataset],
15
+ ?x_axis: Axis,
16
+ ?y_axis: Axis,
17
+ ?block: Widgets::Block?,
18
+ ?style: Style::Style?,
19
+ ?legend_position: Symbol?,
20
+ ?hidden_legend_constraints: Array[Layout::Constraint]
21
+ }
22
+
23
+ # Options hash type for Dataset constructor arguments.
24
+ type dataset_options = {
25
+ ?name: String | Symbol,
26
+ ?data: Array[[_ToF, _ToF]],
27
+ ?style: Style::Style?,
28
+ ?marker: Symbol,
29
+ ?graph_type: Symbol
30
+ }
31
+
32
+ # Options hash type for Axis constructor arguments.
33
+ type axis_options = {
34
+ ?title: String,
35
+ ?bounds: [_ToF, _ToF],
36
+ ?labels: Array[String],
37
+ ?style: Style::Style?,
38
+ ?labels_alignment: Symbol?
39
+ }
40
+
41
+ class Chart < Data
42
+ attr_reader datasets: Array[Dataset]
43
+ attr_reader x_axis: Axis
44
+ attr_reader y_axis: Axis
45
+ attr_reader block: Widgets::Block?
46
+ attr_reader style: Style::Style?
47
+ attr_reader legend_position: Symbol?
48
+ attr_reader hidden_legend_constraints: Array[Layout::Constraint]
49
+
50
+ include CoerceableWidget
51
+
52
+ def self.coerce_args: (chart_options first, ?chart_options kwargs) -> Chart
53
+ | (nil first, chart_options kwargs) -> Chart
54
+
55
+ def self.new: (datasets: Array[Dataset], x_axis: Axis, y_axis: Axis, ?block: Widgets::Block?, ?style: Style::Style?, ?legend_position: Symbol?, ?hidden_legend_constraints: Array[Layout::Constraint]) -> Chart
56
+ def initialize: (datasets: Array[Dataset], x_axis: Axis, y_axis: Axis, ?block: Widgets::Block?, ?style: Style::Style?, ?legend_position: Symbol?, ?hidden_legend_constraints: Array[Layout::Constraint]) -> void
57
+ end
58
+
59
+ class Dataset < Data
60
+ attr_reader name: String | Symbol
61
+ attr_reader data: Array[[Float, Float]]
62
+ attr_reader style: Style::Style?
63
+ attr_reader marker: Symbol
64
+ attr_reader graph_type: Symbol
65
+
66
+ include CoerceableWidget
67
+
68
+ def self.coerce_args: (dataset_options first, ?dataset_options kwargs) -> Dataset
69
+ | (nil first, dataset_options kwargs) -> Dataset
70
+
71
+ def self.new: (name: String | Symbol, data: Array[[_ToF, _ToF]], ?style: Style::Style?, ?marker: Symbol, ?graph_type: Symbol) -> Dataset
72
+ def initialize: (name: String | Symbol, data: Array[[_ToF, _ToF]], ?style: Style::Style?, ?marker: Symbol, ?graph_type: Symbol) -> void
73
+ end
74
+
75
+ class Axis < Data
76
+ attr_reader title: String
77
+ attr_reader bounds: [Float, Float]
78
+ attr_reader labels: Array[String]
79
+ attr_reader style: Style::Style?
80
+ attr_reader labels_alignment: Symbol?
81
+
82
+ include CoerceableWidget
83
+
84
+ def self.coerce_args: (axis_options first, ?axis_options kwargs) -> Axis
85
+ | (nil first, axis_options kwargs) -> Axis
86
+
87
+ def self.new: (?title: String, ?bounds: [_ToF, _ToF], ?labels: Array[String], ?style: Style::Style?, ?labels_alignment: Symbol?) -> Axis
88
+ def initialize: (?title: String, ?bounds: [_ToF, _ToF], ?labels: Array[String], ?style: Style::Style?, ?labels_alignment: Symbol?) -> void
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,26 @@
1
+ # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
2
+ # SPDX-License-Identifier: LGPL-3.0-or-later
3
+
4
+ module RatatuiRuby
5
+ module Widgets
6
+ # Mixin that provides DWIM hash coercion for widget classes.
7
+ #
8
+ # When users call `tui.table(hash)` instead of `tui.table(**hash)`,
9
+ # this mixin detects the bare hash and automatically splats it.
10
+ #
11
+ # This module is designed to be included in Data subclasses.
12
+ # The coerce_args method is typed per-widget rather than generically
13
+ # here because RBS cannot express "self.new" in module ClassMethods.
14
+ module CoerceableWidget
15
+ KNOWN_KEYS: Array[Symbol]
16
+
17
+ # Class methods extended onto widget classes.
18
+ # Each widget class provides its own typed coerce_args signature.
19
+ module ClassMethods
20
+ end
21
+
22
+ # Called when the module is included; extends ClassMethods.
23
+ def self.included: (Class base) -> void
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,44 @@
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
+ # SPDX-License-Identifier: AGPL-3.0-or-later
9
+
10
+ module RatatuiRuby
11
+ module Widgets
12
+ # Options hash type for Gauge constructor arguments.
13
+ type gauge_options = {
14
+ ?ratio: _ToF?,
15
+ ?percent: _ToF?,
16
+ ?label: String | Text::Span | nil,
17
+ ?style: Style::Style?,
18
+ ?gauge_style: Style::Style?,
19
+ ?block: Widgets::Block?,
20
+ ?use_unicode: bool
21
+ }
22
+
23
+ class Gauge < Data
24
+ attr_reader ratio: Float
25
+ attr_reader label: (String | Text::Span)?
26
+ attr_reader style: Style::Style?
27
+ attr_reader gauge_style: Style::Style?
28
+ attr_reader block: Widgets::Block?
29
+ attr_reader use_unicode: bool
30
+
31
+ include CoerceableWidget
32
+
33
+ def self.coerce_args: (gauge_options first, ?gauge_options kwargs) -> Gauge
34
+ | (nil first, gauge_options kwargs) -> Gauge
35
+
36
+ def self.new: (?ratio: _ToF?, ?percent: _ToF?, ?label: String | Text::Span | nil, ?style: Style::Style?, ?gauge_style: Style::Style?, ?block: Widgets::Block?, ?use_unicode: bool) -> Gauge
37
+ def initialize: (?ratio: _ToF?, ?percent: _ToF?, ?label: String | Text::Span | nil, ?style: Style::Style?, ?gauge_style: Style::Style?, ?block: Widgets::Block?, ?use_unicode: bool) -> void
38
+
39
+ def filled?: () -> bool
40
+ def complete?: () -> bool
41
+ def percent: () -> Integer
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,48 @@
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
+ # SPDX-License-Identifier: AGPL-3.0-or-later
9
+
10
+ module RatatuiRuby
11
+ module Widgets
12
+ # Options hash type for LineGauge constructor arguments.
13
+ type line_gauge_options = {
14
+ ?ratio: _ToF?,
15
+ ?percent: _ToF?,
16
+ ?label: String | Text::Span | nil,
17
+ ?style: Style::Style?,
18
+ ?filled_style: Style::Style?,
19
+ ?unfilled_style: Style::Style?,
20
+ ?block: Widgets::Block?,
21
+ ?filled_symbol: String,
22
+ ?unfilled_symbol: String
23
+ }
24
+
25
+ class LineGauge < Data
26
+ attr_reader ratio: Float
27
+ attr_reader label: (String | Text::Span)?
28
+ attr_reader style: Style::Style?
29
+ attr_reader filled_style: Style::Style?
30
+ attr_reader unfilled_style: Style::Style?
31
+ attr_reader block: Widgets::Block?
32
+ attr_reader filled_symbol: String
33
+ attr_reader unfilled_symbol: String
34
+
35
+ include CoerceableWidget
36
+
37
+ def self.coerce_args: (line_gauge_options first, ?line_gauge_options kwargs) -> LineGauge
38
+ | (nil first, line_gauge_options kwargs) -> LineGauge
39
+
40
+ def self.new: (?ratio: _ToF?, ?percent: _ToF?, ?label: String | Text::Span | nil, ?style: Style::Style?, ?filled_style: Style::Style?, ?unfilled_style: Style::Style?, ?block: Widgets::Block?, ?filled_symbol: String, ?unfilled_symbol: String) -> LineGauge
41
+ def initialize: (?ratio: _ToF?, ?percent: _ToF?, ?label: String | Text::Span | nil, ?style: Style::Style?, ?filled_style: Style::Style?, ?unfilled_style: Style::Style?, ?block: Widgets::Block?, ?filled_symbol: String, ?unfilled_symbol: String) -> void
42
+
43
+ def filled?: () -> bool
44
+ def complete?: () -> bool
45
+ def percent: () -> Integer
46
+ end
47
+ end
48
+ end