-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Convert components concept docs from SC to FC (#2434)
* Convert components concept docs from SC to FC - moved struct components to advanced topics - added docs about HOC for Suspense and Context - added a ease-in topic before components that introduces HTML/CSS/JS in yew - edit components concept to use function components * translations * fix todo links * fix tests * spelling bee
- Loading branch information
1 parent
bd373d2
commit 6366925
Showing
39 changed files
with
1,648 additions
and
712 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
--- | ||
title: "Higher Order Components" | ||
--- | ||
|
||
There are several cases where Struct components dont directly support a feature (ex. Suspense) or require a lot of boiler plate to use the features (ex. Context). | ||
|
||
In those cases it is recommended to create function components that are higher order components. | ||
|
||
## Higher Order Components Definition | ||
|
||
Higher Order Components are components that dont add any new Html and only wrap some other component to provide extra functionality. | ||
|
||
### Example | ||
|
||
Hook into Context and pass it down to a struct component | ||
|
||
```rust | ||
use yew::prelude::*; | ||
|
||
#[derive(Clone, Debug, PartialEq)] | ||
struct Theme { | ||
foreground: String, | ||
background: String, | ||
} | ||
|
||
#[function_component] | ||
pub fn App() -> Html { | ||
let ctx = use_state(|| Theme { | ||
foreground: "#000000".to_owned(), | ||
background: "#eeeeee".to_owned(), | ||
}); | ||
|
||
html! { | ||
<ContextProvider<Theme> context={(*ctx).clone()}> | ||
<ThemedButtonHOC /> | ||
</ContextProvider<Theme>> | ||
} | ||
} | ||
|
||
// highlight-start | ||
#[function_component] | ||
pub fn ThemedButtonHOC() -> Html { | ||
let theme = use_context::<Theme>().expect("no ctx found"); | ||
|
||
html! {<ThemedButtonStructComponent {theme} />} | ||
} | ||
// highlight-end | ||
|
||
#[derive(Properties, PartialEq)] | ||
pub struct Props { | ||
pub theme: Theme, | ||
} | ||
|
||
struct ThemedButtonStructComponent; | ||
|
||
impl Component for ThemedButtonStructComponent { | ||
type Message = (); | ||
type Properties = Props; | ||
|
||
fn create(_ctx: &Context<Self>) -> Self { | ||
Self | ||
} | ||
|
||
fn view(&self, ctx: &Context<Self>) -> Html { | ||
let theme = &ctx.props().theme; | ||
html! { | ||
<button style={format!( | ||
"background: {}; color: {};", | ||
theme.background, | ||
theme.foreground | ||
)} | ||
> | ||
{ "Click me!" } | ||
</button> | ||
} | ||
} | ||
} | ||
|
||
|
||
|
||
|
||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
--- | ||
title: "CSS with classes!" | ||
description: "A handy macro to handle classes" | ||
comment: "Keep this file as short and simple as possible. Its purpose is to ease in the reader into components in Yew instead of providing proper API docs" | ||
--- | ||
|
||
import Tabs from "@theme/Tabs"; | ||
import TabItem from "@theme/TabItem"; | ||
|
||
> Yew mostly operates on the idea of keeping everything that a reusable piece of | ||
> UI may need, in one place - rust files. But also seeks to stay close to the | ||
> original look of the technology. | ||
Yew does not provide css in rs solutions natively, but helps with css by providing | ||
programmatic ways to interact with css classes. | ||
|
||
## Classes | ||
|
||
The struct `Classes` simplifies use of HTML classes: | ||
|
||
<Tabs> | ||
<TabItem value="Literal" label="Literal"> | ||
|
||
```rust | ||
use yew::{classes, html}; | ||
|
||
html! { | ||
<div class={classes!("container")}></div> | ||
}; | ||
``` | ||
|
||
</TabItem> | ||
<TabItem value="Multiple" label="Multiple"> | ||
|
||
```rust | ||
use yew::{classes, html}; | ||
|
||
html! { | ||
<div class={classes!("class-1", "class-2")}></div> | ||
}; | ||
``` | ||
|
||
</TabItem> | ||
<TabItem value="String" label="String"> | ||
|
||
```rust | ||
use yew::{classes, html}; | ||
|
||
html! { | ||
<div class={classes!(String::from("class-1 class-2"))}></div> | ||
}; | ||
``` | ||
|
||
</TabItem> | ||
<TabItem value="Optional" label="Optional"> | ||
|
||
```rust | ||
use yew::{classes, html}; | ||
|
||
html! { | ||
<div class={classes!(Some("class"))} /> | ||
}; | ||
``` | ||
|
||
</TabItem> | ||
<TabItem value="Vector" label="Vector"> | ||
|
||
```rust | ||
use yew::{classes, html}; | ||
|
||
html! { | ||
<div class={classes!(vec!["class-1", "class-2"])}></div> | ||
}; | ||
``` | ||
|
||
</TabItem> | ||
<TabItem value="Slice" label="Slice"> | ||
|
||
```rust | ||
use yew::{classes, html}; | ||
|
||
html! { | ||
<div class={classes!(["class-1", "class-2"].as_ref())}></div> | ||
}; | ||
``` | ||
|
||
</TabItem> | ||
</Tabs> | ||
|
||
We will expand upon this concept in [more CSS](../../more/css). | ||
|
||
## Inline Styles | ||
|
||
Currently Yew does not provide any help with inline styles natively: | ||
|
||
```rust | ||
use yew::{classes, html}; | ||
|
||
html! { | ||
<div styles="color: red;"></div> | ||
}; | ||
``` | ||
|
||
We will expand upon this concept in [more CSS](../../more/css). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
--- | ||
title: "HTML with html!" | ||
description: "Its HTML but not quite!" | ||
comment: "Keep this file as short and simple as possible. Its purpose is to ease in the reader into components in Yew instead of providing proper API docs" | ||
--- | ||
|
||
import Tabs from "@theme/Tabs"; | ||
import TabItem from "@theme/TabItem"; | ||
|
||
> Yew mostly operates on the idea of keeping everything that a reusable piece of | ||
> UI may need, in one place - rust files. But also seeks to stay close to the | ||
> original look of the technology. | ||
For HTML we achieve this by providing the `html!` macro: | ||
|
||
```rust | ||
use yew::prelude::*; | ||
|
||
let my_header: Html = html!{<img src="img_girl.jpg" alt="Girl in a jacket" width="500" height="600" />}; | ||
``` | ||
|
||
`html!` macro allows you to write html generation as if it was in a `.html` file and then behind the scenes by yew gets turned into internal builder patterns that generate all DOM nodes. | ||
|
||
As it is part of rust code it provides a easy way to switch from html to rust by applying curly brackets: | ||
|
||
```rust | ||
use yew::prelude::*; | ||
|
||
let header_text = "Hello world".to_string(); | ||
let header_html: Html = html!{<h1>{header_text}</h1>}; | ||
|
||
let count: usize = 5; | ||
let counter_html: Html = html!{<p>{"My age is: "}{count}</p>}; | ||
|
||
let combined_html: Html = html!{<div>{header_html}{counter_html}</div>}; | ||
``` | ||
|
||
One rule major rule comes with use of `html!` - you can only return 1 wrapping node: | ||
|
||
<Tabs> | ||
<TabItem value="Valid" label="Valid"> | ||
|
||
```rust | ||
use yew::html; | ||
|
||
html! { | ||
<div> | ||
<div></div> | ||
<p></p> | ||
</div> | ||
}; | ||
|
||
``` | ||
|
||
</TabItem> | ||
|
||
<TabItem value="Invalid" label="Invalid"> | ||
|
||
```rust, compile_fail | ||
use yew::html; | ||
// error: only one root html element allowed | ||
html! { | ||
<div></div> | ||
<p></p> | ||
}; | ||
``` | ||
|
||
</TabItem> | ||
</Tabs> | ||
|
||
To help with this rule and avoid `div` abuse `html!` allows fragments. Fragments are empty tags that do not provide any html result: | ||
|
||
```rust | ||
use yew::html; | ||
|
||
html! { | ||
<> | ||
<div></div> | ||
<p></p> | ||
</> | ||
}; | ||
|
||
``` | ||
|
||
We will introduce Yew and HTML further in depth in [more HTML](../html). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
--- | ||
title: "JS with RS" | ||
description: "Javascript with Rust" | ||
comment: "Keep this file as short and simple as possible. Its purpose is to ease in the reader into components in Yew instead of providing proper API docs" | ||
--- | ||
|
||
import Tabs from "@theme/Tabs"; | ||
import TabItem from "@theme/TabItem"; | ||
|
||
> Yew mostly operates on the idea of keeping everything that a reusable piece of | ||
> UI may need, in one place - rust files. But also seeks to stay close to the | ||
> original look of the technology. | ||
Sadly as of today WebAssembly is not feature-complete for DOM interactions. This means even in Yew we sometimes rely on calling Javascript. | ||
|
||
## wasm-bindgen | ||
|
||
[`wasm-bindgen`](https://github.com/rustwasm/wasm-bindgen) is a library and tool that allows to call javascript from rust and rust from javascript. | ||
|
||
We highly recommend you give a look to their [documentation](https://rustwasm.github.io/docs/wasm-bindgen/) | ||
|
||
We will also expand upon this concept in the [more wasm-bindgen](../wasm-bindgen). | ||
|
||
## web-sys | ||
|
||
The [`web-sys` crate](https://crates.io/crates/web-sys) provides bindings for Web APIs and allows us to write Javascript code in a rustyfied and safe way. | ||
|
||
Example: | ||
|
||
<Tabs> | ||
<TabItem value="JS" label="JS"> | ||
|
||
```js | ||
let document = window.document; | ||
``` | ||
|
||
</TabItem> | ||
|
||
<TabItem value="RS" label="RS"> | ||
|
||
```rust ,no_run | ||
use wasm_bindgen::UnwrapThrowExt; | ||
use web_sys::window; | ||
|
||
let document = window() | ||
.expect_throw("window is undefined") | ||
.document() | ||
.expect_throw("document is undefined"); | ||
``` | ||
|
||
</TabItem> | ||
</Tabs> | ||
|
||
Once again we highly recommend you give a look to their [documentation](https://rustwasm.github.io/docs/wasm-bindgen/) | ||
|
||
We will also expand upon this concept in the [more wasm-bindgen](../wasm-bindgen). |
Oops, something went wrong.
6366925
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yew master branch benchmarks (Lower is better)
yew-struct-keyed 01_run1k
213.4295
162.92700000000002
1.31
yew-struct-keyed 02_replace1k
234.239
172.9105
1.35
yew-struct-keyed 03_update10th1k_x16
448.5355
312.041
1.44
yew-struct-keyed 04_select1k
90.4245
68.25
1.32
yew-struct-keyed 05_swap1k
99.735
92.3215
1.08
yew-struct-keyed 06_remove-one-1k
30.8775
30.8305
1.00
yew-struct-keyed 07_create10k
2698.133
2175.1040000000003
1.24
yew-struct-keyed 08_create1k-after1k_x2
557.3240000000001
432.8855
1.29
yew-struct-keyed 09_clear1k_x8
251.2665
210.3835
1.19
yew-struct-keyed 21_ready-memory
0.9634513854980468
0.9634513854980468
1
yew-struct-keyed 22_run-memory
1.4578094482421875
1.4578094482421875
1
yew-struct-keyed 23_update5-memory
1.4615478515625
1.5068473815917969
0.97
yew-struct-keyed 24_run5-memory
1.510845184326172
1.510845184326172
1
yew-struct-keyed 25_run-clear-memory
1.1287879943847656
1.1287879943847656
1
yew-struct-keyed 31_startup-ci
1857.71075
1882.03
0.99
yew-struct-keyed 32_startup-bt
31.641999999999992
40.54199999999999
0.78
yew-struct-keyed 34_startup-totalbytes
367.962890625
367.962890625
1
This comment was automatically generated by workflow using github-action-benchmark.