ratatui_ruby 0.9.1 → 0.10.1
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.
- checksums.yaml +4 -4
- data/.builds/ruby-3.2.yml +1 -1
- data/.builds/ruby-3.3.yml +1 -1
- data/.builds/ruby-3.4.yml +1 -1
- data/.builds/ruby-4.0.0.yml +1 -1
- data/AGENTS.md +2 -1
- data/CHANGELOG.md +113 -0
- data/README.md +17 -0
- data/REUSE.toml +5 -0
- data/Rakefile +1 -1
- data/Steepfile +49 -0
- data/doc/concepts/debugging.md +401 -0
- data/doc/getting_started/quickstart.md +8 -3
- data/doc/images/app_all_events.png +0 -0
- data/doc/images/app_color_picker.png +0 -0
- data/doc/images/app_debugging_showcase.gif +0 -0
- data/doc/images/app_debugging_showcase.png +0 -0
- data/doc/images/app_login_form.png +0 -0
- data/doc/images/app_stateful_interaction.png +0 -0
- data/doc/images/verify_quickstart_dsl.png +0 -0
- data/doc/images/verify_quickstart_layout.png +0 -0
- data/doc/images/verify_quickstart_lifecycle.png +0 -0
- data/doc/images/verify_readme_usage.png +0 -0
- data/doc/images/widget_barchart.png +0 -0
- data/doc/images/widget_block.png +0 -0
- data/doc/images/widget_box.png +0 -0
- data/doc/images/widget_calendar.png +0 -0
- data/doc/images/widget_canvas.png +0 -0
- data/doc/images/widget_cell.png +0 -0
- data/doc/images/widget_center.png +0 -0
- data/doc/images/widget_chart.png +0 -0
- data/doc/images/widget_gauge.png +0 -0
- data/doc/images/widget_layout_split.png +0 -0
- data/doc/images/widget_line_gauge.png +0 -0
- data/doc/images/widget_list.png +0 -0
- data/doc/images/widget_map.png +0 -0
- data/doc/images/widget_overlay.png +0 -0
- data/doc/images/widget_popup.png +0 -0
- data/doc/images/widget_ratatui_logo.png +0 -0
- data/doc/images/widget_ratatui_mascot.png +0 -0
- data/doc/images/widget_rect.png +0 -0
- data/doc/images/widget_render.png +0 -0
- data/doc/images/widget_rich_text.png +0 -0
- data/doc/images/widget_scroll_text.png +0 -0
- data/doc/images/widget_scrollbar.png +0 -0
- data/doc/images/widget_sparkline.png +0 -0
- data/doc/images/widget_style_colors.png +0 -0
- data/doc/images/widget_table.png +0 -0
- data/doc/images/widget_tabs.png +0 -0
- data/doc/images/widget_text_width.png +0 -0
- data/doc/troubleshooting/async.md +4 -0
- data/examples/app_debugging_showcase/README.md +119 -0
- data/examples/app_debugging_showcase/app.rb +318 -0
- data/examples/widget_canvas/app.rb +19 -14
- data/examples/widget_gauge/app.rb +18 -3
- data/examples/widget_layout_split/app.rb +10 -4
- data/examples/widget_list/app.rb +22 -6
- data/examples/widget_rect/app.rb +7 -6
- data/examples/widget_rich_text/app.rb +62 -37
- data/examples/widget_style_colors/app.rb +26 -47
- data/examples/widget_table/app.rb +28 -5
- data/examples/widget_text_width/app.rb +6 -4
- data/ext/ratatui_ruby/Cargo.lock +48 -1
- data/ext/ratatui_ruby/Cargo.toml +6 -2
- data/ext/ratatui_ruby/src/color.rs +82 -0
- data/ext/ratatui_ruby/src/errors.rs +28 -0
- data/ext/ratatui_ruby/src/events.rs +15 -14
- data/ext/ratatui_ruby/src/lib.rs +56 -0
- data/ext/ratatui_ruby/src/rendering.rs +3 -1
- data/ext/ratatui_ruby/src/style.rs +48 -21
- data/ext/ratatui_ruby/src/terminal.rs +40 -9
- data/ext/ratatui_ruby/src/text.rs +21 -9
- data/ext/ratatui_ruby/src/widgets/chart.rs +2 -1
- data/ext/ratatui_ruby/src/widgets/layout.rs +90 -2
- data/ext/ratatui_ruby/src/widgets/list.rs +6 -5
- data/ext/ratatui_ruby/src/widgets/overlay.rs +2 -1
- data/ext/ratatui_ruby/src/widgets/table.rs +7 -6
- data/ext/ratatui_ruby/src/widgets/table_state.rs +55 -0
- data/ext/ratatui_ruby/src/widgets/tabs.rs +3 -2
- data/lib/ratatui_ruby/buffer/cell.rb +25 -15
- data/lib/ratatui_ruby/buffer.rb +134 -2
- data/lib/ratatui_ruby/cell.rb +13 -5
- data/lib/ratatui_ruby/debug.rb +215 -0
- data/lib/ratatui_ruby/event/key.rb +3 -2
- data/lib/ratatui_ruby/event.rb +1 -1
- data/lib/ratatui_ruby/layout/constraint.rb +49 -0
- data/lib/ratatui_ruby/layout/layout.rb +119 -13
- data/lib/ratatui_ruby/layout/position.rb +55 -0
- data/lib/ratatui_ruby/layout/rect.rb +188 -0
- data/lib/ratatui_ruby/layout/size.rb +55 -0
- data/lib/ratatui_ruby/layout.rb +4 -0
- data/lib/ratatui_ruby/style/color.rb +149 -0
- data/lib/ratatui_ruby/style/style.rb +51 -4
- data/lib/ratatui_ruby/style.rb +2 -0
- data/lib/ratatui_ruby/symbols.rb +435 -0
- data/lib/ratatui_ruby/synthetic_events.rb +1 -1
- data/lib/ratatui_ruby/table_state.rb +51 -0
- data/lib/ratatui_ruby/terminal_lifecycle.rb +2 -1
- data/lib/ratatui_ruby/test_helper/event_injection.rb +6 -1
- data/lib/ratatui_ruby/test_helper.rb +9 -0
- data/lib/ratatui_ruby/text/line.rb +245 -0
- data/lib/ratatui_ruby/text/span.rb +158 -0
- data/lib/ratatui_ruby/text.rb +99 -0
- data/lib/ratatui_ruby/tui/canvas_factories.rb +103 -0
- data/lib/ratatui_ruby/tui/core.rb +13 -2
- data/lib/ratatui_ruby/tui/layout_factories.rb +50 -3
- data/lib/ratatui_ruby/tui/state_factories.rb +42 -0
- data/lib/ratatui_ruby/tui/text_factories.rb +40 -0
- data/lib/ratatui_ruby/tui/widget_factories.rb +135 -60
- data/lib/ratatui_ruby/tui.rb +22 -1
- data/lib/ratatui_ruby/version.rb +1 -1
- data/lib/ratatui_ruby/widgets/bar_chart/bar.rb +2 -0
- data/lib/ratatui_ruby/widgets/bar_chart/bar_group.rb +2 -0
- data/lib/ratatui_ruby/widgets/bar_chart.rb +30 -20
- data/lib/ratatui_ruby/widgets/block.rb +14 -6
- data/lib/ratatui_ruby/widgets/calendar.rb +2 -0
- data/lib/ratatui_ruby/widgets/canvas.rb +56 -0
- data/lib/ratatui_ruby/widgets/cell.rb +2 -0
- data/lib/ratatui_ruby/widgets/center.rb +2 -0
- data/lib/ratatui_ruby/widgets/chart.rb +6 -0
- data/lib/ratatui_ruby/widgets/clear.rb +2 -0
- data/lib/ratatui_ruby/widgets/coerceable_widget.rb +77 -0
- data/lib/ratatui_ruby/widgets/cursor.rb +2 -0
- data/lib/ratatui_ruby/widgets/gauge.rb +61 -3
- data/lib/ratatui_ruby/widgets/line_gauge.rb +66 -4
- data/lib/ratatui_ruby/widgets/list.rb +87 -3
- data/lib/ratatui_ruby/widgets/list_item.rb +2 -0
- data/lib/ratatui_ruby/widgets/overlay.rb +2 -0
- data/lib/ratatui_ruby/widgets/paragraph.rb +4 -0
- data/lib/ratatui_ruby/widgets/ratatui_logo.rb +2 -0
- data/lib/ratatui_ruby/widgets/ratatui_mascot.rb +2 -0
- data/lib/ratatui_ruby/widgets/row.rb +45 -0
- data/lib/ratatui_ruby/widgets/scrollbar.rb +2 -0
- data/lib/ratatui_ruby/widgets/shape/label.rb +2 -0
- data/lib/ratatui_ruby/widgets/sparkline.rb +21 -13
- data/lib/ratatui_ruby/widgets/table.rb +13 -3
- data/lib/ratatui_ruby/widgets/tabs.rb +6 -4
- data/lib/ratatui_ruby/widgets.rb +1 -0
- data/lib/ratatui_ruby.rb +42 -11
- data/sig/examples/app_all_events/model/app_model.rbs +23 -0
- data/sig/examples/app_all_events/model/event_entry.rbs +15 -8
- data/sig/examples/app_all_events/model/timestamp.rbs +1 -1
- data/sig/examples/app_all_events/view.rbs +1 -1
- data/sig/examples/app_stateful_interaction/app.rbs +5 -5
- data/sig/examples/widget_block_demo/app.rbs +6 -6
- data/sig/manifest.yaml +5 -0
- data/sig/patches/data.rbs +26 -0
- data/sig/patches/debugger__.rbs +8 -0
- data/sig/ratatui_ruby/buffer/cell.rbs +46 -0
- data/sig/ratatui_ruby/buffer.rbs +18 -0
- data/sig/ratatui_ruby/cell.rbs +44 -0
- data/sig/ratatui_ruby/clear.rbs +18 -0
- data/sig/ratatui_ruby/constraint.rbs +26 -0
- data/sig/ratatui_ruby/debug.rbs +45 -0
- data/sig/ratatui_ruby/draw.rbs +30 -0
- data/sig/ratatui_ruby/event.rbs +68 -8
- data/sig/ratatui_ruby/frame.rbs +4 -4
- data/sig/ratatui_ruby/interfaces.rbs +25 -0
- data/sig/ratatui_ruby/layout/constraint.rbs +39 -0
- data/sig/ratatui_ruby/layout/layout.rbs +45 -0
- data/sig/ratatui_ruby/layout/position.rbs +18 -0
- data/sig/ratatui_ruby/layout/rect.rbs +64 -0
- data/sig/ratatui_ruby/layout/size.rbs +18 -0
- data/sig/ratatui_ruby/output_guard.rbs +23 -0
- data/sig/ratatui_ruby/ratatui_ruby.rbs +84 -5
- data/sig/ratatui_ruby/rect.rbs +17 -0
- data/sig/ratatui_ruby/style/color.rbs +22 -0
- data/sig/ratatui_ruby/style/style.rbs +29 -0
- data/sig/ratatui_ruby/symbols.rbs +141 -0
- data/sig/ratatui_ruby/synthetic_events.rbs +21 -0
- data/sig/ratatui_ruby/table_state.rbs +6 -0
- data/sig/ratatui_ruby/terminal_lifecycle.rbs +31 -0
- data/sig/ratatui_ruby/test_helper/event_injection.rbs +2 -2
- data/sig/ratatui_ruby/test_helper/snapshot.rbs +22 -3
- data/sig/ratatui_ruby/test_helper/style_assertions.rbs +8 -1
- data/sig/ratatui_ruby/test_helper/test_doubles.rbs +7 -3
- data/sig/ratatui_ruby/text/line.rbs +27 -0
- data/sig/ratatui_ruby/text/span.rbs +23 -0
- data/sig/ratatui_ruby/text.rbs +12 -0
- data/sig/ratatui_ruby/tui/buffer_factories.rbs +1 -1
- data/sig/ratatui_ruby/tui/canvas_factories.rbs +23 -5
- data/sig/ratatui_ruby/tui/core.rbs +2 -2
- data/sig/ratatui_ruby/tui/layout_factories.rbs +16 -2
- data/sig/ratatui_ruby/tui/state_factories.rbs +8 -3
- data/sig/ratatui_ruby/tui/style_factories.rbs +3 -1
- data/sig/ratatui_ruby/tui/text_factories.rbs +7 -4
- data/sig/ratatui_ruby/tui/widget_factories.rbs +123 -30
- data/sig/ratatui_ruby/widgets/bar_chart.rbs +95 -0
- data/sig/ratatui_ruby/widgets/block.rbs +51 -0
- data/sig/ratatui_ruby/widgets/calendar.rbs +45 -0
- data/sig/ratatui_ruby/widgets/canvas.rbs +95 -0
- data/sig/ratatui_ruby/widgets/chart.rbs +91 -0
- data/sig/ratatui_ruby/widgets/coerceable_widget.rbs +26 -0
- data/sig/ratatui_ruby/widgets/gauge.rbs +44 -0
- data/sig/ratatui_ruby/widgets/line_gauge.rbs +48 -0
- data/sig/ratatui_ruby/widgets/list.rbs +63 -0
- data/sig/ratatui_ruby/widgets/misc.rbs +158 -0
- data/sig/ratatui_ruby/widgets/paragraph.rbs +45 -0
- data/sig/ratatui_ruby/widgets/row.rbs +43 -0
- data/sig/ratatui_ruby/widgets/scrollbar.rbs +53 -0
- data/sig/ratatui_ruby/widgets/shape/label.rbs +37 -0
- data/sig/ratatui_ruby/widgets/sparkline.rbs +45 -0
- data/sig/ratatui_ruby/widgets/table.rbs +78 -0
- data/sig/ratatui_ruby/widgets/tabs.rbs +44 -0
- data/sig/ratatui_ruby/{schema/list_item.rbs → widgets.rbs} +4 -4
- data/tasks/steep.rake +11 -0
- metadata +80 -63
- data/doc/contributors/v1.0.0_blockers.md +0 -870
- data/doc/troubleshooting/debugging.md +0 -101
- data/lib/ratatui_ruby/schema/bar_chart/bar.rb +0 -47
- data/lib/ratatui_ruby/schema/bar_chart/bar_group.rb +0 -25
- data/lib/ratatui_ruby/schema/bar_chart.rb +0 -287
- data/lib/ratatui_ruby/schema/block.rb +0 -198
- data/lib/ratatui_ruby/schema/calendar.rb +0 -84
- data/lib/ratatui_ruby/schema/canvas.rb +0 -239
- data/lib/ratatui_ruby/schema/center.rb +0 -67
- data/lib/ratatui_ruby/schema/chart.rb +0 -159
- data/lib/ratatui_ruby/schema/clear.rb +0 -62
- data/lib/ratatui_ruby/schema/constraint.rb +0 -151
- data/lib/ratatui_ruby/schema/cursor.rb +0 -50
- data/lib/ratatui_ruby/schema/gauge.rb +0 -72
- data/lib/ratatui_ruby/schema/layout.rb +0 -122
- data/lib/ratatui_ruby/schema/line_gauge.rb +0 -80
- data/lib/ratatui_ruby/schema/list.rb +0 -135
- data/lib/ratatui_ruby/schema/list_item.rb +0 -51
- data/lib/ratatui_ruby/schema/overlay.rb +0 -51
- data/lib/ratatui_ruby/schema/paragraph.rb +0 -107
- data/lib/ratatui_ruby/schema/ratatui_logo.rb +0 -31
- data/lib/ratatui_ruby/schema/ratatui_mascot.rb +0 -36
- data/lib/ratatui_ruby/schema/rect.rb +0 -174
- data/lib/ratatui_ruby/schema/row.rb +0 -76
- data/lib/ratatui_ruby/schema/scrollbar.rb +0 -143
- data/lib/ratatui_ruby/schema/shape/label.rb +0 -76
- data/lib/ratatui_ruby/schema/sparkline.rb +0 -142
- data/lib/ratatui_ruby/schema/style.rb +0 -97
- data/lib/ratatui_ruby/schema/table.rb +0 -141
- data/lib/ratatui_ruby/schema/tabs.rb +0 -85
- data/lib/ratatui_ruby/schema/text.rb +0 -217
- data/sig/examples/app_all_events/model/events.rbs +0 -15
- data/sig/examples/app_all_events/view_state.rbs +0 -21
- data/sig/ratatui_ruby/schema/bar_chart/bar.rbs +0 -22
- data/sig/ratatui_ruby/schema/bar_chart/bar_group.rbs +0 -19
- data/sig/ratatui_ruby/schema/bar_chart.rbs +0 -38
- data/sig/ratatui_ruby/schema/block.rbs +0 -18
- data/sig/ratatui_ruby/schema/calendar.rbs +0 -23
- data/sig/ratatui_ruby/schema/canvas.rbs +0 -81
- data/sig/ratatui_ruby/schema/center.rbs +0 -17
- data/sig/ratatui_ruby/schema/chart.rbs +0 -39
- data/sig/ratatui_ruby/schema/constraint.rbs +0 -30
- data/sig/ratatui_ruby/schema/cursor.rbs +0 -16
- data/sig/ratatui_ruby/schema/draw.rbs +0 -33
- data/sig/ratatui_ruby/schema/gauge.rbs +0 -23
- data/sig/ratatui_ruby/schema/layout.rbs +0 -27
- data/sig/ratatui_ruby/schema/line_gauge.rbs +0 -24
- data/sig/ratatui_ruby/schema/list.rbs +0 -28
- data/sig/ratatui_ruby/schema/overlay.rbs +0 -15
- data/sig/ratatui_ruby/schema/paragraph.rbs +0 -20
- data/sig/ratatui_ruby/schema/ratatui_logo.rbs +0 -14
- data/sig/ratatui_ruby/schema/ratatui_mascot.rbs +0 -17
- data/sig/ratatui_ruby/schema/rect.rbs +0 -48
- data/sig/ratatui_ruby/schema/row.rbs +0 -28
- data/sig/ratatui_ruby/schema/scrollbar.rbs +0 -42
- data/sig/ratatui_ruby/schema/sparkline.rbs +0 -22
- data/sig/ratatui_ruby/schema/style.rbs +0 -19
- data/sig/ratatui_ruby/schema/table.rbs +0 -32
- data/sig/ratatui_ruby/schema/tabs.rbs +0 -21
- data/sig/ratatui_ruby/schema/text.rbs +0 -31
- /data/lib/ratatui_ruby/{schema/draw.rb → draw.rb} +0 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
6
|
+
#++
|
|
7
|
+
|
|
8
|
+
module RatatuiRuby
|
|
9
|
+
module Style
|
|
10
|
+
# Color constructors for creating RGB color values.
|
|
11
|
+
#
|
|
12
|
+
# Styles accept colors in multiple formats: symbols (<tt>:red</tt>),
|
|
13
|
+
# indexed integers (0-255), or hex strings (<tt>"#FF0000"</tt>).
|
|
14
|
+
# Converting from other color representations manually is tedious.
|
|
15
|
+
#
|
|
16
|
+
# This module provides factory methods matching Ratatui's Color API.
|
|
17
|
+
# Convert from hex integers, HSL, or other formats in a single call.
|
|
18
|
+
#
|
|
19
|
+
# Use these constructors when you have color data in non-standard formats.
|
|
20
|
+
#
|
|
21
|
+
# === Example
|
|
22
|
+
#
|
|
23
|
+
#--
|
|
24
|
+
# SPDX-SnippetBegin
|
|
25
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
26
|
+
# SPDX-License-Identifier: MIT-0
|
|
27
|
+
#++
|
|
28
|
+
# # From a hex integer (common in design tools)
|
|
29
|
+
# red = Style::Color.from_u32(0xFF0000)
|
|
30
|
+
# style = Style::Style.new(fg: red)
|
|
31
|
+
#
|
|
32
|
+
# # From HSL (common in color pickers)
|
|
33
|
+
# blue = Style::Color.from_hsl(240, 100, 50)
|
|
34
|
+
# style = Style::Style.new(bg: blue)
|
|
35
|
+
#--
|
|
36
|
+
# SPDX-SnippetEnd
|
|
37
|
+
#++
|
|
38
|
+
module Color
|
|
39
|
+
class << self
|
|
40
|
+
# Creates a color from a 32-bit unsigned integer.
|
|
41
|
+
#
|
|
42
|
+
# Design tools and APIs often represent colors as hex integers.
|
|
43
|
+
# Manually extracting RGB components and formatting is error-prone.
|
|
44
|
+
#
|
|
45
|
+
# This method parses the integer and returns a hex string
|
|
46
|
+
# ready for use with Style.
|
|
47
|
+
#
|
|
48
|
+
# === Example
|
|
49
|
+
#
|
|
50
|
+
#--
|
|
51
|
+
# SPDX-SnippetBegin
|
|
52
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
53
|
+
# SPDX-License-Identifier: MIT-0
|
|
54
|
+
#++
|
|
55
|
+
# Color.from_u32(0xFF0000) # => "#ff0000" (red)
|
|
56
|
+
# Color.from_u32(0x00FF00) # => "#00ff00" (green)
|
|
57
|
+
# Color.from_u32(0x0000FF) # => "#0000ff" (blue)
|
|
58
|
+
#--
|
|
59
|
+
# SPDX-SnippetEnd
|
|
60
|
+
#++
|
|
61
|
+
#
|
|
62
|
+
# [value] Integer in <tt>0xRRGGBB</tt> format.
|
|
63
|
+
#
|
|
64
|
+
# Returns a hex string like <tt>"#rrggbb"</tt>.
|
|
65
|
+
def from_u32(value)
|
|
66
|
+
RatatuiRuby._color_from_u32(value)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Creates a color from HSL (Hue, Saturation, Lightness) values.
|
|
70
|
+
#
|
|
71
|
+
# Color pickers often use HSL because it matches human perception
|
|
72
|
+
# better than RGB. Converting HSL to RGB manually requires math.
|
|
73
|
+
#
|
|
74
|
+
# This method handles the conversion by delegating to Ratatui's
|
|
75
|
+
# palette integration.
|
|
76
|
+
#
|
|
77
|
+
# Note: This implementation uses degrees (0-360) for hue and
|
|
78
|
+
# percentages (0-100) for saturation and lightness, matching
|
|
79
|
+
# common UI conventions.
|
|
80
|
+
#
|
|
81
|
+
# === Example
|
|
82
|
+
#
|
|
83
|
+
#--
|
|
84
|
+
# SPDX-SnippetBegin
|
|
85
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
86
|
+
# SPDX-License-Identifier: MIT-0
|
|
87
|
+
#++
|
|
88
|
+
# Color.from_hsl(0, 100, 50) # => "#ff0000" (red)
|
|
89
|
+
# Color.from_hsl(120, 100, 50) # => "#00ff00" (green)
|
|
90
|
+
# Color.from_hsl(240, 100, 50) # => "#0000ff" (blue)
|
|
91
|
+
# Color.from_hsl(0, 0, 50) # => "#808080" (gray)
|
|
92
|
+
#--
|
|
93
|
+
# SPDX-SnippetEnd
|
|
94
|
+
#++
|
|
95
|
+
#
|
|
96
|
+
# [h] Hue in degrees (0-360). Values wrap automatically.
|
|
97
|
+
# [s] Saturation as percentage (0-100).
|
|
98
|
+
# [l] Lightness as percentage (0-100).
|
|
99
|
+
#
|
|
100
|
+
# Returns a hex string like <tt>"#rrggbb"</tt>.
|
|
101
|
+
def from_hsl(h, s, l)
|
|
102
|
+
RatatuiRuby._color_from_hsl(h.to_f, s.to_f, l.to_f)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Ruby-idiomatic aliases (TIMTOWTDI)
|
|
106
|
+
alias hex from_u32
|
|
107
|
+
alias hsl from_hsl
|
|
108
|
+
|
|
109
|
+
# Creates a color from HSLuv (Human-friendly Hue, Saturation, Lightness) values.
|
|
110
|
+
#
|
|
111
|
+
# HSLuv is a perceptually uniform color space. Unlike standard HSL,
|
|
112
|
+
# colors at the same lightness appear equally bright regardless of hue.
|
|
113
|
+
# This makes it ideal for generating color palettes with consistent
|
|
114
|
+
# perceived brightness.
|
|
115
|
+
#
|
|
116
|
+
# This method delegates to Ratatui's palette integration for the
|
|
117
|
+
# complex HSLuv to RGB conversion.
|
|
118
|
+
#
|
|
119
|
+
# Note: Ratatui uses the range [-180, 180] for hue and [0, 100] for
|
|
120
|
+
# saturation and lightness. This implementation matches those conventions.
|
|
121
|
+
#
|
|
122
|
+
# === Example
|
|
123
|
+
#
|
|
124
|
+
#--
|
|
125
|
+
# SPDX-SnippetBegin
|
|
126
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
127
|
+
# SPDX-License-Identifier: MIT-0
|
|
128
|
+
#++
|
|
129
|
+
# Color.from_hsluv(12.18, 100, 53.2) # => "#ff0000" (bright red)
|
|
130
|
+
# Color.from_hsluv(-94.13, 100, 32.3) # => "#0000ff" (bright blue)
|
|
131
|
+
# Color.from_hsluv(0, 0, 50) # => gray
|
|
132
|
+
#--
|
|
133
|
+
# SPDX-SnippetEnd
|
|
134
|
+
#++
|
|
135
|
+
#
|
|
136
|
+
# [h] Hue in degrees (-180 to 360). Values wrap automatically.
|
|
137
|
+
# [s] Saturation as percentage (0-100). Values are clamped.
|
|
138
|
+
# [l] Lightness as percentage (0-100). Values are clamped.
|
|
139
|
+
#
|
|
140
|
+
# Returns a hex string like <tt>"#rrggbb"</tt>.
|
|
141
|
+
def from_hsluv(h, s, l)
|
|
142
|
+
RatatuiRuby._color_from_hsluv(h.to_f, s.to_f, l.to_f)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
alias hsluv from_hsluv
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
@@ -60,7 +60,7 @@ module RatatuiRuby
|
|
|
60
60
|
# ==== String
|
|
61
61
|
# Represents a specific RGB color using a Hex code (<tt>"#RRGGBB"</tt>).
|
|
62
62
|
# Requires a terminal emulator with "True Color" (24-bit color) support.
|
|
63
|
-
class Style < Data.define(:fg, :bg, :modifiers)
|
|
63
|
+
class Style < Data.define(:fg, :bg, :underline_color, :modifiers, :remove_modifiers)
|
|
64
64
|
##
|
|
65
65
|
# :attr_reader: fg
|
|
66
66
|
# Foreground color.
|
|
@@ -73,19 +73,36 @@ module RatatuiRuby
|
|
|
73
73
|
#
|
|
74
74
|
# Symbol (<tt>:black</tt>), Hex String (<tt>"#000000"</tt>), or Integer (0-255).
|
|
75
75
|
|
|
76
|
+
##
|
|
77
|
+
# :attr_reader: underline_color
|
|
78
|
+
# Color of the underline.
|
|
79
|
+
#
|
|
80
|
+
# Symbol (<tt>:red</tt>), Hex String (<tt>"#ff0000"</tt>), or Integer (0-255).
|
|
81
|
+
# Distinct from foreground color. Terminals supporting this feature render
|
|
82
|
+
# the underline in this color while text remains in the foreground color.
|
|
83
|
+
|
|
76
84
|
##
|
|
77
85
|
# :attr_reader: modifiers
|
|
78
|
-
# Text effects.
|
|
86
|
+
# Text effects to add.
|
|
79
87
|
#
|
|
80
88
|
# Array of symbols: <tt>:bold</tt>, <tt>:dim</tt>, <tt>:italic</tt>, <tt>:underlined</tt>,
|
|
81
89
|
# <tt>:slow_blink</tt>, <tt>:rapid_blink</tt>, <tt>:reversed</tt>, <tt>:hidden</tt>, <tt>:crossed_out</tt>.
|
|
82
90
|
|
|
91
|
+
##
|
|
92
|
+
# :attr_reader: remove_modifiers
|
|
93
|
+
# Text effects to remove.
|
|
94
|
+
#
|
|
95
|
+
# Array of symbols. When this style is applied, these modifiers are removed
|
|
96
|
+
# from any inherited/patched styles. Corresponds to Ratatui's sub_modifier.
|
|
97
|
+
|
|
83
98
|
# Creates a new Style.
|
|
84
99
|
#
|
|
85
100
|
# [fg] Color (Symbol/String/Integer).
|
|
86
101
|
# [bg] Color (Symbol/String/Integer).
|
|
87
|
-
# [
|
|
88
|
-
|
|
102
|
+
# [underline_color] Color for underline (Symbol/String/Integer).
|
|
103
|
+
# [modifiers] Array of Symbols to add.
|
|
104
|
+
# [remove_modifiers] Array of Symbols to remove (Ratatui: sub_modifier).
|
|
105
|
+
def initialize(fg: nil, bg: nil, underline_color: nil, modifiers: [], remove_modifiers: [])
|
|
89
106
|
super
|
|
90
107
|
end
|
|
91
108
|
|
|
@@ -95,6 +112,36 @@ module RatatuiRuby
|
|
|
95
112
|
def self.default
|
|
96
113
|
new
|
|
97
114
|
end
|
|
115
|
+
|
|
116
|
+
# Creates a new Style (convenience alias for {#initialize}).
|
|
117
|
+
#
|
|
118
|
+
# Constructor keyword arguments require typing out the full <tt>Style.new</tt> form.
|
|
119
|
+
# This gets verbose in tight layout code or one-liners.
|
|
120
|
+
#
|
|
121
|
+
# <tt>Style.with</tt> reads more naturally and enables method chaining.
|
|
122
|
+
# It shows intent: "use this style with these properties."
|
|
123
|
+
#
|
|
124
|
+
# Use it for inline styling where conciseness matters.
|
|
125
|
+
#
|
|
126
|
+
# === Examples
|
|
127
|
+
#
|
|
128
|
+
#--
|
|
129
|
+
# SPDX-SnippetBegin
|
|
130
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
131
|
+
# SPDX-License-Identifier: MIT-0
|
|
132
|
+
#++
|
|
133
|
+
# Style.with(fg: :red, bg: :black, modifiers: [:bold])
|
|
134
|
+
# Style.with(fg: :white, modifiers: [:underlined], underline_color: :red)
|
|
135
|
+
# Style.with(modifiers: [:bold], remove_modifiers: [:italic]) # Add bold, remove italic
|
|
136
|
+
# paragraph = Paragraph.new(text: "Alert!", style: Style.with(fg: :red))
|
|
137
|
+
#--
|
|
138
|
+
# SPDX-SnippetEnd
|
|
139
|
+
#++
|
|
140
|
+
#
|
|
141
|
+
# @return [Style]
|
|
142
|
+
def self.with(fg: nil, bg: nil, underline_color: nil, modifiers: [], remove_modifiers: [])
|
|
143
|
+
new(fg:, bg:, underline_color:, modifiers:, remove_modifiers:)
|
|
144
|
+
end
|
|
98
145
|
end
|
|
99
146
|
end
|
|
100
147
|
end
|
data/lib/ratatui_ruby/style.rb
CHANGED
|
@@ -10,8 +10,10 @@ module RatatuiRuby
|
|
|
10
10
|
#
|
|
11
11
|
# This module mirrors +ratatui::style+ and contains:
|
|
12
12
|
# - {Style} — Colors and modifiers
|
|
13
|
+
# - {Color} — Color constructors
|
|
13
14
|
module Style
|
|
14
15
|
end
|
|
15
16
|
end
|
|
16
17
|
|
|
17
18
|
require_relative "style/style"
|
|
19
|
+
require_relative "style/color"
|
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
6
|
+
#++
|
|
7
|
+
|
|
8
|
+
module RatatuiRuby
|
|
9
|
+
# Symbol constants from Ratatui's symbols module.
|
|
10
|
+
#
|
|
11
|
+
# Ratatui provides various character sets for rendering UI elements.
|
|
12
|
+
# Hardcoding these characters is error-prone and makes code less readable.
|
|
13
|
+
#
|
|
14
|
+
# This module exposes those constants for Ruby apps to use directly.
|
|
15
|
+
# Use them for gradients, fills, or custom widget styling.
|
|
16
|
+
module Symbols
|
|
17
|
+
# Shade characters for creating gradient or density effects.
|
|
18
|
+
#
|
|
19
|
+
# Terminal UIs often need to show density levels or create visual gradients.
|
|
20
|
+
# Memorizing Unicode block characters is tedious and error-prone.
|
|
21
|
+
#
|
|
22
|
+
# These constants provide named access to the standard shade characters.
|
|
23
|
+
# Use them to fill areas with varying visual densities.
|
|
24
|
+
#
|
|
25
|
+
# === Examples
|
|
26
|
+
#
|
|
27
|
+
#--
|
|
28
|
+
# SPDX-SnippetBegin
|
|
29
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
30
|
+
# SPDX-License-Identifier: MIT-0
|
|
31
|
+
#++
|
|
32
|
+
# # Create a density gradient
|
|
33
|
+
# gradient = [Shade::EMPTY, Shade::LIGHT, Shade::MEDIUM, Shade::DARK, Shade::FULL]
|
|
34
|
+
#
|
|
35
|
+
# # Use in a progress indicator
|
|
36
|
+
# filled = Shade::FULL * progress
|
|
37
|
+
# empty = Shade::LIGHT * (total - progress)
|
|
38
|
+
#--
|
|
39
|
+
# SPDX-SnippetEnd
|
|
40
|
+
#++
|
|
41
|
+
module Shade
|
|
42
|
+
# Empty space - 0% density.
|
|
43
|
+
EMPTY = " "
|
|
44
|
+
|
|
45
|
+
# Light shading - approximately 25% density.
|
|
46
|
+
LIGHT = "░"
|
|
47
|
+
|
|
48
|
+
# Medium shading - approximately 50% density.
|
|
49
|
+
MEDIUM = "▒"
|
|
50
|
+
|
|
51
|
+
# Dark shading - approximately 75% density.
|
|
52
|
+
DARK = "▓"
|
|
53
|
+
|
|
54
|
+
# Full block - 100% density.
|
|
55
|
+
FULL = "█"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Box-drawing characters for borders and lines.
|
|
59
|
+
#
|
|
60
|
+
# Terminal UIs need consistent box-drawing characters for borders and dividers.
|
|
61
|
+
# Memorizing Unicode box-drawing characters is tedious and error-prone.
|
|
62
|
+
#
|
|
63
|
+
# This module exposes both individual characters and predefined sets.
|
|
64
|
+
# Use the sets with widgets that accept a line_set parameter, or use
|
|
65
|
+
# individual characters for custom drawing.
|
|
66
|
+
#
|
|
67
|
+
# === Examples
|
|
68
|
+
#
|
|
69
|
+
#--
|
|
70
|
+
# SPDX-SnippetBegin
|
|
71
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
72
|
+
# SPDX-License-Identifier: MIT-0
|
|
73
|
+
#++
|
|
74
|
+
# # Use a predefined set for drawing boxes
|
|
75
|
+
# line_set = Symbols::Line::ROUNDED
|
|
76
|
+
#
|
|
77
|
+
# # Draw a simple frame
|
|
78
|
+
# top = "#{line_set[:top_left]}#{line_set[:horizontal] * 10}#{line_set[:top_right]}"
|
|
79
|
+
# mid = "#{line_set[:vertical]}#{' ' * 10}#{line_set[:vertical]}"
|
|
80
|
+
# bot = "#{line_set[:bottom_left]}#{line_set[:horizontal] * 10}#{line_set[:bottom_right]}"
|
|
81
|
+
#
|
|
82
|
+
# # Use individual characters for custom drawing
|
|
83
|
+
# corner = Symbols::Line::ROUNDED_TOP_LEFT # => "╭"
|
|
84
|
+
#--
|
|
85
|
+
# SPDX-SnippetEnd
|
|
86
|
+
#++
|
|
87
|
+
module Line
|
|
88
|
+
# Standard vertical line.
|
|
89
|
+
VERTICAL = "│"
|
|
90
|
+
# Double vertical line.
|
|
91
|
+
DOUBLE_VERTICAL = "║"
|
|
92
|
+
# Thick (heavy) vertical line.
|
|
93
|
+
THICK_VERTICAL = "┃"
|
|
94
|
+
|
|
95
|
+
# Standard horizontal line.
|
|
96
|
+
HORIZONTAL = "─"
|
|
97
|
+
# Double horizontal line.
|
|
98
|
+
DOUBLE_HORIZONTAL = "═"
|
|
99
|
+
# Thick (heavy) horizontal line.
|
|
100
|
+
THICK_HORIZONTAL = "━"
|
|
101
|
+
|
|
102
|
+
# Standard top-right corner.
|
|
103
|
+
TOP_RIGHT = "┐"
|
|
104
|
+
# Rounded top-right corner.
|
|
105
|
+
ROUNDED_TOP_RIGHT = "╮"
|
|
106
|
+
# Double top-right corner.
|
|
107
|
+
DOUBLE_TOP_RIGHT = "╗"
|
|
108
|
+
# Thick top-right corner.
|
|
109
|
+
THICK_TOP_RIGHT = "┓"
|
|
110
|
+
|
|
111
|
+
# Standard top-left corner.
|
|
112
|
+
TOP_LEFT = "┌"
|
|
113
|
+
# Rounded top-left corner.
|
|
114
|
+
ROUNDED_TOP_LEFT = "╭"
|
|
115
|
+
# Double top-left corner.
|
|
116
|
+
DOUBLE_TOP_LEFT = "╔"
|
|
117
|
+
# Thick top-left corner.
|
|
118
|
+
THICK_TOP_LEFT = "┏"
|
|
119
|
+
|
|
120
|
+
# Standard bottom-right corner.
|
|
121
|
+
BOTTOM_RIGHT = "┘"
|
|
122
|
+
# Rounded bottom-right corner.
|
|
123
|
+
ROUNDED_BOTTOM_RIGHT = "╯"
|
|
124
|
+
# Double bottom-right corner.
|
|
125
|
+
DOUBLE_BOTTOM_RIGHT = "╝"
|
|
126
|
+
# Thick bottom-right corner.
|
|
127
|
+
THICK_BOTTOM_RIGHT = "┛"
|
|
128
|
+
|
|
129
|
+
# Standard bottom-left corner.
|
|
130
|
+
BOTTOM_LEFT = "└"
|
|
131
|
+
# Rounded bottom-left corner.
|
|
132
|
+
ROUNDED_BOTTOM_LEFT = "╰"
|
|
133
|
+
# Double bottom-left corner.
|
|
134
|
+
DOUBLE_BOTTOM_LEFT = "╚"
|
|
135
|
+
# Thick bottom-left corner.
|
|
136
|
+
THICK_BOTTOM_LEFT = "┗"
|
|
137
|
+
|
|
138
|
+
# Standard T-junction pointing left.
|
|
139
|
+
VERTICAL_LEFT = "┤"
|
|
140
|
+
# Double T-junction pointing left.
|
|
141
|
+
DOUBLE_VERTICAL_LEFT = "╣"
|
|
142
|
+
# Thick T-junction pointing left.
|
|
143
|
+
THICK_VERTICAL_LEFT = "┫"
|
|
144
|
+
|
|
145
|
+
# Standard T-junction pointing right.
|
|
146
|
+
VERTICAL_RIGHT = "├"
|
|
147
|
+
# Double T-junction pointing right.
|
|
148
|
+
DOUBLE_VERTICAL_RIGHT = "╠"
|
|
149
|
+
# Thick T-junction pointing right.
|
|
150
|
+
THICK_VERTICAL_RIGHT = "┣"
|
|
151
|
+
|
|
152
|
+
# Standard T-junction pointing down.
|
|
153
|
+
HORIZONTAL_DOWN = "┬"
|
|
154
|
+
# Double T-junction pointing down.
|
|
155
|
+
DOUBLE_HORIZONTAL_DOWN = "╦"
|
|
156
|
+
# Thick T-junction pointing down.
|
|
157
|
+
THICK_HORIZONTAL_DOWN = "┳"
|
|
158
|
+
|
|
159
|
+
# Standard T-junction pointing up.
|
|
160
|
+
HORIZONTAL_UP = "┴"
|
|
161
|
+
# Double T-junction pointing up.
|
|
162
|
+
DOUBLE_HORIZONTAL_UP = "╩"
|
|
163
|
+
# Thick T-junction pointing up.
|
|
164
|
+
THICK_HORIZONTAL_UP = "┻"
|
|
165
|
+
|
|
166
|
+
# Standard cross (4-way intersection).
|
|
167
|
+
CROSS = "┼"
|
|
168
|
+
# Double cross (4-way intersection).
|
|
169
|
+
DOUBLE_CROSS = "╬"
|
|
170
|
+
# Thick cross (4-way intersection).
|
|
171
|
+
THICK_CROSS = "╋"
|
|
172
|
+
|
|
173
|
+
# Standard box-drawing set with straight corners.
|
|
174
|
+
NORMAL = {
|
|
175
|
+
vertical: VERTICAL,
|
|
176
|
+
horizontal: HORIZONTAL,
|
|
177
|
+
top_right: TOP_RIGHT,
|
|
178
|
+
top_left: TOP_LEFT,
|
|
179
|
+
bottom_right: BOTTOM_RIGHT,
|
|
180
|
+
bottom_left: BOTTOM_LEFT,
|
|
181
|
+
vertical_left: VERTICAL_LEFT,
|
|
182
|
+
vertical_right: VERTICAL_RIGHT,
|
|
183
|
+
horizontal_down: HORIZONTAL_DOWN,
|
|
184
|
+
horizontal_up: HORIZONTAL_UP,
|
|
185
|
+
cross: CROSS,
|
|
186
|
+
}.freeze
|
|
187
|
+
|
|
188
|
+
# Box-drawing set with rounded corners.
|
|
189
|
+
ROUNDED = {
|
|
190
|
+
vertical: VERTICAL,
|
|
191
|
+
horizontal: HORIZONTAL,
|
|
192
|
+
top_right: ROUNDED_TOP_RIGHT,
|
|
193
|
+
top_left: ROUNDED_TOP_LEFT,
|
|
194
|
+
bottom_right: ROUNDED_BOTTOM_RIGHT,
|
|
195
|
+
bottom_left: ROUNDED_BOTTOM_LEFT,
|
|
196
|
+
vertical_left: VERTICAL_LEFT,
|
|
197
|
+
vertical_right: VERTICAL_RIGHT,
|
|
198
|
+
horizontal_down: HORIZONTAL_DOWN,
|
|
199
|
+
horizontal_up: HORIZONTAL_UP,
|
|
200
|
+
cross: CROSS,
|
|
201
|
+
}.freeze
|
|
202
|
+
|
|
203
|
+
# Double-line box-drawing set.
|
|
204
|
+
DOUBLE = {
|
|
205
|
+
vertical: DOUBLE_VERTICAL,
|
|
206
|
+
horizontal: DOUBLE_HORIZONTAL,
|
|
207
|
+
top_right: DOUBLE_TOP_RIGHT,
|
|
208
|
+
top_left: DOUBLE_TOP_LEFT,
|
|
209
|
+
bottom_right: DOUBLE_BOTTOM_RIGHT,
|
|
210
|
+
bottom_left: DOUBLE_BOTTOM_LEFT,
|
|
211
|
+
vertical_left: DOUBLE_VERTICAL_LEFT,
|
|
212
|
+
vertical_right: DOUBLE_VERTICAL_RIGHT,
|
|
213
|
+
horizontal_down: DOUBLE_HORIZONTAL_DOWN,
|
|
214
|
+
horizontal_up: DOUBLE_HORIZONTAL_UP,
|
|
215
|
+
cross: DOUBLE_CROSS,
|
|
216
|
+
}.freeze
|
|
217
|
+
|
|
218
|
+
# Thick (heavy) box-drawing set.
|
|
219
|
+
THICK = {
|
|
220
|
+
vertical: THICK_VERTICAL,
|
|
221
|
+
horizontal: THICK_HORIZONTAL,
|
|
222
|
+
top_right: THICK_TOP_RIGHT,
|
|
223
|
+
top_left: THICK_TOP_LEFT,
|
|
224
|
+
bottom_right: THICK_BOTTOM_RIGHT,
|
|
225
|
+
bottom_left: THICK_BOTTOM_LEFT,
|
|
226
|
+
vertical_left: THICK_VERTICAL_LEFT,
|
|
227
|
+
vertical_right: THICK_VERTICAL_RIGHT,
|
|
228
|
+
horizontal_down: THICK_HORIZONTAL_DOWN,
|
|
229
|
+
horizontal_up: THICK_HORIZONTAL_UP,
|
|
230
|
+
cross: THICK_CROSS,
|
|
231
|
+
}.freeze
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# Vertical bar characters for sparklines and bar charts.
|
|
235
|
+
#
|
|
236
|
+
# Sparklines and vertical bar charts need characters that show partial fill.
|
|
237
|
+
# Memorizing Unicode lower block characters is tedious and error-prone.
|
|
238
|
+
#
|
|
239
|
+
# This module exposes both individual characters and predefined sets.
|
|
240
|
+
# Use the sets with Sparkline widget, or use individual characters for
|
|
241
|
+
# custom visualizations.
|
|
242
|
+
#
|
|
243
|
+
# === Examples
|
|
244
|
+
#
|
|
245
|
+
#--
|
|
246
|
+
# SPDX-SnippetBegin
|
|
247
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
248
|
+
# SPDX-License-Identifier: MIT-0
|
|
249
|
+
#++
|
|
250
|
+
# # Use NINE_LEVELS for high-resolution sparklines (default)
|
|
251
|
+
# sparkline = tui.sparkline(data: [1, 2, 3], bar_set: Symbols::Bar::NINE_LEVELS)
|
|
252
|
+
#
|
|
253
|
+
# # Use THREE_LEVELS for simpler rendering
|
|
254
|
+
# sparkline = tui.sparkline(data: [1, 2, 3], bar_set: Symbols::Bar::THREE_LEVELS)
|
|
255
|
+
#--
|
|
256
|
+
# SPDX-SnippetEnd
|
|
257
|
+
#++
|
|
258
|
+
module Bar
|
|
259
|
+
# Full height bar (8/8).
|
|
260
|
+
FULL = "█"
|
|
261
|
+
# 7/8 height bar.
|
|
262
|
+
SEVEN_EIGHTHS = "▇"
|
|
263
|
+
# 3/4 height bar (6/8).
|
|
264
|
+
THREE_QUARTERS = "▆"
|
|
265
|
+
# 5/8 height bar.
|
|
266
|
+
FIVE_EIGHTHS = "▅"
|
|
267
|
+
# Half height bar (4/8).
|
|
268
|
+
HALF = "▄"
|
|
269
|
+
# 3/8 height bar.
|
|
270
|
+
THREE_EIGHTHS = "▃"
|
|
271
|
+
# 1/4 height bar (2/8).
|
|
272
|
+
ONE_QUARTER = "▂"
|
|
273
|
+
# 1/8 height bar.
|
|
274
|
+
ONE_EIGHTH = "▁"
|
|
275
|
+
|
|
276
|
+
# High-resolution bar set with 9 distinct levels.
|
|
277
|
+
NINE_LEVELS = {
|
|
278
|
+
full: FULL,
|
|
279
|
+
seven_eighths: SEVEN_EIGHTHS,
|
|
280
|
+
three_quarters: THREE_QUARTERS,
|
|
281
|
+
five_eighths: FIVE_EIGHTHS,
|
|
282
|
+
half: HALF,
|
|
283
|
+
three_eighths: THREE_EIGHTHS,
|
|
284
|
+
one_quarter: ONE_QUARTER,
|
|
285
|
+
one_eighth: ONE_EIGHTH,
|
|
286
|
+
empty: " ",
|
|
287
|
+
}.freeze
|
|
288
|
+
|
|
289
|
+
# Low-resolution bar set with 3 levels (full, half, empty).
|
|
290
|
+
THREE_LEVELS = {
|
|
291
|
+
full: FULL,
|
|
292
|
+
seven_eighths: FULL, # collapsed to full
|
|
293
|
+
three_quarters: HALF, # collapsed to half
|
|
294
|
+
five_eighths: HALF, # collapsed to half
|
|
295
|
+
half: HALF,
|
|
296
|
+
three_eighths: HALF, # collapsed to half
|
|
297
|
+
one_quarter: HALF, # collapsed to half
|
|
298
|
+
one_eighth: " ", # collapsed to empty
|
|
299
|
+
empty: " ",
|
|
300
|
+
}.freeze
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
# Horizontal block characters for gauges and progress indicators.
|
|
304
|
+
#
|
|
305
|
+
# Progress bars and gauges need characters that show partial fill from left to right.
|
|
306
|
+
# Memorizing Unicode left block characters is tedious and error-prone.
|
|
307
|
+
#
|
|
308
|
+
# This module exposes both individual characters and predefined sets.
|
|
309
|
+
# Use the sets with Gauge widget, or use individual characters for
|
|
310
|
+
# custom progress indicators.
|
|
311
|
+
#
|
|
312
|
+
# Note: Block uses LEFT block characters (fill from left) while Bar uses
|
|
313
|
+
# LOWER block characters (fill from bottom). They look similar but are different.
|
|
314
|
+
#
|
|
315
|
+
# === Examples
|
|
316
|
+
#
|
|
317
|
+
#--
|
|
318
|
+
# SPDX-SnippetBegin
|
|
319
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
320
|
+
# SPDX-License-Identifier: MIT-0
|
|
321
|
+
#++
|
|
322
|
+
# # Use NINE_LEVELS for high-resolution gauges (default)
|
|
323
|
+
# gauge = tui.gauge(percent: 50, block_set: Symbols::Block::NINE_LEVELS)
|
|
324
|
+
#
|
|
325
|
+
# # Use THREE_LEVELS for simpler rendering
|
|
326
|
+
# gauge = tui.gauge(percent: 50, block_set: Symbols::Block::THREE_LEVELS)
|
|
327
|
+
#--
|
|
328
|
+
# SPDX-SnippetEnd
|
|
329
|
+
#++
|
|
330
|
+
module Block
|
|
331
|
+
# Full width block (8/8).
|
|
332
|
+
FULL = "█"
|
|
333
|
+
# 7/8 width block.
|
|
334
|
+
SEVEN_EIGHTHS = "▉"
|
|
335
|
+
# 3/4 width block (6/8).
|
|
336
|
+
THREE_QUARTERS = "▊"
|
|
337
|
+
# 5/8 width block.
|
|
338
|
+
FIVE_EIGHTHS = "▋"
|
|
339
|
+
# Half width block (4/8).
|
|
340
|
+
HALF = "▌"
|
|
341
|
+
# 3/8 width block.
|
|
342
|
+
THREE_EIGHTHS = "▍"
|
|
343
|
+
# 1/4 width block (2/8).
|
|
344
|
+
ONE_QUARTER = "▎"
|
|
345
|
+
# 1/8 width block.
|
|
346
|
+
ONE_EIGHTH = "▏"
|
|
347
|
+
|
|
348
|
+
# High-resolution block set with 9 distinct levels.
|
|
349
|
+
NINE_LEVELS = {
|
|
350
|
+
full: FULL,
|
|
351
|
+
seven_eighths: SEVEN_EIGHTHS,
|
|
352
|
+
three_quarters: THREE_QUARTERS,
|
|
353
|
+
five_eighths: FIVE_EIGHTHS,
|
|
354
|
+
half: HALF,
|
|
355
|
+
three_eighths: THREE_EIGHTHS,
|
|
356
|
+
one_quarter: ONE_QUARTER,
|
|
357
|
+
one_eighth: ONE_EIGHTH,
|
|
358
|
+
empty: " ",
|
|
359
|
+
}.freeze
|
|
360
|
+
|
|
361
|
+
# Low-resolution block set with 3 levels (full, half, empty).
|
|
362
|
+
THREE_LEVELS = {
|
|
363
|
+
full: FULL,
|
|
364
|
+
seven_eighths: FULL, # collapsed to full
|
|
365
|
+
three_quarters: HALF, # collapsed to half
|
|
366
|
+
five_eighths: HALF, # collapsed to half
|
|
367
|
+
half: HALF,
|
|
368
|
+
three_eighths: HALF, # collapsed to half
|
|
369
|
+
one_quarter: HALF, # collapsed to half
|
|
370
|
+
one_eighth: " ", # collapsed to empty
|
|
371
|
+
empty: " ",
|
|
372
|
+
}.freeze
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
# Scrollbar symbol sets for the Scrollbar widget.
|
|
376
|
+
#
|
|
377
|
+
# Scrollbars need consistent visual elements: a track, a thumb, and arrow indicators.
|
|
378
|
+
# Memorizing Unicode scroll characters is tedious and error-prone.
|
|
379
|
+
#
|
|
380
|
+
# This module exposes predefined sets with different visual styles.
|
|
381
|
+
# Use them with the Scrollbar widget to customize its appearance.
|
|
382
|
+
#
|
|
383
|
+
# Note: Uses <tt>begin_char</tt> and <tt>end_char</tt> instead of Rust's
|
|
384
|
+
# <tt>begin</tt>/<tt>end</tt> to avoid Ruby reserved word conflicts.
|
|
385
|
+
#
|
|
386
|
+
# === Examples
|
|
387
|
+
#
|
|
388
|
+
#--
|
|
389
|
+
# SPDX-SnippetBegin
|
|
390
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long
|
|
391
|
+
# SPDX-License-Identifier: MIT-0
|
|
392
|
+
#++
|
|
393
|
+
# # Use DOUBLE_VERTICAL for bold vertical scrollbars (default)
|
|
394
|
+
# scrollbar = tui.scrollbar(symbols: Symbols::Scrollbar::DOUBLE_VERTICAL)
|
|
395
|
+
#
|
|
396
|
+
# # Use VERTICAL for lighter appearance
|
|
397
|
+
# scrollbar = tui.scrollbar(symbols: Symbols::Scrollbar::VERTICAL)
|
|
398
|
+
#--
|
|
399
|
+
# SPDX-SnippetEnd
|
|
400
|
+
#++
|
|
401
|
+
module Scrollbar
|
|
402
|
+
# Double-line vertical scrollbar with triangle arrows.
|
|
403
|
+
DOUBLE_VERTICAL = {
|
|
404
|
+
track: Line::DOUBLE_VERTICAL,
|
|
405
|
+
thumb: Block::FULL,
|
|
406
|
+
begin_char: "▲",
|
|
407
|
+
end_char: "▼",
|
|
408
|
+
}.freeze
|
|
409
|
+
|
|
410
|
+
# Double-line horizontal scrollbar with triangle arrows.
|
|
411
|
+
DOUBLE_HORIZONTAL = {
|
|
412
|
+
track: Line::DOUBLE_HORIZONTAL,
|
|
413
|
+
thumb: Block::FULL,
|
|
414
|
+
begin_char: "◄",
|
|
415
|
+
end_char: "►",
|
|
416
|
+
}.freeze
|
|
417
|
+
|
|
418
|
+
# Single-line vertical scrollbar with arrow characters.
|
|
419
|
+
VERTICAL = {
|
|
420
|
+
track: Line::VERTICAL,
|
|
421
|
+
thumb: Block::FULL,
|
|
422
|
+
begin_char: "↑",
|
|
423
|
+
end_char: "↓",
|
|
424
|
+
}.freeze
|
|
425
|
+
|
|
426
|
+
# Single-line horizontal scrollbar with arrow characters.
|
|
427
|
+
HORIZONTAL = {
|
|
428
|
+
track: Line::HORIZONTAL,
|
|
429
|
+
thumb: Block::FULL,
|
|
430
|
+
begin_char: "←",
|
|
431
|
+
end_char: "→",
|
|
432
|
+
}.freeze
|
|
433
|
+
end
|
|
434
|
+
end
|
|
435
|
+
end
|