ratatui_ruby 0.7.2 → 0.7.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 (56) 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 +4 -3
  7. data/CHANGELOG.md +28 -0
  8. data/README.md +2 -2
  9. data/doc/concepts/application_testing.md +4 -2
  10. data/doc/contributors/developing_examples.md +7 -7
  11. data/doc/contributors/upstream_requests/tab_rects.md +173 -0
  12. data/doc/contributors/upstream_requests/title_rects.md +132 -0
  13. data/doc/contributors/v1.0.0_blockers.md +46 -739
  14. data/doc/troubleshooting/tui_output.md +76 -0
  15. data/examples/widget_barchart/README.md +1 -1
  16. data/examples/widget_block/README.md +1 -1
  17. data/examples/widget_overlay/README.md +1 -1
  18. data/ext/ratatui_ruby/Cargo.lock +1 -1
  19. data/ext/ratatui_ruby/Cargo.toml +1 -1
  20. data/ext/ratatui_ruby/src/lib.rs +2 -2
  21. data/ext/ratatui_ruby/src/rendering.rs +9 -0
  22. data/ext/ratatui_ruby/src/style.rs +22 -2
  23. data/ext/ratatui_ruby/src/text.rs +26 -0
  24. data/ext/ratatui_ruby/src/widgets/chart.rs +5 -0
  25. data/lib/ratatui_ruby/style/style.rb +1 -0
  26. data/lib/ratatui_ruby/test_helper/snapshot.rb +60 -21
  27. data/lib/ratatui_ruby/test_helper/snapshots/axis_labels_alignment.ansi +24 -0
  28. data/lib/ratatui_ruby/test_helper/snapshots/axis_labels_alignment.txt +24 -0
  29. data/lib/ratatui_ruby/test_helper/snapshots/barchart_styled_label.ansi +5 -0
  30. data/lib/ratatui_ruby/test_helper/snapshots/barchart_styled_label.txt +5 -0
  31. data/lib/ratatui_ruby/test_helper/snapshots/chart_rendering.ansi +24 -0
  32. data/lib/ratatui_ruby/test_helper/snapshots/chart_rendering.txt +24 -0
  33. data/lib/ratatui_ruby/test_helper/snapshots/half_block_marker.ansi +12 -0
  34. data/lib/ratatui_ruby/test_helper/snapshots/half_block_marker.txt +12 -0
  35. data/lib/ratatui_ruby/test_helper/snapshots/legend_position_bottom.ansi +12 -0
  36. data/lib/ratatui_ruby/test_helper/snapshots/legend_position_bottom.txt +12 -0
  37. data/lib/ratatui_ruby/test_helper/snapshots/legend_position_left.ansi +12 -0
  38. data/lib/ratatui_ruby/test_helper/snapshots/legend_position_left.txt +12 -0
  39. data/lib/ratatui_ruby/test_helper/snapshots/legend_position_right.ansi +12 -0
  40. data/lib/ratatui_ruby/test_helper/snapshots/legend_position_right.txt +12 -0
  41. data/lib/ratatui_ruby/test_helper/snapshots/legend_position_top.ansi +12 -0
  42. data/lib/ratatui_ruby/test_helper/snapshots/legend_position_top.txt +12 -0
  43. data/lib/ratatui_ruby/test_helper/snapshots/my_snapshot.txt +1 -0
  44. data/lib/ratatui_ruby/test_helper/snapshots/styled_axis_title.ansi +10 -0
  45. data/lib/ratatui_ruby/test_helper/snapshots/styled_axis_title.txt +10 -0
  46. data/lib/ratatui_ruby/test_helper/snapshots/styled_dataset_name.ansi +10 -0
  47. data/lib/ratatui_ruby/test_helper/snapshots/styled_dataset_name.txt +10 -0
  48. data/lib/ratatui_ruby/test_helper/terminal.rb +3 -0
  49. data/lib/ratatui_ruby/test_helper.rb +1 -1
  50. data/lib/ratatui_ruby/version.rb +1 -1
  51. data/lib/ratatui_ruby/widgets/bar_chart.rb +3 -2
  52. data/lib/ratatui_ruby/widgets/block.rb +42 -0
  53. data/lib/ratatui_ruby/widgets/chart.rb +9 -4
  54. data/lib/ratatui_ruby/widgets/sparkline.rb +3 -2
  55. data/lib/ratatui_ruby.rb +128 -9
  56. metadata +26 -2
@@ -5,13 +5,8 @@ SPDX-License-Identifier: CC-BY-SA-4.0
5
5
 
6
6
  # alignment_audit
7
7
  ## alignment_audit
8
- - Colors
9
- - Reset (1)
10
- - Enums and Constants
11
- - LegendPosition (4)
12
8
  - Symbol Sets
13
- - Marker::HalfBlock (1)
14
- - line::Set, bar::Set, block::Set, scrollbar::Set
9
+ - line::Set, block::Set, scrollbar::Set
15
10
  - Layout
16
11
  - Rect methods (~13)
17
12
  - Constraint batch constructors (6)
@@ -24,294 +19,12 @@ SPDX-License-Identifier: CC-BY-SA-4.0
24
19
 
25
20
  ###### MISALIGNED (non-additive, breaking)
26
21
 
27
- **All items fixed in v0.7.0:**
28
-
29
- - ~~Text::Line missing `style:` field~~ ✅ Added
30
- - ~~Widgets::Table uses `highlight_style:`~~ ✅ Renamed to `row_highlight_style:`
31
-
32
-
33
- ---
34
-
35
-
36
- ### alignment_audit_colors
37
- ##### v0.7.0 Alignment Audit: Colors
38
-
39
- Audit of color alignment between Ratatui/Crossterm and RatatuiRuby.
40
-
41
- > [!IMPORTANT]
42
- > **MISSING** = Can be added as new features, backwards-compatible.
43
- > **MISALIGNED** = Requires breaking changes before v1.0.0.
44
-
45
- ---
46
-
47
- ###### Summary
48
-
49
- | Color Type | Ratatui | RatatuiRuby | Status |
50
- |------------|---------|-------------|--------|
51
- | Named colors (8 base) | ✅ | ✅ Symbols | ✅ Aligned |
52
- | Named colors (8 light) | ✅ | ✅ Symbols | ✅ Aligned |
53
- | `Reset` | ✅ | ⚠️ Not documented | MISSING |
54
- | `Rgb(r, g, b)` | ✅ | `"#RRGGBB"` | ✅ Aligned |
55
- | `Indexed(u8)` | ✅ | Integer (0-255) | ✅ Aligned |
56
-
57
- ---
58
-
59
- ###### MISALIGNED (Breaking Changes Required)
60
-
61
- **None.** All exposed color types are correctly aligned.
62
-
63
- ---
64
-
65
- ###### MISSING — Reset Color
66
-
67
- | Ratatui | Ruby | Status |
68
- |---------|------|--------|
69
- | `Color::Reset` | ❌ Not documented | MISSING |
70
-
71
- **Impact**: Users cannot explicitly reset foreground/background to terminal default.
72
-
73
- **Recommendation**: Document `:reset` symbol support if already implemented in Rust backend, or add support if missing.
74
-
75
- ---
76
-
77
- ###### Aligned — Named Colors (Base)
78
-
79
- | Ratatui | Ruby Symbol |
80
- |---------|-------------|
81
- | `Color::Black` | `:black` |
82
- | `Color::Red` | `:red` |
83
- | `Color::Green` | `:green` |
84
- | `Color::Yellow` | `:yellow` |
85
- | `Color::Blue` | `:blue` |
86
- | `Color::Magenta` | `:magenta` |
87
- | `Color::Cyan` | `:cyan` |
88
- | `Color::Gray` | `:gray` |
89
-
90
- ---
91
-
92
- ###### Aligned — Named Colors (Light/Bright)
93
-
94
- | Ratatui | Ruby Symbol |
95
- |---------|-------------|
96
- | `Color::DarkGray` | `:dark_gray` |
97
- | `Color::LightRed` | `:light_red` |
98
- | `Color::LightGreen` | `:light_green` |
99
- | `Color::LightYellow` | `:light_yellow` |
100
- | `Color::LightBlue` | `:light_blue` |
101
- | `Color::LightMagenta` | `:light_magenta` |
102
- | `Color::LightCyan` | `:light_cyan` |
103
- | `Color::White` | `:white` |
104
-
105
- ---
106
-
107
- ###### Aligned — RGB Colors
108
-
109
- | Ratatui | Ruby |
110
- |---------|------|
111
- | `Color::Rgb(255, 0, 0)` | `"#FF0000"` |
112
- | `Color::Rgb(0, 255, 0)` | `"#00FF00"` |
113
- | `Color::Rgb(0, 0, 255)` | `"#0000FF"` |
114
-
115
- Ruby accepts hex strings in the format `"#RRGGBB"`.
116
-
117
- ---
118
-
119
- ###### Aligned — Indexed Colors (256-color palette)
120
-
121
- | Ratatui | Ruby |
122
- |---------|------|
123
- | `Color::Indexed(0)` | `0` |
124
- | `Color::Indexed(42)` | `42` |
125
- | `Color::Indexed(255)` | `255` |
126
-
127
- Ruby accepts integers 0-255 representing the Xterm 256-color palette:
128
- - 0-15: Standard and bright ANSI colors
129
- - 16-231: 6×6×6 color cube
130
- - 232-255: Grayscale ramp
131
-
132
- ---
133
-
134
- ###### Supported Modifiers
135
-
136
- Ruby supports all Ratatui style modifiers:
137
-
138
- | Ratatui | Ruby Symbol |
139
- |---------|-------------|
140
- | `Modifier::BOLD` | `:bold` |
141
- | `Modifier::DIM` | `:dim` |
142
- | `Modifier::ITALIC` | `:italic` |
143
- | `Modifier::UNDERLINED` | `:underlined` |
144
- | `Modifier::SLOW_BLINK` | `:slow_blink` |
145
- | `Modifier::RAPID_BLINK` | `:rapid_blink` |
146
- | `Modifier::REVERSED` | `:reversed` |
147
- | `Modifier::HIDDEN` | `:hidden` |
148
- | `Modifier::CROSSED_OUT` | `:crossed_out` |
149
-
150
- ---
151
-
152
- ###### Recommendations
153
-
154
- | Priority | Item | Notes |
155
- |----------|------|-------|
156
- | Low | Document `:reset` color | May already be supported |
157
-
158
- All missing items are **additive** and do not require breaking changes.
159
-
160
-
161
- ---
162
-
163
-
164
- ### alignment_audit_enums_constants
165
- ##### v0.7.0 Alignment Audit: Enums and Constants
166
-
167
- Audit of enum and constant alignment between Ratatui/Crossterm and RatatuiRuby.
168
-
169
- > [!IMPORTANT]
170
- > **MISSING** = Can be added as new features, backwards-compatible.
171
- > **MISALIGNED** = Requires breaking changes before v1.0.0.
172
22
 
173
23
  ---
174
24
 
175
- ###### Summary
176
-
177
- | Enum | Ratatui Variants | Ruby Symbols | Status |
178
- |------|------------------|--------------|--------|
179
- | `Alignment` | 3 | 3 | ✅ Aligned |
180
- | `BorderType` | 6 | 6+ | ✅ Aligned (Ruby adds `:hidden`) |
181
- | `Flex` | 6 | 6 | ✅ Aligned |
182
- | `HighlightSpacing` | 3 | 3 | ✅ Aligned |
183
- | `Borders` | 6 flags | 5 symbols | ✅ Aligned |
184
- | `GraphType` | 2 | 2 | ✅ Aligned |
185
- | `LegendPosition` | 8 | 4 | ⚠️ MISSING 4 |
186
- | `ListDirection` | 2 | 2 | ✅ Aligned |
187
- | `RenderDirection` (Sparkline) | 2 | 2 | ✅ Aligned |
188
-
189
- ---
190
-
191
- ###### MISALIGNED (Breaking Changes Required)
192
-
193
- **None.** All exposed enum values are correctly aligned.
194
-
195
- ---
196
25
 
197
- ###### MISSING — LegendPosition Variants
198
26
 
199
- | Ratatui | Ruby | Status |
200
- |---------|------|--------|
201
- | `TopLeft` | `:top_left` | ✅ |
202
- | `TopRight` | `:top_right` | ✅ |
203
- | `BottomLeft` | `:bottom_left` | ✅ |
204
- | `BottomRight` | `:bottom_right` | ✅ |
205
- | `Top` | ❌ | MISSING |
206
- | `Bottom` | ❌ | MISSING |
207
- | `Left` | ❌ | MISSING |
208
- | `Right` | ❌ | MISSING |
209
-
210
- **Impact**: Users cannot place chart legends at edge-center positions.
211
-
212
- ---
213
-
214
- ###### Aligned Enums (Detail)
215
-
216
- ###### `Alignment`
217
-
218
- | Ratatui | Ruby | Used By |
219
- |---------|------|---------|
220
- | `Left` | `:left` | Paragraph, Line, Block title |
221
- | `Center` | `:center` | Paragraph, Line, Block title |
222
- | `Right` | `:right` | Paragraph, Line, Block title |
223
-
224
- ---
225
27
 
226
- ###### `BorderType`
227
-
228
- | Ratatui | Ruby | Characters |
229
- |---------|------|------------|
230
- | `Plain` | `:plain` | `┌─┐│└┘` |
231
- | `Rounded` | `:rounded` | `╭─╮│╰╯` |
232
- | `Double` | `:double` | `╔═╗║╚╝` |
233
- | `Thick` | `:thick` | `┏━┓┃┗┛` |
234
- | `QuadrantInside` | `:quadrant_inside` | `▗▄▖▐▝▘` |
235
- | `QuadrantOutside` | `:quadrant_outside` | `▛▀▜▌▙▟` |
236
- | N/A | `:hidden` | Ruby extension (spaces) |
237
-
238
- ---
239
-
240
- ###### `Flex`
241
-
242
- | Ratatui | Ruby |
243
- |---------|------|
244
- | `Legacy` | `:legacy` |
245
- | `Start` | `:start` |
246
- | `End` | `:end` |
247
- | `Center` | `:center` |
248
- | `SpaceBetween` | `:space_between` |
249
- | `SpaceAround` | `:space_around` |
250
-
251
- ---
252
-
253
- ###### `HighlightSpacing`
254
-
255
- | Ratatui | Ruby | Used By |
256
- |---------|------|---------|
257
- | `Always` | `:always` | Table, List |
258
- | `WhenSelected` | `:when_selected` | Table, List |
259
- | `Never` | `:never` | Table, List |
260
-
261
- ---
262
-
263
- ###### `Borders` (Bitflags)
264
-
265
- | Ratatui | Ruby |
266
- |---------|------|
267
- | `NONE` | `[]` (empty array) |
268
- | `TOP` | `:top` |
269
- | `BOTTOM` | `:bottom` |
270
- | `LEFT` | `:left` |
271
- | `RIGHT` | `:right` |
272
- | `ALL` | `:all` |
273
-
274
- Ruby uses array of symbols: `borders: [:top, :bottom]` vs Ratatui's `Borders::TOP | Borders::BOTTOM`.
275
-
276
- ---
277
-
278
- ###### `GraphType`
279
-
280
- | Ratatui | Ruby |
281
- |---------|------|
282
- | `Scatter` | `:scatter` |
283
- | `Line` | `:line` |
284
-
285
- ---
286
-
287
- ###### `ListDirection`
288
-
289
- | Ratatui | Ruby |
290
- |---------|------|
291
- | `TopToBottom` | `:top_to_bottom` |
292
- | `BottomToTop` | `:bottom_to_top` |
293
-
294
- ---
295
-
296
- ###### `RenderDirection` (Sparkline)
297
-
298
- | Ratatui | Ruby |
299
- |---------|------|
300
- | `LeftToRight` | `:left_to_right` |
301
- | `RightToLeft` | `:right_to_left` |
302
-
303
- ---
304
-
305
- ###### Recommendations
306
-
307
- | Priority | Item | Notes |
308
- |----------|------|-------|
309
- | Low | Add `:top`, `:bottom`, `:left`, `:right` to `legend_position` | Edge-center legend positions |
310
-
311
- All missing items are **additive** and do not require breaking changes.
312
-
313
-
314
- ---
315
28
 
316
29
 
317
30
  ### alignment_audit_granular_level
@@ -325,29 +38,6 @@ This document audits alignment between RatatuiRuby v0.7.0 and the upstream Ratat
325
38
 
326
39
  ---
327
40
 
328
- ###### MISALIGNED (Breaking Changes Required)
329
-
330
- These require breaking changes before v1.0.0.
331
-
332
- ###### `Text::Line` — ~~Missing `style` Field~~ ✅ Fixed
333
-
334
- | Current Ruby API | Ratatui API | Status |
335
- |------------------|-------------|--------|
336
- | `Line.new(spans:, alignment:, style:)` | `Line { style, alignment, spans }` | ✅ Aligned |
337
-
338
- **Fixed in v0.7.0**: Added `style:` parameter.
339
-
340
- ---
341
-
342
- ###### `Widgets::Table` — ~~Deprecated Parameter Name~~ ✅ Fixed
343
-
344
- | Ruby Parameter | Ratatui Parameter | Status |
345
- |----------------|-------------------|--------|
346
- | `row_highlight_style:` | `row_highlight_style` | ✅ Aligned |
347
-
348
- **Fixed in v0.7.0**: Renamed `highlight_style:` → `row_highlight_style:`.
349
-
350
- ---
351
41
 
352
42
  ###### MISSING — Layout Module
353
43
 
@@ -397,13 +87,6 @@ These require breaking changes before v1.0.0.
397
87
 
398
88
  ###### `Style::Style` — Missing Parameters/Methods
399
89
 
400
- | Missing | Ratatui API | Notes |
401
- |---------|-------------|-------|
402
- | `sub_modifier` | `style.remove_modifier(Modifier::BOLD)` | Remove specific modifiers |
403
- | `underline_color` | `style.underline_color(Color::Red)` | Set underline color separately |
404
-
405
- ---
406
-
407
90
  ###### MISSING — Text Module
408
91
 
409
92
  ###### `Text::Span` — Missing Methods
@@ -430,14 +113,6 @@ These require breaking changes before v1.0.0.
430
113
 
431
114
  ---
432
115
 
433
- ###### MISSING — Widgets Module
434
-
435
- ###### `Widgets::List` — Missing Parameters
436
-
437
- | Missing Parameter | Ratatui Name | Notes |
438
- |-------------------|--------------|-------|
439
- | N/A | N/A | List is fully aligned |
440
-
441
116
  ---
442
117
 
443
118
  ###### `Widgets::Table` — Missing Row Methods (via `Widgets::Row`)
@@ -448,109 +123,76 @@ These require breaking changes before v1.0.0.
448
123
 
449
124
  ---
450
125
 
451
- ###### `Widgets::Gauge` — Widget Not Implemented
452
-
453
- Ratatui has `Gauge` and `LineGauge` widgets. These are not currently exposed in RatatuiRuby.
454
126
 
455
- ---
456
127
 
457
- ###### `Widgets::Sparkline` — Missing Parameters
128
+ ###### Widget Computation Methods — Missing
458
129
 
459
- | Missing Parameter | Ratatui Name | Notes |
460
- |-------------------|--------------|-------|
461
- | `max` | `max` | Maximum value for scaling |
462
- | `bar_set` | `bar_set` | Custom bar symbols |
130
+ These are public `&self` methods on upstream widgets that compute/query values without rendering.
463
131
 
464
- ---
132
+ | Widget | Missing Method | Ratatui API | Notes |
133
+ |--------|----------------|-------------|-------|
465
134
 
466
- ###### `Widgets::Tabs` Missing Parameters
135
+ | `List` | `len` | `list.len()` → `usize` | Number of items in the list |
136
+ | `List` | `is_empty` | `list.is_empty()` → `bool` | True if no items (`empty?` in Ruby) |
137
+ | `Canvas` | `get_point` | `canvas.get_point(x, y)` → `Option<(usize, usize)>` | Map coordinates to grid cell |
467
138
 
468
- | Missing Parameter | Ratatui Name | Notes |
469
- |-------------------|--------------|-------|
470
- | `padding` | `padding` | Padding between tabs |
471
- | `divider` | `divider` | Divider between tabs |
139
+ > [!NOTE]
140
+ > `Paragraph#line_count(width)` and `Paragraph#line_width` ARE exposed ✓
141
+ > `Tabs#width` IS exposed
472
142
 
473
143
  ---
474
144
 
475
- ###### `Widgets::Chart`Fully Aligned
145
+ ###### State Navigation Methods Missing
476
146
 
477
- Chart, Axis, and Dataset parameters are all aligned with Ratatui equivalents.
147
+ ListState and TableState have navigation helpers that are not exposed.
478
148
 
479
- ---
149
+ | State Class | Missing Method | Ratatui API | Notes |
150
+ |-------------|----------------|-------------|-------|
151
+ | `ListState` | `select_next` | `state.select_next()` | Move selection to next item |
152
+ | `ListState` | `select_previous` | `state.select_previous()` | Move selection to previous item |
153
+ | `ListState` | `select_first` | `state.select_first()` | Jump to first item |
154
+ | `ListState` | `select_last` | `state.select_last()` | Jump to last item |
480
155
 
481
- ###### MISSING Event Module (Crossterm)
156
+ | `TableState` | `selected_cell` | `state.selected_cell()` | Get (row, col) tuple |
157
+ | `TableState` | `with_selected_cell` | `state.with_selected_cell((r,c))` | Builder pattern |
158
+ | `TableState` | `select_next_column` | `state.select_next_column()` | Navigate columns |
159
+ | `TableState` | `select_previous_column` | `state.select_previous_column()` | Navigate columns |
160
+ | `TableState` | `select_first_column` | `state.select_first_column()` | Jump to first column |
161
+ | `TableState` | `select_last_column` | `state.select_last_column()` | Jump to last column |
482
162
 
483
- ###### `MediaKeyCode` — All Values Aligned
163
+ ---
484
164
 
485
- Ruby exposes all crossterm `MediaKeyCode` variants with snake_case mapping:
165
+ ###### Layout Module Additional Missing
486
166
 
487
- | Crossterm | Ruby |
488
- |-----------|------|
489
- | `Play` | `:play` / `"play"` |
490
- | `Pause` | `:media_pause` / `"media_pause"` |
491
- | `PlayPause` | `:play_pause` / `"play_pause"` |
492
- | `Reverse` | `:reverse` / `"reverse"` |
493
- | `Stop` | `:stop` / `"stop"` |
494
- | `FastForward` | `:fast_forward` / `"fast_forward"` |
495
- | `Rewind` | `:rewind` / `"rewind"` |
496
- | `TrackNext` | `:track_next` / `"track_next"` |
497
- | `TrackPrevious` | `:track_previous` / `"track_previous"` |
498
- | `Record` | `:record` / `"record"` |
499
- | `LowerVolume` | `:lower_volume` / `"lower_volume"` |
500
- | `RaiseVolume` | `:raise_volume` / `"raise_volume"` |
501
- | `MuteVolume` | `:mute_volume` / `"mute_volume"` |
167
+ | Module | Missing | Ratatui API | Notes |
168
+ |--------|---------|-------------|-------|
169
+ | `Rect` | `as_position` | `rect.as_position()` → `Position` | Convert to Position |
170
+ | `Rect` | `as_size` | `rect.as_size()` → `Size` | Convert to Size |
171
+ | `Constraint` | `apply` | `constraint.apply(length)` → `u16` | Compute constrained size |
172
+ | `Layout` | `split_with_spacers` | `layout.split_with_spacers(area)` | Returns segments AND spacers |
502
173
 
503
174
  ---
504
175
 
505
- ###### `ModifierKeyCode` — All Values Aligned
506
-
507
- Ruby exposes all crossterm `ModifierKeyCode` variants:
508
-
509
- | Crossterm | Ruby |
510
- |-----------|------|
511
- | `LeftShift` | `:left_shift` |
512
- | `LeftControl` | `:left_control` |
513
- | `LeftAlt` | `:left_alt` |
514
- | `LeftSuper` | `:left_super` |
515
- | `LeftHyper` | `:left_hyper` |
516
- | `LeftMeta` | `:left_meta` |
517
- | `RightShift` | `:right_shift` |
518
- | `RightControl` | `:right_control` |
519
- | `RightAlt` | `:right_alt` |
520
- | `RightSuper` | `:right_super` |
521
- | `RightHyper` | `:right_hyper` |
522
- | `RightMeta` | `:right_meta` |
523
- | `IsoLevel3Shift` | `:iso_level3_shift` |
524
- | `IsoLevel5Shift` | `:iso_level5_shift` |
525
176
 
526
- ---
527
177
 
528
- ###### `KeyModifiers`All Values Aligned
178
+ ###### ColorMissing Constructors
529
179
 
530
- | Crossterm | Ruby |
531
- |-----------|------|
532
- | `SHIFT` | `"shift"` |
533
- | `CONTROL` | `"ctrl"` |
534
- | `ALT` | `"alt"` |
535
- | `SUPER` | `"super"` |
536
- | `HYPER` | `"hyper"` |
537
- | `META` | `"meta"` |
180
+ | Missing | Ratatui API | Notes |
181
+ |---------|-------------|-------|
182
+ | `from_u32` | `Color::from_u32(0xRRGGBB)` | Construct from hex integer |
183
+ | `from_hsl` | `Color::from_hsl(hsl)` | Construct from HSL (requires palette feature) |
184
+ | `from_hsluv` | `Color::from_hsluv(hsluv)` | Construct from HSLuv (requires palette feature) |
538
185
 
539
186
  ---
540
187
 
541
- ###### Summary
188
+ ###### Buffer — Missing Query Methods
542
189
 
543
- | Category | Count | Priority |
544
- |----------|-------|----------|
545
- | **MISALIGNED** (breaking) | ~~2~~ 0 | All fixed in v0.7.0 |
546
- | **MISSING methods** | ~25 | Low (additive) |
547
- | **MISSING parameters** | ~10 | Low (additive) |
548
- | **MISSING widgets** | Gauge, LineGauge | Medium (new features) |
549
-
550
- ###### Pre-v1.0.0 Checklist
551
-
552
- - [x] Add `style:` parameter to `Text::Line`
553
- - [x] Rename `highlight_style:` → `row_highlight_style:` in `Widgets::Table`
190
+ | Missing Method | Ratatui API | Notes |
191
+ |----------------|-------------|-------|
192
+ | `content` | `buffer.content()` `&[Cell]` | Get all cells as slice |
193
+ | `get` | `buffer.get(x, y)` → `&Cell` | Get cell at position |
194
+ | `index_of` | `buffer.index_of(x, y)` → `usize` | Position to linear index |
195
+ | `pos_of` | `buffer.pos_of(i)` → `(u16, u16)` | Linear index to position |
554
196
 
555
197
  ---
556
198
 
@@ -564,80 +206,7 @@ This document audits strict alignment between RatatuiRuby v0.7.0 and the upstrea
564
206
  > The TUI facade API is explicitly excluded from this audit. It provides ergonomic shortcuts that intentionally diverge from Ratatui naming.
565
207
 
566
208
  ---
567
-
568
- ###### Module Structure Alignment
569
-
570
- | Rust Module | Ruby Module | Status | Notes |
571
- |-------------|-------------|--------|-------|
572
- | `ratatui::layout` | `RatatuiRuby::Layout` | ✅ Aligned | Rect, Constraint, Layout |
573
- | `ratatui::widgets` | `RatatuiRuby::Widgets` | ✅ Aligned | All widgets |
574
- | `ratatui::widgets::table` | `RatatuiRuby::Widgets` | ✅ Aligned | Row, Cell in Widgets (Rust has table submodule) |
575
- | `ratatui::style` | `RatatuiRuby::Style` | ✅ Aligned | Style, Color support |
576
- | `ratatui::text` | `RatatuiRuby::Text` | ✅ Aligned | Span, Line |
577
- | `ratatui::buffer` | `RatatuiRuby::Buffer` | ✅ Aligned | Cell for inspection |
578
-
579
209
  ---
580
-
581
- ###### Class-by-Class Audit
582
-
583
- ###### Layout Module
584
-
585
- ###### `Layout::Rect`
586
-
587
- | Attribute | Ratatui | RatatuiRuby | Status |
588
- |-----------|---------|-------------|--------|
589
- | `x` | `u16` | `Integer` | ✅ |
590
- | `y` | `u16` | `Integer` | ✅ |
591
- | `width` | `u16` | `Integer` | ✅ |
592
- | `height` | `u16` | `Integer` | ✅ |
593
-
594
- | Method | Ratatui | RatatuiRuby | Status |
595
- |--------|---------|-------------|--------|
596
- | `new(x, y, width, height)` | ✅ | ✅ | ✅ Aligned |
597
- | `contains(position)` | ✅ | `contains?(px, py)` | ✅ Aligned (Ruby uses two args) |
598
- | `intersects(other)` | ✅ | `intersects?(other)` | ✅ Aligned |
599
- | `intersection(other)` | ✅ | ✅ | ✅ Aligned |
600
- | `area()` | ✅ | ❌ Missing | Gap |
601
- | `left()`, `right()`, `top()`, `bottom()` | ✅ | ❌ Missing | Gap (trivial: `x`, `x+width`, etc.) |
602
- | `union(other)` | ✅ | ❌ Missing | Gap |
603
- | `inner(margin)` | ✅ | ❌ Missing | Gap |
604
- | `offset(offset)` | ✅ | ❌ Missing | Gap |
605
-
606
- **Verdict**: Core constructor and hit-testing aligned. Additional geometric methods are gaps for future work.
607
-
608
- ---
609
-
610
- ###### `Layout::Constraint`
611
-
612
- | Constructor | Ratatui | RatatuiRuby | Status |
613
- |-------------|---------|-------------|--------|
614
- | `Length(u16)` | ✅ | `length(v)` | ✅ Aligned |
615
- | `Percentage(u16)` | ✅ | `percentage(v)` | ✅ Aligned |
616
- | `Min(u16)` | ✅ | `min(v)` | ✅ Aligned |
617
- | `Max(u16)` | ✅ | `max(v)` | ✅ Aligned |
618
- | `Fill(u16)` | ✅ | `fill(v=1)` | ✅ Aligned |
619
- | `Ratio(u32, u32)` | ✅ | `ratio(num, denom)` | ✅ Aligned |
620
-
621
- | Batch Constructor | Ratatui | RatatuiRuby | Status |
622
- |-------------------|---------|-------------|--------|
623
- | `from_lengths([...])` | ✅ | ❌ Missing | Gap |
624
- | `from_percentages([...])` | ✅ | ❌ Missing | Gap |
625
- | `from_mins([...])` | ✅ | ❌ Missing | Gap |
626
- | `from_maxes([...])` | ✅ | ❌ Missing | Gap |
627
- | `from_fills([...])` | ✅ | ❌ Missing | Gap |
628
- | `from_ratios([...])` | ✅ | ❌ Missing | Gap |
629
-
630
- **Verdict**: All constraint variants aligned. Batch constructors are convenience gaps.
631
-
632
- ---
633
-
634
- ###### `Layout::Layout`
635
-
636
- | Attribute | Ratatui | RatatuiRuby | Status |
637
- |-----------|---------|-------------|--------|
638
- | `direction` | `:horizontal` / `:vertical` | `:horizontal` / `:vertical` | ✅ Aligned |
639
- | `constraints` | `Vec<Constraint>` | `Array<Constraint>` | ✅ Aligned |
640
- | `flex` | `Flex` enum | Symbol (`:start`, `:center`, etc.) | ✅ Aligned |
641
210
  | `margin` | `Margin` | ❌ Missing | Gap |
642
211
  | `spacing` | `u16` | ❌ Missing | Gap |
643
212
 
@@ -645,147 +214,6 @@ This document audits strict alignment between RatatuiRuby v0.7.0 and the upstrea
645
214
 
646
215
  ---
647
216
 
648
- ###### Widgets Module
649
-
650
- ###### `Widgets::Row`
651
-
652
- | Attribute | Ratatui | RatatuiRuby | Status |
653
- |-----------|---------|-------------|--------|
654
- | `cells` | `Vec<Cell>` | `Array` | ✅ Aligned |
655
- | `style` | `Style` | `Style` | ✅ Aligned |
656
- | `height` | `u16` | `Integer` | ✅ Aligned |
657
- | `top_margin` | `u16` | `Integer` | ✅ Aligned |
658
- | `bottom_margin` | `u16` | `Integer` | ✅ Aligned |
659
-
660
- **Verdict**: ✅ Fully aligned.
661
-
662
- ---
663
-
664
- ###### `Widgets::Cell`
665
-
666
- | Attribute | Ratatui | RatatuiRuby | Status |
667
- |-----------|---------|-------------|--------|
668
- | `content` | `Text` | `String`/`Span`/`Line` | ✅ Aligned |
669
- | `style` | `Style` | `Style` | ✅ Aligned |
670
-
671
- **Verdict**: ✅ Fully aligned.
672
-
673
- ---
674
-
675
- ###### `Widgets::Table`
676
-
677
- | Attribute | Ratatui | RatatuiRuby | Status |
678
- |-----------|---------|-------------|--------|
679
- | `rows` | `Vec<Row>` | `Array` | ✅ Aligned |
680
- | `header` | `Option<Row>` | `Array` or `nil` | ✅ Aligned |
681
- | `footer` | `Option<Row>` | `Array` or `nil` | ✅ Aligned |
682
- | `widths` | `Vec<Constraint>` | `Array<Constraint>` | ✅ Aligned |
683
- | `column_spacing` | `u16` | `Integer` | ✅ Aligned |
684
- | `style` | `Style` | `Style` | ✅ Aligned |
685
- | `highlight_style` | `Style` | `Style` | ✅ Aligned |
686
- | `highlight_symbol` | `Option<Text>` | `String` | ✅ Aligned |
687
- | `selected_row` | via state | `selected_row` | ✅ Aligned |
688
- | `selected_column` | via state | `selected_column` | ✅ Aligned |
689
- | `highlight_spacing` | `HighlightSpacing` | Symbol | ✅ Aligned |
690
- | `flex` | `Flex` | Symbol | ✅ Aligned |
691
- | `offset` | via state | `offset` | ✅ Aligned |
692
- | `block` | `Option<Block>` | `Block` | ✅ Aligned |
693
-
694
- **Verdict**: ✅ Fully aligned.
695
-
696
- ---
697
-
698
- ###### Style Module
699
-
700
- ###### `Style::Style`
701
-
702
- | Attribute | Ratatui | RatatuiRuby | Status |
703
- |-----------|---------|-------------|--------|
704
- | `fg` | `Option<Color>` | `Symbol`/`String`/`Integer` | ✅ Aligned |
705
- | `bg` | `Option<Color>` | `Symbol`/`String`/`Integer` | ✅ Aligned |
706
- | `add_modifier` | `Modifier` | `modifiers: Array` | ⚠️ Different API |
707
- | `sub_modifier` | `Modifier` | ❌ Missing | Gap |
708
- | `underline_color` | `Option<Color>` | ❌ Missing | Gap |
709
-
710
- **API Difference**: Ratatui uses `add_modifier(Modifier::BOLD)` and `sub_modifier()`. Ruby uses `modifiers: [:bold]` array. This is an intentional Rubyism for ergonomics while being functionally equivalent.
711
-
712
- **Verdict**: Functionally aligned with idiomatic Ruby API.
713
-
714
- ---
715
-
716
- ###### Text Module
717
-
718
- ###### `Text::Span`
719
-
720
- | Attribute | Ratatui | RatatuiRuby | Status |
721
- |-----------|---------|-------------|--------|
722
- | `content` | `Cow<str>` | `String` | ✅ Aligned |
723
- | `style` | `Style` | `Style` | ✅ Aligned |
724
-
725
- | Constructor | Ratatui | RatatuiRuby | Status |
726
- |-------------|---------|-------------|--------|
727
- | `raw(content)` | ✅ | ❌ (use `new`) | Gap (trivial) |
728
- | `styled(content, style)` | ✅ | `styled(content, style)` | ✅ Aligned |
729
-
730
- | Method | Ratatui | RatatuiRuby | Status |
731
- |--------|---------|-------------|--------|
732
- | `width()` | ✅ | ❌ Missing | Gap |
733
-
734
- **Verdict**: Core aligned. Missing `width()` instance method and `raw()` constructor.
735
-
736
- ---
737
-
738
- ###### `Text::Line`
739
-
740
- | Attribute | Ratatui | RatatuiRuby | Status |
741
- |-----------|---------|-------------|--------|
742
- | `spans` | `Vec<Span>` | `Array<Span>` | ✅ Aligned |
743
- | `style` | `Style` | ❌ Missing | Gap |
744
- | `alignment` | `Option<Alignment>` | `alignment` | ✅ Aligned |
745
-
746
- | Method | Ratatui | RatatuiRuby | Status |
747
- |--------|---------|-------------|--------|
748
- | `width()` | ✅ | ✅ | ✅ Aligned |
749
- | `left_aligned()` | ✅ | ❌ (use constructor) | Gap |
750
- | `centered()` | ✅ | ❌ (use constructor) | Gap |
751
- | `right_aligned()` | ✅ | ❌ (use constructor) | Gap |
752
-
753
- **Verdict**: Core aligned. Missing `style` field on Line (Ratatui has line-level style separate from span styles).
754
-
755
- ---
756
-
757
- ###### Buffer Module
758
-
759
- ###### `Buffer::Cell`
760
-
761
- | Attribute | Ratatui | RatatuiRuby | Status |
762
- |-----------|---------|-------------|--------|
763
- | `char` / `symbol` | `String` | `char` | ✅ Aligned |
764
- | `fg` | `Color` | `Symbol`/`String`/`Integer` | ✅ Aligned |
765
- | `bg` | `Color` | `Symbol`/`String`/`Integer` | ✅ Aligned |
766
- | `modifiers` | `Modifier` | `Array<Symbol>` | ⚠️ Ruby array vs Rust bitflags |
767
-
768
- **Verdict**: ✅ Aligned (read-only inspection).
769
-
770
- ---
771
-
772
- ###### Summary
773
-
774
- ###### Fully Aligned ✅
775
-
776
- - **Module structure**: All 5 modules map correctly
777
- - **Widgets::Row**: All 5 attributes aligned
778
- - **Widgets::Cell**: Both attributes aligned
779
- - **Widgets::Table**: All major attributes aligned
780
- - **Layout::Constraint**: All 6 variants aligned
781
- - **Layout::Rect**: Constructor and hit-testing aligned
782
-
783
- ###### Intentional Ruby Idioms ⚠️
784
-
785
- These are **not misalignments**. They are deliberate API choices that provide functional equivalence with idiomatic Ruby patterns:
786
-
787
- - **Style modifiers**: Array `[:bold, :italic]` vs Rust's `add_modifier(BOLD | ITALIC)`
788
- - **Buffer::Cell modifiers**: Same array-based approach
789
217
 
790
218
  ---
791
219
 
@@ -810,105 +238,23 @@ These are gaps that can be filled in future minor releases without breaking exis
810
238
  | `Span` | `raw()` constructor | New class method (alias for `new`) |
811
239
  | `Line` | `left_aligned()`, `centered()`, `right_aligned()` | New instance methods (fluent) |
812
240
 
813
- ###### MISALIGNED Structure (Breaking Changes Required) ⚠️
814
-
815
- > [!CAUTION]
816
- > These gaps represent **structural misalignment** where the current API shape differs from Ratatui in a way that cannot be fixed without breaking changes. **Must be addressed before v1.0.0.**
817
-
818
- | Component | Current API | Ratatui API | Required Change |
819
- |-----------|-------------|-------------|-----------------|
820
- | `Text::Line` | No `style` field | Has `style: Style` | Add `style:` parameter to `Line.new()` |
821
-
822
- **Details:**
823
-
824
- ###### `Text::Line` Missing `style` Field
825
-
826
- Ratatui's `Line` has three fields:
827
- ```rust
828
- pub struct Line<'a> {
829
- pub style: Style, // ← Missing in Ruby
830
- pub alignment: Option<Alignment>,
831
- pub spans: Vec<Span<'a>>,
832
- }
833
- ```
834
-
835
- Ruby's `Line` has only two:
836
- ```ruby
837
- class Line < Data.define(:spans, :alignment)
838
- ```
839
-
840
- **Impact**: Users cannot set a line-level style that applies uniformly across all spans. They must either:
841
- 1. Apply the same style to every span manually, or
842
- 2. Wrap the line in a styled container
843
-
844
- **Required Fix**: Add `style:` parameter to `Line.new()`. This is a **breaking change** because:
845
- - Positional argument order changes (if used positionally)
846
- - `Data.define` member list changes
847
-
848
- **Recommendation**: Fix in v0.8.0 or earlier, before v1.0.0 API freeze.
849
-
850
- ---
851
-
852
- ###### Conclusion
853
-
854
- The v0.7.0 namespace restructuring achieves **strict alignment** with Ratatui's module hierarchy as specified in the design principles. All new types (`Widgets::Row`, `Widgets::Cell`, `Buffer::Cell`) follow the established pattern.
855
-
856
- ###### Release Guidance
857
-
858
- | Category | Count | Action |
859
- |----------|-------|--------|
860
- | **Fully Aligned** | 6 components | ✅ No action needed |
861
- | **Intentional Idioms** | 2 items | ✅ Document as Ruby conventions |
862
- | **MISSING (additive)** | 14 features | 📋 Add in future minor releases |
863
- | **MISALIGNED (breaking)** | 1 issue | ⚠️ **Must fix before v1.0.0** |
864
-
865
- The single misalignment (`Text::Line` missing `style` field) is the only blocking issue for v1.0.0 API stability. All other gaps are additive and can be addressed incrementally.
866
-
867
- ---
868
241
 
869
242
 
870
243
  ### alignment_audit_symbol_sets
871
- ##### v0.7.0 Alignment Audit: Symbol Sets
872
-
873
244
  Audit of symbol set alignment between Ratatui's `symbols::` module and RatatuiRuby.
874
245
 
875
246
  > [!IMPORTANT]
876
247
  > **MISSING** = Can be added as new features, backwards-compatible.
877
248
  > **MISALIGNED** = Requires breaking changes before v1.0.0.
878
249
 
879
- ---
880
-
881
- ###### Summary
882
-
883
- | Symbol Category | Ratatui | RatatuiRuby | Status |
884
- |-----------------|---------|-------------|--------|
885
- | `Marker` enum | 5 variants | 4 exposed | ⚠️ MISSING 1 |
886
- | `border::Set` | 12 predefined sets | Via `border_type:` symbols | ✅ Aligned |
887
- | Custom `border::Set` | Custom struct | Via `border_set:` hash | ✅ Aligned |
888
- | `line::Set` | 4 predefined sets | ❌ Not exposed | MISSING |
889
- | `bar::Set` | 2 predefined sets | ❌ Not exposed | MISSING |
890
- | `block::Set` | 2 predefined sets | ❌ Not exposed | MISSING |
891
250
  | `scrollbar::Set` | 4 predefined sets | ❌ Not exposed | MISSING |
892
251
  | `shade` constants | 5 constants | ❌ Not exposed | MISSING |
893
252
 
894
- ---
895
-
896
- ###### MISALIGNED (Breaking Changes Required)
897
-
898
- **None.** All exposed symbol sets are correctly aligned.
899
-
900
- ---
901
253
 
902
254
  ###### MISSING — Marker Enum
903
255
 
904
256
  ###### `Marker::HalfBlock`
905
257
 
906
- | Ratatui | RatatuiRuby | Status |
907
- |---------|-------------|--------|
908
- | `Marker::Dot` | `:dot` | ✅ |
909
- | `Marker::Block` | `:block` | ✅ |
910
- | `Marker::Bar` | `:bar` | ✅ |
911
- | `Marker::Braille` | `:braille` | ✅ |
912
258
  | `Marker::HalfBlock` | ❌ Not exposed | MISSING |
913
259
 
914
260
  **Impact**: Users cannot use the `HalfBlock` marker type, which provides double-resolution square pixels using `█`, `▄`, and `▀` characters.
@@ -966,46 +312,7 @@ Ratatui provides `symbols::shade` constants:
966
312
  - `LIGHT` — `░`
967
313
  - `MEDIUM` — `▒`
968
314
  - `DARK` — `▓`
969
- - `FULL` — `█`
970
-
971
- **Ruby Status**: Not exposed as constants.
972
-
973
- ---
974
-
975
- ###### Currently Aligned
976
-
977
- ###### `border_type:` Parameter
978
-
979
- Ruby's `Block.new(border_type:)` maps to Ratatui's `border::Set`:
980
-
981
- | Ruby Symbol | Ratatui Constant | Characters |
982
- |-------------|------------------|------------|
983
- | `:plain` | `border::PLAIN` | `┌─┐│└┘` |
984
- | `:rounded` | `border::ROUNDED` | `╭─╮│╰╯` |
985
- | `:double` | `border::DOUBLE` | `╔═╗║╚╝` |
986
- | `:thick` | `border::THICK` | `┏━┓┃┗┛` |
987
- | `:quadrant_outside` | `border::QUADRANT_OUTSIDE` | `▛▀▜▌▙▟` |
988
- | `:quadrant_inside` | `border::QUADRANT_INSIDE` | `▗▄▖▐▝▘` |
989
- | `:hidden` | ❌ Custom Ruby | Empty borders (spaces) |
990
-
991
- ###### `border_set:` Parameter
992
-
993
- Ruby supports custom border characters via hash:
994
-
995
- ```ruby
996
- Block.new(border_set: {
997
- top_left: "╭",
998
- top_right: "╮",
999
- bottom_left: "╰",
1000
- bottom_right: "╯",
1001
- vertical_left: "│",
1002
- vertical_right: "│",
1003
- horizontal_top: "─",
1004
- horizontal_bottom: "─"
1005
- })
1006
- ```
1007
315
 
1008
- This is functionally equivalent to Ratatui's custom `border::Set`.
1009
316
 
1010
317
  ---
1011
318