Adding in link, apply_methods, with_node, and on_click_go_to_url macros
This commit is contained in:
parent
b4aadeb42b
commit
2bed86b49e
|
@ -5,7 +5,7 @@ use wasm_bindgen::prelude::*;
|
|||
use serde_derive::{Serialize, Deserialize};
|
||||
use futures_signals::signal::{Signal, SignalExt, Mutable};
|
||||
use futures_signals::signal_vec::{SignalVec, SignalVecExt, MutableVec};
|
||||
use dominator::{Dom, text_signal, routing, html, clone, events};
|
||||
use dominator::{Dom, text_signal, html, clone, events, link};
|
||||
|
||||
use crate::todo::Todo;
|
||||
use crate::routing::Route;
|
||||
|
@ -166,7 +166,7 @@ impl App {
|
|||
fn render_button(text: &str, route: Route) -> Dom {
|
||||
html!("li", {
|
||||
.children(&mut [
|
||||
routing::link(route.url(), |dom| { dom
|
||||
link!(route.url(), {
|
||||
.text(text)
|
||||
.class_signal("selected", Route::signal().map(move |x| x == route))
|
||||
})
|
||||
|
|
|
@ -2,10 +2,9 @@ use std::rc::Rc;
|
|||
|
||||
use wasm_bindgen::prelude::*;
|
||||
use serde_derive::{Serialize, Deserialize};
|
||||
use web_sys::HtmlElement;
|
||||
use futures_signals::map_ref;
|
||||
use futures_signals::signal::{SignalExt, Mutable};
|
||||
use dominator::{Dom, html, clone, events};
|
||||
use dominator::{Dom, html, clone, events, with_node};
|
||||
|
||||
use crate::util::trim;
|
||||
use crate::app::App;
|
||||
|
@ -120,20 +119,19 @@ impl Todo {
|
|||
.focused_signal(todo.editing.signal_cloned()
|
||||
.map(|x| x.is_some()))
|
||||
|
||||
.event(clone!(todo => move |event: events::KeyDown| {
|
||||
match event.key().as_str() {
|
||||
"Enter" => {
|
||||
event.dyn_target::<HtmlElement>()
|
||||
.unwrap_throw()
|
||||
.blur()
|
||||
.unwrap_throw();
|
||||
},
|
||||
"Escape" => {
|
||||
todo.cancel_editing();
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}))
|
||||
.with_node!(element => {
|
||||
.event(clone!(todo => move |event: events::KeyDown| {
|
||||
match event.key().as_str() {
|
||||
"Enter" => {
|
||||
element.blur().unwrap_throw();
|
||||
},
|
||||
"Escape" => {
|
||||
todo.cancel_editing();
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
.event(clone!(todo => move |event: events::Input| {
|
||||
todo.editing.set_neq(Some(event.value().unwrap_throw()));
|
||||
|
|
13
src/dom.rs
13
src/dom.rs
|
@ -380,6 +380,18 @@ pub struct DomBuilder<A> {
|
|||
has_children: bool,
|
||||
}
|
||||
|
||||
impl<A> DomBuilder<A> where A: JsCast {
|
||||
#[inline]
|
||||
pub fn new_html(name: &str) -> Self {
|
||||
Self::new(create_element(name))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn new_svg(name: &str) -> Self {
|
||||
Self::new(create_element_ns(name, SVG_NAMESPACE))
|
||||
}
|
||||
}
|
||||
|
||||
impl<A> DomBuilder<A> {
|
||||
#[inline]
|
||||
pub fn new(value: A) -> Self {
|
||||
|
@ -443,6 +455,7 @@ impl<A> DomBuilder<A> where A: Clone {
|
|||
self.element.clone()
|
||||
}
|
||||
|
||||
#[deprecated(since = "0.5.1", note = "Use the with_node macro instead")]
|
||||
#[inline]
|
||||
pub fn with_element<B, F>(self, f: F) -> B where F: FnOnce(Self, A) -> B {
|
||||
let element = self.element.clone();
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! __internal_builder_method {
|
||||
($this:expr,) => {
|
||||
macro_rules! apply_methods {
|
||||
($this:expr, {}) => {
|
||||
$this
|
||||
};
|
||||
($this:expr, .$name:ident!($($args:tt)*) $($rest:tt)*) => {
|
||||
$crate::__internal_builder_method!($name!($this, $($args)*), $($rest)*)
|
||||
($this:expr, { .$name:ident!($($args:tt)*) $($rest:tt)* }) => {
|
||||
$crate::apply_methods!({
|
||||
let this = $this;
|
||||
$name!(this, $($args)*)
|
||||
}, { $($rest)* })
|
||||
};
|
||||
($this:expr, .$name:ident($($args:expr),*) $($rest:tt)*) => {
|
||||
$crate::__internal_builder_method!($this.$name($($args),*), $($rest)*)
|
||||
($this:expr, { .$name:ident($($args:expr),*) $($rest:tt)* }) => {
|
||||
$crate::apply_methods!($this.$name($($args),*), { $($rest)* })
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -16,32 +18,28 @@ macro_rules! __internal_builder_method {
|
|||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! __internal_builder {
|
||||
($default:ty, $name:ident => $make:expr, $kind:expr) => {
|
||||
$crate::__internal_builder!($default, $name => $make, $kind => $default, {})
|
||||
($default:ty, $make:ident, $kind:expr) => {
|
||||
$crate::__internal_builder!($default, $make, $kind => $default, {})
|
||||
};
|
||||
($default:ty, $name:ident => $make:expr, $kind:expr, $($rest:tt)*) => {
|
||||
$crate::__internal_builder!($default, $name => $make, $kind => $default, $($rest)*)
|
||||
($default:ty, $make:ident, $kind:expr, $($rest:tt)*) => {
|
||||
$crate::__internal_builder!($default, $make, $kind => $default, $($rest)*)
|
||||
};
|
||||
($default:ty, $name:ident => $make:expr, $kind:expr => $t:ty) => {
|
||||
$crate::__internal_builder!($default, $name => $make, $kind => $t, {})
|
||||
($default:ty, $make:ident, $kind:expr => $t:ty) => {
|
||||
$crate::__internal_builder!($default, $make, $kind => $t, {})
|
||||
};
|
||||
($default:ty, $name:ident => $make:expr, $kind:expr => $t:ty, { $($methods:tt)* }) => {{
|
||||
let a: $t = {
|
||||
let $name = $kind;
|
||||
$make
|
||||
};
|
||||
let b = $crate::DomBuilder::new(a);
|
||||
let c = $crate::__internal_builder_method!(b, $($methods)*);
|
||||
$crate::DomBuilder::into_dom(c)
|
||||
($default:ty, $make:ident, $kind:expr => $t:ty, $($methods:tt)*) => {{
|
||||
let builder = $crate::DomBuilder::<$t>::$make($kind);
|
||||
let output = $crate::apply_methods!(builder, $($methods)*);
|
||||
$crate::DomBuilder::into_dom(output)
|
||||
}};
|
||||
}
|
||||
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! with_node {
|
||||
($this:expr, $name:ident => { $($methods:tt)* }) => {{
|
||||
($this:ident, $name:ident => { $($methods:tt)* }) => {{
|
||||
let $name = $crate::DomBuilder::__internal_element(&$this);
|
||||
$crate::__internal_builder_method!($this, $($methods)*)
|
||||
$crate::apply_methods!($this, { $($methods)* })
|
||||
}};
|
||||
}
|
||||
|
||||
|
@ -49,7 +47,7 @@ macro_rules! with_node {
|
|||
#[macro_export]
|
||||
macro_rules! html {
|
||||
($($args:tt)+) => {
|
||||
$crate::__internal_builder!($crate::HtmlElement, kind => $crate::create_element(kind), $($args)+)
|
||||
$crate::__internal_builder!($crate::HtmlElement, new_html, $($args)+)
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -57,7 +55,7 @@ macro_rules! html {
|
|||
#[macro_export]
|
||||
macro_rules! svg {
|
||||
($($args:tt)+) => {
|
||||
$crate::__internal_builder!($crate::SvgElement, kind => $crate::create_element_ns(kind, $crate::SVG_NAMESPACE), $($args)+)
|
||||
$crate::__internal_builder!($crate::SvgElement, new_svg, $($args)+)
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -67,19 +65,17 @@ macro_rules! stylesheet {
|
|||
($rule:expr) => {
|
||||
$crate::stylesheet!($rule, {})
|
||||
};
|
||||
($rule:expr, { $($methods:tt)* }) => {{
|
||||
let a = $crate::StylesheetBuilder::new($rule);
|
||||
$crate::__internal_builder_method!(a, $($methods)*).done()
|
||||
}};
|
||||
($rule:expr, { $($methods:tt)* }) => {
|
||||
$crate::apply_methods!($crate::StylesheetBuilder::new($rule), { $($methods)* }).done()
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! class {
|
||||
($($methods:tt)*) => {{
|
||||
let a = $crate::ClassBuilder::new();
|
||||
$crate::__internal_builder_method!(a, $($methods)*).done()
|
||||
}};
|
||||
($($methods:tt)*) => {
|
||||
$crate::apply_methods!($crate::ClassBuilder::new(), { $($methods)* }).done()
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@ pub fn go_to_url(new_url: &str) {
|
|||
}
|
||||
|
||||
|
||||
#[deprecated(since = "0.5.1", note = "Use the on_click_go_to_url macro instead")]
|
||||
#[inline]
|
||||
pub fn on_click_go_to_url<A, B>(new_url: A) -> impl FnOnce(DomBuilder<B>) -> DomBuilder<B>
|
||||
where A: Into<Cow<'static, str>>,
|
||||
|
@ -87,6 +88,8 @@ pub fn on_click_go_to_url<A, B>(new_url: A) -> impl FnOnce(DomBuilder<B>) -> Dom
|
|||
|
||||
// TODO better type than HtmlElement
|
||||
// TODO maybe make this a macro ?
|
||||
#[deprecated(since = "0.5.1", note = "Use the link macro instead")]
|
||||
#[allow(deprecated)]
|
||||
#[inline]
|
||||
pub fn link<A, F>(url: A, f: F) -> Dom
|
||||
where A: Into<Cow<'static, str>>,
|
||||
|
@ -99,3 +102,31 @@ pub fn link<A, F>(url: A, f: F) -> Dom
|
|||
.apply(f)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// TODO test this
|
||||
#[macro_export]
|
||||
macro_rules! on_click_go_to_url {
|
||||
($this:ident, $url:expr) => {{
|
||||
let url = $url;
|
||||
|
||||
$this.event_preventable(move |e: $crate::events::Click| {
|
||||
e.prevent_default();
|
||||
$crate::routing::go_to_url(&url);
|
||||
})
|
||||
}};
|
||||
}
|
||||
|
||||
// TODO test this
|
||||
#[macro_export]
|
||||
macro_rules! link {
|
||||
($url:expr, { $($methods:tt)* }) => {{
|
||||
let url = $url;
|
||||
|
||||
$crate::html!("a", {
|
||||
.attribute("href", &url)
|
||||
.apply(move |dom| $crate::on_click_go_to_url!(dom, url))
|
||||
$($methods)*
|
||||
})
|
||||
}};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue