diff --git a/frontend/src/components/ui/toast.rs b/frontend/src/components/ui/toast.rs index 49860ac..d8f32b1 100644 --- a/frontend/src/components/ui/toast.rs +++ b/frontend/src/components/ui/toast.rs @@ -45,6 +45,7 @@ pub fn SonnerTrigger( index: usize, total: usize, position: SonnerPosition, + is_expanded: Signal, #[prop(optional)] on_dismiss: Option>, ) -> impl IntoView { let variant_classes = match toast.variant { @@ -64,23 +65,31 @@ pub fn SonnerTrigger( _ => "bg-primary", }; - // Sonner Stacking Logic - let inverse_index = index; - let offset = inverse_index as f64 * 12.0; - let scale = 1.0 - (inverse_index as f64 * 0.05); - let opacity = if inverse_index > 2 { 0.0 } else { 1.0 - (inverse_index as f64 * 0.15) }; - - let is_bottom = position.to_string().contains("Bottom"); - let y_direction = if is_bottom { -1.0 } else { 1.0 }; - let translate_y = offset * y_direction; + // Stacking & Expansion Logic + let style = move || { + let is_bottom = position.to_string().contains("Bottom"); + let y_direction = if is_bottom { -1.0 } else { 1.0 }; + + let (translate_y, scale, opacity) = if is_expanded.get() { + // Expanded state: Full list layout + let y = index as f64 * 70.0; // height + gap + (y * y_direction, 1.0, 1.0) + } else { + // Stacked state: Sonner look + let y = index as f64 * 10.0; + let s = 1.0 - (index as f64 * 0.05); + let o = if index > 2 { 0.0 } else { 1.0 - (index as f64 * 0.2) }; + (y * y_direction, s, o) + }; - let style = format!( - "z-index: {}; transform: translateY({}px) scale({}); opacity: {};", - total - index, - translate_y, - scale, - opacity - ); + format!( + "z-index: {}; transform: translateY({}px) scale({}); opacity: {};", + total - index, + translate_y, + scale, + opacity + ) + }; let icon = match toast.variant { ToastType::Success => Some(view! { "✓" }.into_any()), @@ -91,23 +100,11 @@ pub fn SonnerTrigger( }; view! { -
}.into_any() @@ -150,14 +150,17 @@ pub fn Toaster(#[prop(default = SonnerPosition::default())] position: SonnerPosi let container_class = match position { SonnerPosition::TopLeft => "left-6 top-6 items-start", - SonnerPosition::TopRight => ("right-6 top-6 items-end"), - SonnerPosition::TopCenter => ("left-1/2 -translate-x-1/2 top-6 items-center"), - SonnerPosition::BottomCenter => ("left-1/2 -translate-x-1/2 bottom-6 items-center"), - SonnerPosition::BottomLeft => ("left-6 bottom-6 items-start"), - SonnerPosition::BottomRight => ("right-6 bottom-6 items-end"), + SonnerPosition::TopRight => "right-6 top-6 items-end", + SonnerPosition::TopCenter => "left-1/2 -translate-x-1/2 top-6 items-center", + SonnerPosition::BottomCenter => "left-1/2 -translate-x-1/2 bottom-6 items-center", + SonnerPosition::BottomLeft => "left-6 bottom-6 items-start", + SonnerPosition::BottomRight => "right-6 bottom-6 items-end", }; view! { +
- -
+ } } /> @@ -242,4 +233,4 @@ pub fn toast_error(title: impl Into) { toast(title, ToastType::Error); } #[allow(dead_code)] pub fn toast_warning(title: impl Into) { toast(title, ToastType::Warning); } #[allow(dead_code)] -pub fn toast_info(title: impl Into) { toast(title, ToastType::Info); } +pub fn toast_info(title: impl Into) { toast(title, ToastType::Info); } \ No newline at end of file