feat: Layout scrollbar

This commit is contained in:
luoxiao 2024-04-05 23:29:28 +08:00 committed by luoxiaozero
parent a1a301a765
commit 8a6e0ee787
6 changed files with 26 additions and 14 deletions

View file

@ -56,7 +56,7 @@ pub fn ComponentsPage() -> impl IntoView {
</Menu>
</LayoutSider>
<Layout style="padding: 8px 12px 28px; overflow-y: auto;">
<Layout content_style="padding: 8px 12px 28px;">
<Outlet/>
</Layout>
</Layout>

View file

@ -55,7 +55,7 @@ pub fn GuidePage() -> impl IntoView {
</Menu>
</LayoutSider>
<Layout style="padding: 8px 12px 28px; overflow-y: auto;">
<Layout content_style="padding: 8px 12px 28px;">
<Outlet/>
</Layout>
</Layout>

View file

@ -35,8 +35,10 @@ view! {
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| class | `OptionalProp<MaybeSignal<String>>` | `Default::default()` | Addtional classes for the layout element. |
| class | `OptionalProp<MaybeSignal<String>>` | `Default::default()` | Class of scrollable content node. |
| style | `OptionalProp<MaybeSignal<String>>` | `Default::default()` | Layout's style. |
| content_class | `OptionalProp<MaybeSignal<String>>` | `Default::default()` | Addtional classes for the layout element. |
| content_style | `OptionalProp<MaybeSignal<String>>` | `Default::default()` | Style of scrollable content node. |
| position | `LayoutPosition` | `LayoutPosition::Static` | static position will make it css position set to static. absolute position will make it css position set to absolute and left, right, top, bottom to 0. absolute position is very useful when you want to make content scroll in a fixed container or make the whole page's layout in a fixed position. You may need to change the style of the component to make it display as you expect. |
| has_sider | `MaybeSignal<bool>` | `false` | Whether the component has sider inside. If so it must be true. |
| children | `Children` | | Layout's content. |

View file

@ -9,3 +9,9 @@
bottom: 0;
left: 0;
}
.thaw-layout--absolute-positioned
> .thaw-scrollbar
> .thaw-scrollbar__container {
display: flex;
}

View file

@ -1,3 +1,4 @@
use crate::Scrollbar;
use leptos::*;
use thaw_utils::{class_list, mount_style, OptionalProp};
@ -5,6 +6,8 @@ use thaw_utils::{class_list, mount_style, OptionalProp};
pub fn LayoutSider(
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>,
#[prop(optional, into)] style: OptionalProp<MaybeSignal<String>>,
#[prop(optional, into)] content_class: OptionalProp<MaybeSignal<String>>,
#[prop(optional, into)] content_style: OptionalProp<MaybeSignal<String>>,
children: Children,
) -> impl IntoView {
mount_style("layout-sider", include_str!("./layout-sider.css"));
@ -13,7 +16,9 @@ pub fn LayoutSider(
class=class_list!["thaw-layout-sider", class.map(| c | move || c.get())]
style=style.map(|s| move || s.get())
>
<Scrollbar content_class content_style>
{children()}
</Scrollbar>
</div>
}
}

View file

@ -4,6 +4,7 @@ mod layout_sider;
pub use layout_header::*;
pub use layout_sider::*;
use crate::Scrollbar;
use leptos::*;
use thaw_utils::{class_list, mount_style, OptionalProp};
@ -27,21 +28,17 @@ impl LayoutPosition {
pub fn Layout(
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>,
#[prop(optional, into)] style: OptionalProp<MaybeSignal<String>>,
#[prop(optional, into)] content_class: OptionalProp<MaybeSignal<String>>,
#[prop(optional, into)] content_style: OptionalProp<MaybeSignal<String>>,
#[prop(optional)] position: LayoutPosition,
#[prop(optional, into)] has_sider: MaybeSignal<bool>,
children: Children,
) -> impl IntoView {
mount_style("layout", include_str!("./layout.css"));
let style = create_memo(move |_| {
let mut new_style = style.as_ref().map(|s| s.get()).unwrap_or_default();
let sider_style = create_memo(move |_| {
if has_sider.get() {
new_style
.push_str("display: flex; flex-wrap: nowrap; flex-direction: row; width: 100%;");
Some(new_style)
} else if style.is_some() {
Some(new_style)
Some("display: flex; flex-wrap: nowrap; flex-direction: row; width: 100%;")
} else {
None
}
@ -49,9 +46,11 @@ pub fn Layout(
view! {
<div
class=class_list![gen_class(position), class.map(| c | move || c.get())]
style=move || style.get()
style=move || style.as_ref().map(|s| s.get())
>
<Scrollbar content_class content_style=Signal::derive(move || format!("{} {}", sider_style.get().unwrap_or_default(), content_style.as_ref().map_or(String::new(), |s| s.get())))>
{children()}
</Scrollbar>
</div>
}
}