feat: grid component

This commit is contained in:
luoxiao 2023-10-12 23:25:10 +08:00
parent 0b18256b85
commit c2712cab15
10 changed files with 158 additions and 28 deletions

View file

@ -25,6 +25,7 @@ pub fn App() -> impl IntoView {
<Route path="/table" view=TablePage/> <Route path="/table" view=TablePage/>
<Route path="/color-picker" view=ColorPickerPage/> <Route path="/color-picker" view=ColorPickerPage/>
<Route path="/alert" view=AlertPage/> <Route path="/alert" view=AlertPage/>
<Route path="/grid" view=GridPage/>
</Route> </Route>
<Route path="/mobile/tabbar" view=TabbarDemoPage/> <Route path="/mobile/tabbar" view=TabbarDemoPage/>
<Route path="/mobile/nav-bar" view=NavBarDemoPage/> <Route path="/mobile/nav-bar" view=NavBarDemoPage/>

View file

@ -10,9 +10,15 @@ pub fn AlertPage() -> impl IntoView {
<h1>"Alert"</h1> <h1>"Alert"</h1>
<Demo> <Demo>
<Space vertical=true> <Space vertical=true>
<Alert variant=AlertVariant::SUCCESS title="title">"success"</Alert> <Alert variant=AlertVariant::SUCCESS title="title">
<Alert variant=AlertVariant::WARNING title="title">"warning"</Alert> "success"
<Alert variant=AlertVariant::ERROR title="title">"error"</Alert> </Alert>
<Alert variant=AlertVariant::WARNING title="title">
"warning"
</Alert>
<Alert variant=AlertVariant::ERROR title="title">
"error"
</Alert>
</Space> </Space>
<DemoCode <DemoCode
slot slot

View file

@ -25,6 +25,7 @@ pub fn ColorPickerPage() -> impl IntoView {
"rust" "rust"
) )
> >
"" ""
</DemoCode> </DemoCode>
</Demo> </Demo>

View file

@ -44,6 +44,7 @@ pub fn ComponentsPage() -> impl IntoView {
<MenuItem key="table" label="Table"/> <MenuItem key="table" label="Table"/>
<MenuItem key="color-picker" label="Color Picker"/> <MenuItem key="color-picker" label="Color Picker"/>
<MenuItem key="alert" label="Alert"/> <MenuItem key="alert" label="Alert"/>
<MenuItem key="grid" label="Grid"/>
</MenuGroup> </MenuGroup>
<MenuGroup label="Mobile Components"> <MenuGroup label="Mobile Components">
<MenuItem key="tabbar" label="Tabbar"/> <MenuItem key="tabbar" label="Tabbar"/>

125
demo/src/pages/grid/mod.rs Normal file
View file

@ -0,0 +1,125 @@
use crate::components::{Demo, DemoCode};
use leptos::*;
use melt_ui::*;
use prisms::highlight_str;
#[component]
pub fn GridPage() -> impl IntoView {
mount_style(
"grid-demo",
r#".melt-grid-item {
height: 130px;
color: white;
text-align: center;
line-height: 130px;
}
.melt-grid-item:nth-child(odd) {
background-color: #3d8ae5dd;
}
.melt-grid-item:nth-child(even) {
background-color: #3d8ae5aa;
}"#,
);
view! {
<div style="width: 896px; margin: 0 auto;">
<h1>"Grid"</h1>
<Demo>
<Space vertical=true>
<Grid>
<GridItem>"123"</GridItem>
<GridItem>"456"</GridItem>
<GridItem>"789"</GridItem>
</Grid>
<Grid cols=2>
<GridItem>"123"</GridItem>
<GridItem>"456"</GridItem>
<GridItem>"789"</GridItem>
</Grid>
</Space>
<DemoCode
slot
html=highlight_str!(
r#"
<Grid>
<GridItem>"123"</GridItem>
<GridItem>"456"</GridItem>
<GridItem>"789"</GridItem>
</Grid>
<Grid :cols=2>
<GridItem>"123"</GridItem>
<GridItem>"456"</GridItem>
<GridItem>"789"</GridItem>
</Grid>
"#,
"rust"
)
>
""
</DemoCode>
</Demo>
<h3>"gap"</h3>
<Demo>
<Grid cols=3 x_gap=8 y_gap=8>
<GridItem>"123"</GridItem>
<GridItem>"321"</GridItem>
<GridItem>"123"</GridItem>
<GridItem>"456"</GridItem>
<GridItem>"7"</GridItem>
<GridItem>"123"</GridItem>
<GridItem>"123"</GridItem>
<GridItem span=2>"1234"</GridItem>
<GridItem>"567"</GridItem>
<GridItem>"567"</GridItem>
</Grid>
<DemoCode
slot
html=highlight_str!(
r#"
<Grid cols=3 x_gap=8 y_gap=8>
<GridItem>"123"</GridItem>
<GridItem>"321"</GridItem>
<GridItem>"123"</GridItem>
<GridItem>"456"</GridItem>
<GridItem>"7"</GridItem>
<GridItem>"123"</GridItem>
<GridItem>"123"</GridItem>
<GridItem span=2>"1234"</GridItem>
<GridItem >"567"</GridItem>
<GridItem >"567"</GridItem>
</Grid>
"#,
"rust"
)
>
""
</DemoCode>
</Demo>
<h3>"gap"</h3>
<Demo>
<Grid cols=4>
<GridItem offset=2>"123"</GridItem>
<GridItem>"456"</GridItem>
</Grid>
<DemoCode
slot
html=highlight_str!(
r#"
<Grid cols=4>
<GridItem offset=2>"123"</GridItem>
<GridItem>"456"</GridItem>
</Grid>
"#,
"rust"
)
>
""
</DemoCode>
</Demo>
</div>
}
}

View file

@ -3,6 +3,7 @@ mod button;
mod checkbox; mod checkbox;
mod color_picker; mod color_picker;
mod components; mod components;
mod grid;
mod home; mod home;
mod image; mod image;
mod input; mod input;
@ -23,6 +24,7 @@ pub use button::*;
pub use checkbox::*; pub use checkbox::*;
pub use color_picker::*; pub use color_picker::*;
pub use components::*; pub use components::*;
pub use grid::*;
pub use home::*; pub use home::*;
pub use image::*; pub use image::*;
pub use input::*; pub use input::*;

View file

@ -82,23 +82,16 @@ pub fn Alert(
<div class="melt-alert" style=move || css_vars.get()> <div class="melt-alert" style=move || css_vars.get()>
<Icon icon class="melt-alert__icon"/> <Icon icon class="melt-alert__icon"/>
<div> <div>
{
move || { {move || {
let title = title.get(); let title = title.get();
if title.is_empty() { if title.is_empty() {
None None
} else { } else {
view! { view! { <div class="melt-alert__header">{title}</div> }.into()
<div class="melt-alert__header">
{title}
</div>
}.into()
}
} }
} }}
<div class="melt-alert__content"> <div class="melt-alert__content">{children()}</div>
{ children() }
</div>
</div> </div>
</div> </div>
} }

View file

@ -168,8 +168,9 @@ fn ColorPanel(hue: ReadSignal<u16>, sv: RwSignal<(f64, f64)>) -> impl IntoView {
class="melt-color-picker-popover__handle" class="melt-color-picker-popover__handle"
style=move || { style=move || {
format!( format!(
"left: calc({}% - 6px); bottom: calc({}% - 6px)", sv.get().0 * 100.0, sv "left: calc({}% - 6px); bottom: calc({}% - 6px)",
.get().1 * 100.0, sv.get().0 * 100.0,
sv.get().1 * 100.0,
) )
} }
> >

View file

@ -2,7 +2,7 @@ use super::use_grid;
use leptos::*; use leptos::*;
#[component] #[component]
fn GridItem( pub fn GridItem(
#[prop(default = MaybeSignal::Static(1u16), into)] span: MaybeSignal<u16>, #[prop(default = MaybeSignal::Static(1u16), into)] span: MaybeSignal<u16>,
#[prop(optional, into)] offset: MaybeSignal<i32>, #[prop(optional, into)] offset: MaybeSignal<i32>,
children: Children, children: Children,
@ -10,14 +10,14 @@ fn GridItem(
let grid = use_grid(); let grid = use_grid();
let style = create_memo(move |_| { let style = create_memo(move |_| {
let mut style = String::from("display: grid;"); let mut style = String::new();
let offset = offset.get(); let offset = offset.get();
let span = i32::from(span.get()); let span = i32::from(span.get());
let x_gap = grid.x_gap.get(); let x_gap = grid.x_gap.get();
if offset > 0 { if offset > 0 {
style.push_str(&format!( style.push_str(&format!(
"margin-left: calc((100% - {}px) / {} * {} + {}px)", "margin-left: calc((100% - {}px) / {} * {} + {}px);",
(span + offset - 1) * x_gap, (span + offset - 1) * x_gap,
span + offset, span + offset,
offset, offset,
@ -25,7 +25,7 @@ fn GridItem(
)); ));
} }
style.push_str(&format!( style.push_str(&format!(
"grid-column: span {} / span {}", "grid-column: span {} / span {};",
span + offset, span + offset,
span + offset span + offset
)); ));

View file

@ -4,13 +4,13 @@ pub use grid_item::*;
use leptos::*; use leptos::*;
#[component] #[component]
fn Grid( pub fn Grid(
#[prop(default = MaybeSignal::Static(1u16), into)] cols: MaybeSignal<u16>, #[prop(default = MaybeSignal::Static(1u16), into)] cols: MaybeSignal<u16>,
#[prop(optional, into)] x_gap: MaybeSignal<i32>, #[prop(optional, into)] x_gap: MaybeSignal<i32>,
#[prop(optional, into)] y_gap: MaybeSignal<i32>, #[prop(optional, into)] y_gap: MaybeSignal<i32>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
let grid_injection_key = create_rw_signal(GridInjectionKey::new(x_gap)); let grid_injection_key = GridInjectionKey::new(x_gap);
provide_context(grid_injection_key); provide_context(grid_injection_key);
let style = create_memo(move |_| { let style = create_memo(move |_| {
@ -19,7 +19,7 @@ fn Grid(
"grid-template-columns: repeat({}, minmax(0px, 1fr));", "grid-template-columns: repeat({}, minmax(0px, 1fr));",
cols.get() cols.get()
)); ));
style.push_str(&format!("grid-gap: {}px ${}px;", y_gap.get(), x_gap.get())); style.push_str(&format!("grid-gap: {}px {}px;", y_gap.get(), x_gap.get()));
style style
}); });