ratatui_ruby 1.3.0 → 1.3.3

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 (301) hide show
  1. checksums.yaml +4 -4
  2. data/ext/ratatui_ruby/Cargo.lock +2 -1
  3. data/ext/ratatui_ruby/Cargo.toml +2 -1
  4. data/ext/ratatui_ruby/src/color.rs +1 -1
  5. data/ext/ratatui_ruby/src/errors.rs +1 -1
  6. data/ext/ratatui_ruby/src/events.rs +158 -19
  7. data/ext/ratatui_ruby/src/frame.rs +1 -1
  8. data/ext/ratatui_ruby/src/lib.rs +1 -1
  9. data/ext/ratatui_ruby/src/lib_header.rs +1 -1
  10. data/ext/ratatui_ruby/src/rendering.rs +1 -1
  11. data/ext/ratatui_ruby/src/string_width.rs +1 -1
  12. data/ext/ratatui_ruby/src/style.rs +1 -1
  13. data/ext/ratatui_ruby/src/terminal/capabilities.rs +1 -1
  14. data/ext/ratatui_ruby/src/terminal/init.rs +1 -1
  15. data/ext/ratatui_ruby/src/terminal/mod.rs +1 -1
  16. data/ext/ratatui_ruby/src/terminal/mutations.rs +1 -1
  17. data/ext/ratatui_ruby/src/terminal/queries.rs +1 -1
  18. data/ext/ratatui_ruby/src/terminal/query.rs +1 -1
  19. data/ext/ratatui_ruby/src/terminal/storage.rs +1 -1
  20. data/ext/ratatui_ruby/src/terminal/wrapper.rs +1 -1
  21. data/ext/ratatui_ruby/src/text.rs +1 -1
  22. data/ext/ratatui_ruby/src/widgets/barchart.rs +1 -1
  23. data/ext/ratatui_ruby/src/widgets/block.rs +1 -1
  24. data/ext/ratatui_ruby/src/widgets/calendar.rs +1 -1
  25. data/ext/ratatui_ruby/src/widgets/canvas.rs +1 -1
  26. data/ext/ratatui_ruby/src/widgets/center.rs +1 -1
  27. data/ext/ratatui_ruby/src/widgets/chart.rs +1 -1
  28. data/ext/ratatui_ruby/src/widgets/clear.rs +1 -1
  29. data/ext/ratatui_ruby/src/widgets/cursor.rs +1 -1
  30. data/ext/ratatui_ruby/src/widgets/gauge.rs +1 -1
  31. data/ext/ratatui_ruby/src/widgets/layout.rs +1 -1
  32. data/ext/ratatui_ruby/src/widgets/line_gauge.rs +1 -1
  33. data/ext/ratatui_ruby/src/widgets/list.rs +1 -1
  34. data/ext/ratatui_ruby/src/widgets/list_state.rs +1 -1
  35. data/ext/ratatui_ruby/src/widgets/mod.rs +1 -1
  36. data/ext/ratatui_ruby/src/widgets/overlay.rs +1 -1
  37. data/ext/ratatui_ruby/src/widgets/paragraph.rs +1 -1
  38. data/ext/ratatui_ruby/src/widgets/ratatui_logo.rs +1 -1
  39. data/ext/ratatui_ruby/src/widgets/ratatui_mascot.rs +1 -1
  40. data/ext/ratatui_ruby/src/widgets/scrollbar.rs +1 -1
  41. data/ext/ratatui_ruby/src/widgets/scrollbar_state.rs +1 -1
  42. data/ext/ratatui_ruby/src/widgets/sparkline.rs +1 -1
  43. data/ext/ratatui_ruby/src/widgets/table.rs +1 -1
  44. data/ext/ratatui_ruby/src/widgets/table_state.rs +1 -1
  45. data/ext/ratatui_ruby/src/widgets/tabs.rs +1 -1
  46. data/lib/ratatui_ruby/version.rb +1 -1
  47. metadata +1 -255
  48. data/.builds/ruby-3.2.yml +0 -54
  49. data/.builds/ruby-3.3.yml +0 -54
  50. data/.builds/ruby-3.4.yml +0 -54
  51. data/.builds/ruby-4.0.0.yml +0 -54
  52. data/.pre-commit-config.yaml +0 -16
  53. data/.rubocop.yml +0 -10
  54. data/AGENTS.md +0 -147
  55. data/CHANGELOG.md +0 -771
  56. data/README.md +0 -187
  57. data/README.rdoc +0 -302
  58. data/Rakefile +0 -11
  59. data/Steepfile +0 -50
  60. data/doc/concepts/application_architecture.md +0 -321
  61. data/doc/concepts/application_testing.md +0 -193
  62. data/doc/concepts/async.md +0 -190
  63. data/doc/concepts/custom_widgets.md +0 -247
  64. data/doc/concepts/debugging.md +0 -401
  65. data/doc/concepts/event_handling.md +0 -162
  66. data/doc/concepts/interactive_design.md +0 -146
  67. data/doc/contributors/auditing/parity.md +0 -239
  68. data/doc/contributors/design/ruby_frontend.md +0 -448
  69. data/doc/contributors/design/rust_backend.md +0 -434
  70. data/doc/contributors/design.md +0 -11
  71. data/doc/contributors/developing_examples.md +0 -400
  72. data/doc/contributors/documentation_style.md +0 -121
  73. data/doc/contributors/index.md +0 -21
  74. data/doc/contributors/releasing.md +0 -215
  75. data/doc/contributors/todo/align/api_completeness_audit-finished.md +0 -381
  76. data/doc/contributors/todo/align/api_completeness_audit-unfinished.md +0 -200
  77. data/doc/contributors/todo/align/term.md +0 -351
  78. data/doc/contributors/todo/align/terminal.md +0 -647
  79. data/doc/contributors/todo/future_work.md +0 -169
  80. data/doc/contributors/upstream_requests/paragraph_span_rects.md +0 -259
  81. data/doc/contributors/upstream_requests/tab_rects.md +0 -173
  82. data/doc/contributors/upstream_requests/title_rects.md +0 -132
  83. data/doc/custom.css +0 -22
  84. data/doc/getting_started/quickstart.md +0 -291
  85. data/doc/getting_started/why.md +0 -93
  86. data/doc/images/app_all_events.png +0 -0
  87. data/doc/images/app_cli_rich_moments.gif +0 -0
  88. data/doc/images/app_color_picker.png +0 -0
  89. data/doc/images/app_debugging_showcase.gif +0 -0
  90. data/doc/images/app_debugging_showcase.png +0 -0
  91. data/doc/images/app_external_editor.gif +0 -0
  92. data/doc/images/app_login_form.png +0 -0
  93. data/doc/images/app_stateful_interaction.png +0 -0
  94. data/doc/images/verify_quickstart_dsl.png +0 -0
  95. data/doc/images/verify_quickstart_layout.png +0 -0
  96. data/doc/images/verify_quickstart_lifecycle.png +0 -0
  97. data/doc/images/verify_readme_usage.png +0 -0
  98. data/doc/images/widget_barchart.png +0 -0
  99. data/doc/images/widget_block.png +0 -0
  100. data/doc/images/widget_box.png +0 -0
  101. data/doc/images/widget_calendar.png +0 -0
  102. data/doc/images/widget_canvas.png +0 -0
  103. data/doc/images/widget_cell.png +0 -0
  104. data/doc/images/widget_center.png +0 -0
  105. data/doc/images/widget_chart.png +0 -0
  106. data/doc/images/widget_gauge.png +0 -0
  107. data/doc/images/widget_layout_split.png +0 -0
  108. data/doc/images/widget_line_gauge.png +0 -0
  109. data/doc/images/widget_list.png +0 -0
  110. data/doc/images/widget_map.png +0 -0
  111. data/doc/images/widget_overlay.png +0 -0
  112. data/doc/images/widget_popup.png +0 -0
  113. data/doc/images/widget_ratatui_logo.png +0 -0
  114. data/doc/images/widget_ratatui_mascot.png +0 -0
  115. data/doc/images/widget_rect.png +0 -0
  116. data/doc/images/widget_render.png +0 -0
  117. data/doc/images/widget_rich_text.png +0 -0
  118. data/doc/images/widget_scroll_text.png +0 -0
  119. data/doc/images/widget_scrollbar.png +0 -0
  120. data/doc/images/widget_sparkline.png +0 -0
  121. data/doc/images/widget_style_colors.png +0 -0
  122. data/doc/images/widget_table.png +0 -0
  123. data/doc/images/widget_tabs.png +0 -0
  124. data/doc/images/widget_text_width.png +0 -0
  125. data/doc/index.md +0 -34
  126. data/doc/troubleshooting/async.md +0 -4
  127. data/doc/troubleshooting/terminal_limitations.md +0 -131
  128. data/doc/troubleshooting/tui_output.md +0 -197
  129. data/examples/app_all_events/README.md +0 -114
  130. data/examples/app_all_events/app.rb +0 -98
  131. data/examples/app_all_events/model/app_model.rb +0 -159
  132. data/examples/app_all_events/model/event_color_cycle.rb +0 -43
  133. data/examples/app_all_events/model/event_entry.rb +0 -94
  134. data/examples/app_all_events/model/msg.rb +0 -39
  135. data/examples/app_all_events/model/timestamp.rb +0 -56
  136. data/examples/app_all_events/update.rb +0 -75
  137. data/examples/app_all_events/view/app_view.rb +0 -80
  138. data/examples/app_all_events/view/controls_view.rb +0 -54
  139. data/examples/app_all_events/view/counts_view.rb +0 -61
  140. data/examples/app_all_events/view/live_view.rb +0 -72
  141. data/examples/app_all_events/view/log_view.rb +0 -57
  142. data/examples/app_all_events/view.rb +0 -9
  143. data/examples/app_cli_rich_moments/README.md +0 -81
  144. data/examples/app_cli_rich_moments/app.rb +0 -189
  145. data/examples/app_color_picker/README.md +0 -156
  146. data/examples/app_color_picker/app.rb +0 -76
  147. data/examples/app_color_picker/clipboard.rb +0 -86
  148. data/examples/app_color_picker/color.rb +0 -193
  149. data/examples/app_color_picker/controls.rb +0 -92
  150. data/examples/app_color_picker/copy_dialog.rb +0 -168
  151. data/examples/app_color_picker/export_pane.rb +0 -128
  152. data/examples/app_color_picker/harmony.rb +0 -58
  153. data/examples/app_color_picker/input.rb +0 -176
  154. data/examples/app_color_picker/main_container.rb +0 -180
  155. data/examples/app_color_picker/palette.rb +0 -111
  156. data/examples/app_debugging_showcase/README.md +0 -119
  157. data/examples/app_debugging_showcase/app.rb +0 -318
  158. data/examples/app_external_editor/README.md +0 -62
  159. data/examples/app_external_editor/app.rb +0 -344
  160. data/examples/app_login_form/README.md +0 -58
  161. data/examples/app_login_form/app.rb +0 -109
  162. data/examples/app_stateful_interaction/README.md +0 -35
  163. data/examples/app_stateful_interaction/app.rb +0 -328
  164. data/examples/timeout_demo.rb +0 -45
  165. data/examples/verify_quickstart_dsl/README.md +0 -55
  166. data/examples/verify_quickstart_dsl/app.rb +0 -49
  167. data/examples/verify_quickstart_layout/README.md +0 -77
  168. data/examples/verify_quickstart_layout/app.rb +0 -73
  169. data/examples/verify_quickstart_lifecycle/README.md +0 -68
  170. data/examples/verify_quickstart_lifecycle/app.rb +0 -62
  171. data/examples/verify_readme_usage/README.md +0 -49
  172. data/examples/verify_readme_usage/app.rb +0 -42
  173. data/examples/verify_website_managed/README.md +0 -48
  174. data/examples/verify_website_managed/app.rb +0 -36
  175. data/examples/verify_website_menu/README.md +0 -60
  176. data/examples/verify_website_menu/app.rb +0 -84
  177. data/examples/verify_website_spinner/README.md +0 -44
  178. data/examples/verify_website_spinner/app.rb +0 -34
  179. data/examples/widget_barchart/README.md +0 -58
  180. data/examples/widget_barchart/app.rb +0 -240
  181. data/examples/widget_block/README.md +0 -44
  182. data/examples/widget_block/app.rb +0 -258
  183. data/examples/widget_box/README.md +0 -54
  184. data/examples/widget_box/app.rb +0 -255
  185. data/examples/widget_calendar/README.md +0 -48
  186. data/examples/widget_calendar/app.rb +0 -115
  187. data/examples/widget_canvas/README.md +0 -31
  188. data/examples/widget_canvas/app.rb +0 -130
  189. data/examples/widget_cell/README.md +0 -45
  190. data/examples/widget_cell/app.rb +0 -112
  191. data/examples/widget_center/README.md +0 -33
  192. data/examples/widget_center/app.rb +0 -118
  193. data/examples/widget_chart/README.md +0 -50
  194. data/examples/widget_chart/app.rb +0 -220
  195. data/examples/widget_gauge/README.md +0 -50
  196. data/examples/widget_gauge/app.rb +0 -229
  197. data/examples/widget_layout_split/README.md +0 -53
  198. data/examples/widget_layout_split/app.rb +0 -260
  199. data/examples/widget_line_gauge/README.md +0 -50
  200. data/examples/widget_line_gauge/app.rb +0 -219
  201. data/examples/widget_list/README.md +0 -58
  202. data/examples/widget_list/app.rb +0 -382
  203. data/examples/widget_map/README.md +0 -48
  204. data/examples/widget_map/app.rb +0 -95
  205. data/examples/widget_overlay/README.md +0 -45
  206. data/examples/widget_overlay/app.rb +0 -250
  207. data/examples/widget_popup/README.md +0 -45
  208. data/examples/widget_popup/app.rb +0 -106
  209. data/examples/widget_ratatui_logo/README.md +0 -43
  210. data/examples/widget_ratatui_logo/app.rb +0 -104
  211. data/examples/widget_ratatui_mascot/README.md +0 -43
  212. data/examples/widget_ratatui_mascot/app.rb +0 -95
  213. data/examples/widget_rect/README.md +0 -53
  214. data/examples/widget_rect/app.rb +0 -222
  215. data/examples/widget_render/README.md +0 -46
  216. data/examples/widget_render/app.rb +0 -186
  217. data/examples/widget_render/app.rbs +0 -41
  218. data/examples/widget_rich_text/README.md +0 -44
  219. data/examples/widget_rich_text/app.rb +0 -193
  220. data/examples/widget_scroll_text/README.md +0 -46
  221. data/examples/widget_scroll_text/app.rb +0 -109
  222. data/examples/widget_scrollbar/README.md +0 -46
  223. data/examples/widget_scrollbar/app.rb +0 -155
  224. data/examples/widget_sparkline/README.md +0 -51
  225. data/examples/widget_sparkline/app.rb +0 -277
  226. data/examples/widget_style_colors/README.md +0 -43
  227. data/examples/widget_style_colors/app.rb +0 -83
  228. data/examples/widget_table/README.md +0 -57
  229. data/examples/widget_table/app.rb +0 -285
  230. data/examples/widget_tabs/README.md +0 -50
  231. data/examples/widget_tabs/app.rb +0 -183
  232. data/examples/widget_text_width/README.md +0 -44
  233. data/examples/widget_text_width/app.rb +0 -117
  234. data/migrate_to_buffer.rb +0 -145
  235. data/mise.toml +0 -8
  236. data/tasks/autodoc/examples.rb +0 -87
  237. data/tasks/autodoc/member.rb +0 -58
  238. data/tasks/autodoc/name.rb +0 -21
  239. data/tasks/autodoc.rake +0 -21
  240. data/tasks/bump/bump_workflow.rb +0 -49
  241. data/tasks/bump/cargo_lockfile.rb +0 -21
  242. data/tasks/bump/changelog.rb +0 -104
  243. data/tasks/bump/header.rb +0 -32
  244. data/tasks/bump/history.rb +0 -32
  245. data/tasks/bump/links.rb +0 -69
  246. data/tasks/bump/manifest.rb +0 -33
  247. data/tasks/bump/patch_release.rb +0 -19
  248. data/tasks/bump/release_branch.rb +0 -17
  249. data/tasks/bump/release_from_trunk.rb +0 -49
  250. data/tasks/bump/repository.rb +0 -54
  251. data/tasks/bump/ruby_gem.rb +0 -29
  252. data/tasks/bump/sem_ver.rb +0 -44
  253. data/tasks/bump/unreleased_section.rb +0 -73
  254. data/tasks/bump.rake +0 -61
  255. data/tasks/doc/documentation.rb +0 -59
  256. data/tasks/doc/link/file_url.rb +0 -30
  257. data/tasks/doc/link/relative_path.rb +0 -61
  258. data/tasks/doc/link/web_url.rb +0 -55
  259. data/tasks/doc/link.rb +0 -52
  260. data/tasks/doc/link_audit.rb +0 -116
  261. data/tasks/doc/problem.rb +0 -40
  262. data/tasks/doc/source_file.rb +0 -93
  263. data/tasks/doc.rake +0 -905
  264. data/tasks/example_viewer.html.erb +0 -172
  265. data/tasks/extension.rake +0 -14
  266. data/tasks/license/headers_md.rb +0 -223
  267. data/tasks/license/headers_rb.rb +0 -210
  268. data/tasks/license/license_utils.rb +0 -130
  269. data/tasks/license/snippets_md.rb +0 -315
  270. data/tasks/license/snippets_rdoc.rb +0 -150
  271. data/tasks/license.rake +0 -91
  272. data/tasks/lint.rake +0 -170
  273. data/tasks/rbs_predicates/predicate_catalog.rb +0 -52
  274. data/tasks/rbs_predicates/predicate_tests.rb +0 -124
  275. data/tasks/rbs_predicates/rbs_signature.rb +0 -63
  276. data/tasks/rbs_predicates.rake +0 -31
  277. data/tasks/rdoc_config.rb +0 -29
  278. data/tasks/resources/build.yml.erb +0 -60
  279. data/tasks/resources/index.html.erb +0 -141
  280. data/tasks/resources/rubies.yml +0 -7
  281. data/tasks/sourcehut.rake +0 -122
  282. data/tasks/steep.rake +0 -11
  283. data/tasks/terminal_preview/app_screenshot.rb +0 -45
  284. data/tasks/terminal_preview/crash_report.rb +0 -54
  285. data/tasks/terminal_preview/example_app.rb +0 -27
  286. data/tasks/terminal_preview/launcher_script.rb +0 -48
  287. data/tasks/terminal_preview/preview_collection.rb +0 -60
  288. data/tasks/terminal_preview/preview_timing.rb +0 -24
  289. data/tasks/terminal_preview/safety_confirmation.rb +0 -58
  290. data/tasks/terminal_preview/saved_screenshot.rb +0 -56
  291. data/tasks/terminal_preview/system_appearance.rb +0 -13
  292. data/tasks/terminal_preview/terminal_window.rb +0 -138
  293. data/tasks/terminal_preview/window_id.rb +0 -16
  294. data/tasks/terminal_preview.rake +0 -30
  295. data/tasks/test.rake +0 -36
  296. data/tasks/website/index_page.rb +0 -30
  297. data/tasks/website/version.rb +0 -122
  298. data/tasks/website/version_menu.rb +0 -68
  299. data/tasks/website/versioned_documentation.rb +0 -83
  300. data/tasks/website/website.rb +0 -53
  301. data/tasks/website.rake +0 -28
@@ -1,155 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- #--
4
- # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: MIT-0
6
- #++
7
-
8
- $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
9
- require "ratatui_ruby"
10
-
11
- # Demonstrates viewport navigation with interactive theme and orientation cycling.
12
- #
13
- # Content overflows. Users get lost in long lists without landmarks. They need to know where they are and how much is left.
14
- #
15
- # This demo showcases the <tt>Scrollbar</tt> widget. It provides an interactive playground where you can toggle orientations and cycle through different themes (Standard, Rounded, ASCII, Minimal) in real-time.
16
- #
17
- # Use it to understand how to provide spatial awareness and navigation cues for overflowing content.
18
- #
19
- # === Example
20
- #
21
- # Run the demo from the terminal:
22
- #
23
- # ruby examples/widget_scrollbar/app.rb
24
- #
25
- # rdoc-image:/doc/images/widget_scrollbar.png
26
- class WidgetScrollbar
27
- def initialize
28
- @scroll_position = 0
29
- @content_length = 50
30
- @lines = (1..@content_length).map { |i| "Line #{i}" }
31
- @orientation_index = 0
32
- @orientations = [
33
- :vertical,
34
- :vertical_right,
35
- :vertical_left,
36
- :horizontal,
37
- :horizontal_bottom,
38
- :horizontal_top,
39
- ]
40
- @theme_index = 0
41
- @themes = [
42
- {
43
- name: "Standard",
44
- track_symbol: nil,
45
- thumb_symbol: "█",
46
- track_style: nil,
47
- thumb_style: nil,
48
- begin_symbol: nil,
49
- end_symbol: nil,
50
- },
51
- {
52
- name: "Rounded",
53
- track_symbol: "│",
54
- thumb_symbol: "┃",
55
- track_style: { fg: "dark_gray" },
56
- thumb_style: { fg: "cyan" },
57
- begin_symbol: "▲",
58
- end_symbol: "▼",
59
- },
60
- {
61
- name: "ASCII",
62
- track_symbol: "|",
63
- thumb_symbol: "#",
64
- track_style: { fg: "white" },
65
- thumb_style: { fg: "red" },
66
- begin_symbol: "^",
67
- end_symbol: "v",
68
- },
69
- {
70
- name: "Minimal",
71
- track_symbol: " ",
72
- thumb_symbol: "▐",
73
- track_style: nil,
74
- thumb_style: { fg: "yellow" },
75
- begin_symbol: nil,
76
- end_symbol: nil,
77
- },
78
- ]
79
- end
80
-
81
- def run
82
- RatatuiRuby.run do |tui|
83
- @tui = tui
84
- loop do
85
- draw
86
- event = @tui.poll_event
87
- break if event == "q" || event == :ctrl_c
88
-
89
- handle_event(event)
90
- end
91
- end
92
- end
93
-
94
- private def handle_event(event)
95
- if event.mouse?
96
- case event.kind
97
- when "scroll_up"
98
- @scroll_position = [@scroll_position - 1, 0].max
99
- when "scroll_down"
100
- @scroll_position = [@scroll_position + 1, @content_length].min
101
- end
102
- end
103
-
104
- if event.key? && event.to_s == "s"
105
- @theme_index = (@theme_index + 1) % @themes.length
106
- end
107
-
108
- if event.key? && event.to_s == "o"
109
- @orientation_index = (@orientation_index + 1) % @orientations.length
110
- end
111
- end
112
-
113
- private def draw
114
- @tui.draw do |frame|
115
- # Calculate visible lines based on scroll position
116
- # In a real app, you'd want to know the height of the available area.
117
- # For this demo, we'll just show all lines but offset the text.
118
- visible_lines = @lines[@scroll_position..-1] || []
119
-
120
- # Paragraph with content
121
- theme = @themes[@theme_index]
122
- orientation = @orientations[@orientation_index]
123
-
124
- p = @tui.paragraph(
125
- text: visible_lines.join("\n"),
126
- block: @tui.block(
127
- titles: [
128
- { content: "Scroll with Mouse Wheel | Theme: #{theme[:name]} | Orientation: #{orientation}" },
129
- { content: "Press 's' to cycle theme, 'o' to cycle orientation", position: :bottom, alignment: :center },
130
- ],
131
- borders: [:all]
132
- )
133
- )
134
-
135
- # Scrollbar
136
- s = @tui.scrollbar(
137
- content_length: @content_length,
138
- position: @scroll_position,
139
- orientation:,
140
- track_symbol: theme[:track_symbol],
141
- thumb_symbol: theme[:thumb_symbol],
142
- track_style: theme[:track_style],
143
- thumb_style: theme[:thumb_style],
144
- begin_symbol: theme[:begin_symbol],
145
- end_symbol: theme[:end_symbol]
146
- )
147
-
148
- # Render paragraph first, then scrollbar on top
149
- frame.render_widget(p, frame.area)
150
- frame.render_widget(s, frame.area)
151
- end
152
- end
153
- end
154
-
155
- WidgetScrollbar.new.run if __FILE__ == $PROGRAM_NAME
@@ -1,51 +0,0 @@
1
- <!--
2
- SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
- SPDX-License-Identifier: CC-BY-SA-4.0
4
- -->
5
-
6
- # Sparkline Widget Example
7
-
8
- [![widget_sparkline](../../doc/images/widget_sparkline.png)](app.rb)
9
-
10
- Demonstrates high-density data visualization in a condensed footprint.
11
-
12
- Users need context. A single number ("90% CPU") tells you status, but not the trend. Full charts take up too much space. Sparklines condense history into a single line, perfect for headers and dashboards.
13
-
14
- ## Features Demonstrated
15
-
16
- - **High Density**: Showing dozens of data points in a small area.
17
- - **Direction**: Rendering Left-to-Right (standard) or Right-to-Left (like a scrolling ticker).
18
- - **Gaps**: Handling `nil` values with "absent symbols" to indicate missing data.
19
- - **Styling**: Using colors and custom characters to indicate severity or type.
20
-
21
- ## Hotkeys
22
-
23
- - **Up/Down (↑/↓)**: Cycle Data Set (`data`)
24
- - **d**: Cycle Direction (`direction`)
25
- - **c**: Cycle Color (`style`)
26
- - **m**: Cycle Absent Value Marker Symbol (`absent_value_symbol`)
27
- - **s**: Cycle Absent Value Marker Style (`absent_value_style`)
28
- - **b**: Cycle Bar Character Set (`bar_set`)
29
- - **q**: Quit
30
-
31
- ## Usage
32
-
33
- <!-- SPDX-SnippetBegin -->
34
- <!--
35
- SPDX-FileCopyrightText: 2026 Kerrick Long
36
- SPDX-License-Identifier: MIT-0
37
- -->
38
- ```bash
39
- ruby examples/widget_sparkline/app.rb
40
- ```
41
- <!-- SPDX-SnippetEnd -->
42
-
43
- ## Learning Outcomes
44
-
45
- Use this example if you need to...
46
-
47
- - Add a "CPU Load" graph to your header.
48
- - Visualize stock price trends in a list row.
49
- - Monitor memory usage over the last 60 seconds.
50
-
51
- [Read the source code →](app.rb)
@@ -1,277 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- #--
4
- # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: MIT-0
6
- #++
7
-
8
- $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
9
- require "ratatui_ruby"
10
-
11
- # Demonstrates high-density data visualization with interactive attribute cycling.
12
- #
13
- # Users need context. A single value ("90% CPU") tells you current status, but not the trend. Full charts take up too much room.
14
- #
15
- # This demo showcases the <tt>Sparkline</tt> widget. It provides an interactive playground where you can cycle through data sets, directions, colors, and custom bar sets.
16
- #
17
- # Use it to understand how to condense history into a single line for dashboards or headers.
18
- #
19
- # === Example
20
- #
21
- # Run the demo from the terminal:
22
- #
23
- # ruby examples/widget_sparkline/app.rb
24
- #
25
- # rdoc-image:/doc/images/widget_sparkline.png
26
- class WidgetSparkline
27
- def run
28
- RatatuiRuby.run do |tui|
29
- @tui = tui
30
- setup
31
- loop do
32
- render
33
- break if handle_input == :quit
34
- end
35
- end
36
- end
37
-
38
- private def setup
39
- # Data sets with different characteristics
40
- @data_sets = [
41
- {
42
- name: "Steady Growth",
43
- data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
44
- },
45
- {
46
- name: "With Gaps",
47
- data: [5, nil, 8, nil, 6, nil, 9, nil, 7, nil, 10, nil],
48
- },
49
- {
50
- name: "Random",
51
- data: [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8],
52
- },
53
- {
54
- name: "Sawtooth",
55
- data: [1, 2, 3, 4, 5, 4, 3, 2, 1, 2, 3, 4],
56
- },
57
- {
58
- name: "Peaks",
59
- data: [1, 5, 1, 8, 1, 6, 1, 9, 1, 7, 1, 10],
60
- },
61
- ]
62
- @data_index = 2
63
- srand(12345) # Ensure reproducible "Random" data for snapshots
64
-
65
- @directions = [
66
- { name: "Left to Right", direction: :left_to_right },
67
- { name: "Right to Left", direction: :right_to_left },
68
- ]
69
- @direction_index = 0
70
-
71
- @styles = [
72
- { name: "Green", style: @tui.style(fg: :green) },
73
- { name: "Yellow", style: @tui.style(fg: :yellow) },
74
- { name: "Red", style: @tui.style(fg: :red) },
75
- { name: "Cyan", style: @tui.style(fg: :cyan) },
76
- { name: "Magenta", style: @tui.style(fg: :magenta) },
77
- ]
78
- @style_index = 3
79
-
80
- @absent_symbols = [
81
- { name: "None", symbol: nil },
82
- { name: "Dot (·)", symbol: "·" },
83
- { name: "Square (▫)", symbol: "▫" },
84
- { name: "Dash (-)", symbol: "-" },
85
- { name: "Underscore (_)", symbol: "_" },
86
- ]
87
- @absent_symbol_index = 1
88
-
89
- @absent_styles = [
90
- { name: "Default", style: nil },
91
- { name: "Dark Gray", style: @tui.style(fg: :dark_gray) },
92
- { name: "Dim Red", style: @tui.style(fg: :red, modifiers: [:dim]) },
93
- { name: "Dim Yellow", style: @tui.style(fg: :yellow, modifiers: [:dim]) },
94
- ]
95
- @absent_style_index = 2
96
-
97
- @bar_sets = [
98
- { name: "Default (Block)", set: nil },
99
- {
100
- name: "Numbers (0-8)",
101
- set: {
102
- 0 => "0", 1 => "1", 2 => "2", 3 => "3", 4 => "4", 5 => "5", 6 => "6", 7 => "7", 8 => "8"
103
- },
104
- },
105
- { name: "ASCII (Heights)", set: [" ", "_", ".", "-", "=", "+", "*", "#", "@"] },
106
- ]
107
- @bar_set_index = 0
108
-
109
- @hotkey_style = @tui.style(modifiers: [:bold, :underlined])
110
- end
111
-
112
- private def render
113
- @tui.draw do |frame|
114
- data_set = @data_sets[@data_index]
115
- direction = @directions[@direction_index][:direction]
116
- style = @styles[@style_index][:style]
117
- absent_symbol = @absent_symbols[@absent_symbol_index][:symbol]
118
- absent_value_style = @absent_styles[@absent_style_index][:style]
119
- bar_set = @bar_sets[@bar_set_index][:set]
120
-
121
- # Use static data for clarity when cycling options
122
- current_data = data_set[:data]
123
-
124
- layout = @tui.layout_split(
125
- frame.area,
126
- direction: :vertical,
127
- constraints: [
128
- @tui.constraint_fill(1),
129
- @tui.constraint_length(6),
130
- ]
131
- )
132
-
133
- # Main content area with multiple sparkline examples
134
- main_content_area = layout[0]
135
- main_layout = @tui.layout_split(
136
- main_content_area,
137
- direction: :vertical,
138
- constraints: [
139
- @tui.constraint_length(1),
140
- @tui.constraint_length(3),
141
- @tui.constraint_length(3),
142
- @tui.constraint_length(3),
143
- @tui.constraint_length(3),
144
- @tui.constraint_fill(1),
145
- ]
146
- )
147
-
148
- frame.render_widget(
149
- @tui.paragraph(text: "Sparkline Widget - Cycle attributes with hotkeys"),
150
- main_layout[0]
151
- )
152
-
153
- # Sparkline 1: Main interactive sparkline
154
- frame.render_widget(
155
- @tui.sparkline(
156
- data: current_data,
157
- direction:,
158
- style:,
159
- absent_value_symbol: absent_symbol,
160
- absent_value_style:,
161
- bar_set:,
162
- block: @tui.block(title: "Interactive Sparkline")
163
- ),
164
- main_layout[1]
165
- )
166
-
167
- # Sparkline 2: Same data, opposite direction
168
- frame.render_widget(
169
- @tui.sparkline(
170
- data: current_data.reverse,
171
- direction:,
172
- style:,
173
- absent_value_symbol: absent_symbol,
174
- absent_value_style:,
175
- bar_set:,
176
- block: @tui.block(title: "Reversed Data")
177
- ),
178
- main_layout[2]
179
- )
180
-
181
- # Sparkline 3: Without absent value symbol (for comparison)
182
- frame.render_widget(
183
- @tui.sparkline(
184
- data: current_data,
185
- direction:,
186
- style:,
187
- bar_set:,
188
- block: @tui.block(title: "Without Absent Marker")
189
- ),
190
- main_layout[3]
191
- )
192
-
193
- # Sparkline 4: Gap pattern responsive to absent marker controls
194
- frame.render_widget(
195
- @tui.sparkline(
196
- data: [5, nil, 8, nil, 6, nil, 9, nil, 7, nil, 10, nil],
197
- direction:,
198
- style: @tui.style(fg: :blue),
199
- absent_value_symbol: absent_symbol,
200
- absent_value_style:,
201
- bar_set:,
202
- block: @tui.block(title: "Gap Pattern (Responsive)")
203
- ),
204
- main_layout[4]
205
- )
206
-
207
- # Bottom control panel
208
- control_area = layout[1]
209
- frame.render_widget(
210
- @tui.block(
211
- title: "Controls",
212
- borders: [:all],
213
- children: [
214
- @tui.paragraph(
215
- text: [
216
- # Line 1: Data
217
- @tui.text_line(spans: [
218
- @tui.text_span(content: "↑/↓", style: @hotkey_style),
219
- @tui.text_span(content: ": Data (#{@data_sets[@data_index][:name]})"),
220
- ]),
221
- # Line 2: View
222
- @tui.text_line(spans: [
223
- @tui.text_span(content: "d", style: @hotkey_style),
224
- @tui.text_span(content: ": Direction (#{@directions[@direction_index][:name]}) "),
225
- @tui.text_span(content: "c", style: @hotkey_style),
226
- @tui.text_span(content: ": Color (#{@styles[@style_index][:name]})"),
227
- ]),
228
- # Line 3: Markers
229
- @tui.text_line(spans: [
230
- @tui.text_span(content: "m", style: @hotkey_style),
231
- @tui.text_span(content: ": Absent Value Symbol (#{@absent_symbols[@absent_symbol_index][:name]}) "),
232
- @tui.text_span(content: "s", style: @hotkey_style),
233
- @tui.text_span(content: ": Absent Value Style (#{@absent_styles[@absent_style_index][:name]})"),
234
- ]),
235
- # Line 4: General
236
- @tui.text_line(spans: [
237
- @tui.text_span(content: "b", style: @hotkey_style),
238
- @tui.text_span(content: ": Bar Set (#{@bar_sets[@bar_set_index][:name]}) "),
239
- @tui.text_span(content: "q", style: @hotkey_style),
240
- @tui.text_span(content: ": Quit"),
241
- ]),
242
- ]
243
- ),
244
- ]
245
- ),
246
- control_area
247
- )
248
- end
249
- end
250
-
251
- private def handle_input
252
- event = @tui.poll_event
253
-
254
- case event
255
- in { type: :key, code: "q" } | { type: :key, code: "c", modifiers: ["ctrl"] }
256
- :quit
257
- in type: :key, code: "up"
258
- @data_index = (@data_index - 1) % @data_sets.length
259
- in type: :key, code: "down"
260
- @data_index = (@data_index + 1) % @data_sets.length
261
- in type: :key, code: "d"
262
- @direction_index = (@direction_index + 1) % @directions.length
263
- in type: :key, code: "c"
264
- @style_index = (@style_index + 1) % @styles.length
265
- in type: :key, code: "m"
266
- @absent_symbol_index = (@absent_symbol_index + 1) % @absent_symbols.length
267
- in type: :key, code: "s"
268
- @absent_style_index = (@absent_style_index + 1) % @absent_styles.length
269
- in type: :key, code: "b"
270
- @bar_set_index = (@bar_set_index + 1) % @bar_sets.length
271
- else
272
- nil
273
- end
274
- end
275
- end
276
-
277
- WidgetSparkline.new.run if __FILE__ == $PROGRAM_NAME
@@ -1,43 +0,0 @@
1
- <!--
2
- SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
- SPDX-License-Identifier: CC-BY-SA-4.0
4
- -->
5
-
6
- # Style Colors Example
7
-
8
- [![widget_style_colors](../../doc/images/widget_style_colors.png)](app.rb)
9
-
10
- Demonstrates high-fidelity color support.
11
-
12
- Terminals support millions of colors. This example generates a mathematically precise HSL gradient to prove the rendering engine's color fidelity.
13
-
14
- ## Features Demonstrated
15
-
16
- - **HSL to RGB Conversion**: generating smooth color gradients programmatically.
17
- - **TrueColor Support**: Rendering arbitrary HEX colors.
18
-
19
- ## Hotkeys
20
-
21
- - **q** / **Ctrl+c**: Quit
22
-
23
- ## Usage
24
-
25
- <!-- SPDX-SnippetBegin -->
26
- <!--
27
- SPDX-FileCopyrightText: 2026 Kerrick Long
28
- SPDX-License-Identifier: MIT-0
29
- -->
30
- ```bash
31
- ruby examples/widget_style_colors/app.rb
32
- ```
33
- <!-- SPDX-SnippetEnd -->
34
-
35
- ## Learning Outcomes
36
-
37
- Use this example if you need to...
38
-
39
- - Create meaningful heatmaps.
40
- - Generate color palettes dynamically.
41
- - Test your terminal's color support capabilities.
42
-
43
- [Read the source code →](app.rb)
@@ -1,83 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- #--
4
- # SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
5
- # SPDX-License-Identifier: MIT-0
6
- #++
7
-
8
- $LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
9
- require "ratatui_ruby"
10
-
11
- # Demonstrates terminal color rendering and the Color module.
12
- #
13
- # Terminal apps need vibrant colors. Specifying colors as symbols or
14
- # calculated hex strings works but limits expressiveness.
15
- #
16
- # This demo shows the Color module's constructors for creating colors
17
- # from HSL values or hex integers, producing a full-spectrum gradient.
18
- #
19
- # Use it to understand color representation and the Color.hsl/Color.hex APIs.
20
- class WidgetStyleColors
21
- def initialize
22
- @width = 80
23
- @height = 24
24
- end
25
-
26
- def run
27
- RatatuiRuby.run do |tui|
28
- loop do
29
- tui.draw do |frame|
30
- frame.render_widget(render(tui), frame.area)
31
- end
32
- event = tui.poll_event
33
- break if event.key? && (event.ctrl_c? || event == :q)
34
- end
35
- end
36
- end
37
-
38
- private def render(tui)
39
- lines = []
40
-
41
- (0...@height).each do |row|
42
- spans = []
43
- (0...@width).each do |col|
44
- hue = (col.to_f / @width) * 360.0
45
- lightness = 50.0 - ((row.to_f / @height) * 50.0)
46
-
47
- # Use Color.hsl for top half, Color.hsluv for bottom half
48
- # HSLuv provides perceptually uniform colors (same visual brightness)
49
- hex = if row < @height / 2
50
- RatatuiRuby::Style::Color.hsl(hue, 100.0, lightness)
51
- else
52
- # HSLuv: perceptually uniform - all colors appear equal brightness
53
- RatatuiRuby::Style::Color.hsluv(hue, 100.0, lightness)
54
- end
55
-
56
- # Demonstrate Style.with for concise inline styling
57
- span = tui.text_span(
58
- content: " ",
59
- style: RatatuiRuby::Style::Style.with(bg: hex)
60
- )
61
- spans << span
62
- end
63
-
64
- lines << tui.text_line(spans:)
65
- end
66
-
67
- # Also demonstrate Color.hex for the border
68
- border_color = RatatuiRuby::Style::Color.hex(0xFFD700) # Gold
69
-
70
- tui.paragraph(
71
- text: lines,
72
- block: tui.block(
73
- title: "HSL (top) vs HSLuv (bottom) - Style.with demo (Press 'q' to exit)",
74
- borders: [:all],
75
- border_type: :rounded,
76
- # Using Style.with for concise border styling
77
- border_style: RatatuiRuby::Style::Style.with(fg: border_color)
78
- )
79
- )
80
- end
81
- end
82
-
83
- WidgetStyleColors.new.run if __FILE__ == $PROGRAM_NAME
@@ -1,57 +0,0 @@
1
- <!--
2
- SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
- SPDX-License-Identifier: CC-BY-SA-4.0
4
- -->
5
-
6
- # Table (Row, Cell) Example
7
-
8
- [![widget_table](../../doc/images/widget_table.png)](app.rb)
9
-
10
- Demonstrates advanced options for the `Table` widget, including selection, row-level highlighting, and column-level highlighting.
11
-
12
- Data grids are complex. Users expect to navigate them with keys, select rows, and clearly see which cell is active. The `Table` widget provides these features out of the box efficiently.
13
-
14
- ## Features Demonstrated
15
-
16
- - **Selection State**: Managing `selected_row` and `selected_column` to track user focus.
17
- - **Complex Highlighting**:
18
- - **Row**: Highlight the entire active row.
19
- - **Highlight Symbol:** Adding a visual indicator (like `> `) to the selected row.
20
- - **Spacing:** Adjusting `column_spacing` and `highlight_spacing` to control layout density.
21
- - **Flex Layout:** Switching between different column distribution modes (`legacy`, `start`, `space_between`, etc.).
22
- - **Offset Control:** Manually controlling the scroll position using `offset`.
23
-
24
- ## Hotkeys
25
-
26
- - **Arrows (↑/↓)**: Navigate Rows (`selected_row`)
27
- - **Arrows (←/→)**: Navigate Columns (`selected_column`)
28
- - **x**: Toggle Row Selection (`selected_row` = nil)
29
- - **s**: Cycle Table Style (`style`)
30
- - **p**: Cycle Spacing (`highlight_spacing`)
31
- - **c**: Toggle Column Highlight (`column_highlight_style`)
32
- - **z**: Toggle Cell Highlight (`cell_highlight_style`)
33
- - **o**: Cycle Offset Mode (`offset`)
34
- - **f**: Cycle Flex Mode (`flex`)
35
- - **q**: Quit
36
-
37
- ## Usage
38
-
39
- <!-- SPDX-SnippetBegin -->
40
- <!--
41
- SPDX-FileCopyrightText: 2026 Kerrick Long
42
- SPDX-License-Identifier: MIT-0
43
- -->
44
- ```bash
45
- ruby examples/widget_table/app.rb
46
- ```
47
- <!-- SPDX-SnippetEnd -->
48
-
49
- ## Learning Outcomes
50
-
51
- Use this example if you need to...
52
-
53
- - Build a file explorer or process list.
54
- - Create a data-heavy dashboard.
55
- - Handle conflicting style requirements (e.g., "Highlight this row, but make this error cell red").
56
-
57
- [Read the source code →](app.rb)