Breaking change: the builder macros now use method call syntax rather than function call syntax
This commit is contained in:
parent
4c0368fd9f
commit
34709737c8
|
@ -24,8 +24,8 @@ fn make_animated_box(value: u32, broadcaster: AnimatedMapBroadcaster) -> Dom {
|
||||||
let high: f64 = (value + 60) as f64;
|
let high: f64 = (value + 60) as f64;
|
||||||
|
|
||||||
html!("div", {
|
html!("div", {
|
||||||
future(animation.signal().for_each(clone!(animation => move |x| {
|
.future(animation.signal().for_each(clone!(animation => move |x| {
|
||||||
let x: f64= x.into();
|
let x: f64 = x.into_f64();
|
||||||
|
|
||||||
if x == 0.0 {
|
if x == 0.0 {
|
||||||
animation.animate_to(Percentage::new(1.0));
|
animation.animate_to(Percentage::new(1.0));
|
||||||
|
@ -35,58 +35,58 @@ fn make_animated_box(value: u32, broadcaster: AnimatedMapBroadcaster) -> Dom {
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})));
|
})))
|
||||||
|
|
||||||
event(clone!(hover_animation => move |_: MouseOverEvent| {
|
.event(clone!(hover_animation => move |_: MouseOverEvent| {
|
||||||
hover_animation.animate_to(Percentage::new(1.0));
|
hover_animation.animate_to(Percentage::new(1.0));
|
||||||
}));
|
}))
|
||||||
|
|
||||||
event(clone!(hover_animation => move |_: MouseOutEvent| {
|
.event(clone!(hover_animation => move |_: MouseOutEvent| {
|
||||||
hover_animation.animate_to(Percentage::new(0.0));
|
hover_animation.animate_to(Percentage::new(0.0));
|
||||||
}));
|
}))
|
||||||
|
|
||||||
style("border-radius", "10px");
|
.style("border-radius", "10px")
|
||||||
|
|
||||||
style_signal("width", animation.signal()
|
.style_signal("width", animation.signal()
|
||||||
.map(|t| easing::in_out(t, easing::cubic))
|
.map(|t| easing::in_out(t, easing::cubic))
|
||||||
.map(|t| Some(format!("{}px", t.range_inclusive(167.0, 500.0)))));
|
.map(|t| Some(format!("{}px", t.range_inclusive(167.0, 500.0)))))
|
||||||
|
|
||||||
style("position", "relative");
|
.style("position", "relative")
|
||||||
|
|
||||||
style_signal("margin-left", animation.signal()
|
.style_signal("margin-left", animation.signal()
|
||||||
.map(|t| t.invert())
|
.map(|t| t.invert())
|
||||||
.map(|t| easing::in_out(t, easing::cubic))
|
.map(|t| easing::in_out(t, easing::cubic))
|
||||||
.map(|t| Some(format!("{}px", t.range_inclusive(20.0, 0.0)))));
|
.map(|t| Some(format!("{}px", t.range_inclusive(20.0, 0.0)))))
|
||||||
|
|
||||||
style_signal("left", broadcaster.signal()
|
.style_signal("left", broadcaster.signal()
|
||||||
.map(|t| easing::in_out(t, easing::cubic))
|
.map(|t| easing::in_out(t, easing::cubic))
|
||||||
.map(|t| Some(format!("{}px", t.range_inclusive(100.0, 0.0)))));
|
.map(|t| Some(format!("{}px", t.range_inclusive(100.0, 0.0)))))
|
||||||
|
|
||||||
style_signal("height", map_ref! {
|
.style_signal("height", map_ref! {
|
||||||
let animation = broadcaster.signal().map(|t| easing::in_out(t, easing::cubic)),
|
let animation = broadcaster.signal().map(|t| easing::in_out(t, easing::cubic)),
|
||||||
let hover = hover_animation.signal().map(|t| easing::out(t, easing::cubic)) =>
|
let hover = hover_animation.signal().map(|t| easing::out(t, easing::cubic)) =>
|
||||||
Some(format!("{}px", animation.range_inclusive(0.0, hover.range_inclusive(5.0, 15.0))))
|
Some(format!("{}px", animation.range_inclusive(0.0, hover.range_inclusive(5.0, 15.0))))
|
||||||
});
|
})
|
||||||
|
|
||||||
style_signal("background-color", animation.signal()
|
.style_signal("background-color", animation.signal()
|
||||||
.map(|t| easing::in_out(t, easing::cubic))
|
.map(|t| easing::in_out(t, easing::cubic))
|
||||||
.map(move |t| Some(format!("hsl({}, {}%, {}%)",
|
.map(move |t| Some(format!("hsl({}, {}%, {}%)",
|
||||||
t.range_inclusive(low, high),
|
t.range_inclusive(low, high),
|
||||||
t.range_inclusive(50.0, 100.0),
|
t.range_inclusive(50.0, 100.0),
|
||||||
t.range_inclusive(50.0, 100.0)))));
|
t.range_inclusive(50.0, 100.0)))))
|
||||||
|
|
||||||
style("border-style", "solid");
|
.style("border-style", "solid")
|
||||||
|
|
||||||
style_signal("border-width", broadcaster.signal()
|
.style_signal("border-width", broadcaster.signal()
|
||||||
.map(|t| easing::in_out(t, easing::cubic))
|
.map(|t| easing::in_out(t, easing::cubic))
|
||||||
.map(|t| Some(format!("{}px", t.range_inclusive(0.0, 5.0)))));
|
.map(|t| Some(format!("{}px", t.range_inclusive(0.0, 5.0)))))
|
||||||
|
|
||||||
style_signal("border-color", animation.signal()
|
.style_signal("border-color", animation.signal()
|
||||||
.map(|t| easing::in_out(t, easing::cubic))
|
.map(|t| easing::in_out(t, easing::cubic))
|
||||||
.map(move |t| Some(format!("hsl({}, {}%, {}%)",
|
.map(move |t| Some(format!("hsl({}, {}%, {}%)",
|
||||||
t.range_inclusive(high, low),
|
t.range_inclusive(high, low),
|
||||||
t.range_inclusive(100.0, 50.0),
|
t.range_inclusive(100.0, 50.0),
|
||||||
t.range_inclusive(100.0, 50.0)))));
|
t.range_inclusive(100.0, 50.0)))))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,23 +144,23 @@ fn main() {
|
||||||
for _ in 0..1 {
|
for _ in 0..1 {
|
||||||
dominator::append_dom(&dominator::body(),
|
dominator::append_dom(&dominator::body(),
|
||||||
html!("div", {
|
html!("div", {
|
||||||
style("display", "flex");
|
.style("display", "flex")
|
||||||
|
|
||||||
children(&mut [
|
.children(&mut [
|
||||||
html!("div", {
|
html!("div", {
|
||||||
children_signal_vec(state.boxes.signal_vec()
|
.children_signal_vec(state.boxes.signal_vec()
|
||||||
.animated_map(2000.0, |value, t| {
|
.animated_map(2000.0, |value, t| {
|
||||||
make_animated_box(value, t)
|
make_animated_box(value, t)
|
||||||
}));
|
}))
|
||||||
}),
|
}),
|
||||||
|
|
||||||
html!("div", {
|
html!("div", {
|
||||||
children_signal_vec(state.boxes.signal_vec()
|
.children_signal_vec(state.boxes.signal_vec()
|
||||||
.animated_map(2000.0, |value, t| {
|
.animated_map(2000.0, |value, t| {
|
||||||
make_animated_box(value, t)
|
make_animated_box(value, t)
|
||||||
}));
|
}))
|
||||||
}),
|
}),
|
||||||
]);
|
])
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "test"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = ["Pauan <pcxunlimited@gmail.com>"]
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
dominator = { path = "../.." }
|
|
||||||
futures-signals = "0.1.0"
|
|
||||||
|
|
||||||
[dependencies.stdweb]
|
|
||||||
version = "0.4.0"
|
|
||||||
features = ["experimental_features_which_may_break_on_minor_version_bumps"]
|
|
|
@ -1 +0,0 @@
|
||||||
default-target = "wasm32-unknown-unknown"
|
|
|
@ -1,171 +0,0 @@
|
||||||
#[macro_use]
|
|
||||||
extern crate stdweb;
|
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate dominator;
|
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate futures_signals;
|
|
||||||
|
|
||||||
use std::rc::Rc;
|
|
||||||
use stdweb::web::{document, HtmlElement};
|
|
||||||
use stdweb::web::event::ClickEvent;
|
|
||||||
use stdweb::web::IParentNode;
|
|
||||||
|
|
||||||
use futures_signals::signal;
|
|
||||||
use futures_signals::signal_vec;
|
|
||||||
use futures_signals::signal::Signal;
|
|
||||||
use futures_signals::signal_vec::SignalVec;
|
|
||||||
use dominator::traits::*;
|
|
||||||
use dominator::{Dom, text};
|
|
||||||
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
stylesheet!("div", {
|
|
||||||
style("border", "5px solid black");
|
|
||||||
});
|
|
||||||
|
|
||||||
let foobar = class! {
|
|
||||||
style("border-right", "10px solid purple");
|
|
||||||
};
|
|
||||||
|
|
||||||
/*let media_query = stylesheet!(format!("@media (max-width: 500px) .{}", foobar), {
|
|
||||||
style("border-left", "10px solid teal");
|
|
||||||
});*/
|
|
||||||
|
|
||||||
let mut count = 0;
|
|
||||||
|
|
||||||
let (sender_count, receiver_count) = signal::unsync::mutable(count);
|
|
||||||
|
|
||||||
|
|
||||||
let mut width: u32 = 10;
|
|
||||||
|
|
||||||
let (sender1, receiver1) = signal::unsync::mutable(width);
|
|
||||||
let (sender2, receiver2) = signal::unsync::mutable(vec![width]);
|
|
||||||
let (sender3, receiver3) = signal::unsync::mutable(vec![width]);
|
|
||||||
let (text_sender, text_receiver) = signal::unsync::mutable(format!("{}", width));
|
|
||||||
|
|
||||||
let (mut sender_elements, receiver_elements) = signal_vec::unsync::mutable();
|
|
||||||
|
|
||||||
/*let style_width = receiver1.switch(move |x| {
|
|
||||||
receiver2.clone().switch(move |y| {
|
|
||||||
receiver3.clone().map(move |z| {
|
|
||||||
Some(format!("{}px", x + y[0] + z[0]))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
});*/
|
|
||||||
|
|
||||||
let style_width = map_clone! {
|
|
||||||
let x: Rc<u32> = receiver1,
|
|
||||||
let y: Rc<Vec<u32>> = receiver2,
|
|
||||||
let z: Rc<Vec<u32>> = receiver3 =>
|
|
||||||
Some(format!("{}px", *x + y[0] + z[0]))
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
let mut elements_index = 0;
|
|
||||||
|
|
||||||
let mut increment = move || {
|
|
||||||
elements_index += 1;
|
|
||||||
elements_index
|
|
||||||
};
|
|
||||||
|
|
||||||
sender_elements.push((increment(), 1));
|
|
||||||
sender_elements.push((increment(), 2));
|
|
||||||
sender_elements.push((increment(), 3));
|
|
||||||
sender_elements.push((increment(), 4));
|
|
||||||
sender_elements.push((increment(), 5));
|
|
||||||
sender_elements.push((increment(), 6));
|
|
||||||
sender_elements.push((increment(), 7));
|
|
||||||
|
|
||||||
|
|
||||||
dominator::append_dom(&document().query_selector("body").unwrap().unwrap(),
|
|
||||||
html!("div", {
|
|
||||||
style("border", "10px solid blue");
|
|
||||||
children(&mut [
|
|
||||||
text("Testing testing!!!"),
|
|
||||||
|
|
||||||
text(text_receiver.dynamic()),
|
|
||||||
|
|
||||||
text(receiver_count.map(|x| format!(" - {}", x)).dynamic()),
|
|
||||||
|
|
||||||
html!("div", {
|
|
||||||
style("width", style_width.dynamic());
|
|
||||||
style("height", "50px");
|
|
||||||
style("background-color", "green");
|
|
||||||
event(move |event: ClickEvent| {
|
|
||||||
count += 1;
|
|
||||||
width += 5;
|
|
||||||
|
|
||||||
console!(log, &event);
|
|
||||||
|
|
||||||
sender1.set(width).unwrap();
|
|
||||||
sender2.set(vec![width]).unwrap();
|
|
||||||
sender3.set(vec![width]).unwrap();
|
|
||||||
text_sender.set(format!("{}", width)).unwrap();
|
|
||||||
sender_count.set(count).unwrap();
|
|
||||||
sender_elements.push((increment(), 8));
|
|
||||||
sender_elements.push((increment(), 0));
|
|
||||||
sender_elements.push((increment(), 5));
|
|
||||||
sender_elements.push((increment(), 9));
|
|
||||||
});
|
|
||||||
children(
|
|
||||||
receiver_elements
|
|
||||||
.filter_map(|(x, y)| {
|
|
||||||
if y > 2 {
|
|
||||||
Some((x, y + 100))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.sort_by(|&(_, a), &(_, b)| {
|
|
||||||
a.cmp(&b).reverse()
|
|
||||||
})
|
|
||||||
.map(|(x, y)| {
|
|
||||||
html!("div", {
|
|
||||||
style("border", "5px solid red");
|
|
||||||
style("width", "100px");
|
|
||||||
style("height", "50px");
|
|
||||||
children(&mut [
|
|
||||||
text(format!("({}, {})", x, y))
|
|
||||||
]);
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.dynamic()
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
|
|
||||||
html!("div", {
|
|
||||||
style("width", "50px");
|
|
||||||
style("height", "50px");
|
|
||||||
style("background-color", "red");
|
|
||||||
class(&foobar, true);
|
|
||||||
children(&mut [
|
|
||||||
html!("div", {
|
|
||||||
style("width", "10px");
|
|
||||||
style("height", "10px");
|
|
||||||
style("background-color", "orange");
|
|
||||||
})
|
|
||||||
]);
|
|
||||||
}),
|
|
||||||
|
|
||||||
Dom::with_state(Rc::new(vec![1, 2, 3]), |a| {
|
|
||||||
html!("div", {
|
|
||||||
style("width", "100px");
|
|
||||||
style("height", "100px");
|
|
||||||
style("background-color", "orange");
|
|
||||||
class("foo", true);
|
|
||||||
class("bar", false);
|
|
||||||
event(clone!({ a } move |event: ClickEvent| {
|
|
||||||
console!(log, &*a, &event);
|
|
||||||
}));
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
|
|
||||||
html!("input", {
|
|
||||||
focused(true);
|
|
||||||
}),
|
|
||||||
]);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -129,38 +129,38 @@ fn get_checked(event: &ChangeEvent) -> bool {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn simple(kind: &str, children: &mut [Dom]) -> Dom {
|
fn simple(kind: &str, children: &mut [Dom]) -> Dom {
|
||||||
html!(kind, {
|
html!(kind, {
|
||||||
children(children);
|
.children(children)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn link(href: &str, t: &str) -> Dom {
|
fn link(href: &str, t: &str) -> Dom {
|
||||||
html!("a", {
|
html!("a", {
|
||||||
attribute("href", href);
|
.attribute("href", href)
|
||||||
children(&mut [
|
.children(&mut [
|
||||||
text(t),
|
text(t),
|
||||||
]);
|
])
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filter_button(state: Rc<State>, kind: Filter) -> Dom {
|
fn filter_button(state: Rc<State>, kind: Filter) -> Dom {
|
||||||
html!("a", {
|
html!("a", {
|
||||||
class_signal("selected", state.filter.signal()
|
.class_signal("selected", state.filter.signal()
|
||||||
.map(clone!(kind => move |filter| filter == kind)));
|
.map(clone!(kind => move |filter| filter == kind)))
|
||||||
|
|
||||||
attribute("href", match kind {
|
.attribute("href", match kind {
|
||||||
Filter::Active => "#/active",
|
Filter::Active => "#/active",
|
||||||
Filter::Completed => "#/completed",
|
Filter::Completed => "#/completed",
|
||||||
Filter::All => "#/",
|
Filter::All => "#/",
|
||||||
});
|
})
|
||||||
|
|
||||||
children(&mut [
|
.children(&mut [
|
||||||
text(match kind {
|
text(match kind {
|
||||||
Filter::Active => "Active",
|
Filter::Active => "Active",
|
||||||
Filter::Completed => "Completed",
|
Filter::Completed => "Completed",
|
||||||
Filter::All => "All",
|
Filter::All => "All",
|
||||||
})
|
})
|
||||||
]);
|
])
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,26 +179,26 @@ fn main() {
|
||||||
|
|
||||||
dominator::append_dom(&body,
|
dominator::append_dom(&body,
|
||||||
html!("section", {
|
html!("section", {
|
||||||
class("todoapp");
|
.class("todoapp")
|
||||||
children(&mut [
|
.children(&mut [
|
||||||
html!("header", {
|
html!("header", {
|
||||||
class("header");
|
.class("header")
|
||||||
children(&mut [
|
.children(&mut [
|
||||||
simple("h1", &mut [
|
simple("h1", &mut [
|
||||||
text("todos"),
|
text("todos"),
|
||||||
]),
|
]),
|
||||||
html!("input", {
|
html!("input", {
|
||||||
focused(true);
|
.focused(true)
|
||||||
class("new-todo");
|
.class("new-todo")
|
||||||
attribute("placeholder", "What needs to be done?");
|
.attribute("placeholder", "What needs to be done?")
|
||||||
|
|
||||||
property_signal("value", state.new_todo_title.signal_cloned());
|
.property_signal("value", state.new_todo_title.signal_cloned())
|
||||||
|
|
||||||
event(clone!(state => move |event: InputEvent| {
|
.event(clone!(state => move |event: InputEvent| {
|
||||||
state.new_todo_title.set_neq(get_value(&event));
|
state.new_todo_title.set_neq(get_value(&event));
|
||||||
}));
|
}))
|
||||||
|
|
||||||
event(clone!(state => move |event: KeyDownEvent| {
|
.event(clone!(state => move |event: KeyDownEvent| {
|
||||||
if event.key() == "Enter" {
|
if event.key() == "Enter" {
|
||||||
event.prevent_default();
|
event.prevent_default();
|
||||||
|
|
||||||
|
@ -221,32 +221,32 @@ fn main() {
|
||||||
state.serialize();
|
state.serialize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}));
|
}))
|
||||||
}),
|
}),
|
||||||
]);
|
])
|
||||||
}),
|
}),
|
||||||
|
|
||||||
html!("section", {
|
html!("section", {
|
||||||
class("main");
|
.class("main")
|
||||||
|
|
||||||
// Hide if it doesn't have any todos.
|
// Hide if it doesn't have any todos.
|
||||||
property_signal("hidden", state.todo_list.signal_vec_cloned()
|
.property_signal("hidden", state.todo_list.signal_vec_cloned()
|
||||||
.len()
|
.len()
|
||||||
.map(|len| len == 0));
|
.map(|len| len == 0))
|
||||||
|
|
||||||
children(&mut [
|
.children(&mut [
|
||||||
html!("input", {
|
html!("input", {
|
||||||
class("toggle-all");
|
.class("toggle-all")
|
||||||
attribute("id", "toggle-all");
|
.attribute("id", "toggle-all")
|
||||||
attribute("type", "checkbox");
|
.attribute("type", "checkbox")
|
||||||
|
|
||||||
property_signal("checked", state.todo_list.signal_vec_cloned()
|
.property_signal("checked", state.todo_list.signal_vec_cloned()
|
||||||
.map_signal(|todo| todo.completed.signal())
|
.map_signal(|todo| todo.completed.signal())
|
||||||
.filter(|completed| !completed)
|
.filter(|completed| !completed)
|
||||||
.len()
|
.len()
|
||||||
.map(|len| len != 0));
|
.map(|len| len != 0))
|
||||||
|
|
||||||
event(clone!(state => move |event: ChangeEvent| {
|
.event(clone!(state => move |event: ChangeEvent| {
|
||||||
let checked = !get_checked(&event);
|
let checked = !get_checked(&event);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -258,28 +258,28 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
state.serialize();
|
state.serialize();
|
||||||
}));
|
}))
|
||||||
}),
|
}),
|
||||||
|
|
||||||
html!("label", {
|
html!("label", {
|
||||||
attribute("for", "toggle-all");
|
.attribute("for", "toggle-all")
|
||||||
children(&mut [
|
.children(&mut [
|
||||||
text("Mark all as complete"),
|
text("Mark all as complete"),
|
||||||
]);
|
])
|
||||||
}),
|
}),
|
||||||
|
|
||||||
html!("ul", {
|
html!("ul", {
|
||||||
class("todo-list");
|
.class("todo-list")
|
||||||
|
|
||||||
children_signal_vec(state.todo_list.signal_vec_cloned()
|
.children_signal_vec(state.todo_list.signal_vec_cloned()
|
||||||
.map(clone!(state => move |todo| {
|
.map(clone!(state => move |todo| {
|
||||||
html!("li", {
|
html!("li", {
|
||||||
class_signal("editing", todo.editing.signal_cloned()
|
.class_signal("editing", todo.editing.signal_cloned()
|
||||||
.map(|x| x.is_some()));
|
.map(|x| x.is_some()))
|
||||||
|
|
||||||
class_signal("completed", todo.completed.signal());
|
.class_signal("completed", todo.completed.signal())
|
||||||
|
|
||||||
property_signal("hidden",
|
.property_signal("hidden",
|
||||||
map_ref!(
|
map_ref!(
|
||||||
let filter = state.filter.signal(),
|
let filter = state.filter.signal(),
|
||||||
let completed = todo.completed.signal() =>
|
let completed = todo.completed.signal() =>
|
||||||
|
@ -289,58 +289,58 @@ fn main() {
|
||||||
Filter::All => true,
|
Filter::All => true,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.dedupe_map(|show| !*show));
|
.dedupe_map(|show| !*show))
|
||||||
|
|
||||||
children(&mut [
|
.children(&mut [
|
||||||
html!("div", {
|
html!("div", {
|
||||||
class("view");
|
.class("view")
|
||||||
children(&mut [
|
.children(&mut [
|
||||||
html!("input", {
|
html!("input", {
|
||||||
attribute("type", "checkbox");
|
.attribute("type", "checkbox")
|
||||||
class("toggle");
|
.class("toggle")
|
||||||
|
|
||||||
property_signal("checked", todo.completed.signal());
|
.property_signal("checked", todo.completed.signal())
|
||||||
|
|
||||||
event(clone!(state, todo => move |event: ChangeEvent| {
|
.event(clone!(state, todo => move |event: ChangeEvent| {
|
||||||
todo.completed.set_neq(get_checked(&event));
|
todo.completed.set_neq(get_checked(&event));
|
||||||
state.serialize();
|
state.serialize();
|
||||||
}));
|
}))
|
||||||
}),
|
}),
|
||||||
|
|
||||||
html!("label", {
|
html!("label", {
|
||||||
event(clone!(todo => move |_: DoubleClickEvent| {
|
.event(clone!(todo => move |_: DoubleClickEvent| {
|
||||||
todo.editing.set_neq(Some(todo.title.get_cloned()));
|
todo.editing.set_neq(Some(todo.title.get_cloned()));
|
||||||
}));
|
}))
|
||||||
|
|
||||||
children(&mut [
|
.children(&mut [
|
||||||
text_signal(todo.title.signal_cloned()),
|
text_signal(todo.title.signal_cloned()),
|
||||||
]);
|
])
|
||||||
}),
|
}),
|
||||||
|
|
||||||
html!("button", {
|
html!("button", {
|
||||||
class("destroy");
|
.class("destroy")
|
||||||
event(clone!(state, todo => move |_: ClickEvent| {
|
.event(clone!(state, todo => move |_: ClickEvent| {
|
||||||
state.remove_todo(&todo);
|
state.remove_todo(&todo);
|
||||||
state.serialize();
|
state.serialize();
|
||||||
}));
|
}))
|
||||||
}),
|
}),
|
||||||
]);
|
])
|
||||||
}),
|
}),
|
||||||
|
|
||||||
html!("input", {
|
html!("input", {
|
||||||
class("edit");
|
.class("edit")
|
||||||
|
|
||||||
property_signal("value", todo.editing.signal_cloned()
|
.property_signal("value", todo.editing.signal_cloned()
|
||||||
.map(|x| x.unwrap_or_else(|| "".to_owned())));
|
.map(|x| x.unwrap_or_else(|| "".to_owned())))
|
||||||
|
|
||||||
property_signal("hidden", todo.editing.signal_cloned()
|
.property_signal("hidden", todo.editing.signal_cloned()
|
||||||
.map(|x| x.is_none()));
|
.map(|x| x.is_none()))
|
||||||
|
|
||||||
// TODO dedupe this somehow ?
|
// TODO dedupe this somehow ?
|
||||||
focused_signal(todo.editing.signal_cloned()
|
.focused_signal(todo.editing.signal_cloned()
|
||||||
.map(|x| x.is_some()));
|
.map(|x| x.is_some()))
|
||||||
|
|
||||||
event(clone!(todo => move |event: KeyDownEvent| {
|
.event(clone!(todo => move |event: KeyDownEvent| {
|
||||||
let key = event.key();
|
let key = event.key();
|
||||||
|
|
||||||
if key == "Enter" {
|
if key == "Enter" {
|
||||||
|
@ -350,14 +350,14 @@ fn main() {
|
||||||
} else if key == "Escape" {
|
} else if key == "Escape" {
|
||||||
todo.editing.set_neq(None);
|
todo.editing.set_neq(None);
|
||||||
}
|
}
|
||||||
}));
|
}))
|
||||||
|
|
||||||
event(clone!(todo => move |event: InputEvent| {
|
.event(clone!(todo => move |event: InputEvent| {
|
||||||
todo.editing.set_neq(Some(get_value(&event)));
|
todo.editing.set_neq(Some(get_value(&event)));
|
||||||
}));
|
}))
|
||||||
|
|
||||||
// TODO global_event ?
|
// TODO global_event ?
|
||||||
event(clone!(state, todo => move |_: BlurEvent| {
|
.event(clone!(state, todo => move |_: BlurEvent| {
|
||||||
if let Some(title) = todo.editing.replace(None) {
|
if let Some(title) = todo.editing.replace(None) {
|
||||||
if let Some(title) = trim(&title) {
|
if let Some(title) = trim(&title) {
|
||||||
todo.title.set_neq(title);
|
todo.title.set_neq(title);
|
||||||
|
@ -368,28 +368,28 @@ fn main() {
|
||||||
|
|
||||||
state.serialize();
|
state.serialize();
|
||||||
}
|
}
|
||||||
}));
|
}))
|
||||||
}),
|
}),
|
||||||
]);
|
])
|
||||||
})
|
})
|
||||||
})));
|
})))
|
||||||
}),
|
}),
|
||||||
]);
|
])
|
||||||
}),
|
}),
|
||||||
|
|
||||||
html!("footer", {
|
html!("footer", {
|
||||||
class("footer");
|
.class("footer")
|
||||||
|
|
||||||
// Hide if it doesn't have any todos.
|
// Hide if it doesn't have any todos.
|
||||||
property_signal("hidden", state.todo_list.signal_vec_cloned()
|
.property_signal("hidden", state.todo_list.signal_vec_cloned()
|
||||||
.len()
|
.len()
|
||||||
.map(|len| len == 0));
|
.map(|len| len == 0))
|
||||||
|
|
||||||
children(&mut [
|
.children(&mut [
|
||||||
html!("span", {
|
html!("span", {
|
||||||
class("todo-count");
|
.class("todo-count")
|
||||||
|
|
||||||
children_signal_vec(state.todo_list.signal_vec_cloned()
|
.children_signal_vec(state.todo_list.signal_vec_cloned()
|
||||||
.map_signal(|todo| todo.completed.signal())
|
.map_signal(|todo| todo.completed.signal())
|
||||||
.filter(|completed| !completed)
|
.filter(|completed| !completed)
|
||||||
.len()
|
.len()
|
||||||
|
@ -406,11 +406,11 @@ fn main() {
|
||||||
}),
|
}),
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
.to_signal_vec());
|
.to_signal_vec())
|
||||||
}),
|
}),
|
||||||
html!("ul", {
|
html!("ul", {
|
||||||
class("filters");
|
.class("filters")
|
||||||
children(&mut [
|
.children(&mut [
|
||||||
simple("li", &mut [
|
simple("li", &mut [
|
||||||
filter_button(state.clone(), Filter::All),
|
filter_button(state.clone(), Filter::All),
|
||||||
]),
|
]),
|
||||||
|
@ -420,37 +420,37 @@ fn main() {
|
||||||
simple("li", &mut [
|
simple("li", &mut [
|
||||||
filter_button(state.clone(), Filter::Completed),
|
filter_button(state.clone(), Filter::Completed),
|
||||||
]),
|
]),
|
||||||
]);
|
])
|
||||||
}),
|
}),
|
||||||
html!("button", {
|
html!("button", {
|
||||||
class("clear-completed");
|
.class("clear-completed")
|
||||||
|
|
||||||
// Hide if it doesn't have any completed items.
|
// Hide if it doesn't have any completed items.
|
||||||
property_signal("hidden", state.todo_list.signal_vec_cloned()
|
.property_signal("hidden", state.todo_list.signal_vec_cloned()
|
||||||
.map_signal(|todo| todo.completed.signal())
|
.map_signal(|todo| todo.completed.signal())
|
||||||
.filter(|completed| *completed)
|
.filter(|completed| *completed)
|
||||||
.len()
|
.len()
|
||||||
.map(|len| len == 0));
|
.map(|len| len == 0))
|
||||||
|
|
||||||
event(clone!(state => move |_: ClickEvent| {
|
.event(clone!(state => move |_: ClickEvent| {
|
||||||
state.todo_list.retain(|todo| todo.completed.get() == false);
|
state.todo_list.retain(|todo| todo.completed.get() == false);
|
||||||
state.serialize();
|
state.serialize();
|
||||||
}));
|
}))
|
||||||
|
|
||||||
children(&mut [
|
.children(&mut [
|
||||||
text("Clear completed"),
|
text("Clear completed"),
|
||||||
]);
|
])
|
||||||
}),
|
}),
|
||||||
]);
|
])
|
||||||
}),
|
}),
|
||||||
]);
|
])
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
dominator::append_dom(&body,
|
dominator::append_dom(&body,
|
||||||
html!("footer", {
|
html!("footer", {
|
||||||
class("info");
|
.class("info")
|
||||||
children(&mut [
|
.children(&mut [
|
||||||
simple("p", &mut [
|
simple("p", &mut [
|
||||||
text("Double-click to edit a todo"),
|
text("Double-click to edit a todo"),
|
||||||
]),
|
]),
|
||||||
|
@ -462,7 +462,7 @@ fn main() {
|
||||||
text("Part of "),
|
text("Part of "),
|
||||||
link("http://todomvc.com", "TodoMVC"),
|
link("http://todomvc.com", "TodoMVC"),
|
||||||
]),
|
]),
|
||||||
]);
|
])
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ macro_rules! builder {
|
||||||
($namespace:expr, $default:ty, $kind:expr => $t:ty) => {
|
($namespace:expr, $default:ty, $kind:expr => $t:ty) => {
|
||||||
builder!($namespace, $default, $kind => $t, {})
|
builder!($namespace, $default, $kind => $t, {})
|
||||||
};
|
};
|
||||||
($namespace:expr, $default:ty, $kind:expr => $t:ty, { $( $name:ident( $( $args:expr ),* ); )* }) => {{
|
($namespace:expr, $default:ty, $kind:expr => $t:ty, { $(.$name:ident($($args:expr),*))* }) => {{
|
||||||
let a: $crate::DomBuilder<$t> = $crate::DomBuilder::new($crate::create_element_ns($kind, $namespace))$(.$name($($args),*))*;
|
let a: $crate::DomBuilder<$t> = $crate::DomBuilder::new($crate::create_element_ns($kind, $namespace))$(.$name($($args),*))*;
|
||||||
let b: $crate::Dom = $crate::DomBuilder::into_dom(a);
|
let b: $crate::Dom = $crate::DomBuilder::into_dom(a);
|
||||||
b
|
b
|
||||||
|
@ -12,8 +12,8 @@ macro_rules! builder {
|
||||||
($namespace:expr, $default:ty, $kind:expr) => {
|
($namespace:expr, $default:ty, $kind:expr) => {
|
||||||
builder!($namespace, $default, $kind => $default)
|
builder!($namespace, $default, $kind => $default)
|
||||||
};
|
};
|
||||||
($namespace:expr, $default:ty, $kind:expr, { $( $name:ident( $( $args:expr ),* ); )* }) => {
|
($namespace:expr, $default:ty, $kind:expr, { $(.$name:ident($($args:expr),*))* }) => {
|
||||||
builder!($namespace, $default, $kind => $default, { $( $name( $( $args ),* ); )* })
|
builder!($namespace, $default, $kind => $default, { $(.$name($($args),*))* })
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ macro_rules! stylesheet {
|
||||||
($rule:expr) => {
|
($rule:expr) => {
|
||||||
stylesheet!($rule, {})
|
stylesheet!($rule, {})
|
||||||
};
|
};
|
||||||
($rule:expr, { $( $name:ident( $( $args:expr ),* ); )* }) => {
|
($rule:expr, { $(.$name:ident($($args:expr),*))* }) => {
|
||||||
$crate::StylesheetBuilder::new($rule)$(.$name($($args),*))*.done()
|
$crate::StylesheetBuilder::new($rule)$(.$name($($args),*))*.done()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ macro_rules! stylesheet {
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! class {
|
macro_rules! class {
|
||||||
($( $name:ident( $( $args:expr ),* ); )*) => {
|
($(.$name:ident($($args:expr),*))*) => {
|
||||||
$crate::ClassBuilder::new()$(.$name($($args),*))*.done()
|
$crate::ClassBuilder::new()$(.$name($($args),*))*.done()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue