Skip to main content

a2ui_base/components/
mod.rs

1//! Framework-agnostic component **behavior** — the `handle_event` logic for
2//! the interactive component types whose handlers touch only core types.
3//!
4//! Rendering is backend-specific (ratatui paints a `Frame`, Slint builds a
5//! reactive tree), but the *semantics* of how a component reacts to a key press
6//! (fire an action, write a data-model value, toggle, …) are identical across
7//! backends. Extracting that logic here lets every backend reuse one
8//! implementation instead of duplicating it.
9//!
10//! Each submodule exposes
11//! `pub fn handle_event(ctx: &ComponentContext, event: &InputEvent) -> Option<EventResult>`.
12//! [`dispatch_event`] routes by component-type name.
13//!
14//! ## Scope
15//!
16//! Only handlers with no backend coupling are extracted here:
17//! [`button`], [`checkbox`], [`slider`], [`text_field`]. The remaining
18//! interactive types stay backend-specific for now:
19//! - `choice_picker` / `tabs` — their handlers share locally-defined
20//!   deserializable types (`ChoiceOption`, `TabEntry`) with the ratatui render
21//!   path; extracting them would pull render types into core.
22//! - `date_time_input` — its handler shares `chrono` parsing helpers with render.
23//! - `audio_player` — drives real audio hardware (rodio), inherently backend-bound.
24//!
25//! A Slint backend reuses the four shared handlers via [`dispatch_event`] and
26//! reimplements the rest locally until they are promoted here.
27
28use crate::event::{EventResult, InputEvent};
29use crate::model::component_context::ComponentContext;
30
31pub mod button;
32pub mod checkbox;
33pub mod slider;
34pub mod text_field;
35
36/// Route a key-press event to the named component type's [`handle_event`].
37///
38/// Returns `None` for types without a shared handler (unknown types,
39/// non-interactive types like Text/Column, or the backend-specific interactive
40/// types listed in the module docs). Callers build a [`ComponentContext`] for
41/// the target component, then call this.
42pub fn dispatch_event(
43    comp_type: &str,
44    ctx: &ComponentContext,
45    event: &InputEvent,
46) -> Option<EventResult> {
47    match comp_type {
48        "Button" => button::handle_event(ctx, event),
49        "CheckBox" => checkbox::handle_event(ctx, event),
50        "Slider" => slider::handle_event(ctx, event),
51        "TextField" => text_field::handle_event(ctx, event),
52        _ => None,
53    }
54}