Skip to content

Commit 7b25826

Browse files
Merge pull request #2 from seed-rs/rosetta-stone
Made template for React/Vue comparison + Seed 0.5.0
2 parents dfda20f + fd58fcb commit 7b25826

14 files changed

+288
-177
lines changed

crate/Cargo.lock

Lines changed: 51 additions & 113 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crate/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ wasm-bindgen-test = "^0.2.50" # sync with `wasm-bindgen`
2424
wasm-bindgen = "^0.2.50" # sync with `wasm-bindgen-test`
2525
serde = { version = "^1.0.102", features = ['derive'] }
2626
serde_json = "^1.0.41"
27-
#seed = "0.5.0"
28-
seed = { git = "https://github.com/seed-rs/seed", branch="master" }
27+
seed = "0.5.0"
28+
#seed = { git = "https://github.com/seed-rs/seed", branch="master" }
2929
#seed = { path = "../../seed" }
3030

3131
[dependencies.web-sys]

crate/guides/about.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ are worth it.
3232

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

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

crate/guides/changelog.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,25 @@
11
# Changelog
22

3+
## 0.5.0
4+
- Added helper `seed::canvas()`, and `seed::canvas_context()` helper functions.
5+
- Fixed `Url` parsing (resolves issue with hash routing).
6+
- [BREAKING] `From<String> for Url` changed to `TryFrom<String> for Url`.
7+
- Fixed jumping cursor in inputs (#158) .
8+
- Added method `orders.after_next_render(Option<RenderTimestampDelta>)` (#207).
9+
- Fixed a bug with back/forward routing to the landing page (#296).
10+
- Deprecated `Init` struct, replacing it with `BeforeMount` and `AfterMount` structs to
11+
better denote state before and after mounting the `App` occurs.
12+
- Added a new function `builder` which replaces `build` as part of deprecating `Init`.
13+
- Added a new function `build_and_start` which replaces `finish` as part of deprecating `Init`.
14+
- Added `IntoInit`and `IntoAfterMount` traits. It is possible to use these
15+
in place of a closure or function to produce the corresponding `Init` and `AfterMount` structs.
16+
- Messages sent from `IntoAfterMount` will now be run after the routing message.
17+
- Added example `app_builder`.
18+
- `events::Listener` is included in `prelude`.
19+
- `()`s have been replaced with structs - e.g. `GMs = ()` => `GMs = UndefinedGMs`.
20+
- `WindowEvents` alias changed to `WindowEventsFn` for consistency with other `*Fn`.
21+
- Commented builder and helper methods.
22+
323
## v0.4.2
424
- Added an `Init` struct, which can help with initial routing (Breaking)
525
- The `routes` function now returns an `Option<Msg>` (Breaking)

crate/guides/code_comparison.md

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# Comparisons to React and Vue code
2+
3+
On this page, we'll show equivalent code snippets in Seed, and other frameworks. For now, we
4+
include examples from `React` and `Vue`.
5+
The [TodoMVC example](https://github.com/seed-rs/seed/tree/master/examples/todomvc) can be used to
6+
compare to [its implementation in other frameworks](http://todomvc.com/).
7+
8+
Note that there are multiple ways to manage state in React, we've picked one where we store state
9+
in the top-level component, and use functional components thereafter.
10+
A closer structure match would be using it coupled with Redux. The Context API's an additional
11+
way to handle it. We're also using Typescript.
12+
13+
## A simple template, ready for state management
14+
15+
## React
16+
17+
```jsx
18+
import * as React from "react"
19+
import * as ReactDOM from "react-dom"
20+
21+
interface MainProps {}
22+
interface MainState {
23+
val: number
24+
}
25+
26+
class Main extends React.Component<MainProps, MainState> {
27+
constructor(props) {
28+
super(props)
29+
30+
this.state = {
31+
val: 0
32+
}
33+
34+
this.increment = this.increment.bind(this)
35+
}
36+
37+
increment() {
38+
this.setState({val: this.state.val + 1})
39+
}
40+
41+
render() {
42+
return (
43+
<button onClick={() => this.state.increment()}>
44+
{"Hello, World × " + this.state.val}
45+
</button>
46+
)
47+
}
48+
}
49+
50+
ReactDOM.render(<Main />, document.getElementById("app"))
51+
```
52+
53+
54+
## Seed
55+
From the Seed quickstart repo
56+
57+
```rust
58+
use seed::{*, prelude::*};
59+
60+
struct Model {
61+
pub val: i32,
62+
}
63+
64+
impl Default for Model { // In this case, we could derive `Default` instead.
65+
fn default() -> Self {
66+
Self {
67+
val: 0,
68+
}
69+
}
70+
}
71+
72+
#[derive(Clone)]
73+
enum Msg {
74+
Increment,
75+
}
76+
77+
fn update(msg: Msg, model: &mut Model, _: &mut impl Orders<Msg>) {
78+
match msg {
79+
Msg::Increment => model.val += 1,
80+
}
81+
}
82+
83+
fn view(model: &Model) -> impl View<Msg> {
84+
button![
85+
simple_ev(Ev::Click, Msg::Increment),
86+
format!("Hello, World × {}", model.val)
87+
]
88+
}
89+
90+
#[wasm_bindgen(start)]
91+
pub fn render() {
92+
App::builder(update, view)
93+
.build_and_start();
94+
}
95+
```
96+
97+
## A component with attributes, styles, and events
98+
99+
## React
100+
101+
```jsx
102+
const Form = ({name, color, value, changeText, doIt}:
103+
{name: string, color: string, value: number, changeText: Function, doIt: Function}) {
104+
// A description
105+
const style: CSSProperties = {fontSize: 12, color: color}
106+
107+
return (
108+
<>
109+
<input value={value.toString() onChange={(ev) => changeText(ev)} />
110+
111+
<button
112+
className="buttons"
113+
title="Click me!"
114+
style={style}
115+
onClick={() => doIt()}
116+
>
117+
{name}
118+
</button>
119+
</>
120+
)
121+
}
122+
```
123+
124+
## Seed
125+
126+
```rust
127+
/// A description
128+
fn form(name: &str, color: &str, value: u32) -> Vec<Node<Msg>> {
129+
let style = style!{St::fontSize => px(12), St::Color => color};
130+
131+
vec![
132+
input![ attrs!{At::Value => value}, input_ev(Ev::Input, Msg::ChangeText)],
133+
134+
button![
135+
class!("buttons"),
136+
attrs!{At::Title => "Click me!"},
137+
style,
138+
simple_ev(Ev::Click, Msg::DoIt)
139+
name,
140+
]
141+
]
142+
143+
}
144+
```
145+
146+
147+
## Reusable UI items (todo)
148+
149+
## HTTP Requests (todo)
150+
151+
## Configuration files and tooling (todo)

crate/guides/events.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ where it handles text input triggered by a key press, and uses prevent_default()
176176

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

212212
#[wasm_bindgen]
213213
pub fn render() {
214-
seed::App::build(Init::new(Model::default()), update, view)
214+
App::builder(update, view)
215215
.window_events(window_events)
216-
.finish()
217-
.run();
216+
.build_and_start()
218217
}
219218
```
220219
If `model.watching` is `true`, the window listens for keyboard and mouse events, then

crate/guides/fetch.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,15 @@ fn view(model: &Model) -> Node<Msg> {
5959
)]
6060
}
6161

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

6767
#[wasm_bindgen]
6868
pub fn render() {
69-
let app = seed::App::build(init, update, view)
70-
.finish()
69+
let app = seed::App::builder(update, view)
70+
.after_mount(after_mount)
7171
.run();
7272

7373
app.update(Msg::FetchData);
@@ -102,6 +102,7 @@ fn view(model: &Model) -> Vec<Node<Msg>> {
102102
}
103103
```
104104

105+
105106
## Sending data
106107

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

171172
Reference the `Request` API docs (linked above) for a full
172173
list of methods available to configure the request, and links to the `MDN` docs describing
173-
them. (eg: `credentials`, `mode`, `integrity`)
174+
them. (eg: `credentials`, `mode`, `integrity`)

crate/guides/misc.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,7 @@ Rust data structure that implements serde's Serialize. Example use:
3232

3333
```rust
3434
extern crate serde;
35-
#[macro_use]
36-
extern crate serde_derive;
37-
extern crate serde_json;
35+
use seed::{*, prelude::*};
3836

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

134-
We also include `seed::canvas()`, and `seed::canvas_context()`. (Unreleased)
132+
We also include `seed::canvas()`, and `seed::canvas_context()`.
135133

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

crate/guides/quickstart.md

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@ The subsequent ones load your app's wasm modules.
3939
The quickstart repo includes this file. You will eventually need to modify it to
4040
change the page's title, add a description, favicon, stylesheet etc.
4141

42-
`Cargo.toml`, which is a file created by Cargo that describes your app, needs `wasm-bindgen`, `web-sys`, and `seed` as depdendencies,
43-
and crate-type
42+
`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
4443
of `"cdylib"`. The version in the quickstart repo has these set up already. Example:
4544

4645
```toml
@@ -54,24 +53,21 @@ edition = "2018"
5453
crate-type = ["cdylib"]
5554

5655
[dependencies]
57-
seed = "^0.4.1"
56+
seed = "^0.5.0"
5857
wasm-bindgen = "^0.2.50"
5958
```
6059

6160
## A short example
6261

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

6867
_lib.rs_:
6968

7069
```rust
71-
#[macro_use]
72-
extern crate seed;
73-
use seed::prelude::*;
74-
70+
use seed::{*, prelude::*};
7571

7672
// Model
7773

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

162158
#[wasm_bindgen(start)]
163159
pub fn render() {
164-
seed::App::build(|_, _| Init::new(Model::default()), update, view)
160+
App::builder(update, view)
165161
.build_and_start();
166162
}
167163
```
@@ -187,4 +183,4 @@ When server(s) are running, open [127.0.0.1:8000](http://127.0.0.1:8000) in your
187183
## Resources
188184
- [Awesome-seed-rs](https://github.com/seed-rs/awesome-seed-rs): A curated list of resources
189185
- [Seed Realworld](https://github.com/seed-rs/seed-rs-realworld): A detailed realworld example site
190-
- [Engineering Rust Web Applications](https://erwabook.com/): A book describing full-stack Rust web-development, using Seed for the frontend
186+
- [Engineering Rust Web Applications](https://erwabook.com/): A book describing full-stack Rust web-development, using Seed for the frontend

crate/guides/routing.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,9 @@ fn routes(url: Url) -> Option<Msg> {
4040

4141
#[wasm_bindgen(start)]
4242
pub fn render() {
43-
seed::App::build(|_, _| Init::new(Model::default()), update, view)
43+
App::builder(update, view)
4444
.routes(routes)
45-
.finish()
46-
.run();
45+
.build_and_start();
4746
}
4847
```
4948

0 commit comments

Comments
 (0)