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:
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.
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.