2024-03-22 17:22:53 +08:00
|
|
|
use super::switch_version::SwitchVersion;
|
2024-07-24 13:22:46 +00:00
|
|
|
use leptos::{
|
|
|
|
ev::{self, MouseEvent},
|
|
|
|
prelude::*,
|
|
|
|
};
|
2024-01-04 23:32:58 +08:00
|
|
|
use leptos_meta::Style;
|
2024-07-07 18:33:45 +08:00
|
|
|
use leptos_router::hooks::use_navigate;
|
|
|
|
// use leptos_use::{storage::use_local_storage, utils::FromToStringCodec};
|
2023-11-05 16:03:58 +08:00
|
|
|
use thaw::*;
|
2023-06-18 19:40:23 +08:00
|
|
|
|
|
|
|
#[component]
|
2023-08-29 09:11:22 +08:00
|
|
|
pub fn SiteHeader() -> impl IntoView {
|
2024-07-10 00:05:22 +08:00
|
|
|
let navigate = use_navigate();
|
2024-07-24 13:22:46 +00:00
|
|
|
let navigate_signal = RwSignal::new(use_navigate());
|
2024-07-08 14:40:17 +08:00
|
|
|
let theme = Theme::use_rw_theme();
|
|
|
|
let theme_name = Memo::new(move |_| {
|
|
|
|
theme.with(|theme| {
|
|
|
|
if theme.name == *"light" {
|
|
|
|
"Dark".to_string()
|
|
|
|
} else {
|
|
|
|
"Light".to_string()
|
|
|
|
}
|
|
|
|
})
|
|
|
|
});
|
|
|
|
// let (_, write_theme, _) = use_local_storage::<String, FromToStringCodec>("theme");
|
2024-07-19 17:30:46 +08:00
|
|
|
let change_theme = move |_| {
|
2024-07-08 14:40:17 +08:00
|
|
|
if theme_name.get_untracked() == "Light" {
|
|
|
|
theme.set(Theme::light());
|
|
|
|
// write_theme.set("light".to_string());
|
|
|
|
} else {
|
|
|
|
theme.set(Theme::dark());
|
|
|
|
// write_theme.set("dark".to_string());
|
|
|
|
}
|
2024-07-19 17:30:46 +08:00
|
|
|
};
|
2024-05-13 17:32:45 +08:00
|
|
|
|
2024-07-07 18:33:45 +08:00
|
|
|
let search_value = RwSignal::new(String::new());
|
|
|
|
let search_all_options = StoredValue::new(gen_search_all_options());
|
2024-07-02 07:18:40 +00:00
|
|
|
|
2024-07-07 18:33:45 +08:00
|
|
|
let search_options = Memo::new(move |_| {
|
2023-11-08 17:27:01 +08:00
|
|
|
let search_value = search_value.get();
|
|
|
|
if search_value.is_empty() {
|
|
|
|
return vec![];
|
|
|
|
}
|
|
|
|
fn match_value(pattern: &str, value: String) -> bool {
|
|
|
|
if pattern.is_empty() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if value.is_empty() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if pattern.chars().next() == value.chars().next() {
|
|
|
|
return match_value(pattern.split_at(1).1, value.split_at(1).1.to_string());
|
|
|
|
}
|
|
|
|
match_value(pattern, value.split_at(1).1.to_string())
|
|
|
|
}
|
|
|
|
search_all_options.with_value(|options| {
|
2023-11-16 12:33:04 +08:00
|
|
|
let search_value = search_value.to_lowercase().replace([' ', '-'], "");
|
2023-11-08 17:27:01 +08:00
|
|
|
let search_value = if search_value.len() > 20 {
|
|
|
|
search_value.split_at(20).0
|
|
|
|
} else {
|
|
|
|
&search_value
|
|
|
|
};
|
|
|
|
options
|
|
|
|
.iter()
|
|
|
|
.filter(|option| {
|
2023-11-16 12:33:04 +08:00
|
|
|
let label = option.label.to_lowercase().replace([' ', '-'], "");
|
2023-11-08 17:27:01 +08:00
|
|
|
match_value(search_value, label)
|
|
|
|
})
|
|
|
|
.cloned()
|
|
|
|
.collect()
|
|
|
|
})
|
|
|
|
});
|
2024-07-10 00:05:22 +08:00
|
|
|
let on_search_select = {
|
|
|
|
let navigate = navigate.clone();
|
|
|
|
move |path: String| {
|
|
|
|
navigate(&path, Default::default());
|
|
|
|
}
|
2023-11-08 21:53:49 +08:00
|
|
|
};
|
2024-07-07 18:33:45 +08:00
|
|
|
let auto_complete_ref = ComponentRef::<AutoCompleteRef>::new();
|
2023-12-15 00:57:23 +08:00
|
|
|
let handle = window_event_listener(ev::keydown, move |event| {
|
|
|
|
let key = event.key();
|
|
|
|
if key == *"/" {
|
|
|
|
if let Some(auto_complete_ref) = auto_complete_ref.get_untracked() {
|
|
|
|
event.prevent_default();
|
|
|
|
auto_complete_ref.focus();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
on_cleanup(move || handle.remove());
|
2024-01-04 23:32:58 +08:00
|
|
|
|
2024-06-03 11:27:29 +08:00
|
|
|
// let menu_value = use_menu_value(change_theme);
|
2023-08-29 09:11:22 +08:00
|
|
|
view! {
|
2024-01-04 23:32:58 +08:00
|
|
|
<Style id="demo-header">
|
|
|
|
"
|
|
|
|
.demo-header {
|
|
|
|
height: 64px;
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
justify-content: space-between;
|
|
|
|
padding: 0 20px;
|
2024-05-13 17:32:45 +08:00
|
|
|
z-index: 1000;
|
|
|
|
position: relative;
|
|
|
|
border-bottom: 1px solid var(--colorNeutralStroke2);
|
2024-01-04 23:32:58 +08:00
|
|
|
}
|
|
|
|
.demo-name {
|
|
|
|
cursor: pointer;
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
height: 100%;
|
|
|
|
font-weight: 600;
|
|
|
|
font-size: 20px;
|
|
|
|
}
|
|
|
|
.demo-header__menu-mobile {
|
2024-03-20 15:56:52 +08:00
|
|
|
display: none !important;
|
2024-01-04 23:32:58 +08:00
|
|
|
}
|
2024-03-22 17:22:53 +08:00
|
|
|
.demo-header__right-btn .thaw-select {
|
|
|
|
width: 60px;
|
|
|
|
}
|
2024-01-04 23:32:58 +08:00
|
|
|
@media screen and (max-width: 600px) {
|
|
|
|
.demo-header {
|
|
|
|
padding: 0 8px;
|
2023-11-02 21:29:45 +08:00
|
|
|
}
|
2024-01-04 23:32:58 +08:00
|
|
|
.demo-name {
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@media screen and (max-width: 1200px) {
|
|
|
|
.demo-header__right-btn {
|
2024-03-20 15:56:52 +08:00
|
|
|
display: none !important;
|
2024-01-04 23:32:58 +08:00
|
|
|
}
|
|
|
|
.demo-header__menu-mobile {
|
2024-03-20 15:56:52 +08:00
|
|
|
display: block !important;
|
2024-01-04 23:32:58 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
"
|
|
|
|
</Style>
|
2024-07-08 14:40:17 +08:00
|
|
|
<LayoutHeader attr:class=("demo-header", true)>
|
|
|
|
<Space on:click=move |_| {
|
|
|
|
navigate("/", Default::default());
|
|
|
|
}>
|
|
|
|
<img src="/logo.svg" style="width: 36px"/>
|
|
|
|
<div class="demo-name">"Thaw UI"</div>
|
|
|
|
</Space>
|
2024-07-24 13:22:46 +00:00
|
|
|
<Space align=SpaceAlign::Center>
|
2024-07-08 14:40:17 +08:00
|
|
|
<AutoComplete
|
|
|
|
value=search_value
|
|
|
|
placeholder="Type '/' to search"
|
|
|
|
clear_after_select=true
|
|
|
|
blur_after_select=true
|
|
|
|
on_select=on_search_select
|
|
|
|
comp_ref=auto_complete_ref
|
|
|
|
>
|
|
|
|
<For each=move || search_options.get() key=|option| option.label.clone() let:option>
|
2024-07-22 16:28:38 +08:00
|
|
|
<AutoCompleteOption value=option.value>{option.label}</AutoCompleteOption>
|
2024-07-08 14:40:17 +08:00
|
|
|
</For>
|
|
|
|
<AutoCompletePrefix slot>
|
|
|
|
<Icon
|
|
|
|
icon=icondata::AiSearchOutlined
|
|
|
|
style="font-size: 18px; color: var(--thaw-placeholder-color);"
|
|
|
|
/>
|
|
|
|
</AutoCompletePrefix>
|
|
|
|
</AutoComplete>
|
2024-07-24 13:22:46 +00:00
|
|
|
<Menu
|
|
|
|
placement=MenuPlacement::BottomEnd
|
|
|
|
on_select=move |value : String| match value.as_str() {
|
|
|
|
"Dark" => change_theme(MouseEvent::new("click").unwrap()),
|
|
|
|
"Light" => change_theme(MouseEvent::new("click").unwrap()),
|
|
|
|
"github" => { _ = window().open_with_url("http://github.com/thaw-ui/thaw"); },//FIXME: breaks page
|
|
|
|
"discord" => { _ = window().open_with_url("https://discord.gg/YPxuprzu6M"); },//FIXME: breaks page
|
|
|
|
_ => navigate_signal.get()(&value, Default::default())
|
|
|
|
|
|
|
|
}
|
2024-07-08 14:40:17 +08:00
|
|
|
>
|
2024-07-24 13:22:46 +00:00
|
|
|
<MenuTrigger slot class="demo-header__menu-mobile">
|
|
|
|
<Button
|
2024-07-08 14:40:17 +08:00
|
|
|
appearance=ButtonAppearance::Subtle
|
|
|
|
icon=icondata::AiUnorderedListOutlined
|
|
|
|
attr:style="font-size: 22px; padding: 0px 6px;"
|
|
|
|
/>
|
2024-07-24 13:22:46 +00:00
|
|
|
</MenuTrigger>
|
|
|
|
<MenuItem key=theme_name label=theme_name/>
|
|
|
|
<MenuItem icon=icondata::AiGithubOutlined key="github" label="Github"/>
|
|
|
|
<MenuItem icon=icondata::BiDiscordAlt key="discord" label="Discord"/>
|
|
|
|
{
|
|
|
|
use crate::pages::{gen_menu_data, MenuGroupOption, MenuItemOption};
|
|
|
|
gen_menu_data().into_iter().map(|data| {
|
|
|
|
let MenuGroupOption { label, children } = data;
|
|
|
|
view! {
|
|
|
|
<Caption1Strong style="margin-inline-start: 10px; margin-top: 10px; display: block">
|
|
|
|
{label}
|
|
|
|
</Caption1Strong>
|
|
|
|
{
|
|
|
|
children.into_iter().map(|item| {
|
|
|
|
let MenuItemOption { label, value } = item;
|
|
|
|
view! {
|
|
|
|
<MenuItem label key=value/>
|
|
|
|
}
|
|
|
|
}).collect_view()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}).collect_view()
|
|
|
|
}
|
|
|
|
</Menu>
|
2024-07-08 14:40:17 +08:00
|
|
|
<Space class="demo-header__right-btn" align=SpaceAlign::Center>
|
|
|
|
<Button
|
|
|
|
appearance=ButtonAppearance::Subtle
|
2024-07-19 17:30:46 +08:00
|
|
|
on_click=change_theme
|
2024-07-08 14:40:17 +08:00
|
|
|
>
|
|
|
|
{move || theme_name.get()}
|
|
|
|
</Button>
|
|
|
|
<SwitchVersion/>
|
|
|
|
<Button
|
|
|
|
appearance=ButtonAppearance::Subtle
|
|
|
|
icon=icondata::BiDiscordAlt
|
|
|
|
attr:style="font-size: 22px; padding: 0px 6px;"
|
|
|
|
on_click=move |_| {
|
|
|
|
_ = window().open_with_url("https://discord.gg/YPxuprzu6M");
|
|
|
|
}
|
|
|
|
/>
|
2024-07-02 07:18:40 +00:00
|
|
|
|
2024-07-08 14:40:17 +08:00
|
|
|
<Button
|
|
|
|
appearance=ButtonAppearance::Subtle
|
|
|
|
icon=icondata::AiGithubOutlined
|
|
|
|
attr:style="font-size: 22px; padding: 0px 6px;"
|
|
|
|
on_click=move |_| {
|
|
|
|
_ = window().open_with_url("http://github.com/thaw-ui/thaw");
|
|
|
|
}
|
|
|
|
/>
|
2024-07-02 07:18:40 +00:00
|
|
|
|
2024-07-08 14:40:17 +08:00
|
|
|
</Space>
|
|
|
|
</Space>
|
2023-10-08 09:28:13 +08:00
|
|
|
|
2023-06-18 19:40:23 +08:00
|
|
|
</LayoutHeader>
|
|
|
|
}
|
|
|
|
}
|
2023-11-08 17:27:01 +08:00
|
|
|
|
2024-07-02 07:18:40 +00:00
|
|
|
#[derive(Clone, PartialEq)]
|
|
|
|
struct AutoCompleteOption {
|
|
|
|
pub label: String,
|
|
|
|
pub value: String,
|
|
|
|
}
|
|
|
|
|
2023-11-08 17:27:01 +08:00
|
|
|
fn gen_search_all_options() -> Vec<AutoCompleteOption> {
|
2024-06-03 11:27:29 +08:00
|
|
|
use crate::pages::gen_menu_data;
|
|
|
|
gen_menu_data()
|
2023-11-08 17:27:01 +08:00
|
|
|
.into_iter()
|
2023-11-16 12:33:04 +08:00
|
|
|
.flat_map(|group| {
|
2023-11-08 17:27:01 +08:00
|
|
|
group.children.into_iter().map(|item| AutoCompleteOption {
|
2024-06-03 11:27:29 +08:00
|
|
|
value: item.value,
|
2023-11-08 17:27:01 +08:00
|
|
|
label: item.label,
|
|
|
|
})
|
|
|
|
})
|
2024-06-03 11:27:29 +08:00
|
|
|
.collect()
|
2023-11-08 17:27:01 +08:00
|
|
|
}
|
2024-01-04 23:32:58 +08:00
|
|
|
|
2024-06-03 11:27:29 +08:00
|
|
|
// TODO
|
|
|
|
// fn use_menu_value(change_theme: Callback<()>) -> RwSignal<String> {
|
|
|
|
// use crate::pages::gen_guide_menu_data;
|
|
|
|
// let guide = store_value(gen_guide_menu_data());
|
|
|
|
// let navigate = use_navigate();
|
|
|
|
// let loaction = use_location();
|
2024-01-04 23:32:58 +08:00
|
|
|
|
2024-06-03 11:27:29 +08:00
|
|
|
// let menu_value = create_rw_signal({
|
|
|
|
// let mut pathname = loaction.pathname.get_untracked();
|
|
|
|
// if pathname.starts_with("/components/") {
|
|
|
|
// pathname.drain(12..).collect()
|
|
|
|
// } else if pathname.starts_with("/guide/") {
|
|
|
|
// pathname.drain(7..).collect()
|
|
|
|
// } else {
|
|
|
|
// String::new()
|
|
|
|
// }
|
|
|
|
// });
|
2024-01-04 23:32:58 +08:00
|
|
|
|
2024-06-03 11:27:29 +08:00
|
|
|
// _ = menu_value.watch(move |name| {
|
|
|
|
// if name == "Dark" || name == "Light" {
|
|
|
|
// change_theme.call(());
|
|
|
|
// return;
|
|
|
|
// } else if name == "github" {
|
|
|
|
// _ = window().open_with_url("http://github.com/thaw-ui/thaw");
|
|
|
|
// return;
|
|
|
|
// }
|
|
|
|
// let pathname = loaction.pathname.get_untracked();
|
|
|
|
// if guide.with_value(|menu| {
|
|
|
|
// menu.iter()
|
|
|
|
// .any(|group| group.children.iter().any(|item| &item.value == name))
|
|
|
|
// }) {
|
|
|
|
// if !pathname.eq(&format!("/guide/{name}")) {
|
|
|
|
// navigate(&format!("/guide/{name}"), Default::default());
|
|
|
|
// }
|
|
|
|
// } else if !pathname.eq(&format!("/components/{name}")) {
|
|
|
|
// navigate(&format!("/components/{name}"), Default::default());
|
|
|
|
// }
|
|
|
|
// });
|
|
|
|
|
|
|
|
// menu_value
|
|
|
|
// }
|