Components
A component exposes event handling and state management.
Any type that implements the anathema::widgets::components::Component
trait is a component.
This trait has no required methods, however note that there are two required associated types:
- State
- Message
If the component does not need to handle state or receive messages these can be set to the unit type.
use anathema::widgets::components::Component;
struct MyComponent;
impl Component for MyComponent {
type State = (); // <-\
// -- Set to () to ignore
type Message = (); // <-/
}
A component has to be registered with the runtime before it can be used in the template.
Template syntax
The component name is prefixed with an @
sign: @component_name
, followed by
optional associated events, attributes and external state.
@ means it's a component
| Component name Attribute name
| | Component event | Attribute value
| | | Parent event | | External state
V V V V V V V
@component (click->parent_click) [attrib: "value"] { external_state: 123 }
Usage
Use a component in a template by prefixing the tag with the @
sign:
border
@my_comp
Focus and receiving events
Mouse events are sent to all components, however key events are only sent to the component that currently has focus.
It is possible to assign focus to a component from another component using
context.set_focus
.
set_focus
takes an attribute name and a value. It is possible to call
set_focus
on multiple components with a single frame. This will result in
multiple components receiving both on_focus
and on_blur
until the last
component in the focus queue which only receives on_focus
.
Example
The following example would set focus on @component_a
as it has a matching id.
It's not required to name the attribute id
, it can be any alphanumerical value
(as long as it doesn't start with a number).
vstack
@component_a [id: 1]
@component_b [id: 2]
@component_c [id: "not a number"]
fn on_key(
&mut self,
key: KeyEvent,
state: &mut Self::State,
mut elements: Elements<'_, '_>,
mut context: Context<'_, Self::State>,
) {
context.set_focus("id", 1);
}