modal

package
v0.74.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 19, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package modal provides declarative modal dialog components with automatic hit region management, focus handling, scrolling, and keyboard/mouse interaction.

Index

Constants

View Source
const (
	DefaultWidth  = 50
	MinModalWidth = 30
	MaxModalWidth = 120
	ModalPadding  = 6 // border(2) + horizontal padding(4)
)

Default modal dimensions

Variables

This section is empty.

Functions

This section is empty.

Types

type BtnOption

type BtnOption func(*ButtonDef)

BtnOption is a functional option for buttons.

func BtnDanger

func BtnDanger() BtnOption

BtnDanger marks the button as a danger/destructive action.

func BtnPrimary

func BtnPrimary() BtnOption

BtnPrimary is a no-op for compatibility (primary styling is default for focused).

type ButtonDef

type ButtonDef struct {
	Label    string
	ID       string
	IsDanger bool
}

ButtonDef defines a button in a button row.

func Btn

func Btn(label, id string, opts ...BtnOption) ButtonDef

Btn creates a button definition.

type CustomRenderFunc

type CustomRenderFunc func(contentWidth int, focusID, hoverID string) RenderedSection

CustomRenderFunc is the signature for custom section render functions.

type CustomUpdateFunc

type CustomUpdateFunc func(msg tea.Msg, focusID string) (action string, cmd tea.Cmd)

CustomUpdateFunc is the signature for custom section update functions.

type FocusableInfo

type FocusableInfo struct {
	ID      string // Unique identifier for this element
	OffsetX int    // X offset relative to section top-left (within content area)
	OffsetY int    // Y offset relative to section top-left (within content area)
	Width   int    // Width in characters
	Height  int    // Height in lines
}

FocusableInfo describes a focusable element within a section.

type InputOption

type InputOption func(*inputSection)

InputOption is a functional option for Input sections.

func WithSubmitAction

func WithSubmitAction(actionID string) InputOption

WithSubmitAction sets the action ID returned on submit.

func WithSubmitOnEnter

func WithSubmitOnEnter(submit bool) InputOption

WithSubmitOnEnter enables or disables submit-on-enter behavior.

type ListItem

type ListItem struct {
	ID    string // Unique identifier for this item
	Label string // Display text
	Data  any    // Optional associated data
}

ListItem represents an item in a list section.

type ListOption

type ListOption func(*listSection)

ListOption is a functional option for List sections.

func WithMaxVisible

func WithMaxVisible(n int) ListOption

WithMaxVisible sets the maximum number of visible items.

func WithPerItemFocus

func WithPerItemFocus() ListOption

WithPerItemFocus makes the list register each item as a separate focusable for Tab navigation. This overrides the default single-focus behavior when you want Tab to cycle through individual items.

func WithSingleFocus

func WithSingleFocus() ListOption

WithSingleFocus makes the list register as a single focusable unit for Tab navigation. When focused, j/k or up/down change selection within the list without Tab-cycling through each item. This is useful for lists that are part of a larger form where Tab should skip between sections. Note: This is now the default behavior. This option is kept for backward compatibility.

type Modal struct {
	// contains filtered or unexported fields
}

Modal represents a declarative modal dialog with automatic hit region management.

func New

func New(title string, opts ...Option) *Modal

New creates a new Modal with the given title and options.

func (*Modal) AddSection

func (m *Modal) AddSection(s Section) *Modal

AddSection adds a section to the modal. Returns the modal for chaining.

func (*Modal) FocusedID

func (m *Modal) FocusedID() string

FocusedID returns the currently focused element ID.

func (*Modal) HandleKey

func (m *Modal) HandleKey(msg tea.KeyMsg) (action string, cmd tea.Cmd)

HandleKey processes keyboard input. Returns:

  • action: the action ID if triggered ("cancel" for Esc, button/input ID for Enter, etc.)
  • cmd: any tea.Cmd from bubbles models (cursor blink, etc.)

func (*Modal) HandleMouse

func (m *Modal) HandleMouse(msg tea.MouseMsg, handler *mouse.Handler) string

HandleMouse processes mouse input. Returns the action ID if a clickable element was clicked, empty string otherwise.

func (*Modal) HoveredID

func (m *Modal) HoveredID() string

HoveredID returns the currently hovered element ID.

func (*Modal) Render

func (m *Modal) Render(screenW, screenH int, handler *mouse.Handler) string

Render renders the modal and registers hit regions. Returns the styled modal content string.

func (*Modal) Reset

func (m *Modal) Reset()

Reset resets the modal state (focus, hover, scroll).

func (*Modal) ScrollBy

func (m *Modal) ScrollBy(delta int)

ScrollBy adjusts the scroll offset by delta lines (positive = down, negative = up). Clamping to valid range happens in buildLayout.

func (*Modal) ScrollToBottom

func (m *Modal) ScrollToBottom()

ScrollToBottom scrolls to the bottom of the content. The offset is clamped to the actual max in buildLayout.

func (*Modal) ScrollToTop

func (m *Modal) ScrollToTop()

ScrollToTop scrolls to the top of the content.

func (*Modal) SetFocus

func (m *Modal) SetFocus(id string)

SetFocus sets focus to a specific element by ID.

type Option

type Option func(*Modal)

Option is a functional option for configuring a Modal.

func WithCloseOnBackdropClick

func WithCloseOnBackdropClick(close bool) Option

WithCloseOnBackdropClick controls whether clicking the backdrop dismisses the modal. Defaults to true.

func WithCustomFooter

func WithCustomFooter(footer string) Option

WithCustomFooter sets a fixed footer line rendered outside the scroll viewport.

func WithHints

func WithHints(show bool) Option

WithHints enables the keyboard hint line at the bottom.

func WithPrimaryAction

func WithPrimaryAction(actionID string) Option

WithPrimaryAction sets the action ID returned when input submits implicitly.

func WithVariant

func WithVariant(v Variant) Option

WithVariant sets the modal visual variant.

func WithWidth

func WithWidth(w int) Option

WithWidth sets the modal width.

type RenderedSection

type RenderedSection struct {
	Content    string          // Rendered string content
	Focusables []FocusableInfo // Focusable elements with hit region info
}

RenderedSection is the result of rendering a section.

type Section

type Section interface {
	// Render returns the rendered section content and focusable elements.
	// contentWidth is the available width for content (modal width minus border/padding).
	// focusID is the ID of the currently focused element (for styling).
	// hoverID is the ID of the currently hovered element (for styling).
	Render(contentWidth int, focusID, hoverID string) RenderedSection

	// Update handles input when this section contains the focused element.
	// Returns action string if the input triggers an action, plus any tea.Cmd.
	Update(msg tea.Msg, focusID string) (action string, cmd tea.Cmd)
}

Section is the interface for modal content sections.

func Buttons

func Buttons(btns ...ButtonDef) Section

Buttons creates a button row section.

func Checkbox

func Checkbox(id, label string, checked *bool) Section

Checkbox creates a checkbox section.

func CheckboxDisplay

func CheckboxDisplay(label string, checked *bool, hint string) Section

CheckboxDisplay creates a non-focusable checkbox display. The hint shows the keyboard shortcut to toggle (e.g., "ctrl+a").

func Custom

func Custom(renderFn CustomRenderFunc, updateFn CustomUpdateFunc) Section

Custom creates a custom section with user-provided render and update functions. If updateFn is nil, updates are no-ops.

func Input

func Input(id string, model *textinput.Model, opts ...InputOption) Section

Input creates an input section wrapping a textinput.Model.

func InputWithLabel

func InputWithLabel(id, label string, model *textinput.Model, opts ...InputOption) Section

InputWithLabel creates an input section with a label.

func List

func List(id string, items []ListItem, selectedIdx *int, opts ...ListOption) Section

List creates a list section with selectable items. selectedIdx is a pointer to the currently selected index (can be nil for no selection).

func Spacer

func Spacer() Section

Spacer creates a blank line section.

func Text

func Text(s string) Section

Text creates a static text section.

func Textarea

func Textarea(id string, model *textarea.Model, height int, opts ...TextareaOption) Section

Textarea creates a textarea section wrapping a textarea.Model.

func TextareaWithLabel

func TextareaWithLabel(id, label string, model *textarea.Model, height int, opts ...TextareaOption) Section

TextareaWithLabel creates a textarea section with a label.

func When

func When(condition func() bool, section Section) Section

When creates a conditional section that only renders when condition() returns true.

type TextareaOption

type TextareaOption func(*textareaSection)

TextareaOption is a functional option for Textarea sections.

type Variant

type Variant int

Variant represents the visual style of the modal.

const (
	VariantDefault Variant = iota // Primary border color
	VariantDanger                 // Red border, danger button styles
	VariantWarning                // Yellow/amber border
	VariantInfo                   // Blue border
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL