Class: Clacky::UI2::Components::ModalComponent

Inherits:
BaseComponent show all
Defined in:
lib/clacky/ui2/components/modal_component.rb

Overview

ModalComponent - Displays a centered modal dialog with form fields

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from BaseComponent

render

Constructor Details

#initializeModalComponent

Returns a new instance of ModalComponent.



14
15
16
17
18
19
20
21
22
23
24
# File 'lib/clacky/ui2/components/modal_component.rb', line 14

def initialize
  super
  @width = 70
  @height = 16
  @title = ""
  @fields = []
  @choices = []
  @values = {}
  @selected_index = 0
  @mode = :form
end

Instance Attribute Details

#heightObject (readonly)

Returns the value of attribute height.



12
13
14
# File 'lib/clacky/ui2/components/modal_component.rb', line 12

def height
  @height
end

#widthObject (readonly)

Returns the value of attribute width.



12
13
14
# File 'lib/clacky/ui2/components/modal_component.rb', line 12

def width
  @width
end

Instance Method Details

#render(data) ⇒ Object

Render method (required by BaseComponent, not used for modal)



85
86
87
88
# File 'lib/clacky/ui2/components/modal_component.rb', line 85

def render(data)
  # Modal uses interactive show() method instead
  ""
end

#show(title:, fields: nil, choices: nil, validator: nil, on_close: nil) ⇒ Hash?

Configure and show the modal

Parameters:

  • title (String)

    Modal title

  • fields (Array<Hash>) (defaults to: nil)

    Field definitions (for form mode)

  • choices (Array<Hash>) (defaults to: nil)

    Choice definitions (for menu mode) Example: [{ name: “Option 1”, value: :opt1 }, { name: “—”, disabled: true }]

  • validator (Proc, nil) (defaults to: nil)

    Optional validation callback that receives values hash Should return { success: true } or { success: false, error: “message” }

  • on_close (Proc, nil) (defaults to: nil)

    Optional callback to execute when modal closes (e.g., to re-render screen)

Returns:

  • (Hash, nil)

    Hash of field values or selected value, or nil if cancelled



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/clacky/ui2/components/modal_component.rb', line 35

def show(title:, fields: nil, choices: nil, validator: nil, on_close: nil)
  @title = title
  @mode = choices ? :menu : :form
  @fields = fields || []
  @choices = choices || []
  @values = {}
  @error_message = nil
  @selected_index = 0
  
  # For menu mode, find first non-disabled choice
  if @mode == :menu
    @selected_index = @choices.index { |c| !c[:disabled] } || 0
  end

  # Adjust height based on mode
  if @mode == :menu
    visible_items = [@choices.length, 15].min
    @height = visible_items + 4  # +4 for title, borders, and instructions
  else
    # Form mode - adjust height based on number of fields
    # Each field takes 2 rows (label + input)
    # +3 for title and top border
    # +5 for error message area, buttons, and bottom border
    @height = (@fields.length * 2) + 3 + 5
  end

  # Get terminal size
  term_height, term_width = IO.console.winsize

  # Calculate modal position (centered)
  start_row = [(term_height - @height) / 2, 1].max
  start_col = [(term_width - @width) / 2, 1].max

  begin
    if @mode == :menu
      # Menu mode - show choices and handle selection
      return show_menu_mode(start_row, start_col)
    else
      # Form mode - collect field inputs
      return show_form_mode(start_row, start_col, validator)
    end
  ensure
    # Clear modal area
    clear_modal(start_row, start_col)
    # Call on_close callback if provided (e.g., to re-render screen)
    on_close&.call
  end
end