mirror of
https://github.com/adoyle0/thaw.git
synced 2025-01-23 06:19:22 -05:00
Feat/collapse (#73)
* feat: add collapse component * feat: collapse adds accordion prop * fix(workflow): ci stable-cargo-leptos
This commit is contained in:
parent
1f889591ed
commit
adcc0b6a54
9 changed files with 179 additions and 0 deletions
1
.github/workflows/ci.yml
vendored
1
.github/workflows/ci.yml
vendored
|
@ -65,4 +65,5 @@ jobs:
|
|||
- name: Build
|
||||
run: |
|
||||
cd ./examples/ssr_axum
|
||||
cargo install --locked cargo-leptos
|
||||
cargo leptos build --release
|
||||
|
|
|
@ -53,6 +53,7 @@ fn TheRouter(is_routing: RwSignal<bool>) -> impl IntoView {
|
|||
<Route path="/calendar" view=CalendarMdPage/>
|
||||
<Route path="/card" view=CardMdPage/>
|
||||
<Route path="/checkbox" view=CheckboxMdPage/>
|
||||
<Route path="/collapse" view=CollapseMdPage/>
|
||||
<Route path="/color-picker" view=ColorPickerMdPage/>
|
||||
<Route path="/date-picker" view=DatePickerMdPage/>
|
||||
<Route path="/divider" view=DividerMdPage/>
|
||||
|
|
|
@ -113,6 +113,10 @@ pub(crate) fn gen_menu_data() -> Vec<MenuGroupOption> {
|
|||
value: "card".into(),
|
||||
label: "Card".into(),
|
||||
},
|
||||
MenuItemOption {
|
||||
value: "collapse".into(),
|
||||
label: "Collapse".into(),
|
||||
},
|
||||
MenuItemOption {
|
||||
value: "divider".into(),
|
||||
label: "Divider".into(),
|
||||
|
|
53
demo_markdown/docs/collapse/mod.md
Normal file
53
demo_markdown/docs/collapse/mod.md
Normal file
|
@ -0,0 +1,53 @@
|
|||
# Collapse
|
||||
|
||||
```rust demo
|
||||
use std::collections::HashSet;
|
||||
|
||||
let value = create_rw_signal(HashSet::from(["thaw".to_string()]));
|
||||
|
||||
view! {
|
||||
<Collapse value>
|
||||
<CollapseItem title="Leptos" key="leptos">
|
||||
"Build fast web applications with Rust."
|
||||
</CollapseItem>
|
||||
<CollapseItem title="Thaw" key="thaw">
|
||||
"An easy to use leptos component library"
|
||||
</CollapseItem>
|
||||
</Collapse>
|
||||
}
|
||||
```
|
||||
|
||||
### Accordion
|
||||
|
||||
Like an accordion.
|
||||
|
||||
```rust demo
|
||||
view! {
|
||||
<Collapse accordion=true>
|
||||
<CollapseItem title="Leptos" key="leptos">
|
||||
"Build fast web applications with Rust."
|
||||
</CollapseItem>
|
||||
<CollapseItem title="Thaw" key="thaw">
|
||||
"An easy to use leptos component library"
|
||||
</CollapseItem>
|
||||
</Collapse>
|
||||
}
|
||||
```
|
||||
|
||||
### Collapse Props
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| --------- | --------------------------- | -------------------- | ------------------------------------------- |
|
||||
| class | `MaybeSignal<String>` | `Default::default()` | Addtional classes for the collapse element. |
|
||||
| value | `RwSignal<HashSet<String>>` | `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<String>` | `Default::default()` | Addtional classes for the collapse item element. |
|
||||
| title | `MaybeSignal<String>` | | The title of the CollapseItem. |
|
||||
| key | `MaybeSignal<String>` | | The indentifier of CollapseItem. |
|
||||
| chilren | `Children` | | CollapseItem's content. |
|
|
@ -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"),
|
||||
|
|
22
thaw/src/collapse/collapse.css
Normal file
22
thaw/src/collapse/collapse.css
Normal file
|
@ -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;
|
||||
}
|
62
thaw/src/collapse/collapse_item.rs
Normal file
62
thaw/src/collapse/collapse_item.rs
Normal file
|
@ -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<String>,
|
||||
#[prop(into)] title: MaybeSignal<String>,
|
||||
#[prop(into)] key: MaybeSignal<String>,
|
||||
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! {
|
||||
<div class=class_list![
|
||||
"thaw-collapse-item", ("thaw-collapse-item--active", move || is_show_content.get()),
|
||||
move || class.get()
|
||||
]>
|
||||
<div
|
||||
class="thaw-collapse-item__header"
|
||||
on:click=on_click
|
||||
>
|
||||
<Icon icon=Icon::from(AiIcon::AiRightOutlined) class="thaw-collapse-item-arrow"/>
|
||||
{move || title.get()}
|
||||
</div>
|
||||
<div
|
||||
class="thaw-collapse-item__content"
|
||||
style=move || (!is_show_content.get()).then_some("display: none;")
|
||||
>
|
||||
{children()}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
33
thaw/src/collapse/mod.rs
Normal file
33
thaw/src/collapse/mod.rs
Normal file
|
@ -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<String>,
|
||||
#[prop(optional, into)] value: RwSignal<HashSet<String>>,
|
||||
#[prop(optional)] accordion: bool,
|
||||
children: Children,
|
||||
) -> impl IntoView {
|
||||
mount_style("collapser", include_str!("./collapse.css"));
|
||||
|
||||
view! {
|
||||
<Provider value=CollapseInjection{ value, accordion }>
|
||||
<div class=class_list!["thaw-collapse", move || class.get()]>{children()}</div>
|
||||
</Provider>
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct CollapseInjection {
|
||||
pub value: RwSignal<HashSet<String>>,
|
||||
pub accordion: bool,
|
||||
}
|
||||
|
||||
pub(crate) fn use_collapse() -> CollapseInjection {
|
||||
expect_context()
|
||||
}
|
|
@ -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::*;
|
||||
|
|
Loading…
Add table
Reference in a new issue