Skip to main content

Module component

Module component 

Expand description

Components: the toolkit’s widgets as described, composable data.

A described widget has props: a plain struct with #[derive(Component)], and the derive generates its Description from it (props, slots, events, bindings, state and semantics, each with its doc text), so the description cannot drift from the widget: a prop or an event whose type has no description does not compile, and an event is an Event, data, never a closure.

The widget takes its props through Described: built from them, and takes changed props in place. Its Rust builder is the same widget; the props are the declarative form, which the generic host adapter, tilolang (the package ui) and serialized graphs use. Each widget takes its props apart field by field, so a prop it does not take does not compile either.

The catalogue of every described widget ships as data (tilo_ui_graph::component::SHIPPED), so tools that do not link the toolkit read it; a test fails while the shipped one is not the one the toolkit generates.

use tilo_ui::component::{Component, Type};
use tilo_ui::widget::ListRowProps;

let row = ListRowProps::describe();
assert_eq!(row.name, "ListRow");
assert_eq!(row.prop("title").map(|p| &p.ty), Some(&Type::Text));
assert!(row.event("activate").is_some());

A prop whose type has no description does not compile, so a closure cannot be one:

ⓘ
use tilo_ui::component::Component;

/// A row.
#[derive(Component, Default)]
#[component(name = "Row", role = "ListItem")]
struct RowProps {
    /// What runs when it is pressed.
    pressed: Option<Box<dyn FnMut()>>,
}

nor can an event, which is an Event:

ⓘ
use tilo_ui::component::Component;

/// A row.
#[derive(Component, Default)]
#[component(name = "Row", role = "ListItem")]
struct RowProps {
    /// What runs when it is pressed.
    #[component(event)]
    pressed: Option<Box<dyn FnMut()>>,
}

and every part is documented, since its doc text is what an author is shown:

ⓘ
use tilo_ui::component::Component;

/// A row.
#[derive(Component, Default)]
#[component(name = "Row", role = "ListItem")]
struct RowProps {
    title: String,
}

Modules§

gallery
What the gallery app (apps/tl/gallery) shows of the toolkit’s described components.

Structs§

BindingDescription
A two-way binding to a resource field or view state.
Bound
A two-way binding as a widget takes it: the value through the widget’s model-binding path (a LocalState its host keeps in step with what it is bound to), and where each edit is reported, for the host to apply with the binding’s merge.
Catalogue
Every described component of one toolkit version.
Description
One described component.
Entry
One described widget, as the generic adapter reaches it.
EnumCase
A case of one of the app’s own enums, by its name, as a binding says it: which cases it holds is the field the binding names, so a description says only that it takes one.
Error
Why an instance’s props could not be read.
EventDescription
Something that happens to a component. What it does is data: an action reference, invoked through the door, or a view-state update; never a closure.
Fired
An event a component reports to its host: which instance (by key) and which event, with the value the event carries.
Intent
A view intent: Fired queued on the host’s crate::Intents.
Moment
A moment, as a component shows one: the instant, in seconds since the Unix epoch. The component decides how it reads (a time of day, a day’s divider).
Offered
An action offered to the person, as a component holds one: how a control shows it, and the event of the instance that choosing it fires. Every field is always written: the wire’s encoding is not self-describing.
OfferedAction
An action offered to the person, as a widget takes one: how it shows, and the event choosing it fires (data, never a closure).
Person
A participant, as a component shows one: their identity and what the workspace calls them.
Picture
A picture a component shows, by where its bytes are. The address is opaque to the toolkit: a window whose host holds a content store reads tilo-blob://<hash> from it, and any other address is fetched by the store the picture loads through.
Prop
A typed value a component takes.
ResourceId
The id of a resource a component presents.
Semantics
How assistive technology and tests see a component.
Slot
Child content a component takes.
StateDescription
What a widget keeps between frames (scroll, selection, caret, expansion). It is lens state: personal, shown as presence, resumed on the person’s other devices.

Enums§

Accepts
What a slot accepts.
BoundValue
A binding as a host hands it over, of one of the types bindings take.
Event
What happens when one of a component’s events happens. Data, never a closure: an action reference, invoked through the door, or a view intent its host applies (a view-state update, or the action reference the host’s view attached to the event).
Merge
How an edit through a binding is applied to what it is bound to.
Type
The type of a prop, an event’s value, a binding or a piece of state: the language’s types.
Value
A value of a Type, as an instance of a component holds it.

Constants§

FORMAT_VERSION
The version of the description format: a change to the shape of Description bumps it.

Traits§

BindType
A Rust type a binding may have.
Component
A widget’s props: the struct its instances are made of. Derive it.
Described
A widget made from props.
PropType
A Rust type a prop (or state, or an event’s value) may have: its Type in a description, and how a Value of it reads.
RowSource
Rows its host renders only when the widget shows them: a loop over ten thousand items costs the rows on screen. The host keeps the keys of every row, renders the rows the widget asks for and forgets the others, and queues what changed (rows inserted, removed or moved, and rendered rows that show something else now) for the widget to take.
SlotType
A Rust type a slot may have: Option<Element> for one view, Vec<Element> for any number, Option<P> of another component’s props for that component only (the derive implements it).
SlotViews
The views in one slot of a widget, which a host inserts, removes, moves and replaces by key: a change of a slot’s content costs what changed, and is described to the window (crate::widget::StructureChange::Described) rather than rebuilding the widget.
Source
An instance of a component as its host gives it: the values of its props, its events and bindings as data, and its slots’ content.

Functions§

build
Build the component name of source.
catalogue
The catalogue of every described widget, as this toolkit generates it.
entry
The Entry of the widget W.
get
The entry of the component name.
moment_day
The day a moment’s text names: its date, or the day an instant falls on.
part_views
The views its slot slot holds for the part key, in the part’s own view slot of, built for an instance of name, to change by key in place: None when the widget changes them only by being built again.
parts
The components that stand only in a slot of another, which reads their props: a property list’s facts, a navigation list’s places and sections, a menu’s commands, separators and emoji bar, a row’s swipe, the items of a virtual list, and what a view attaches to the element it stands in (its context menu, hover toolbar and swipe). Generated: every #[derive(Component)] props that no described widget is built from.
registry
Every described widget: generated by the build script from each impl Described in the toolkit’s sources (component_scan.rs), so a widget described where it is written is registered with no list to add it to.
slot_views
The views of the slot slot of widget, built for an instance of name, to change by key in place: None when the widget changes them only by being built again.
update
Bring widget, built for an instance of name, to source’s props in place: Ok(false) when it is to be built again.

Type Aliases§

SharedRows
Rows a host and the widget showing them share.

Attribute Macros§

not_a_component
Say of a public widget why it is not a described component, where it is declared: #[not_a_component(layout, "the language's stack")]. The toolkit’s coverage check reads it: every public widget is either described (impl Described) or says why not, so a widget that works in Tilo is either in tilolang or names the reason it never will be.

Derive Macros§

Component
Derive tilo_ui::component::Component for a widget’s props: the struct an instance of the widget is made from. The widget’s component description is generated from it, so the description cannot drift from the widget.