This commit is contained in:
2025-06-30 12:19:17 -05:00
parent c2a3899fe1
commit 915dabe9e2
17 changed files with 773 additions and 1 deletions
@@ -0,0 +1,96 @@
---
title: RSX
---
This macro is the recommended way to describe a ui, it is a div that holds multiple elements
```rust
fn app() -> Element {
rsx! {
button { "click me" }
text { "This is some text" }
}
}
```
> :::info `rsx!` is really just a div, so you can just do something like
> ```rust
> rsx! {
> id: "root", class: "root",
>
> button { "click me" }
> text { "This is some text" }
> }
> ```
## Child values
If you want to add more children to values then just simply express it like a `rsx!`
```rust
fn app() -> Element {
let x = 69;
rsx! {
div {
text { "the number is {x}, Nice!" }
}
}
}
```
## Formatted text
```rust
fn app() -> Element {
let x = 69;
rsx! {
text { "the number is {x}, Nice!" }
}
}
```
> :::info You can also do expressions after the string
```rust
text { "the number is {}, Nice!", x }
```
## For loops
```rust
fn app() -> Element {
rsx! {
for (i in 0..5) { // () are required
text { "{i}" }
}
}
}
```
## Attribute
You can change the element's struct fields by just providing some attributes before the children
```rust
fn app() -> Element {
rsx! {
text { class: "my_text" }
}
}
```
## Type assignment
In special elements like `data_holder` You can specify what `type` the element holds. It would act like `my_fn::<Type>()`
```rust
fn app() -> Element {
rsx! {
// assign the type u32
data_holder as u32 { id: "count" }
}
}
```
## Handler functions
Instead of closures which are tricky to work with on structs, We use `Handler`, It's basically a closure wrapped with a `Arc<Mutex<T>>`
```rust
fn app() -> Element {
rsx! {
button {
on_click: fn(btn: &mut Button, event, document) {
// do something
}
}
}
}
```
@@ -0,0 +1,24 @@
---
title: Handler
---
A `Handler` is a closure wrapper. Due to how closures work, they aren't the best to work with on structs (in this case: elements). So to fix this we use a `Handler` which is a wrapper for the closure, Then you can safely clone and use it without any problems (in which a normal closure would fail at)
## Examples
```rust
Handler::new(|btn: &mut Button, event, document| {
// do something
})
```
A better way to do this is:
```rust
rsx! {
button {
// No need for Handler::new
on_click: fn(btn: &mut Button, event, document) {
// do something
}
}
}
```
> :::info `fn() {}` is a part of our macro `rsx!`. In rust you would normally use `|| {}`
@@ -0,0 +1,66 @@
---
title: CSS
---
Along with the `Css` type, This macro provides styling for multiple elements by their class name or struct name.
## Style by classname
```rust
fn app() -> Element {
rsx! {
styling: Some(styles()) // Set the css styling for the div.
button { class: "my_btn", "Click me!" }
}
}
fn styles() -> Css {
css! {
.my_btn { // style by classname
color: Red,
}
}
}
```
## Style by state
```rust
fn app() -> Element {
rsx! {
styling: Some(styles()) // Set the css styling for the div.
button { class: "my_btn", "Click me!" }
}
}
fn styles() -> Css {
css! {
.my_btn: clicked { // When the element state is clicked
color: Blue,
}
}
}
```
## Style by struct name
```rust
fn app() -> Element {
rsx! {
styling: Some(styles()) // Set the css styling for the div.
button { "Click me!" } // No need for classes
}
}
fn styles() -> Css {
css! {
Button { // style by the struct name
color: Red,
}
Button: clicked { // When the element state is clicked
color: Blue,
}
}
}
```
@@ -0,0 +1,20 @@
---
title: Style
---
Like `css!`, `style!` is a way to style a element. But unlike `css!`, `style!` is only meant to style a single element
```rust
rsx! {
button {
style: style! {
color: Red,
clicked { // when the button state is 'clicked'
color: Blue,
}
},
"click me!"
}
}
```
@@ -0,0 +1,28 @@
---
title: Document
---
The `Document` holds the root element and it renders and passes events to the `Element`. It's important for updating the UI.
## Example
```rust
fn(_, _, document) {
if let Some(my_text) = document.get_element_by_id::<Text>("my_text") {
my_text.children.set_text("Updated!");
}
}
```
## Methods
### `exit()`
Exits the program
### `restart()`
Restarts the program
### `get_element_by_id<T>(id: &str) -> Option<&mut Box<T>>`
Retrieves a mutable reference to a boxed element of type T by its string identifier, returning None if no such element exists.
> :::info Please make sure that the type of the element is correctly matched to the element of that id
### `get_element_by_id_raw(id: &str) -> Option<&mut Element>`
> :::warning Not recommended to use this function, Use `get_element_by_id` instead
Retrieves a mutable reference to a boxed element by its string identifier, returning None if no such element exists
### `render()`
Renders/reloads the screen, useful when a element updates
@@ -0,0 +1,5 @@
---
title: Element
---
`Element` is a type alias of `Box<dyn ElementWidget>`. It makes the code look cleaner
@@ -0,0 +1,14 @@
---
title: ElementWidget
---
`ElementWidget` is a trait that defines the Elements and it's rendering / event updates.
## Methods
### `render(&self, focused: bool) -> Option<RenderResult>`
- **required**
- This function renders the element
### `event(&mut self, event: Event, document: &Document)`
- **optional**
- This function updates the element when there is a event
@@ -0,0 +1,32 @@
---
title: ElementCore
---
`ElementCore` is a trait that will automatically be implemented by the `osui_element::element` proc-macro. All of it's functions are used by OSUI.
## `element` proc-macro
This macro adds the essential fields and functions for a `ElementCore` structure.
```rust
use osui_element::element;
#[element]
#[derive(Default, Debug)]
struct MyElement {}
```
## `elem_fn` proc-macro
This macro makes a function that returns a `Box<T>` of which T is the default of `MyElement`
```rust
use osui_element::{element, elem_fn};
#[element]
#[elem_fn]
#[derive(Default, Debug)]
struct MyElement {}
```
>:::info
>You can also define a function for the element manually:
>```rust
>pub fn my_element() -> Box<MyElement> {
> Box::new(MyElement::default())
>}
>```