Merge branch 'main' of github.com:luoxiaozero/melt-ui

This commit is contained in:
luoxiao 2023-10-20 11:20:23 +08:00
commit 95edd0d4e2
11 changed files with 226 additions and 1 deletions

View file

@ -36,6 +36,7 @@ pub fn App() -> impl IntoView {
<Route path="/input-number" view=InputNumberPage/> <Route path="/input-number" view=InputNumberPage/>
<Route path="/icon" view=IconPage/> <Route path="/icon" view=IconPage/>
<Route path="/message" view=MessagePage/> <Route path="/message" view=MessagePage/>
<Route path="/radio" view=RadioPage/>
</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

@ -125,6 +125,10 @@ fn gen_menu_data() -> Vec<MenuGroupOption> {
value: "input-number".into(), value: "input-number".into(),
label: "InputNumber".into(), label: "InputNumber".into(),
}, },
MenuItemOption {
value: "radio".into(),
label: "Radio".into(),
},
MenuItemOption { MenuItemOption {
value: "select".into(), value: "select".into(),
label: "Select".into(), label: "Select".into(),

View file

@ -19,6 +19,7 @@ mod message;
mod mobile; mod mobile;
mod modal; mod modal;
mod nav_bar; mod nav_bar;
mod radio;
mod select; mod select;
mod slider; mod slider;
mod space; mod space;
@ -48,6 +49,7 @@ pub use message::*;
pub use mobile::*; pub use mobile::*;
pub use modal::*; pub use modal::*;
pub use nav_bar::*; pub use nav_bar::*;
pub use radio::*;
pub use select::*; pub use select::*;
pub use slider::*; pub use slider::*;
pub use space::*; pub use space::*;

View file

@ -0,0 +1,35 @@
use crate::components::{Demo, DemoCode};
use leptos::*;
use melt_ui::*;
use prisms::highlight_str;
#[component]
pub fn RadioPage() -> impl IntoView {
let checked = create_rw_signal(false);
view! {
<div style="width: 896px; margin: 0 auto;">
<h1>"Radio"</h1>
<Demo>
<Radio value=checked>"Click"</Radio>
<DemoCode
slot
html=highlight_str!(
r#"
let value = create_rw_signal(false);
view! {
<Radio value>
"Click"
</Radio>
}
"#,
"rust"
)
>
""
</DemoCode>
</Demo>
</div>
}
}

View file

@ -20,7 +20,9 @@ mod message;
pub mod mobile; pub mod mobile;
mod modal; mod modal;
mod progress; mod progress;
mod radio;
mod select; mod select;
mod skeleton;
mod slider; mod slider;
mod space; mod space;
mod switch; mod switch;
@ -51,7 +53,9 @@ pub use menu::*;
pub use message::*; pub use message::*;
pub use modal::*; pub use modal::*;
pub use progress::*; pub use progress::*;
pub use radio::*;
pub use select::*; pub use select::*;
pub use skeleton::*;
pub use slider::*; pub use slider::*;
pub use space::*; pub use space::*;
pub use switch::*; pub use switch::*;

38
src/radio/mod.rs Normal file
View file

@ -0,0 +1,38 @@
use crate::{
theme::use_theme,
utils::{maybe_rw_signal::MaybeRwSignal, mount_style::mount_style},
Theme,
};
use leptos::*;
#[component]
pub fn Radio(
#[prop(optional, into)] value: MaybeRwSignal<bool>,
children: Children,
) -> impl IntoView {
let theme = use_theme(Theme::light);
mount_style("radio", include_str!("./radio.css"));
let css_vars = create_memo(move |_| {
let mut css_vars = String::new();
theme.with(|theme| {
let bg_color = theme.common.color_primary.clone();
css_vars.push_str(&format!("--background-color-checked: {bg_color};"));
});
css_vars
});
view! {
<div
class="melt-radio"
class=("melt-radio--checked", move || value.get())
style=move || css_vars.get()
on:click=move |_| value.set(!value.get_untracked())
>
<input class="melt-radio__input" type="radio" prop:value=move || value.get()/>
<div class="melt-radio__dot"></div>
<div class="melt-radio__label">{children()}</div>
</div>
}
}

42
src/radio/radio.css Normal file
View file

@ -0,0 +1,42 @@
.melt-radio {
display: inline-flex;
align-items: center;
cursor: pointer;
}
.melt-radio__input {
width: 0;
height: 0;
opacity: 0;
}
.melt-radio__dot {
display: inline-block;
position: relative;
width: 14px;
height: 14px;
border: 1px solid #ddd;
border-radius: 50%;
}
.melt-radio:hover .melt-radio__dot,
.melt-radio--checked .melt-radio__dot {
border-color: var(--background-color-checked);
}
.melt-radio--checked .melt-radio__dot::before {
content: "";
position: absolute;
top: 3px;
bottom: 3px;
left: 3px;
right: 3px;
background-color: var(--background-color-checked);
border-radius: 50%;
}
.melt-radio__label {
display: inline-block;
padding: 0 6px;
user-select: none;
}

47
src/skeleton/mod.rs Normal file
View file

@ -0,0 +1,47 @@
mod theme;
use crate::{theme::use_theme, Theme};
use leptos::*;
pub use theme::SkeletionTheme;
#[component]
pub fn Skeleton(
#[prop(default = MaybeSignal::Static(1), into)] repeat: MaybeSignal<u32>,
#[prop(optional, into)] text: MaybeSignal<bool>,
#[prop(optional, into)] width: Option<MaybeSignal<String>>,
#[prop(optional, into)] height: Option<MaybeSignal<String>>,
) -> impl IntoView {
let theme = use_theme(Theme::light);
let css_vars = create_memo(move |_| {
let mut css_vars = String::new();
if text.get() {
css_vars.push_str("display: inline-block;");
}
if let Some(width) = width.as_ref() {
css_vars.push_str(&format!("width: {};", width.get()));
}
if let Some(height) = height.as_ref() {
css_vars.push_str(&format!("height: {};", height.get()));
}
theme.with(|theme| {
css_vars.push_str(&format!(
"--background-color-start: {};",
theme.skeletion.background_color_start
));
css_vars.push_str(&format!(
"--background-color-end: {};",
theme.skeletion.background_color_end
));
});
css_vars
});
(0..repeat.get())
.into_iter()
.map(|_| {
view! { <div class="melt-skeleton" style=move || css_vars.get()></div> }
})
.collect_view()
}

24
src/skeleton/skeleton.css vendored Normal file
View file

@ -0,0 +1,24 @@
.melt-skeleton {
width: 100%;
height: 1em;
background-color: var(--background-color-start);
background: linear-gradient(
90deg,
var(--background-color-start) 25%,
var(--background-color-end) 37%,
var(--background-color-start) 63%
);
animation: meltSkeletonLoading 1.4s ease infinite;
background-size: 400% 100%;
}
@keyframes meltSkeletonLoading {
from {
background-position: 100% 50%;
}
to {
background-position: 0 50%;
}
}

23
src/skeleton/theme.rs Normal file
View file

@ -0,0 +1,23 @@
use crate::theme::ThemeMethod;
#[derive(Clone)]
pub struct SkeletionTheme {
pub background_color_start: String,
pub background_color_end: String,
}
impl ThemeMethod for SkeletionTheme {
fn light() -> Self {
Self {
background_color_start: "#f2f2f2".into(),
background_color_end: "#e6e6e6".into(),
}
}
fn dark() -> Self {
Self {
background_color_start: "rgba(255, 255, 255, 0.12)".into(),
background_color_end: "rgba(255, 255, 255, 0.18)".into(),
}
}
}

View file

@ -2,7 +2,7 @@ mod common;
use leptos::*; use leptos::*;
use self::common::CommonTheme; use self::common::CommonTheme;
use crate::{AlertTheme, ButtonTheme, InputTheme, MenuTheme, TableTheme}; use crate::{AlertTheme, ButtonTheme, InputTheme, MenuTheme, SkeletionTheme, TableTheme};
pub trait ThemeMethod { pub trait ThemeMethod {
fn light() -> Self; fn light() -> Self;
@ -17,6 +17,7 @@ pub struct Theme {
pub menu: MenuTheme, pub menu: MenuTheme,
pub table: TableTheme, pub table: TableTheme,
pub alert: AlertTheme, pub alert: AlertTheme,
pub skeletion: SkeletionTheme,
} }
impl Theme { impl Theme {
@ -28,6 +29,7 @@ impl Theme {
menu: MenuTheme::light(), menu: MenuTheme::light(),
table: TableTheme::light(), table: TableTheme::light(),
alert: AlertTheme::light(), alert: AlertTheme::light(),
skeletion: SkeletionTheme::light(),
} }
} }
pub fn dark() -> Self { pub fn dark() -> Self {
@ -38,6 +40,7 @@ impl Theme {
menu: MenuTheme::dark(), menu: MenuTheme::dark(),
table: TableTheme::dark(), table: TableTheme::dark(),
alert: AlertTheme::dark(), alert: AlertTheme::dark(),
skeletion: SkeletionTheme::dark(),
} }
} }
} }
@ -51,6 +54,7 @@ impl ThemeMethod for Theme {
menu: MenuTheme::light(), menu: MenuTheme::light(),
table: TableTheme::light(), table: TableTheme::light(),
alert: AlertTheme::light(), alert: AlertTheme::light(),
skeletion: SkeletionTheme::light(),
} }
} }
fn dark() -> Self { fn dark() -> Self {
@ -61,6 +65,7 @@ impl ThemeMethod for Theme {
menu: MenuTheme::dark(), menu: MenuTheme::dark(),
table: TableTheme::dark(), table: TableTheme::dark(),
alert: AlertTheme::dark(), alert: AlertTheme::dark(),
skeletion: SkeletionTheme::dark(),
} }
} }
} }