Components

Components are reusable UI objects — the widgets you compose into views. They come in two kinds:

  • Interactive components sit in a controller’s focus ring, handle key and mouse events, and report back through return values — a List you arrow through, a TextInput you type into, a Form you submit.
  • Static renderables just draw — a Badge, a Sparkline, a StatusBar. Some animate when you drive them from a timer (Spinner, Progressbar) — for physics-based motion, see Animation.

Every component inherits from Charming::Component, so assigns passed to new become reader methods and render can use the view DSL. Render any of them from a template or view with render_component:

<%= render_component Charming::Components::List.new(
  items: ["Alpha", "Beta", "Gamma"],
  selected_index: 0,
  theme: theme
) %>

One rule underlies everything: components are rebuilt on every event. They hold no state of their own between keystrokes — anything durable (a selected index, a filter query, text in a field) lives in controller state or session and gets passed back in through the constructor. Each component page shows this idiom.

Pickers & navigation

Component What it does
List Selectable list with keyboard navigation, mouse support, and fuzzy filtering.
MultiSelectList List with [x] checkboxes — Space toggles, Enter submits the checked set.
Table Unicode data table with a scrolling window, sortable columns, and row selection.
Tree Collapsible hierarchy — expand and collapse branches, select leaves.
Filepicker Directory browser — descend into folders, pick a file.
TabBar Horizontal tabs — arrow between them, Enter or click selects.
Breadcrumbs Home › Projects › Current trail with the last item highlighted.
Paginator Page tracker rendering ○ ● ○ dots or 2/3; slices the current page for you.
Viewport Scrollable window over tall content, with wrapping and horizontal scroll.

Text & input

Component What it does
TextInput Single-line text field — masking for passwords, shell-style history, paste support.
TextArea Multiline editor — Enter inserts a newline, wide-character aware.
Autocomplete Text input with a live-filtered suggestion dropdown.
Form Multi-field form with inputs, selects, confirms, validation, and submit/cancel.
CommandPalette Fuzzy-search command picker, plus the modal chrome that frames it.

Overlays & messaging

Component What it does
Modal Centered overlay dialog with title, help text, and an optionally scrollable body.
Toast Auto-dismissing notification box with info/success/warn/error accents.
HelpOverlay Keyboard cheat-sheet modal, buildable straight from a controller’s key bindings.
StatusBar One-row bar with left/center/right segments and key-hint pairs.
Badge Inline styled pill for statuses, counts, and versions.
EmptyState “Nothing here yet” placeholder with loading and error variants.
ErrorScreen The panel the runtime renders for unhandled exceptions.

Progress & time

Component What it does
Spinner Animated frame-cycling indicator with named presets — :dots, :moon, :meter, …
ActivityIndicator Gradient activity bar with label and ellipsis animation.
Progressbar Text progress bar with optional gradient fill and percent tracking.
Timer Countdown clock (mm:ss) — tick it from a controller timer.
Stopwatch Count-up clock — start, stop, reset; accumulates only while running.

Data & media

Component What it does
Chart Line charts (braille subpixels) and bar charts in a fixed-size box.
Sparkline One-line ▁▂▄▇ bar graph, one cell per value.
Markdown CommonMark/GFM renderer with syntax highlighting and clickable links.
Image Inline terminal images on Kitty/Ghostty, with a text fallback everywhere else.
Audio One-line playback-status indicator for an audio player.

How components talk to controllers

Interactive components return values from handle_key / handle_mouse, and the runtime translates them into controller hooks named after the focus slot:

Return value Controller hook
:handled — (event consumed)
[:selected, object] <slot>_selected(object)
[:submitted, value] <slot>_submitted(value)
:cancelled <slot>_cancelled
nil — (event falls through)

The full protocol — key handling, text capture, paste, mouse events, theming — lives in Build Your Own, along with charming generate component for scaffolding your own.


Table of contents


This site uses Just the Docs, a documentation theme for Jekyll.