From adcc0b6a54e3e80092ebc917593b0a8a28693c99 Mon Sep 17 00:00:00 2001 From: luoxiaozero <48741584+luoxiaozero@users.noreply.github.com> Date: Tue, 9 Jan 2024 14:32:13 +0800 Subject: [PATCH] Feat/collapse (#73) * feat: add collapse component * feat: collapse adds accordion prop * fix(workflow): ci stable-cargo-leptos --- .github/workflows/ci.yml | 1 + demo/src/app.rs | 1 + demo/src/pages/components.rs | 4 ++ demo_markdown/docs/collapse/mod.md | 53 +++++++++++++++++++++++++ demo_markdown/src/lib.rs | 1 + thaw/src/collapse/collapse.css | 22 +++++++++++ thaw/src/collapse/collapse_item.rs | 62 ++++++++++++++++++++++++++++++ thaw/src/collapse/mod.rs | 33 ++++++++++++++++ thaw/src/lib.rs | 2 + 9 files changed, 179 insertions(+) create mode 100644 demo_markdown/docs/collapse/mod.md create mode 100644 thaw/src/collapse/collapse.css create mode 100644 thaw/src/collapse/collapse_item.rs create mode 100644 thaw/src/collapse/mod.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4914ac9..7851798 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,4 +65,5 @@ jobs: - name: Build run: | cd ./examples/ssr_axum + cargo install --locked cargo-leptos cargo leptos build --release diff --git a/demo/src/app.rs b/demo/src/app.rs index 54598b1..c1bf021 100644 --- a/demo/src/app.rs +++ b/demo/src/app.rs @@ -53,6 +53,7 @@ fn TheRouter(is_routing: RwSignal) -> impl IntoView { + diff --git a/demo/src/pages/components.rs b/demo/src/pages/components.rs index 5215885..fbf55f2 100644 --- a/demo/src/pages/components.rs +++ b/demo/src/pages/components.rs @@ -113,6 +113,10 @@ pub(crate) fn gen_menu_data() -> Vec { value: "card".into(), label: "Card".into(), }, + MenuItemOption { + value: "collapse".into(), + label: "Collapse".into(), + }, MenuItemOption { value: "divider".into(), label: "Divider".into(), diff --git a/demo_markdown/docs/collapse/mod.md b/demo_markdown/docs/collapse/mod.md new file mode 100644 index 0000000..b560dff --- /dev/null +++ b/demo_markdown/docs/collapse/mod.md @@ -0,0 +1,53 @@ +# Collapse + +```rust demo +use std::collections::HashSet; + +let value = create_rw_signal(HashSet::from(["thaw".to_string()])); + +view! { + + + "Build fast web applications with Rust." + + + "An easy to use leptos component library" + + +} +``` + +### Accordion + +Like an accordion. + +```rust demo +view! { + + + "Build fast web applications with Rust." + + + "An easy to use leptos component library" + + +} +``` + +### Collapse Props + +| Name | Type | Default | Description | +| --------- | --------------------------- | -------------------- | ------------------------------------------- | +| class | `MaybeSignal` | `Default::default()` | Addtional classes for the collapse element. | +| value | `RwSignal>` | `Default::default()` | Currently active panel. | +| accordion | `bool` | `false` | Only allow one panel open at a time. | +| children | `Children` | | Collapse's content. | + +### CollapseItem Props + +| Name | Type | Default | Description | +| ------- | --------------------- | -------------------- | ------------------------------------------------ | +| class | `MaybeSignal` | `Default::default()` | Addtional classes for the collapse item element. | +| title | `MaybeSignal` | | The title of the CollapseItem. | +| key | `MaybeSignal` | | The indentifier of CollapseItem. | +| chilren | `Children` | | CollapseItem's content. | diff --git a/demo_markdown/src/lib.rs b/demo_markdown/src/lib.rs index 04c74b2..83f3f8b 100644 --- a/demo_markdown/src/lib.rs +++ b/demo_markdown/src/lib.rs @@ -41,6 +41,7 @@ pub fn include_md(_token_stream: proc_macro::TokenStream) -> proc_macro::TokenSt ("CalendarMdPage", include_str!("../docs/calendar/mod.md")), ("CardMdPage", include_str!("../docs/card/mod.md")), ("CheckboxMdPage", include_str!("../docs/checkbox/mod.md")), + ("CollapseMdPage", include_str!("../docs/collapse/mod.md")), ( "ColorPickerMdPage", include_str!("../docs/color_picker/mod.md"), diff --git a/thaw/src/collapse/collapse.css b/thaw/src/collapse/collapse.css new file mode 100644 index 0000000..3bcb967 --- /dev/null +++ b/thaw/src/collapse/collapse.css @@ -0,0 +1,22 @@ +.thaw-collapse .thaw-collapse-item:not(:first-child) { + margin-top: 16px; +} + +.thaw-collapse-item__header { + display: flex; + align-items: center; + cursor: pointer; +} + +.thaw-collapse-item-arrow { + margin-right: 4px; + transition: transform 0.15s cubic-bezier(0.4, 0, 0.2, 1); +} + +.thaw-collapse-item--active .thaw-collapse-item-arrow { + transform: rotate(90deg); +} + +.thaw-collapse-item__content { + padding-top: 16px; +} diff --git a/thaw/src/collapse/collapse_item.rs b/thaw/src/collapse/collapse_item.rs new file mode 100644 index 0000000..b1ff2a2 --- /dev/null +++ b/thaw/src/collapse/collapse_item.rs @@ -0,0 +1,62 @@ +use super::use_collapse; +use crate::{ + utils::{class_list::class_list, StoredMaybeSignal}, + Icon, +}; +use icondata::AiIcon; +use leptos::*; + +#[component] +pub fn CollapseItem( + #[prop(optional, into)] class: MaybeSignal, + #[prop(into)] title: MaybeSignal, + #[prop(into)] key: MaybeSignal, + children: Children, +) -> impl IntoView { + let collapse = use_collapse(); + let key: StoredMaybeSignal<_> = key.into(); + let is_show_content = create_memo(move |_| { + collapse.value.with(|keys| { + if key.with(|key| keys.contains(key)) { + true + } else { + false + } + }) + }); + + let on_click = move |_| { + collapse.value.update(|keys| { + if collapse.accordion { + keys.clear(); + } + let key = key.get_untracked(); + if is_show_content.get_untracked() { + keys.remove(&key); + } else { + keys.insert(key); + } + }); + }; + + view! { +
+
+ + {move || title.get()} +
+
+ {children()} +
+
+ } +} diff --git a/thaw/src/collapse/mod.rs b/thaw/src/collapse/mod.rs new file mode 100644 index 0000000..c883955 --- /dev/null +++ b/thaw/src/collapse/mod.rs @@ -0,0 +1,33 @@ +mod collapse_item; + +pub use collapse_item::CollapseItem; + +use crate::utils::{class_list::class_list, mount_style}; +use leptos::*; +use std::collections::HashSet; + +#[component] +pub fn Collapse( + #[prop(optional, into)] class: MaybeSignal, + #[prop(optional, into)] value: RwSignal>, + #[prop(optional)] accordion: bool, + children: Children, +) -> impl IntoView { + mount_style("collapser", include_str!("./collapse.css")); + + view! { + +
{children()}
+
+ } +} + +#[derive(Clone)] +pub(crate) struct CollapseInjection { + pub value: RwSignal>, + pub accordion: bool, +} + +pub(crate) fn use_collapse() -> CollapseInjection { + expect_context() +} diff --git a/thaw/src/lib.rs b/thaw/src/lib.rs index 09d938e..f2023ef 100644 --- a/thaw/src/lib.rs +++ b/thaw/src/lib.rs @@ -8,6 +8,7 @@ mod calendar; mod card; mod checkbox; mod code; +mod collapse; mod color_picker; mod components; mod date_picker; @@ -54,6 +55,7 @@ pub use card::*; pub use checkbox::*; pub use chrono; pub use code::*; +pub use collapse::*; pub use color_picker::*; pub use date_picker::*; pub use divider::*;