Updated to 0.2.0

This commit is contained in:
2026-01-31 20:52:02 +01:00
parent a30c1ac52a
commit 0b7a72dc5d
56 changed files with 7365 additions and 0 deletions
@@ -0,0 +1,33 @@
markdown
---
sidebar_position: 0
title: Introduction
---
# Introduction to OSUI
OSUI is a powerful and flexible Rust library for building advanced Terminal User Interfaces (TUIs). It provides a component-based architecture inspired by modern web frameworks, offering a familiar and ergonomic development experience for crafting interactive command-line applications.
## What is OSUI?
OSUI stands for "Operating System User Interface" in the terminal context. It aims to bridge the gap between simple text-based applications and rich graphical user interfaces by offering a robust framework for complex TUI development.
### Key Features
* **Component System**: Build UIs using reusable, composable components that manage their own state and lifecycle.
* **Reactive State Management**: Leverage React-like hooks (`useState`, `useEffect`) for efficient and predictable state handling.
* **Declarative UI with RSX**: Define your UI structure using an intuitive, macro-based RSX (React-like Syntax) similar to JSX.
* **Event Handling**: A type-safe event system allows components to communicate and respond to user input and internal changes.
* **Pluggable Rendering Engine**: Ships with a `Console` engine for `crossterm`-based terminal rendering, and an extensible `Engine` trait for custom backends.
* **Benchmark Tooling**: Built-in benchmarking capabilities to measure and optimize rendering performance.
## Why OSUI?
Traditional TUI libraries often require imperative manipulation of the terminal buffer, which can become cumbersome for complex applications. OSUI addresses this by:
* **Promoting Modularity**: Components encapsulate UI logic and appearance, making code easier to organize, test, and maintain.
* **Simplifying State Logic**: The hook-based state management system ensures that your UI automatically reacts to data changes, reducing boilerplate and potential bugs.
* **Enhancing Developer Experience**: The `rsx!` macro and `#[component]` attribute provide a declarative way to define your UI, allowing you to focus on *what* your UI should look like, rather than *how* to draw it.
* **Encouraging Scalability**: The clear separation of concerns (components, state, rendering engine) makes OSUI suitable for applications ranging from simple utilities to complex interactive dashboards.
Whether you're building a CLI dashboard, an interactive configuration tool, or a text-based game, OSUI provides the tools to create engaging and performant terminal experiences.
@@ -0,0 +1,44 @@
markdown
---
sidebar_position: 1
title: Installation
---
# Installation
To get started with OSUI, you need to add it as a dependency to your Rust project. OSUI is available on [crates.io](https://crates.io/crates/osui).
## Adding OSUI to Your Project
Open your project in your terminal and run this command:
```bash
cargo add osui
```
The `osui` crate re-exports its procedural macros (`#[component]` and `rsx!`) through its `prelude` module, so you typically don't need to add `osui-macros` as a separate dependency.
## Enabling the `rsx` Feature (Recommended)
The `rsx` feature is crucial for using OSUI's declarative UI syntax. It is usually enabled by default when you add `osui` as a dependency. If you ever explicitly disable default features for `osui`, remember to re-enable `rsx`:
```toml
[dependencies]
osui = { version = "0.2.0", features = ["rsx"] }
```
:::info
The `rsx` feature is vital for using OSUI's `rsx!` macro and `#[component]` attribute, which are fundamental to building UIs in OSUI.
:::
## Building Your Project
Once `osui` is added to your `Cargo.toml`, you can build your project using Cargo:
```bash
cargo build
```
This will download and compile OSUI and its dependencies.
You are now ready to start building your first OSUI application! Proceed to the [Getting Started](./02-getting-started.md) guide to write your first "Hello World" component.
@@ -0,0 +1,90 @@
markdown
---
sidebar_position: 2
title: Getting Started
---
# Getting Started: Hello World
Let's write a minimal OSUI application that displays "Hello World" in the terminal. This example will introduce you to the core concepts of an OSUI application: the `Console` engine, running an application, and defining a basic component with `rsx!`.
## 1. Create a New Project
If you haven't already, create a new Rust binary project:
```bash
cargo new hello-osui
cd hello-osui
```
## 2. Add OSUI Dependency
```bash
cargo add osui
```
## 3. Write the Hello World Code
Open `src/main.rs` and replace its contents with the following:
```rust title="src/main.rs"
use osui::prelude::*; // Import commonly used OSUI items
use std::sync::Arc;
pub fn main() {
// 1. Initialize the Console engine
// The Console engine uses crossterm to interact with the terminal.
let engine = Console::new();
// 2. Run the application
// The `run` method takes your root component and starts the rendering loop.
// It returns a `Result`, which we unwrap here for simplicity.
engine.run(App {}).expect("Failed to run OSUI application");
}
/// 3. Define your root component
/// The `#[component]` attribute transforms a function into a reusable UI component.
/// - The first parameter `cx: &Arc<Context>` is mandatory and provides access to component context (state, events, children).
/// - Components must return a `View`.
#[component]
fn App(cx: &Arc<Context>) -> View {
// 4. Use RSX (React-like Syntax) to define the UI
// `rsx!` is a procedural macro for declarative UI construction.
// Here, it just renders a simple string literal.
rsx! {
"Hello World"
}
// `view(&cx)` converts the RSX into a `View` that can be rendered.
.view(&cx)
}
```
## 4. Run Your Application
Execute your application from the terminal:
```bash
cargo run
```
You should see "Hello World" displayed in your terminal, which will then clear when the application exits.
## Understanding the Code
Let's break down the key parts of the "Hello World" example:
* **`use osui::prelude::*;`**: This line imports the `prelude` module, which re-exports the most commonly used types and macros from OSUI. This includes `Console`, `Context`, `View`, `#[component]`, and `rsx!`.
* **`Console::new()`**: The `Console` struct is OSUI's default rendering engine. It uses the `crossterm` library to draw content to your terminal.
* **`engine.run(App {})`**: This starts the OSUI application lifecycle. It takes an instance of your root component (`App {}` in this case) and begins the continuous rendering loop. The `App` component will be rendered repeatedly until the application is stopped (e.g., by pressing `Ctrl+C` or a command from within the app).
* **`#[component] fn App(cx: &Arc<Context>) -> View { ... }`**:
* The `#[component]` attribute is a procedural macro that transforms a standard Rust function into an OSUI component. This enables prop handling and integration into the component tree.
* All component functions must take `cx: &Arc<Context>` as their first argument. The `Context` provides access to component-specific state, lifecycle methods, event handlers, and the ability to add child components.
* Component functions must return a `View`, which is an `Arc<dyn Fn(&mut DrawContext) + Send + Sync>`. This `View` represents the instructions for rendering the component.
* **`rsx! { "Hello World" }.view(&cx)`**:
* The `rsx!` macro is OSUI's declarative UI syntax. It allows you to define a hierarchy of components and text nodes in a way that feels similar to HTML or React's JSX.
* In this simple case, `"Hello World"` is a text literal that `rsx!` converts into a renderable element.
* The `.view(&cx)` method takes the `Rsx` object generated by the `rsx!` macro and processes it within the current `Context`, ultimately producing the final `View` to be returned by the component.
This simple example demonstrates the fundamental building blocks of an OSUI application. Next, we'll explore how to create more complex components and pass data between them.
**Next:** Learn about [Creating Components](./03-example-basic-component.md) and passing them data.
@@ -0,0 +1,113 @@
markdown
---
sidebar_position: 3
title: Basic Component with Children
---
# 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`.
```rust title="src/main.rs"
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
```bash
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:
```rust
rsx! {
MyComponent { "------ example" }
}
```
The string literal `"------ example"` becomes the `children` prop for `MyComponent`.
### `MyComponent` Definition
Let's look at `MyComponent`'s definition:
```rust
#[component]
fn MyComponent(cx: &Arc<Context>, children: &Rsx) -> View {
// ...
}
```
1. **`#[component]`**: Marks `MyComponent` as a reusable component.
2. **`cx: &Arc<Context>`**: The mandatory context parameter.
3. **`children: &Rsx`**: This is where the magic happens. Any content passed as children within the `rsx!` invocation for `MyComponent` (like `"------ example"`) will be collected into an `Rsx` type and passed to this `children` prop. The `Rsx` type itself is a collection of renderable nodes.
4. **`-> View`**: Components must return a `View`.
### Rendering Children with `@{children}`
Inside `MyComponent`'s `rsx!`:
```rust
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 your `rsx!` output. In this case, `children` is an `&Rsx` value which implements `ToRsx`, making it eligible to be directly rendered as part of the component's output. When `children` is rendered, it generates its own `View`, effectively embedding the child content into the parent component's render tree.
* **`"Simple Component"`**: This is a direct text literal within `MyComponent`'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.
**Next:** Dive into the details of the [RSX Syntax Guide](../guides/01-rsx-syntax.md).