Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 51 additions & 113 deletions crate/Cargo.lock

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions crate/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ wasm-bindgen-test = "^0.2.50" # sync with `wasm-bindgen`
wasm-bindgen = "^0.2.50" # sync with `wasm-bindgen-test`
serde = { version = "^1.0.102", features = ['derive'] }
serde_json = "^1.0.41"
#seed = "0.5.0"
seed = { git = "https://github.com/seed-rs/seed", branch="master" }
seed = "0.5.0"
#seed = { git = "https://github.com/seed-rs/seed", branch="master" }
#seed = { path = "../../seed" }

[dependencies.web-sys]
Expand Down
4 changes: 3 additions & 1 deletion crate/guides/about.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ are worth it.

## Where to start if you're familiar with existing frontend frameworks

The [todomvc example](https://github.com/seed-rs/seed/tree/master/examples/todomvc) is an implementation of the [TodoMVC project](http://todomvc.com/),
Check out the (Code comparison)[https://seed-rs.org/guide/code-comarison]) section of this guide. Additionally,
the [todomvc example](https://github.com/seed-rs/seed/tree/master/examples/todomvc) is an implementation of
the [TodoMVC project](https://todomvc.com/),
which has example code in other frameworks that produce identitcal apps. Compare the example in this
project to one on that page that uses a framework you're familiar with.

Expand Down
20 changes: 20 additions & 0 deletions crate/guides/changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
# Changelog

## 0.5.0
- Added helper `seed::canvas()`, and `seed::canvas_context()` helper functions.
- Fixed `Url` parsing (resolves issue with hash routing).
- [BREAKING] `From<String> for Url` changed to `TryFrom<String> for Url`.
- Fixed jumping cursor in inputs (#158) .
- Added method `orders.after_next_render(Option<RenderTimestampDelta>)` (#207).
- Fixed a bug with back/forward routing to the landing page (#296).
- Deprecated `Init` struct, replacing it with `BeforeMount` and `AfterMount` structs to
better denote state before and after mounting the `App` occurs.
- Added a new function `builder` which replaces `build` as part of deprecating `Init`.
- Added a new function `build_and_start` which replaces `finish` as part of deprecating `Init`.
- Added `IntoInit`and `IntoAfterMount` traits. It is possible to use these
in place of a closure or function to produce the corresponding `Init` and `AfterMount` structs.
- Messages sent from `IntoAfterMount` will now be run after the routing message.
- Added example `app_builder`.
- `events::Listener` is included in `prelude`.
- `()`s have been replaced with structs - e.g. `GMs = ()` => `GMs = UndefinedGMs`.
- `WindowEvents` alias changed to `WindowEventsFn` for consistency with other `*Fn`.
- Commented builder and helper methods.

## v0.4.2
- Added an `Init` struct, which can help with initial routing (Breaking)
- The `routes` function now returns an `Option<Msg>` (Breaking)
Expand Down
151 changes: 151 additions & 0 deletions crate/guides/code_comparison.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# Comparisons to React and Vue code

On this page, we'll show equivalent code snippets in Seed, and other frameworks. For now, we
include examples from `React` and `Vue`.
The [TodoMVC example](https://github.com/seed-rs/seed/tree/master/examples/todomvc) can be used to
compare to [its implementation in other frameworks](http://todomvc.com/).

Note that there are multiple ways to manage state in React, we've picked one where we store state
in the top-level component, and use functional components thereafter.
A closer structure match would be using it coupled with Redux. The Context API's an additional
way to handle it. We're also using Typescript.

## A simple template, ready for state management

## React

```jsx
import * as React from "react"
import * as ReactDOM from "react-dom"

interface MainProps {}
interface MainState {
val: number
}

class Main extends React.Component<MainProps, MainState> {
constructor(props) {
super(props)

this.state = {
val: 0
}

this.increment = this.increment.bind(this)
}

increment() {
this.setState({val: this.state.val + 1})
}

render() {
return (
<button onClick={() => this.state.increment()}>
{"Hello, World × " + this.state.val}
</button>
)
}
}

ReactDOM.render(<Main />, document.getElementById("app"))
```


## Seed
From the Seed quickstart repo

```rust
use seed::{*, prelude::*};

struct Model {
pub val: i32,
}

impl Default for Model { // In this case, we could derive `Default` instead.
fn default() -> Self {
Self {
val: 0,
}
}
}

#[derive(Clone)]
enum Msg {
Increment,
}

fn update(msg: Msg, model: &mut Model, _: &mut impl Orders<Msg>) {
match msg {
Msg::Increment => model.val += 1,
}
}

fn view(model: &Model) -> impl View<Msg> {
button![
simple_ev(Ev::Click, Msg::Increment),
format!("Hello, World × {}", model.val)
]
}

#[wasm_bindgen(start)]
pub fn render() {
App::builder(update, view)
.build_and_start();
}
```

## A component with attributes, styles, and events

## React

```jsx
const Form = ({name, color, value, changeText, doIt}:
{name: string, color: string, value: number, changeText: Function, doIt: Function}) {
// A description
const style: CSSProperties = {fontSize: 12, color: color}

return (
<>
<input value={value.toString() onChange={(ev) => changeText(ev)} />

<button
className="buttons"
title="Click me!"
style={style}
onClick={() => doIt()}
>
{name}
</button>
</>
)
}
```

## Seed

```rust
/// A description
fn form(name: &str, color: &str, value: u32) -> Vec<Node<Msg>> {
let style = style!{St::fontSize => px(12), St::Color => color};

vec![
input![ attrs!{At::Value => value}, input_ev(Ev::Input, Msg::ChangeText)],

button![
class!("buttons"),
attrs!{At::Title => "Click me!"},
style,
simple_ev(Ev::Click, Msg::DoIt)
name,
]
]

}
```


## Reusable UI items (todo)

## HTTP Requests (todo)

## Configuration files and tooling (todo)
7 changes: 3 additions & 4 deletions crate/guides/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ where it handles text input triggered by a key press, and uses prevent_default()

## Window events
We handle events triggered by the overall window specially, since it doesn't fit directly
into our virtual DOM. We pass to `Seed::App::build::window_events()` a function that accepts a
into our virtual DOM. We pass to `App::builder::window_events()` a function that accepts a
ref to `Model`, and returns a `Vec<devents::Listener>`. We use it to control
which listeners are attached to the window based on the model. Excerpt from the
[window_events](https://github.com/seed-rs/seed/blob/master/examples/window_events/src/lib.rs)
Expand Down Expand Up @@ -211,10 +211,9 @@ fn window_events(model: &Model) -> Vec<seed::events::Listener<Msg>> {

#[wasm_bindgen]
pub fn render() {
seed::App::build(Init::new(Model::default()), update, view)
App::builder(update, view)
.window_events(window_events)
.finish()
.run();
.build_and_start()
}
```
If `model.watching` is `true`, the window listens for keyboard and mouse events, then
Expand Down
11 changes: 6 additions & 5 deletions crate/guides/fetch.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,15 @@ fn view(model: &Model) -> Node<Msg> {
)]
}

fn init(_: Url, orders: &mut impl Orders<Msg>) -> Init<Model> {
fn after_mount(_: Url, orders: &mut impl Orders<Msg>) -> AfterMount<Model> {
orders.perform_cmd(fetch_data());
Init::new(Model::default())
AfterMount::default()
}

#[wasm_bindgen]
pub fn render() {
let app = seed::App::build(init, update, view)
.finish()
let app = seed::App::builder(update, view)
.after_mount(after_mount)
.run();

app.update(Msg::FetchData);
Comment on lines +69 to 73
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Todo for next PRs

In all examples:

  • seed::App replace with App and make sure we have the line use seed::{*, prelude::*} at the top of the example (if necessary) ; And we probably should add App into prelude.
  • let app ... app.update(... is anti-pattern. It should be refactored with after_mount.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated this PR and the Rust quickstart with this import style.

Expand Down Expand Up @@ -102,6 +102,7 @@ fn view(model: &Model) -> Vec<Node<Msg>> {
}
```


## Sending data

Example showing a POST request where we send data to a server and receive the response,
Expand Down Expand Up @@ -170,4 +171,4 @@ fn view(model: &Model) -> Node<Msg> {

Reference the `Request` API docs (linked above) for a full
list of methods available to configure the request, and links to the `MDN` docs describing
them. (eg: `credentials`, `mode`, `integrity`)
them. (eg: `credentials`, `mode`, `integrity`)
6 changes: 2 additions & 4 deletions crate/guides/misc.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,7 @@ Rust data structure that implements serde's Serialize. Example use:

```rust
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
use seed::{*, prelude::*};

// ...
#[derive(Serialize, Deserialize)]
Expand Down Expand Up @@ -131,7 +129,7 @@ fn view(model: &Model) -> Vec<Node<Msg>> {
Additionally, use `seed::html_document()` in the same way, to return a
[HtmlDocument](https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.HtmlDocument.html)

We also include `seed::canvas()`, and `seed::canvas_context()`. (Unreleased)
We also include `seed::canvas()`, and `seed::canvas_context()`.

You can call `seed::cookies()` to retrieve all cookies from the current `HtmlDocument`.

Expand Down
16 changes: 6 additions & 10 deletions crate/guides/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ The subsequent ones load your app's wasm modules.
The quickstart repo includes this file. You will eventually need to modify it to
change the page's title, add a description, favicon, stylesheet etc.

`Cargo.toml`, which is a file created by Cargo that describes your app, needs `wasm-bindgen`, `web-sys`, and `seed` as depdendencies,
and crate-type
`Cargo.toml`, which is a file created by Cargo that describes your app, needs `wasm-bindgen`, `web-sys`, and `seed` as dependencies, and crate-type
of `"cdylib"`. The version in the quickstart repo has these set up already. Example:

```toml
Expand All @@ -54,24 +53,21 @@ edition = "2018"
crate-type = ["cdylib"]

[dependencies]
seed = "^0.4.1"
seed = "^0.5.0"
wasm-bindgen = "^0.2.50"
```

## A short example

Here's an example demonstrating structure and syntax; it can be found in working form
in the [counter example](https://github.com/seed-rs/seed/tree/master/examples/counter)
in the [counter example](https://github.com/seed-rs/seed/tree/master/examples/counter).
Descriptions of its parts are in the
Guide section below. Its structure follows [The Elm Architecture](https://guide.elm-lang.org/architecture/).

_lib.rs_:

```rust
#[macro_use]
extern crate seed;
use seed::prelude::*;

use seed::{*, prelude::*};

// Model

Expand Down Expand Up @@ -161,7 +157,7 @@ fn view(model: &Model) -> impl View<Msg> {

#[wasm_bindgen(start)]
pub fn render() {
seed::App::build(|_, _| Init::new(Model::default()), update, view)
App::builder(update, view)
.build_and_start();
}
```
Expand All @@ -187,4 +183,4 @@ When server(s) are running, open [127.0.0.1:8000](http://127.0.0.1:8000) in your
## Resources
- [Awesome-seed-rs](https://github.com/seed-rs/awesome-seed-rs): A curated list of resources
- [Seed Realworld](https://github.com/seed-rs/seed-rs-realworld): A detailed realworld example site
- [Engineering Rust Web Applications](https://erwabook.com/): A book describing full-stack Rust web-development, using Seed for the frontend
- [Engineering Rust Web Applications](https://erwabook.com/): A book describing full-stack Rust web-development, using Seed for the frontend
5 changes: 2 additions & 3 deletions crate/guides/routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,9 @@ fn routes(url: Url) -> Option<Msg> {

#[wasm_bindgen(start)]
pub fn render() {
seed::App::build(|_, _| Init::new(Model::default()), update, view)
App::builder(update, view)
.routes(routes)
.finish()
.run();
.build_and_start();
}
```

Expand Down
Loading