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
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
cd ./examples/ssr_axum
|
cd ./examples/ssr_axum
|
||||||
|
cargo install --locked cargo-leptos
|
||||||
cargo leptos build --release
|
cargo leptos build --release
|
||||||
|
|
|
@ -53,6 +53,7 @@ fn TheRouter(is_routing: RwSignal<bool>) -> impl IntoView {
|
||||||
<Route path="/calendar" view=CalendarMdPage/>
|
<Route path="/calendar" view=CalendarMdPage/>
|
||||||
<Route path="/card" view=CardMdPage/>
|
<Route path="/card" view=CardMdPage/>
|
||||||
<Route path="/checkbox" view=CheckboxMdPage/>
|
<Route path="/checkbox" view=CheckboxMdPage/>
|
||||||
|
<Route path="/collapse" view=CollapseMdPage/>
|
||||||
<Route path="/color-picker" view=ColorPickerMdPage/>
|
<Route path="/color-picker" view=ColorPickerMdPage/>
|
||||||
<Route path="/date-picker" view=DatePickerMdPage/>
|
<Route path="/date-picker" view=DatePickerMdPage/>
|
||||||
<Route path="/divider" view=DividerMdPage/>
|
<Route path="/divider" view=DividerMdPage/>
|
||||||
|
|
|
@ -113,6 +113,10 @@ pub(crate) fn gen_menu_data() -> Vec<MenuGroupOption> {
|
||||||
value: "card".into(),
|
value: "card".into(),
|
||||||
label: "Card".into(),
|
label: "Card".into(),
|
||||||
},
|
},
|
||||||
|
MenuItemOption {
|
||||||
|
value: "collapse".into(),
|
||||||
|
label: "Collapse".into(),
|
||||||
|
},
|
||||||
MenuItemOption {
|
MenuItemOption {
|
||||||
value: "divider".into(),
|
value: "divider".into(),
|
||||||
label: "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")),
|
("CalendarMdPage", include_str!("../docs/calendar/mod.md")),
|
||||||
("CardMdPage", include_str!("../docs/card/mod.md")),
|
("CardMdPage", include_str!("../docs/card/mod.md")),
|
||||||
("CheckboxMdPage", include_str!("../docs/checkbox/mod.md")),
|
("CheckboxMdPage", include_str!("../docs/checkbox/mod.md")),
|
||||||
|
("CollapseMdPage", include_str!("../docs/collapse/mod.md")),
|
||||||
(
|
(
|
||||||
"ColorPickerMdPage",
|
"ColorPickerMdPage",
|
||||||
include_str!("../docs/color_picker/mod.md"),
|
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 card;
|
||||||
mod checkbox;
|
mod checkbox;
|
||||||
mod code;
|
mod code;
|
||||||
|
mod collapse;
|
||||||
mod color_picker;
|
mod color_picker;
|
||||||
mod components;
|
mod components;
|
||||||
mod date_picker;
|
mod date_picker;
|
||||||
|
@ -54,6 +55,7 @@ pub use card::*;
|
||||||
pub use checkbox::*;
|
pub use checkbox::*;
|
||||||
pub use chrono;
|
pub use chrono;
|
||||||
pub use code::*;
|
pub use code::*;
|
||||||
|
pub use collapse::*;
|
||||||
pub use color_picker::*;
|
pub use color_picker::*;
|
||||||
pub use date_picker::*;
|
pub use date_picker::*;
|
||||||
pub use divider::*;
|
pub use divider::*;
|
||||||
|
|
Loading…
Add table
Reference in a new issue