feat: nav

This commit is contained in:
luoxiao 2024-05-11 15:53:37 +08:00
parent 7219c0cb93
commit 6d42248e76
11 changed files with 160 additions and 18 deletions

View file

@ -161,13 +161,13 @@ pub fn SiteHeader() -> impl IntoView {
<Menu value=menu_value> <Menu value=menu_value>
<MenuItem key=theme_name label=theme_name /> <MenuItem key=theme_name label=theme_name />
<MenuItem key="github" label="Github" /> <MenuItem key="github" label="Github" />
{ // {
use crate::pages::{gen_guide_menu_data, gen_menu_data}; // use crate::pages::{gen_guide_menu_data, gen_menu_data};
vec![ // vec![
gen_guide_menu_data().into_view(), // gen_guide_menu_data().into_view(),
gen_menu_data().into_view(), // gen_menu_data().into_view(),
] // ]
} // }
</Menu> </Menu>
</div> </div>
</Popover> </Popover>

View file

@ -59,11 +59,11 @@ pub fn ComponentsPage() -> impl IntoView {
<SiteHeader/> <SiteHeader/>
<Layout has_sider=true position=LayoutPosition::Absolute style="top: 64px;"> <Layout has_sider=true position=LayoutPosition::Absolute style="top: 64px;">
<LayoutSider class="demo-components__sider"> <LayoutSider class="demo-components__sider">
<Menu value=select_name> <NavDrawer selected_value=select_name>
{gen_menu_data().into_view()} {gen_menu_data().into_view()}
</Menu> </NavDrawer>
</LayoutSider> </LayoutSider>
<Layout content_style="padding: 8px 12px 28px; display: flex;" class="doc-content"> <Layout content_style="padding: 8px 12px 28px; display: flex;" class="doc-content">
<Outlet/> <Outlet/>
@ -81,15 +81,13 @@ pub(crate) struct MenuGroupOption {
impl IntoView for MenuGroupOption { impl IntoView for MenuGroupOption {
fn into_view(self) -> View { fn into_view(self) -> View {
let Self { label, children } = self; let Self { label, children } = self;
let children_len = children.len();
view! { view! {
<MenuGroup label=format!( <Text>
"{label} ({})", children.len() {format!("{label} ({children_len})")}
)> </Text>
{children.into_iter().map(|v| v.into_view()).collect_view()}
{children.into_iter().map(|v| v.into_view()).collect_view()} }.into_view()
</MenuGroup>
}
} }
} }
@ -101,7 +99,8 @@ pub(crate) struct MenuItemOption {
impl IntoView for MenuItemOption { impl IntoView for MenuItemOption {
fn into_view(self) -> View { fn into_view(self) -> View {
let Self { label, value } = self; let Self { label, value } = self;
view! { <MenuItem key=value label/> } // key=value label
view! { <NavItem value>{label}</NavItem> }
} }
} }

View file

@ -3,6 +3,7 @@
} }
.thaw-layout--absolute-positioned { .thaw-layout--absolute-positioned {
background-color: inherit;
position: absolute; position: absolute;
top: 0; top: 0;
right: 0; right: 0;

View file

@ -27,6 +27,7 @@ mod menu;
mod message; mod message;
pub mod mobile; pub mod mobile;
mod modal; mod modal;
mod nav;
mod popover; mod popover;
mod progress; mod progress;
mod radio; mod radio;
@ -40,6 +41,7 @@ mod switch;
mod table; mod table;
mod tabs; mod tabs;
mod tag; mod tag;
mod text;
mod theme; mod theme;
mod time_picker; mod time_picker;
mod typography; mod typography;
@ -73,6 +75,7 @@ pub use loading_bar::*;
pub use menu::*; pub use menu::*;
pub use message::*; pub use message::*;
pub use modal::*; pub use modal::*;
pub use nav::*;
pub use popover::*; pub use popover::*;
pub use progress::*; pub use progress::*;
pub use radio::*; pub use radio::*;

5
thaw/src/nav/mod.rs Normal file
View file

@ -0,0 +1,5 @@
mod nav_drawer;
mod nav_item;
pub use nav_drawer::*;
pub use nav_item::*;

View file

@ -0,0 +1,61 @@
.thaw-nav-drawer {
overflow: hidden;
width: 260px;
max-width: 100vw;
height: auto;
/* max-height: 100vh; */
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
background-color: var(--colorNeutralBackground1);
color: var(--colorNeutralForeground1);
position: relative;
}
.thaw-nav-drawer__body {
padding: 0 var(--spacingVerticalMNudge);
flex: 1 1 0%;
align-self: stretch;
position: relative;
z-index: 1;
/* overflow: auto; */
}
.thaw-nav-item {
display: flex;
text-transform: none;
position: relative;
justify-content: start;
gap: var(--spacingVerticalL);
padding: var(--spacingVerticalMNudge);
/* background-color: var(--colorNeutralBackground4); */
border-radius: var(--borderRadiusMedium);
color: var(--colorNeutralForeground2);
text-decoration-line: none;
border: none;
font-family: var(--fontFamilyBase);
font-size: var(--fontSizeBase300);
font-weight: var(--fontWeightRegular);
line-height: var(--lineHeightBase300);
cursor: pointer;
}
.thaw-nav-item:hover {
background-color: var(--colorNeutralBackground4Hover);
}
.thaw-nav-item:active {
background-color: var(--colorNeutralBackground4Pressed);
}
.thaw-nav-item--selected::after {
content: "";
position: absolute;
width: 4px;
height: 20px;
background-color: var(--colorNeutralForeground2BrandSelected);
border-radius: var(--borderRadiusCircular);
margin-inline-start: -18px;
}

View file

@ -0,0 +1,27 @@
use leptos::*;
use thaw_utils::{mount_style, Model};
#[component]
pub fn NavDrawer(
#[prop(optional, into)] selected_value: Model<String>,
children: Children,
) -> impl IntoView {
mount_style("nav-drawer", include_str!("./nav-drawer.css"));
view! {
<Provider value=NavDrawerInjection(selected_value)>
<div class="thaw-nav-drawer">
<div class="thaw-nav-drawer__body">
{children()}
</div>
</div>
</Provider>
}
}
#[derive(Clone)]
pub(crate) struct NavDrawerInjection(pub Model<String>);
pub(crate) fn use_nav_drawer() -> NavDrawerInjection {
expect_context()
}

24
thaw/src/nav/nav_item.rs Normal file
View file

@ -0,0 +1,24 @@
use leptos::*;
use crate::use_nav_drawer;
use thaw_utils::{class_list, StoredMaybeSignal};
#[component]
pub fn NavItem(#[prop(into)] value: MaybeSignal<String>, children: Children) -> impl IntoView {
let nav_drawer = use_nav_drawer();
let value: StoredMaybeSignal<_> = value.into();
let on_click = move |_| {
let value = value.get();
if nav_drawer.0.with(|key| key != &value) {
nav_drawer.0.set(value);
}
};
view! {
<a class=class_list!["thaw-nav-item", ("thaw-nav-item--selected", move || nav_drawer.0.get() == value.get())]
role="nav"
type="navigation"
on:click=on_click
>
{children()}
</a>
}
}

6
thaw/src/text/mod.rs Normal file
View file

@ -0,0 +1,6 @@
use leptos::*;
pub fn Caption1Strong() {
}

View file

@ -6,6 +6,9 @@ pub struct ColorTheme {
pub color_neutral_background_1: String, pub color_neutral_background_1: String,
pub color_neutral_background_1_hover: String, pub color_neutral_background_1_hover: String,
pub color_neutral_background_1_pressed: String, pub color_neutral_background_1_pressed: String,
pub color_neutral_background_4: String,
pub color_neutral_background_4_hover: String,
pub color_neutral_background_4_pressed: String,
pub color_neutral_background_6: String, pub color_neutral_background_6: String,
pub color_neutral_foreground_disabled: String, pub color_neutral_foreground_disabled: String,
@ -17,6 +20,7 @@ pub struct ColorTheme {
pub color_neutral_foreground_2_pressed: String, pub color_neutral_foreground_2_pressed: String,
pub color_neutral_foreground_2_brand_hover: String, pub color_neutral_foreground_2_brand_hover: String,
pub color_neutral_foreground_2_brand_pressed: String, pub color_neutral_foreground_2_brand_pressed: String,
pub color_neutral_foreground_2_brand_selected: String,
pub color_neutral_foreground_3: String, pub color_neutral_foreground_3: String,
pub color_neutral_foreground_4: String, pub color_neutral_foreground_4: String,
pub color_neutral_foreground_on_brand: String, pub color_neutral_foreground_on_brand: String,
@ -50,6 +54,9 @@ impl ColorTheme {
color_neutral_background_1: "#fff".into(), color_neutral_background_1: "#fff".into(),
color_neutral_background_1_hover: "#f5f5f5".into(), color_neutral_background_1_hover: "#f5f5f5".into(),
color_neutral_background_1_pressed: "#e0e0e0".into(), color_neutral_background_1_pressed: "#e0e0e0".into(),
color_neutral_background_4: "#f0f0f0".into(),
color_neutral_background_4_hover: "#fafafa".into(),
color_neutral_background_4_pressed: "#f5f5f5".into(),
color_neutral_background_6: "#e6e6e6".into(), color_neutral_background_6: "#e6e6e6".into(),
color_neutral_foreground_disabled: "#bdbdbd".into(), color_neutral_foreground_disabled: "#bdbdbd".into(),
@ -61,6 +68,7 @@ impl ColorTheme {
color_neutral_foreground_2_pressed: "#242424".into(), color_neutral_foreground_2_pressed: "#242424".into(),
color_neutral_foreground_2_brand_hover: "#0f6cbd".into(), color_neutral_foreground_2_brand_hover: "#0f6cbd".into(),
color_neutral_foreground_2_brand_pressed: "#115ea3".into(), color_neutral_foreground_2_brand_pressed: "#115ea3".into(),
color_neutral_foreground_2_brand_selected: "#0f6cbd".into(),
color_neutral_foreground_3: "#616161".into(), color_neutral_foreground_3: "#616161".into(),
color_neutral_foreground_4: "#707070".into(), color_neutral_foreground_4: "#707070".into(),
color_neutral_foreground_on_brand: "#fff".into(), color_neutral_foreground_on_brand: "#fff".into(),
@ -94,6 +102,9 @@ impl ColorTheme {
color_neutral_background_1: "#292929".into(), color_neutral_background_1: "#292929".into(),
color_neutral_background_1_hover: "#3d3d3d".into(), color_neutral_background_1_hover: "#3d3d3d".into(),
color_neutral_background_1_pressed: "#1f1f1f".into(), color_neutral_background_1_pressed: "#1f1f1f".into(),
color_neutral_background_4: "#0a0a0a".into(),
color_neutral_background_4_hover: "#1f1f1f".into(),
color_neutral_background_4_pressed: "#000000".into(),
color_neutral_background_6: "#333333".into(), color_neutral_background_6: "#333333".into(),
color_neutral_foreground_disabled: "#5c5c5c".into(), color_neutral_foreground_disabled: "#5c5c5c".into(),
@ -105,6 +116,7 @@ impl ColorTheme {
color_neutral_foreground_2_pressed: "#fff".into(), color_neutral_foreground_2_pressed: "#fff".into(),
color_neutral_foreground_2_brand_hover: "#479ef5".into(), color_neutral_foreground_2_brand_hover: "#479ef5".into(),
color_neutral_foreground_2_brand_pressed: "#2886de".into(), color_neutral_foreground_2_brand_pressed: "#2886de".into(),
color_neutral_foreground_2_brand_selected: "#479ef5".into(),
color_neutral_foreground_3: "#adadad".into(), color_neutral_foreground_3: "#adadad".into(),
color_neutral_foreground_4: "#999999".into(), color_neutral_foreground_4: "#999999".into(),
color_neutral_foreground_on_brand: "#fff".into(), color_neutral_foreground_on_brand: "#fff".into(),

View file

@ -51,6 +51,8 @@ pub struct CommonTheme {
pub spacing_horizontal_m_nudge: String, pub spacing_horizontal_m_nudge: String,
pub spacing_horizontal_m: String, pub spacing_horizontal_m: String,
pub spacing_horizontal_l: String, pub spacing_horizontal_l: String,
pub spacing_vertical_m_nudge: String,
pub spacing_vertical_l: String,
pub duration_ultra_fast: String, pub duration_ultra_fast: String,
pub duration_faster: String, pub duration_faster: String,
@ -119,6 +121,8 @@ impl CommonTheme {
spacing_horizontal_m_nudge: "10px".into(), spacing_horizontal_m_nudge: "10px".into(),
spacing_horizontal_m: "12px".into(), spacing_horizontal_m: "12px".into(),
spacing_horizontal_l: "16px".into(), spacing_horizontal_l: "16px".into(),
spacing_vertical_m_nudge: "10px".into(),
spacing_vertical_l: "16px".into(),
duration_ultra_fast: "50ms".into(), duration_ultra_fast: "50ms".into(),
duration_faster: "100ms".into(), duration_faster: "100ms".into(),