mirror of
https://github.com/adoyle0/thaw.git
synced 2025-02-02 16:44:15 -05:00
demo: adaptive mobile (#68)
* demo: adaptive mobile * fix: demo callback
This commit is contained in:
parent
3684f5961b
commit
5cce9afcb9
6 changed files with 210 additions and 64 deletions
|
@ -10,7 +10,7 @@ edition = "2021"
|
||||||
leptos = { version = "0.5.4" }
|
leptos = { version = "0.5.4" }
|
||||||
leptos_meta = { version = "0.5.4" }
|
leptos_meta = { version = "0.5.4" }
|
||||||
leptos_router = { version = "0.5.4" }
|
leptos_router = { version = "0.5.4" }
|
||||||
leptos_devtools = "0.0.1"
|
leptos_devtools = { version = "0.0.1", optional = true}
|
||||||
thaw = { path = "../thaw", default-features = false }
|
thaw = { path = "../thaw", default-features = false }
|
||||||
icondata = { version = "0.1.0", features = [
|
icondata = { version = "0.1.0", features = [
|
||||||
"AiCloseOutlined",
|
"AiCloseOutlined",
|
||||||
|
@ -18,6 +18,7 @@ icondata = { version = "0.1.0", features = [
|
||||||
"AiGithubOutlined",
|
"AiGithubOutlined",
|
||||||
"AiUserOutlined",
|
"AiUserOutlined",
|
||||||
"AiSearchOutlined",
|
"AiSearchOutlined",
|
||||||
|
"AiUnorderedListOutlined"
|
||||||
] }
|
] }
|
||||||
demo_markdown = { path = "../demo_markdown" }
|
demo_markdown = { path = "../demo_markdown" }
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use leptos_router::use_navigate;
|
use leptos_meta::Style;
|
||||||
|
use leptos_router::{use_location, use_navigate};
|
||||||
use thaw::*;
|
use thaw::*;
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
|
@ -8,23 +9,21 @@ pub fn SiteHeader() -> impl IntoView {
|
||||||
let theme_name = create_memo(move |_| {
|
let theme_name = create_memo(move |_| {
|
||||||
theme.with(|theme| {
|
theme.with(|theme| {
|
||||||
if theme.name == *"light" {
|
if theme.name == *"light" {
|
||||||
"Dark"
|
"Dark".to_string()
|
||||||
} else {
|
} else {
|
||||||
"Light"
|
"Light".to_string()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
let on_theme = move |_| {
|
let change_theme = Callback::new(move |_| {
|
||||||
if theme_name.get_untracked() == "Light" {
|
if theme_name.get_untracked() == "Light" {
|
||||||
theme.set(Theme::light())
|
theme.set(Theme::light());
|
||||||
} else {
|
} else {
|
||||||
theme.set(Theme::dark())
|
theme.set(Theme::dark());
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
let style = create_memo(move |_| {
|
let style = create_memo(move |_| {
|
||||||
theme.with(|theme| {
|
theme.with(|theme| format!("border-bottom: 1px solid {}", theme.common.border_color))
|
||||||
format!("height: 64px; display: flex; align-items: center; justify-content: space-between; padding: 0 20px; border-bottom: 1px solid {}", theme.common.border_color)
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
let search_value = create_rw_signal(String::new());
|
let search_value = create_rw_signal(String::new());
|
||||||
let search_all_options = store_value(gen_search_all_options());
|
let search_all_options = store_value(gen_search_all_options());
|
||||||
|
@ -77,18 +76,58 @@ pub fn SiteHeader() -> impl IntoView {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
on_cleanup(move || handle.remove());
|
on_cleanup(move || handle.remove());
|
||||||
|
|
||||||
|
let menu_value = use_menu_value(change_theme);
|
||||||
view! {
|
view! {
|
||||||
<LayoutHeader style>
|
<Style id="demo-header">
|
||||||
<Space>
|
"
|
||||||
<img src="/thaw/logo.svg" style="width: 36px"/>
|
.demo-header {
|
||||||
<div
|
height: 64px;
|
||||||
style="cursor: pointer; display: flex; align-items: center; height: 100%; font-weight: 600; font-size: 20px"
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
.demo-name {
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
.demo-header__menu-mobile {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.demo-header__menu-popover-mobile {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 600px) {
|
||||||
|
.demo-header {
|
||||||
|
padding: 0 8px;
|
||||||
|
}
|
||||||
|
.demo-name {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 1200px) {
|
||||||
|
.demo-header__right-btn {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.demo-header__menu-mobile {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"
|
||||||
|
</Style>
|
||||||
|
<LayoutHeader class="demo-header" style>
|
||||||
|
<Space
|
||||||
on:click=move |_| {
|
on:click=move |_| {
|
||||||
let navigate = use_navigate();
|
let navigate = use_navigate();
|
||||||
navigate("/", Default::default());
|
navigate("/", Default::default());
|
||||||
}
|
}>
|
||||||
>
|
<img src="/thaw/logo.svg" style="width: 36px"/>
|
||||||
|
<div class="demo-name">
|
||||||
"Thaw UI"
|
"Thaw UI"
|
||||||
</div>
|
</div>
|
||||||
</Space>
|
</Space>
|
||||||
|
@ -105,6 +144,29 @@ pub fn SiteHeader() -> impl IntoView {
|
||||||
<Icon icon=icondata::Icon::from(icondata::AiIcon::AiSearchOutlined) style="font-size: 18px; color: var(--thaw-placeholder-color);"/>
|
<Icon icon=icondata::Icon::from(icondata::AiIcon::AiSearchOutlined) style="font-size: 18px; color: var(--thaw-placeholder-color);"/>
|
||||||
</AutoCompletePrefix>
|
</AutoCompletePrefix>
|
||||||
</AutoComplete>
|
</AutoComplete>
|
||||||
|
<Popover placement=PopoverPlacement::BottomEnd class="demo-header__menu-popover-mobile">
|
||||||
|
<PopoverTrigger slot class="demo-header__menu-mobile">
|
||||||
|
<Button
|
||||||
|
variant=ButtonVariant::Text
|
||||||
|
icon=icondata::AiIcon::AiUnorderedListOutlined
|
||||||
|
style="font-size: 22px; padding: 0px 6px;"
|
||||||
|
/>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<div style="height: 70vh; overflow: auto;">
|
||||||
|
<Menu value=menu_value>
|
||||||
|
<MenuItem key=theme_name label=theme_name />
|
||||||
|
<MenuItem key="github" label="Github" />
|
||||||
|
{
|
||||||
|
use crate::pages::{gen_guide_menu_data, gen_menu_data};
|
||||||
|
vec![
|
||||||
|
gen_guide_menu_data().into_view(),
|
||||||
|
gen_menu_data().into_view(),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
</Menu>
|
||||||
|
</div>
|
||||||
|
</Popover>
|
||||||
|
<Space class="demo-header__right-btn">
|
||||||
<Button
|
<Button
|
||||||
variant=ButtonVariant::Text
|
variant=ButtonVariant::Text
|
||||||
on_click=move |_| {
|
on_click=move |_| {
|
||||||
|
@ -125,7 +187,7 @@ pub fn SiteHeader() -> impl IntoView {
|
||||||
|
|
||||||
"Components"
|
"Components"
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant=ButtonVariant::Text on_click=on_theme>
|
<Button variant=ButtonVariant::Text on_click=Callback::new(move |_| change_theme.call(()))>
|
||||||
{move || theme_name.get()}
|
{move || theme_name.get()}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
|
@ -137,7 +199,7 @@ pub fn SiteHeader() -> impl IntoView {
|
||||||
_ = window().open_with_url("http://github.com/thaw-ui/thaw");
|
_ = window().open_with_url("http://github.com/thaw-ui/thaw");
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
</Space>
|
||||||
</Space>
|
</Space>
|
||||||
|
|
||||||
</LayoutHeader>
|
</LayoutHeader>
|
||||||
|
@ -163,3 +225,44 @@ fn gen_search_all_options() -> Vec<AutoCompleteOption> {
|
||||||
}));
|
}));
|
||||||
options
|
options
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
let menu_value = create_rw_signal({
|
||||||
|
let mut pathname = loaction.pathname.get_untracked();
|
||||||
|
if pathname.starts_with("/thaw/components/") {
|
||||||
|
pathname.drain(17..).collect()
|
||||||
|
} else if pathname.starts_with("/thaw/guide/") {
|
||||||
|
pathname.drain(12..).collect()
|
||||||
|
} else {
|
||||||
|
String::new()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_ = 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!("/thaw/guide/{name}")) {
|
||||||
|
navigate(&format!("/guide/{name}"), Default::default());
|
||||||
|
}
|
||||||
|
} else if !pathname.eq(&format!("/thaw/components/{name}")) {
|
||||||
|
navigate(&format!("/components/{name}"), Default::default());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
menu_value
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::components::SiteHeader;
|
use crate::components::SiteHeader;
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
|
use leptos_meta::Style;
|
||||||
use leptos_router::{use_location, use_navigate, Outlet};
|
use leptos_router::{use_location, use_navigate, Outlet};
|
||||||
use thaw::*;
|
use thaw::*;
|
||||||
|
|
||||||
|
@ -26,10 +27,29 @@ pub fn ComponentsPage() -> impl IntoView {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
view! {
|
view! {
|
||||||
|
<Style>
|
||||||
|
"
|
||||||
|
.demo-components__component {
|
||||||
|
width: 896px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.demo-md-table-box {
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 1200px) {
|
||||||
|
.demo-components__sider {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.demo-components__component {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"
|
||||||
|
</Style>
|
||||||
<Layout position=LayoutPosition::Absolute>
|
<Layout position=LayoutPosition::Absolute>
|
||||||
<SiteHeader/>
|
<SiteHeader/>
|
||||||
<Layout has_sider=true position=LayoutPosition::Absolute style="top: 64px;">
|
<Layout has_sider=true position=LayoutPosition::Absolute style="top: 64px;">
|
||||||
<LayoutSider>
|
<LayoutSider class="demo-components__sider">
|
||||||
<Menu value=select_name>
|
<Menu value=select_name>
|
||||||
|
|
||||||
{gen_menu_data().into_view()}
|
{gen_menu_data().into_view()}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::components::SiteHeader;
|
use crate::components::SiteHeader;
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
|
use leptos_meta::Style;
|
||||||
use leptos_router::{use_location, use_navigate, Outlet};
|
use leptos_router::{use_location, use_navigate, Outlet};
|
||||||
use thaw::*;
|
use thaw::*;
|
||||||
|
|
||||||
|
@ -25,10 +26,29 @@ pub fn GuidePage() -> impl IntoView {
|
||||||
selected
|
selected
|
||||||
});
|
});
|
||||||
view! {
|
view! {
|
||||||
|
<Style>
|
||||||
|
"
|
||||||
|
.demo-components__component {
|
||||||
|
width: 896px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.demo-md-table-box {
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 1200px) {
|
||||||
|
.demo-guide__sider {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.demo-components__component {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"
|
||||||
|
</Style>
|
||||||
<Layout position=LayoutPosition::Absolute>
|
<Layout position=LayoutPosition::Absolute>
|
||||||
<SiteHeader/>
|
<SiteHeader/>
|
||||||
<Layout has_sider=true position=LayoutPosition::Absolute style="top: 64px;">
|
<Layout has_sider=true position=LayoutPosition::Absolute style="top: 64px;">
|
||||||
<LayoutSider>
|
<LayoutSider class="demo-guide__sider">
|
||||||
<Menu value=selected>
|
<Menu value=selected>
|
||||||
|
|
||||||
{gen_guide_menu_data().into_view()}
|
{gen_guide_menu_data().into_view()}
|
||||||
|
|
|
@ -124,7 +124,7 @@ pub fn include_md(_token_stream: proc_macro::TokenStream) -> proc_macro::TokenSt
|
||||||
#(#demos)*
|
#(#demos)*
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
<div style="width: 896px; margin: 0 auto;">
|
<div class="demo-components__component">
|
||||||
#body
|
#body
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,6 +83,7 @@ fn iter_nodes<'a>(node: &'a AstNode<'a>, demos: &mut Vec<String>) -> TokenStream
|
||||||
let header_children: Vec<TokenStream> = children.drain(0..header_index).collect();
|
let header_children: Vec<TokenStream> = children.drain(0..header_index).collect();
|
||||||
|
|
||||||
quote!(
|
quote!(
|
||||||
|
<div class="demo-md-table-box">
|
||||||
<Table single_column=true>
|
<Table single_column=true>
|
||||||
<thead>
|
<thead>
|
||||||
#(#header_children)*
|
#(#header_children)*
|
||||||
|
@ -91,6 +92,7 @@ fn iter_nodes<'a>(node: &'a AstNode<'a>, demos: &mut Vec<String>) -> TokenStream
|
||||||
#(#children)*
|
#(#children)*
|
||||||
</tbody>
|
</tbody>
|
||||||
</Table>
|
</Table>
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
NodeValue::TableRow(_) => {
|
NodeValue::TableRow(_) => {
|
||||||
|
|
Loading…
Add table
Reference in a new issue