Expand description
Widget trait + attribute bag - the thin surface implemented by
#[derive(Widget)] (see the sibling lumen-widget-macros crate).
§Why this crate
Authoring a custom Lumen widget today repeats the same five-step
boilerplate per primitive (hover, scroll, tooltip, transition,
validation … all of lumen-primitives):
- Define a marker [
bevy_ecs::component::Component]. - Define a
Pluginstruct. - In
Plugin::build, register N systems against one or morelumen_core::tick::TickStagesets. - Tell the markup parser about the new tag. The plugin the derive
generates calls
<Type>::register()in itsbuild, publishingWidget::parser_taginto the registry the parser consults after its built-in table. - Provide a spawn fn that turns the element spawned for a parsed
<tag attr="...">into the widget: the marker + the author-specified props.
The first three steps are repeated verbatim per widget. This crate
defines the minimal surface that the Widget derive macro
implements so authors only write the unique parts: the prop /
state fields and the per-tick system bodies.
§The trait
use lumen_widget::{Attributes, Widget};
use lumen_widget_macros::Widget;
use bevy_ecs::prelude::*;
#[derive(Component, Widget, Default)]
#[widget(tag = "tooltip")]
pub struct Tooltip {
#[widget(prop)] pub text: String,
#[widget(state)] pub visible: bool,
}The derive emits:
impl Plugin for TooltipPlugin- a zero-sized struct that the author adds to theirApp. Defaultbuildbody inserts the marker resource and registers any author-supplied systems via the#[widget(systems = "fn1,fn2")]attribute (forward-looking).impl Widget for Tooltip- connects the marker component, the parser tag, and the spawn glue.- A
spawnfn that walks anAttributesbag, populates the prop fields, and inserts the component on the supplied entity.
§Scope of v1
The macro covers Plugin scaffolding + entity-spawn glue. Widget-
specific systems (the record_hover_started / spawn_popup chain
for tooltips) stay hand-written. A future iteration may grow the
#[widget(systems = ...)] attribute to register them automatically.
§Parser integration
The lumenc HTML parser checks its built-in tag table
(KNOWN_TAGS in public/lumenc/src/parse/html.rs) first and falls back
to is_widget_tag_registered. The plugin the derive generates
calls <Type>::register() when it is added, so adding that plugin
before the parser runs is enough for <my-thing> markup to be
accepted; no edit to the built-in table is needed.
The parser keeps every attribute such an element was written with, and
the spawner, once it has spawned the element, looks the tag up with
widget_spawner and hands the element and its Attributes to the
widget’s Widget::spawn. So <my-thing greeting="hi"/> ends up an
element carrying the widget’s component with greeting set.
Structs§
- Attributes
- Untyped attribute bag handed to
Widget::spawn: every attribute the element was written with in markup.
Traits§
- Widget
- Thin surface implemented by
#[derive(Widget)].
Functions§
- is_
widget_ tag_ registered - Returns
truewhentagwas registered viaregister_widget_tag,register_widgetorregister_widget_tag_ownedearlier in this process. Consulted bypublic/lumenc/src/parse/html.rs’sKNOWN_TAGSfallback path. - register_
widget - Register
W: the lumenc HTML parser accepts<tag ...>for itsWidget::parser_tag, and every element spawned for that tag is handed, with its authored attributes, toWidget::spawn. - register_
widget_ tag - Register
tagso the lumenc HTML parser accepts<tag ...>markup. - register_
widget_ tag_ owned - Register a tag whose name is only known at run time, so
<tag ...>markup is accepted. - widget_
spawner - The
Widget::spawnregistered fortag, if aWidgetwas registered for it withregister_widget.
Type Aliases§
- Widget
Spawn Fn - What builds the widget an element with a registered tag stands for: the
tag’s
Widget::spawn.