diff --git a/examples/hello_world.rs b/examples/hello_world.rs index e70de82..c1eebf7 100644 --- a/examples/hello_world.rs +++ b/examples/hello_world.rs @@ -1,4 +1,5 @@ -use leptos::*; +use leptos::{ev::keydown, *}; +use leptos_use::use_event_listener; use lerni::*; #[component] @@ -11,10 +12,43 @@ pub fn HelloWorld() -> impl IntoView { + } } +#[component] +pub fn Counter() -> impl IntoView { + let (counter, set_counter) = create_signal(0); + + let node_ref = create_node_ref(); + _ = use_event_listener(document().body(), keydown, move |e| { + if is_active_slide(node_ref) { + if e.key() == "Enter" { + set_counter.set(counter.get() + 1); + } else if e.key() == "Escape" && counter.get() > 0 { + set_counter.set(counter.get() - 1); + } + } + }); + + create_effect(move |_| { + if let Some(el) = node_ref.get() { + let panel_item = + view! { }; + _ = el.on_mount(move |_| mount_on_panel(node_ref, panel_item)); + } + }); + + view! { + + + + } +} + #[wasm_bindgen(start)] pub fn main() { lerni::start(HelloWorld); diff --git a/src/utils.rs b/src/utils.rs index 04d7f6f..57d2c4c 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,4 +1,4 @@ -use leptos::*; +use leptos::{html::Div, *}; /// Start function. /// @@ -69,3 +69,39 @@ pub mod keys { /// Digit 9 key. pub const DIGIT_9: u32 = 57; } + +/// Check whether a slide is active. +pub fn is_active_slide(node_ref: NodeRef
) -> bool { + if let Some(node) = node_ref.get() { + if let Some(parent) = node.parent_element() { + return parent.get_attribute("hidden").is_none(); + } + } + + false +} + +/// Check whether a slide is visible. +pub fn slide_number(node_ref: NodeRef
) -> Option { + if let Some(node) = node_ref.get_untracked() { + if let Some(parent) = node.parent_element() { + return parent.get_attribute("number").and_then(|n| n.parse().ok()); + } + } + + None +} + +/// Mount a child view on a panel. +pub fn mount_on_panel(node_ref: NodeRef
, item: impl IntoView) { + let panel_item_refs: Option>> = use_context(); + if let Some(panel_item_refs) = panel_item_refs { + if let Some(n) = slide_number(node_ref) { + if let Some(panel_item_ref) = panel_item_refs.get(n) { + if let Some(el) = panel_item_ref.get_untracked() { + _ = el.child(item); + } + } + } + } +} diff --git a/src/widgets.rs b/src/widgets.rs index 9dfa642..fc3f5c9 100644 --- a/src/widgets.rs +++ b/src/widgets.rs @@ -25,8 +25,6 @@ pub use text::Text; /// Additional information provided to all slides. #[derive(Clone, Copy, Default, Debug, PartialEq)] pub struct Metadata { - /// Visibility flag. - pub visible: bool, /// Teacher mode flag. pub teacher_mode: bool, /// Pointer on/off flag. diff --git a/src/widgets/slide.rs b/src/widgets/slide.rs index 4365ae4..065369c 100644 --- a/src/widgets/slide.rs +++ b/src/widgets/slide.rs @@ -1,5 +1,6 @@ use leptos::{ ev::{resize, MouseEvent}, + html::Div, svg::Svg, *, }; @@ -21,6 +22,7 @@ pub fn Slide( #[prop(optional, into)] pointer: MaybeSignal, #[prop(optional, into)] blur: MaybeSignal, #[prop(default = 15)] blur_radius: i32, + #[prop(optional)] node_ref: Option>, children: Children, ) -> impl IntoView { let metadata = use_context::(); @@ -82,8 +84,11 @@ pub fn Slide( Default::default() }; + let node_ref = node_ref.unwrap_or_else(create_node_ref); + view! { } + let panel_item_ref = create_node_ref(); + panel_item_refs.push(panel_item_ref); + panel_items + .push(view! { }); + view! { + + } }) .collect_view(); + provide_context(panel_item_refs); + view! {
-
{children}
+
+ {children} {panel_items} +
@@ -75,15 +88,25 @@ pub fn SlideShow( } #[component] -fn ControlPanel() -> impl IntoView { +fn ControlPanel(children: Children) -> impl IntoView { view! {
-
- +
+

+ +

+

+ +

+ {children()}
} @@ -190,3 +213,11 @@ fn is_page_number_visible(index: usize, current: usize, count: usize) -> bool { pages.contains(&index) } } + +fn history_back(_event: MouseEvent) { + if let Some(window) = web_sys::window() { + if let Ok(history) = window.history() { + history.back().unwrap_or_default(); + } + } +}