diff --git a/examples/basic/src/app.rs b/examples/basic/src/app.rs index 147ae9a..0e5e748 100644 --- a/examples/basic/src/app.rs +++ b/examples/basic/src/app.rs @@ -10,6 +10,9 @@ pub fn App(cx: Scope) -> impl IntoView { } /> + + } /> } /> diff --git a/examples/basic/src/pages/menu/mod.rs b/examples/basic/src/pages/menu/mod.rs new file mode 100644 index 0000000..9a8a7e2 --- /dev/null +++ b/examples/basic/src/pages/menu/mod.rs @@ -0,0 +1,13 @@ +use leptos::*; +use melt_ui::*; + +#[component] +pub fn MenuPage(cx: Scope) -> impl IntoView { + let selected = create_rw_signal(cx, String::from("o")); + view! { cx, + + + + + } +} diff --git a/examples/basic/src/pages/mod.rs b/examples/basic/src/pages/mod.rs index dbabfb0..39db5b8 100644 --- a/examples/basic/src/pages/mod.rs +++ b/examples/basic/src/pages/mod.rs @@ -1,5 +1,7 @@ mod home; +mod menu; mod slider; pub use home::*; -pub use slider::*; \ No newline at end of file +pub use menu::*; +pub use slider::*; diff --git a/src/lib.rs b/src/lib.rs index ec538d4..4bc7f4a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,7 @@ mod card; mod checkbox; mod components; mod input; +mod menu; mod modal; mod progress; mod slider; @@ -16,6 +17,7 @@ mod wave; pub use button::*; pub use checkbox::*; pub use input::*; +pub use menu::*; pub use modal::*; pub use progress::*; pub use slider::*; diff --git a/src/menu/menu-item.css b/src/menu/menu-item.css new file mode 100644 index 0000000..0df4feb --- /dev/null +++ b/src/menu/menu-item.css @@ -0,0 +1,16 @@ +.melt-menu-item__content { + margin: 6px 8px; + padding: 12px 10px; + padding-left: 14px; + cursor: pointer; + border-radius: var(--border-radius); +} + +.melt-menu-item__content:hover { + color: var(--font-color); +} + +.melt-menu-item__content--selected { + color: var(--font-color); + background-color: var(--bg-color); +} diff --git a/src/menu/menu_item.rs b/src/menu/menu_item.rs new file mode 100644 index 0000000..84735a2 --- /dev/null +++ b/src/menu/menu_item.rs @@ -0,0 +1,36 @@ +use super::{use_menu, MenuInjectionKey}; +use crate::{theme::use_theme, utils::mount_style::mount_style, Theme}; +use leptos::*; +use stylers::style_sheet_str; + +#[component] +pub fn MenuItem( + cx: Scope, + #[prop(into)] key: MaybeSignal<&'static str>, + #[prop(into)] label: MaybeSignal, +) -> 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 onclick_select = move |_| { + menu.set(MenuInjectionKey::from_string(cx, key.get().to_string())); + }; + + let css_vars = create_memo(cx, move |_| { + let mut css_vars = String::new(); + let theme = theme.get(); + let font_color = theme.common.color_primary.clone(); + css_vars.push_str(&format!("--font-color: {font_color};")); + css_vars.push_str(&format!("--bg-color: {font_color}1a;")); + let border_radius = theme.common.border_radius.clone(); + css_vars.push_str(&format!("--border-radius: {border_radius};")); + css_vars + }); + view! {cx, class=class_name, +
+
+ { move || label.get() } +
+
+ } +} diff --git a/src/menu/mod.rs b/src/menu/mod.rs new file mode 100644 index 0000000..e0f77f6 --- /dev/null +++ b/src/menu/mod.rs @@ -0,0 +1,45 @@ +mod menu_item; + +use leptos::*; +pub use menu_item::*; + +#[component] +pub fn Menu( + cx: Scope, + #[prop(into)] selected: RwSignal, + children: Children, +) -> impl IntoView { + let menu_injection_key = create_rw_signal(cx, MenuInjectionKey::new(selected)); + provide_context(cx, menu_injection_key); + view! {cx, +
+ { children(cx) } +
+ } +} + +#[derive(Clone)] +pub struct MenuInjectionKey { + value: RwSignal, +} + + +impl MenuInjectionKey { + pub fn new(value: RwSignal) -> Self { + Self { value } + } + + pub fn from_string(cx: Scope, value: String) -> Self { + Self { + value: create_rw_signal(cx, value), + } + } + + pub fn value(&self) -> String { + self.value.get() + } +} + +pub fn use_menu(cx: Scope) -> RwSignal { + use_context::>(cx).expect("MenuInjectionKey not exist") +}