Components
Components are first-class language constructs. The component keyword declares a composable unit with props, state, events, and an optional view tree.
Declaration syntax
tape
component Name {
prop label: *u8;
prop size: i64 = 48;
var count: i64 = 0;
state hovered: bool = false;
event on_click();
slot content;
@dispatch fn paint(ctx: *u8, x: i32, y: i32, w: i32, h: i32);
@tape { ui.drawable(); }
fn increment() {
count = count + 1;
}
view {
widgets.Label { text: label; }
}
}Keywords inside components
| Keyword | Purpose |
|---|---|
prop name: Type = default; | Immutable input from parent |
var name: Type = init; | Mutable reactive state |
state name: bool = init; | Boolean interaction flag (targetable from #style) |
event name(params); | Typed callback channel |
slot name; | Named insertion point for child content |
@dispatch fn name(params); | Vtable slot for polymorphic dispatch |
@dispatch(required) fn ...; | Required dispatch (must be implemented) |
@tape { ... } | Compile-time code generation block |
view { ... } | Declarative visual tree |
fire event_name(args); | Emit an event to the parent’s handler |
state and #style
state fields are bool-only and targetable from #style via :name pseudo-selectors:
tape
component Button {
state hovered: bool = false;
state active: bool = false;
}tape
#style
Button {
bg: #444444;
:hovered { bg: #555555; }
:active { bg: #333333; }
}The compiler verifies that each :name matches a state declaration — unmatched selectors are a compile error.
Component constraint type
The *component[...] type constrains a pointer to components implementing specific dispatches:
tape
fn render(widget: *component[@dispatch fn paint(ctx: *u8, x: i32, y: i32, w: i32, h: i32)]) {
widget.paint(ctx, 0, 0, 100, 100);
}The is operator checks constraints at runtime:
tape
if (widget is *component[@dispatch fn paint(ctx: *u8, x: i32, y: i32, w: i32, h: i32)]) {
widget.paint(ctx, x, y, w, h);
}View tree syntax
View trees contain component instances, control flow, and slot references:
tape
view {
ui.Column {
if (show_header) {
widgets.Label { text: "Header"; }
}
for (item in items) {
ListItem { data: item; on_click: handle_select; }
}
content;
}
}Props bind with name: expr;. Slots fill with slot name { children };.
For full details on props, events, lifecycle, views, and dispatch, see the Components section.
Last modified: