Skip to content

Commit c6099cf

Browse files
author
mc1098
authored
Remove InputData & ChangeData (#2000)
1 parent 0afc695 commit c6099cf

File tree

16 files changed

+240
-162
lines changed

16 files changed

+240
-162
lines changed

examples/boids/src/slider.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
use std::cell::Cell;
2-
use yew::{html, Callback, Component, ComponentLink, Html, InputData, Properties, ShouldRender};
2+
use yew::{
3+
html, web_sys::HtmlInputElement, Callback, Component, ComponentLink, Html, InputEvent,
4+
Properties, ShouldRender, TargetCast,
5+
};
36

47
thread_local! {
58
static SLIDER_ID: Cell<usize> = Cell::default();
@@ -78,15 +81,19 @@ impl Component for Slider {
7881
10f64.powi(-(p as i32))
7982
});
8083

84+
let oninput = onchange.reform(|e: InputEvent| {
85+
let input: HtmlInputElement = e.target_unchecked_into();
86+
input.value_as_number()
87+
});
88+
8189
html! {
8290
<div class="slider">
8391
<label for={id.clone()} class="slider__label">{ label }</label>
8492
<input type="range"
8593
{id}
8694
class="slider__input"
8795
min={min.to_string()} max={max.to_string()} step={step.to_string()}
88-
oninput={onchange.reform(|data: InputData| data.value.parse().unwrap())}
89-
value={value.to_string()}
96+
{oninput}
9097
/>
9198
<span class="slider__value">{ display_value }</span>
9299
</div>

examples/crm/src/add_client.rs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use crate::Client;
22
use yew::{
3-
classes, html, Callback, Component, ComponentLink, Html, InputData, Properties, ShouldRender,
3+
classes, html,
4+
web_sys::{Event, HtmlInputElement, HtmlTextAreaElement},
5+
Callback, Component, ComponentLink, Html, Properties, ShouldRender, TargetCast,
46
};
57

68
#[derive(Debug)]
@@ -72,26 +74,36 @@ impl Component for AddClientForm {
7274

7375
fn view(&self) -> Html {
7476
let Self { link, client, .. } = self;
77+
78+
let update_name = |f: fn(String) -> Msg| {
79+
link.callback(move |e: Event| {
80+
let input: HtmlInputElement = e.target_unchecked_into();
81+
f(input.value())
82+
})
83+
};
84+
85+
let update_desc = link.callback(|e: Event| {
86+
let textarea: HtmlTextAreaElement = e.target_unchecked_into();
87+
Msg::UpdateDescription(textarea.value())
88+
});
89+
7590
html! {
7691
<>
7792
<div class="names">
7893
<input
7994
class={classes!("new-client", "firstname")}
8095
placeholder="First name"
81-
value={client.first_name.clone()}
82-
oninput={link.callback(|e: InputData| Msg::UpdateFirstName(e.value))}
96+
onchange={update_name(Msg::UpdateFirstName)}
8397
/>
8498
<input
8599
class={classes!("new-client", "lastname")}
86100
placeholder="Last name"
87-
value={client.last_name.clone()}
88-
oninput={link.callback(|e: InputData| Msg::UpdateLastName(e.value))}
101+
onchange={update_name(Msg::UpdateLastName)}
89102
/>
90103
<textarea
91104
class={classes!("new-client", "description")}
92105
placeholder="Description"
93-
value={client.description.clone()}
94-
oninput={link.callback(|e: InputData| Msg::UpdateDescription(e.value))}
106+
onchange={update_desc}
95107
/>
96108
</div>
97109

examples/file_upload/src/main.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
use yew::{html, ChangeData, Component, ComponentLink, Html, ShouldRender};
1+
use web_sys::{Event, HtmlInputElement};
2+
use yew::{html, html::TargetCast, Component, ComponentLink, Html, ShouldRender};
23

34
use gloo::file::callbacks::FileReader;
45
use gloo::file::File;
@@ -87,9 +88,11 @@ impl Component for Model {
8788
<div>
8889
<div>
8990
<p>{ "Choose a file to upload to see the uploaded bytes" }</p>
90-
<input type="file" multiple=true onchange={self.link.callback(move |value| {
91+
<input type="file" multiple=true onchange={self.link.callback(move |e: Event| {
9192
let mut result = Vec::new();
92-
if let ChangeData::Files(files) = value {
93+
let input: HtmlInputElement = e.target_unchecked_into();
94+
95+
if let Some(files) = input.files() {
9396
let files = js_sys::try_iter(&files)
9497
.unwrap()
9598
.unwrap()

examples/js_callback/src/main.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use wasm_bindgen::prelude::*;
2-
use yew::prelude::*;
2+
use yew::{prelude::*, web_sys::HtmlTextAreaElement};
33

44
mod bindings;
55

@@ -57,7 +57,10 @@ impl Component for Model {
5757
<>
5858
<textarea
5959
class="code-block"
60-
oninput={self.link.callback(|input: InputData| Msg::Payload(input.value))}
60+
oninput={self.link.callback(|e: InputEvent| {
61+
let input: HtmlTextAreaElement = e.target_unchecked_into();
62+
Msg::Payload(input.value())
63+
})}
6164
value={self.payload.clone()}
6265
/>
6366
<button onclick={self.link.callback(|_| Msg::Payload(bindings::get_payload()))}>

examples/keyed_list/src/main.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@ use instant::Instant;
22
use person::PersonType;
33
use yew::prelude::*;
44
use yew::utils::NeqAssign;
5-
use yew::web_sys::HtmlElement;
5+
use yew::web_sys::{HtmlElement, HtmlInputElement};
66

77
mod person;
88
mod random;
99

1010
pub enum Msg {
1111
CreatePersons(usize),
1212
CreatePersonsPrepend(usize),
13-
ChangeRatio(String),
13+
ChangeRatio(f64),
1414
DeletePersonById(usize),
1515
DeleteEverybody,
1616
SwapRandom,
@@ -70,7 +70,6 @@ impl Component for Model {
7070
true
7171
}
7272
Msg::ChangeRatio(ratio) => {
73-
let ratio: f64 = ratio.parse().unwrap_or(0.5);
7473
if self.build_component_ratio.neq_assign(ratio) {
7574
log::info!("Ratio changed: {}", ratio);
7675
true
@@ -169,8 +168,10 @@ impl Model {
169168
{ self.build_component_ratio }
170169
</p>
171170
<input name="ratio" type="range" class="form-control-range" min="0.0" max="1.0" step="any"
172-
value={self.build_component_ratio.to_string()}
173-
oninput={self.link.callback(|e: InputData| Msg::ChangeRatio(e.value))}
171+
oninput={self.link.callback(|e: InputEvent| {
172+
let input: HtmlInputElement = e.target_unchecked_into();
173+
Msg::ChangeRatio(input.value_as_number())
174+
})}
174175
/>
175176
</div>
176177
</div>

examples/mount_point/src/main.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use wasm_bindgen::JsValue;
2-
use web_sys::{CanvasRenderingContext2d, Document, HtmlCanvasElement};
3-
use yew::{html, Component, ComponentLink, Html, InputData, ShouldRender};
2+
use web_sys::{
3+
CanvasRenderingContext2d, Document, HtmlCanvasElement, HtmlInputElement, InputEvent,
4+
};
5+
use yew::{html, Component, ComponentLink, Html, ShouldRender, TargetCast};
46

57
pub enum Msg {
68
UpdateName(String),
@@ -40,7 +42,10 @@ impl Component for Model {
4042
<div>
4143
<input
4244
value={self.name.clone()}
43-
oninput={self.link.callback(|e: InputData| Msg::UpdateName(e.value))}
45+
oninput={self.link.callback(|e: InputEvent| {
46+
let input = e.target_unchecked_into::<HtmlInputElement>();
47+
Msg::UpdateName(input.value())
48+
})}
4449
/>
4550
<p>{ self.name.chars().rev().collect::<String>() }</p>
4651
</div>

examples/store/src/text_input.rs

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1+
use weblog::web_sys::HtmlInputElement;
12
use yew::prelude::*;
23

34
pub enum Msg {
4-
SetText(String),
5-
Submit,
5+
Submit(String),
66
}
77

88
#[derive(Properties, Clone, PartialEq)]
@@ -31,12 +31,7 @@ impl Component for TextInput {
3131

3232
fn update(&mut self, msg: Self::Message) -> ShouldRender {
3333
match msg {
34-
Msg::SetText(text) => {
35-
self.text = text;
36-
true
37-
}
38-
Msg::Submit => {
39-
let text = std::mem::replace(&mut self.text, self.props.value.clone());
34+
Msg::Submit(text) => {
4035
self.props.onsubmit.emit(text);
4136
true
4237
}
@@ -54,15 +49,23 @@ impl Component for TextInput {
5449
}
5550

5651
fn view(&self) -> Html {
52+
let onkeydown = self.link.batch_callback(|e: KeyboardEvent| {
53+
e.stop_propagation();
54+
if e.key() == "Enter" {
55+
let input: HtmlInputElement = e.target_unchecked_into();
56+
let value = input.value();
57+
input.set_value("");
58+
Some(Msg::Submit(value))
59+
} else {
60+
None
61+
}
62+
});
63+
5764
html! {
5865
<input
66+
placeholder={self.props.value.clone()}
5967
type="text"
60-
value={self.text.clone()}
61-
oninput={self.link.callback(|e: InputData| Msg::SetText(e.value))}
62-
onkeydown={self.link.batch_callback(move |e: KeyboardEvent| {
63-
e.stop_propagation();
64-
if e.key() == "Enter" { Some(Msg::Submit) } else { None }
65-
})}
68+
{onkeydown}
6669
/>
6770
}
6871
}

examples/todomvc/src/main.rs

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@ use gloo::storage::{LocalStorage, Storage};
22
use state::{Entry, Filter, State};
33
use strum::IntoEnumIterator;
44
use yew::web_sys::HtmlInputElement as InputElement;
5-
use yew::{classes, html, Component, ComponentLink, Html, InputData, NodeRef, ShouldRender};
5+
use yew::{
6+
classes, html, Component, ComponentLink, FocusEvent, Html, NodeRef, ShouldRender, TargetCast,
7+
};
68
use yew::{events::KeyboardEvent, Classes};
79

810
mod state;
911

1012
const KEY: &str = "yew.todomvc.self";
1113

1214
pub enum Msg {
13-
Add,
14-
Edit(usize),
15-
Update(String),
16-
UpdateEdit(String),
15+
Add(String),
16+
Edit((usize, String)),
1717
Remove(usize),
1818
SetFilter(Filter),
1919
ToggleAll,
@@ -38,7 +38,6 @@ impl Component for Model {
3838
let state = State {
3939
entries,
4040
filter: Filter::All,
41-
value: "".into(),
4241
edit_value: "".into(),
4342
};
4443
let focus_ref = NodeRef::default();
@@ -51,31 +50,20 @@ impl Component for Model {
5150

5251
fn update(&mut self, msg: Self::Message) -> ShouldRender {
5352
match msg {
54-
Msg::Add => {
55-
let description = self.state.value.trim();
53+
Msg::Add(description) => {
5654
if !description.is_empty() {
5755
let entry = Entry {
58-
description: description.to_string(),
56+
description: description.trim().to_string(),
5957
completed: false,
6058
editing: false,
6159
};
6260
self.state.entries.push(entry);
6361
}
64-
self.state.value = "".to_string();
6562
}
66-
Msg::Edit(idx) => {
67-
let edit_value = self.state.edit_value.trim().to_string();
68-
self.state.complete_edit(idx, edit_value);
63+
Msg::Edit((idx, edit_value)) => {
64+
self.state.complete_edit(idx, edit_value.trim().to_string());
6965
self.state.edit_value = "".to_string();
7066
}
71-
Msg::Update(val) => {
72-
println!("Input: {}", val);
73-
self.state.value = val;
74-
}
75-
Msg::UpdateEdit(val) => {
76-
println!("Input: {}", val);
77-
self.state.edit_value = val;
78-
}
7967
Msg::Remove(idx) => {
8068
self.state.remove(idx);
8169
}
@@ -180,17 +168,23 @@ impl Model {
180168
}
181169

182170
fn view_input(&self) -> Html {
171+
let onkeypress = self.link.batch_callback(|e: KeyboardEvent| {
172+
if e.key() == "Enter" {
173+
let input: InputElement = e.target_unchecked_into();
174+
let value = input.value();
175+
input.set_value("");
176+
Some(Msg::Add(value))
177+
} else {
178+
None
179+
}
180+
});
183181
html! {
184182
// You can use standard Rust comments. One line:
185183
// <li></li>
186184
<input
187185
class="new-todo"
188186
placeholder="What needs to be done?"
189-
value={self.state.value.clone()}
190-
oninput={self.link.callback(|e: InputData| Msg::Update(e.value))}
191-
onkeypress={self.link.batch_callback(|e: KeyboardEvent| {
192-
if e.key() == "Enter" { Some(Msg::Add) } else { None }
193-
})}
187+
{onkeypress}
194188
/>
195189
/* Or multiline:
196190
<ul>
@@ -226,6 +220,20 @@ impl Model {
226220
}
227221

228222
fn view_entry_edit_input(&self, (idx, entry): (usize, &Entry)) -> Html {
223+
let edit = move |input: InputElement| {
224+
let value = input.value();
225+
input.set_value("");
226+
Msg::Edit((idx, value))
227+
};
228+
229+
let onblur = self
230+
.link
231+
.callback(move |e: FocusEvent| edit(e.target_unchecked_into()));
232+
233+
let onkeypress = self.link.batch_callback(move |e: KeyboardEvent| {
234+
(e.key() == "Enter").then(|| edit(e.target_unchecked_into()))
235+
});
236+
229237
if entry.editing {
230238
html! {
231239
<input
@@ -234,11 +242,8 @@ impl Model {
234242
ref={self.focus_ref.clone()}
235243
value={self.state.edit_value.clone()}
236244
onmouseover={self.link.callback(|_| Msg::Focus)}
237-
oninput={self.link.callback(|e: InputData| Msg::UpdateEdit(e.value))}
238-
onblur={self.link.callback(move |_| Msg::Edit(idx))}
239-
onkeypress={self.link.batch_callback(move |e: KeyboardEvent| {
240-
if e.key() == "Enter" { Some(Msg::Edit(idx)) } else { None }
241-
})}
245+
{onblur}
246+
{onkeypress}
242247
/>
243248
}
244249
} else {

examples/todomvc/src/state.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use strum_macros::{EnumIter, ToString};
55
pub struct State {
66
pub entries: Vec<Entry>,
77
pub filter: Filter,
8-
pub value: String,
98
pub edit_value: String,
109
}
1110

packages/yew-macro/tests/derive_props/fail.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ help: consider importing one of these items
2727
83 | use crate::t9::foo;
2828
|
2929

30-
error[E0277]: the trait bound `t1::Value: std::default::Default` is not satisfied
30+
error[E0277]: the trait bound `Value: std::default::Default` is not satisfied
3131
--> $DIR/fail.rs:9:21
3232
|
3333
9 | #[derive(Clone, Properties)]
34-
| ^^^^^^^^^^ the trait `std::default::Default` is not implemented for `t1::Value`
34+
| ^^^^^^^^^^ the trait `std::default::Default` is not implemented for `Value`
3535
|
3636
= note: required by `Option::<T>::unwrap_or_default`
3737
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)

0 commit comments

Comments
 (0)