mirror of
https://github.com/adoyle0/thaw.git
synced 2025-01-22 22:09:22 -05:00
✨ feat: add menu component
This commit is contained in:
parent
571191fb4f
commit
a9e82e994e
7 changed files with 118 additions and 1 deletions
|
@ -10,6 +10,9 @@ pub fn App(cx: Scope) -> impl IntoView {
|
|||
<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 />
|
||||
} />
|
||||
|
|
13
examples/basic/src/pages/menu/mod.rs
Normal file
13
examples/basic/src/pages/menu/mod.rs
Normal file
|
@ -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,
|
||||
<Menu selected>
|
||||
<MenuItem key="a" label="and"/>
|
||||
<MenuItem key="o" label="or"/>
|
||||
</Menu>
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
mod home;
|
||||
mod menu;
|
||||
mod slider;
|
||||
|
||||
pub use home::*;
|
||||
pub use slider::*;
|
||||
pub use menu::*;
|
||||
pub use slider::*;
|
||||
|
|
|
@ -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::*;
|
||||
|
|
16
src/menu/menu-item.css
Normal file
16
src/menu/menu-item.css
Normal file
|
@ -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);
|
||||
}
|
36
src/menu/menu_item.rs
Normal file
36
src/menu/menu_item.rs
Normal file
|
@ -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<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 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,
|
||||
<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() }
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
45
src/menu/mod.rs
Normal file
45
src/menu/mod.rs
Normal file
|
@ -0,0 +1,45 @@
|
|||
mod menu_item;
|
||||
|
||||
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));
|
||||
provide_context(cx, menu_injection_key);
|
||||
view! {cx,
|
||||
<div class="melt-menu">
|
||||
{ children(cx) }
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct MenuInjectionKey {
|
||||
value: RwSignal<String>,
|
||||
}
|
||||
|
||||
|
||||
impl MenuInjectionKey {
|
||||
pub fn new(value: RwSignal<String>) -> 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<MenuInjectionKey> {
|
||||
use_context::<RwSignal<MenuInjectionKey>>(cx).expect("MenuInjectionKey not exist")
|
||||
}
|
Loading…
Add table
Reference in a new issue