Class: Charming::Components::Modal

Inherits:
Charming::Component show all
Defined in:
lib/charming/presentation/components/modal.rb

Overview

Modal is a centered, boxed overlay with an optional title, help line, and body content. The body may be a string, View, or Component; when it responds to ‘render`, its output is used. The result is wrapped in a UI::Style border with padding.

When max_body_height is given and the body is taller, the body is windowed through a Viewport: up/down (and page/home/end) keys scroll it via ‘handle_key`, and the current scroll position is exposed as `scroll_offset` so controllers can persist it.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Charming::Component

#captures_text?

Methods inherited from View

#focused?, #layout_assigns

Constructor Details

#initialize(content:, title: nil, help: nil, width: 52, max_body_height: nil, scroll_offset: 0, style: nil, theme: nil) ⇒ Modal

content is the modal body. title (optional) is rendered centered at the top. help (optional) is rendered as a muted footer line. width is the modal’s total width. max_body_height caps the visible body rows (scrollable). scroll_offset restores a previous scroll position. style overrides the default ‘theme.modal` style.



20
21
22
23
24
25
26
27
28
29
# File 'lib/charming/presentation/components/modal.rb', line 20

def initialize(content:, title: nil, help: nil, width: 52, max_body_height: nil, scroll_offset: 0, style: nil, theme: nil)
  super(theme: theme)
  @content = content
  @title = title
  @help = help
  @width = width
  @max_body_height = max_body_height
  @scroll_offset = scroll_offset
  @style = style
end

Instance Attribute Details

#scroll_offsetObject (readonly)

The body’s current scroll offset (only meaningful with max_body_height).



14
15
16
# File 'lib/charming/presentation/components/modal.rb', line 14

def scroll_offset
  @scroll_offset
end

Instance Method Details

#handle_key(event) ⇒ Object

Scrolls the body when it is taller than max_body_height. Returns :handled when the key moved the viewport, nil otherwise (so callers can route unconsumed keys).



33
34
35
36
37
38
39
40
# File 'lib/charming/presentation/components/modal.rb', line 33

def handle_key(event)
  return nil unless scrollable?

  viewport = body_viewport
  result = viewport.handle_key(event)
  @scroll_offset = viewport.offset
  result
end

#renderObject

Renders the modal as a bordered, padded string with the title and help lines stacked above the content.



44
45
46
# File 'lib/charming/presentation/components/modal.rb', line 44

def render
  box(column(*lines, gap: 1), style: modal_style)
end