Key Concepts
Settings

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

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..