diff --git a/gh-pages/src/app.rs b/gh-pages/src/app.rs index 2e66b3d..96f653c 100644 --- a/gh-pages/src/app.rs +++ b/gh-pages/src/app.rs @@ -46,6 +46,9 @@ pub fn App(cx: Scope) -> impl IntoView { <Route path="/checkbox" view=move |cx| view! {cx, <CheckboxPage /> } /> + <Route path="/toast" view=move |cx| view! {cx, + <MobilePage path="/melt-ui?path=/mobile/toast" /> + } /> </Route> </Routes> <Routes base="/melt-ui/mobile".to_string()> @@ -55,6 +58,9 @@ pub fn App(cx: Scope) -> impl IntoView { <Route path="/nav-bar" view=move |cx| view! {cx, <NavBarPage /> } /> + <Route path="/toast" view=move |cx| view! {cx, + <ToastPage /> + } /> </Routes> </Router> } diff --git a/gh-pages/src/pages/components.rs b/gh-pages/src/pages/components.rs index c57fd4f..235e705 100644 --- a/gh-pages/src/pages/components.rs +++ b/gh-pages/src/pages/components.rs @@ -42,6 +42,7 @@ pub fn ComponentsPage(cx: Scope) -> impl IntoView { <MenuItem key="nav-bar" label="nav-bar" /> <MenuItem key="button" label="button" /> <MenuItem key="checkbox" label="checkbox" /> + <MenuItem key="toast" label="toast" /> </Menu> </aside> <main> diff --git a/gh-pages/src/pages/mod.rs b/gh-pages/src/pages/mod.rs index 54f95c8..8f587ec 100644 --- a/gh-pages/src/pages/mod.rs +++ b/gh-pages/src/pages/mod.rs @@ -10,6 +10,7 @@ mod modal; mod nav_bar; mod slider; mod tabbar; +mod toast; pub use button::*; pub use checkbox::*; @@ -23,3 +24,4 @@ pub use modal::*; pub use nav_bar::*; pub use slider::*; pub use tabbar::*; +pub use toast::*; diff --git a/gh-pages/src/pages/toast/mod.rs b/gh-pages/src/pages/toast/mod.rs new file mode 100644 index 0000000..edd8bee --- /dev/null +++ b/gh-pages/src/pages/toast/mod.rs @@ -0,0 +1,24 @@ +use std::time::Duration; +use leptos::*; +use melt_ui::mobile::*; +use melt_ui::*; + +#[component] +pub fn ToastPage(cx: Scope) -> impl IntoView { + let count = create_rw_signal(cx, 0u32); + let onclick = move |_| { + show_toast( + cx, + ToastOptions { + message: format!("Hello {}", count.get_untracked()), + duration: Duration::from_millis(2000), + }, + ); + count.set(count.get_untracked() + 1); + }; + view! {cx, + <div style="margin: 20px"> + <Button on:click=onclick>"hi"</Button> + </div> + } +} diff --git a/src/mobile/mod.rs b/src/mobile/mod.rs index 4ea22ba..10e8be6 100644 --- a/src/mobile/mod.rs +++ b/src/mobile/mod.rs @@ -1,5 +1,7 @@ -mod tabbar; mod nav_bar; +mod tabbar; +mod toast; +pub use nav_bar::*; pub use tabbar::*; -pub use nav_bar::*; \ No newline at end of file +pub use toast::*; diff --git a/src/mobile/toast/mod.rs b/src/mobile/toast/mod.rs new file mode 100644 index 0000000..cd94eeb --- /dev/null +++ b/src/mobile/toast/mod.rs @@ -0,0 +1,35 @@ +use crate::utils::mount_style::mount_style; +use leptos::*; +use std::time::Duration; +use stylers::style_sheet_str; +use web_sys::Element; + +pub struct ToastOptions { + pub message: String, + pub duration: Duration, +} + +pub fn show_toast(cx: Scope, options: ToastOptions) { + let class_name = mount_style("toast", || style_sheet_str!("./src/mobile/toast/toast.css")); + + let parent = Element::from(document().body().expect("body element not to exist")); + let children = view! {cx, class=class_name, + <div class="melt-toast"> + { options.message } + </div> + }; + let node = children.into_view(cx); + + #[cfg(all(target_arch = "wasm32"))] + { + use leptos_dom::Mountable; + let node = node.get_mountable_node(); + parent.append_child(&node).unwrap(); + set_timeout( + move || { + _ = parent.remove_child(&node); + }, + options.duration, + ); + } +} diff --git a/src/mobile/toast/toast.css b/src/mobile/toast/toast.css new file mode 100644 index 0000000..cc0ac3a --- /dev/null +++ b/src/mobile/toast/toast.css @@ -0,0 +1,15 @@ +.melt-toast { + white-space: pre-wrap; + word-break: break-all; + max-width: 80%; + font-size: 14px; + line-height: 20px; + color: #fff; + background-color: #000000b3; + padding: 8px 12px; + position: fixed; + top: 50%; + left: 50%; + transform: translate3d(-50%, -50%, 0); + border-radius: 8px; +}