Properties & Settings
Properties
and Settings
are two sides of the same idea, so they share a chapter in this book.

Two illuminated switchboards: one light, one dark
Recall that the atomic unit of Pax is the component. Components pass data to each other through properties
and settings
.[1]
Properties
Properties
could be summarized as inputs to a component — they are the properties of a component that are exposed to consumers. For example, Stacker
, the layout component, exposes a property direction
, which dictates whether Stacker
lays out its cells horizontally or vertically.
Properties are also used internally within a component as state containers, similar in purpose to state
in React (opens in a new tab). A component's properties may be referred to by any of that component's expressions like: {self.some_property && self.some_other_property}
Properties are defined on Rust structs, such as counter
below:
use pax_lang::api::*;
#[pax]
#[inlined(
<Text text={counter}></Text>
)]
pub struct MyComponent {
counter: Property<i64>,
}
Notice that counter
is a member of a Pax-attached Rust struct, with a pax_lang::api::Property<T>
wrapper around its type.
Settings
Settings
are declarations of values. If Properties
are inputs to a component, then Settings
are outputs. When composing the definition of a component or program, you set the properties of any element in order to specify behavior or appearance.
Building off of the Stacker
example above, any component that instantiates a Stacker
in its template has the opportunity to apply a setting to Stacker
, to set its direction
property.
Let's use the above component inside a new component, AnotherComponent
.
use pax_lang::api::*;
use crate::MyComponent;
#[pax(
<MyComponent counter={self.num_clicks * 2} />
)]
pub struct AnotherComponent {
num_clicks: Property<i64>,
}
In this example, MyComponent
's counter
property gets set — the declaration of a value, in this case an expression {self.num_clicks * 2}
, is a setting.
Settings declarations may either be literal values or expressions. counter=5
would be another valid setting for the example above.
Declarative Settings Syntax
Settings can be declared with two different syntaxes: inline settings
or settings block
syntax. Each syntax has access to the exact same properties, and expressions
can be bound in either place.
Inline Settings
Inline settings are authored inline into a template definition. You might recognize this syntax as nearly identical to XML attributes. Example:
//inside a template definition
<SomeComponent some_property="SomeSetting" />
Unlike XML, Pax's inline settings syntax supports values beyond string literals, such as enums, symbolic identifiers, and numeric literals. Pax inline settings may also be bound to expressions, wrapped in {}
, such as:
//`self.current_width` refers to a property from the attached Rust struct, not shown here.
<Rectangle width={self.current_width} height={self.current_width * 1.5} />
Settings blocks
As an alternative to inline syntax, settings may be authored in a CSS-like syntax, binding a block of settings to an element by id. For example:
<Rectangle id=my_rect>
@settings {
#my_rect {
fill: rgb(100%, 100%, 0)
}
}
Every property that is available inline is also available in the settings block syntax, and settings can be mixed and matches across syntaxes.
Settings precedence
When both an inline setting and a setting block apply settings for the same property, the inline setting takes precedence. This "cascading" behavior is inspired by HTML and CSS. When a property
is set
at runtime, the latest set value takes precedence.
Setting Properties at Runtime
For a Property<T>
, the following API is exposed to Rust logic at runtime:
.set
Set a property value
.ease_to
Ease a property value over time with an easing curve (generally, for animation)
.ease_to_later
Same as ease_to
, but enqueues the specified transition to occur after all currently enqueued transitions are completed.
[1] The relationship between properties & settings is inspired by digital circuits..