-
-
Notifications
You must be signed in to change notification settings - Fork 697
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add directives with
use:
(#1821)
- Loading branch information
Showing
15 changed files
with
370 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
[build] | ||
rustflags = ["--cfg=web_sys_unstable_apis"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
[package] | ||
name = "directives" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
leptos = { path = "../../leptos", features = ["csr", "nightly"] } | ||
log = "0.4" | ||
console_log = "1" | ||
console_error_panic_hook = "0.1.7" | ||
web-sys = { version = "0.3", features = ["Clipboard", "Navigator"] } | ||
|
||
[dev-dependencies] | ||
wasm-bindgen-test = "0.3.0" | ||
wasm-bindgen = "0.2" | ||
web-sys = "0.3" | ||
gloo-timers = { version = "0.3", features = ["futures"] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
extend = [ | ||
{ path = "../cargo-make/main.toml" }, | ||
{ path = "../cargo-make/wasm-test.toml" }, | ||
{ path = "../cargo-make/trunk_server.toml" }, | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Leptos Directives Example | ||
|
||
This example showcases a basic leptos app that shows how to write and use directives. | ||
|
||
## Getting Started | ||
|
||
See the [Examples README](../README.md) for setup and run instructions. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<link data-trunk rel="rust" data-wasm-opt="z" data-weak-refs/> | ||
</head> | ||
<body></body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
|
||
[toolchain] | ||
channel = "nightly" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
use leptos::{ev::click, html::AnyElement, *}; | ||
|
||
pub fn highlight(el: HtmlElement<AnyElement>) { | ||
let mut highlighted = false; | ||
|
||
let _ = el.clone().on(click, move |_| { | ||
highlighted = !highlighted; | ||
|
||
if highlighted { | ||
let _ = el.clone().style("background-color", "yellow"); | ||
} else { | ||
let _ = el.clone().style("background-color", "transparent"); | ||
} | ||
}); | ||
} | ||
|
||
pub fn copy_to_clipboard(el: HtmlElement<AnyElement>, content: &str) { | ||
let content = content.to_string(); | ||
|
||
let _ = el.clone().on(click, move |evt| { | ||
evt.prevent_default(); | ||
evt.stop_propagation(); | ||
|
||
let _ = window() | ||
.navigator() | ||
.clipboard() | ||
.expect("navigator.clipboard to be available") | ||
.write_text(&content); | ||
|
||
let _ = el.clone().inner_html(format!("Copied \"{}\"", &content)); | ||
}); | ||
} | ||
|
||
#[component] | ||
pub fn SomeComponent() -> impl IntoView { | ||
view! { | ||
<p>Some paragraphs</p> | ||
<p>that can be clicked</p> | ||
<p>in order to highlight them</p> | ||
} | ||
} | ||
|
||
#[component] | ||
pub fn App() -> impl IntoView { | ||
let data = "Hello World!"; | ||
|
||
view! { | ||
<a href="#" use:copy_to_clipboard=data>"Copy \"" {data} "\" to clipboard"</a> | ||
<SomeComponent use:highlight /> | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
use directives::App; | ||
use leptos::*; | ||
|
||
fn main() { | ||
_ = console_log::init_with_level(log::Level::Debug); | ||
console_error_panic_hook::set_once(); | ||
mount_to_body(|| view! { <App/> }) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
use gloo_timers::future::sleep; | ||
use std::time::Duration; | ||
use wasm_bindgen::JsCast; | ||
use wasm_bindgen_test::*; | ||
|
||
wasm_bindgen_test_configure!(run_in_browser); | ||
use directives::App; | ||
use leptos::*; | ||
use web_sys::HtmlElement; | ||
|
||
#[wasm_bindgen_test] | ||
async fn test_directives() { | ||
mount_to_body(|| view! { <App/> }); | ||
sleep(Duration::ZERO).await; | ||
|
||
let document = leptos::document(); | ||
let paragraphs = document.query_selector_all("p").unwrap(); | ||
|
||
assert_eq!(paragraphs.length(), 3); | ||
|
||
for i in 0..paragraphs.length() { | ||
println!("i: {}", i); | ||
let p = paragraphs | ||
.item(i) | ||
.unwrap() | ||
.dyn_into::<HtmlElement>() | ||
.unwrap(); | ||
assert_eq!( | ||
p.style().get_property_value("background-color").unwrap(), | ||
"" | ||
); | ||
|
||
p.click(); | ||
|
||
assert_eq!( | ||
p.style().get_property_value("background-color").unwrap(), | ||
"yellow" | ||
); | ||
|
||
p.click(); | ||
|
||
assert_eq!( | ||
p.style().get_property_value("background-color").unwrap(), | ||
"transparent" | ||
); | ||
} | ||
|
||
let a = document | ||
.query_selector("a") | ||
.unwrap() | ||
.unwrap() | ||
.dyn_into::<HtmlElement>() | ||
.unwrap(); | ||
assert_eq!(a.inner_html(), "Copy \"Hello World!\" to clipboard"); | ||
|
||
a.click(); | ||
assert_eq!(a.inner_html(), "Copied \"Hello World!\""); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
use crate::{html::AnyElement, HtmlElement}; | ||
use std::rc::Rc; | ||
|
||
/// Trait for a directive handler function. | ||
/// This is used so it's possible to use functions with one or two | ||
/// parameters as directive handlers. | ||
/// | ||
/// You can use directives like the following. | ||
/// | ||
/// ``` | ||
/// # use leptos::{*, html::AnyElement}; | ||
/// | ||
/// // This doesn't take an attribute value | ||
/// fn my_directive(el: HtmlElement<AnyElement>) { | ||
/// // do sth | ||
/// } | ||
/// | ||
/// // This requires an attribute value | ||
/// fn another_directive(el: HtmlElement<AnyElement>, params: i32) { | ||
/// // do sth | ||
/// } | ||
/// | ||
/// #[component] | ||
/// pub fn MyComponent() -> impl IntoView { | ||
/// view! { | ||
/// // no attribute value | ||
/// <div use:my_directive></div> | ||
/// | ||
/// // with an attribute value | ||
/// <div use:another_directive=8></div> | ||
/// } | ||
/// } | ||
/// ``` | ||
/// | ||
/// A directive is just syntactic sugar for | ||
/// | ||
/// ```ignore | ||
/// let node_ref = create_node_ref(); | ||
/// | ||
/// create_effect(move |_| { | ||
/// if let Some(el) = node_ref.get() { | ||
/// directive_func(el, possibly_some_param); | ||
/// } | ||
/// }); | ||
/// ``` | ||
/// | ||
/// A directive can be a function with one or two parameters. | ||
/// The first is the element the directive is added to and the optional | ||
/// second is the parameter that is provided in the attribute. | ||
pub trait Directive<T: ?Sized, P> { | ||
/// Calls the handler function | ||
fn run(&self, el: HtmlElement<AnyElement>, param: P); | ||
} | ||
|
||
impl<F> Directive<(HtmlElement<AnyElement>,), ()> for F | ||
where | ||
F: Fn(HtmlElement<AnyElement>), | ||
{ | ||
fn run(&self, el: HtmlElement<AnyElement>, _: ()) { | ||
self(el) | ||
} | ||
} | ||
|
||
impl<F, P> Directive<(HtmlElement<AnyElement>, P), P> for F | ||
where | ||
F: Fn(HtmlElement<AnyElement>, P), | ||
{ | ||
fn run(&self, el: HtmlElement<AnyElement>, param: P) { | ||
self(el, param); | ||
} | ||
} | ||
|
||
impl<T: ?Sized, P> Directive<T, P> for Rc<dyn Directive<T, P>> { | ||
fn run(&self, el: HtmlElement<AnyElement>, param: P) { | ||
(**self).run(el, param) | ||
} | ||
} | ||
|
||
impl<T: ?Sized, P> Directive<T, P> for Box<dyn Directive<T, P>> { | ||
fn run(&self, el: HtmlElement<AnyElement>, param: P) { | ||
(**self).run(el, param); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.