feat: icon componen

This commit is contained in:
luoxiao 2023-10-18 23:49:27 +08:00
parent 28956cf732
commit 92165edebf
7 changed files with 104 additions and 57 deletions

View file

@ -16,7 +16,7 @@ license = "MIT"
leptos = { version = "0.5.1", features = ["csr"] } leptos = { version = "0.5.1", features = ["csr"] }
web-sys = { version = "0.3.62", features = ["DomRect"] } web-sys = { version = "0.3.62", features = ["DomRect"] }
wasm-bindgen = "0.2.85" wasm-bindgen = "0.2.85"
icondata = { version = "0.0.7", features = [ icondata = { version = "0.1.0", features = [
"AiCloseOutlined", "AiCloseOutlined",
"AiCheckOutlined", "AiCheckOutlined",
"AiLeftOutlined", "AiLeftOutlined",
@ -28,6 +28,7 @@ icondata = { version = "0.0.7", features = [
"AiPlusOutlined", "AiPlusOutlined",
"AiMinusOutlined", "AiMinusOutlined",
] } ] }
icondata_core = "0.0.2"
[workspace] [workspace]
members = ["demo"] members = ["demo"]

View file

@ -9,7 +9,7 @@ edition = "2021"
[dependencies] [dependencies]
leptos = { version = "0.5.1", features = ["csr"] } leptos = { version = "0.5.1", features = ["csr"] }
melt-ui = { path = "../" } melt-ui = { path = "../" }
icondata = { version = "0.0.7", features = [ icondata = { version = "0.1.0", features = [
"AiCloseOutlined", "AiCloseOutlined",
"AiCheckOutlined", "AiCheckOutlined",
] } ] }

View file

@ -32,6 +32,7 @@ pub fn App() -> impl IntoView {
<Route path="/card" view=CardPage/> <Route path="/card" view=CardPage/>
<Route path="/divider" view=DividerPage/> <Route path="/divider" view=DividerPage/>
<Route path="/input-number" view=InputNumberPage/> <Route path="/input-number" view=InputNumberPage/>
<Route path="/icon" view=IconPage/>
</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

@ -96,6 +96,10 @@ fn gen_menu_data() -> Vec<MenuGroupOption> {
value: "divider".into(), value: "divider".into(),
label: "Divider".into(), label: "Divider".into(),
}, },
MenuItemOption {
value: "icon".into(),
label: "Icon".into(),
},
], ],
}, },
MenuGroupOption { MenuGroupOption {

View file

@ -0,0 +1,34 @@
use crate::components::{Demo, DemoCode};
use leptos::*;
use melt_ui::*;
use prisms::highlight_str;
#[component]
pub fn IconPage() -> impl IntoView {
view! {
<div style="width: 896px; margin: 0 auto;">
<h1>"Icon"</h1>
<Demo>
<Space>
<Icon icon=icondata::Icon::from(icondata::AiIcon::AiCloseOutlined) />
<Icon icon=icondata::Icon::from(icondata::AiIcon::AiCheckOutlined) />
</Space>
<DemoCode
slot
html=highlight_str!(
r#"
<Space>
<Icon icon=icondata::Icon::from(icondata::AiIcon::AiCloseOutlined) />
<Icon icon=icondata::Icon::from(icondata::AiIcon::AiCheckOutlined) />
</Space>
"#,
"rust"
)
>
""
</DemoCode>
</Demo>
</div>
}
}

View file

@ -10,6 +10,7 @@ mod components;
mod divider; mod divider;
mod grid; mod grid;
mod home; mod home;
mod icon;
mod image; mod image;
mod input; mod input;
mod input_number; mod input_number;
@ -37,6 +38,7 @@ pub use components::*;
pub use divider::*; pub use divider::*;
pub use grid::*; pub use grid::*;
pub use home::*; pub use home::*;
pub use icon::*;
pub use image::*; pub use image::*;
pub use input::*; pub use input::*;
pub use input_number::*; pub use input_number::*;

View file

@ -22,61 +22,66 @@ pub fn Icon(
#[prop(into, optional)] #[prop(into, optional)]
style: Option<MaybeSignal<String>>, style: Option<MaybeSignal<String>>,
) -> impl IntoView { ) -> impl IntoView {
let icon: IconData = icon.get().into(); let icon = move || icondata_core::IconData::from(icon.get());
let mut svg = svg::svg(); let svg = move || {
if let Some(classes) = class { let icon = icon();
svg = svg.classes(classes.get()); let mut svg = svg::svg();
} if let Some(classes) = class.clone() {
// The style set by the user overrides the style set by the icon. svg = svg.classes(classes.get());
svg = match (style, icon.style) { }
(Some(a), Some(b)) => svg.attr("style", format!("{b} {}", a.get())), let mut svg = match (style.clone(), icon.style) {
(Some(a), None) => svg.attr("style", a.get()), (Some(a), Some(b)) => svg.attr("style", format!("{b} {}", a.get())),
(None, Some(b)) => svg.attr("style", b), (Some(a), None) => svg.attr("style", a.get()),
(None, None) => svg, (None, Some(b)) => svg.attr("style", b),
(None, None) => svg,
};
if let Some(x) = icon.x {
svg = svg.attr("x", x);
}
if let Some(y) = icon.y {
svg = svg.attr("x", y);
}
//// The style set by the user overrides the style set by the icon.
// We ignore the width and height attributes of the icon, even if the user hasn't specified any.
svg = svg.attr(
"width",
Attribute::String(match (width.clone(), 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",
Attribute::String(match (height.clone(), 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 {
svg = svg.attr("viewBox", view_box);
}
if let Some(stroke_linecap) = icon.stroke_linecap {
svg = svg.attr("stroke-linecap", stroke_linecap);
}
if let Some(stroke_linejoin) = icon.stroke_linejoin {
svg = svg.attr("stroke-linejoin", stroke_linejoin);
}
if let Some(stroke_width) = icon.stroke_width {
svg = svg.attr("stroke-width", stroke_width);
}
if let Some(stroke) = icon.stroke {
svg = svg.attr("stroke", stroke);
}
svg = svg.attr("fill", icon.fill.unwrap_or("currentColor"));
svg = svg.attr("role", "graphics-symbol");
svg = svg.inner_html(icon.data);
svg
}; };
if let Some(x) = icon.x { svg.into_view()
svg = svg.attr("x", x);
}
if let Some(y) = icon.y {
svg = svg.attr("x", y);
}
// We ignore the width and height attributes of the icon, even if the user hasn't specified any.
svg = svg.attr(
"width",
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",
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 {
svg = svg.attr("viewBox", view_box);
}
if let Some(stroke_linecap) = icon.stroke_linecap {
svg = svg.attr("stroke-linecap", stroke_linecap);
}
if let Some(stroke_linejoin) = icon.stroke_linejoin {
svg = svg.attr("stroke-linejoin", stroke_linejoin);
}
if let Some(stroke_width) = icon.stroke_width {
svg = svg.attr("stroke-width", stroke_width);
}
if let Some(stroke) = icon.stroke {
svg = svg.attr("stroke", stroke);
}
svg = svg.attr("fill", icon.fill.unwrap_or("currentColor"));
svg = svg.attr("role", "graphics-symbol");
svg = svg.inner_html(icon.data);
IntoView::into_view(svg)
} }