Basic Component with Children and Props
In OSUI, applications are built by composing smaller, reusable components. This guide expands on the "Hello World" example by demonstrating how to define a custom component, pass data to it (props), and render its children.
1. The MyComponent Example
Let's modify our src/main.rs to introduce MyComponent.
use osui::prelude::*;
use std::sync::Arc;
pub fn main() {
let engine = Console::new();
engine.run(App {}).expect("Failed to run engine");
}
#[component]
fn App(cx: &Arc<Context>) -> View {
rsx! {
// Here, MyComponent is instantiated with a string literal as its child.
// This string will be available inside MyComponent via the `children` prop.
MyComponent { "------ example" }
}
.view(&cx)
}
#[component]
fn MyComponent(cx: &Arc<Context>, children: &Rsx) -> View {
rsx! {
// `@{children}` is an RSX expression that renders the children passed to MyComponent.
// It's a special syntax to embed an `Rsx` value directly into the component's output.
@{children}
"Simple Component"
}
.view(&cx)
}
2. Run the Application
cargo run
You should see output similar to this:
------ example
Simple Component
The exact positioning will depend on your terminal's size and OSUI's default rendering behavior, but the text "------ example" (from the child) should appear before "Simple Component" (from MyComponent itself).
Understanding the Component Pattern
The children Prop
In OSUI, just like in React or other component-based frameworks, content nested inside a component's rsx! invocation is implicitly passed as children.
When you write:
rsx! {
MyComponent { "------ example" }
}
The string literal "------ example" becomes the children prop for MyComponent.
MyComponent Definition
Let's look at MyComponent's definition:
#[component]
fn MyComponent(cx: &Arc<Context>, children: &Rsx) -> View {
// ...
}
#[component]: MarksMyComponentas a reusable component.cx: &Arc<Context>: The mandatory context parameter.children: &Rsx: This is where the magic happens. Any content passed as children within thersx!invocation forMyComponent(like"------ example") will be collected into anRsxtype and passed to thischildrenprop. TheRsxtype itself is a collection of renderable nodes.-> View: Components must return aView.
Rendering Children with @{children}
Inside MyComponent's rsx!:
rsx! {
@{children} // Renders the content passed to MyComponent
"Simple Component"
}
@{children}: This is an RSX expression. The@{...}syntax allows you to embed arbitrary Rust expressions directly into yourrsx!output. In this case,childrenis an&Rsxvalue which implementsToRsx, making it eligible to be directly rendered as part of the component's output. Whenchildrenis rendered, it generates its ownView, effectively embedding the child content into the parent component's render tree."Simple Component": This is a direct text literal withinMyComponent's own output, rendered after the children.
This pattern allows you to build highly flexible and composable components, where parents can define the overall structure and layout, while children provide specific content.
Next Steps
You've seen how to define components and pass basic children. The next step is to explore the full power of OSUI's RSX syntax, including how to pass other types of props, use conditional rendering, and loop through data.