mirror of
https://github.com/adoyle0/thaw.git
synced 2025-01-23 06:19:22 -05:00
feat: nav
This commit is contained in:
parent
7219c0cb93
commit
6d42248e76
11 changed files with 160 additions and 18 deletions
|
@ -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>
|
||||||
|
|
|
@ -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> }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
5
thaw/src/nav/mod.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
mod nav_drawer;
|
||||||
|
mod nav_item;
|
||||||
|
|
||||||
|
pub use nav_drawer::*;
|
||||||
|
pub use nav_item::*;
|
61
thaw/src/nav/nav-drawer.css
Normal file
61
thaw/src/nav/nav-drawer.css
Normal 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;
|
||||||
|
}
|
27
thaw/src/nav/nav_drawer.rs
Normal file
27
thaw/src/nav/nav_drawer.rs
Normal 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
24
thaw/src/nav/nav_item.rs
Normal 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
6
thaw/src/text/mod.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
use leptos::*;
|
||||||
|
|
||||||
|
|
||||||
|
pub fn Caption1Strong() {
|
||||||
|
|
||||||
|
}
|
|
@ -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(),
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
Loading…
Add table
Reference in a new issue