Title
Your subtitle
Title
Your subtitle
Title
Your subtitle
use leptos::prelude::*; use crate::components::extensions::js_stack::{ShowHideButton, StackCard, StackContainer, StackGrid, StackList}; #[component] pub fn DemoJsStack() -> impl IntoView { view! { <StackGrid class="min-h-[400px]"> <StackContainer> <StackList> <StackCard> <DemoContent /> </StackCard> <StackCard> <DemoContent /> </StackCard> <StackCard> <DemoContent /> </StackCard> </StackList> <ShowHideButton /> </StackContainer> </StackGrid> } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* ✨ FUNCTIONS ✨ */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ #[component] pub fn DemoContent() -> impl IntoView { view! { <IconRandom /> <div class="flex flex-col flex-1 gap-1"> <p class="text-base font-medium text-[#18181b]">"Title"</p> <p class="text-sm text-zinc-500">"Your subtitle"</p> </div> <span class="text-sm text-right text-zinc-500">"17 October"</span> } } #[component] pub fn IconRandom() -> impl IntoView { const CLASS_ICON_WRAPPER: &str = "icon size-12 bg-[#18181b] rounded-xl grid place-items-center"; view! { <div class=CLASS_ICON_WRAPPER> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" width="24" height="24" color="white" class="transition-all duration-300" > <path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z" stroke-width="2" /> <path d="M13 2v7h7" stroke-width="2" /> </svg> </div> } }
Installation
You can run either of the following commands:
# cargo install ui-cli --forceui add demo_js_stackui add js_stack
Update the imports to match your project setup.
Copy and paste the following code into your project:
components/ui/js_stack.rs
use leptos::prelude::*; use leptos_ui::{clx, transition}; use crate::components::ui::button::{Button, ButtonSize, ButtonVariant}; use crate::utilities::utils::Utils; mod components { use super::*; clx! { StackGrid, div, "grid font-sans place-items-center"} transition! { StackList, div, "list-transition flex flex-col gap-4"} transition! { StackContainer, div, "stack__container", "bg-white rounded-[24px] p-6 w-[400px] shadow-lg"} transition! { StackCard, div, "stack__item_transition", "flex items-center gap-4 p-4 bg-white border shadow-md cursor-pointer rounded-2xl border-zinc-200", } clx! { RootShow, span, "show__btn w-fit group-[.expanded]:hidden"} clx! { RootHide, span, "hide__btn display-none hidden w-fit group-[.expanded]:block"} } pub use components::*; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* ✨ FUNCTIONS ✨ */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ #[component] pub fn ShowHideButton() -> impl IntoView { const VIEW_TRANSITION_SPAN: &str = "view-transition-name: osef-1;"; const VIEW_TRANSITION_BUTTON: &str = "view-transition-name: osef-2;"; view! { <Button class="flex gap-2 mx-auto mt-2 show_hide_btn group" variant=ButtonVariant::Bordered size=ButtonSize::Mobile onclick="document.startViewTransition(() => { this.closest('.stack__container').classList.toggle('expanded'); })" style=VIEW_TRANSITION_BUTTON > <RootShow style=VIEW_TRANSITION_SPAN>"Show All"</RootShow> <RootHide style=VIEW_TRANSITION_SPAN>"Hide"</RootHide> <ChevronDownTransition /> </Button> } } #[component] fn ChevronDownTransition() -> impl IntoView { const STYLE_TRANSITION_NAME: &str = "view-transition-name: show_hide_btn-icon;"; const GROUP_CLASS: &str = "transition-transform duration-600 group-[.expanded]:rotate-180"; view! { <svg class=GROUP_CLASS width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" style=STYLE_TRANSITION_NAME > <path d="M4 6l4 4 4-4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> </svg> } }
Update the imports to match your project setup.
Usage
// Coming soon 🦀