ratatui_ruby 0.2.0 → 0.3.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 (93) hide show
  1. checksums.yaml +4 -4
  2. data/.builds/ruby-3.2.yml +2 -2
  3. data/.builds/ruby-3.3.yml +2 -2
  4. data/.builds/ruby-3.4.yml +2 -2
  5. data/.builds/{ruby-4.0.0-preview3.yml → ruby-4.0.0.yml} +5 -5
  6. data/.pre-commit-config.yaml +9 -2
  7. data/AGENTS.md +51 -3
  8. data/CHANGELOG.md +51 -1
  9. data/README.md +7 -7
  10. data/REUSE.toml +1 -1
  11. data/{docs → doc}/contributors/index.md +2 -1
  12. data/doc/custom.css +8 -0
  13. data/doc/images/examples-custom_widget.rb.png +0 -0
  14. data/doc/images/examples-popup_demo.rb.gif +0 -0
  15. data/doc/images/examples-scroll_text.rb.png +0 -0
  16. data/doc/images/examples-table_select.rb.png +0 -0
  17. data/{docs → doc}/index.md +1 -1
  18. data/{docs → doc}/quickstart.md +24 -0
  19. data/examples/custom_widget.rb +43 -0
  20. data/examples/popup_demo.rb +105 -0
  21. data/examples/scroll_text.rb +74 -0
  22. data/examples/table_select.rb +70 -0
  23. data/examples/test_popup_demo.rb +62 -0
  24. data/examples/test_scroll_text.rb +130 -0
  25. data/examples/test_table_select.rb +37 -0
  26. data/ext/ratatui_ruby/Cargo.lock +167 -50
  27. data/ext/ratatui_ruby/Cargo.toml +4 -4
  28. data/ext/ratatui_ruby/src/buffer.rs +54 -0
  29. data/ext/ratatui_ruby/src/events.rs +111 -106
  30. data/ext/ratatui_ruby/src/lib.rs +15 -6
  31. data/ext/ratatui_ruby/src/rendering.rs +14 -0
  32. data/ext/ratatui_ruby/src/style.rs +2 -1
  33. data/ext/ratatui_ruby/src/terminal.rs +24 -19
  34. data/ext/ratatui_ruby/src/widgets/calendar.rs +4 -3
  35. data/ext/ratatui_ruby/src/widgets/canvas.rs +1 -2
  36. data/ext/ratatui_ruby/src/widgets/center.rs +0 -2
  37. data/ext/ratatui_ruby/src/widgets/chart.rs +11 -4
  38. data/ext/ratatui_ruby/src/widgets/clear.rs +37 -0
  39. data/ext/ratatui_ruby/src/widgets/cursor.rs +1 -1
  40. data/ext/ratatui_ruby/src/widgets/layout.rs +2 -1
  41. data/ext/ratatui_ruby/src/widgets/list.rs +6 -4
  42. data/ext/ratatui_ruby/src/widgets/mod.rs +1 -0
  43. data/ext/ratatui_ruby/src/widgets/overlay.rs +2 -1
  44. data/ext/ratatui_ruby/src/widgets/paragraph.rs +10 -0
  45. data/ext/ratatui_ruby/src/widgets/table.rs +25 -6
  46. data/ext/ratatui_ruby/src/widgets/tabs.rs +2 -1
  47. data/lib/ratatui_ruby/dsl.rb +2 -0
  48. data/lib/ratatui_ruby/schema/clear.rb +83 -0
  49. data/lib/ratatui_ruby/schema/paragraph.rb +7 -4
  50. data/lib/ratatui_ruby/schema/rect.rb +24 -0
  51. data/lib/ratatui_ruby/schema/table.rb +8 -2
  52. data/lib/ratatui_ruby/version.rb +1 -1
  53. data/lib/ratatui_ruby.rb +3 -1
  54. data/sig/ratatui_ruby/buffer.rbs +11 -0
  55. data/sig/ratatui_ruby/schema/rect.rbs +14 -0
  56. data/tasks/bump/changelog.rb +37 -0
  57. data/tasks/bump/comparison_links.rb +41 -0
  58. data/tasks/bump/header.rb +30 -0
  59. data/tasks/bump/history.rb +30 -0
  60. data/tasks/bump/manifest.rb +8 -0
  61. data/tasks/bump/ruby_gem.rb +6 -10
  62. data/tasks/bump/sem_ver.rb +6 -0
  63. data/tasks/bump/unreleased_section.rb +38 -0
  64. data/tasks/bump.rake +5 -1
  65. data/tasks/doc.rake +5 -4
  66. data/tasks/resources/build.yml.erb +1 -1
  67. data/tasks/resources/rubies.yml +1 -1
  68. data/tasks/sourcehut.rake +11 -2
  69. data/tasks/website/version.rb +1 -0
  70. data/tasks/website/version_menu.rb +68 -0
  71. data/tasks/website/versioned_documentation.rb +2 -1
  72. data/tasks/website/website.rb +4 -1
  73. data/tasks/website.rake +3 -3
  74. metadata +75 -25
  75. data/CODE_OF_CONDUCT.md +0 -30
  76. data/CONTRIBUTING.md +0 -40
  77. /data/{docs → doc}/application_testing.md +0 -0
  78. /data/{docs → doc}/contributors/design/ruby_frontend.md +0 -0
  79. /data/{docs → doc}/contributors/design/rust_backend.md +0 -0
  80. /data/{docs → doc}/contributors/design.md +0 -0
  81. /data/{docs → doc}/images/examples-analytics.rb.png +0 -0
  82. /data/{docs → doc}/images/examples-box_demo.rb.png +0 -0
  83. /data/{docs → doc}/images/examples-calendar_demo.rb.png +0 -0
  84. /data/{docs → doc}/images/examples-chart_demo.rb.png +0 -0
  85. /data/{docs → doc}/images/examples-dashboard.rb.png +0 -0
  86. /data/{docs → doc}/images/examples-list_styles.rb.png +0 -0
  87. /data/{docs → doc}/images/examples-login_form.rb.png +0 -0
  88. /data/{docs → doc}/images/examples-map_demo.rb.png +0 -0
  89. /data/{docs → doc}/images/examples-mouse_events.rb.png +0 -0
  90. /data/{docs → doc}/images/examples-quickstart_lifecycle.rb.png +0 -0
  91. /data/{docs → doc}/images/examples-scrollbar_demo.rb.png +0 -0
  92. /data/{docs → doc}/images/examples-stock_ticker.rb.png +0 -0
  93. /data/{docs → doc}/images/examples-system_monitor.rb.png +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a5a3b028ff3dc634d6b77c5c0b13d63dcc1dc501f0cca3fd541499dbab8ca3a9
4
- data.tar.gz: a8e6f86565a4dec484935444fa3f2a2e5e1691aaa8db5c5bd244c92f07e082fc
3
+ metadata.gz: 0e4a0958532fe7b493fcf0d9ee971bbc94194f5ff03fd420f895197597dac1c8
4
+ data.tar.gz: 480c3a5a467d478626a12c739064f894952e23d7a4574d0ad73a21dcc7b80ff5
5
5
  SHA512:
6
- metadata.gz: efcd43721bd3db1f115529deaabc40d7ec0549490b4bc899b0b0e9120399be5201892fd213dd799aa19c99d120674ecd2cea54afb53c58bfbb14a3bef3ceb6b2
7
- data.tar.gz: 7b3abbb0dcefbab609c5fdeff706b28421215f15d48c272c065b47469d1095073686fdbd85045594c82bc7f528fe9bd2511b09984314ec44f5d2358adfec8827
6
+ metadata.gz: 28f9f71581859a3ddaecb62df012e942fa3617dfcac1634af88e84b676b13802d3bb0bf7443ebba96f2bc1a00f503e86b8a2e2d3d6f613864d35b7002d432dac
7
+ data.tar.gz: f08716e00372054fcbee63e44ecb39e692ec2cc0b23d6e5596243b6df5c248274bf5b750b376d004644d8cf7a91993bde3e7c5dc980856befe84e0ce680de7b5
data/.builds/ruby-3.2.yml CHANGED
@@ -16,7 +16,7 @@ packages:
16
16
  - clang-dev
17
17
  - git
18
18
  artifacts:
19
- - ratatui_ruby/pkg/ratatui_ruby-0.2.0.gem
19
+ - ratatui_ruby/pkg/ratatui_ruby-0.3.0.gem
20
20
  sources:
21
21
  - https://git.sr.ht/~kerrick/ratatui_ruby
22
22
  tasks:
@@ -31,7 +31,7 @@ tasks:
31
31
  sed -i 's/ruby = .*/ruby = "3.2"/' mise.toml
32
32
  mise install
33
33
  mise x -- pip install reuse
34
- mise x -- gem install bundler
34
+ mise x -- gem install bundler:2.6.9
35
35
  mise reshim
36
36
  mise x -- bundle config set --local frozen 'true'
37
37
  mise x -- bundle install
data/.builds/ruby-3.3.yml CHANGED
@@ -16,7 +16,7 @@ packages:
16
16
  - clang-dev
17
17
  - git
18
18
  artifacts:
19
- - ratatui_ruby/pkg/ratatui_ruby-0.2.0.gem
19
+ - ratatui_ruby/pkg/ratatui_ruby-0.3.0.gem
20
20
  sources:
21
21
  - https://git.sr.ht/~kerrick/ratatui_ruby
22
22
  tasks:
@@ -31,7 +31,7 @@ tasks:
31
31
  sed -i 's/ruby = .*/ruby = "3.3"/' mise.toml
32
32
  mise install
33
33
  mise x -- pip install reuse
34
- mise x -- gem install bundler
34
+ mise x -- gem install bundler:2.6.9
35
35
  mise reshim
36
36
  mise x -- bundle config set --local frozen 'true'
37
37
  mise x -- bundle install
data/.builds/ruby-3.4.yml CHANGED
@@ -16,7 +16,7 @@ packages:
16
16
  - clang-dev
17
17
  - git
18
18
  artifacts:
19
- - ratatui_ruby/pkg/ratatui_ruby-0.2.0.gem
19
+ - ratatui_ruby/pkg/ratatui_ruby-0.3.0.gem
20
20
  sources:
21
21
  - https://git.sr.ht/~kerrick/ratatui_ruby
22
22
  tasks:
@@ -31,7 +31,7 @@ tasks:
31
31
  sed -i 's/ruby = .*/ruby = "3.4"/' mise.toml
32
32
  mise install
33
33
  mise x -- pip install reuse
34
- mise x -- gem install bundler
34
+ mise x -- gem install bundler:2.6.9
35
35
  mise reshim
36
36
  mise x -- bundle config set --local frozen 'true'
37
37
  mise x -- bundle install
@@ -16,7 +16,7 @@ packages:
16
16
  - clang-dev
17
17
  - git
18
18
  artifacts:
19
- - ratatui_ruby/pkg/ratatui_ruby-0.2.0.gem
19
+ - ratatui_ruby/pkg/ratatui_ruby-0.3.0.gem
20
20
  sources:
21
21
  - https://git.sr.ht/~kerrick/ratatui_ruby
22
22
  tasks:
@@ -28,10 +28,10 @@ tasks:
28
28
  export RUSTFLAGS="-C target-feature=-crt-static"
29
29
  export CI="true"
30
30
  cd ratatui_ruby
31
- sed -i 's/ruby = .*/ruby = "4.0.0-preview3"/' mise.toml
31
+ sed -i 's/ruby = .*/ruby = "4.0.0"/' mise.toml
32
32
  mise install
33
33
  mise x -- pip install reuse
34
- mise x -- gem install bundler
34
+ mise x -- gem install bundler:2.6.9
35
35
  mise reshim
36
36
  mise x -- bundle config set --local frozen 'true'
37
37
  mise x -- bundle install
@@ -40,12 +40,12 @@ tasks:
40
40
  - test: |
41
41
  . ~/.buildenv
42
42
  cd ratatui_ruby
43
- echo "Testing Ruby 4.0.0-preview3"
43
+ echo "Testing Ruby 4.0.0"
44
44
  mise x -- bundle exec rake test || true
45
45
  - lint: |
46
46
  . ~/.buildenv
47
47
  cd ratatui_ruby
48
- echo "Linting Ruby 4.0.0-preview3"
48
+ echo "Linting Ruby 4.0.0"
49
49
  mise x -- bundle exec rake lint || true
50
50
  - package: |
51
51
  . ~/.buildenv
@@ -3,7 +3,14 @@
3
3
  repos:
4
4
  - repo: local
5
5
  hooks:
6
+ - id: bundle-check
7
+ name: Check Gemfile.lock
8
+ entry: bundle check
9
+ language: system
10
+ files: (Gemfile|Gemfile\.lock|ratatui_ruby\.gemspec)
11
+ pass_filenames: false
6
12
  - id: rake
7
13
  name: rake
8
- entry: rake
9
- language: ruby
14
+ entry: bundle exec rake
15
+ language: system
16
+ pass_filenames: false
data/AGENTS.md CHANGED
@@ -36,7 +36,7 @@ Every file must begin with an SPDX-compliant header. Use the following format:
36
36
  ### Ruby Standards
37
37
 
38
38
  - **Version:** Tested against the latest releases of Ruby 3.2, 3.3, and 3.4, and must work. Also tested in CI (with allowed failures) against the latest preview Ruby 4.0 to prepare for its release. Local development happens on the latest stable release.
39
- - **Linter:** Run via `rake lint`. You are not done until all linting passes.
39
+ - **Linter:** Run via `bundle exec rake lint`. You are not done until all linting passes.
40
40
  - **Style:**
41
41
  - Use `Data.define` for all value objects (UI Nodes). (Prefer `class Foo < Data.define()` over `Foo = Data.define() do`).
42
42
  - Prefer `frozen_string_literal: true`.
@@ -94,14 +94,15 @@ The project follows a standard Gem layout with an `ext/` directory for Rust code
94
94
  ### Development Environment
95
95
 
96
96
  - **Setup:** `bin/setup` must handle both Bundler and Cargo dependencies.
97
- - **Pre-commit:** Use `.pre-commit-config.yaml` to enforce `rake` and `cargo fmt`.
97
+ - **Pre-commit:** Use `.pre-commit-config.yaml` to enforce `bundle exec rake` and `cargo fmt`.
98
98
 
99
99
  ### Documentation
100
100
 
101
101
  - Follow the `docs/` structure: `index.md` -> `contributors/` | `quickstart.md`.
102
102
  - Documentation should separate "User Guide" (Ruby API for TUI developers) from "Contributor Guide" (Ruby/Rust/Magnus internals).
103
103
  - Don't write .md files for something RDoc (Ruby) or rustdoc (Rust) can generate.
104
- - **Never edit the `doc/` folder directly.** It is automatically generated by `rake rerdoc`. If you need to refresh the generated documentation, run that command instead.
104
+ - **The `doc/` folder contains source markdown files** that are included in RDoc output. You can edit these files.
105
+ - **The `tmp/rdoc/` folder is auto-generated** by `bundle exec rake rerdoc`. Never edit files in `tmp/rdoc/` directly.
105
106
 
106
107
  ## 4. The Ruby <-> Rust Bridge Contract
107
108
 
@@ -117,3 +118,50 @@ The project follows a standard Gem layout with an `ext/` directory for Rust code
117
118
 
118
119
  - The gem builds a native extension.
119
120
  - Artifact naming: Ensure the output shared library matches Ruby's expectation on macOS (rename `.dylib`to `.bundle` if necessary during the build process in `extconf.rb` or `Rakefile`).
121
+
122
+ ## 6. Source Control Standards
123
+
124
+ - **Commits:**
125
+ - Who commits: Only humans should affect the git index and history. Rather than staging and/or committing, you should suggest a commit message.
126
+ - When: At the end of each task, before reporting the task as complete to the user, suggest the commit message.
127
+ - **Format:**
128
+ - Subject line: Concise summary (50 chars or less).
129
+ - Body: Detailed explanation if necessary (wrap at 72 chars). Explain why this is the implementation, as opposed to other possible implementations. Skip the body entirely if it's rote, a duplication of the diff, or otherwise unhelpful. **Do not simply list the files changed or the minor edits made to them.** Do not use markdown, except as required in AI Attribution.
130
+ - Footer: AI attribution if generated by an agent, sourcehut ticket if implemented by a ticket, or both.
131
+ - **AI Attribution:**
132
+ - **Antigravity:**
133
+ Specify the model used in the footer. Examples:
134
+ ```
135
+ Generated with [Antigravity](https://antigravity.google)
136
+
137
+ Co-Authored-By: Gemini 3 Pro (High) <noreply@google.com>
138
+ ```
139
+ ```
140
+ Generated with [Antigravity](https://antigravity.google)
141
+
142
+ Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
143
+ ```
144
+ - **Gemini 3:**
145
+ ```
146
+ Generated with [Gemini 3 Pro](https://gemini.google.com/)
147
+
148
+ Co-Authored-By: Gemini 3 Pro <noreply@google.com>
149
+ ```
150
+ - **JetBrains Junie:**
151
+ ```
152
+ Generated with [JetBrains Junie](https://www.jetbrains.com/ai/)
153
+
154
+ Co-Authored-By: Junie <junie@jetbrains.com>
155
+ ```
156
+ - **Sourcehut Tickets:**
157
+ - If the commit implements a specific ticket, include a footer: `Implements: https://todo.sr.ht/~kerrick/ratatui_ruby/<id>`
158
+ - This must be the **last** item in the footer, if present.
159
+
160
+ ## 7. Definition of Done
161
+
162
+ Before considering a task complete and returning control to the user, you **MUST** ensure:
163
+
164
+ 1. **Tests & Linting Pass:** Run `bundle exec rake` and confirm it passes. No new errors **or warnings** should be introduced.
165
+ 2. **Documentation Updated:** If public APIs or observable behavior changed, update relevant `doc/` files, `README.md`, and/or `ratatui_ruby-wiki` files,.
166
+ 3. **Changelog Updated:** If public APIs, observable behavior, or gemspec dependencies changed, update [CHANGELOG.md](CHANGELOG.md)'s **Unreleased** section according to the [Semantic Versioning](https://semver.org/) and [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) specifications. Changelogs should be useful to human users of the library, not simple restatements of diffs or commit messages. **Do not add entries for internal tooling, CI, or build configuration changes that do not affect the distributed gem.**
167
+ 4. **Commit Message Suggested:** You **MUST** ensure the final message to the user includes a suggested commit message block. This is NOT optional.
data/CHANGELOG.md CHANGED
@@ -12,4 +12,54 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
12
12
 
13
13
  ### Added
14
14
 
15
- - Created the gem
15
+ ### Changed
16
+
17
+ ### Fixed
18
+
19
+ ### Removed
20
+
21
+ ## [0.3.0] - 2025-12-28
22
+
23
+ ### Added
24
+
25
+ - **The Escape Hatch (Ruby Render Callback)**: Added the ability to define custom widgets in pure Ruby by implementing a `render(area, buffer)` method. The `Buffer` object provides low-level drawing primitives like `set_string`, allowing developers to create custom TUI components without writing Rust code.
26
+ - **Clear Widget**: Added the `Clear` widget, which resets the terminal buffer in the area it is rendered. This is essential for creating opaque popups and modals that prevent background styles from "bleeding" through transparent widgets.
27
+ - **Interactive Table Selection**: The `Table` widget now supports row selection with `selected_row`, `highlight_style`, and `highlight_symbol` parameters. This enables building interactive data grids and file explorers where users can navigate through rows using keyboard input.
28
+ - **Scrollable Paragraphs**: The `Paragraph` widget now supports a `scroll` parameter that accepts a `(y, x)` array to scroll content vertically and horizontally. This enables viewing long text content that exceeds the visible area, such as logs or documents. The parameter order matches ratatui's convention.
29
+
30
+ ### Changed
31
+
32
+ - **Center Widget**: Removed the implicit `Clear` call from the `Center` widget. `Center` is now a pure layout widget, requiring an explicit `Clear` widget if background clearing is desired. This restores correct behavior for transparent overlays.
33
+
34
+ ## [0.2.0] - 2025-12-24
35
+
36
+ ### Added
37
+
38
+ - **DSL for Simpler Apps**: Introduced `RatatuiRuby.main_loop`, a new entrypoint that simplifies application structure when you don't need control of the event loop or application lifecycle.
39
+ - **Calendar Widget**: Added the `Calendar` widget, allowing you to display monthly views and visualize date-based information.
40
+ - **Generic Charts**: Implemented the full `Chart` widget, which supersedes the now-deprecated `LineChart` and `BarChart` widgets, giving you more freedom to visualize data sets.
41
+ - **Enhanced List Styling**: You can now customize the appearance of selected items in a `List` using `highlight_style` and `highlight_symbol`.
42
+ - **Broader Ruby Support**: Added support for a wider range of Ruby versions: every non-EOL version. The latest preview of Ruby 4.0 is tested in CI, but not supported.
43
+ - **Dev Tools**: Added internal Rake tasks for managing historical documentation and SemVer checks.
44
+
45
+ ## [0.1.0] - 2025-12-22
46
+
47
+ ### Added
48
+
49
+ - **First Release**: Initial public release of `ratatui_ruby`, bringing the power of the Rust [ratatui](https://github.com/ratatui-org/ratatui) library to Rubyists!
50
+ - **Core Widget Set**: Includes a comprehensive suite of widgets to get you started:
51
+ - `Block`, `Borders`, and `Paragraph` for basic content.
52
+ - `List` and `Table` for structured data.
53
+ - `Gauge` and `Sparkline` for progress and metrics.
54
+ - `Tabs` for navigation.
55
+ - `Canvas` for drawing shapes (Lines, Circles, Rectangles, Maps).
56
+ - **Layout System**: A flexible layout engine using `Flex`, `Layout`, and `Constraints` to build responsive interfaces that adapt to any terminal size.
57
+ - **Forms & Layers**: Primitives like `Overlay` and `Center` for creating modal dialogs, plus a `Cursor` widget for text input interactions.
58
+ - **Styling**: Full support for `Ratatui`'s styling primitives, including modifiers and RGB/ANSI colors.
59
+ - **Input Handling**: Robust handling for both Keyboard and Mouse events.
60
+ - **Testing Support**: Included `RatatuiRuby::TestHelper` and RSpec integration to make testing your TUI applications possible.
61
+
62
+ [Unreleased]: https://git.sr.ht/~kerrick/ratatui_ruby/compare/v0.3.0...HEAD
63
+ [0.3.0]: https://git.sr.ht/~kerrick/ratatui_ruby/compare/v0.2.0...v0.3.0
64
+ [0.2.0]: https://git.sr.ht/~kerrick/ratatui_ruby/compare/v0.1.0...v0.2.0
65
+ [0.1.0]: https://git.sr.ht/~kerrick/ratatui_ruby/tree/v0.1.0
data/README.md CHANGED
@@ -23,7 +23,7 @@ Mailing List: Announcements](https://img.shields.io/badge/mailing_list-announcem
23
23
  > [!WARNING]
24
24
  > **ratatui_ruby** is currently in an early stage of development. Use at your own risk.
25
25
 
26
- Please join our **announce** mailing list at https://lists.sr.ht/~kerrick/ratatui_ruby-announce to stay up-to-date on new releases and announcements.
26
+ Please join the **announce** mailing list at https://lists.sr.ht/~kerrick/ratatui_ruby-announce to stay up-to-date on new releases and announcements.
27
27
 
28
28
 
29
29
  ## Compatibility
@@ -34,8 +34,8 @@ Please join our **announce** mailing list at https://lists.sr.ht/~kerrick/ratatu
34
34
  - x86_64 (AMD, Intel) and ARM (Apple Silicon, Raspberry Pi).
35
35
 
36
36
  We support the latest minor version of every
37
- [non-eol Ruby version](https://www.ruby-lang.org/en/downloads/branches/),
38
- plus the latest preview of the next version.
37
+ [non-eol Ruby version](https://www.ruby-lang.org/en/downloads/branches/).
38
+ Support for Ruby 4 is coming soon.
39
39
 
40
40
 
41
41
  ## Installation
@@ -80,21 +80,21 @@ RatatuiRuby.main_loop do |tui|
80
80
  end
81
81
  ```
82
82
 
83
- For a full tutorial, see [the Quickstart](./docs/quickstart.md).
83
+ For a full tutorial, see [the Quickstart](./doc/quickstart.md).
84
84
 
85
85
 
86
86
  ## Documentation
87
87
 
88
- For the full documentation on how to use **ratatui_ruby**, see our [docs](./docs/index.md).
88
+ For the full documentation on how to use **ratatui_ruby**, see the [documentation](./doc/index.md). For other information, see the [wiki](https://man.sr.ht/~kerrick/ratatui_ruby).
89
89
 
90
90
 
91
91
  ## Contributing
92
92
 
93
- Bug reports and pull requests are welcome on [sourcehut](https://sourcehut.org) at https://sr.ht/~kerrick/ratatui_ruby/. This project is intended to be a safe, productive collaboration, and contributors are expected to adhere to the [Ruby Community Conduct Guideline](https://www.ruby-lang.org/en/conduct/).
93
+ Bug reports and pull requests are welcome on [sourcehut](https://sourcehut.org) at https://sr.ht/~kerrick/ratatui_ruby/. This project is intended to be a safe, productive collaboration, and contributors are expected to adhere to the [Code of Conduct](https://man.sr.ht/~kerrick/ratatui_ruby/code_of_conduct.md).
94
94
 
95
95
  Issues for the underlying Rust library should be filed at [ratatui/ratatui](https://github.com/ratatui/ratatui).
96
96
 
97
- Want to help develop **ratatui_ruby**? Check out our [contribution guide](./CONTRIBUTING.md).
97
+ Want to help develop **ratatui_ruby**? Check out the [contribution guide on the wiki](https://man.sr.ht/~kerrick/ratatui_ruby/contributing.md).
98
98
 
99
99
 
100
100
  ## Copyright & License
data/REUSE.toml CHANGED
@@ -17,6 +17,6 @@ SPDX-FileCopyrightText = "2025 Kerrick Long <me@kerricklong.com>"
17
17
  SPDX-License-Identifier = "CC0-1.0"
18
18
 
19
19
  [[annotations]]
20
- path = 'docs/images/*.png'
20
+ path = 'doc/images/*.png'
21
21
  SPDX-FileCopyrightText = "2025 Kerrick Long <me@kerricklong.com>"
22
22
  SPDX-License-Identifier = "CC-BY-SA-4.0"
@@ -7,7 +7,8 @@
7
7
 
8
8
  ## Documentation for Contributors
9
9
 
10
- - [Contributing Guidelines](../../CONTRIBUTING.md)
10
+ - [Contributing Guidelines](https://man.sr.ht/~kerrick/ratatui_ruby/contributing.md)
11
+ - [Documentation Guide](https://man.sr.ht/~kerrick/ratatui_ruby/documentation_guide.md)
11
12
  - [The Design of **ratatui_ruby**](./design.md)
12
13
 
13
14
  ## Documentation for Users
data/doc/custom.css ADDED
@@ -0,0 +1,8 @@
1
+ img {
2
+ max-width: 100%;
3
+ height: auto;
4
+ }
5
+
6
+ .theme-toggle {
7
+ margin-left: 0 !important;
8
+ }
@@ -14,5 +14,5 @@
14
14
 
15
15
  ## Documentation for Contributors
16
16
 
17
- - [Contributing Guidelines](../CONTRIBUTING.md)
17
+ - [Contributing Guidelines](https://man.sr.ht/~kerrick/ratatui_ruby/contributing.md)
18
18
  - [More Documentation for Contributors](./contributors/index.md)
@@ -129,9 +129,18 @@ A simple demonstration of `Block` and `Paragraph` widgets, reacting to arrow key
129
129
  ### [Calendar Demo](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/calendar_demo.rb)
130
130
  A simple demo application for the `Calendar` widget.
131
131
 
132
+ ![Calendar Screenshot](./images/examples-calendar_demo.rb.png)
133
+
132
134
  ### [Chart Demo](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/chart_demo.rb)
133
135
  Demonstrates the `Chart` widget with both scatter and line datasets, including custom axes.
134
136
 
137
+ ![Chart Screenshot](./images/examples-chart_demo.rb.png)
138
+
139
+ ### [Custom Widget (Escape Hatch)](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/custom_widget.rb)
140
+ Demonstrates how to define a custom widget in pure Ruby using the `render(area, buffer)` escape hatch for low-level drawing.
141
+
142
+ ![Custom Widget Screenshot](./images/examples-custom_widget.rb.png)
143
+
135
144
  ### [Dashboard](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/dashboard.rb)
136
145
  Uses `Layout`, `List`, and `Paragraph` to create a classic sidebar-and-content interface.
137
146
 
@@ -155,11 +164,21 @@ Detailed plumbing of mouse events, including clicks, drags, and movement trackin
155
164
 
156
165
  ![Mouse Events Screenshot](./images/examples-mouse_events.rb.png)
157
166
 
167
+ ### [Popup Demo](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/popup_demo.rb)
168
+ Demonstrates the `Clear` widget and how to prevent "style bleed" when rendering opaque popups over colored backgrounds.
169
+
170
+ ![Popup Demo Screenshot](./images/examples-popup_demo.rb.gif)
171
+
158
172
  ### [Scrollbar Demo](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/scrollbar_demo.rb)
159
173
  A simple example of integrating the `Scrollbar` widget and handling mouse wheel events for scrolling.
160
174
 
161
175
  ![Scrollbar Demo Screenshot](./images/examples-scrollbar_demo.rb.png)
162
176
 
177
+ ### [Scroll Text](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/scroll_text.rb)
178
+ Demonstrates the `Paragraph` widget's scroll functionality, allowing navigation through long text content using arrow keys for both horizontal and vertical scrolling.
179
+
180
+ ![Scroll Text Screenshot](./images/examples-scroll_text.rb.png)
181
+
163
182
  ### [Stock Ticker](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/stock_ticker.rb)
164
183
  Utilizes `Sparkline` and `Chart` widgets to visualize real-time (simulated) data.
165
184
 
@@ -170,3 +189,8 @@ Combines `Table` and `Gauge` widgets in a vertical layout to create a functional
170
189
 
171
190
  ![System Monitor Screenshot](./images/examples-system_monitor.rb.png)
172
191
 
192
+ ### [Table Select](https://git.sr.ht/~kerrick/ratatui_ruby/tree/main/item/examples/table_select.rb)
193
+ Demonstrates interactive row selection in the `Table` widget with keyboard navigation, highlighting selected rows with custom styles and symbols.
194
+
195
+ ![Table Select Screenshot](./images/examples-table_select.rb.png)
196
+
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
+ # SPDX-License-Identifier: AGPL-3.0-or-later
5
+
6
+ $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
7
+ require "ratatui_ruby"
8
+
9
+ # A custom widget that draws a diagonal line.
10
+ class DiagonalWidget
11
+ def render(area, buffer)
12
+ # Draw a diagonal line within the area
13
+ (0..10).each do |i|
14
+ next if area.x + i >= area.x + area.width || area.y + i >= area.y + area.height
15
+
16
+ buffer.set_string(
17
+ area.x + i,
18
+ area.y + i,
19
+ "\\",
20
+ RatatuiRuby::Style.new(fg: :red, modifiers: [:bold])
21
+ )
22
+ end
23
+ end
24
+ end
25
+
26
+ RatatuiRuby.main_loop do |tui|
27
+ tui.draw(
28
+ RatatuiRuby::Layout.new(
29
+ direction: :vertical,
30
+ constraints: [
31
+ RatatuiRuby::Constraint.percentage(50),
32
+ RatatuiRuby::Constraint.percentage(50),
33
+ ],
34
+ children: [
35
+ RatatuiRuby::Paragraph.new(text: "Above custom widget"),
36
+ DiagonalWidget.new,
37
+ ]
38
+ )
39
+ )
40
+
41
+ event = RatatuiRuby.poll_event
42
+ break if event && event[:type] == :key && event[:code] == "q"
43
+ end
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
4
+ # SPDX-License-Identifier: AGPL-3.0-or-later
5
+
6
+ $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
7
+ require "ratatui_ruby"
8
+
9
+ # Popup Demo Example
10
+ # Demonstrates the Clear widget for creating opaque popups.
11
+
12
+ class PopupDemo
13
+ def initialize
14
+ @clear_enabled = false
15
+ end
16
+
17
+ def run
18
+ RatatuiRuby.init_terminal
19
+ begin
20
+ loop do
21
+ render
22
+ break if handle_input == :quit
23
+ sleep 0.05
24
+ end
25
+ ensure
26
+ RatatuiRuby.restore_terminal
27
+ end
28
+ end
29
+
30
+ def render
31
+ # 1. Background: Loud Red Background
32
+ # This demonstrates "Style Bleed" where the background color persists
33
+ # unless explicitly cleared or overwritten.
34
+ background = RatatuiRuby::Paragraph.new(
35
+ text: "BACKGROUND RED " * 100,
36
+ style: RatatuiRuby::Style.new(bg: :red, fg: :white),
37
+ wrap: true
38
+ )
39
+
40
+ # 2. Popup Content: No specific background set (Style.default)
41
+ # Without Clear, this will "inherit" the red background from underneath.
42
+ popup_text = if @clear_enabled
43
+ "✓ Clear is ENABLED\n\nResets background to default\n(Usually Black/Transparent)\n\nPress Space to toggle"
44
+ else
45
+ "✗ Clear is DISABLED\n\nStyle Bleed: Popup is RED!\n(Inherits background style)\n\nPress Space to toggle"
46
+ end
47
+
48
+ popup_content = RatatuiRuby::Paragraph.new(
49
+ text: popup_text,
50
+ align: :center,
51
+ block: RatatuiRuby::Block.new(
52
+ title: "Popup Demo (Press 'q' to quit)",
53
+ borders: [:all]
54
+ )
55
+ )
56
+
57
+ # Build the UI with or without Clear
58
+ if @clear_enabled
59
+ # With Clear: Resets the style in the popup area before rendering content
60
+ ui = RatatuiRuby::Overlay.new(
61
+ layers: [
62
+ background,
63
+ RatatuiRuby::Center.new(
64
+ child: RatatuiRuby::Overlay.new(
65
+ layers: [
66
+ RatatuiRuby::Clear.new,
67
+ popup_content
68
+ ]
69
+ ),
70
+ width_percent: 60,
71
+ height_percent: 50
72
+ )
73
+ ]
74
+ )
75
+ else
76
+ # Without Clear: Background style (RED) bleeds through the popup
77
+ ui = RatatuiRuby::Overlay.new(
78
+ layers: [
79
+ background,
80
+ RatatuiRuby::Center.new(
81
+ child: popup_content,
82
+ width_percent: 60,
83
+ height_percent: 50
84
+ )
85
+ ]
86
+ )
87
+ end
88
+
89
+ RatatuiRuby.draw(ui)
90
+ end
91
+
92
+ def handle_input
93
+ event = RatatuiRuby.poll_event
94
+ if event
95
+ case event[:code]
96
+ when "q"
97
+ :quit
98
+ when " "
99
+ @clear_enabled = !@clear_enabled
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ PopupDemo.new.run if __FILE__ == $0
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
5
+ # SPDX-License-Identifier: AGPL-3.0-or-later
6
+
7
+ $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
8
+ require "ratatui_ruby"
9
+
10
+ # Demo: Scrollable Paragraph
11
+ # Shows how to scroll through long text content using arrow keys
12
+ class ScrollTextDemo
13
+ def initialize
14
+ @scroll_x = 0
15
+ @scroll_y = 0
16
+ @lines = (1..100).map { |i| "Line #{i}: This is a long line of text that can be scrolled horizontally" }
17
+ end
18
+
19
+ def run
20
+ RatatuiRuby.init_terminal
21
+ begin
22
+ loop do
23
+ draw
24
+ break if handle_input == :quit
25
+ end
26
+ ensure
27
+ RatatuiRuby.restore_terminal
28
+ end
29
+ end
30
+
31
+ def render
32
+ draw
33
+ end
34
+
35
+ def handle_input
36
+ event = RatatuiRuby.poll_event
37
+ return nil unless event
38
+
39
+ if event[:type] == :key
40
+ case event[:code]
41
+ when "up"
42
+ @scroll_y = [@scroll_y - 1, 0].max
43
+ when "down"
44
+ @scroll_y = [@scroll_y + 1, @lines.length].min
45
+ when "left"
46
+ @scroll_x = [@scroll_x - 1, 0].max
47
+ when "right"
48
+ @scroll_x = [@scroll_x + 1, 100].min
49
+ when "q"
50
+ return :quit
51
+ end
52
+ end
53
+ nil
54
+ end
55
+
56
+ private
57
+
58
+ def draw
59
+ text = @lines.join("\n")
60
+
61
+ paragraph = RatatuiRuby::Paragraph.new(
62
+ text: text,
63
+ scroll: [@scroll_y, @scroll_x],
64
+ block: RatatuiRuby::Block.new(
65
+ title: "Scrollable Text (X: #{@scroll_x}, Y: #{@scroll_y}) - Arrow keys to scroll, 'q' to quit",
66
+ borders: [:all]
67
+ )
68
+ )
69
+
70
+ RatatuiRuby.draw(paragraph)
71
+ end
72
+ end
73
+
74
+ ScrollTextDemo.new.run if __FILE__ == $PROGRAM_NAME