diff --git a/docs/guide/src/components/component_children.md b/docs/guide/src/components/component_children.md index d425132ba..9fb0f8552 100644 --- a/docs/guide/src/components/component_children.md +++ b/docs/guide/src/components/component_children.md @@ -1,6 +1,6 @@ # Passing children and attributes -Often times, you'll want to wrap some important functionality *around* your state, not directly nested *inside* another component. In these cases, you'll want to pass elements and attributes into a component and let the component place them appropriately. +Oftentimes, you'll want to wrap some important functionality *around* your state, not directly nested *inside* another component. In these cases, you'll want to pass elements and attributes into a component and let the component place them appropriately. In this chapter, you'll learn about: - Passing elements into components @@ -216,4 +216,3 @@ In this chapter, we learned: - How the `attributes` field works on component properties - How to convert `listeners` into `EventHandlers` for components - How to extend any node with custom attributes and children - diff --git a/docs/guide/src/components/propsmacro.md b/docs/guide/src/components/propsmacro.md index a86a453e2..ec9ff255e 100644 --- a/docs/guide/src/components/propsmacro.md +++ b/docs/guide/src/components/propsmacro.md @@ -1,12 +1,14 @@ # Component Properties + Dioxus components are functions that accept Props as input and output an Element. In fact, the `App` function you saw in the previous chapter was a component with no Props! Most components, however, will need to take some Props to render something useful – so, in this section, we'll learn about props: - Deriving the Props trait - Memoization through PartialEq - Optional fields on props -- The inline_props macro +- The inline_props macro ## Props + The input of your Component must be passed in a single struct, which must implement the `Props` trait. We can derive this trait automatically with `#[derive(Props)]`. > Dioxus `Props` is very similar to [@idanarye](https://github.com/idanarye)'s [TypedBuilder crate](https://github.com/idanarye/rust-typed-builder) and supports many of the same parameters. @@ -56,10 +58,10 @@ And we can see that the Component indeed gets rendered: ![Screenshot of running app. Text: "+ \ 42 \ -"](component_example_votes.png) > The simplest Owned Props you can have is `()` - or no value at all. This is what the `App` Component takes as props. `Scope` accepts a generic for the Props which defaults to `()`. -> +> > ```rust >// this scope ->Scope<()> +>Scope<()> > >// is the same as this scope >Scope @@ -146,13 +148,13 @@ fn Demo(cx: MyProps) -> Element { Some(d) => d, // if a value is provided None => "No description" // if the prop is omitted }; - + cx.render(rsx! { "{name}": "{text}" }) } ``` -In this example ˋnameˋ is a required prop and ˋdescriptionˋ is optional. +In this example `name` is a required prop and `description` is optional. This means we can completely omit the description field when calling the component: ```rust @@ -163,20 +165,20 @@ rsx!{ } } ``` -Additionally if we provide a value we don't have to wrap it with ˋSome(…)ˋ. This is done automatically for us: +Additionally if we provide a value we don't have to wrap it with `Some(…)`. This is done automatically for us: -ˋˋˋrust +```rust rsx!{ Demo { name: "Thing".to_string(), description: "This is explains it".to_string(), } } -ˋˋˋ +``` -If you want to make a prop required even though it is of type ˋOptionˋ you can provide the ˋ!optionalˋ modifier: +If you want to make a prop required even though it is of type `Option` you can provide the `!optional` modifier: -ˋˋˋrust +```rust #[derive(Props, PartialEq)] struct MyProps { name: String, @@ -184,11 +186,11 @@ struct MyProps { #[props(!optional)] description: Option } -ˋˋˋ +``` -This can be especially useful if you have a type alias named ˋOptionˋ in the current scope. +This can be especially useful if you have a type alias named `Option` in the current scope. -For more information on how tags work, check out the [TypedBuilder](https://github.com/idanarye/rust-typed-builder) crate. However, all attributes for props in Dioxus are flattened (no need for `setter` syntax) and the `optional` field is new. The `optional` modifier is a combination of two separate modifiers: `default` and `strip_option` and it is automatically detected on ˋOption<…>ˋ types. +For more information on how tags work, check out the [TypedBuilder](https://github.com/idanarye/rust-typed-builder) crate. However, all attributes for props in Dioxus are flattened (no need for `setter` syntax) and the `optional` field is new. The `optional` modifier is a combination of two separate modifiers: `default` and `strip_option` and it is automatically detected on `Option<…>` types. The full list of Dioxus' modifiers includes: diff --git a/docs/guide/src/elements/conditional_rendering.md b/docs/guide/src/elements/conditional_rendering.md index 5c19de237..f5d2836f3 100644 --- a/docs/guide/src/elements/conditional_rendering.md +++ b/docs/guide/src/elements/conditional_rendering.md @@ -1,6 +1,6 @@ # Conditional Rendering -Your components will often need to display different things depending on different conditions. With Dioxus, we can use Rust's normal control flow to conditional hide, show, and modify the structure of our markup. +Your components will often need to display different things depending on different conditions. With Dioxus, we can use Rust's normal control flow to conditionally hide, show, and modify the structure of our markup. In this chapter, you'll learn: - How to return different Elements depending on a condition diff --git a/docs/guide/src/elements/special_attributes.md b/docs/guide/src/elements/special_attributes.md index a09ce0bf7..7b4e1ba40 100644 --- a/docs/guide/src/elements/special_attributes.md +++ b/docs/guide/src/elements/special_attributes.md @@ -7,7 +7,6 @@ In this section, we'll cover special attributes built into Dioxus: - `dangerous_inner_html` - Boolean attributes - `prevent_default` - - event handlers as string attributes - `value`, `checked`, and `selected` @@ -31,7 +30,7 @@ fn BlogPost(cx: Scope) -> Element { ``` > Note! This attribute is called "dangerous_inner_html" because it is **dangerous** to pass it data you don't trust. If you're not careful, you can easily expose cross-site-scripting (XSS) attacks to your users. -> +> > If you're handling untrusted input, make sure to sanitize your HTML before passing it into `dangerous_inner_html` – or just pass it to a Text Element to escape any HTML tags. @@ -49,9 +48,9 @@ rsx!{ } } ``` -wouldn't actually render the `hidden` attribute: +wouldn't actually render the `hidden` attribute: ```html -
hello
+
hello
``` Not all attributes work like this however. *Only the following attributes* have this behavior: @@ -87,9 +86,9 @@ For any other attributes, a value of `"false"` will be sent directly to the DOM. ## Stopping form input and navigation with `prevent_default` -Currently, calling `prevent_default` on events in EventHandlers is not possible from Desktop/Mobile. Until this is supported, it's possible to prevent default using the `prevent_default` attribute. +Currently, calling `prevent_default` on events in EventHandlers is not possible from Desktop/Mobile. Until this is supported, it's possible to prevent default using the `prevent_default` attribute. -> Note: you cannot conditionally prevent default with this approach. This is a limitation until synchronous event handling is available across the Webview boundary +> Note: you cannot conditionally prevent default with this approach. This is a limitation until synchronous event handling is available across the Webview boundary To use `prevent_default`, simply attach the `prevent_default` attribute to a given element and set it to the name of the event handler you want to prevent default on. We can attach this attribute multiple times for multiple attributes. @@ -104,7 +103,7 @@ rsx!{ } } ``` - diff --git a/docs/guide/src/elements/vnodes.md b/docs/guide/src/elements/vnodes.md index 4adbf962d..5312306f0 100644 --- a/docs/guide/src/elements/vnodes.md +++ b/docs/guide/src/elements/vnodes.md @@ -8,6 +8,7 @@ In this chapter, we'll cover: - Element properties ## Declaring our first Element + Because Dioxus is mostly used with HTML/CSS renderers, the default Element "collection" is HTML. Provided the `html` feature is not disabled, we can declare Elements using the `rsx!` macro: ```rust @@ -29,6 +30,7 @@ Produces: ``` We can construct any valid HTML tag with the `tag {}` pattern and expect the resulting HTML structure to resemble our declaration. + ## Composing Elements Of course, we need more complex structures to make our apps actually useful! Just like HTML, the `rsx!` macro lets us nest Elements inside of each other. @@ -81,7 +83,7 @@ let name = "Bob"; rsx! ( "hello {name}" ) ``` -Unfortunately, you cannot drop in arbitrary expressions directly into the string literal. In the cases where we need to compute a complex value, we'll want to use `format_args!` directly. Due to specifics of the `rsx!` macro (which we'll cover later), our call to `format_args` must be contained within square braces. +Unfortunately, you cannot yet drop in arbitrary expressions directly into the string literal with Rust. In the cases where we need to compute a complex value, we'll want to use `format_args!` directly. Due to specifics of the `rsx!` macro (which we'll cover later), our call to `format_args` must be contained within square braces. ```rust rsx!( [format_args!("Hello {}", if enabled { "Jack" } else { "Bob" } )] ) @@ -150,7 +152,7 @@ All element attributes must occur *before* child elements. The `rsx!` macro will Listeners are a special type of Attribute that only accept functions. Listeners let us attach functionality to our Elements by running a provided closure whenever the specified Listener is triggered. -We'll cover listeners in more depth in the Listeners chapter, but for now, just know that every listener must start with the `on` keyword and accepts closures. +We'll cover listeners in more depth in the Adding Interactivity chapter, but for now, just know that every listener starts with "on" and accepts closures. ```rust rsx!( diff --git a/docs/guide/src/hello_world.md b/docs/guide/src/hello_world.md index 6bcc77e30..d01122959 100644 --- a/docs/guide/src/hello_world.md +++ b/docs/guide/src/hello_world.md @@ -115,13 +115,13 @@ At this point, you could call `cargo run` and be greeted with a simple `Hello, W ### Dissecting our example -The `use` statement at the top of our app imports everything from the the `prelude` module. `use`-ing the prelude imports the right traits, types, and macros needed for working with Dioxus. +The `use` statement at the top of our app imports everything from the `prelude` module. `use`-ing the prelude imports the right traits, types, and macros needed for working with Dioxus. ```rust use dioxus::prelude::*; ``` -This initialization code launches a Tokio runtime on a helper thread where your code will run. Then, the WebView renderer will be launched on the main-thread. Due to platform requirements, the main thread is blocked by your app's event loop. +This initialization code launches a Tokio runtime on a helper thread where your code will run. Then, the WebView renderer will be launched on the main thread. Due to platform requirements, the main thread is blocked by your app's event loop. ```rust fn main() { diff --git a/docs/guide/src/interactivity/event_handlers.md b/docs/guide/src/interactivity/event_handlers.md index ee6a7675f..89139adb4 100644 --- a/docs/guide/src/interactivity/event_handlers.md +++ b/docs/guide/src/interactivity/event_handlers.md @@ -1,6 +1,6 @@ # Event handlers -To make our boring UIs less static and more interesting, we want to add the ability to interact to user input. To do this, we need to add some event handlers. +To make our boring UIs less static and more interesting, we want to add the ability to interact with user input. To do this, we need to add some event handlers. ## The most basic events: clicks @@ -82,7 +82,7 @@ div { } ``` -In this particular layout, a click on the inner div is transitively also a click on the outer div. If we didn't want the outer div to be triggered every time we trigger the inner div, then we'd want to call "cancel_bubble". +In this particular layout, a click on the inner div is transitively also a click on the outer div. If we didn't want the outer div to be triggered every time we trigger the inner div, then we'd want to call `cancel_bubble()`. This will prevent any listeners above the current listener from being triggered. @@ -102,7 +102,7 @@ div { ## Prevent Default -With HTML based renderers, the browser will automatically perform some action. For text inputs, this would be entering the provided key. For forms, this might involve navigating the page. +With HTML-based renderers, the browser will automatically perform some action. For text inputs, this would be entering the provided key. For forms, this might involve navigating the page. In some instances, you don't want this default behavior. In these cases, instead of handling the event directly, you'd want to prevent any default handlers. diff --git a/docs/guide/src/interactivity/index.md b/docs/guide/src/interactivity/index.md index b6b9abc88..02c39b5b1 100644 --- a/docs/guide/src/interactivity/index.md +++ b/docs/guide/src/interactivity/index.md @@ -157,7 +157,7 @@ fn App(cx: Scope)-> Element { } ``` -Using asynchronous code can be difficult! This is just scratching the surface of what's possible. We have an entire chapter on using async properly in your Dioxus Apps. We have an entire section dedicated to using `async` properly later in this book. +Using asynchronous code can be difficult! This is just scratching the surface of what's possible. We have an entire chapter on using async properly in your Dioxus Apps. ### How do I tell Dioxus that my state changed? @@ -173,9 +173,9 @@ With these building blocks, we can craft new hooks similar to `use_state` that l In general, Dioxus should be plenty fast for most use cases. However, there are some rules you should consider following to ensure your apps are quick. -- 1) **Don't call set_state _while rendering_**. This will cause Dioxus to unnecessarily re-check the component for updates or enter an infinite loop. -- 2) **Break your state apart into smaller sections.** Hooks are explicitly designed to "unshackle" your state from the typical model-view-controller paradigm, making it easy to reuse useful bits of code with a single function. -- 3) **Move local state down**. Dioxus will need to re-check child components of your app if the root component is constantly being updated. You'll get best results if rapidly-changing state does not cause major re-renders. +1) **Don't call set_state _while rendering_**. This will cause Dioxus to unnecessarily re-check the component for updates or enter an infinite loop. +2) **Break your state apart into smaller sections.** Hooks are explicitly designed to "unshackle" your state from the typical model-view-controller paradigm, making it easy to reuse useful bits of code with a single function. +3) **Move local state down**. Dioxus will need to re-check child components of your app if the root component is constantly being updated. You'll get best results if rapidly-changing state does not cause major re-renders.