-
Notifications
You must be signed in to change notification settings - Fork 0
Props
The #[props] macro turns a named-field struct into a Nestix prop container and
typed builder.
#[props(debug)]
#[derive(Debug)]
pub struct ButtonProps {
#[props(default)]
disabled: bool,
on_click: Option<Shared<dyn Fn()>>,
}Every normal field is transformed into PropValue<T>. Component code reads the
current value with .get().
if props.disabled.get() {
// disabled
}Fields are required unless they are Option<T> or marked with
#[props(default)] or #[props(start)].
#[props]
pub struct TextProps {
text: String,
}
layout! {
Text(.text = "Hello".to_string())
}The generated builder tracks required fields at the type level.
Option<T> fields default to None automatically.
#[props]
pub struct LinkProps {
href: String,
target: Option<String>,
}Callers may omit .target.
Use #[props(default)] to default through Default::default().
#[props]
pub struct InputProps {
#[props(default)]
value: String,
}Use #[props(default = expr)] for a custom default.
#[props]
pub struct BadgeProps {
#[props(default = "neutral".to_string())]
tone: String,
}Use #[props(start)] for positional arguments in layout! and build_props!.
#[props(debug)]
#[derive(Debug)]
pub struct TextProps {
#[props(start)]
text: String,
}
layout! {
Text("Hello")
}Start fields are passed to the generated builder constructor before named properties.
#[props(debug)] makes the generated Props::debug_fmt implementation delegate
to the struct's Debug implementation.
#[props(debug)]
#[derive(Debug)]
pub struct PanelProps {
#[props(default)]
children: Layout,
}Without debug, type-erased props format as Props(..).
Use #[props(bounds(...))] to provide bounds for generated implementations.
#[props(bounds(I: IntoIterator + 'static, K: 'static))]
pub struct ForProps<I: IntoIterator, K> {
data: I,
key: Shared<dyn Fn(&I::Item) -> K>,
}#[props(extensible(TraitName))] generates a trait exposing the prop struct and
its fields. Other prop structs can include an extension field with
#[props(extends(TraitName))].
This is useful for component libraries that want prop inheritance or shared prop groups.
#[props(extensible(ViewPropsExt))]
pub struct ViewProps {
#[props(default)]
class: String,
}
#[props]
pub struct ButtonProps {
#[props(extends(ViewPropsExt))]
view: ViewProps,
on_click: Option<Shared<dyn Fn()>>,
}Extension fields are not wrapped in PropValue<T> and cannot also be start or
default fields.
build_props! drives the generated builder. This is what layout! uses for
component prop syntax.
let props = build_props!(ButtonProps(
.disabled = false,
.on_click = callback!(|| log::info!("clicked")),
));Positional arguments fill start fields:
let props = build_props!(TextProps("Hello"));Named values are converted with prop_value!, so plain values, signals, and
existing PropValue<T> values are accepted.
prop_value! converts:
- plain values to
PropValue::from_plain; - signals to
PropValue::from_signal; - existing
PropValue<T>values unchanged.
let plain = prop_value!("Hello".to_string());
let reactive = prop_value!(computed!([count] || count.get().to_string()));