Update Docs CI with mdbook translation support (#516)

* Update Docs CI with mdbook translation support #514

* install mdbook with --rev
This commit is contained in:
Marco Godoy authored and GitHub committed 2022-08-04 10:26:04 -05:00
1 parent df5338f4e6
commit 9538cfe733
37 files changed
+151 -145

No files matched your search

@@ -9,7 +9,7 @@ To avoid repetition, you can encapsulate business logic based on existing hooks
For example, if many components need to access an `AppSettings` struct, you can create a "shortcut" hook:
```rust
{{#include ../../examples/hooks_composed.rs:wrap_context}}
{{#include ../../../examples/hooks_composed.rs:wrap_context}}
```
## Custom Hook Logic
@@ -7,7 +7,7 @@ Sometimes you want to render different things depending on the state/props. With
To render different elements based on a condition, you could use an `if-else` statement:
```rust
{{#include ../../examples/conditional_rendering.rs:if_else}}
{{#include ../../../examples/conditional_rendering.rs:if_else}}
```
> You could also use `match` statements, or any Rust function to conditionally render different things.
@@ -18,7 +18,7 @@ To render different elements based on a condition, you could use an `if-else` st
Since `Element` is a `Option<VNode>`, components accepting `Element` as a prop can actually inspect its contents, and render different things based on that. Example:
```rust
{{#include ../../examples/component_children_inspect.rs:Clickable}}
{{#include ../../../examples/component_children_inspect.rs:Clickable}}
```
You can't mutate the `Element`, but if you need a modified version of it, you can construct a new one based on its attributes/children/etc.
@@ -29,7 +29,7 @@ You can't mutate the `Element`, but if you need a modified version of it, you ca
To render nothing, you can return `None` from a component. This is useful if you want to conditionally hide something:
```rust
{{#include ../../examples/conditional_rendering.rs:conditional_none}}
{{#include ../../../examples/conditional_rendering.rs:conditional_none}}
```
This works because the `Element` type is just an alias for `Option<VNode>`
@@ -50,7 +50,7 @@ For this, Dioxus accepts iterators that produce `Element`s. So we need to:
Example: suppose you have a list of comments you want to render. Then, you can render them like this:
```rust
{{#include ../../examples/rendering_lists.rs:render_list}}
{{#include ../../../examples/rendering_lists.rs:render_list}}
```
### The `key` Attribute
@@ -9,7 +9,7 @@ Event handlers are similar to regular attributes, but their name usually starts
For example, to handle clicks on an element, we can specify an `onclick` handler:
```rust
{{#include ../../examples/event_click.rs:rsx}}
{{#include ../../../examples/event_click.rs:rsx}}
```
## The `Event` object
@@ -30,7 +30,7 @@ To learn what the different event types provide, read the [events module docs](h
When you have e.g. a `button` inside a `div`, any click on the `button` is also a click on the `div`. For this reason, Dioxus propagates the click event: first, it is triggered on the target element, then on parent elements. If you want to prevent this behavior, you can call `cancel_bubble()` on the event:
```rust
{{#include ../../examples/event_click.rs:rsx}}
{{#include ../../../examples/event_click.rs:rsx}}
```
## Prevent Default
@@ -40,7 +40,7 @@ Some events have a default behavior. For keyboard events, this might be entering
In some instances, might want to avoid this default behavior. For this, you can add the `prevent_default` attribute with the name of the handler whose default behavior you want to stop. This attribute is special: you can attach it multiple times for multiple attributes:
```rust
{{#include ../../examples/event_prevent_default.rs:prevent_default}}
{{#include ../../../examples/event_prevent_default.rs:prevent_default}}
```
Any event handlers will still be called.
@@ -52,15 +52,15 @@ Any event handlers will still be called.
Sometimes, you might want to make a component that accepts an event handler. A simple example would be a `FancyButton` component, which accepts an `on_click` handler:
```rust
{{#include ../../examples/event_handler_prop.rs:component_with_handler}}
{{#include ../../../examples/event_handler_prop.rs:component_with_handler}}
```
Then, you can use it like any other handler:
```rust
{{#include ../../examples/event_handler_prop.rs:usage}}
{{#include ../../../examples/event_handler_prop.rs:usage}}
```
> Note: just like any other attribute, you can name the handlers anything you want! Though they must start with `on`, for the prop to be automatically turned into an `EventHandler` at the call site.
>
>
> You can also put custom data in the event, rather than e.g. `MouseData`
+8 -8
View File
@@ -2,7 +2,7 @@
So far our components, being Rust functions, had no state – they were always rendering the same thing. However, in a UI component, it is often useful to have stateful functionality to build user interactions. For example, you might want to track whether the user has openend a drop-down, and render different things accordingly.
For stateful logic, you can use hooks. Hooks are Rust functions that take a reference to `ScopeState` (in a component, you can pass `&cx`), and provide you with functionality and state.
For stateful logic, you can use hooks. Hooks are Rust functions that take a reference to `ScopeState` (in a component, you can pass `&cx`), and provide you with functionality and state.
## `use_state` Hook
@@ -15,7 +15,7 @@ For stateful logic, you can use hooks. Hooks are Rust functions that take a refe
For example, you might have seen the counter example, in which state (a number) is tracked using the `use_state` hook:
```rust
{{#include ../../examples/hooks_counter.rs:component}}
{{#include ../../../examples/hooks_counter.rs:component}}
```
![Screenshot: counter app](./images/counter.png)
@@ -26,7 +26,7 @@ Every time the component's state changes, it re-renders, and the component funct
You can use multiple hooks in the same component if you want:
```rust
{{#include ../../examples/hooks_counter_two_state.rs:component}}
{{#include ../../../examples/hooks_counter_two_state.rs:component}}
```
![Screenshot: app with two counters](./images/counter_two_state.png)
@@ -37,7 +37,7 @@ The above example might seem a bit magic, since Rust functions are typically not
But how can Dioxus differentiate between multiple hooks in the same component? As you saw in the second example, both `use_state` functions were called with the same parameters, so how come they can return different things when the counters are different?
```rust
{{#include ../../examples/hooks_counter_two_state.rs:use_state_calls}}
{{#include ../../../examples/hooks_counter_two_state.rs:use_state_calls}}
```
This is only possible because the two hooks are always called in the same order, so Dioxus knows which is which. So the order you call hooks matters, which is why you must follow certain rules when using hooks:
@@ -52,17 +52,17 @@ These rules mean that there are certain things you can't do with hooks:
### No Hooks in Conditionals
```rust
{{#include ../../examples/hooks_bad.rs:conditional}}
{{#include ../../../examples/hooks_bad.rs:conditional}}
```
### No Hooks in Closures
```rust
{{#include ../../examples/hooks_bad.rs:closure}}
{{#include ../../../examples/hooks_bad.rs:closure}}
```
### No Hooks in Loops
```rust
{{#include ../../examples/hooks_bad.rs:loop}}
{{#include ../../../examples/hooks_bad.rs:loop}}
```
## `use_ref` Hook
@@ -76,7 +76,7 @@ Thankfully, there is another hook for that, `use_ref`! It is similar to `use_sta
Here's a simple example that keeps a list of events in a `use_ref`. We can acquire write access to the state with `.write()`, and then just `.push` a new value to the state:
```rust
{{#include ../../examples/hooks_use_ref.rs:component}}
{{#include ../../../examples/hooks_use_ref.rs:component}}
```
> The return values of `use_state` and `use_ref`, (`UseState` and `UseRef`, respectively) are in some ways similar to [`Cell`](https://doc.rust-lang.org/std/cell/) and [`RefCell`](https://doc.rust-lang.org/std/cell/struct.RefCell.html) – they provide interior mutability. However, these Dioxus wrappers also ensure that the component gets re-rendered whenever you change the state.
@@ -12,7 +12,7 @@ For example, suppose we want to build a meme editor. We want to have an input to
We start with a `Meme` component, responsible for rendering a meme with a given caption:
```rust
{{#include ../../examples/meme_editor.rs:meme_component}}
{{#include ../../../examples/meme_editor.rs:meme_component}}
```
> Note that the `Meme` component is unaware where the caption is coming from – it could be stored in `use_state`, `use_ref`, or a constant. This ensures that it is very reusable – the same component can be used for a meme gallery without any changes!
@@ -20,12 +20,12 @@ We start with a `Meme` component, responsible for rendering a meme with a given
We also create a caption editor, completely decoupled from the meme. The caption editor must not store the caption itself – otherwise, how will we provide it to the `Meme` component? Instead, it should accept the current caption as a prop, as well as an event handler to delegate input events to:
```rust
{{#include ../../examples/meme_editor.rs:caption_editor}}
{{#include ../../../examples/meme_editor.rs:caption_editor}}
```
Finally, a third component will render the other two as children. It will be responsible for keeping the state and passing down the relevant props.
```rust
{{#include ../../examples/meme_editor.rs:meme_editor}}
{{#include ../../../examples/meme_editor.rs:meme_editor}}
```
![Meme Editor Screenshot: An old plastic skeleton sitting on a park bench. Caption: "me waiting for a language feature"](./images/meme_editor_screenshot.png)
@@ -44,23 +44,23 @@ Dioxus offers a better solution than this "prop drilling" – providing context.
First, we have to create a struct for our dark mode configuration:
```rust
{{#include ../../examples/meme_editor_dark_mode.rs:DarkMode_struct}}
{{#include ../../../examples/meme_editor_dark_mode.rs:DarkMode_struct}}
```
Now, in a top-level component (like `App`), we can provide the `DarkMode` context to all children components:
Now, in a top-level component (like `App`), we can provide the `DarkMode` context to all children components:
```rust
{{#include ../../examples/meme_editor_dark_mode.rs:context_provider}}
{{#include ../../../examples/meme_editor_dark_mode.rs:context_provider}}
```
As a result, any child component of `App` (direct or not), can access the `DarkMode` context.
```rust
{{#include ../../examples/meme_editor_dark_mode.rs:use_context}}
{{#include ../../../examples/meme_editor_dark_mode.rs:use_context}}
```
> `use_context` returns `Option<UseSharedState<DarkMode>>` here. If the context has been provided, the value is `Some(UseSharedState)`, which you can call `.read` or `.write` on, similarly to `UseRef`. Otherwise, the value is `None`.
For example, here's how we would implement the dark mode toggle, which both reads the context (to determine what color it should render) and writes to it (to toggle dark mode):
```rust
{{#include ../../examples/meme_editor_dark_mode.rs:toggle}}
{{#include ../../../examples/meme_editor_dark_mode.rs:toggle}}
```
@@ -7,7 +7,7 @@ Interfaces often need to provide a way to input data: e.g. text, numbers, checkb
With controlled inputs, you are directly in charge of the state of the input. This gives you a lot of flexibility, and makes it easy to keep things in sync. For example, this is how you would create a controlled text input:
```rust
{{#include ../../examples/input_controlled.rs:component}}
{{#include ../../../examples/input_controlled.rs:component}}
```
Notice the flexibility – you can:
@@ -24,7 +24,7 @@ As an alternative to controlled inputs, you can simply let the platform keep tra
Since you don't necessarily have the current value of the uncontrolled input in state, you can access it either by listening to `oninput` events (similarly to controlled components), or, if the input is part of a form, you can access the form data in the form events (e.g. `oninput` or `onsubmit`):
```rust
{{#include ../../examples/input_uncontrolled.rs:component}}
{{#include ../../../examples/input_uncontrolled.rs:component}}
```
```
Submitted! UiEvent { data: FormData { value: "", values: {"age": "very old", "date": "1966", "name": "Fred"} } }