Class: Charming::UI::Style

Inherits:
Object
  • Object
show all
Defined in:
lib/charming/presentation/ui/style.rb

Overview

Style is an immutable builder for terminal text styling. Every method returns a new Style instance with the requested attribute added, so styles can be safely chained and shared across views. render(value) applies the accumulated style to a string.

Constant Summary collapse

ATTRIBUTES =
ANSICodes::ATTRIBUTES
COLORS =
ANSICodes::COLORS

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Style

Initializes a new style with an optional options hash. Recognized keys: :attributes (array of attribute symbols), :padding ([top, right, bottom, left]), :align (:left/:right/:center), and any of :foreground, :background, :border, :border_sides, :border_foreground, :width, :height.



17
18
19
20
21
22
23
24
# File 'lib/charming/presentation/ui/style.rb', line 17

def initialize(options = {})
  @options = {
    attributes: [],
    padding: [0, 0, 0, 0],
    margin: [0, 0, 0, 0],
    align: :left
  }.merge(options)
end

Instance Method Details

#align(value) ⇒ Object

Returns a new Style with horizontal alignment set (:left, :right, or :center).



115
116
117
# File 'lib/charming/presentation/ui/style.rb', line 115

def align(value)
  with(align: value)
end

#align_vertical(value) ⇒ Object

Returns a new Style with vertical alignment within a fixed height set (:top, :middle, or :bottom).



121
122
123
# File 'lib/charming/presentation/ui/style.rb', line 121

def align_vertical(value)
  with(align_vertical: value)
end

#background(color) ⇒ Object Also known as: bg

Returns a new Style with the background color set.



34
35
36
# File 'lib/charming/presentation/ui/style.rb', line 34

def background(color)
  with(background: color)
end

#border(style = :normal, sides: nil, foreground: nil, background: nil) ⇒ Object

Returns a new Style with the border set. style is a border name (e.g., :normal, :rounded, :square, :hidden, :block) or a custom Border instance. sides optionally restricts the border to specific sides. foreground colors the border — a single color, or a per-side hash like {top: :red, left: :green}. background colors the border independently of the box background.



76
77
78
# File 'lib/charming/presentation/ui/style.rb', line 76

def border(style = :normal, sides: nil, foreground: nil, background: nil)
  with(border: style, border_sides: sides, border_foreground: foreground, border_background: background)
end

#foreground(color) ⇒ Object Also known as: fg

Returns a new Style with the foreground color set. color is a color name (":red"), 256-color index (integer), or hex string ("#rrggbb").



28
29
30
# File 'lib/charming/presentation/ui/style.rb', line 28

def foreground(color)
  with(foreground: color)
end

#height(value) ⇒ Object

Returns a new Style that fixes the rendered height to value (in rows).



86
87
88
# File 'lib/charming/presentation/ui/style.rb', line 86

def height(value)
  with(height: value)
end

#margin(*values) ⇒ Object

Returns a new Style with the margin set — blank space applied outside the border and untouched by the style's colors. Accepts the same CSS-style shorthand as padding.



55
56
57
# File 'lib/charming/presentation/ui/style.rb', line 55

def margin(*values)
  with(margin: expand_box_values(values))
end

#max_height(value) ⇒ Object

Returns a new Style that caps the rendered height to value rows. Unlike height, content shorter than the cap is not filled with blank rows.



98
99
100
# File 'lib/charming/presentation/ui/style.rb', line 98

def max_height(value)
  with(max_height: value)
end

#max_width(value) ⇒ Object

Returns a new Style that caps the rendered width to value display columns. Unlike width, content narrower than the cap is not padded out to it.



92
93
94
# File 'lib/charming/presentation/ui/style.rb', line 92

def max_width(value)
  with(max_width: value)
end

#padding(*values) ⇒ Object

Returns a new Style with the padding set. Accepts 1, 2, or 4 values following CSS-style shorthand: 1 → all sides, 2 → [vertical, horizontal], 4 → [top, right, bottom, left].



49
50
51
# File 'lib/charming/presentation/ui/style.rb', line 49

def padding(*values)
  with(padding: expand_box_values(values))
end

#render(value) ⇒ Object

Applies the configured style to value and returns the styled string. Steps:

  1. wrap to :width, 2. align horizontally and vertically, 3. expand to :height,
  2. apply padding, 5. paint border, 6. emit ANSI attribute/foreground/background escapes, 7. surround with unstyled margin space.


129
130
131
132
133
134
# File 'lib/charming/presentation/ui/style.rb', line 129

def render(value)
  lines = apply_dimensions(value.to_s.lines(chomp: true))
  lines = apply_padding(lines)
  lines = apply_border(lines)
  apply_margin(apply_ansi(lines.join("\n")))
end

#truncate(ellipsis: Truncate::ELLIPSIS) ⇒ Object

Returns a new Style that marks lines clipped at the fixed width with a trailing ellipsis instead of cutting them silently.



110
111
112
# File 'lib/charming/presentation/ui/style.rb', line 110

def truncate(ellipsis: Truncate::ELLIPSIS)
  with(fit: :truncate, ellipsis: ellipsis)
end

#width(value) ⇒ Object

Returns a new Style that fixes the rendered width to value (in display columns).



81
82
83
# File 'lib/charming/presentation/ui/style.rb', line 81

def width(value)
  with(width: value)
end

#wrapObject

Returns a new Style that word-wraps overflowing lines at the fixed width instead of clipping them.



104
105
106
# File 'lib/charming/presentation/ui/style.rb', line 104

def wrap
  with(fit: :wrap)
end