Class: Charming::Presentation::Components::Form::Textarea

Inherits:
Field show all
Defined in:
lib/charming/presentation/components/form/textarea.rb

Overview

Textarea is a multi-line Form field backed by a TextArea widget. The cursor offset, top-visible row, and preferred vertical column are all persisted in the form’s per-field state so the field behaves consistently when refocused mid-edit.

Instance Attribute Summary

Attributes inherited from Field

#help, #label, #name, #state

Instance Method Summary collapse

Methods inherited from Field

#focusable?, #validate, #value

Methods inherited from View

#focused?, #layout_assigns

Constructor Details

#initialize(name, value: "", placeholder: "", width: nil, height: nil, **options) ⇒ Textarea

value is the initial text. placeholder is shown when the value is empty. width and height constrain the rendered area. All other options are forwarded to Field (label, required, validate, help, theme).



14
15
16
17
18
19
20
# File 'lib/charming/presentation/components/form/textarea.rb', line 14

def initialize(name, value: "", placeholder: "", width: nil, height: nil, **options)
  super(name, **options)
  @initial_value = value
  @placeholder = placeholder
  @width = width
  @height = height
end

Instance Method Details

#bind(state) ⇒ Object

Binds the field, seeds the initial value, and initializes the cursor/offset state.



23
24
25
26
27
28
# File 'lib/charming/presentation/components/form/textarea.rb', line 23

def bind(state)
  super
  state[:values][name] = @initial_value if state[:values][name].nil?
  field_state[:cursor] = state[:values][name].to_s.length unless field_state.key?(:cursor)
  field_state[:offset] ||= 0
end

#handle_key(event) ⇒ Object

Forwards key events to the underlying TextArea, syncing the value, cursor, offset, and preferred column back into the form state. Returns :handled when consumed.



32
33
34
35
36
37
38
39
40
41
42
# File 'lib/charming/presentation/components/form/textarea.rb', line 32

def handle_key(event)
  area = text_area
  result = area.handle_key(event)
  return nil unless result == :handled

  state[:values][name] = area.value
  field_state[:cursor] = area.cursor
  field_state[:offset] = area.offset
  field_state[:preferred_column] = area.preferred_column
  :handled
end

#render(active: false) ⇒ Object

Renders the field with its label on the first line, body lines indented, and optional help/error lines below.



46
47
48
49
50
# File 'lib/charming/presentation/components/form/textarea.rb', line 46

def render(active: false)
  label_line = "#{active ? ">" : " "} #{label}:"
  label_line = theme.selected.render(label_line) if active
  [label_line, *body_lines, help_line, *error_lines].compact.join("\n")
end