mirror of
https://github.com/adoyle0/thaw.git
synced 2025-01-23 06:19:22 -05:00
Merge pull request #2 from luoxiaozero/feat/leptos-0.5.0-beta
Feat/leptos 0.5.0 beta
This commit is contained in:
commit
f7d8b16483
76 changed files with 286 additions and 835 deletions
|
@ -13,10 +13,10 @@ license = "MIT"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
leptos = { version = "0.4.8", features = ["csr"] }
|
||||
leptos = { version = "0.5.0-beta2", features = ["csr"] }
|
||||
stylers = { git = "https://github.com/abishekatp/stylers", rev = "4bfd2df" }
|
||||
web-sys = { version = "0.3.62", features = ["DomRect"] }
|
||||
leptos_dom = { version = "0.4.0" }
|
||||
leptos_dom = { version = "0.5.0-beta2" }
|
||||
wasm-bindgen = "0.2.85"
|
||||
icondata = { version = "0.0.7", features = [
|
||||
"AiCloseOutlined",
|
||||
|
@ -25,4 +25,4 @@ icondata = { version = "0.0.7", features = [
|
|||
] }
|
||||
|
||||
[workspace]
|
||||
members = ["examples/basic", "gh-pages"]
|
||||
members = ["gh-pages"]
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
[package]
|
||||
name = "basic"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
leptos = { version = "0.4.0", features = ["csr"] }
|
||||
melt-ui = { path = "../../" }
|
||||
icondata = { version = "0.0.7", features = [
|
||||
"AiCloseOutlined",
|
||||
"AiCheckOutlined",
|
||||
] }
|
||||
leptos_router = { version = "0.4.0", features = ["csr"] }
|
||||
regex = "1.8.2"
|
|
@ -1,13 +0,0 @@
|
|||
[build]
|
||||
target = "index.html"
|
||||
|
||||
[watch]
|
||||
watch = [
|
||||
"../../src",
|
||||
"./src"
|
||||
]
|
||||
|
||||
[serve]
|
||||
address = "127.0.0.1"
|
||||
port = 6421
|
||||
open = false
|
|
@ -1,13 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<link data-trunk rel="css" href="./src/assets/css/index.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,61 +0,0 @@
|
|||
use crate::pages::*;
|
||||
use leptos::*;
|
||||
use leptos_router::*;
|
||||
|
||||
#[component]
|
||||
pub fn App(cx: Scope) -> impl IntoView {
|
||||
view! { cx,
|
||||
<Router>
|
||||
<Routes>
|
||||
<Route path="/" view=move |cx| view! {cx,
|
||||
<Home />
|
||||
} />
|
||||
<Route path="/menu" view=move |cx| view! {cx,
|
||||
<MenuPage />
|
||||
} />
|
||||
<Route path="/slider" view=move |cx| view! {cx,
|
||||
<SliderPage />
|
||||
} />
|
||||
<Route path="/components" view=move |cx| view! {cx,
|
||||
<ComponentsPage />
|
||||
} >
|
||||
<Route path="/menu" view=move |cx| view! {cx,
|
||||
<MenuPage />
|
||||
} />
|
||||
<Route path="/slider" view=move |cx| view! {cx,
|
||||
<SliderPage />
|
||||
} />
|
||||
<Route path="/tabbar" view=move |cx| view! {cx,
|
||||
<MobilePage path="/mobile/tabbar" />
|
||||
} />
|
||||
<Route path="/nav-bar" view=move |cx| view! {cx,
|
||||
<MobilePage path="/mobile/nav-bar" />
|
||||
} />
|
||||
<Route path="/input" view=move |cx| view! {cx,
|
||||
<InputPage />
|
||||
} />
|
||||
<Route path="/image" view=move |cx| view! {cx,
|
||||
<ImagePage />
|
||||
} />
|
||||
<Route path="/modal" view=move |cx| view! {cx,
|
||||
<ModalPage />
|
||||
} />
|
||||
<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()>
|
||||
<Route path="/tabbar" view=move |cx| view! {cx,
|
||||
<TabbarPage />
|
||||
} />
|
||||
<Route path="/nav-bar" view=move |cx| view! {cx,
|
||||
<NavBarPage />
|
||||
} />
|
||||
</Routes>
|
||||
</Router>
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
||||
.components-page-box {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.components-page-box aside {
|
||||
width: 260px;
|
||||
}
|
||||
|
||||
.components-page-box main {
|
||||
flex: 1;
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
mod app;
|
||||
mod pages;
|
||||
|
||||
use app::*;
|
||||
use leptos::*;
|
||||
|
||||
fn main() {
|
||||
mount_to_body(|cx| view! { cx, <App/> })
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
use leptos::*;
|
||||
use melt_ui::*;
|
||||
|
||||
#[component]
|
||||
pub fn ButtonPage(cx: Scope) -> impl IntoView {
|
||||
view! {cx,
|
||||
<Space>
|
||||
<Button type_=ButtonType::PRIMARY>
|
||||
"PRIMARY"
|
||||
</Button>
|
||||
<Button type_=ButtonType::SOLID>
|
||||
"SOLID"
|
||||
</Button>
|
||||
<Button type_=ButtonType::TEXT>
|
||||
"TEXT"
|
||||
</Button>
|
||||
<Button type_=ButtonType::LINK>
|
||||
"LINK"
|
||||
</Button>
|
||||
<Button color=ButtonColor::PRIMARY>
|
||||
"PRIMARY Color"
|
||||
</Button>
|
||||
<Button color=ButtonColor::SUCCESS>
|
||||
"SUCCESS Color"
|
||||
</Button>
|
||||
<Button color=ButtonColor::WARNING>
|
||||
"WARNING Color"
|
||||
</Button>
|
||||
<Button color=ButtonColor::ERROR>
|
||||
"ERROR Color"
|
||||
</Button>
|
||||
<Button color=ButtonColor::ERROR icon=icondata::AiIcon::AiCloseOutlined>
|
||||
"ERROR Color Icon"
|
||||
</Button>
|
||||
<Button color=ButtonColor::ERROR icon=icondata::AiIcon::AiCloseOutlined round=true>
|
||||
</Button>
|
||||
</Space>
|
||||
<div style="padding-top: 12px">
|
||||
<Button style="background: blue;">"style blue"</Button>
|
||||
<Button style="width: 40px; height: 20px">"size"</Button>
|
||||
</div>
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
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>
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
use leptos::*;
|
||||
use leptos_router::{use_location, use_navigate, Outlet};
|
||||
use melt_ui::*;
|
||||
use regex::Regex;
|
||||
|
||||
#[component]
|
||||
pub fn ComponentsPage(cx: Scope) -> impl IntoView {
|
||||
let loaction = use_location(cx);
|
||||
let navigate = use_navigate(cx);
|
||||
let selected = create_rw_signal(cx, String::from(""));
|
||||
create_effect(cx, move |_| {
|
||||
let pathname = loaction.pathname.get();
|
||||
|
||||
let re = Regex::new(r"^/components/(.+)$").unwrap();
|
||||
let Some(caps) = re.captures(&pathname) else {
|
||||
return;
|
||||
};
|
||||
let Some(path) = caps.get(1) else {
|
||||
return;
|
||||
};
|
||||
let path = path.as_str().to_string();
|
||||
selected.set(path);
|
||||
});
|
||||
|
||||
create_effect(cx, move |value| {
|
||||
let selected = selected.get();
|
||||
if value.is_some() {
|
||||
_ = navigate(&format!("/components/{selected}"), Default::default());
|
||||
}
|
||||
selected
|
||||
});
|
||||
view! {cx,
|
||||
<div class="components-page-box">
|
||||
<aside>
|
||||
<Menu selected>
|
||||
<MenuItem key="menu" label="menu" />
|
||||
<MenuItem key="slider" label="slider" />
|
||||
<MenuItem key="tabbar" label="tabbar" />
|
||||
<MenuItem key="input" label="input" />
|
||||
<MenuItem key="image" label="image" />
|
||||
<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>
|
||||
<Outlet />
|
||||
</main>
|
||||
</div>
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
use leptos::*;
|
||||
use leptos_router::use_navigate;
|
||||
use melt_ui::*;
|
||||
|
||||
#[component]
|
||||
pub fn Home(cx: Scope) -> impl IntoView {
|
||||
let (theme, set_theme) = create_signal(cx, Theme::light());
|
||||
provide_context(cx, theme);
|
||||
let (count, set_count) = create_signal(cx, 0.0);
|
||||
let (button_type, set_button_type) = create_signal(cx, ButtonType::TEXT);
|
||||
view! { cx,
|
||||
<Button on:click=move |_| {
|
||||
let navigate = use_navigate(cx);
|
||||
_ = navigate("/components/menu", Default::default());
|
||||
}>
|
||||
"components"
|
||||
</Button>
|
||||
<hr />
|
||||
<Space>
|
||||
<Button
|
||||
on:click=move |_| set_theme.update(move |value| *value = Theme::dark())
|
||||
type_=button_type
|
||||
>
|
||||
"theme"
|
||||
</Button>
|
||||
<Button on:click=move |_| set_button_type.update(move |value| *value = ButtonType::PRIMARY)>
|
||||
"click"
|
||||
</Button>
|
||||
<Button
|
||||
on:click=move |_| set_count.update(move |value| *value += 1.0)
|
||||
type_=button_type
|
||||
>
|
||||
"click"
|
||||
</Button>
|
||||
{move || count.get()}
|
||||
|
||||
<Progress percentage=count/>
|
||||
</Space>
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
use leptos::*;
|
||||
use melt_ui::*;
|
||||
|
||||
#[component]
|
||||
pub fn ImagePage(cx: Scope) -> impl IntoView {
|
||||
view! { cx,
|
||||
<>
|
||||
<Image src="https://s3.bmp.ovh/imgs/2021/10/2c3b013418d55659.jpg" width="500px"/>
|
||||
<Image width="200px" height="200px"/>
|
||||
</>
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
use leptos::*;
|
||||
use melt_ui::*;
|
||||
|
||||
#[component]
|
||||
pub fn InputPage(cx: Scope) -> impl IntoView {
|
||||
let value = create_rw_signal(cx, String::from("o"));
|
||||
view! { cx,
|
||||
<>
|
||||
{move || value.get()}
|
||||
<Input value/>
|
||||
<Input value type_=InputType::PASSWORD />
|
||||
</>
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
use leptos::*;
|
||||
use melt_ui::*;
|
||||
|
||||
#[component]
|
||||
pub fn MenuPage(cx: Scope) -> impl IntoView {
|
||||
let selected = create_rw_signal(cx, String::from("o"));
|
||||
view! { cx,
|
||||
<>
|
||||
{ move || selected.get() }
|
||||
<Menu selected>
|
||||
<MenuItem key="a" label="and"/>
|
||||
<MenuItem key="o" label="or"/>
|
||||
</Menu>
|
||||
</>
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
use leptos::*;
|
||||
|
||||
#[component]
|
||||
pub fn MobilePage(cx: Scope, path: &'static str) -> impl IntoView {
|
||||
view! { cx,
|
||||
<div style="height: 100vh; display: flex; align-items: center; justify-content: center; background: #eff2f5">
|
||||
<iframe src=path style="width: 360px; height: 640px; background-color: #fff; border: none; border-radius: 16px; border: 1px solid #e1e1e1"/>
|
||||
</div>
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
mod button;
|
||||
mod checkbox;
|
||||
mod components;
|
||||
mod home;
|
||||
mod image;
|
||||
mod input;
|
||||
mod menu;
|
||||
mod mobile;
|
||||
mod modal;
|
||||
mod nav_bar;
|
||||
mod slider;
|
||||
mod tabbar;
|
||||
|
||||
pub use button::*;
|
||||
pub use checkbox::*;
|
||||
pub use components::*;
|
||||
pub use home::*;
|
||||
pub use image::*;
|
||||
pub use input::*;
|
||||
pub use menu::*;
|
||||
pub use mobile::*;
|
||||
pub use modal::*;
|
||||
pub use nav_bar::*;
|
||||
pub use slider::*;
|
||||
pub use tabbar::*;
|
|
@ -1,15 +0,0 @@
|
|||
use leptos::*;
|
||||
use melt_ui::*;
|
||||
|
||||
#[component]
|
||||
pub fn ModalPage(cx: Scope) -> impl IntoView {
|
||||
let show = create_rw_signal(cx, false);
|
||||
view! { cx,
|
||||
<Button on:click=move |_| show.set(true)>
|
||||
"open modal"
|
||||
</Button>
|
||||
<Modal title="标题" show>
|
||||
"sd"
|
||||
</Modal>
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
use leptos::*;
|
||||
use melt_ui::mobile::NavBar;
|
||||
|
||||
#[component]
|
||||
pub fn NavBarPage(cx: Scope) -> impl IntoView {
|
||||
let click_text = create_rw_signal(cx, String::from("none"));
|
||||
|
||||
let click_left = SignalSetter::map(cx, move |_| {
|
||||
click_text.set("left".to_string())
|
||||
});
|
||||
|
||||
let click_right = SignalSetter::map(cx, move |_| {
|
||||
click_text.set("right".to_string())
|
||||
});
|
||||
|
||||
view! { cx,
|
||||
<div style="height: 100vh; background: #f5f5f5">
|
||||
<NavBar title="Home" left_arrow=true left_text="back" right_text="add" click_left=click_left click_right=click_right/>
|
||||
<div style="padding-top: 50px">
|
||||
{ move || click_text.get() }
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
use leptos::*;
|
||||
use melt_ui::*;
|
||||
|
||||
#[component]
|
||||
pub fn SliderPage(cx: Scope) -> impl IntoView {
|
||||
let value = create_rw_signal(cx, 0.0);
|
||||
|
||||
view! { cx,
|
||||
<Slider value/>
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
use leptos::*;
|
||||
use melt_ui::mobile::*;
|
||||
|
||||
#[component]
|
||||
pub fn TabbarPage(cx: Scope) -> impl IntoView {
|
||||
let selected = create_rw_signal(cx, String::from("o"));
|
||||
view! { cx,
|
||||
<div style="height: 100vh; background: #f5f5f5">
|
||||
{ move || selected.get() }
|
||||
<Tabbar selected>
|
||||
<TabbarItem name="a">
|
||||
"and"
|
||||
</TabbarItem>
|
||||
<TabbarItem name="i">
|
||||
"if"
|
||||
</TabbarItem>
|
||||
<TabbarItem name="o" icon=icondata::AiIcon::AiCloseOutlined>
|
||||
"or"
|
||||
</TabbarItem>
|
||||
</Tabbar>
|
||||
</div>
|
||||
}
|
||||
}
|
|
@ -6,12 +6,12 @@ edition = "2021"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
leptos = { version = "0.4.8", features = ["csr"] }
|
||||
leptos = { version = "0.5.0-beta2", features = ["csr"] }
|
||||
melt-ui = { path = "../" }
|
||||
icondata = { version = "0.0.7", features = [
|
||||
"AiCloseOutlined",
|
||||
"AiCheckOutlined",
|
||||
] }
|
||||
leptos_router = { version = "0.4.0", features = ["csr"] }
|
||||
leptos_router = { version = "0.5.0-beta2", features = ["csr"] }
|
||||
indoc = "2.0.1"
|
||||
regex = "1.8.2"
|
||||
|
|
3
gh-pages/README.md
Normal file
3
gh-pages/README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
## Used
|
||||
|
||||
Run the `trunk serve` command and then open the `http://127.0.0.1:6421/melt-ui` URL
|
|
@ -2,7 +2,7 @@
|
|||
target = "index.html"
|
||||
public_url = "/melt-ui/"
|
||||
dist = "../docs"
|
||||
release = true
|
||||
# release = true
|
||||
|
||||
[watch]
|
||||
watch = [
|
||||
|
|
|
@ -3,70 +3,34 @@ use leptos::*;
|
|||
use leptos_router::*;
|
||||
|
||||
#[component]
|
||||
pub fn App(cx: Scope) -> impl IntoView {
|
||||
view! { cx,
|
||||
pub fn App() -> impl IntoView {
|
||||
view! {
|
||||
<Router base="/melt-ui">
|
||||
<Routes base="/melt-ui".to_string() >
|
||||
<Route path="/" view=move |cx| view! {cx,
|
||||
<Home />
|
||||
} />
|
||||
<Route path="/menu" view=move |cx| view! {cx,
|
||||
<MenuPage />
|
||||
} />
|
||||
<Route path="/slider" view=move |cx| view! {cx,
|
||||
<SliderPage />
|
||||
} />
|
||||
<Route path="/components" view=move |cx| view! {cx,
|
||||
<ComponentsPage />
|
||||
} >
|
||||
<Route path="/menu" view=move |cx| view! {cx,
|
||||
<MenuPage />
|
||||
} />
|
||||
<Route path="/slider" view=move |cx| view! {cx,
|
||||
<SliderPage />
|
||||
} />
|
||||
<Route path="/tabbar" view=move |cx| view! {cx,
|
||||
<Route path="/" view=Home />
|
||||
<Route path="/components" view=ComponentsPage>
|
||||
<Route path="/menu" view=MenuPage />
|
||||
<Route path="/slider" view=SliderPage />
|
||||
<Route path="/tabbar" view=|| view! {
|
||||
<MobilePage path="/melt-ui?path=/mobile/tabbar" />
|
||||
} />
|
||||
<Route path="/nav-bar" view=move |cx| view! {cx,
|
||||
<Route path="/nav-bar" view=|| view! {
|
||||
<MobilePage path="/melt-ui?path=/mobile/nav-bar" />
|
||||
} />
|
||||
<Route path="/input" view=move |cx| view! {cx,
|
||||
<InputPage />
|
||||
} />
|
||||
<Route path="/image" view=move |cx| view! {cx,
|
||||
<ImagePage />
|
||||
} />
|
||||
<Route path="/modal" view=move |cx| view! {cx,
|
||||
<ModalPage />
|
||||
} />
|
||||
<Route path="/button" view=move |cx| view! {cx,
|
||||
<ButtonPage />
|
||||
} />
|
||||
<Route path="/checkbox" view=move |cx| view! {cx,
|
||||
<CheckboxPage />
|
||||
} />
|
||||
<Route path="/toast" view=move |cx| view! {cx,
|
||||
<Route path="/input" view=InputPage />
|
||||
<Route path="/image" view=ImagePage />
|
||||
<Route path="/modal" view=ModalPage />
|
||||
<Route path="/button" view=ButtonPage />
|
||||
<Route path="/checkbox" view=CheckboxPage />
|
||||
<Route path="/toast" view=|| view! {
|
||||
<MobilePage path="/melt-ui?path=/mobile/toast" />
|
||||
} />
|
||||
<Route path="/tabs" view=move |cx| view! {cx,
|
||||
<TabsPage />
|
||||
} />
|
||||
<Route path="/select" view=move |cx| view! {cx,
|
||||
<SelectPage />
|
||||
} />
|
||||
<Route path="/tabs" view=TabsPage />
|
||||
<Route path="/select" view=SelectPage />
|
||||
</Route>
|
||||
</Routes>
|
||||
<Routes base="/melt-ui/mobile".to_string()>
|
||||
<Route path="/tabbar" view=move |cx| view! {cx,
|
||||
<TabbarPage />
|
||||
} />
|
||||
<Route path="/nav-bar" view=move |cx| view! {cx,
|
||||
<NavBarPage />
|
||||
} />
|
||||
<Route path="/toast" view=move |cx| view! {cx,
|
||||
<ToastPage />
|
||||
} />
|
||||
<Route path="/mobile/tabbar" view=TabbarPage />
|
||||
<Route path="/mobile/nav-bar" view=NavBarPage />
|
||||
<Route path="/mobile/toast" view=ToastPage />
|
||||
</Routes>
|
||||
</Router>
|
||||
}
|
||||
|
|
|
@ -3,14 +3,14 @@ use leptos_router::use_navigate;
|
|||
use melt_ui::*;
|
||||
|
||||
#[component]
|
||||
pub fn SiteHeader(cx: Scope) -> impl IntoView {
|
||||
view! { cx,
|
||||
pub fn SiteHeader() -> impl IntoView {
|
||||
view! {
|
||||
<LayoutHeader
|
||||
style="height: 54px; display: flex; align-items: center; justify-content: space-between; padding: 0 20px; border-bottom: 1px solid #efeff6"
|
||||
>
|
||||
<span style="cursor: pointer" on:click=move |_| {
|
||||
let navigate = use_navigate(cx);
|
||||
_ = navigate("/", Default::default());
|
||||
let navigate = use_navigate();
|
||||
navigate("/", Default::default());
|
||||
}>
|
||||
"Melt UI"
|
||||
</span>
|
||||
|
|
|
@ -6,5 +6,5 @@ use app::*;
|
|||
use leptos::*;
|
||||
|
||||
fn main() {
|
||||
mount_to_body(|cx| view! { cx, <App/> })
|
||||
mount_to_body(App)
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@ use leptos::*;
|
|||
use melt_ui::*;
|
||||
|
||||
#[component]
|
||||
pub fn ButtonPage(cx: Scope) -> impl IntoView {
|
||||
view! {cx,
|
||||
pub fn ButtonPage() -> impl IntoView {
|
||||
view! {
|
||||
<Space>
|
||||
<Button type_=ButtonType::PRIMARY>
|
||||
"PRIMARY"
|
||||
|
|
|
@ -2,9 +2,9 @@ use leptos::*;
|
|||
use melt_ui::*;
|
||||
|
||||
#[component]
|
||||
pub fn CheckboxPage(cx: Scope) -> impl IntoView {
|
||||
let checked = create_rw_signal(cx, false);
|
||||
view! {cx,
|
||||
pub fn CheckboxPage() -> impl IntoView {
|
||||
let checked = create_rw_signal(false);
|
||||
view! {
|
||||
<div>
|
||||
<Checkbox checked>
|
||||
"Click"
|
||||
|
|
|
@ -5,11 +5,11 @@ use melt_ui::*;
|
|||
use regex::Regex;
|
||||
|
||||
#[component]
|
||||
pub fn ComponentsPage(cx: Scope) -> impl IntoView {
|
||||
let loaction = use_location(cx);
|
||||
let navigate = use_navigate(cx);
|
||||
let selected = create_rw_signal(cx, String::from(""));
|
||||
create_effect(cx, move |_| {
|
||||
pub fn ComponentsPage() -> impl IntoView {
|
||||
let loaction = use_location();
|
||||
let navigate = use_navigate();
|
||||
let selected = create_rw_signal(String::from(""));
|
||||
create_effect(move |_| {
|
||||
let pathname = loaction.pathname.get();
|
||||
|
||||
let re = Regex::new(r"^/melt-ui/components/(.+)$").unwrap();
|
||||
|
@ -23,14 +23,14 @@ pub fn ComponentsPage(cx: Scope) -> impl IntoView {
|
|||
selected.set(path);
|
||||
});
|
||||
|
||||
create_effect(cx, move |value| {
|
||||
create_effect(move |value| {
|
||||
let selected = selected.get();
|
||||
if value.is_some() {
|
||||
_ = navigate(&format!("/components/{selected}"), Default::default());
|
||||
navigate(&format!("/components/{selected}"), Default::default());
|
||||
}
|
||||
selected
|
||||
});
|
||||
view! {cx,
|
||||
view! {
|
||||
<Layout position=LayoutPosition::ABSOLUTE>
|
||||
<SiteHeader />
|
||||
<Layout has_sider=true position=LayoutPosition::ABSOLUTE style="top: 54px;">
|
||||
|
|
|
@ -4,23 +4,20 @@ use leptos_router::{use_navigate, use_query_map};
|
|||
use melt_ui::*;
|
||||
|
||||
#[component]
|
||||
pub fn Home(cx: Scope) -> impl IntoView {
|
||||
let query_map = use_query_map(cx).get();
|
||||
pub fn Home() -> impl IntoView {
|
||||
let query_map = use_query_map().get_untracked();
|
||||
if let Some(path) = query_map.get("path") {
|
||||
let path = store_value(cx, path.clone());
|
||||
request_animation_frame(move || {
|
||||
let navigate = use_navigate(cx);
|
||||
_ = navigate(&path.get_value(), Default::default());
|
||||
});
|
||||
let navigate = use_navigate();
|
||||
navigate(path, Default::default());
|
||||
}
|
||||
view! { cx,
|
||||
view! {
|
||||
<Layout position=LayoutPosition::ABSOLUTE>
|
||||
<SiteHeader />
|
||||
<Layout position=LayoutPosition::ABSOLUTE style="top: 54px; display: flex; align-items: center; justify-content: center; flex-direction: column;">
|
||||
<p>"A Leptos UI Library"</p>
|
||||
<Button on:click=move |_| {
|
||||
let navigate = use_navigate(cx);
|
||||
_ = navigate("/components/menu", Default::default());
|
||||
let navigate = use_navigate();
|
||||
navigate("/components/menu", Default::default());
|
||||
}>
|
||||
"Read the docs"
|
||||
</Button>
|
||||
|
|
|
@ -2,8 +2,8 @@ use leptos::*;
|
|||
use melt_ui::*;
|
||||
|
||||
#[component]
|
||||
pub fn ImagePage(cx: Scope) -> impl IntoView {
|
||||
view! { cx,
|
||||
pub fn ImagePage() -> impl IntoView {
|
||||
view! {
|
||||
<>
|
||||
<Image src="https://s3.bmp.ovh/imgs/2021/10/2c3b013418d55659.jpg" width="500px"/>
|
||||
<Image width="200px" height="200px"/>
|
||||
|
|
|
@ -2,9 +2,9 @@ use leptos::*;
|
|||
use melt_ui::*;
|
||||
|
||||
#[component]
|
||||
pub fn InputPage(cx: Scope) -> impl IntoView {
|
||||
let value = create_rw_signal(cx, String::from("o"));
|
||||
view! { cx,
|
||||
pub fn InputPage() -> impl IntoView {
|
||||
let value = create_rw_signal(String::from("o"));
|
||||
view! {
|
||||
<>
|
||||
{move || value.get()}
|
||||
<Input value/>
|
||||
|
|
|
@ -3,9 +3,9 @@ use leptos::*;
|
|||
use melt_ui::*;
|
||||
|
||||
#[component]
|
||||
pub fn MenuPage(cx: Scope) -> impl IntoView {
|
||||
let selected = create_rw_signal(cx, String::from("o"));
|
||||
view! { cx,
|
||||
pub fn MenuPage() -> impl IntoView {
|
||||
let selected = create_rw_signal(String::from("o"));
|
||||
view! {
|
||||
<Card>
|
||||
{ move || selected.get() }
|
||||
<Menu selected>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use leptos::*;
|
||||
|
||||
#[component]
|
||||
pub fn MobilePage(cx: Scope, path: &'static str) -> impl IntoView {
|
||||
view! { cx,
|
||||
pub fn MobilePage(path: &'static str) -> impl IntoView {
|
||||
view! {
|
||||
<div style="height: 100vh; display: flex; align-items: center; justify-content: center; background: #eff2f5">
|
||||
<iframe src=path style="width: 360px; height: 640px; background-color: #fff; border: none; border-radius: 16px; border: 1px solid #e1e1e1"/>
|
||||
</div>
|
||||
|
|
|
@ -2,9 +2,9 @@ use leptos::*;
|
|||
use melt_ui::*;
|
||||
|
||||
#[component]
|
||||
pub fn ModalPage(cx: Scope) -> impl IntoView {
|
||||
let show = create_rw_signal(cx, false);
|
||||
view! { cx,
|
||||
pub fn ModalPage() -> impl IntoView {
|
||||
let show = create_rw_signal(false);
|
||||
view! {
|
||||
<Button on:click=move |_| show.set(true)>
|
||||
"open modal"
|
||||
</Button>
|
||||
|
|
|
@ -2,18 +2,14 @@ use leptos::*;
|
|||
use melt_ui::mobile::NavBar;
|
||||
|
||||
#[component]
|
||||
pub fn NavBarPage(cx: Scope) -> impl IntoView {
|
||||
let click_text = create_rw_signal(cx, String::from("none"));
|
||||
pub fn NavBarPage() -> impl IntoView {
|
||||
let click_text = create_rw_signal(String::from("none"));
|
||||
|
||||
let click_left = SignalSetter::map(cx, move |_| {
|
||||
click_text.set("left".to_string())
|
||||
});
|
||||
let click_left = SignalSetter::map(move |_| click_text.set("left".to_string()));
|
||||
|
||||
let click_right = SignalSetter::map(cx, move |_| {
|
||||
click_text.set("right".to_string())
|
||||
});
|
||||
let click_right = SignalSetter::map(move |_| click_text.set("right".to_string()));
|
||||
|
||||
view! { cx,
|
||||
view! {
|
||||
<div style="height: 100vh; background: #f5f5f5">
|
||||
<NavBar title="Home" left_arrow=true left_text="back" right_text="add" click_left=click_left click_right=click_right/>
|
||||
<div style="padding-top: 50px">
|
||||
|
|
|
@ -2,14 +2,14 @@ use leptos::*;
|
|||
use melt_ui::*;
|
||||
|
||||
#[component]
|
||||
pub fn SelectPage(cx: Scope) -> impl IntoView {
|
||||
let selected_value = create_rw_signal(cx, Some(String::from("apple")));
|
||||
pub fn SelectPage() -> impl IntoView {
|
||||
let selected_value = create_rw_signal(Some(String::from("apple")));
|
||||
|
||||
let options = vec![SelectOption {
|
||||
label: String::from("apple"),
|
||||
value: String::from("apple"),
|
||||
}];
|
||||
view! { cx,
|
||||
view! {
|
||||
<Select value=selected_value options/>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,10 +2,10 @@ use leptos::*;
|
|||
use melt_ui::*;
|
||||
|
||||
#[component]
|
||||
pub fn SliderPage(cx: Scope) -> impl IntoView {
|
||||
let value = create_rw_signal(cx, 0.0);
|
||||
pub fn SliderPage() -> impl IntoView {
|
||||
let value = create_rw_signal(0.0);
|
||||
|
||||
view! { cx,
|
||||
view! {
|
||||
<Slider value/>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,9 @@ use leptos::*;
|
|||
use melt_ui::mobile::*;
|
||||
|
||||
#[component]
|
||||
pub fn TabbarPage(cx: Scope) -> impl IntoView {
|
||||
let selected = create_rw_signal(cx, String::from("o"));
|
||||
view! { cx,
|
||||
pub fn TabbarPage() -> impl IntoView {
|
||||
let selected = create_rw_signal(String::from("o"));
|
||||
view! {
|
||||
<div style="height: 100vh; background: #f5f5f5">
|
||||
{ move || selected.get() }
|
||||
<Tabbar selected>
|
||||
|
|
|
@ -2,9 +2,9 @@ use leptos::*;
|
|||
use melt_ui::*;
|
||||
|
||||
#[component]
|
||||
pub fn TabsPage(cx: Scope) -> impl IntoView {
|
||||
let active_key = create_rw_signal(cx, "apple");
|
||||
view! { cx,
|
||||
pub fn TabsPage() -> impl IntoView {
|
||||
let active_key = create_rw_signal("apple");
|
||||
view! {
|
||||
<Tabs active_key>
|
||||
<Tab key="apple" label="Apple">
|
||||
"apple"
|
||||
|
|
|
@ -1,22 +1,19 @@
|
|||
use std::time::Duration;
|
||||
use leptos::*;
|
||||
use melt_ui::mobile::*;
|
||||
use melt_ui::*;
|
||||
use std::time::Duration;
|
||||
|
||||
#[component]
|
||||
pub fn ToastPage(cx: Scope) -> impl IntoView {
|
||||
let count = create_rw_signal(cx, 0u32);
|
||||
pub fn ToastPage() -> impl IntoView {
|
||||
let count = create_rw_signal(0u32);
|
||||
let onclick = move |_| {
|
||||
show_toast(
|
||||
cx,
|
||||
ToastOptions {
|
||||
message: format!("Hello {}", count.get_untracked()),
|
||||
duration: Duration::from_millis(2000),
|
||||
},
|
||||
);
|
||||
show_toast(ToastOptions {
|
||||
message: format!("Hello {}", count.get_untracked()),
|
||||
duration: Duration::from_millis(2000),
|
||||
});
|
||||
count.set(count.get_untracked() + 1);
|
||||
};
|
||||
view! {cx,
|
||||
view! {
|
||||
<div style="margin: 20px">
|
||||
<Button on:click=onclick>"hi"</Button>
|
||||
</div>
|
||||
|
|
|
@ -35,7 +35,6 @@ impl ButtonColor {
|
|||
|
||||
#[component]
|
||||
pub fn Button(
|
||||
cx: Scope,
|
||||
#[prop(optional, into)] style: MaybeSignal<String>,
|
||||
#[prop(optional, into)] type_: MaybeSignal<ButtonType>,
|
||||
#[prop(optional, into)] color: MaybeSignal<ButtonColor>,
|
||||
|
@ -43,8 +42,8 @@ pub fn Button(
|
|||
#[prop(optional, into)] icon: Option<Icon>,
|
||||
#[prop(optional)] children: Option<ChildrenFn>,
|
||||
) -> impl IntoView {
|
||||
let theme = use_theme(cx, Theme::light);
|
||||
let css_vars = create_memo(cx, move |_| {
|
||||
let theme = use_theme(Theme::light);
|
||||
let css_vars = create_memo(move |_| {
|
||||
let mut css_vars = String::new();
|
||||
let theme = theme.get();
|
||||
let bg_color = color.get().theme_color(&theme);
|
||||
|
@ -69,7 +68,7 @@ pub fn Button(
|
|||
""
|
||||
};
|
||||
|
||||
view! {cx, class=class_name,
|
||||
view! { class=class_name,
|
||||
<button
|
||||
class:melt-button=true
|
||||
class=("melt-button--text", move || type_.get() == ButtonType::TEXT)
|
||||
|
@ -81,7 +80,7 @@ pub fn Button(
|
|||
<Icon icon=icon style=icon_style/>
|
||||
</OptionComp>
|
||||
<OptionComp value=children bind:children>
|
||||
{ children(cx) }
|
||||
{ children() }
|
||||
</OptionComp>
|
||||
</button>
|
||||
}
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
use crate::theme::ThemeMethod;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ButtonTheme {
|
||||
|
||||
}
|
||||
pub struct ButtonTheme {}
|
||||
|
||||
impl ThemeMethod for ButtonTheme {
|
||||
fn light() -> Self {
|
||||
Self { }
|
||||
Self {}
|
||||
}
|
||||
|
||||
fn dark() -> Self {
|
||||
Self { }
|
||||
Self {}
|
||||
}
|
||||
}
|
|
@ -23,7 +23,6 @@ pub struct CardFooter {
|
|||
|
||||
#[component]
|
||||
pub fn Card(
|
||||
cx: Scope,
|
||||
#[prop(optional, into)] title: MaybeSignal<&'static str>,
|
||||
#[prop(optional)] card_header: Option<CardHeader>,
|
||||
#[prop(optional)] card_header_extra: Option<CardHeaderExtra>,
|
||||
|
@ -38,9 +37,9 @@ pub fn Card(
|
|||
// let footer = card_footer.map_or(None, |v| Some(Rc::new(v)));
|
||||
|
||||
view! {
|
||||
cx, class=class_name,
|
||||
class=class_name,
|
||||
<div class="melt-card">
|
||||
<If cond=MaybeSignal::derive(cx, move || is_header || !title.get().is_empty()) >
|
||||
<If cond=MaybeSignal::derive( move || is_header || !title.get().is_empty()) >
|
||||
<Then slot>
|
||||
<div class="melt-card__header">
|
||||
<div class="melt-card__header-content">
|
||||
|
@ -48,25 +47,25 @@ pub fn Card(
|
|||
<Fallback slot>
|
||||
{ title.get() }
|
||||
</Fallback>
|
||||
{ (header.children)(cx) }
|
||||
{ (header.children)() }
|
||||
</OptionComp>
|
||||
</div>
|
||||
<OptionComp value=header_extra.clone() bind:header_extra>
|
||||
<div class="melt-card__header-extra">
|
||||
{ (header_extra.children)(cx) }
|
||||
{ (header_extra.children)() }
|
||||
</div>
|
||||
</OptionComp>
|
||||
</div>
|
||||
</Then>
|
||||
</If>
|
||||
<div class="melt-card__content">
|
||||
{ children(cx) }
|
||||
{ children() }
|
||||
</div>
|
||||
<OptionComp value=card_footer bind:footer>
|
||||
<If cond=footer.if_ >
|
||||
<Then slot>
|
||||
<div class="melt-card__footer">
|
||||
{ (footer.children)(cx) }
|
||||
{ (footer.children)() }
|
||||
</div>
|
||||
</Then>
|
||||
</If>
|
||||
|
|
|
@ -4,17 +4,13 @@ use leptos::*;
|
|||
use stylers::style_sheet_str;
|
||||
|
||||
#[component]
|
||||
pub fn Checkbox(
|
||||
cx: Scope,
|
||||
#[prop(into)] checked: RwSignal<bool>,
|
||||
children: Children,
|
||||
) -> impl IntoView {
|
||||
let theme = use_theme(cx, Theme::light);
|
||||
pub fn Checkbox(#[prop(into)] checked: RwSignal<bool>, children: Children) -> impl IntoView {
|
||||
let theme = use_theme(Theme::light);
|
||||
let class_name = mount_style("checkbox", || {
|
||||
style_sheet_str!("./src/checkbox/checkbox.css")
|
||||
});
|
||||
|
||||
let css_vars = create_memo(cx, move |_| {
|
||||
let css_vars = create_memo(move |_| {
|
||||
let mut css_vars = String::new();
|
||||
let theme = theme.get();
|
||||
let bg_color = theme.common.color_primary;
|
||||
|
@ -22,7 +18,7 @@ pub fn Checkbox(
|
|||
css_vars
|
||||
});
|
||||
|
||||
view! {cx, class=class_name,
|
||||
view! { class=class_name,
|
||||
<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" />
|
||||
|
@ -34,7 +30,7 @@ pub fn Checkbox(
|
|||
</If>
|
||||
</div>
|
||||
<div class="melt-checkbox__label">
|
||||
{ children(cx) }
|
||||
{ children() }
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use leptos::*;
|
||||
|
||||
#[component]
|
||||
pub fn Code(cx: Scope, children: Children) -> impl IntoView {
|
||||
view! { cx,
|
||||
pub fn Code(children: Children) -> impl IntoView {
|
||||
view! {
|
||||
<code class="melt-code">
|
||||
{ children(cx) }
|
||||
{ children() }
|
||||
</code>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use leptos::*;
|
||||
use super::Fallback;
|
||||
use leptos::*;
|
||||
|
||||
#[slot]
|
||||
pub struct Then {
|
||||
|
@ -14,7 +14,6 @@ pub struct ElseIf {
|
|||
|
||||
#[component]
|
||||
pub fn If(
|
||||
cx: Scope,
|
||||
#[prop(into)] cond: MaybeSignal<bool>,
|
||||
then: Then,
|
||||
#[prop(default=vec![])] else_if: Vec<ElseIf>,
|
||||
|
@ -22,13 +21,13 @@ pub fn If(
|
|||
) -> impl IntoView {
|
||||
move || {
|
||||
if cond.get() {
|
||||
(then.children)(cx).into_view(cx)
|
||||
(then.children)().into_view()
|
||||
} else if let Some(else_if) = else_if.iter().find(|i| i.cond.get()) {
|
||||
(else_if.children)(cx).into_view(cx)
|
||||
(else_if.children)().into_view()
|
||||
} else if let Some(fallback) = &fallback {
|
||||
(fallback.children)(cx).into_view(cx)
|
||||
(fallback.children)().into_view()
|
||||
} else {
|
||||
().into_view(cx)
|
||||
().into_view()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@ mod if_comp;
|
|||
mod option_comp;
|
||||
|
||||
pub use if_comp::*;
|
||||
pub use option_comp::*;
|
||||
use leptos::*;
|
||||
pub use option_comp::*;
|
||||
|
||||
#[slot]
|
||||
pub struct Fallback {
|
||||
|
|
|
@ -1,22 +1,21 @@
|
|||
use leptos::*;
|
||||
use super::Fallback;
|
||||
use leptos::*;
|
||||
|
||||
#[component]
|
||||
pub fn OptionComp<T, CF, IV>(
|
||||
cx: Scope,
|
||||
value: Option<T>,
|
||||
children: CF,
|
||||
#[prop(optional)] fallback: Option<Fallback>,
|
||||
) -> impl IntoView
|
||||
where
|
||||
CF: Fn(Scope, T) -> IV + 'static,
|
||||
CF: Fn(T) -> IV + 'static,
|
||||
IV: IntoView,
|
||||
{
|
||||
if let Some(value) = value {
|
||||
children(cx, value).into_view(cx)
|
||||
children(value).into_view()
|
||||
} else if let Some(fallback) = fallback {
|
||||
(fallback.children)(cx).into_view(cx)
|
||||
(fallback.children)().into_view()
|
||||
} else {
|
||||
().into_view(cx)
|
||||
().into_view()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,31 +1,30 @@
|
|||
// copy https://github.com/Carlosted/leptos-icons
|
||||
// leptos updated version causes leptos_icons error
|
||||
pub use icondata::*;
|
||||
use leptos::SignalGet;
|
||||
use leptos::*;
|
||||
|
||||
/// The Icon component.
|
||||
#[leptos::component]
|
||||
#[component]
|
||||
pub fn Icon(
|
||||
cx: leptos::Scope,
|
||||
/// The icon to show.
|
||||
#[prop(into)]
|
||||
icon: leptos::MaybeSignal<Icon>,
|
||||
icon: MaybeSignal<Icon>,
|
||||
/// The width of the icon (horizontal side length of the square surrounding the icon). Defaults to "1em".
|
||||
#[prop(into, optional)]
|
||||
width: Option<leptos::MaybeSignal<String>>,
|
||||
width: Option<MaybeSignal<String>>,
|
||||
/// The height of the icon (vertical side length of the square surrounding the icon). Defaults to "1em".
|
||||
#[prop(into, optional)]
|
||||
height: Option<leptos::MaybeSignal<String>>,
|
||||
height: Option<MaybeSignal<String>>,
|
||||
/// HTML class attribute.
|
||||
#[prop(into, optional)]
|
||||
class: Option<leptos::MaybeSignal<String>>,
|
||||
class: Option<MaybeSignal<String>>,
|
||||
/// HTML style attribute.
|
||||
#[prop(into, optional)]
|
||||
style: Option<leptos::MaybeSignal<String>>,
|
||||
) -> impl leptos::IntoView {
|
||||
style: Option<MaybeSignal<String>>,
|
||||
) -> impl IntoView {
|
||||
let icon: IconData = icon.get().into();
|
||||
|
||||
let mut svg = leptos::svg::svg(cx);
|
||||
let mut svg = svg::svg();
|
||||
if let Some(classes) = class {
|
||||
svg = svg.classes(classes.get());
|
||||
}
|
||||
|
@ -45,20 +44,20 @@ pub fn Icon(
|
|||
// We ignore the width and height attributes of the icon, even if the user hasn't specified any.
|
||||
svg = svg.attr(
|
||||
"width",
|
||||
leptos::Attribute::String(match (width, icon.width) {
|
||||
(Some(a), Some(_b)) => std::borrow::Cow::from(a.get()),
|
||||
(Some(a), None) => std::borrow::Cow::from(a.get()),
|
||||
(None, Some(_b)) => std::borrow::Cow::from("1em"),
|
||||
(None, None) => std::borrow::Cow::from("1em"),
|
||||
Attribute::String(match (width, icon.width) {
|
||||
(Some(a), Some(_b)) => Oco::from(a.get()),
|
||||
(Some(a), None) => Oco::from(a.get()),
|
||||
(None, Some(_b)) => Oco::from("1em"),
|
||||
(None, None) => Oco::from("1em"),
|
||||
}),
|
||||
);
|
||||
svg = svg.attr(
|
||||
"height",
|
||||
leptos::Attribute::String(match (height, icon.height) {
|
||||
(Some(a), Some(_b)) => std::borrow::Cow::from(a.get()),
|
||||
(Some(a), None) => std::borrow::Cow::from(a.get()),
|
||||
(None, Some(_b)) => std::borrow::Cow::from("1em"),
|
||||
(None, None) => std::borrow::Cow::from("1em"),
|
||||
Attribute::String(match (height, icon.height) {
|
||||
(Some(a), Some(_b)) => Oco::from(a.get()),
|
||||
(Some(a), None) => Oco::from(a.get()),
|
||||
(None, Some(_b)) => Oco::from("1em"),
|
||||
(None, None) => Oco::from("1em"),
|
||||
}),
|
||||
);
|
||||
if let Some(view_box) = icon.view_box {
|
||||
|
@ -79,5 +78,5 @@ pub fn Icon(
|
|||
svg = svg.attr("fill", icon.fill.unwrap_or("currentColor"));
|
||||
svg = svg.attr("role", "graphics-symbol");
|
||||
svg = svg.inner_html(icon.data);
|
||||
leptos::IntoView::into_view(svg, cx)
|
||||
IntoView::into_view(svg)
|
||||
}
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
|
||||
use leptos::*;
|
||||
|
||||
#[component]
|
||||
pub fn Image(
|
||||
cx: Scope,
|
||||
#[prop(optional, into)] src: MaybeSignal<String>,
|
||||
#[prop(optional, into)] alt: MaybeSignal<String>,
|
||||
#[prop(optional, into)] width: MaybeSignal<String>,
|
||||
|
@ -11,7 +9,6 @@ pub fn Image(
|
|||
#[prop(optional, into)] border_radius: MaybeSignal<String>,
|
||||
#[prop(optional, into)] object_fit: MaybeSignal<String>,
|
||||
) -> impl IntoView {
|
||||
|
||||
let style = move || {
|
||||
let mut style = String::new();
|
||||
|
||||
|
@ -33,7 +30,7 @@ pub fn Image(
|
|||
style
|
||||
};
|
||||
view! {
|
||||
cx,
|
||||
|
||||
<img src=move || src.get() alt=move || alt.get() style=style object_fit=move || object_fit.get()/>
|
||||
}
|
||||
}
|
|
@ -25,21 +25,20 @@ impl InputType {
|
|||
|
||||
#[component]
|
||||
pub fn Input(
|
||||
cx: Scope,
|
||||
#[prop(into)] value: RwSignal<String>,
|
||||
#[prop(optional, into)] type_: MaybeSignal<InputType>,
|
||||
) -> impl IntoView {
|
||||
let theme = use_theme(cx, Theme::light);
|
||||
let theme = use_theme(Theme::light);
|
||||
let class_name = mount_style("input", || style_sheet_str!("./src/input/input.css"));
|
||||
|
||||
let input_ref = create_node_ref::<html::Input>(cx);
|
||||
input_ref.on_load(cx, move |input| {
|
||||
let input_ref = create_node_ref::<html::Input>();
|
||||
input_ref.on_load(move |input| {
|
||||
input.on(ev::input, move |ev| {
|
||||
value.set(event_target_value(&ev));
|
||||
});
|
||||
});
|
||||
|
||||
let css_vars = create_memo(cx, move |_| {
|
||||
let css_vars = create_memo(move |_| {
|
||||
let mut css_vars = String::new();
|
||||
let theme = theme.get();
|
||||
let border_color_hover = theme.common.color_primary.clone();
|
||||
|
@ -49,7 +48,7 @@ pub fn Input(
|
|||
css_vars
|
||||
});
|
||||
view! {
|
||||
cx, class=class_name,
|
||||
class=class_name,
|
||||
<div class:melt-input=true style=move || css_vars.get()>
|
||||
<input type=move || type_.get().as_str() prop:value=move || value.get() ref=input_ref class="melt-input__input-el"/>
|
||||
</div>
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
use crate::theme::ThemeMethod;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct InputTheme {
|
||||
|
||||
}
|
||||
pub struct InputTheme {}
|
||||
|
||||
impl ThemeMethod for InputTheme {
|
||||
fn light() -> Self {
|
||||
Self { }
|
||||
Self {}
|
||||
}
|
||||
|
||||
fn dark() -> Self {
|
||||
Self { }
|
||||
Self {}
|
||||
}
|
||||
}
|
|
@ -2,13 +2,12 @@ use leptos::*;
|
|||
|
||||
#[component]
|
||||
pub fn LayoutHeader(
|
||||
cx: Scope,
|
||||
#[prop(optional, into)] style: MaybeSignal<String>,
|
||||
children: Children,
|
||||
) -> impl IntoView {
|
||||
view! { cx,
|
||||
view! {
|
||||
<div class="melt-layout-header" style=move || style.get()>
|
||||
{ children(cx) }
|
||||
{ children() }
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,13 +3,13 @@ use leptos::*;
|
|||
use stylers::style_sheet_str;
|
||||
|
||||
#[component]
|
||||
pub fn LayoutSider(cx: Scope, children: Children) -> impl IntoView {
|
||||
pub fn LayoutSider(children: Children) -> impl IntoView {
|
||||
let class_name = mount_style("layout-sider", || {
|
||||
style_sheet_str!("./src/layout/layout-sider.css")
|
||||
});
|
||||
view! { cx, class=class_name,
|
||||
view! { class=class_name,
|
||||
<div class="melt-layout-sider">
|
||||
{ children(cx) }
|
||||
{ children() }
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ impl LayoutPosition {
|
|||
|
||||
#[component]
|
||||
pub fn Layout(
|
||||
cx: Scope,
|
||||
#[prop(optional, into)] style: MaybeSignal<String>,
|
||||
#[prop(optional)] position: LayoutPosition,
|
||||
#[prop(optional, into)] has_sider: MaybeSignal<bool>,
|
||||
|
@ -33,16 +32,16 @@ pub fn Layout(
|
|||
) -> impl IntoView {
|
||||
let class_name = mount_style("layout", || style_sheet_str!("./src/layout/layout.css"));
|
||||
|
||||
let style = create_memo(cx, move |_| {
|
||||
let style = create_memo(move |_| {
|
||||
let mut style = style.get();
|
||||
if has_sider.get() {
|
||||
style.push_str("display: flex; flex-wrap: nowrap; flex-direction: row; width: 100;%")
|
||||
}
|
||||
style
|
||||
});
|
||||
view! { cx, class=class_name,
|
||||
view! { class=class_name,
|
||||
<div class="melt-layout" class=("melt-layout--absolute-positioned", position == LayoutPosition::ABSOLUTE) style=move || style.get()>
|
||||
{ children(cx) }
|
||||
{ children() }
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,18 +5,17 @@ use stylers::style_sheet_str;
|
|||
|
||||
#[component]
|
||||
pub fn MenuItem(
|
||||
cx: Scope,
|
||||
#[prop(into)] key: MaybeSignal<&'static str>,
|
||||
#[prop(into)] label: MaybeSignal<String>,
|
||||
) -> impl IntoView {
|
||||
let class_name = mount_style("menu-item", || style_sheet_str!("./src/menu/menu-item.css"));
|
||||
let theme = use_theme(cx, Theme::light);
|
||||
let menu = use_menu(cx);
|
||||
let theme = use_theme(Theme::light);
|
||||
let menu = use_menu();
|
||||
let onclick_select = move |_| {
|
||||
menu.set(MenuInjectionKey::new(key.get().to_string()));
|
||||
};
|
||||
|
||||
let css_vars = create_memo(cx, move |_| {
|
||||
let css_vars = create_memo(move |_| {
|
||||
let mut css_vars = String::new();
|
||||
let theme = theme.get();
|
||||
let font_color = theme.common.color_primary.clone();
|
||||
|
@ -26,7 +25,7 @@ pub fn MenuItem(
|
|||
css_vars.push_str(&format!("--border-radius: {border_radius};"));
|
||||
css_vars
|
||||
});
|
||||
view! {cx, class=class_name,
|
||||
view! { class=class_name,
|
||||
<div class="melt-menu-item">
|
||||
<div class="melt-menu-item__content" class=("melt-menu-item__content--selected", move || menu.get().value == key.get()) on:click=onclick_select style=move || css_vars.get()>
|
||||
{ move || label.get() }
|
||||
|
|
|
@ -4,13 +4,9 @@ use leptos::*;
|
|||
pub use menu_item::*;
|
||||
|
||||
#[component]
|
||||
pub fn Menu(
|
||||
cx: Scope,
|
||||
#[prop(into)] selected: RwSignal<String>,
|
||||
children: Children,
|
||||
) -> impl IntoView {
|
||||
let menu_injection_key = create_rw_signal(cx, MenuInjectionKey::new(selected.get()));
|
||||
create_effect(cx, move |_| {
|
||||
pub fn Menu(#[prop(into)] selected: RwSignal<String>, children: Children) -> impl IntoView {
|
||||
let menu_injection_key = create_rw_signal(MenuInjectionKey::new(selected.get_untracked()));
|
||||
create_effect(move |_| {
|
||||
let selected_key = selected.get();
|
||||
let key = menu_injection_key.get_untracked();
|
||||
if selected_key != key.value {
|
||||
|
@ -18,17 +14,17 @@ pub fn Menu(
|
|||
}
|
||||
});
|
||||
|
||||
create_effect(cx, move |_| {
|
||||
create_effect(move |_| {
|
||||
let selected_key = selected.get_untracked();
|
||||
let key = menu_injection_key.get();
|
||||
if selected_key != key.value {
|
||||
selected.set(key.value);
|
||||
}
|
||||
});
|
||||
provide_context(cx, menu_injection_key);
|
||||
view! {cx,
|
||||
provide_context(menu_injection_key);
|
||||
view! {
|
||||
<div class="melt-menu">
|
||||
{ children(cx) }
|
||||
{ children() }
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
@ -38,13 +34,12 @@ pub struct MenuInjectionKey {
|
|||
value: String,
|
||||
}
|
||||
|
||||
|
||||
impl MenuInjectionKey {
|
||||
pub fn new(value: String) -> Self {
|
||||
Self { value }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn use_menu(cx: Scope) -> RwSignal<MenuInjectionKey> {
|
||||
use_context::<RwSignal<MenuInjectionKey>>(cx).expect("MenuInjectionKey not exist")
|
||||
pub fn use_menu() -> RwSignal<MenuInjectionKey> {
|
||||
use_context::<RwSignal<MenuInjectionKey>>().expect("MenuInjectionKey not exist")
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ use web_sys::MouseEvent;
|
|||
|
||||
#[component]
|
||||
pub fn NavBar(
|
||||
cx: Scope,
|
||||
#[prop(optional, into)] title: MaybeSignal<&'static str>,
|
||||
#[prop(optional, into)] left_arrow: MaybeSignal<bool>,
|
||||
#[prop(optional, into)] left_text: MaybeSignal<&'static str>,
|
||||
|
@ -28,9 +27,9 @@ pub fn NavBar(
|
|||
}
|
||||
};
|
||||
|
||||
view! { cx, class=class_name,
|
||||
view! { class=class_name,
|
||||
<div class="melt-nav-bar">
|
||||
<If cond=MaybeSignal::derive(cx, move || left_arrow.get() || !left_text.get().is_empty())>
|
||||
<If cond=MaybeSignal::derive( move || left_arrow.get() || !left_text.get().is_empty())>
|
||||
<Then slot>
|
||||
<div class="melt-nav-bar__left" on:click=onclick_left>
|
||||
<If cond=left_arrow>
|
||||
|
@ -45,7 +44,7 @@ pub fn NavBar(
|
|||
<div class="melt-nav-bar__center">
|
||||
{ move || title.get() }
|
||||
</div>
|
||||
<If cond=MaybeSignal::derive(cx, move || !right_text.get().is_empty())>
|
||||
<If cond=MaybeSignal::derive( move || !right_text.get().is_empty())>
|
||||
<Then slot>
|
||||
<div class="melt-nav-bar__right" on:click=onclick_right>
|
||||
{ right_text.get() }
|
||||
|
|
|
@ -6,17 +6,13 @@ use stylers::style_sheet_str;
|
|||
pub use tabbar_item::*;
|
||||
|
||||
#[component]
|
||||
pub fn Tabbar(
|
||||
cx: Scope,
|
||||
#[prop(into)] selected: RwSignal<String>,
|
||||
children: Children,
|
||||
) -> impl IntoView {
|
||||
pub fn Tabbar(#[prop(into)] selected: RwSignal<String>, children: Children) -> impl IntoView {
|
||||
let class_name = mount_style("tabbar", || {
|
||||
style_sheet_str!("./src/mobile/tabbar/tabbar.css")
|
||||
});
|
||||
|
||||
let tabbar_injection_key = create_rw_signal(cx, TabbarInjectionKey::new(selected.get()));
|
||||
create_effect(cx, move |_| {
|
||||
let tabbar_injection_key = create_rw_signal(TabbarInjectionKey::new(selected.get()));
|
||||
create_effect(move |_| {
|
||||
let selected_key = selected.get();
|
||||
let key = tabbar_injection_key.get_untracked();
|
||||
if selected_key != key.value {
|
||||
|
@ -24,17 +20,17 @@ pub fn Tabbar(
|
|||
}
|
||||
});
|
||||
|
||||
create_effect(cx, move |_| {
|
||||
create_effect(move |_| {
|
||||
let selected_key = selected.get_untracked();
|
||||
let key = tabbar_injection_key.get();
|
||||
if selected_key != key.value {
|
||||
selected.set(key.value);
|
||||
}
|
||||
});
|
||||
provide_context(cx, tabbar_injection_key);
|
||||
view! {cx, class=class_name,
|
||||
provide_context(tabbar_injection_key);
|
||||
view! { class=class_name,
|
||||
<div class="melt-tabbar">
|
||||
{ children(cx) }
|
||||
{ children() }
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
@ -50,6 +46,6 @@ impl TabbarInjectionKey {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn use_tabbar(cx: Scope) -> RwSignal<TabbarInjectionKey> {
|
||||
use_context::<RwSignal<TabbarInjectionKey>>(cx).expect("TabbarInjectionKey not exist")
|
||||
pub fn use_tabbar() -> RwSignal<TabbarInjectionKey> {
|
||||
use_context::<RwSignal<TabbarInjectionKey>>().expect("TabbarInjectionKey not exist")
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ use stylers::style_sheet_str;
|
|||
|
||||
#[component]
|
||||
pub fn TabbarItem(
|
||||
cx: Scope,
|
||||
#[prop(into)] name: MaybeSignal<&'static str>,
|
||||
#[prop(optional, into)] icon: Option<Icon>,
|
||||
children: Children,
|
||||
|
@ -14,13 +13,13 @@ pub fn TabbarItem(
|
|||
let class_name = mount_style("tabbar-item", || {
|
||||
style_sheet_str!("./src/mobile/tabbar/tabbar-item.css")
|
||||
});
|
||||
let theme = use_theme(cx, Theme::light);
|
||||
let tabbar = use_tabbar(cx);
|
||||
let theme = use_theme(Theme::light);
|
||||
let tabbar = use_tabbar();
|
||||
let onclick_select = move |_| {
|
||||
tabbar.set(TabbarInjectionKey::new(name.get().to_string()));
|
||||
};
|
||||
|
||||
let css_vars = create_memo(cx, move |_| {
|
||||
let css_vars = create_memo(move |_| {
|
||||
let mut css_vars = String::new();
|
||||
let theme = theme.get();
|
||||
let font_color = theme.common.color_primary.clone();
|
||||
|
@ -28,13 +27,13 @@ pub fn TabbarItem(
|
|||
css_vars
|
||||
});
|
||||
|
||||
view! {cx, class=class_name,
|
||||
view! { class=class_name,
|
||||
<div class="melt-tabbar-item" class=("melt-tabbar-item--selected", move || tabbar.get().value == name.get()) on:click=onclick_select style=move || css_vars.get()>
|
||||
<OptionComp value=icon bind:icon>
|
||||
<Icon icon=icon width="22px" height="22px" class="melt-tabbar-item__icon"/>
|
||||
</OptionComp>
|
||||
<div class="melt-tabbar-item__content">
|
||||
{ children(cx) }
|
||||
{ children() }
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -9,16 +9,16 @@ pub struct ToastOptions {
|
|||
pub duration: Duration,
|
||||
}
|
||||
|
||||
pub fn show_toast(cx: Scope, options: ToastOptions) {
|
||||
pub fn show_toast(options: ToastOptions) {
|
||||
let class_name = mount_style("toast", || style_sheet_str!("./src/mobile/toast/toast.css"));
|
||||
|
||||
let parent = Element::from(document().body().expect("body element not to exist"));
|
||||
let children = view! {cx, class=class_name,
|
||||
let children = view! { class=class_name,
|
||||
<div class="melt-toast">
|
||||
{ options.message }
|
||||
</div>
|
||||
};
|
||||
let node = children.into_view(cx);
|
||||
let node = children.into_view();
|
||||
|
||||
#[cfg(all(target_arch = "wasm32"))]
|
||||
{
|
||||
|
@ -32,4 +32,9 @@ pub fn show_toast(cx: Scope, options: ToastOptions) {
|
|||
options.duration,
|
||||
);
|
||||
}
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
_ = parent;
|
||||
_ = node;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ pub struct ModalFooter {
|
|||
|
||||
#[component]
|
||||
pub fn Modal(
|
||||
cx: Scope,
|
||||
#[prop(into)] show: RwSignal<bool>,
|
||||
#[prop(optional, into)] title: MaybeSignal<&'static str>,
|
||||
children: Children,
|
||||
|
@ -22,7 +21,7 @@ pub fn Modal(
|
|||
let class_name = mount_style("modal", || style_sheet_str!("./src/modal/modal.css"));
|
||||
|
||||
view! {
|
||||
cx, class=class_name,
|
||||
class=class_name,
|
||||
<Teleport>
|
||||
<div class="melt-modal-container" style=move || if show.get() { "" } else { "display: none" }>
|
||||
<div class="melt-modal-mask"></div>
|
||||
|
@ -38,10 +37,10 @@ pub fn Modal(
|
|||
<Icon icon=Icon::from(AiIcon::AiCloseOutlined)/>
|
||||
</span>
|
||||
</CardHeaderExtra>
|
||||
{ children(cx) }
|
||||
{ children() }
|
||||
<CardFooter slot if_=modal_footer.is_some()>
|
||||
<OptionComp value=modal_footer.as_ref() bind:footer>
|
||||
{ (footer.children)(cx) }
|
||||
{ (footer.children)() }
|
||||
</OptionComp>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
|
|
|
@ -1,21 +1,22 @@
|
|||
use crate::{utils::mount_style::mount_style, components::*};
|
||||
use crate::{components::*, utils::mount_style::mount_style};
|
||||
use leptos::*;
|
||||
use stylers::style_sheet_str;
|
||||
|
||||
#[component]
|
||||
pub fn Progress(
|
||||
cx: Scope,
|
||||
#[prop(optional, into)] left_tip: MaybeSignal<&'static str>,
|
||||
#[prop(optional, into)] right_tip: MaybeSignal<&'static str>,
|
||||
percentage: ReadSignal<f64>,
|
||||
) -> impl IntoView {
|
||||
let class_name = mount_style("progress", || style_sheet_str!("./src/progress/progress.css"));
|
||||
let class_name = mount_style("progress", || {
|
||||
style_sheet_str!("./src/progress/progress.css")
|
||||
});
|
||||
let style = move || format!("width: {}%", percentage.get());
|
||||
view! {
|
||||
cx, class=class_name,
|
||||
class=class_name,
|
||||
<div class="melt-progress">
|
||||
<span class="melt-progress__tip-left">
|
||||
<If cond=MaybeSignal::derive(cx, move || !left_tip.get().is_empty())>
|
||||
<If cond=MaybeSignal::derive( move || !left_tip.get().is_empty())>
|
||||
<Then slot>
|
||||
{ left_tip.get() }
|
||||
</Then>
|
||||
|
@ -27,7 +28,7 @@ pub fn Progress(
|
|||
</span>
|
||||
</span>
|
||||
<span class="melt-progress__tip-right">
|
||||
<If cond=MaybeSignal::derive(cx, move || !right_tip.get().is_empty())>
|
||||
<If cond=MaybeSignal::derive( move || !right_tip.get().is_empty())>
|
||||
<Then slot>
|
||||
{ right_tip.get() }
|
||||
</Then>
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
use crate::{
|
||||
teleport::Teleport,
|
||||
theme::use_theme,
|
||||
utils::{dom::window_event_listener, mount_style::mount_style},
|
||||
Theme,
|
||||
};
|
||||
use crate::{teleport::Teleport, theme::use_theme, utils::mount_style::mount_style, Theme};
|
||||
use leptos::*;
|
||||
use std::hash::Hash;
|
||||
use stylers::style_sheet_str;
|
||||
|
@ -17,7 +12,6 @@ pub struct SelectOption<T> {
|
|||
|
||||
#[component]
|
||||
pub fn Select<T>(
|
||||
cx: Scope,
|
||||
#[prop(into)] value: RwSignal<Option<T>>,
|
||||
#[prop(optional, into)] options: MaybeSignal<Vec<SelectOption<T>>>,
|
||||
) -> impl IntoView
|
||||
|
@ -26,8 +20,8 @@ where
|
|||
{
|
||||
let class_name = mount_style("select", || style_sheet_str!("./src/select/select.css"));
|
||||
|
||||
let theme = use_theme(cx, Theme::light);
|
||||
let css_vars = create_memo(cx, move |_| {
|
||||
let theme = use_theme(Theme::light);
|
||||
let css_vars = create_memo(move |_| {
|
||||
let mut css_vars = String::new();
|
||||
let theme = theme.get();
|
||||
let bg_color = theme.common.color_primary;
|
||||
|
@ -37,9 +31,9 @@ where
|
|||
css_vars
|
||||
});
|
||||
|
||||
let is_show_popover = create_rw_signal(cx, false);
|
||||
let trigger_ref = create_node_ref::<html::Div>(cx);
|
||||
let popover_ref = create_node_ref::<html::Div>(cx);
|
||||
let is_show_popover = create_rw_signal(false);
|
||||
let trigger_ref = create_node_ref::<html::Div>();
|
||||
let popover_ref = create_node_ref::<html::Div>();
|
||||
let show_popover = move |_| {
|
||||
let rect = trigger_ref.get().unwrap().get_bounding_client_rect();
|
||||
is_show_popover.set(true);
|
||||
|
@ -74,10 +68,10 @@ where
|
|||
}
|
||||
is_show_popover.set(false);
|
||||
});
|
||||
on_cleanup(cx, timer);
|
||||
on_cleanup(move || timer.remove());
|
||||
|
||||
let temp_options = options.clone();
|
||||
let select_option_label = create_memo(cx, move |_| match value.get() {
|
||||
let select_option_label = create_memo(move |_| match value.get() {
|
||||
Some(value) => temp_options
|
||||
.get()
|
||||
.iter()
|
||||
|
@ -85,7 +79,7 @@ where
|
|||
.map_or(String::new(), |v| v.label.clone()),
|
||||
None => String::new(),
|
||||
});
|
||||
view! { cx, class=class_name,
|
||||
view! { class=class_name,
|
||||
<div class="melt-select" ref=trigger_ref on:click=show_popover style=move || css_vars.get()>
|
||||
{
|
||||
move || select_option_label.get()
|
||||
|
@ -96,14 +90,14 @@ where
|
|||
<For
|
||||
each=move || options.get()
|
||||
key=move |item| item.value.clone()
|
||||
view=move |cx, item| {
|
||||
let item = store_value(cx, item);
|
||||
view=move | item| {
|
||||
let item = store_value( item);
|
||||
let onclick = move |_| {
|
||||
let SelectOption { value: item_value, label: _ } = item.get_value();
|
||||
value.set(Some(item_value));
|
||||
is_show_popover.set(false);
|
||||
};
|
||||
view! { cx, class=class_name,
|
||||
view! { class=class_name,
|
||||
<div class="melt-select-menu__item" class=("melt-select-menu__item-selected", move || value.get() == Some(item.get_value().value) ) on:click=onclick>
|
||||
{ item.get_value().label }
|
||||
</div>
|
||||
|
|
|
@ -1,20 +1,15 @@
|
|||
use crate::{
|
||||
theme::use_theme,
|
||||
utils::{dom::window_event_listener, mount_style::mount_style},
|
||||
Theme,
|
||||
};
|
||||
use crate::{theme::use_theme, utils::mount_style::mount_style, Theme};
|
||||
use leptos::*;
|
||||
use stylers::style_sheet_str;
|
||||
use wasm_bindgen::JsCast;
|
||||
|
||||
#[component]
|
||||
pub fn Slider(
|
||||
cx: Scope,
|
||||
#[prop(into)] value: RwSignal<f64>,
|
||||
#[prop(default = MaybeSignal::Static(100f64), into)] max: MaybeSignal<f64>,
|
||||
) -> impl IntoView {
|
||||
let theme = use_theme(cx, Theme::light);
|
||||
let css_vars = create_memo(cx, move |_| {
|
||||
let theme = use_theme(Theme::light);
|
||||
let css_vars = create_memo(move |_| {
|
||||
let mut css_vars = String::new();
|
||||
let theme = theme.get();
|
||||
let bg_color = theme.common.color_primary;
|
||||
|
@ -23,7 +18,7 @@ pub fn Slider(
|
|||
css_vars
|
||||
});
|
||||
|
||||
let percentage = create_memo(cx, move |_| {
|
||||
let percentage = create_memo(move |_| {
|
||||
if value.get() < 0.0 || max.get() <= 0.0 {
|
||||
0f64
|
||||
} else if value.get() >= max.get() {
|
||||
|
@ -38,9 +33,9 @@ pub fn Slider(
|
|||
value.set(val);
|
||||
};
|
||||
|
||||
let rail_ref = create_node_ref::<html::Div>(cx);
|
||||
let (mouse_move_value, set_mouse_move_value) = create_signal::<Option<f64>>(cx, None);
|
||||
let (is_mouse_move, set_mouse_move) = create_signal(cx, false);
|
||||
let rail_ref = create_node_ref::<html::Div>();
|
||||
let (mouse_move_value, set_mouse_move_value) = create_signal::<Option<f64>>(None);
|
||||
let (is_mouse_move, set_mouse_move) = create_signal(false);
|
||||
let on_mouse_down = move |_| {
|
||||
set_mouse_move.set(true);
|
||||
};
|
||||
|
@ -48,7 +43,7 @@ pub fn Slider(
|
|||
let on_mouse_up = window_event_listener(ev::mouseup, move |_| {
|
||||
set_mouse_move.set(false);
|
||||
});
|
||||
on_cleanup(cx, on_mouse_up);
|
||||
on_cleanup(move || on_mouse_up.remove());
|
||||
|
||||
let on_mouse_move = window_event_listener(ev::mousemove, move |ev| {
|
||||
if is_mouse_move.get_untracked() {
|
||||
|
@ -69,9 +64,9 @@ pub fn Slider(
|
|||
};
|
||||
}
|
||||
});
|
||||
on_cleanup(cx, on_mouse_move);
|
||||
on_cleanup(move || on_mouse_move.remove());
|
||||
|
||||
view! {cx, class=class_name,
|
||||
view! { class=class_name,
|
||||
<div class="melt-slider" style=move || css_vars.get()>
|
||||
<div class="melt-slider-rail" ref=rail_ref>
|
||||
<div class="melt-slider-rail__fill" style=move || format!("width: {}%", percentage.get())></div>
|
||||
|
|
|
@ -13,7 +13,7 @@ pub enum SpaceGap {
|
|||
}
|
||||
|
||||
#[component]
|
||||
pub fn Space(cx: Scope, #[prop(optional)] gap: SpaceGap, children: Children) -> impl IntoView {
|
||||
pub fn Space(#[prop(optional)] gap: SpaceGap, children: Children) -> impl IntoView {
|
||||
let class_name = mount_style("space", || style_sheet_str!("./src/space/space.css"));
|
||||
let gap = match gap {
|
||||
SpaceGap::SMALL => "gap: 4px 8px".into(),
|
||||
|
@ -24,12 +24,12 @@ pub fn Space(cx: Scope, #[prop(optional)] gap: SpaceGap, children: Children) ->
|
|||
};
|
||||
|
||||
view! {
|
||||
cx, class=class_name,
|
||||
class=class_name,
|
||||
<div class="melt-space" style=format!("{gap};")>
|
||||
{
|
||||
children(cx).nodes.into_iter().map(|node| {
|
||||
children().nodes.into_iter().map(|node| {
|
||||
view! {
|
||||
cx, class=class_name,
|
||||
class=class_name,
|
||||
<div class="melt-space__item">
|
||||
{node}
|
||||
</div>
|
||||
|
|
|
@ -3,11 +3,11 @@ use leptos::*;
|
|||
use stylers::style_sheet_str;
|
||||
|
||||
#[component]
|
||||
pub fn Table(cx: Scope, children: Children) -> impl IntoView {
|
||||
pub fn Table(children: Children) -> impl IntoView {
|
||||
let class_name = mount_style("table", || style_sheet_str!("./src/table/table.css"));
|
||||
view! {cx, class=class_name,
|
||||
view! { class=class_name,
|
||||
<table class="melt-table">
|
||||
{children(cx)}
|
||||
{children()}
|
||||
</table>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,18 +5,15 @@ use stylers::style_sheet_str;
|
|||
pub use tab::*;
|
||||
|
||||
#[component]
|
||||
pub fn Tabs(cx: Scope, active_key: RwSignal<&'static str>, children: Children) -> impl IntoView {
|
||||
pub fn Tabs(active_key: RwSignal<&'static str>, children: Children) -> impl IntoView {
|
||||
let class_name = mount_style("tabs", || style_sheet_str!("./src/tabs/tabs.css"));
|
||||
let tab_options_vec = create_rw_signal(cx, vec![]);
|
||||
provide_context(
|
||||
cx,
|
||||
TabsInjectionKey {
|
||||
active_key: active_key.clone(),
|
||||
tab_options_vec: tab_options_vec.clone(),
|
||||
},
|
||||
);
|
||||
let theme = use_theme(cx, Theme::light);
|
||||
let css_vars = create_memo(cx, move |_| {
|
||||
let tab_options_vec = create_rw_signal(vec![]);
|
||||
provide_context(TabsInjectionKey {
|
||||
active_key: active_key.clone(),
|
||||
tab_options_vec: tab_options_vec.clone(),
|
||||
});
|
||||
let theme = use_theme(Theme::light);
|
||||
let css_vars = create_memo(move |_| {
|
||||
let mut css_vars = String::new();
|
||||
let theme = theme.get();
|
||||
let color_primary = theme.common.color_primary.clone();
|
||||
|
@ -26,22 +23,22 @@ pub fn Tabs(cx: Scope, active_key: RwSignal<&'static str>, children: Children) -
|
|||
css_vars
|
||||
});
|
||||
|
||||
let label_line = create_rw_signal::<Option<TabsLabelLine>>(cx, None);
|
||||
let label_line_style = create_memo(cx, move |_| {
|
||||
let label_line = create_rw_signal::<Option<TabsLabelLine>>(None);
|
||||
let label_line_style = create_memo(move |_| {
|
||||
let mut style = String::new();
|
||||
if let Some(line) = label_line.get() {
|
||||
style.push_str(&format!("width: {}px; left: {}px", line.width, line.left))
|
||||
}
|
||||
style
|
||||
});
|
||||
let label_list_ref = create_node_ref::<html::Div>(cx);
|
||||
let label_list_ref = create_node_ref::<html::Div>();
|
||||
|
||||
view! { cx, class=class_name,
|
||||
view! { class=class_name,
|
||||
<div class="melt-tabs" style=move || css_vars.get()>
|
||||
<div class="melt-tabs__label-list" ref=label_list_ref>
|
||||
<For each=move || tab_options_vec.get() key=move |v| v.key.clone() view=move |cx, options| {
|
||||
let label_ref = create_node_ref::<html::Span>(cx);
|
||||
create_effect(cx, move |_| {
|
||||
<For each=move || tab_options_vec.get() key=move |v| v.key.clone() view=move | options| {
|
||||
let label_ref = create_node_ref::<html::Span>();
|
||||
create_effect( move |_| {
|
||||
let Some(label) = label_ref.get() else {
|
||||
return;
|
||||
};
|
||||
|
@ -59,7 +56,7 @@ pub fn Tabs(cx: Scope, active_key: RwSignal<&'static str>, children: Children) -
|
|||
});
|
||||
}
|
||||
});
|
||||
view! {cx, class=class_name,
|
||||
view! { class=class_name,
|
||||
<span class="melt-tabs__label" class=("melt-tabs__label--active", move || options.key == active_key.get())
|
||||
on:click=move |_| active_key.set(options.key)
|
||||
ref=label_ref
|
||||
|
@ -72,7 +69,7 @@ pub fn Tabs(cx: Scope, active_key: RwSignal<&'static str>, children: Children) -
|
|||
<span class="melt-tabs-label__line" style=move || label_line_style.get()></span>
|
||||
</div>
|
||||
<div>
|
||||
{ children(cx) }
|
||||
{ children() }
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
@ -102,6 +99,6 @@ impl TabsInjectionKey {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn use_tabs(cx: Scope) -> TabsInjectionKey {
|
||||
use_context::<TabsInjectionKey>(cx).expect("TabsInjectionKey not exist")
|
||||
pub fn use_tabs() -> TabsInjectionKey {
|
||||
use_context::<TabsInjectionKey>().expect("TabsInjectionKey not exist")
|
||||
}
|
||||
|
|
|
@ -10,13 +10,13 @@ pub(crate) struct TabOptions {
|
|||
}
|
||||
|
||||
#[component]
|
||||
pub fn Tab(cx: Scope, key: &'static str, label: &'static str, children: Children) -> impl IntoView {
|
||||
pub fn Tab(key: &'static str, label: &'static str, children: Children) -> impl IntoView {
|
||||
let class_name = mount_style("tab", || style_sheet_str!("./src/tabs/tab.css"));
|
||||
let tabs = use_tabs(cx);
|
||||
let tabs = use_tabs();
|
||||
tabs.push_tab_options(TabOptions { key, label });
|
||||
view! { cx, class=class_name,
|
||||
view! { class=class_name,
|
||||
<div class="melt-tab" class=("melt-tab--hidden", move || key != tabs.get_key()) >
|
||||
{ children(cx) }
|
||||
{ children() }
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,11 +3,7 @@ use web_sys::Element;
|
|||
|
||||
/// https://github.com/solidjs/solid/blob/main/packages/solid/web/src/index.ts#L56
|
||||
#[component]
|
||||
pub fn Teleport(
|
||||
cx: Scope,
|
||||
#[prop(optional)] to: Option<&'static str>,
|
||||
children: Children,
|
||||
) -> impl IntoView {
|
||||
pub fn Teleport(#[prop(optional)] to: Option<&'static str>, children: Children) -> impl IntoView {
|
||||
let parent = if let Some(to) = to {
|
||||
document()
|
||||
.query_selector(to)
|
||||
|
@ -20,16 +16,15 @@ pub fn Teleport(
|
|||
#[cfg(all(target_arch = "wasm32"))]
|
||||
{
|
||||
use leptos_dom::Mountable;
|
||||
let node = children(cx).into_view(cx);
|
||||
let node = children().into_view();
|
||||
parent.append_child(&node.get_mountable_node()).unwrap();
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
_ = cx;
|
||||
_ = parent;
|
||||
_ = children;
|
||||
}
|
||||
|
||||
view! { cx, <></> }
|
||||
view! { <></> }
|
||||
}
|
||||
|
|
|
@ -31,24 +31,20 @@ impl CommonTheme {
|
|||
fn common() -> Self {
|
||||
Self {
|
||||
font_family: "-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,'Noto Sans',sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol','Noto Color Emoji'".into(),
|
||||
|
||||
color_primary: "".into(),
|
||||
color_success: "".into(),
|
||||
color_warning: "".into(),
|
||||
color_error: "".into(),
|
||||
|
||||
font_size: "14px".into(),
|
||||
font_size_small: "12px".into(),
|
||||
font_size_medium: "16px".into(),
|
||||
font_size_large: "20px".into(),
|
||||
font_size_huge: "24px".into(),
|
||||
|
||||
line_height: "22px".into(),
|
||||
line_height_small: "20px".into(),
|
||||
line_height_medium: "24px".into(),
|
||||
line_height_large: "28px".into(),
|
||||
line_height_huge: "32px".into(),
|
||||
|
||||
border_radius: "3px".into(),
|
||||
border_radius_small: "2px".into(),
|
||||
border_radius_medium: "4px".into(),
|
||||
|
|
|
@ -50,16 +50,15 @@ impl ThemeMethod for Theme {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn use_theme(cx: Scope, default: impl Fn() -> Theme) -> ReadSignal<Theme> {
|
||||
use_context::<ReadSignal<Theme>>(cx).unwrap_or_else(|| create_signal(cx, default()).0)
|
||||
pub fn use_theme(default: impl Fn() -> Theme) -> ReadSignal<Theme> {
|
||||
use_context::<ReadSignal<Theme>>().unwrap_or_else(|| create_signal(default()).0)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{use_theme, Theme};
|
||||
use leptos::*;
|
||||
|
||||
fn _t_use_theme(cx: Scope) {
|
||||
use_theme(cx, Theme::dark);
|
||||
fn _t_use_theme() {
|
||||
use_theme(Theme::dark);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
use leptos::window;
|
||||
use leptos_dom::ev;
|
||||
use std::borrow::Cow;
|
||||
use wasm_bindgen::{prelude::Closure, JsCast};
|
||||
|
||||
pub fn window_event_listener<E: ev::EventDescriptor + 'static>(
|
||||
event: E,
|
||||
cb: impl Fn(E::EventType) + 'static,
|
||||
) -> impl FnOnce() -> ()
|
||||
where
|
||||
E::EventType: JsCast,
|
||||
{
|
||||
fn wel(
|
||||
cb: Box<dyn FnMut(web_sys::Event)>,
|
||||
event_name: Cow<'static, str>,
|
||||
) -> impl FnOnce() -> () + 'static {
|
||||
let cb = Closure::wrap(cb).into_js_value();
|
||||
_ = window().add_event_listener_with_callback(&event_name, cb.unchecked_ref());
|
||||
move || {
|
||||
_ = window().remove_event_listener_with_callback(&event_name, cb.unchecked_ref());
|
||||
}
|
||||
}
|
||||
|
||||
wel(
|
||||
Box::new(move |e| cb(e.unchecked_into::<E::EventType>())),
|
||||
event.name(),
|
||||
)
|
||||
}
|
|
@ -1,2 +1 @@
|
|||
pub(crate) mod mount_style;
|
||||
pub mod dom;
|
||||
|
|
|
@ -3,13 +3,13 @@ use leptos::*;
|
|||
use stylers::style_sheet_str;
|
||||
|
||||
#[component]
|
||||
pub fn Wave(cx: Scope, children: Children) -> impl IntoView {
|
||||
pub fn Wave(children: Children) -> impl IntoView {
|
||||
let class_name = mount_style("wave", || style_sheet_str!("./src/wave/wave.css"));
|
||||
let (css_vars, set_css_vars) = create_signal(cx, String::new());
|
||||
let wave_ref = create_node_ref::<html::Div>(cx);
|
||||
wave_ref.on_load(cx, move |wave| {
|
||||
let (css_vars, set_css_vars) = create_signal(String::new());
|
||||
let wave_ref = create_node_ref::<html::Div>();
|
||||
wave_ref.on_load(move |wave| {
|
||||
wave.on(ev::mousedown, move |ev| {
|
||||
wave_ref.on_load(cx, move |wave| {
|
||||
wave_ref.on_load(move |wave| {
|
||||
let rect = wave.get_bounding_client_rect();
|
||||
let client_x = f64::from(ev.client_x());
|
||||
let client_y = f64::from(ev.client_y());
|
||||
|
@ -22,9 +22,9 @@ pub fn Wave(cx: Scope, children: Children) -> impl IntoView {
|
|||
});
|
||||
});
|
||||
view! {
|
||||
cx, class=class_name,
|
||||
class=class_name,
|
||||
<div class="melt-wave" ref=wave_ref style=move || css_vars.get()>
|
||||
{ children(cx) }
|
||||
{ children() }
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue