From 03af81fc6ff8de32a304196c4b6f7a22178cbc14 Mon Sep 17 00:00:00 2001 From: gitbook-bot Date: Tue, 26 Nov 2019 23:10:58 -0500 Subject: [PATCH 001/119] Initialize repository --- README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000000..e69de29bb2d From 1b375dadc326b6fb461f896b6d5179085f82aa3f Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Wed, 27 Nov 2019 04:11:07 +0000 Subject: [PATCH 002/119] GitBook: [master] 17 pages and one asset modified --- .gitbook/assets/yew.svg | 7 ++ README.md | 8 +++ SUMMARY.md | 19 ++++++ agents.md | 42 ++++++++++++ componentlink.md | 34 ++++++++++ components.md | 144 ++++++++++++++++++++++++++++++++++++++++ external-libs.md | 22 ++++++ getting-started.md | 119 +++++++++++++++++++++++++++++++++ how-it-works.md | 8 +++ html.md | 141 +++++++++++++++++++++++++++++++++++++++ optimizations.md | 96 +++++++++++++++++++++++++++ properties.md | 70 +++++++++++++++++++ refs.md | 29 ++++++++ router.md | 28 ++++++++ services.md | 8 +++ testing.md | 8 +++ web-sys.md | 8 +++ what-is-yew.md | 37 +++++++++++ 18 files changed, 828 insertions(+) create mode 100644 .gitbook/assets/yew.svg create mode 100644 SUMMARY.md create mode 100644 agents.md create mode 100644 componentlink.md create mode 100644 components.md create mode 100644 external-libs.md create mode 100644 getting-started.md create mode 100644 how-it-works.md create mode 100644 html.md create mode 100644 optimizations.md create mode 100644 properties.md create mode 100644 refs.md create mode 100644 router.md create mode 100644 services.md create mode 100644 testing.md create mode 100644 web-sys.md create mode 100644 what-is-yew.md diff --git a/.gitbook/assets/yew.svg b/.gitbook/assets/yew.svg new file mode 100644 index 00000000000..3082a4c3da2 --- /dev/null +++ b/.gitbook/assets/yew.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/README.md b/README.md index e69de29bb2d..21c5eb7b104 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,8 @@ +# Initial page + +{% page-ref page="what-is-yew.md" %} + +{% page-ref page="getting-started.md" %} + + + diff --git a/SUMMARY.md b/SUMMARY.md new file mode 100644 index 00000000000..e196f4d7aa2 --- /dev/null +++ b/SUMMARY.md @@ -0,0 +1,19 @@ +# Table of contents + +* [Initial page](README.md) +* [What Is Yew?](what-is-yew.md) +* [Getting Started](getting-started.md) +* [html!](html.md) +* [Components](components.md) +* [Properties](properties.md) +* [ComponentLink and Callbacks](componentlink.md) +* [Agents](agents.md) +* [Services](services.md) +* [web-sys](web-sys.md) +* [Refs](refs.md) +* [Testing](testing.md) +* [Optimizations & Best Practices](optimizations.md) +* [Low-level library internals](how-it-works.md) +* [Router](router.md) +* [External Libs](external-libs.md) + diff --git a/agents.md b/agents.md new file mode 100644 index 00000000000..f2b07462731 --- /dev/null +++ b/agents.md @@ -0,0 +1,42 @@ +--- +description: Yew's Actor System +--- + +# Agents + +Agents are similar to Angular's [Services](https://angular.io/guide/architecture-services) \(but without dependency injection\), and provide a Yew with an [Actor Model](https://en.wikipedia.org/wiki/Actor_model). Agents can be used to route messages between components independently of where they sit in the component hierarchy, or they can be used to coordinate global state, or they can be used to offload computationally expensive tasks off of the main UI-thread, or communicate between different tabs \(in the future\). + +Agents that run concurrently use [web-workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers) to achieve that concurrency. + +## Lifecycle + + + +## Types of Agents + +#### Reaches + +* Job - Spawn a new agent on the UI thread for every new bridge. This is good for moving shared but independent behavior that communicates with the browser out of components. \(TODO verify\) When the task is done, the agent will disappear. +* Context - Bridges will spawn or connect to an agent on the UI thread. This can be used to coordinate with state between components or other agents. When no bridges are are connected to this agent, the agent will disappear. +* Private - Same as Job, but runs on its own web worker. +* Public - Same as Context, but runs on its own web worker. +* Global \(WIP\) + +## Agent Communication + +### Bridges + +Bridges will connect to an agent and allow two way communication. + +### Dispatchers + +Dispatchers are like bridges, but they can only send messages to agents. + +## Overhead + +Agents communicate by serializing their messages using bincode\(???\). So there is a higher performance cost then just calling functions. Unless the cost of computation or the need to coordinate across arbitrary components will outweigh the cost of message passing, you should contain your logic to functions where possible. + + + + + diff --git a/componentlink.md b/componentlink.md new file mode 100644 index 00000000000..bb216b162ce --- /dev/null +++ b/componentlink.md @@ -0,0 +1,34 @@ +--- +description: ComponentLink and Callbacks. +--- + +# ComponentLink and Callbacks + +The component link is the mechanism through which component logic will register logic that can send messages to its associated component's update mechanism. + +#### send\_self + +Sends a message to the component immediately after the current loop finishes, causing another update loop to initiate. + +#### send\_back + +Registers a callback that will send a message to the component's update mechanism when it is executed. Under the hood, it will call `send_self` with the message that is returned by the provided closure. A`Fn(IN) -> Vec` is provided and a `Callback` is returned. + +#### send\_back\_batch + +Registers a callback that sends a batch of many messages at once when it is executed. If any of the messages cause the component to re-render, the component will re-render after all messages in the batch have been processed. A `Fn(IN) -> COMP::Message` is provided and a `Callback` is returned. + +#### send\_future + +Register a future that will send a message to the component's update mechanism when it completes. Because this uses promises under the hood, they start executing immediately when `send_future` is called, and no handle that represents the computation is returned. + + + +## Callbacks + +This might need its own short page. + +Callbacks are used to communicate with services, agents, and parent components within Yew. They are just a `Fn`wrapped by an `Rc` to allow them to be cloned. + +They have an `emit` function that takes their `` type as an argument and converts that to a message expected by its destination. If a callback from a parent is provided in props to a child component, the child can call `emit` on the callback in its `update` lifecycle hook to send a message back to its parent. Closures or Functions provided as props inside the `html!` macro are automatically converted to Callbacks. + diff --git a/components.md b/components.md new file mode 100644 index 00000000000..29ef1a690bd --- /dev/null +++ b/components.md @@ -0,0 +1,144 @@ +--- +description: Components and their lifecycle hooks +--- + +# Components + +## What are Components? + +A component is an independent bundle of state that can update itself and render itself to the DOM. + +`Component` is probably the most prominent trait in Yew. It describes the lifecycle of a component attached to the DOM. What happens when it is created, how it updates, how it renders, and more, is described by this trait. + +A struct that implements `Component` can be used in the `html!` macro in a variety of ways: + +```rust +html!{ + <> + // Alone (or with non-required props) + + + // With children (if the props for MyComponent have the field - children: Children) + +
{"Arbitrary Content"}
+
+ + // With Properties + + + // With the whole set of props provided at once + + +} +``` + +## Component lifecycle hooks and associated types + +### Associated types + +The `Component` trait has two associated types: `Message` and `Properties`. + +`Message` is typically an enum, although it can be a struct, that represents a variety of messages that can be processed by the component. It is common practice to create a type called `Msg` or `ComponentNameMsg` in your component's module and use that as the message type in the component. It is common to shorten "message" to "msg". + +The `Properties` associated type is a struct that has implemented the `Properties` trait \(usually by deriving it\). This type is used when creating and updating a component. It is common practice to create an enum called `Props` or `ComponentNameProps` in your component's module and use that as the component's `Properties` type. It is common to shorten "properties" to "props". Since props are handed down from parent components, the root component of your application typically has a `Properties` type of `()`, because it has no state to inherit from its parent. + +### Create + +When a component is created, it gets a copy of the component's properties, and a link, and is expected to produce an instance of the component's model - the model being the state that makes up the component. + +Properties come from the parent and should be used to initialize your component to a particular state, or be persisted in its entirety. The `ComponentLink` item is used to register callbacks or send messages to the component. It is useful to keep around for use in the `update()` method. + +It is common to keep all of the props, and the link as well for medium to large sized components. In these cases its recommended to structure the model you are implementing `Component` for like so: + +```rust +pub struct MyComponent { + /// State from the parent + props: MyComponentProps, + /// Utility object + link: ComponentLink, + /// State that is created durring the lifecycle of the component + input_box_text: String, + // ... +} +``` + +And implement `create()` like so: + +```rust +impl Component for MyComponent { + // ... + fn create(props: Self::Properties, link: ComponentLink) -> Self { + MyComponent { + props, + link, + ..Default::default() // Fill the remaining fields with their default values. + } + } + // ... +} +``` + +### Mounted + +`create()` initializes your component's state, but it isn't mounted to the DOM yet. `mounted()` is called directly after the component has been mounted to the DOM, which allows you perform actions that should be done after the component has rendered once. `mounted()` does not have to be implemented, and by default it will do nothing. + +### Update + +When a component receives a message, its `update()` method is called. This allows the component to update itself based on what the message was, and determine if it needs to re-render. Messages can come from HTML elements, child components, or Agents. + +An example of update would be: + +```rust +pub enum Msg { + SetInputBoxText(String) +} + +impl Component for MyComponent { + // ... + fn update(&mut self, msg: Self::Message) -> ShouldRender { + match msg { + Msg::SetInputBoxText(text) => { + self.input_box_text = text; + true // Re-render when the input box text is set. + } + } + } + // ... +} +``` + +### Change + +`change()` is like `update()` but it handles communications from its parent component. This is done in the form of its props being changed. You don't have to implement `change()` but you probably want to if you want to update a component via props after it has been created. + +A naive implementation would look like: + +```rust +impl Component for MyComponent { + // ... + fn change(&mut self, props: Self::Properties) -> ShouldRender { + self.props = props; + true // This will always re-render when new props are provided. + } + // ... +} +``` + +### Destroy + +Its called right before the component is unmounted from the DOM. + +### View + +`view()` is where you take a reference to the component's model, and create `Html` using the `html!` macro. `html!` has its own section, but in short, it acts like JSX does for React, embedding a HTML-alike language inside of Rust. + +TODO example + +## Nested Components + +TODO + +## Full example + +A complete example for the snippets code can be found here. + diff --git a/external-libs.md b/external-libs.md new file mode 100644 index 00000000000..672e4d0ab2e --- /dev/null +++ b/external-libs.md @@ -0,0 +1,22 @@ +--- +description: Libraries that can help with yew development +--- + +# External Libs + +### Yewtil + +Yewtil is a collection of common utilities that help you write Yew programs. It includes: + +* NeqAssign - As discussed earlier, is the best way to assign props to ensure minimal re-rendering. +* PureComponents - Components that don't update any of their state. Using NeqAssign under the hood, they act as memoized functions that are called from inside the `html!` macro like normal components are. +* Lrc - linked list reference counted smart pointer functions like `Rc` does, but allows for novel data update patterns. +* Mrc/Irc - Mutable/Immutable reference counted smart pointers that function like `Rc` but are more ergonomic to use within Yew, due to implementing `DerefMut` and `BorrowMut`for `Mrc`. This allows `Mrc` to be used with `NeqAssign`. `Irc` acts as an immutable view into the data, which makes this ideal for holding data used in display-only tasks. +* History - A history tracking wrapper that uses a `VecDeque` to hold on to previous values that it has represented. + +## Looking For + +Libraries that the ecosystem needs, but doesn't have yet. + +Bootstrap/MaterialUi/arbitrary css framewrok component wrappers. + diff --git a/getting-started.md b/getting-started.md new file mode 100644 index 00000000000..8471a1a00f9 --- /dev/null +++ b/getting-started.md @@ -0,0 +1,119 @@ +--- +description: How to set up and build your app +--- + +# Getting Started + +## Project Setup for Cargo Web + +Using cargo-web is pretty straight-forward: + +You create a new binary project: + +```bash +cargo new --bin my-app && cd my-app +``` + +Add yew to your dependencies: + +{% code title="Cargo.toml" %} +```text + [package] +name = "my-app" +version = "0.1.0" +authors = ["Your Name Here "] +edition = "2018" + +[dependencies] +yew = "0.10.0" +``` +{% endcode %} + +And copy the template into your `src/main.rs` file: + +{% code title="src/main.rs" %} +```rust +use yew::{html, Component, ComponentLink, Html, ShouldRender}; + +struct Model { } + +enum Msg { + DoIt, +} + +impl Component for Model { + // Some details are omitted. Explore the examples to see more. + type Message = Msg; + type Properties = (); + + fn create(_: Self::Properties, _: ComponentLink) -> Self { + Model { } + } + + fn update(&mut self, msg: Self::Message) -> ShouldRender { + match msg { + Msg::DoIt => { + // Update your model on events + true + } + } + } + + fn view(&self) -> Html { + html! { + // Render your model here + + } + } +} + +fn main() { + yew::start_app::(); +} +``` +{% endcode %} + +This template sets up your root component, called `Model` which shows a button that sends an message that does nothing when you click it. `yew::start_app::()` starts your app with the `Model` component as the root component. + +#### Building using Cargo Web + +To build and start a development server, run: + +```bash +cargo web start +``` + +This compile using the `wasm32-unknown-unknown` target and will make your application available at [http://\[::1\]:8000](http://[::1]:8000) by default. Consult `cargo web start --help` for other options. + +## Project Setup for wasm-pack + +If you want to use a JS Bundler instead of cargo web, it is recommended that you copy from an existing template. + +* [Minimal](https://github.com/yewstack/yew-wasm-pack-minimal) - Uses wasm-pack, and rollup to build your application, and your own server to serve it. No bells or whistles here. + * `python -m SimpleHTTPServer 8080` Is a good quick and dirty server for development purposes. +* [WebPack](https://github.com/yewstack/yew-wasm-pack-template) - WebPack is used to manage your development and deployments via a wasm-pack plugin. +* Parcel - Parcel is used to manage your development and deployments + +The important distinction between this approach and using cargo-web is that this approach uses a lib, not a bin target, and the entry-point to your program is annotated with `#[wasm_bindgen]` annotation and is called from a JS file you must supply yourself. + +Your `Cargo.toml` also should specify that you have a cdylib crate-type. + +{% code title="Cargo.toml" %} +```text + [package] +name = "my-app" +version = "0.1.0" +authors = ["Your Name Here "] +edition = "2018" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +yew = "0.10.0" +wasm-bindgen = "0.2" +``` +{% endcode %} + + + diff --git a/how-it-works.md b/how-it-works.md new file mode 100644 index 00000000000..88d5577c975 --- /dev/null +++ b/how-it-works.md @@ -0,0 +1,8 @@ +--- +description: Low level details about the framework +--- + +# Low-level library internals + +Component-lifecycle state machine, vdom diff algorithm. + diff --git a/html.md b/html.md new file mode 100644 index 00000000000..c53751ef63a --- /dev/null +++ b/html.md @@ -0,0 +1,141 @@ +--- +description: html! macro +--- + +# html! + +## HTML in Rust + +The `html!` macro allows you to write HTML in Rust, with a few extensions and modifications. It is comparable to the JSX syntax used prominently in React. + +\(Note:`Html` is an alias to `VNode)` + +### Fragments + +At the top-most level, the `html!` macro expects a single virtual dom node, which would preclude you from having something like: + +```rust +// INVALID +html! { +
+

+} +``` + +Fragments, which use `<>` syntax, are used to denote a list of items as the top level of a `html!` macro. + +```rust +// VALID +html! { + <> +
+

+ +} +``` + +### Expressions + +You can insert expressions in your HTML using `{}` blocks, as long as they resolve to `Html<_>.` + +```rust +let show_link = true; +html! { +
+ { + if show_link { + html! { + {"Link"} + } + } else { + html! { + "No link today" + } + } + } +
+} +``` + +It often makes sense to extract these expressions into functions or closures in order to keep the code from drifting rightward: + +```rust +let show_link = true; +let maybe_display_link = move || -> Html { + if show_link { + html! { + {"Link"} + } + } else { + html! { + "No link today" + } + } +} +html! { +
{maybe_display_link()}
+} +``` + +### Text + +If these expressions resolve to types that implement `Display`, they will be converted to strings and inserted into the DOM as a text node. + +All display text must be enclosed by `{}` blocks. + +```rust +let text = "lorem ipsum"; +html!{ + <> +
{text}
+
{"dolor sit"}
+ +} +``` + +### Callbacks + +Closures declared _within_ a `html!` macro are automatically converted to `Callbacks`. Callbacks will return messages to the component. They are used for receiving messages from child components, and for handling events from HTML elements like `input`s and `button`s. + +```rust +pub enum Msg { + ButtonClicked +} +html!{ + +} +``` + +If the message you want your callback to return _wraps_ the argument in the closure in a tuple-variant, you can use the function tuple syntax instead, but only for `Component`s, and not for plain elements. + +```rust +pub enum Msg { + ButtonClicked(ClickEvent) +} +html! { + +} +``` + +This extends to the case if the argument is the same as the message you want to capture: + +```rust +html! { + +} +// or +html! { + +} +``` + + + +### + +### Components + +See the following section on ways to use components in the `html!` macro. + + + diff --git a/optimizations.md b/optimizations.md new file mode 100644 index 00000000000..5776dd39db5 --- /dev/null +++ b/optimizations.md @@ -0,0 +1,96 @@ +--- +description: Make your app faster. +--- + +# Optimizations & Best Practices + +### neq\_assign + +When a component receives props from its parent component, the `change` method is called. This, in addition to allowing you to update the component's state, also allows you to return a `ShouldRender` boolean value that indicates if the component should re-render itself in response to the prop changes. + +Re-rendering is expensive, and if you can avoid it, you should. As a general rule, you only want to re-render when the props actually changed. The following block of code represents this rule, returning `true` if the props differed from the previous props: + +```rust +fn change(&mut self, props: Self::Properties) -> ShouldRender { + if self.props != &props { + *self.props = props; + true + } else { + false + } +} +``` + +But we can go further! This is six lines of boilerplate can be reduced down to one by using a trait and a blanket implementation for anything that implements `PartialEq`. + +{% code title="neq\_assign.rs" %} +```rust +pub trait NeqAssign { + fn neq_assign(&mut self, new: Self) -> ShouldRender; +} +impl NeqAssign for T { + fn neq_assign(&mut self, new: T) -> ShouldRender { + if self != &new { + *self = new; + true + } else { + false + } + } +} + +// ... +fn change(&mut self, props: Self::Properties) -> ShouldRender { + self.props.neq_assign(props) +} +``` +{% endcode %} + +The trait is called `NeqAssign` because it assigns the new value if the target and new value aren't equal. + +This is even shorter than the naive implementation: + +```rust +// Don't do this, unless you can't avoid it. +fn change(&mut self, props: Self::Properties) -> ShouldRender { + self.props = props; + true +} +``` + +You aren't limited to using this in the `change` function. It often makes sense to do this in the `update` function as well, although the performance wins aren't as obvious there. + +### wee\_alloc + +[wee\_alloc](https://github.com/rustwasm/wee_alloc) is a tiny allocator that is much smaller than the allocator that is normally used in Rust binaries. Replacing the default allocator with this one will result in smaller WASM file sizes, at the expense of speed and memory overhead. + +The slower speed and memory overhead are minor in comparison to the size gains made by not including the default allocator. This smaller file size means that your page will load faster, and so it is generally recommended that you use this allocator over the default, unless your app is doing some allocation-heavy work. + +```rust +// Use `wee_alloc` as the global allocator. +#[global_allocator] +static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; +``` + +### RC + +In an effort to avoid cloning large chunks of data to create props when re-rendering, we can use smart pointers to only clone the pointer instead. If you use `Rc<_>`s in your props and child components instead of plain unboxed values, you can delay cloning until you need to modify the data in the child component, where you use `Rc::make_mut` to clone and get a mutable reference to the data you want to alter. By not cloning until mutation, child components can reject props identical to their state-owned props in `Component::change` for almost no performance cost, versus the case where the data itself needs to be copied into the props struct in the parent before it is compared and rejected in the child. + +This optimization is most useful for data types that aren't `Copy`. If you can copy your data easily, then it probably isn't worth putting it behind a smart pointer. For structures that can contain lots of data like `Vec`, `HashMap`, and `String`, this optimization should be worthwhile. + +This optimization works best if the values are never updated by the children, and even better, if they are rarely updated by parents. This makes `Rc<_>s` a good choice for wrapping property values in for pure components. + +### View Functions + +For code readability reasons, it often makes sense to migrate sections of`html!` to their own functions so you can avoid the rightward drift present in deeply nested HTML. + +### Pure Components/Function Components + +Pure components are components that don't mutate their state, only displaying content and propagating messages up to normal, mutable components. They differ from view functions in that they can be used from within the `html!` macro using the component syntax \(``\) instead of expression syntax \(`{some_view_function()}`\), and that depending on their implementation, they can be memoized - preventing re-renders for identical props using aforementioned `neq_assign` logic. + +Yew doesn't natively support pure or function components, but they are available via external crates. + +Function components don't exist yet, but in theory, pure components could be generated by using proc macros and annotating functions. + +### Keyed DOM nodes when they arrive + diff --git a/properties.md b/properties.md new file mode 100644 index 00000000000..cfc7dd9da78 --- /dev/null +++ b/properties.md @@ -0,0 +1,70 @@ +--- +description: Parent to child communication +--- + +# Properties + +As stated in the Components page, Properties are used to communicate from a parent to a child component. + +## Derive macro + +Don't try to implement `Properties` yourself, instead derive it by using `#[derive(Properties)]` instead. + +### Required attribute + +The fields within a struct that implements `Properties` must be either `Default` or have a `#[props(required)]` attribute applied to them. This attribute signals to the framework that the field must be supplied when the component is created in a `html!` macro, otherwise you will receive a compiler error. For fields that aren't required, it is common to wrap them in an `Option`, which will default to `None` when the field isn't supplied. + +### PartialEq + +It often makes sense to derive `PartialEq` on your props if you can. This makes it much easier to avoid rerendering using a trick explained in the **Optimizations & Best Practices** section. + +## Memory/Speed overhead of Properties + +Remember the component's `view` function signature: + +```rust +fn view(&self) -> Html +``` + +You take a reference of the component's state, and use that to create `Html<_>`. But properties are owned values. This means that in order to create them and pass them to child components, we need to get ownership of the references provided in the `view` function. This is done by implicitly cloning the references as they are passed to components in order to get owned values that constitute their props. + +This means that each component has its own distinct copy of state passed down from its parent, and that whenever you re-render a component, the props for all child components of the re-rendering component will have to be cloned. + +The implication of this is if you would otherwise be passing _huge_ amounts of data down as props \(Strings that are 10s of kilobytes in size\), you may want to consider turning your child component into a `Html<_>`-returning function that runs in the parent, as you aren't forced to clone your data. + +Alternatively, if you won't need to alter the large data that is passed as props, and only will display it, you can wrap it in an `Rc` so that only a ref-counted pointer is cloned, instead of the data itself. + +## Example + +```rust +pub struct LinkColor { + Blue, + Red, + Green + Black, + Purple, +} + +impl Default for LinkColor { + fn default() -> Self { + // The link color will be Blue unless otherwise specified. + LinkColor::Blue + } +} + +#[derive(Properties, PartialEq)] +pub struct LinkProps { + /// The link must have a target. + #[props(required)] + href: String, + /// If the link text is huge, this will make copying the string much cheaper. + /// This isn't usually recromended unless performance is a problem. + #[props(required)] + text: Rc, + /// Color of the link. + color: LinkColor, + /// The view function will not specify a size if this is None. + size: Option +} +``` + diff --git a/refs.md b/refs.md new file mode 100644 index 00000000000..7351fb2bc2c --- /dev/null +++ b/refs.md @@ -0,0 +1,29 @@ +--- +description: Out-of-band DOM access +--- + +# Refs + +## Refs + +The `ref` keyword can be used inside of any HTML element or component to get the dom `Element` that the item is attached to. This can be used to make changes to the DOM outside of the `view` hook. + +This is useful for getting ahold of canvas elements, or telling divs to scroll to the bottom. + +The syntax is: + +```rust +// In create +self.node_ref = NodeRef::default(); + +// In view +html! { +
+} + +// In update +let has_attributes = self.node_ref.try_into::().has_attributes(); +``` + + + diff --git a/router.md b/router.md new file mode 100644 index 00000000000..7fc88dab77d --- /dev/null +++ b/router.md @@ -0,0 +1,28 @@ +--- +description: Yew-Router crate +--- + +# Router + +### Route + +Contains a String representing everything after the domain in the url and optionally the state stored in the history api. + +### RouteService + +Communicates with the browser to get and set Routes + +### RouteAgent + +Owns a RouteService and is used to coordinate updates when the route changes, either from within the application logic or from an event fired from the browser. + +### Switch + +The `Switch` trait is used to convert a `Route` to and from the implementer of this trait. + +### Router + +The Router component communicates with `RouteAgent` and will automatically resolve Routes it gets from the agent into switches, which it will expose via a `render` prop that allows specifying how the resulting switch gets converted to Html<\_> + +How to use the router. + diff --git a/services.md b/services.md new file mode 100644 index 00000000000..ad04b665d3b --- /dev/null +++ b/services.md @@ -0,0 +1,8 @@ +--- +description: Yew's glue to browser APIs. +--- + +# Services + +How to use some services. + diff --git a/testing.md b/testing.md new file mode 100644 index 00000000000..dd878cd4f79 --- /dev/null +++ b/testing.md @@ -0,0 +1,8 @@ +--- +description: Testing your app +--- + +# Testing + +How to test with cargo web and with wasm-pack. \(I honestly don't know at the moment\) + diff --git a/web-sys.md b/web-sys.md new file mode 100644 index 00000000000..1c9c778d406 --- /dev/null +++ b/web-sys.md @@ -0,0 +1,8 @@ +--- +description: Using web-sys instead of services. +--- + +# web-sys + +Using web-sys instead of services. + diff --git a/what-is-yew.md b/what-is-yew.md new file mode 100644 index 00000000000..c80cc632185 --- /dev/null +++ b/what-is-yew.md @@ -0,0 +1,37 @@ +--- +description: A high level overview of the framework. +--- + +# What Is Yew? + +## What is Yew? + +Yew is a frontend web framework, similar to React or Elm, that allows you to build websites with complex logic that runs in a web browser. Apps that use Yew are written in Rust, which compiles to Web Assembly \(**WASM**\), or plain JavaScript, in order to run in the browser. + +### Value Proposition + +Rust is the best positioned language that compiles to WASM given its nearly non-existent runtime \(leading to smaller file sizes\), and its various language features that allow safe usage of WASM as a target, while achieving maximum performance. Yew is a Rust/WASM framework, the architecture of which should be familiar to anyone who has used React or Elm, that allows you to build fast, small, and correct frontend web applications. + +### What Makes Up Yew? + +Yew is comprised of a few distinct parts that are used to create a working application. + +* `html!` macro - A procedural macro that creates a tree that represents HTML that will be shown in the browser. +* `Component` trait - Specifies how a data structure in Rust can be displayed in, as well as interact with, the browser. +* `Properties` trait - Allows components to pass state to child components. +* `Callback` event system - Allows child components, actors, or HTML elements to send messages to components. +* `Agent` trait - Specifies actors that can coordinate global state, or run independent tasks on web workers. +* `Services` - Rust glue code to APIs present in the browser. Examples include: fetch requests, timers, console access, and more. + +#### Dependencies + +Yew is built on top of `StdWeb`, a library that provides bindings between Rust and the Browser. Some features rely on another library called `web-sys`, which is auto-generated from web browser specification documents, and makes use of `wasm_bindgen`. + +#### Build environments + +If your app is architected to only use StdWeb-based features, you can use the `cargo-web` build tool to build, test, and run your application. If you want to make use of advanced features, or just prefer the ecosystem, you can use various existing JS bundlers and their wasm\_bindgen based plugins to build your app. These include building using `wasm-pack` and bundling it yourself using `rollup`, or using `Webpack` or `Parcel` to manage your development and deployment tasks. + +`cargo-web` supports compiling to JS via `Emscripten` or compiling to WASM using `rustc`, while using wasm\_bindgen based approaches only support compiling to WASM. + + + From 854f5f59226f238abd8204419f73306014ff8f3b Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Thu, 28 Nov 2019 03:38:14 +0000 Subject: [PATCH 003/119] GitBook: [master] one page modified --- external-libs.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/external-libs.md b/external-libs.md index 672e4d0ab2e..f5b47733cde 100644 --- a/external-libs.md +++ b/external-libs.md @@ -13,6 +13,8 @@ Yewtil is a collection of common utilities that help you write Yew programs. It * Lrc - linked list reference counted smart pointer functions like `Rc` does, but allows for novel data update patterns. * Mrc/Irc - Mutable/Immutable reference counted smart pointers that function like `Rc` but are more ergonomic to use within Yew, due to implementing `DerefMut` and `BorrowMut`for `Mrc`. This allows `Mrc` to be used with `NeqAssign`. `Irc` acts as an immutable view into the data, which makes this ideal for holding data used in display-only tasks. * History - A history tracking wrapper that uses a `VecDeque` to hold on to previous values that it has represented. +* Futures - Support for running futures that send messages to component update loops. +* Fetch - Abstractions for handling fetch requests made using `web_sys` and the aforementioned futures feature. ## Looking For From fb8901fe149d23ae9261483bb539d5399e0bfb5c Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Thu, 28 Nov 2019 03:38:51 +0000 Subject: [PATCH 004/119] GitBook: [master] one page modified --- html.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/html.md b/html.md index c53751ef63a..a489f0379c4 100644 --- a/html.md +++ b/html.md @@ -34,6 +34,23 @@ html! { } ``` +### Tag structure + +Tags deviate from normal HTML slightly. Opening tags must either have a corresponding closing tag, or be terminated with a `/>`. + +This will prevent you from copying and pasting some vanilla HTML into your Yew project. + +```rust +html! { + // INVALID + +} +html! { + // VALID + +} +``` + ### Expressions You can insert expressions in your HTML using `{}` blocks, as long as they resolve to `Html<_>.` @@ -81,7 +98,7 @@ html! { If these expressions resolve to types that implement `Display`, they will be converted to strings and inserted into the DOM as a text node. -All display text must be enclosed by `{}` blocks. +All display text must be enclosed by `{}` blocks because text is handled like an expression. This is the largest deviation from normal HTML syntax that Yew makes. ```rust let text = "lorem ipsum"; From 91122341ed15cb64329add68afb613cf927946f1 Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Thu, 28 Nov 2019 03:40:22 +0000 Subject: [PATCH 005/119] GitBook: [master] 2 pages modified --- optimizations.md | 8 ++++++++ testing.md | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/optimizations.md b/optimizations.md index 5776dd39db5..69f5bfb5ca1 100644 --- a/optimizations.md +++ b/optimizations.md @@ -94,3 +94,11 @@ Function components don't exist yet, but in theory, pure components could be gen ### Keyed DOM nodes when they arrive +### Compile speed optimizations using Cargo Workspaces + +Arguabley, the largest drawback to using Yew is the long time it takes to compile. Compile time seems to correlate with the quantity of code found within `html!` macro blocks. This tends to not be a significant problem for smaller projects, but for webapps that span multiple pages, it makes sense to break apart your code across multiple crates to minimize the amount of work the compiler has to do. + +You should try to make your main crate handle routing/page selection, move all commonly shared code to another crate, and then make a different crate for each page, where each page could be a different component, or just a big function that produces `Html<_>`. In the best case scenario, you go from rebuilding all of your code on each compile to rebuilding only the main crate, and one of your page crates. In the worst case, where you edit something in the "common" crate, you will be right back to where you started: compiling all code that depends on that commonly shared crate, which is probably everything else. + +If your main crate is too heavyweight, or you want to rapidly iterate on a deeply nested page \(eg. a page that renders on top of another page\), you can use an example crate to create a more simple implementation of the main page and render your work-in-progress component on top of that. + diff --git a/testing.md b/testing.md index dd878cd4f79..46cd2a888bc 100644 --- a/testing.md +++ b/testing.md @@ -6,3 +6,9 @@ description: Testing your app How to test with cargo web and with wasm-pack. \(I honestly don't know at the moment\) + + +## Rust WebDriving + +For programmatically driving UI integration testing using Rust, [https://crates.io/crates/fantoccini](https://crates.io/crates/fantoccini) is a recommended choice. It allows you to test your website by finding specific elements using CSS selectors, and then performing actions on them like inputting text, or clicking buttons, or waiting specific amounts of time for client code to execute \(eg, wait for a fetch request to finish and cause a UI change\). + From c3efe1a9dec2d961b3ca158363e6be9dfd1a5041 Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Thu, 28 Nov 2019 05:37:01 +0000 Subject: [PATCH 006/119] GitBook: [master] 7 pages modified --- README.md | 46 ++++++++++- SUMMARY.md | 8 +- getting-started.md | 119 --------------------------- getting-started/README.md | 91 ++++++++++++++++++++ getting-started/build-environment.md | 76 +++++++++++++++++ getting-started/examples.md | 13 +++ getting-started/starter-templates.md | 32 +++++++ 7 files changed, 260 insertions(+), 125 deletions(-) delete mode 100644 getting-started.md create mode 100644 getting-started/README.md create mode 100644 getting-started/build-environment.md create mode 100644 getting-started/examples.md create mode 100644 getting-started/starter-templates.md diff --git a/README.md b/README.md index 21c5eb7b104..11b9858f4fd 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,48 @@ -# Initial page +# Introduction -{% page-ref page="what-is-yew.md" %} +## What is Yew? -{% page-ref page="getting-started.md" %} +**Yew** is a modern Rust framework for creating multi-threaded frontend web apps with WebAssembly. +### Architecture +Yew's architecture is heavily inspired by Elm and React. The basic building block of a Yew app is called a `Component`. Each `Component` stores its own state, expresses how to render that state to HTML, and chooses how to respond to asynchronous updates. Yew maintains an internal "virtual DOM" in order to minimize the patches needed to update the browser page DOM for each re-render of a `Component`. + +### Concurrency + +Yew was built before the standardization of async-await and has promoted the use of the [actor model](https://en.wikipedia.org/wiki/Actor_model) of concurrency. This model will feel very natural if you choose to write the server side of your application with [actix-web](https://github.com/actix/actix-web). In Yew, an actor is called an `Agent`. Using agents, a Yew application can delegate tasks to worker threads using Web Workers and subscribe to async messages from those agents. + +An alternative approach is using futures which are can be leveraged through the [wasm-bindgen-futures](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen_futures/) crate which bridges Rust futures to JS Promises. An example project using futures and async-await can be found [here](https://github.com/yewstack/yew/tree/master/examples/futures). + +### HTML + +Yew includes a procedural macro for generating HTML. It closely resembles React's JSX with some exceptions _\(string literals and listener callbacks to name a few\)_. Here is a quick look at its usage: + +```rust +html! { +
+
+

{ "todos" }

+ { self.view_input(&model) } +
+
+ { self.view_entries(&model) } +
+
+} +``` + +Full guide [here](html.md) + +### Why Rust? + +Rust is a modern systems language pursuing safety, concurrency, and speed and has been voted the most loved programming languages [multiple](https://insights.stackoverflow.com/survey/2018#technology-_-most-loved-dreaded-and-wanted-languages) [years](https://insights.stackoverflow.com/survey/2019#technology-_-most-loved-dreaded-and-wanted-languages) in a row in Stack Overflow Developer Surveys. Rust can be compiled to WebAssembly using the `cargo` build system which can achieve near-native speeds in a browser. + +Similar to how Node.js web applications can share JavaScript code between the server and client, Rust-based apps can reuse the same Rust code for the server and client, with the client code first needing to be compiled to WebAssembly for execution in a browser. + +### Why WebAssembly? + +First of all, using WASM is not going to be faster than a JavaScript app if you're primarily using DOM APIs. This will probably change in the near future, with the adoption of [Web IDL](https://heycam.github.io/webidl/). But for the time being, Wasm applications have to serialize commands from Wasm to JavaScript to interact with the DOM which will impact performance. + +That being said, WebAssembly can be leveraged for data heavy and graphics intensive calculations in the background. When client UI performance is not too important \(internal tooling, for example\) using WebAssembly for the full web application can be acceptable. diff --git a/SUMMARY.md b/SUMMARY.md index e196f4d7aa2..4457ddce3d1 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -1,8 +1,10 @@ # Table of contents -* [Initial page](README.md) -* [What Is Yew?](what-is-yew.md) -* [Getting Started](getting-started.md) +* [Introduction](README.md) +* [Getting Started](getting-started/README.md) + * [Build Environment](getting-started/build-environment.md) + * [Starter Templates](getting-started/starter-templates.md) + * [Examples](getting-started/examples.md) * [html!](html.md) * [Components](components.md) * [Properties](properties.md) diff --git a/getting-started.md b/getting-started.md deleted file mode 100644 index 8471a1a00f9..00000000000 --- a/getting-started.md +++ /dev/null @@ -1,119 +0,0 @@ ---- -description: How to set up and build your app ---- - -# Getting Started - -## Project Setup for Cargo Web - -Using cargo-web is pretty straight-forward: - -You create a new binary project: - -```bash -cargo new --bin my-app && cd my-app -``` - -Add yew to your dependencies: - -{% code title="Cargo.toml" %} -```text - [package] -name = "my-app" -version = "0.1.0" -authors = ["Your Name Here "] -edition = "2018" - -[dependencies] -yew = "0.10.0" -``` -{% endcode %} - -And copy the template into your `src/main.rs` file: - -{% code title="src/main.rs" %} -```rust -use yew::{html, Component, ComponentLink, Html, ShouldRender}; - -struct Model { } - -enum Msg { - DoIt, -} - -impl Component for Model { - // Some details are omitted. Explore the examples to see more. - type Message = Msg; - type Properties = (); - - fn create(_: Self::Properties, _: ComponentLink) -> Self { - Model { } - } - - fn update(&mut self, msg: Self::Message) -> ShouldRender { - match msg { - Msg::DoIt => { - // Update your model on events - true - } - } - } - - fn view(&self) -> Html { - html! { - // Render your model here - - } - } -} - -fn main() { - yew::start_app::(); -} -``` -{% endcode %} - -This template sets up your root component, called `Model` which shows a button that sends an message that does nothing when you click it. `yew::start_app::()` starts your app with the `Model` component as the root component. - -#### Building using Cargo Web - -To build and start a development server, run: - -```bash -cargo web start -``` - -This compile using the `wasm32-unknown-unknown` target and will make your application available at [http://\[::1\]:8000](http://[::1]:8000) by default. Consult `cargo web start --help` for other options. - -## Project Setup for wasm-pack - -If you want to use a JS Bundler instead of cargo web, it is recommended that you copy from an existing template. - -* [Minimal](https://github.com/yewstack/yew-wasm-pack-minimal) - Uses wasm-pack, and rollup to build your application, and your own server to serve it. No bells or whistles here. - * `python -m SimpleHTTPServer 8080` Is a good quick and dirty server for development purposes. -* [WebPack](https://github.com/yewstack/yew-wasm-pack-template) - WebPack is used to manage your development and deployments via a wasm-pack plugin. -* Parcel - Parcel is used to manage your development and deployments - -The important distinction between this approach and using cargo-web is that this approach uses a lib, not a bin target, and the entry-point to your program is annotated with `#[wasm_bindgen]` annotation and is called from a JS file you must supply yourself. - -Your `Cargo.toml` also should specify that you have a cdylib crate-type. - -{% code title="Cargo.toml" %} -```text - [package] -name = "my-app" -version = "0.1.0" -authors = ["Your Name Here "] -edition = "2018" - -[lib] -crate-type = ["cdylib"] - -[dependencies] -yew = "0.10.0" -wasm-bindgen = "0.2" -``` -{% endcode %} - - - diff --git a/getting-started/README.md b/getting-started/README.md new file mode 100644 index 00000000000..8da7d783929 --- /dev/null +++ b/getting-started/README.md @@ -0,0 +1,91 @@ +--- +description: How to set up and build your app +--- + +# Getting Started + +## Quick Sample App + +First create a new binary project: + +```bash +cargo new --bin yew-app && cd yew-app +``` + +Add yew to your dependencies \(refer [here](https://docs.rs/yew) for the latest version\) + +{% code title="Cargo.toml" %} +```text + [package] +name = "yew-app" +version = "0.1.0" +authors = ["Yew App Developer "] +edition = "2018" + +[dependencies] +yew = "0.10.0" +``` +{% endcode %} + +Copy this template into your `src/main.rs` file: + +{% code title="src/main.rs" %} +```rust +use yew::{html, Component, ComponentLink, Html, ShouldRender}; + +struct App { + clicked: bool, +} + +enum Msg { + Click, +} + +impl Component for App { + type Message = Msg; + type Properties = (); + + fn create(_: Self::Properties, _: ComponentLink) -> Self { + Model { clicked: false } + } + + fn update(&mut self, msg: Self::Message) -> ShouldRender { + match msg { + Msg::Click => { + self.clicked = true; + true // Indicate that the Component should re-render + } + } + } + + fn view(&self) -> Html { + let button_text = if self.clicked { + "Clicked!" + } else { + "Click me!" + }; + + html! { + + } + } +} + +fn main() { + yew::start_app::(); +} +``` +{% endcode %} + +This template sets up your root `Component`, called `App` which shows a button which updates itself when you click it. `yew::start_app::()` starts your app and mounts it to the page's `` tag. + +#### Run your App! + +Using [`cargo-web`](https://github.com/koute/cargo-web) is the quickest way to get up and running. First install the tool with `cargo install cargo-web` and then to build and start a development server, run: + +```bash +cargo web start +``` + +This compiles using the `wasm32-unknown-unknown` target and will make your application available at [http://\[::1\]:8000](http://[::1]:8000) by default. Consult `cargo web start --help` for other options. + diff --git a/getting-started/build-environment.md b/getting-started/build-environment.md new file mode 100644 index 00000000000..16d202a7a1b --- /dev/null +++ b/getting-started/build-environment.md @@ -0,0 +1,76 @@ +# Build Environment + +## Build Tools + +As shown in [Getting Started](./), using `cargo-web` is the quickest way to get up and running. Unfortunately `cargo-web` requires multiple compile passes and therefore is not as fast as other approaches. The most popular alternative is called `wasm-pack`. Check out the [Starter Templates](starter-templates.md) to get up and running quickly. + +### `cargo-web` + +Cargo web is a cargo subcommand for building client web apps. It makes building and deploying web applications. Read more [here](https://github.com/koute/cargo-web). + +**Install** + +```bash +cargo install cargo-web +``` + +#### Build + +```bash +cargo web build +``` + +#### Run + +```bash +cargo web start +``` + +#### Supported Targets + +* `wasm32-unknown-unknown` +* `wasm32-unknown-emscripten` +* `asmjs-unknown-emscripten` + +### `wasm-pack` + +This tool was created by the Rust / Wasm Working Group and is the most actively developed tool for building WebAssembly applications. It supports building to a Node.JS package and has an accompanying Webpack plugin for easy integration with an existing JavaScript application. Find more information [here](https://rustwasm.github.io/docs/wasm-pack/introduction.html). + +{% hint style="info" %} +Note that your crate-type will need to be `cdylib`when using `wasm-pack` +{% endhint %} + +**Install** + +```bash +cargo install wasm-pack +``` + +#### Build + +This command will produce a bundle in the `./pkg` directory with your app's compiled WebAssembly along with a JavaScript wrapper which can be used to start your application. + +```bash +wasm-pack build +``` + +#### Bundle + +For more information on Rollup visit this [guide](https://rollupjs.org/guide/en/#quick-start) + +```bash +rollup ./main.js --format iife --file ./pkg/bundle.js +``` + +#### Serve + +Feel free to use your preferred server. Here we use a simple python server to serve to [http://\[::1\]:8000](http://[::1]:8000). + +```bash +python -m SimpleHTTPServer 8080 +``` + +#### Supported Targets + +* `wasm32-unknown-unknown` + diff --git a/getting-started/examples.md b/getting-started/examples.md new file mode 100644 index 00000000000..32718ee55f3 --- /dev/null +++ b/getting-started/examples.md @@ -0,0 +1,13 @@ +# Examples + +The Yew repository is chock-full of examples \(in various states of maintenance\). We recommend perusing them to get a feel for how to use different framework features. We also welcome pull-requests and issues for when they inevitably get neglected and need some ♥️ + +* \*\*\*\*[**Todo App**](https://github.com/yewstack/yew/tree/master/examples/todomvc)\*\*\*\* +* \*\*\*\*[**Custom Components**](https://github.com/yewstack/yew/tree/master/examples/custom_components)\*\*\*\* +* \*\*\*\*[**Multi-threading \(Agents\)**](https://github.com/yewstack/yew/tree/master/examples/multi_thread) +* \*\*\*\*[**Nested Components**](https://github.com/yewstack/yew/tree/master/examples/nested_list)\*\*\*\* +* \*\*\*\*[**Timer Service**](https://github.com/yewstack/yew/tree/master/examples/timer)\*\*\*\* +* \*\*\*\*[**Nested Components**](https://github.com/yewstack/yew/tree/master/examples/nested_list)\*\*\*\* + +\*\*\*\* + diff --git a/getting-started/starter-templates.md b/getting-started/starter-templates.md new file mode 100644 index 00000000000..97af457d0b4 --- /dev/null +++ b/getting-started/starter-templates.md @@ -0,0 +1,32 @@ +# Starter Templates + +## Project Setup for `wasm-pack` + +If you want to use a JS Bundler instead of cargo web, it is recommended that you copy from an existing template. + +* [Minimal Template](https://github.com/yewstack/yew-wasm-pack-minimal) - Uses `wasm-pack` and `rollup` to build your application, and your own server to serve it. No bells or whistles here. + * `python -m SimpleHTTPServer 8080` Is a good quick and dirty server for development purposes. +* [Webpack Template](https://github.com/yewstack/yew-wasm-pack-template) - Webpack is used to manage your development and deployments via a `wasm-pack` plugin. +* [Parcel Template](https://github.com/spielrs/yew-parcel-template) - Created by a community member and uses [Parcel](https://parceljs.org/) + +The important distinction between this approach and using `cargo-web` is that this approach uses a `lib`, not a `bin` crate, and the entry-point to your program is annotated with a `#[wasm_bindgen]` annotation. + +Your `Cargo.toml` also should specify that you have a "cdylib" crate-type. + +{% code title="Cargo.toml" %} +```text + [package] +name = "yew-app" +version = "0.1.0" +authors = ["Yew App Developer "] +edition = "2018" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +yew = "0.10.0" +wasm-bindgen = "0.2" +``` +{% endcode %} + From 3bb95652ca68b123ab3da61c27e401b9266a6aaf Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Thu, 28 Nov 2019 05:50:07 +0000 Subject: [PATCH 007/119] GitBook: [master] one page modified --- html.md | 98 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 54 insertions(+), 44 deletions(-) diff --git a/html.md b/html.md index a489f0379c4..cc1fe3e877b 100644 --- a/html.md +++ b/html.md @@ -1,5 +1,5 @@ --- -description: html! macro +description: The procedural macro for generating HTML --- # html! @@ -8,11 +8,13 @@ description: html! macro The `html!` macro allows you to write HTML in Rust, with a few extensions and modifications. It is comparable to the JSX syntax used prominently in React. -\(Note:`Html` is an alias to `VNode)` +{% hint style="info" %} +Note that`Html`is an alias to`VNode` +{% endhint %} ### Fragments -At the top-most level, the `html!` macro expects a single virtual dom node, which would preclude you from having something like: +The `html!` macro always requires a single root node. The following example will produce the following compiler message: `error: only one root html element allowed` ```rust // INVALID @@ -22,7 +24,7 @@ html! { } ``` -Fragments, which use `<>` syntax, are used to denote a list of items as the top level of a `html!` macro. +To work around this, Yew allows the use of fragments, which use `<>` syntax, to denote a list of items as the top level of a `html!` macro. ```rust // VALID @@ -34,69 +36,78 @@ html! { } ``` -### Tag structure +### Tags -Tags deviate from normal HTML slightly. Opening tags must either have a corresponding closing tag, or be terminated with a `/>`. - -This will prevent you from copying and pasting some vanilla HTML into your Yew project. +Tags are required to roughly follow the HTML standard syntax with some variations. For example, tags must either self-close... ```rust html! { - // INVALID - + // INVALID (MISSING SELF-CLOSE) + } + html! { // VALID } ``` +Or open tags must have a corresponding close tag + +```rust +html! { + // INVALID (MISSING CLOSE TAG) +
+} + +html! { + // VALID +
+} +``` + ### Expressions -You can insert expressions in your HTML using `{}` blocks, as long as they resolve to `Html<_>.` +You can insert expressions in your HTML using `{}` blocks, as long as they resolve to `Html<_>` ```rust -let show_link = true; html! { -
- { - if show_link { - html! { - {"Link"} - } - } else { - html! { - "No link today" - } - } - } -
+
+ { + if show_link { + html! { + {"Link"} + } + } else { + html! {} + } + } +
} ``` -It often makes sense to extract these expressions into functions or closures in order to keep the code from drifting rightward: +It often makes sense to extract these expressions into functions or closures to optimize for readability: ```rust let show_link = true; let maybe_display_link = move || -> Html { - if show_link { - html! { - {"Link"} - } - } else { - html! { - "No link today" - } - } -} + if show_link { + html! { + {"Link"} + } + } else { + html! {} + } +}; + html! {
{maybe_display_link()}
} ``` -### Text +### Text Literals -If these expressions resolve to types that implement `Display`, they will be converted to strings and inserted into the DOM as a text node. +If these expressions resolve to types that implement `Display`, they will be converted to strings and inserted into the DOM as a [Text](https://developer.mozilla.org/en-US/docs/Web/API/Text) node. All display text must be enclosed by `{}` blocks because text is handled like an expression. This is the largest deviation from normal HTML syntax that Yew makes. @@ -118,17 +129,19 @@ Closures declared _within_ a `html!` macro are automatically converted to `Callb pub enum Msg { ButtonClicked } + html!{ - + } ``` -If the message you want your callback to return _wraps_ the argument in the closure in a tuple-variant, you can use the function tuple syntax instead, but only for `Component`s, and not for plain elements. +If the message you want your callback to return _wraps_ the argument in the closure in a tuple-variant, you can use the function tuple syntax instead, but only for `Component`s, and not for plain elements \([Issue](https://github.com/yewstack/yew/issues/733)\) ```rust pub enum Msg { ButtonClicked(ClickEvent) } + html! { } @@ -140,16 +153,13 @@ This extends to the case if the argument is the same as the message you want to html! { } + // or html! { } ``` - - -### - ### Components See the following section on ways to use components in the `html!` macro. From e78089f669ef8ba3f3fc75904d0dfe5536577e6c Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Thu, 28 Nov 2019 17:41:06 +0000 Subject: [PATCH 008/119] GitBook: [master] 2 pages modified --- components.md | 8 ++++---- getting-started/README.md | 12 ++++++++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/components.md b/components.md index 29ef1a690bd..dcffd709ccd 100644 --- a/components.md +++ b/components.md @@ -6,7 +6,7 @@ description: Components and their lifecycle hooks ## What are Components? -A component is an independent bundle of state that can update itself and render itself to the DOM. +Components are the building blocks of Yew and contain their own state and can update and render themselves to the DOM. `Component` is probably the most prominent trait in Yew. It describes the lifecycle of a component attached to the DOM. What happens when it is created, how it updates, how it renders, and more, is described by this trait. @@ -32,9 +32,7 @@ html!{ } ``` -## Component lifecycle hooks and associated types - -### Associated types +## Associated Types The `Component` trait has two associated types: `Message` and `Properties`. @@ -42,6 +40,8 @@ The `Component` trait has two associated types: `Message` and `Properties`. The `Properties` associated type is a struct that has implemented the `Properties` trait \(usually by deriving it\). This type is used when creating and updating a component. It is common practice to create an enum called `Props` or `ComponentNameProps` in your component's module and use that as the component's `Properties` type. It is common to shorten "properties" to "props". Since props are handed down from parent components, the root component of your application typically has a `Properties` type of `()`, because it has no state to inherit from its parent. +## Component Lifecycle + ### Create When a component is created, it gets a copy of the component's properties, and a link, and is expected to produce an instance of the component's model - the model being the state that makes up the component. diff --git a/getting-started/README.md b/getting-started/README.md index 8da7d783929..22e461040af 100644 --- a/getting-started/README.md +++ b/getting-started/README.md @@ -4,6 +4,14 @@ description: How to set up and build your app # Getting Started +## Installation + +First, you'll need to install Rust. You can follow the official instructions [here](https://www.rust-lang.org/tools/install). Next, we'll be using `cargo-web` to create a sample app. You can install it by running: + +```bash +cargo install cargo-web +``` + ## Quick Sample App First create a new binary project: @@ -81,11 +89,11 @@ This template sets up your root `Component`, called `App` which shows a button w #### Run your App! -Using [`cargo-web`](https://github.com/koute/cargo-web) is the quickest way to get up and running. First install the tool with `cargo install cargo-web` and then to build and start a development server, run: +Using [`cargo-web`](https://github.com/koute/cargo-web) is the quickest way to get up and running. If you haven't already, install the tool with `cargo install cargo-web` and then build and start a development server by running: ```bash cargo web start ``` -This compiles using the `wasm32-unknown-unknown` target and will make your application available at [http://\[::1\]:8000](http://[::1]:8000) by default. Consult `cargo web start --help` for other options. +`cargo-web` should automatically add the `wasm32-unknown-unknown` target for you and then will build your app and make your application available at [http://\[::1\]:8000](http://[::1]:8000) by default. Consult `cargo web start --help` for other options. From 929d4e9705cef18a06b1886c25dcebadc644099c Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Thu, 28 Nov 2019 17:42:55 +0000 Subject: [PATCH 009/119] GitBook: [master] one page modified --- getting-started/build-environment.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/getting-started/build-environment.md b/getting-started/build-environment.md index 16d202a7a1b..ff0bd98f62a 100644 --- a/getting-started/build-environment.md +++ b/getting-started/build-environment.md @@ -32,6 +32,10 @@ cargo web start * `wasm32-unknown-emscripten` * `asmjs-unknown-emscripten` +{% hint style="info" %} +For `*-emscripten` targets, `cargo-web` will automatically install the Emscripten SDK and target for you. +{% endhint %} + ### `wasm-pack` This tool was created by the Rust / Wasm Working Group and is the most actively developed tool for building WebAssembly applications. It supports building to a Node.JS package and has an accompanying Webpack plugin for easy integration with an existing JavaScript application. Find more information [here](https://rustwasm.github.io/docs/wasm-pack/introduction.html). From 1eaf0c8d8af88ac24fed5366f69c1585150396d6 Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Thu, 28 Nov 2019 18:52:55 +0000 Subject: [PATCH 010/119] GitBook: [master] 2 pages modified --- SUMMARY.md | 1 + roadmap.md | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 roadmap.md diff --git a/SUMMARY.md b/SUMMARY.md index 4457ddce3d1..aa6f2a8d9c7 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -18,4 +18,5 @@ * [Low-level library internals](how-it-works.md) * [Router](router.md) * [External Libs](external-libs.md) +* [Roadmap](roadmap.md) diff --git a/roadmap.md b/roadmap.md new file mode 100644 index 00000000000..a3e608c1652 --- /dev/null +++ b/roadmap.md @@ -0,0 +1,36 @@ +--- +description: The planned feature roadmap for the Yew framework +--- + +# Roadmap + +## `v0.11.0` + +#### Planned Features + +* Easy generation of HTML fragments: [https://github.com/yewstack/yew/issues/743](https://github.com/yewstack/yew/issues/743) +* Nested components v2: [https://github.com/yewstack/yew/pull/756](https://github.com/yewstack/yew/pull/756) + +## `v1.0.0` + +#### Planned Features + +* Keyed list items [https://github.com/yewstack/yew/issues/479](https://github.com/yewstack/yew/issues/479) +* Migrate from `stdweb` to `web-sys` & `js-sys` [https://github.com/yewstack/yew/issues/558](https://github.com/yewstack/yew/issues/558) +* Routing: [https://github.com/yewstack/yew\_router](https://github.com/yewstack/yew_router) + +**Performance** + +* Add benchmark tooling [https://github.com/yewstack/yew/issues/5](https://github.com/yewstack/yew/issues/5) + +#### Guides + +* Best practices: [https://yew.rs/docs/optimizations](https://yew.rs/docs/optimizations) +* End-to-end Tutorial +* Futures / Concurrency +* CSS / Styling +* Testing +* State management + + + From 686f4dff1db23e5c09fc4eba128187157b20dbee Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Thu, 28 Nov 2019 18:58:55 +0000 Subject: [PATCH 011/119] GitBook: [master] one page modified --- roadmap.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/roadmap.md b/roadmap.md index a3e608c1652..2e3f23e37f1 100644 --- a/roadmap.md +++ b/roadmap.md @@ -32,5 +32,15 @@ description: The planned feature roadmap for the Yew framework * Testing * State management +## Future +#### Potential Features + +* Server Side Rendering: [https://github.com/yewstack/yew/issues/41](https://github.com/yewstack/yew/issues/41) +* Component Library: [https://github.com/yewstrap/yewstrap](https://github.com/yewstrap/yewstrap) +* Code Splitting [https://github.com/yewstack/yew/issues/599](https://github.com/yewstack/yew/issues/599) +* Allow different Virtual DOM backends: [https://github.com/yewstack/yew/issues/482](https://github.com/yewstack/yew/issues/482) +* Rethink Services: [https://github.com/yewstack/yew/issues/364](https://github.com/yewstack/yew/issues/364) +* Mature Utility crate: [https://github.com/yewstack/yewtil](https://github.com/yewstack/yewtil) +* HTML template alternatives: [https://github.com/yewstack/yew/issues/438](https://github.com/yewstack/yew/issues/438) From a802a7911c03468b8cc0d9e3f45dea332b05f6bc Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Thu, 28 Nov 2019 19:14:36 +0000 Subject: [PATCH 012/119] GitBook: [master] one page modified --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 11b9858f4fd..39566859c23 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,14 @@ Yew was built before the standardization of async-await and has promoted the use An alternative approach is using futures which are can be leveraged through the [wasm-bindgen-futures](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen_futures/) crate which bridges Rust futures to JS Promises. An example project using futures and async-await can be found [here](https://github.com/yewstack/yew/tree/master/examples/futures). +### Safety + +Rust helps developers write safer code. For example, in JavaScript, an uncaught error can cause serious problems in your application. Rust encourages proper error handling and you can even get stacktraces for your Rust code with the [`console_error_panic_hook`](https://github.com/rustwasm/console_error_panic_hook) crate. Also, Yew apps can leverage Rust's static typing to ensure that your `Component` receives the correct properties for creation \(otherwise your app won't compile!\). + +### JavaScript + +Yew is built on top of great web tooling like `wasm-bindgen` and `stdweb` and will be supporting `web-sys` and `js-sys` in the near future. These crates enable WebAssembly code to call into JavaScript and vice-versa. For some examples, visit [here](https://github.com/yewstack/yew/tree/master/examples/js_callback) to see how to leverage `stdweb` to write JavaScript code in your Rust app and [here](https://github.com/yewstack/yew/tree/master/examples/npm_and_rest) for how to interact with an NPM module. + ### HTML Yew includes a procedural macro for generating HTML. It closely resembles React's JSX with some exceptions _\(string literals and listener callbacks to name a few\)_. Here is a quick look at its usage: From c79d89546cf377f9acba2726ed5dca707a070ab0 Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Fri, 29 Nov 2019 04:23:11 +0000 Subject: [PATCH 013/119] GitBook: [master] one page modified --- html.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/html.md b/html.md index cc1fe3e877b..d634c3306b5 100644 --- a/html.md +++ b/html.md @@ -36,9 +36,9 @@ html! { } ``` -### Tags +### Elements -Tags are required to roughly follow the HTML standard syntax with some variations. For example, tags must either self-close... +Elements are required to roughly follow the standard HTML or SVG syntax with some variations. For example, element tags must either self-close... ```rust html! { @@ -52,7 +52,7 @@ html! { } ``` -Or open tags must have a corresponding close tag +Or open tags must have a corresponding close tag: ```rust html! { @@ -105,9 +105,9 @@ html! { } ``` -### Text Literals +### Literals -If these expressions resolve to types that implement `Display`, they will be converted to strings and inserted into the DOM as a [Text](https://developer.mozilla.org/en-US/docs/Web/API/Text) node. +If expressions resolve to types that implement `Display`, they will be converted to strings and inserted into the DOM as a [Text](https://developer.mozilla.org/en-US/docs/Web/API/Text) node. All display text must be enclosed by `{}` blocks because text is handled like an expression. This is the largest deviation from normal HTML syntax that Yew makes. From 067d2816e044f439f279c32499378cc4b0cad4a6 Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Sun, 1 Dec 2019 10:27:18 -0500 Subject: [PATCH 014/119] Create LICENSE --- LICENSE | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000000..0e259d42c99 --- /dev/null +++ b/LICENSE @@ -0,0 +1,121 @@ +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. From ce9a4bf79948d51b9a33745cce629f355abd886c Mon Sep 17 00:00:00 2001 From: Danilo Chiarlone <39843321+danbugs@users.noreply.github.com> Date: Sun, 1 Dec 2019 10:28:04 -0800 Subject: [PATCH 015/119] Changed 'Model' to 'App' (#1) --- getting-started/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/getting-started/README.md b/getting-started/README.md index 22e461040af..1a2855f514c 100644 --- a/getting-started/README.md +++ b/getting-started/README.md @@ -24,7 +24,8 @@ Add yew to your dependencies \(refer [here](https://docs.rs/yew) for the latest {% code title="Cargo.toml" %} ```text - [package] + +[package] name = "yew-app" version = "0.1.0" authors = ["Yew App Developer "] @@ -39,7 +40,7 @@ Copy this template into your `src/main.rs` file: {% code title="src/main.rs" %} ```rust -use yew::{html, Component, ComponentLink, Html, ShouldRender}; +use yew::{html, Component, ComponentLink, Html, ShouldRender}; struct App { clicked: bool, @@ -54,7 +55,7 @@ impl Component for App { type Properties = (); fn create(_: Self::Properties, _: ComponentLink) -> Self { - Model { clicked: false } + App { clicked: false } } fn update(&mut self, msg: Self::Message) -> ShouldRender { From 87d231a03e7b39a144510c353987f39927330360 Mon Sep 17 00:00:00 2001 From: jake <19259921+jakequade@users.noreply.github.com> Date: Mon, 2 Dec 2019 05:30:03 +1100 Subject: [PATCH 016/119] Gitbook: [master] one page modified (#2) Minor typo in `components.md`: 'durring' -> 'during'. Hope this isn't seen as me being nitpicky, just wanted to help :) --- components.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components.md b/components.md index dcffd709ccd..ea607d684a3 100644 --- a/components.md +++ b/components.md @@ -56,7 +56,7 @@ pub struct MyComponent { props: MyComponentProps, /// Utility object link: ComponentLink, - /// State that is created durring the lifecycle of the component + /// State that is created during the lifecycle of the component input_box_text: String, // ... } From 590b547a7f562ae84b35b14a91a50fe05d6fa857 Mon Sep 17 00:00:00 2001 From: Even Cai Date: Sun, 1 Dec 2019 18:59:22 +0000 Subject: [PATCH 017/119] GitBook: [master] 2 pages modified --- components.md | 14 +++++++------- getting-started/README.md | 5 ++--- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/components.md b/components.md index ea607d684a3..729097518ca 100644 --- a/components.md +++ b/components.md @@ -6,9 +6,9 @@ description: Components and their lifecycle hooks ## What are Components? -Components are the building blocks of Yew and contain their own state and can update and render themselves to the DOM. +Components are the building blocks of Yew and contain their own state and can update and render themselves to the DOM. -`Component` is probably the most prominent trait in Yew. It describes the lifecycle of a component attached to the DOM. What happens when it is created, how it updates, how it renders, and more, is described by this trait. +`Component` is probably the most prominent trait in Yew. It describes the lifecycle of a component attached to the DOM. What happens when it is created, how it updates, how it renders, and more, is described by this trait. A struct that implements `Component` can be used in the `html!` macro in a variety of ways: @@ -17,15 +17,15 @@ html!{ <> // Alone (or with non-required props) - + // With children (if the props for MyComponent have the field - children: Children)
{"Arbitrary Content"}
- + // With Properties - + // With the whole set of props provided at once @@ -46,9 +46,9 @@ The `Properties` associated type is a struct that has implemented the `Propertie When a component is created, it gets a copy of the component's properties, and a link, and is expected to produce an instance of the component's model - the model being the state that makes up the component. -Properties come from the parent and should be used to initialize your component to a particular state, or be persisted in its entirety. The `ComponentLink` item is used to register callbacks or send messages to the component. It is useful to keep around for use in the `update()` method. +Properties come from the parent and should be used to initialize your component to a particular state, or be persisted in its entirety. The `ComponentLink` item is used to register callbacks or send messages to the component. It is useful to keep around for use in the `update()` method. -It is common to keep all of the props, and the link as well for medium to large sized components. In these cases its recommended to structure the model you are implementing `Component` for like so: +It is common to keep all of the props, and the link as well for medium to large sized components. In these cases its recommended to structure the model you are implementing `Component` for like so: ```rust pub struct MyComponent { diff --git a/getting-started/README.md b/getting-started/README.md index 1a2855f514c..17bed827670 100644 --- a/getting-started/README.md +++ b/getting-started/README.md @@ -24,7 +24,6 @@ Add yew to your dependencies \(refer [here](https://docs.rs/yew) for the latest {% code title="Cargo.toml" %} ```text - [package] name = "yew-app" version = "0.1.0" @@ -73,7 +72,7 @@ impl Component for App { } else { "Click me!" }; - + html! { } @@ -88,7 +87,7 @@ fn main() { This template sets up your root `Component`, called `App` which shows a button which updates itself when you click it. `yew::start_app::()` starts your app and mounts it to the page's `` tag. -#### Run your App! +### Run your App! Using [`cargo-web`](https://github.com/koute/cargo-web) is the quickest way to get up and running. If you haven't already, install the tool with `cargo install cargo-web` and then build and start a development server by running: From f751f81c362c97b65254cdf6e154a86f673869e6 Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Mon, 2 Dec 2019 00:54:42 +0000 Subject: [PATCH 018/119] GitBook: [master] 2 pages modified --- README.md | 60 +++++++++++++--------------- getting-started/starter-templates.md | 7 +++- 2 files changed, 33 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 39566859c23..28aa3699a33 100644 --- a/README.md +++ b/README.md @@ -2,55 +2,49 @@ ## What is Yew? -**Yew** is a modern Rust framework for creating multi-threaded frontend web apps with WebAssembly. +**Yew** is a Rust framework for creating multi-threaded frontend web apps with WebAssembly. -### Architecture +#### Why Rust and WebAssembly? -Yew's architecture is heavily inspired by Elm and React. The basic building block of a Yew app is called a `Component`. Each `Component` stores its own state, expresses how to render that state to HTML, and chooses how to respond to asynchronous updates. Yew maintains an internal "virtual DOM" in order to minimize the patches needed to update the browser page DOM for each re-render of a `Component`. +\*\*\*\*[**Rust**](https://www.rust-lang.org/) is blazing fast and super reliable with its rich type system and ownership model. It can have a tough learning curve but worth the effort. Rust has been voted the most loved programming language [multiple](https://insights.stackoverflow.com/survey/2018#technology-_-most-loved-dreaded-and-wanted-languages) [years](https://insights.stackoverflow.com/survey/2019#technology-_-most-loved-dreaded-and-wanted-languages) in a row in Stack Overflow Developer Surveys. -### Concurrency +\*\*\*\*[**WebAssembly**](https://webassembly.org/) _\(Wasm\)_ is a portable low-level language that Rust can compile into which aims to run at native speeds in the browser and is interoperable with JavaScript and supported in all major browsers. -Yew was built before the standardization of async-await and has promoted the use of the [actor model](https://en.wikipedia.org/wiki/Actor_model) of concurrency. This model will feel very natural if you choose to write the server side of your application with [actix-web](https://github.com/actix/actix-web). In Yew, an actor is called an `Agent`. Using agents, a Yew application can delegate tasks to worker threads using Web Workers and subscribe to async messages from those agents. +### Modern Web Framework -An alternative approach is using futures which are can be leveraged through the [wasm-bindgen-futures](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen_futures/) crate which bridges Rust futures to JS Promises. An example project using futures and async-await can be found [here](https://github.com/yewstack/yew/tree/master/examples/futures). - -### Safety - -Rust helps developers write safer code. For example, in JavaScript, an uncaught error can cause serious problems in your application. Rust encourages proper error handling and you can even get stacktraces for your Rust code with the [`console_error_panic_hook`](https://github.com/rustwasm/console_error_panic_hook) crate. Also, Yew apps can leverage Rust's static typing to ensure that your `Component` receives the correct properties for creation \(otherwise your app won't compile!\). - -### JavaScript - -Yew is built on top of great web tooling like `wasm-bindgen` and `stdweb` and will be supporting `web-sys` and `js-sys` in the near future. These crates enable WebAssembly code to call into JavaScript and vice-versa. For some examples, visit [here](https://github.com/yewstack/yew/tree/master/examples/js_callback) to see how to leverage `stdweb` to write JavaScript code in your Rust app and [here](https://github.com/yewstack/yew/tree/master/examples/npm_and_rest) for how to interact with an NPM module. - -### HTML - -Yew includes a procedural macro for generating HTML. It closely resembles React's JSX with some exceptions _\(string literals and listener callbacks to name a few\)_. Here is a quick look at its usage: +Yew is a component-based framework that makes it easy to create complex interactive UIs. Developers who have experience with frameworks like React and Elm should feel quite at home when using Yew. Creating HTML in Yew even looks a lot like React's JSX with a few minor exceptions. Here's a quick look: ```rust -html! { +fn view(&self) -> Html { + html! {
-
-

{ "todos" }

- { self.view_input(&model) } -
-
- { self.view_entries(&model) } -
+
+

{ "todos" }

+
+
+ + { self.view_todos() } +
+ } } ``` -Full guide [here](html.md) +### Performance and Concurrency + +First and foremost, it should be clear that using Wasm is not a silver bullet for improving the performance of a web app. As of right now, using DOM APIs from WebAssembly is still slower than calling them directly from JavaScript. This is a temporary hurdle which the [WebAssembly Interface Types](https://github.com/WebAssembly/interface-types/blob/master/proposals/interface-types/Explainer.md) proposal aims to resolve. If you would like to learn more, check out this [excellent article](https://hacks.mozilla.org/2019/08/webassembly-interface-types/) from Mozilla. -### Why Rust? +In the meantime, Yew will boost the performance of your app by minimizing the number of expensive DOM API calls and making it simple to leverage workers to offload processing from the main browser thread. For more ideas on how WebAssembly can help out your app, check out this list of [Use Cases](https://webassembly.org/docs/use-cases/). -Rust is a modern systems language pursuing safety, concurrency, and speed and has been voted the most loved programming languages [multiple](https://insights.stackoverflow.com/survey/2018#technology-_-most-loved-dreaded-and-wanted-languages) [years](https://insights.stackoverflow.com/survey/2019#technology-_-most-loved-dreaded-and-wanted-languages) in a row in Stack Overflow Developer Surveys. Rust can be compiled to WebAssembly using the `cargo` build system which can achieve near-native speeds in a browser. +### Type Safety and Reliability -Similar to how Node.js web applications can share JavaScript code between the server and client, Rust-based apps can reuse the same Rust code for the server and client, with the client code first needing to be compiled to WebAssembly for execution in a browser. +Rust helps developers write safer code with its rich type system and ownership model. Say goodbye to hard to track down race condition bugs in JavaScript! In fact, with Rust, most of your bugs will be caught by the compiler before your app even runs, often with a very helpful error message explaining what went wrong. Rust also encourages proper error handling and in the uncommon case that your app panics, you can even get full stack-traces for your Rust code in the browser console. -### Why WebAssembly? +### JavaScript Interop -First of all, using WASM is not going to be faster than a JavaScript app if you're primarily using DOM APIs. This will probably change in the near future, with the adoption of [Web IDL](https://heycam.github.io/webidl/). But for the time being, Wasm applications have to serialize commands from Wasm to JavaScript to interact with the DOM which will impact performance. +Yew is built on top of great web tooling created by the Rust community. It's easy to call JavaScript code from Rust and vice-versa, enabling you to try out Yew for a small part of your web app without any headaches. It's even possible to use your favorite NPM packages within Yew! -That being said, WebAssembly can be leveraged for data heavy and graphics intensive calculations in the background. When client UI performance is not too important \(internal tooling, for example\) using WebAssembly for the full web application can be acceptable. +### diff --git a/getting-started/starter-templates.md b/getting-started/starter-templates.md index 97af457d0b4..bcf89d56232 100644 --- a/getting-started/starter-templates.md +++ b/getting-started/starter-templates.md @@ -7,7 +7,6 @@ If you want to use a JS Bundler instead of cargo web, it is recommended that you * [Minimal Template](https://github.com/yewstack/yew-wasm-pack-minimal) - Uses `wasm-pack` and `rollup` to build your application, and your own server to serve it. No bells or whistles here. * `python -m SimpleHTTPServer 8080` Is a good quick and dirty server for development purposes. * [Webpack Template](https://github.com/yewstack/yew-wasm-pack-template) - Webpack is used to manage your development and deployments via a `wasm-pack` plugin. -* [Parcel Template](https://github.com/spielrs/yew-parcel-template) - Created by a community member and uses [Parcel](https://parceljs.org/) The important distinction between this approach and using `cargo-web` is that this approach uses a `lib`, not a `bin` crate, and the entry-point to your program is annotated with a `#[wasm_bindgen]` annotation. @@ -30,3 +29,9 @@ wasm-bindgen = "0.2" ``` {% endcode %} +## Parcel + +* [Parcel Template](https://github.com/spielrs/yew-parcel-template) - Created by a community member and uses [Parcel](https://parceljs.org/) + + + From bd84cc4613ac135c362effb961722762f6d38a6b Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Mon, 2 Dec 2019 00:56:45 +0000 Subject: [PATCH 019/119] GitBook: [master] one page modified --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 28aa3699a33..c6d6544349c 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,13 @@ ## What is Yew? -**Yew** is a Rust framework for creating multi-threaded frontend web apps with WebAssembly. +**Yew** is a [Rust](https://www.rust-lang.org/) framework for creating multi-threaded front-end web apps with [WebAssembly](https://webassembly.org/). #### Why Rust and WebAssembly? -\*\*\*\*[**Rust**](https://www.rust-lang.org/) is blazing fast and super reliable with its rich type system and ownership model. It can have a tough learning curve but worth the effort. Rust has been voted the most loved programming language [multiple](https://insights.stackoverflow.com/survey/2018#technology-_-most-loved-dreaded-and-wanted-languages) [years](https://insights.stackoverflow.com/survey/2019#technology-_-most-loved-dreaded-and-wanted-languages) in a row in Stack Overflow Developer Surveys. +**Rust** is blazing fast and super reliable with its rich type system and ownership model. It can have a tough learning curve but worth the effort. Rust has been voted the most loved programming language [multiple](https://insights.stackoverflow.com/survey/2018#technology-_-most-loved-dreaded-and-wanted-languages) [years](https://insights.stackoverflow.com/survey/2019#technology-_-most-loved-dreaded-and-wanted-languages) in a row in Stack Overflow Developer Surveys. -\*\*\*\*[**WebAssembly**](https://webassembly.org/) _\(Wasm\)_ is a portable low-level language that Rust can compile into which aims to run at native speeds in the browser and is interoperable with JavaScript and supported in all major browsers. +**WebAssembly** _\(Wasm\)_ is a portable low-level language that Rust can compile into which aims to run at native speeds in the browser and is interoperable with JavaScript and supported in all major browsers. ### Modern Web Framework From 5dad9d4c25cb0ffb2b63284d9d61e3b2f0c525ea Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Mon, 2 Dec 2019 01:15:30 +0000 Subject: [PATCH 020/119] GitBook: [master] one page modified --- README.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index c6d6544349c..d4d09520559 100644 --- a/README.md +++ b/README.md @@ -4,15 +4,17 @@ **Yew** is a [Rust](https://www.rust-lang.org/) framework for creating multi-threaded front-end web apps with [WebAssembly](https://webassembly.org/). -#### Why Rust and WebAssembly? +#### Why Rust? -**Rust** is blazing fast and super reliable with its rich type system and ownership model. It can have a tough learning curve but worth the effort. Rust has been voted the most loved programming language [multiple](https://insights.stackoverflow.com/survey/2018#technology-_-most-loved-dreaded-and-wanted-languages) [years](https://insights.stackoverflow.com/survey/2019#technology-_-most-loved-dreaded-and-wanted-languages) in a row in Stack Overflow Developer Surveys. +Rust is blazing fast and reliable with its rich type system and ownership model. It can have a tough learning curve but is well worth the effort. Rust has been voted the most loved programming language multiple years in a row in [Stack Overflow](https://insights.stackoverflow.com/survey/2018#technology-_-most-loved-dreaded-and-wanted-languages) [Developer Surveys](https://insights.stackoverflow.com/survey/2019#technology-_-most-loved-dreaded-and-wanted-languages). -**WebAssembly** _\(Wasm\)_ is a portable low-level language that Rust can compile into which aims to run at native speeds in the browser and is interoperable with JavaScript and supported in all major browsers. +**Why WebAssembly?** + +WebAssembly _\(Wasm\)_ is a portable low-level language that Rust can compile into which aims to run at native speeds in the browser and is interoperable with JavaScript and supported in all major browsers. ### Modern Web Framework -Yew is a component-based framework that makes it easy to create complex interactive UIs. Developers who have experience with frameworks like React and Elm should feel quite at home when using Yew. Creating HTML in Yew even looks a lot like React's JSX with a few minor exceptions. Here's a quick look: +Yew is a component-based framework that makes it easy to create interactive UIs. Developers who have experience with frameworks like React and Elm should feel quite at home when using Yew. Creating HTML in Yew even looks a lot like React's JSX with a few minor exceptions. Here's a quick look: ```rust fn view(&self) -> Html { @@ -34,9 +36,9 @@ fn view(&self) -> Html { ### Performance and Concurrency -First and foremost, it should be clear that using Wasm is not a silver bullet for improving the performance of a web app. As of right now, using DOM APIs from WebAssembly is still slower than calling them directly from JavaScript. This is a temporary hurdle which the [WebAssembly Interface Types](https://github.com/WebAssembly/interface-types/blob/master/proposals/interface-types/Explainer.md) proposal aims to resolve. If you would like to learn more, check out this [excellent article](https://hacks.mozilla.org/2019/08/webassembly-interface-types/) from Mozilla. +Yew makes it easy to build performant applications by minimizing the number of expensive DOM API calls and making it simple to offload processing to background workers. For more ideas on how to get the most out of WebAssembly, check out this list of [Use Cases](https://webassembly.org/docs/use-cases/). -In the meantime, Yew will boost the performance of your app by minimizing the number of expensive DOM API calls and making it simple to leverage workers to offload processing from the main browser thread. For more ideas on how WebAssembly can help out your app, check out this list of [Use Cases](https://webassembly.org/docs/use-cases/). +However, it should be noted that using Wasm is not a silver bullet for improving the performance of a web app. As of right now, using DOM APIs from WebAssembly is still slower than calling them directly from JavaScript. This is a temporary hurdle which the [WebAssembly Interface Types](https://github.com/WebAssembly/interface-types/blob/master/proposals/interface-types/Explainer.md) proposal aims to resolve. If you would like to learn more, check out this [excellent article](https://hacks.mozilla.org/2019/08/webassembly-interface-types/) from Mozilla. ### Type Safety and Reliability From 5ef250281c103a2e38d7f4b2b6c6b7efa3f6a6c4 Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Mon, 2 Dec 2019 02:00:57 +0000 Subject: [PATCH 021/119] GitBook: [master] one page modified --- README.md | 60 ++++++++++++++++++++++++++----------------------------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index d4d09520559..794d764e519 100644 --- a/README.md +++ b/README.md @@ -2,51 +2,47 @@ ## What is Yew? -**Yew** is a [Rust](https://www.rust-lang.org/) framework for creating multi-threaded front-end web apps with [WebAssembly](https://webassembly.org/). +**Yew** is a modern [Rust](https://www.rust-lang.org/) framework for creating multi-threaded front-end web apps with [WebAssembly](https://webassembly.org/). -#### Why Rust? +* It features a **component-based** framework which makes it easy to create interactive UIs. Developers who have experience with frameworks like [React](https://reactjs.org/) and [Elm](https://elm-lang.org/) should feel quite at home when using Yew. +* It has **great performance** by minimizing DOM API calls by helping developers easily offload processing to background web workers. +* It even boasts **JavaScript interoperability**, allowing developers to leverage NPM packages and integrate with existing JavaScript applications. -Rust is blazing fast and reliable with its rich type system and ownership model. It can have a tough learning curve but is well worth the effort. Rust has been voted the most loved programming language multiple years in a row in [Stack Overflow](https://insights.stackoverflow.com/survey/2018#technology-_-most-loved-dreaded-and-wanted-languages) [Developer Surveys](https://insights.stackoverflow.com/survey/2019#technology-_-most-loved-dreaded-and-wanted-languages). +### Join Us -**Why WebAssembly?** +* You can report bugs and discuss features on the [GitHub issues page](https://github.com/yewstack/yew/issues) +* Our [Gitter chatroom](https://gitter.im/yewframework/Lobby) is pretty active and is a great place to ask questions -WebAssembly _\(Wasm\)_ is a portable low-level language that Rust can compile into which aims to run at native speeds in the browser and is interoperable with JavaScript and supported in all major browsers. +### Ready to dive in? -### Modern Web Framework +Click the link below to learn how to build your first Yew app and learn from community example projects -Yew is a component-based framework that makes it easy to create interactive UIs. Developers who have experience with frameworks like React and Elm should feel quite at home when using Yew. Creating HTML in Yew even looks a lot like React's JSX with a few minor exceptions. Here's a quick look: +{% page-ref page="getting-started/" %} -```rust -fn view(&self) -> Html { - html! { -
-
-

{ "todos" }

-
-
- - { self.view_todos() } -
-
- } -} -``` +### \*\*\*\* -### Performance and Concurrency +### **Still not convinced?** -Yew makes it easy to build performant applications by minimizing the number of expensive DOM API calls and making it simple to offload processing to background workers. For more ideas on how to get the most out of WebAssembly, check out this list of [Use Cases](https://webassembly.org/docs/use-cases/). +This project is built on cutting edge technology and is great for developers who like to develop the foundational projects of tomorrow. Here are some reasons why we believe that frameworks like Yew are the future of web development. -However, it should be noted that using Wasm is not a silver bullet for improving the performance of a web app. As of right now, using DOM APIs from WebAssembly is still slower than calling them directly from JavaScript. This is a temporary hurdle which the [WebAssembly Interface Types](https://github.com/WebAssembly/interface-types/blob/master/proposals/interface-types/Explainer.md) proposal aims to resolve. If you would like to learn more, check out this [excellent article](https://hacks.mozilla.org/2019/08/webassembly-interface-types/) from Mozilla. +#### **Wait, why WebAssembly?** -### Type Safety and Reliability +WebAssembly _\(Wasm\)_ is a portable low-level language that Rust can compile into. It runs at native speeds in the browser and is interoperable with JavaScript and supported in all major browsers. For more ideas on how to get the most out of WebAssembly, check out this list of [Use Cases](https://webassembly.org/docs/use-cases/). -Rust helps developers write safer code with its rich type system and ownership model. Say goodbye to hard to track down race condition bugs in JavaScript! In fact, with Rust, most of your bugs will be caught by the compiler before your app even runs, often with a very helpful error message explaining what went wrong. Rust also encourages proper error handling and in the uncommon case that your app panics, you can even get full stack-traces for your Rust code in the browser console. +It should be noted that using Wasm is not \(yet\) a silver bullet for improving the performance of a web app. As of right now, using DOM APIs from WebAssembly is still slower than calling them directly from JavaScript. This is a temporary hurdle which the [WebAssembly Interface Types](https://github.com/WebAssembly/interface-types/blob/master/proposals/interface-types/Explainer.md) proposal aims to resolve. If you would like to learn more, check out this [excellent article](https://hacks.mozilla.org/2019/08/webassembly-interface-types/) from Mozilla. -### JavaScript Interop +#### Ok, but why Rust? -Yew is built on top of great web tooling created by the Rust community. It's easy to call JavaScript code from Rust and vice-versa, enabling you to try out Yew for a small part of your web app without any headaches. It's even possible to use your favorite NPM packages within Yew! +Rust is blazing fast and reliable with its rich type system and ownership model. It has a tough learning curve but is well worth the effort. Rust has been voted the most loved programming language multiple years in a row in [Stack Overflow](https://insights.stackoverflow.com/survey/2018#technology-_-most-loved-dreaded-and-wanted-languages) [Developer Surveys](https://insights.stackoverflow.com/survey/2019#technology-_-most-loved-dreaded-and-wanted-languages). -### +Rust helps developers write safer code with its rich type system and ownership model. Say goodbye to hard to track down race condition bugs in JavaScript! In fact, with Rust, most of your bugs will be caught by the compiler before your app even runs. And don't worry, when your app does run into an error, you can still get full stack-traces for your Rust code in the browser console. + +#### Alternatives? + +We love to share ideas with other projects and believe we can all help each other reach the full potential of this exciting new technology. If you're not into Yew, you may like the following projects \(listed alphabetically\) + +* [Draco](https://github.com/utkarshkukreti/draco) - _"A Rust library for building client side web applications with Web Assembly"_ +* [Percy](https://github.com/chinedufn/percy) - _"A modular toolkit for building isomorphic web apps with Rust + WebAssembly"_ +* [Seed](https://github.com/seed-rs/seed) - _"A Rust framework for creating web apps"_ +* [Smithy](https://github.com/rbalicki2/smithy) - _"A framework for building WebAssembly apps in Rust"_ From ee9364bcfd6c4262330ad57702e88c27ad849d43 Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Mon, 2 Dec 2019 02:02:00 +0000 Subject: [PATCH 022/119] GitBook: [master] one page modified --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 794d764e519..4d5840de0cf 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,9 @@ * It features a **component-based** framework which makes it easy to create interactive UIs. Developers who have experience with frameworks like [React](https://reactjs.org/) and [Elm](https://elm-lang.org/) should feel quite at home when using Yew. * It has **great performance** by minimizing DOM API calls by helping developers easily offload processing to background web workers. -* It even boasts **JavaScript interoperability**, allowing developers to leverage NPM packages and integrate with existing JavaScript applications. +* It supports **JavaScript interoperability**, allowing developers to leverage NPM packages and integrate with existing JavaScript applications. -### Join Us +### Join Us 😊 * You can report bugs and discuss features on the [GitHub issues page](https://github.com/yewstack/yew/issues) * Our [Gitter chatroom](https://gitter.im/yewframework/Lobby) is pretty active and is a great place to ask questions From b9c3e3ffaa5a23fa66c15d077538d936644cba85 Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Mon, 2 Dec 2019 02:19:05 +0000 Subject: [PATCH 023/119] GitBook: [master] one page modified --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 4d5840de0cf..56960332aee 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,11 @@ ### Join Us 😊 * You can report bugs and discuss features on the [GitHub issues page](https://github.com/yewstack/yew/issues) +* We ❤️pull requests. Check out [good first issues](https://github.com/yewstack/yew/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) if you'd like to help out! * Our [Gitter chatroom](https://gitter.im/yewframework/Lobby) is pretty active and is a great place to ask questions +![](https://img.shields.io/github/stars/yewstack/yew?color=009A5B&label=Github%20stars) + ### Ready to dive in? Click the link below to learn how to build your first Yew app and learn from community example projects From 7d91013bf84a2572c98286ab6964652400207779 Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Mon, 2 Dec 2019 02:19:14 +0000 Subject: [PATCH 024/119] GitBook: [master] one page modified --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 56960332aee..b619349ed31 100644 --- a/README.md +++ b/README.md @@ -10,12 +10,12 @@ ### Join Us 😊 +![](https://img.shields.io/github/stars/yewstack/yew?color=009A5B&label=Github%20stars) + * You can report bugs and discuss features on the [GitHub issues page](https://github.com/yewstack/yew/issues) * We ❤️pull requests. Check out [good first issues](https://github.com/yewstack/yew/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) if you'd like to help out! * Our [Gitter chatroom](https://gitter.im/yewframework/Lobby) is pretty active and is a great place to ask questions -![](https://img.shields.io/github/stars/yewstack/yew?color=009A5B&label=Github%20stars) - ### Ready to dive in? Click the link below to learn how to build your first Yew app and learn from community example projects From d3d9b1e9d46a52b30bc6804b20d03056891b06ac Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Mon, 2 Dec 2019 02:20:17 +0000 Subject: [PATCH 025/119] GitBook: [master] one page modified --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b619349ed31..be83c3bfb39 100644 --- a/README.md +++ b/README.md @@ -10,12 +10,12 @@ ### Join Us 😊 -![](https://img.shields.io/github/stars/yewstack/yew?color=009A5B&label=Github%20stars) - * You can report bugs and discuss features on the [GitHub issues page](https://github.com/yewstack/yew/issues) * We ❤️pull requests. Check out [good first issues](https://github.com/yewstack/yew/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) if you'd like to help out! * Our [Gitter chatroom](https://gitter.im/yewframework/Lobby) is pretty active and is a great place to ask questions +![Our community is thriving!](https://img.shields.io/github/stars/yewstack/yew?color=009A5B&label=Github%20stars) + ### Ready to dive in? Click the link below to learn how to build your first Yew app and learn from community example projects From 0b45ba4713d19780a599d7fa25b0471733351e13 Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Mon, 2 Dec 2019 02:26:58 +0000 Subject: [PATCH 026/119] GitBook: [master] one page modified --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index be83c3bfb39..627ebf2a10b 100644 --- a/README.md +++ b/README.md @@ -36,9 +36,9 @@ It should be noted that using Wasm is not \(yet\) a silver bullet for improving #### Ok, but why Rust? -Rust is blazing fast and reliable with its rich type system and ownership model. It has a tough learning curve but is well worth the effort. Rust has been voted the most loved programming language multiple years in a row in [Stack Overflow](https://insights.stackoverflow.com/survey/2018#technology-_-most-loved-dreaded-and-wanted-languages) [Developer Surveys](https://insights.stackoverflow.com/survey/2019#technology-_-most-loved-dreaded-and-wanted-languages). +Rust is blazing fast and reliable with its rich type system and ownership model. It has a tough learning curve but is well worth the effort. Rust has been voted the most loved programming language in Stack Overflow's Developer Surveys for both [2018](https://insights.stackoverflow.com/survey/2018#technology-_-most-loved-dreaded-and-wanted-languages) and [2019](https://insights.stackoverflow.com/survey/2019#technology-_-most-loved-dreaded-and-wanted-languages). -Rust helps developers write safer code with its rich type system and ownership model. Say goodbye to hard to track down race condition bugs in JavaScript! In fact, with Rust, most of your bugs will be caught by the compiler before your app even runs. And don't worry, when your app does run into an error, you can still get full stack-traces for your Rust code in the browser console. +Rust also helps developers write safer code with its rich type system and ownership model. Say goodbye to hard to track down race condition bugs in JavaScript! In fact, with Rust, most of your bugs will be caught by the compiler before your app even runs. And don't worry, when your app does run into an error, you can still get full stack-traces for your Rust code in the browser console. #### Alternatives? From 8e8ba8251e8a962f0418d97c895249c3fea4a84f Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Mon, 2 Dec 2019 02:55:28 +0000 Subject: [PATCH 027/119] GitBook: [master] 39 pages modified --- README.md | 2 +- SUMMARY.md | 49 ++++++++++++------- .../how-it-works.md | 0 .../optimizations.md | 0 .../build-a-sample-app.md | 18 +------ .../build-environment.md | 2 +- .../examples.md | 0 getting-started-1/getting-started.md | 22 +++++++++ .../starter-templates.md | 0 agents.md => learning-yew/agents.md | 0 .../components/README.md | 0 .../components/callbacks.md | 2 +- .../components/properties.md | 0 refs.md => learning-yew/components/refs.md | 0 html.md => learning-yew/html.md | 2 +- router.md => learning-yew/router.md | 0 services.md => learning-yew/services.md | 0 external-libs.md => more/external-libs.md | 0 roadmap.md => more/roadmap.md | 0 testing.md => more/testing.md | 0 web-sys.md => more/web-sys.md | 0 21 files changed, 59 insertions(+), 38 deletions(-) rename how-it-works.md => advanced-topics/how-it-works.md (100%) rename optimizations.md => advanced-topics/optimizations.md (100%) rename getting-started/README.md => getting-started-1/build-a-sample-app.md (74%) rename {getting-started => getting-started-1}/build-environment.md (83%) rename {getting-started => getting-started-1}/examples.md (100%) create mode 100644 getting-started-1/getting-started.md rename {getting-started => getting-started-1}/starter-templates.md (100%) rename agents.md => learning-yew/agents.md (100%) rename components.md => learning-yew/components/README.md (100%) rename componentlink.md => learning-yew/components/callbacks.md (98%) rename properties.md => learning-yew/components/properties.md (100%) rename refs.md => learning-yew/components/refs.md (100%) rename html.md => learning-yew/html.md (99%) rename router.md => learning-yew/router.md (100%) rename services.md => learning-yew/services.md (100%) rename external-libs.md => more/external-libs.md (100%) rename roadmap.md => more/roadmap.md (100%) rename testing.md => more/testing.md (100%) rename web-sys.md => more/web-sys.md (100%) diff --git a/README.md b/README.md index 627ebf2a10b..522e262ba8a 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Click the link below to learn how to build your first Yew app and learn from community example projects -{% page-ref page="getting-started/" %} +{% page-ref page="getting-started-1/getting-started.md" %} ### \*\*\*\* diff --git a/SUMMARY.md b/SUMMARY.md index aa6f2a8d9c7..3db64dfec6e 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -1,22 +1,35 @@ # Table of contents * [Introduction](README.md) -* [Getting Started](getting-started/README.md) - * [Build Environment](getting-started/build-environment.md) - * [Starter Templates](getting-started/starter-templates.md) - * [Examples](getting-started/examples.md) -* [html!](html.md) -* [Components](components.md) -* [Properties](properties.md) -* [ComponentLink and Callbacks](componentlink.md) -* [Agents](agents.md) -* [Services](services.md) -* [web-sys](web-sys.md) -* [Refs](refs.md) -* [Testing](testing.md) -* [Optimizations & Best Practices](optimizations.md) -* [Low-level library internals](how-it-works.md) -* [Router](router.md) -* [External Libs](external-libs.md) -* [Roadmap](roadmap.md) + +## Getting Started + +* [Installation](getting-started-1/getting-started.md) +* [Build a Sample App](getting-started-1/build-a-sample-app.md) +* [Build Environment](getting-started-1/build-environment.md) +* [Starter Templates](getting-started-1/starter-templates.md) +* [Examples](getting-started-1/examples.md) + +## Core Concepts + +* [Using html!](learning-yew/html.md) +* [Components](learning-yew/components/README.md) + * [Properties](learning-yew/components/properties.md) + * [Callbacks](learning-yew/components/callbacks.md) + * [Refs](learning-yew/components/refs.md) +* [Agents](learning-yew/agents.md) +* [Services](learning-yew/services.md) +* [Router](learning-yew/router.md) + +## Advanced Topics + +* [Optimizations & Best Practices](advanced-topics/optimizations.md) +* [Low-level library internals](advanced-topics/how-it-works.md) + +## More + +* [Roadmap](more/roadmap.md) +* [Testing](more/testing.md) +* [External Libs](more/external-libs.md) +* [web-sys](more/web-sys.md) diff --git a/how-it-works.md b/advanced-topics/how-it-works.md similarity index 100% rename from how-it-works.md rename to advanced-topics/how-it-works.md diff --git a/optimizations.md b/advanced-topics/optimizations.md similarity index 100% rename from optimizations.md rename to advanced-topics/optimizations.md diff --git a/getting-started/README.md b/getting-started-1/build-a-sample-app.md similarity index 74% rename from getting-started/README.md rename to getting-started-1/build-a-sample-app.md index 17bed827670..9ec56e85b31 100644 --- a/getting-started/README.md +++ b/getting-started-1/build-a-sample-app.md @@ -1,18 +1,4 @@ ---- -description: How to set up and build your app ---- - -# Getting Started - -## Installation - -First, you'll need to install Rust. You can follow the official instructions [here](https://www.rust-lang.org/tools/install). Next, we'll be using `cargo-web` to create a sample app. You can install it by running: - -```bash -cargo install cargo-web -``` - -## Quick Sample App +# Build a Sample App First create a new binary project: @@ -95,5 +81,5 @@ Using [`cargo-web`](https://github.com/koute/cargo-web) is the quickest way to g cargo web start ``` -`cargo-web` should automatically add the `wasm32-unknown-unknown` target for you and then will build your app and make your application available at [http://\[::1\]:8000](http://[::1]:8000) by default. Consult `cargo web start --help` for other options. +`cargo-web` will automatically add the `wasm32-unknown-unknown` target for you and then will build your app and make your application available at [http://\[::1\]:8000](http://[::1]:8000) by default. Consult `cargo web start --help` for other options. diff --git a/getting-started/build-environment.md b/getting-started-1/build-environment.md similarity index 83% rename from getting-started/build-environment.md rename to getting-started-1/build-environment.md index ff0bd98f62a..697131d1a80 100644 --- a/getting-started/build-environment.md +++ b/getting-started-1/build-environment.md @@ -2,7 +2,7 @@ ## Build Tools -As shown in [Getting Started](./), using `cargo-web` is the quickest way to get up and running. Unfortunately `cargo-web` requires multiple compile passes and therefore is not as fast as other approaches. The most popular alternative is called `wasm-pack`. Check out the [Starter Templates](starter-templates.md) to get up and running quickly. +As shown in [Getting Started](getting-started.md), using `cargo-web` is the quickest way to get up and running. Unfortunately `cargo-web` requires multiple compile passes and therefore is not as fast as other approaches. The most popular alternative is called `wasm-pack`. Check out the [Starter Templates](starter-templates.md) to get up and running quickly. ### `cargo-web` diff --git a/getting-started/examples.md b/getting-started-1/examples.md similarity index 100% rename from getting-started/examples.md rename to getting-started-1/examples.md diff --git a/getting-started-1/getting-started.md b/getting-started-1/getting-started.md new file mode 100644 index 00000000000..c0d933662f5 --- /dev/null +++ b/getting-started-1/getting-started.md @@ -0,0 +1,22 @@ +--- +description: Set yourself up for success +--- + +# Installation + +### Rust + +First, you'll need Rust. To install Rust and the `cargo` build tool, follow the official instructions [here](https://www.rust-lang.org/tools/install). + +### **Build Tooling** + +[**`wasm-pack`**](https://rustwasm.github.io/docs/wasm-pack/) is a tool developed by the Rust-Wasm working group and is the **recommended** tool for building your application. You can find the installation instructions here. + +**\`\`**[**`cargo-web`**](https://github.com/koute/cargo-web) was the preferred web workflow tool before the introduction of `wasm-pack`. It is still the **quickest** way to get up and running and worth installing to run examples that haven't been migrated to support `wasm-pack` yet. Install it by running: + +```bash +cargo install cargo-web +``` + + + diff --git a/getting-started/starter-templates.md b/getting-started-1/starter-templates.md similarity index 100% rename from getting-started/starter-templates.md rename to getting-started-1/starter-templates.md diff --git a/agents.md b/learning-yew/agents.md similarity index 100% rename from agents.md rename to learning-yew/agents.md diff --git a/components.md b/learning-yew/components/README.md similarity index 100% rename from components.md rename to learning-yew/components/README.md diff --git a/componentlink.md b/learning-yew/components/callbacks.md similarity index 98% rename from componentlink.md rename to learning-yew/components/callbacks.md index bb216b162ce..b99f1b8f34e 100644 --- a/componentlink.md +++ b/learning-yew/components/callbacks.md @@ -2,7 +2,7 @@ description: ComponentLink and Callbacks. --- -# ComponentLink and Callbacks +# Callbacks The component link is the mechanism through which component logic will register logic that can send messages to its associated component's update mechanism. diff --git a/properties.md b/learning-yew/components/properties.md similarity index 100% rename from properties.md rename to learning-yew/components/properties.md diff --git a/refs.md b/learning-yew/components/refs.md similarity index 100% rename from refs.md rename to learning-yew/components/refs.md diff --git a/html.md b/learning-yew/html.md similarity index 99% rename from html.md rename to learning-yew/html.md index d634c3306b5..e132bd11449 100644 --- a/html.md +++ b/learning-yew/html.md @@ -2,7 +2,7 @@ description: The procedural macro for generating HTML --- -# html! +# Using html! ## HTML in Rust diff --git a/router.md b/learning-yew/router.md similarity index 100% rename from router.md rename to learning-yew/router.md diff --git a/services.md b/learning-yew/services.md similarity index 100% rename from services.md rename to learning-yew/services.md diff --git a/external-libs.md b/more/external-libs.md similarity index 100% rename from external-libs.md rename to more/external-libs.md diff --git a/roadmap.md b/more/roadmap.md similarity index 100% rename from roadmap.md rename to more/roadmap.md diff --git a/testing.md b/more/testing.md similarity index 100% rename from testing.md rename to more/testing.md diff --git a/web-sys.md b/more/web-sys.md similarity index 100% rename from web-sys.md rename to more/web-sys.md From a94640415e1151a4f8dd7f30e868022b08017724 Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Mon, 2 Dec 2019 02:55:53 +0000 Subject: [PATCH 028/119] GitBook: [master] one page modified --- getting-started-1/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/getting-started-1/getting-started.md b/getting-started-1/getting-started.md index c0d933662f5..9322592182d 100644 --- a/getting-started-1/getting-started.md +++ b/getting-started-1/getting-started.md @@ -12,7 +12,7 @@ First, you'll need Rust. To install Rust and the `cargo` build tool, follow the [**`wasm-pack`**](https://rustwasm.github.io/docs/wasm-pack/) is a tool developed by the Rust-Wasm working group and is the **recommended** tool for building your application. You can find the installation instructions here. -**\`\`**[**`cargo-web`**](https://github.com/koute/cargo-web) was the preferred web workflow tool before the introduction of `wasm-pack`. It is still the **quickest** way to get up and running and worth installing to run examples that haven't been migrated to support `wasm-pack` yet. Install it by running: +[**`cargo-web`**](https://github.com/koute/cargo-web) was the preferred web workflow tool before the introduction of `wasm-pack`. It is still the **quickest** way to get up and running and worth installing to run examples that haven't been migrated to support `wasm-pack` yet. Install it by running: ```bash cargo install cargo-web From f45bf322000d4a6f275ecf21b5dab034ccd02c45 Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Mon, 2 Dec 2019 03:15:25 +0000 Subject: [PATCH 029/119] GitBook: [master] 4 pages modified --- getting-started-1/build-a-sample-app.md | 6 +-- getting-started-1/build-environment.md | 72 +++++++++++++------------ getting-started-1/getting-started.md | 6 +-- getting-started-1/starter-templates.md | 9 ++-- 4 files changed, 46 insertions(+), 47 deletions(-) diff --git a/getting-started-1/build-a-sample-app.md b/getting-started-1/build-a-sample-app.md index 9ec56e85b31..b06b050d457 100644 --- a/getting-started-1/build-a-sample-app.md +++ b/getting-started-1/build-a-sample-app.md @@ -6,7 +6,7 @@ First create a new binary project: cargo new --bin yew-app && cd yew-app ``` -Add yew to your dependencies \(refer [here](https://docs.rs/yew) for the latest version\) +Add `yew` to your dependencies \(refer [here](https://docs.rs/yew) for the latest version\) {% code title="Cargo.toml" %} ```text @@ -21,7 +21,7 @@ yew = "0.10.0" ``` {% endcode %} -Copy this template into your `src/main.rs` file: +Copy the following template into your `src/main.rs` file: {% code title="src/main.rs" %} ```rust @@ -71,7 +71,7 @@ fn main() { ``` {% endcode %} -This template sets up your root `Component`, called `App` which shows a button which updates itself when you click it. `yew::start_app::()` starts your app and mounts it to the page's `` tag. +This template sets up your root `Component`, called `App` which shows a button which updates itself when you click it. Take special note of `yew::start_app::()` which starts your app and mounts it to the page's `` tag. ### Run your App! diff --git a/getting-started-1/build-environment.md b/getting-started-1/build-environment.md index 697131d1a80..d82e08d50c8 100644 --- a/getting-started-1/build-environment.md +++ b/getting-started-1/build-environment.md @@ -2,46 +2,16 @@ ## Build Tools -As shown in [Getting Started](getting-started.md), using `cargo-web` is the quickest way to get up and running. Unfortunately `cargo-web` requires multiple compile passes and therefore is not as fast as other approaches. The most popular alternative is called `wasm-pack`. Check out the [Starter Templates](starter-templates.md) to get up and running quickly. +You actually don't need extra build tools to release a Yew application but we recommend them. They make deployment and packaging much less of a headache by generating all of the wrapper JavaScript code necessary to run the `.wasm` file from you app in the browser. -### `cargo-web` +You can check out the [Starter Templates](starter-templates.md) to get up and running quickly or read on to learn more about your options. -Cargo web is a cargo subcommand for building client web apps. It makes building and deploying web applications. Read more [here](https://github.com/koute/cargo-web). +## `wasm-pack` -**Install** - -```bash -cargo install cargo-web -``` - -#### Build - -```bash -cargo web build -``` - -#### Run - -```bash -cargo web start -``` - -#### Supported Targets - -* `wasm32-unknown-unknown` -* `wasm32-unknown-emscripten` -* `asmjs-unknown-emscripten` +This tool was created by the Rust / Wasm Working Group and is the most actively developed tool for building WebAssembly applications. It supports packaging code into `npm` modules and has an accompanying [Webpack plugin](https://github.com/wasm-tool/wasm-pack-plugin) for easy integration with an existing JavaScript application. Find more information [here](https://rustwasm.github.io/docs/wasm-pack/introduction.html). {% hint style="info" %} -For `*-emscripten` targets, `cargo-web` will automatically install the Emscripten SDK and target for you. -{% endhint %} - -### `wasm-pack` - -This tool was created by the Rust / Wasm Working Group and is the most actively developed tool for building WebAssembly applications. It supports building to a Node.JS package and has an accompanying Webpack plugin for easy integration with an existing JavaScript application. Find more information [here](https://rustwasm.github.io/docs/wasm-pack/introduction.html). - -{% hint style="info" %} -Note that your crate-type will need to be `cdylib`when using `wasm-pack` +Note that the crate-type in your `Cargo.toml` will need to be `cdylib`when using `wasm-pack` {% endhint %} **Install** @@ -78,3 +48,35 @@ python -m SimpleHTTPServer 8080 * `wasm32-unknown-unknown` +## `cargo-web` + +Cargo web is a cargo subcommand for building client web apps. It makes building and deploying web applications incredibly easy. It is also the only toolchain that supports Emscripten targets. Read more [here](https://github.com/koute/cargo-web). + +**Install** + +```bash +cargo install cargo-web +``` + +#### Build + +```bash +cargo web build +``` + +#### Run + +```bash +cargo web start +``` + +#### Supported Targets + +* `wasm32-unknown-unknown` +* `wasm32-unknown-emscripten` +* `asmjs-unknown-emscripten` + +{% hint style="info" %} +For `*-emscripten` targets, `cargo-web` will automatically install the Emscripten SDK and target for you. +{% endhint %} + diff --git a/getting-started-1/getting-started.md b/getting-started-1/getting-started.md index 9322592182d..ee9a221a2bd 100644 --- a/getting-started-1/getting-started.md +++ b/getting-started-1/getting-started.md @@ -6,11 +6,11 @@ description: Set yourself up for success ### Rust -First, you'll need Rust. To install Rust and the `cargo` build tool, follow the official instructions [here](https://www.rust-lang.org/tools/install). +First, you'll need Rust. To install Rust and the `cargo` build tool, follow the ****[**official instructions**](https://www.rust-lang.org/tools/install)**.** -### **Build Tooling** +### **Build Tools** -[**`wasm-pack`**](https://rustwasm.github.io/docs/wasm-pack/) is a tool developed by the Rust-Wasm working group and is the **recommended** tool for building your application. You can find the installation instructions here. +[**`wasm-pack`**](https://rustwasm.github.io/docs/wasm-pack/) is a tool developed by the Rust-Wasm working group and is the **recommended** tool for building your application. Install using the official [**install instructions**](https://rustwasm.github.io/wasm-pack/installer/)**.** [**`cargo-web`**](https://github.com/koute/cargo-web) was the preferred web workflow tool before the introduction of `wasm-pack`. It is still the **quickest** way to get up and running and worth installing to run examples that haven't been migrated to support `wasm-pack` yet. Install it by running: diff --git a/getting-started-1/starter-templates.md b/getting-started-1/starter-templates.md index bcf89d56232..383e21934dc 100644 --- a/getting-started-1/starter-templates.md +++ b/getting-started-1/starter-templates.md @@ -1,14 +1,11 @@ # Starter Templates -## Project Setup for `wasm-pack` - -If you want to use a JS Bundler instead of cargo web, it is recommended that you copy from an existing template. +## `wasm-pack` * [Minimal Template](https://github.com/yewstack/yew-wasm-pack-minimal) - Uses `wasm-pack` and `rollup` to build your application, and your own server to serve it. No bells or whistles here. - * `python -m SimpleHTTPServer 8080` Is a good quick and dirty server for development purposes. -* [Webpack Template](https://github.com/yewstack/yew-wasm-pack-template) - Webpack is used to manage your development and deployments via a `wasm-pack` plugin. +* [Webpack Template](https://github.com/yewstack/yew-wasm-pack-template) - Uses `wasm-pack` and the [`wasm-pack-plugin`](https://github.com/wasm-tool/wasm-pack-plugin) for Webpack to streamline development. -The important distinction between this approach and using `cargo-web` is that this approach uses a `lib`, not a `bin` crate, and the entry-point to your program is annotated with a `#[wasm_bindgen]` annotation. +The important distinction between these templates and using `cargo-web` is that this approach uses a `lib`, not a `bin` crate, and the entry-point to your program is annotated with a `#[wasm_bindgen]` annotation. Your `Cargo.toml` also should specify that you have a "cdylib" crate-type. From ffc9fce6e4cdfa9bb7574dbeee2c9a2cb6ba2ddf Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Mon, 2 Dec 2019 04:37:36 +0000 Subject: [PATCH 030/119] GitBook: [master] 31 pages modified --- README.md | 2 +- SUMMARY.md | 39 +-- {learning-yew => concepts}/agents.md | 0 .../components/README.md | 0 .../components/callbacks.md | 0 .../components/properties.md | 0 {learning-yew => concepts}/components/refs.md | 0 concepts/html/README.md | 22 ++ concepts/html/elements.md | 277 ++++++++++++++++++ concepts/html/lists.md | 56 ++++ concepts/html/literals-and-expressions.md | 62 ++++ {learning-yew => concepts}/router.md | 0 {learning-yew => concepts}/services.md | 0 .../build-a-sample-app.md | 0 .../build-environment.md | 0 .../examples.md | 2 +- .../getting-started.md | 0 .../starter-templates.md | 0 learning-yew/html.md | 168 ----------- 19 files changed, 440 insertions(+), 188 deletions(-) rename {learning-yew => concepts}/agents.md (100%) rename {learning-yew => concepts}/components/README.md (100%) rename {learning-yew => concepts}/components/callbacks.md (100%) rename {learning-yew => concepts}/components/properties.md (100%) rename {learning-yew => concepts}/components/refs.md (100%) create mode 100644 concepts/html/README.md create mode 100644 concepts/html/elements.md create mode 100644 concepts/html/lists.md create mode 100644 concepts/html/literals-and-expressions.md rename {learning-yew => concepts}/router.md (100%) rename {learning-yew => concepts}/services.md (100%) rename {getting-started-1 => getting-started}/build-a-sample-app.md (100%) rename {getting-started-1 => getting-started}/build-environment.md (100%) rename {getting-started-1 => getting-started}/examples.md (96%) rename {getting-started-1 => getting-started}/getting-started.md (100%) rename {getting-started-1 => getting-started}/starter-templates.md (100%) delete mode 100644 learning-yew/html.md diff --git a/README.md b/README.md index 522e262ba8a..f013432427f 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Click the link below to learn how to build your first Yew app and learn from community example projects -{% page-ref page="getting-started-1/getting-started.md" %} +{% page-ref page="getting-started/getting-started.md" %} ### \*\*\*\* diff --git a/SUMMARY.md b/SUMMARY.md index 3db64dfec6e..513cab9324f 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -2,24 +2,27 @@ * [Introduction](README.md) -## Getting Started - -* [Installation](getting-started-1/getting-started.md) -* [Build a Sample App](getting-started-1/build-a-sample-app.md) -* [Build Environment](getting-started-1/build-environment.md) -* [Starter Templates](getting-started-1/starter-templates.md) -* [Examples](getting-started-1/examples.md) - -## Core Concepts - -* [Using html!](learning-yew/html.md) -* [Components](learning-yew/components/README.md) - * [Properties](learning-yew/components/properties.md) - * [Callbacks](learning-yew/components/callbacks.md) - * [Refs](learning-yew/components/refs.md) -* [Agents](learning-yew/agents.md) -* [Services](learning-yew/services.md) -* [Router](learning-yew/router.md) +## Getting Started + +* [Installation](getting-started/getting-started.md) +* [Build a Sample App](getting-started/build-a-sample-app.md) +* [Build Environment](getting-started/build-environment.md) +* [Starter Templates](getting-started/starter-templates.md) +* [Examples](getting-started/examples.md) + +## Core Concepts + +* [Using html!](concepts/html/README.md) + * [Lists](concepts/html/lists.md) + * [Elements](concepts/html/elements.md) + * [Literals & Expressions](concepts/html/literals-and-expressions.md) +* [Components](concepts/components/README.md) + * [Properties](concepts/components/properties.md) + * [Callbacks](concepts/components/callbacks.md) + * [Refs](concepts/components/refs.md) +* [Agents](concepts/agents.md) +* [Services](concepts/services.md) +* [Router](concepts/router.md) ## Advanced Topics diff --git a/learning-yew/agents.md b/concepts/agents.md similarity index 100% rename from learning-yew/agents.md rename to concepts/agents.md diff --git a/learning-yew/components/README.md b/concepts/components/README.md similarity index 100% rename from learning-yew/components/README.md rename to concepts/components/README.md diff --git a/learning-yew/components/callbacks.md b/concepts/components/callbacks.md similarity index 100% rename from learning-yew/components/callbacks.md rename to concepts/components/callbacks.md diff --git a/learning-yew/components/properties.md b/concepts/components/properties.md similarity index 100% rename from learning-yew/components/properties.md rename to concepts/components/properties.md diff --git a/learning-yew/components/refs.md b/concepts/components/refs.md similarity index 100% rename from learning-yew/components/refs.md rename to concepts/components/refs.md diff --git a/concepts/html/README.md b/concepts/html/README.md new file mode 100644 index 00000000000..94cb14795dd --- /dev/null +++ b/concepts/html/README.md @@ -0,0 +1,22 @@ +--- +description: The procedural macro for generating HTML and SVG +--- + +# Using html! + +The `html!` macro allows you to write declarative HTML and SVG for your components. If you've used React's JSX it will feel quite familiar. + +**Important notes** + +1. There must be only one root node in an `html!` invocation +2. An empty `html! {}` invocation is valid and will not render anything +3. Literals must always be quoted and wrapped in braces: `html! { "Hello, World" }` + +{% page-ref page="lists.md" %} + +{% page-ref page="elements.md" %} + +{% page-ref page="literals-and-expressions.md" %} + + + diff --git a/concepts/html/elements.md b/concepts/html/elements.md new file mode 100644 index 00000000000..1daa7b11f51 --- /dev/null +++ b/concepts/html/elements.md @@ -0,0 +1,277 @@ +--- +description: Both HTML and SVG elements are supported +--- + +# Elements + +### Tag Structure + +Element tags must either self-close `<... />` or have a corresponding close tag for each open tag + +{% tabs %} +{% tab title="Open - Close" %} +```rust +html! { +
+} +``` +{% endtab %} + +{% tab title="INVALID" %} +```rust +html! { +
// <- MISSING CLOSE TAG +} +``` +{% endtab %} + +{% tab title="Self-Closing" %} +```rust +html! { + +} +``` +{% endtab %} + +{% tab title="INVALID" %} +```rust +html! { + // <- MISSING SELF-CLOSE +} +``` +{% endtab %} +{% endtabs %} + +{% hint style="info" %} +For convenience, elements which _usually_ require a closing tag are **allowed** to self-close. For example, writing `html! {
}` is valid. +{% endhint %} + +### Children + +Create complex nested HTML and SVG layouts with ease: + +{% tabs %} +{% tab title="HTML" %} +```rust +html! { +
+
+
+ + + + +