mirror of
https://github.com/adoyle0/thaw.git
synced 2025-01-22 22:09:22 -05:00
✨ feat: use if component
This commit is contained in:
parent
4e0b338a65
commit
933a9c7316
13 changed files with 105 additions and 111 deletions
|
@ -43,6 +43,9 @@ pub fn App(cx: Scope) -> impl IntoView {
|
|||
<Route path="/button" view=move |cx| view! {cx,
|
||||
<ButtonPage />
|
||||
} />
|
||||
<Route path="/checkbox" view=move |cx| view! {cx,
|
||||
<CheckboxPage />
|
||||
} />
|
||||
</Route>
|
||||
</Routes>
|
||||
<Routes base="/mobile".to_string()>
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
use leptos::*;
|
||||
use melt_ui::*;
|
||||
|
||||
#[component]
|
||||
pub fn DemoCheckout(cx: Scope) -> impl IntoView {
|
||||
let (checked, set_checked) = create_signal(cx, false);
|
||||
view! {cx,
|
||||
<div>
|
||||
<Checkbox>
|
||||
"A"
|
||||
</Checkbox>
|
||||
<Checkbox checked=true>
|
||||
"B"
|
||||
</Checkbox>
|
||||
<Checkbox checked=checked on_checked=set_checked>
|
||||
"Click"
|
||||
</Checkbox>
|
||||
</div>
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
use leptos::*;
|
||||
use melt_ui::*;
|
||||
|
||||
#[component]
|
||||
pub fn DemoSlider(cx: Scope) -> impl IntoView {
|
||||
let (value, set_value) = create_signal(cx, 0.0);
|
||||
let on_value = SignalSetter::map(cx, move |value| {
|
||||
set_value.set(value);
|
||||
});
|
||||
view! { cx,
|
||||
<Slider value=value on_value=on_value/>
|
||||
}
|
||||
}
|
|
@ -1,6 +1,4 @@
|
|||
mod app;
|
||||
mod demo_checkbox;
|
||||
mod demo_slider;
|
||||
mod pages;
|
||||
|
||||
use app::*;
|
||||
|
|
14
examples/basic/src/pages/checkbox/mod.rs
Normal file
14
examples/basic/src/pages/checkbox/mod.rs
Normal file
|
@ -0,0 +1,14 @@
|
|||
use leptos::*;
|
||||
use melt_ui::*;
|
||||
|
||||
#[component]
|
||||
pub fn CheckboxPage(cx: Scope) -> impl IntoView {
|
||||
let checked = create_rw_signal(cx, false);
|
||||
view! {cx,
|
||||
<div>
|
||||
<Checkbox checked>
|
||||
"Click"
|
||||
</Checkbox>
|
||||
</div>
|
||||
}
|
||||
}
|
|
@ -41,6 +41,7 @@ pub fn ComponentsPage(cx: Scope) -> impl IntoView {
|
|||
<MenuItem key="modal" label="madal" />
|
||||
<MenuItem key="nav-bar" label="nav-bar" />
|
||||
<MenuItem key="button" label="button" />
|
||||
<MenuItem key="checkbox" label="checkbox" />
|
||||
</Menu>
|
||||
</aside>
|
||||
<main>
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
use crate::demo_checkbox::*;
|
||||
use crate::demo_slider::*;
|
||||
use leptos::*;
|
||||
use leptos_router::use_navigate;
|
||||
use melt_ui::*;
|
||||
|
@ -38,9 +36,5 @@ pub fn Home(cx: Scope) -> impl IntoView {
|
|||
|
||||
<Progress percentage=count/>
|
||||
</Space>
|
||||
<hr />
|
||||
<DemoCheckout />
|
||||
<hr />
|
||||
<DemoSlider />
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
mod button;
|
||||
mod checkbox;
|
||||
mod components;
|
||||
mod home;
|
||||
mod image;
|
||||
|
@ -11,6 +12,7 @@ mod slider;
|
|||
mod tabbar;
|
||||
|
||||
pub use button::*;
|
||||
pub use checkbox::*;
|
||||
pub use components::*;
|
||||
pub use home::*;
|
||||
pub use image::*;
|
||||
|
|
|
@ -1,51 +1,75 @@
|
|||
use std::rc::Rc;
|
||||
|
||||
use crate::{components::*, utils::mount_style::mount_style};
|
||||
use leptos::*;
|
||||
use stylers::style_sheet_str;
|
||||
|
||||
#[slot]
|
||||
pub struct CardHeader {
|
||||
children: ChildrenFn,
|
||||
}
|
||||
|
||||
#[slot]
|
||||
pub struct CardHeaderExtra {
|
||||
children: ChildrenFn,
|
||||
}
|
||||
|
||||
#[slot]
|
||||
pub struct CardFooter {
|
||||
#[prop(default = leptos::MaybeSignal::Static(true), into)]
|
||||
if_: MaybeSignal<bool>,
|
||||
children: ChildrenFn,
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn Card(
|
||||
cx: Scope,
|
||||
#[prop(optional)] title: MaybeSignal<String>,
|
||||
#[prop(default = None)] header: Option<Children>,
|
||||
#[prop(default = None)] header_extra: Option<Children>,
|
||||
#[prop(optional, into)] title: MaybeSignal<&'static str>,
|
||||
#[prop(optional)] card_header: Option<CardHeader>,
|
||||
#[prop(optional)] card_header_extra: Option<CardHeaderExtra>,
|
||||
children: Children,
|
||||
#[prop(default = None)] footer: Option<Children>,
|
||||
#[prop(optional)] card_footer: Option<CardFooter>,
|
||||
) -> impl IntoView {
|
||||
let class_name = mount_style("card", || style_sheet_str!("./src/card/card.css"));
|
||||
|
||||
let is_header = card_header.is_some();
|
||||
let header = card_header.map_or(None, |v| Some(Rc::new(v)));
|
||||
let header_extra = card_header_extra.map_or(None, |v| Some(Rc::new(v)));
|
||||
// let footer = card_footer.map_or(None, |v| Some(Rc::new(v)));
|
||||
|
||||
view! {
|
||||
cx, class=class_name,
|
||||
<div class="melt-card">
|
||||
{
|
||||
if header.is_some() || title.get().is_empty() {
|
||||
view! {
|
||||
cx, class=class_name,
|
||||
<If cond=MaybeSignal::derive(cx, move || is_header || title.get().is_empty()) >
|
||||
<Then slot>
|
||||
<div class="melt-card__header">
|
||||
<div class="melt-card__header-content">
|
||||
<OptionComp value=header bind:header>
|
||||
<OptionComp value=header.clone() bind:header>
|
||||
<Fallback slot>
|
||||
{ title.get() }
|
||||
</Fallback>
|
||||
{ header(cx) }
|
||||
{ (header.children)(cx) }
|
||||
</OptionComp>
|
||||
</div>
|
||||
<OptionComp value=header_extra bind:header_extra>
|
||||
<OptionComp value=header_extra.clone() bind:header_extra>
|
||||
<div class="melt-card__header-extra">
|
||||
{ header_extra(cx) }
|
||||
{ (header_extra.children)(cx) }
|
||||
</div>
|
||||
</OptionComp>
|
||||
</div>
|
||||
}.into()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
</Then>
|
||||
</If>
|
||||
<div class="melt-card__content">
|
||||
{ children(cx) }
|
||||
</div>
|
||||
<OptionComp value=footer bind:footer>
|
||||
<div class="melt-card__footer">
|
||||
{ footer(cx) }
|
||||
</div>
|
||||
<OptionComp value=card_footer bind:footer>
|
||||
<If cond=footer.if_ >
|
||||
<Then slot>
|
||||
<div class="melt-card__footer">
|
||||
{ (footer.children)(cx) }
|
||||
</div>
|
||||
</Then>
|
||||
</If>
|
||||
</OptionComp>
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
use crate::{theme::use_theme, utils::mount_style::mount_style, Theme};
|
||||
use crate::{theme::use_theme, utils::mount_style::mount_style, Theme, components::*};
|
||||
use leptos::*;
|
||||
use stylers::style_sheet_str;
|
||||
use leptos_icons::*;
|
||||
use stylers::style_sheet_str;
|
||||
|
||||
#[component]
|
||||
pub fn Checkbox(
|
||||
cx: Scope,
|
||||
#[prop(optional, into)] checked: MaybeSignal<bool>,
|
||||
#[prop(optional, into)] on_checked: Option<SignalSetter<bool>>,
|
||||
#[prop(into)] checked: RwSignal<bool>,
|
||||
children: Children,
|
||||
) -> impl IntoView {
|
||||
let theme = use_theme(cx, Theme::light);
|
||||
|
@ -22,29 +21,20 @@ pub fn Checkbox(
|
|||
css_vars.push_str(&format!("--background-color-checked: {bg_color};"));
|
||||
css_vars
|
||||
});
|
||||
let on_click = move |_| {
|
||||
if let Some(on_checked) = on_checked {
|
||||
on_checked.set(!checked.get());
|
||||
}
|
||||
};
|
||||
|
||||
view! {cx, class=class_name,
|
||||
<div class:melt-checkbox=true class=("melt-checkbox--checked", move || checked.get()) style=move || css_vars.get() on:click=on_click>
|
||||
<div class:melt-checkbox=true class=("melt-checkbox--checked", move || checked.get()) style=move || css_vars.get()
|
||||
on:click=move |_| checked.set(!checked.get_untracked())>
|
||||
<input class="melt-checkbox__input" type="checkbox" />
|
||||
<div class="melt-checkbox__dot">
|
||||
{
|
||||
move || {
|
||||
if checked.get() {
|
||||
view! {cx,
|
||||
<Icon icon=AiIcon::AiCheckOutlined style="color: white"/>
|
||||
}.into()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
<If cond=checked>
|
||||
<Then slot>
|
||||
<Icon icon=AiIcon::AiCheckOutlined style="color: white"/>
|
||||
</Then>
|
||||
</If>
|
||||
</div>
|
||||
<div class="melt-checkbox__label">
|
||||
{children(cx)}
|
||||
{ children(cx) }
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ pub struct ElseIf {
|
|||
#[component]
|
||||
pub fn If(
|
||||
cx: Scope,
|
||||
cond: MaybeSignal<bool>,
|
||||
#[prop(into)] cond: MaybeSignal<bool>,
|
||||
then: Then,
|
||||
#[prop(default=vec![])] else_if: Vec<ElseIf>,
|
||||
#[prop(optional)] fallback: Option<Fallback>,
|
||||
|
|
|
@ -2,8 +2,8 @@ mod if_comp;
|
|||
mod option_comp;
|
||||
|
||||
pub use if_comp::*;
|
||||
use leptos::*;
|
||||
pub use option_comp::*;
|
||||
use leptos::*;
|
||||
|
||||
#[slot]
|
||||
pub struct Fallback {
|
||||
|
|
|
@ -1,48 +1,49 @@
|
|||
use crate::card::*;
|
||||
use crate::components::OptionComp;
|
||||
use crate::teleport::*;
|
||||
use crate::utils::mount_style::mount_style;
|
||||
use leptos::*;
|
||||
use stylers::style_sheet_str;
|
||||
use leptos_icons::*;
|
||||
|
||||
#[slot]
|
||||
pub struct ModalFooter {
|
||||
children: ChildrenFn,
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn Modal(
|
||||
cx: Scope,
|
||||
#[prop(optional, into)] title: Option<MaybeSignal<String>>,
|
||||
children: Children,
|
||||
#[prop(optional)] footer: Option<Children>,
|
||||
#[prop(into)] show: RwSignal<bool>,
|
||||
#[prop(optional, into)] title: MaybeSignal<&'static str>,
|
||||
children: Children,
|
||||
#[prop(optional)] modal_footer: Option<ModalFooter>,
|
||||
) -> impl IntoView {
|
||||
let class_name = mount_style("modal", || style_sheet_str!("./src/modal/modal.css"));
|
||||
let header = move |cx| {
|
||||
view! {
|
||||
cx, class=class_name,
|
||||
<>
|
||||
<span class="melt-model-title">
|
||||
{title}
|
||||
</span>
|
||||
</>
|
||||
}
|
||||
};
|
||||
|
||||
let header_extra = move |cx| {
|
||||
view! {
|
||||
cx,
|
||||
<>
|
||||
<span style="cursor: pointer;" on:click=move |_| show.set(false)>
|
||||
<Icon icon=AiIcon::AiCloseOutlined/>
|
||||
</span>
|
||||
</>
|
||||
}
|
||||
};
|
||||
view! {
|
||||
cx, class=class_name,
|
||||
<Teleport>
|
||||
<div class="melt-modal-container" style=move || if show.get() { "" } else { "display: none" }>
|
||||
<div class="melt-modal-mask"></div>
|
||||
<div class="melt-modal-body">
|
||||
<Card header=Some(Box::new(header)) header_extra=Some(Box::new(header_extra)) footer=footer>
|
||||
{children(cx)}
|
||||
<Card>
|
||||
<CardHeader slot>
|
||||
<span class="melt-model-title">
|
||||
{ title.get() }
|
||||
</span>
|
||||
</CardHeader>
|
||||
<CardHeaderExtra slot>
|
||||
<span style="cursor: pointer;" on:click=move |_| show.set(false)>
|
||||
<Icon icon=AiIcon::AiCloseOutlined/>
|
||||
</span>
|
||||
</CardHeaderExtra>
|
||||
{ children(cx) }
|
||||
<CardFooter slot if_=modal_footer.is_some()>
|
||||
<OptionComp value=modal_footer.as_ref() bind:footer>
|
||||
{ (footer.children)(cx) }
|
||||
</OptionComp>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Reference in a new issue