A massive, unorganized PR. #44
No files matched your search
+7
-1
@@ -1,2 +1,8 @@
|
|||||||
[target.'cfg(target_os = "linux")']
|
[target.'cfg(target_os = "linux")']
|
||||||
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
|
rustflags = [
|
||||||
|
"--cfg=web_sys_unstable_apis",
|
||||||
|
"-C", "link-arg=-fuse-ld=mold"
|
||||||
|
]
|
||||||
|
|
||||||
|
[target.wasm32-unknown-unknown]
|
||||||
|
rustflags = ["--cfg=web_sys_unstable_apis"]
|
||||||
Generated
+613
-753
File diff suppressed because it is too large.
Load diff
+3
-1
@@ -14,7 +14,7 @@ console_error_panic_hook = { version = "0.1", optional = true}
|
|||||||
leptos_axum = { version = "0.8", optional = true }
|
leptos_axum = { version = "0.8", optional = true }
|
||||||
leptos_meta = { version = "0.8" }
|
leptos_meta = { version = "0.8" }
|
||||||
tokio = { version = "1", features = ["rt-multi-thread"], optional = true }
|
tokio = { version = "1", features = ["rt-multi-thread"], optional = true }
|
||||||
wasm-bindgen = { version = "=0.2.100", optional = true }
|
wasm-bindgen = { version = "=0.2.106", optional = true }
|
||||||
aws-sdk-dynamodb = { version = "1", optional = true }
|
aws-sdk-dynamodb = { version = "1", optional = true }
|
||||||
aws-config = { version = "1.6.2", optional = true }
|
aws-config = { version = "1.6.2", optional = true }
|
||||||
serde = "1.0.219"
|
serde = "1.0.219"
|
||||||
@@ -24,11 +24,13 @@ leptos_oidc = "0.9.0"
|
|||||||
base64 = "0.22.1"
|
base64 = "0.22.1"
|
||||||
chrono = "0.4.42"
|
chrono = "0.4.42"
|
||||||
regex = "1.11.2"
|
regex = "1.11.2"
|
||||||
|
leptos_animate = "0.1.9"
|
||||||
|
|
||||||
macros = { path = "./macros" }
|
macros = { path = "./macros" }
|
||||||
traits = { path = "./traits" }
|
traits = { path = "./traits" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
default = ["ssr"]
|
||||||
hydrate = [
|
hydrate = [
|
||||||
"leptos/hydrate",
|
"leptos/hydrate",
|
||||||
"dep:console_error_panic_hook",
|
"dep:console_error_panic_hook",
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
mod toast_list;
|
||||||
|
mod toast;
|
||||||
|
|
||||||
|
pub use toast_list::*;
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
use std::time::Duration;
|
||||||
|
use leptos::prelude::*;
|
||||||
|
use leptos_animate::animate;
|
||||||
|
use leptos_animate::animations::classes::In;
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn Toast(
|
||||||
|
#[prop(into)] on_close: Callback<()>,
|
||||||
|
#[prop(into)] message: Signal<String>,
|
||||||
|
#[prop(into)] title: Signal<String>
|
||||||
|
) -> impl IntoView {
|
||||||
|
set_timeout(
|
||||||
|
move || {
|
||||||
|
on_close.run(())
|
||||||
|
},
|
||||||
|
Duration::from_secs(3)
|
||||||
|
);
|
||||||
|
|
||||||
|
view! {
|
||||||
|
<div class="flex flex-col rounded-md shadow-md"
|
||||||
|
use:animate=In::default()
|
||||||
|
.source("opacity-0 -translate-y-2 -scale-10")
|
||||||
|
.active("transition-all duration-150")
|
||||||
|
.target("opacity-100")>
|
||||||
|
<h3 class="font-bold text-lg">{title}</h3>
|
||||||
|
<p>{message}</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
use leptos::prelude::*;
|
||||||
|
use crate::components::toasts::toast::Toast;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct Toast {
|
||||||
|
id: String,
|
||||||
|
message: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Toast {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Toast {
|
||||||
|
id: "".to_owned(),
|
||||||
|
message: "".to_owned(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn msg(mut self, msg: impl Into<String>) -> Self {
|
||||||
|
self.message = msg.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn id(mut self, id: impl Into<String>) -> Self {
|
||||||
|
self.id = id.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct ToastContext {
|
||||||
|
messages: RwSignal<Vec<Toast>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToastContext {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
messages: RwSignal::new(vec![]),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn toast(&mut self, toast: Toast) {
|
||||||
|
self.messages.update(|list| list.push(toast));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// # Toast List Component
|
||||||
|
/// Displays a list of toasts. They must be queued using the [`ToastContext`].
|
||||||
|
#[component]
|
||||||
|
pub fn ToastList(
|
||||||
|
children: Children,
|
||||||
|
) -> impl IntoView {
|
||||||
|
// This context should be used wherever the application might need to use a toast.
|
||||||
|
// That specific component should also be wrapped in a ToastList component, otherwise
|
||||||
|
// this context won't exist.
|
||||||
|
let context = use_context::<ToastContext>()
|
||||||
|
.unwrap_or_else(provide_toast_context);
|
||||||
|
|
||||||
|
view! {
|
||||||
|
{children()}
|
||||||
|
<div class="fixed top-1 left-1/2 right-1/2 -translate-x-1/2 min-w-lg">
|
||||||
|
<For
|
||||||
|
each=move || context.messages.get()
|
||||||
|
key=|toast| toast.id.clone()
|
||||||
|
let(Toast { id, message })
|
||||||
|
>
|
||||||
|
<Toast
|
||||||
|
message=message
|
||||||
|
title="Testing Toast"
|
||||||
|
on_close=move || {
|
||||||
|
context.messages.update(|list|
|
||||||
|
list.retain(|v| v.id != id)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</For>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn provide_toast_context() -> ToastContext {
|
||||||
|
let context = ToastContext::new();
|
||||||
|
provide_context(context);
|
||||||
|
context
|
||||||
|
}
|
||||||
Reference in new issue
Block a user