feat(lepots-v0.7): demo

This commit is contained in:
luoxiao 2024-07-07 18:33:45 +08:00 committed by luoxiaozero
parent 41c5a2ea89
commit 48b62a4d07
23 changed files with 220 additions and 222 deletions

View file

@ -7,10 +7,9 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
leptos = { version = "0.6.10" } leptos = { workspace = true }
leptos_meta = { version = "0.6.10" } leptos_meta = { workspace = true }
leptos_router = { version = "0.6.10" } leptos_router = { git = "https://github.com/leptos-rs/leptos", rev = "ae0dc13c" }
leptos_devtools = { version = "0.0.1", optional = true }
thaw = { path = "../thaw" } thaw = { path = "../thaw" }
demo_markdown = { path = "../demo_markdown" } demo_markdown = { path = "../demo_markdown" }
icondata = "0.3.0" icondata = "0.3.0"
@ -22,15 +21,13 @@ leptos-use = "0.10.10"
[features] [features]
default = ["csr"] default = ["csr"]
tracing = ["leptos/tracing"] tracing = ["leptos/tracing"]
csr = ["leptos/csr", "leptos_meta/csr", "leptos_router/csr", "thaw/csr"] csr = ["leptos/csr", "thaw/csr"]
ssr = ["leptos/ssr", "leptos_meta/ssr", "leptos_router/ssr", "thaw/ssr"] ssr = ["leptos/ssr", "leptos_meta/ssr", "leptos_router/ssr", "thaw/ssr"]
hydrate = [ hydrate = [
"leptos/hydrate", "leptos/hydrate",
"leptos_meta/hydrate",
"leptos_router/hydrate",
"thaw/hydrate", "thaw/hydrate",
] ]
nightly = ["leptos/nightly", "leptos_meta/nightly", "leptos_router/nightly"] nightly = ["leptos/nightly", "leptos_router/nightly"]
# https://benw.is/posts/how-i-improved-my-rust-compile-times-by-seventy-five-percent#optimization-level # https://benw.is/posts/how-i-improved-my-rust-compile-times-by-seventy-five-percent#optimization-level

View file

@ -1,16 +1,19 @@
use crate::pages::*; use crate::pages::*;
use leptos::*; use leptos::{prelude::*, reactive_graph::wrappers::write::SignalSetter};
use leptos_meta::provide_meta_context; use leptos_meta::provide_meta_context;
use leptos_router::*; use leptos_router::{
use leptos_use::{ components::{Route, Router, Routes},
storage::use_local_storage, StaticSegment,
utils::{FromToStringCodec, StringCodec},
}; };
// use leptos_use::{
// storage::use_local_storage,
// utils::{FromToStringCodec, StringCodec},
// };
use thaw::*; use thaw::*;
#[component] #[component]
pub fn App() -> impl IntoView { pub fn App() -> impl IntoView {
let is_routing = create_rw_signal(false); let is_routing = RwSignal::new(false);
let set_is_routing = SignalSetter::map(move |is_routing_data| { let set_is_routing = SignalSetter::map(move |is_routing_data| {
is_routing.set(is_routing_data); is_routing.set(is_routing_data);
}); });
@ -37,65 +40,66 @@ fn TheRouter(is_routing: RwSignal<bool>) -> impl IntoView {
}); });
view! { view! {
<Routes> <Routes fallback=|| "404">
<Route path="/" view=Home/> <Route path=StaticSegment("") view=Home/>
<Route path="/guide" view=ComponentsPage> <Route path=StaticSegment("/home") view=Home/>
<Route path="/installation" view=InstallationMdPage/> // <Route path="/guide" view=ComponentsPage>
<Route path="/usage" view=UsageMdPage/> // <Route path="/installation" view=InstallationMdPage/>
<Route path="/server-sider-rendering" view=ServerSiderRenderingMdPage/> // <Route path="/usage" view=UsageMdPage/>
<Route path="/development/guide" view=DevelopmentGuideMdPage/> // <Route path="/server-sider-rendering" view=ServerSiderRenderingMdPage/>
<Route path="/development/components" view=DevelopmentComponentsMdPage/> // <Route path="/development/guide" view=DevelopmentGuideMdPage/>
</Route> // <Route path="/development/components" view=DevelopmentComponentsMdPage/>
<Route path="/components" view=ComponentsPage> // </Route>
// <Route path="/tabbar" view=TabbarPage/> // <Route path="/components" view=ComponentsPage>
// <Route path="/nav-bar" view=NavBarPage/> // // <Route path="/tabbar" view=TabbarPage/>
// <Route path="/toast" view=ToastPage/> // // <Route path="/nav-bar" view=NavBarPage/>
<Route path="/accordion" view=AccordionMdPage/> // // <Route path="/toast" view=ToastPage/>
<Route path="/anchor" view=AnchorMdPage/> // <Route path="/accordion" view=AccordionMdPage/>
<Route path="/auto-complete" view=AutoCompleteMdPage/> // <Route path="/anchor" view=AnchorMdPage/>
<Route path="/avatar" view=AvatarMdPage/> // <Route path="/auto-complete" view=AutoCompleteMdPage/>
<Route path="/back-top" view=BackTopMdPage/> // <Route path="/avatar" view=AvatarMdPage/>
<Route path="/badge" view=BadgeMdPage/> // <Route path="/back-top" view=BackTopMdPage/>
<Route path="/breadcrumb" view=BreadcrumbMdPage/> // <Route path="/badge" view=BadgeMdPage/>
<Route path="/button" view=ButtonMdPage/> // <Route path="/breadcrumb" view=BreadcrumbMdPage/>
<Route path="/calendar" view=CalendarMdPage/> // <Route path="/button" view=ButtonMdPage/>
<Route path="/card" view=CardMdPage/> // <Route path="/calendar" view=CalendarMdPage/>
<Route path="/checkbox" view=CheckboxMdPage/> // <Route path="/card" view=CardMdPage/>
<Route path="/color-picker" view=ColorPickerMdPage/> // <Route path="/checkbox" view=CheckboxMdPage/>
<Route path="/combobox" view=ComboboxMdPage/> // <Route path="/color-picker" view=ColorPickerMdPage/>
<Route path="/config-provider" view=ConfigProviderMdPage/> // <Route path="/combobox" view=ComboboxMdPage/>
<Route path="/date-picker" view=DatePickerMdPage/> // <Route path="/config-provider" view=ConfigProviderMdPage/>
<Route path="/dialog" view=DialogMdPage/> // <Route path="/date-picker" view=DatePickerMdPage/>
<Route path="/divider" view=DividerMdPage/> // <Route path="/dialog" view=DialogMdPage/>
<Route path="/drawer" view=DrawerMdPage/> // <Route path="/divider" view=DividerMdPage/>
<Route path="/grid" view=GridMdPage/> // <Route path="/drawer" view=DrawerMdPage/>
<Route path="/icon" view=IconMdPage/> // <Route path="/grid" view=GridMdPage/>
<Route path="/image" view=ImageMdPage/> // <Route path="/icon" view=IconMdPage/>
<Route path="/input" view=InputMdPage/> // <Route path="/image" view=ImageMdPage/>
<Route path="/layout" view=LayoutMdPage/> // <Route path="/input" view=InputMdPage/>
<Route path="/loading-bar" view=LoadingBarMdPage/> // <Route path="/layout" view=LayoutMdPage/>
// <Route path="/message" view=MessageMdPage/> // <Route path="/loading-bar" view=LoadingBarMdPage/>
<Route path="/message-bar" view=MessageBarMdPage/> // // <Route path="/message" view=MessageMdPage/>
<Route path="/popover" view=PopoverMdPage/> // <Route path="/message-bar" view=MessageBarMdPage/>
<Route path="/progress-bar" view=ProgressBarMdPage/> // <Route path="/popover" view=PopoverMdPage/>
<Route path="/radio" view=RadioMdPage/> // <Route path="/progress-bar" view=ProgressBarMdPage/>
<Route path="/scrollbar" view=ScrollbarMdPage/> // <Route path="/radio" view=RadioMdPage/>
// <Route path="/select" view=SelectMdPage/> // <Route path="/scrollbar" view=ScrollbarMdPage/>
<Route path="/skeleton" view=SkeletonMdPage/> // // <Route path="/select" view=SelectMdPage/>
<Route path="/slider" view=SliderMdPage/> // <Route path="/skeleton" view=SkeletonMdPage/>
<Route path="/space" view=SpaceMdPage/> // <Route path="/slider" view=SliderMdPage/>
<Route path="/spin-button" view=SpinButtonMdPage/> // <Route path="/space" view=SpaceMdPage/>
<Route path="/spinner" view=SpinnerMdPage/> // <Route path="/spin-button" view=SpinButtonMdPage/>
<Route path="/switch" view=SwitchMdPage/> // <Route path="/spinner" view=SpinnerMdPage/>
<Route path="/tab-list" view=TabListMdPage/> // <Route path="/switch" view=SwitchMdPage/>
<Route path="/table" view=TableMdPage/> // <Route path="/tab-list" view=TabListMdPage/>
<Route path="/tag" view=TagMdPage/> // <Route path="/table" view=TableMdPage/>
<Route path="/text" view=TextMdPage/> // <Route path="/tag" view=TagMdPage/>
<Route path="/textarea" view=TextareaMdPage/> // <Route path="/text" view=TextMdPage/>
<Route path="/time-picker" view=TimePickerMdPage/> // <Route path="/textarea" view=TextareaMdPage/>
<Route path="/toast" view=ToastMdPage /> // <Route path="/time-picker" view=TimePickerMdPage/>
<Route path="/upload" view=UploadMdPage/> // <Route path="/toast" view=ToastMdPage />
</Route> // <Route path="/upload" view=UploadMdPage/>
// </Route>
// <Route path="/mobile/tabbar" view=TabbarDemoPage/> // <Route path="/mobile/tabbar" view=TabbarDemoPage/>
// <Route path="/mobile/nav-bar" view=NavBarDemoPage/> // <Route path="/mobile/nav-bar" view=NavBarDemoPage/>
// <Route path="/mobile/toast" view=ToastDemoPage/> // <Route path="/mobile/toast" view=ToastDemoPage/>
@ -105,11 +109,11 @@ fn TheRouter(is_routing: RwSignal<bool>) -> impl IntoView {
#[component] #[component]
fn TheProvider(children: Children) -> impl IntoView { fn TheProvider(children: Children) -> impl IntoView {
let (read_theme, _, _) = use_local_storage::<String, FromToStringCodec>("theme"); // let (read_theme, _, _) = use_local_storage::<String, FromToStringCodec>("theme");
let theme = RwSignal::new(Theme::from(read_theme.get_untracked())); // let theme = RwSignal::new(Theme::from(read_theme.get_untracked()));
view! { view! {
<ConfigProvider theme> <ConfigProvider>
<ToasterProvider> <ToasterProvider>
<LoadingBarProvider>{children()}</LoadingBarProvider> <LoadingBarProvider>{children()}</LoadingBarProvider>
</ToasterProvider> </ToasterProvider>

View file

@ -1,4 +1,4 @@
use leptos::*; use leptos::prelude::*;
use leptos_meta::Style; use leptos_meta::Style;
use thaw::*; use thaw::*;
@ -6,7 +6,8 @@ use thaw::*;
pub struct DemoCode { pub struct DemoCode {
#[prop(default = true)] #[prop(default = true)]
is_highlight: bool, is_highlight: bool,
children: Children, #[prop(into)]
text: String,
} }
#[component] #[component]
@ -38,16 +39,7 @@ pub fn Demo(demo_code: DemoCode, #[prop(optional)] children: Option<Children>) -
let is_show_code = RwSignal::new(children.is_none()); let is_show_code = RwSignal::new(children.is_none());
let is_highlight = demo_code.is_highlight; let is_highlight = demo_code.is_highlight;
let frag = (demo_code.children)(); let html = demo_code.text;
let mut html = String::new();
for node in frag.nodes {
match node {
View::Text(text) => html.push_str(&text.content),
_ => {
leptos::logging::warn!("Only text nodes are supported as children of <DemoCode />.")
}
}
}
view! { view! {
<Style id="leptos-thaw-syntect-css"> <Style id="leptos-thaw-syntect-css">
@ -93,7 +85,7 @@ pub fn Demo(demo_code: DemoCode, #[prop(optional)] children: Option<Children>) -
None None
} }
} }
<div class=move || code_class.get() style:display=move || (!is_show_code.get()).then_some("none")> <div class=move || code_class.get() style:display=move || (!is_show_code.get()).then_some("none").unwrap_or_default()>
{ {
if is_highlight { if is_highlight {
view! { view! {

View file

@ -1,14 +1,14 @@
use super::switch_version::SwitchVersion; use super::switch_version::SwitchVersion;
use leptos::*; use leptos::{prelude::*, ev};
use leptos_meta::Style; use leptos_meta::Style;
use leptos_router::use_navigate; use leptos_router::hooks::use_navigate;
use leptos_use::{storage::use_local_storage, utils::FromToStringCodec}; // use leptos_use::{storage::use_local_storage, utils::FromToStringCodec};
use thaw::*; use thaw::*;
#[component] #[component]
pub fn SiteHeader() -> impl IntoView { pub fn SiteHeader() -> impl IntoView {
let theme = Theme::use_rw_theme(); let theme = Theme::use_rw_theme();
let theme_name = create_memo(move |_| { let theme_name = Memo::new(move |_| {
theme.with(|theme| { theme.with(|theme| {
if theme.name == *"light" { if theme.name == *"light" {
"Dark".to_string() "Dark".to_string()
@ -17,21 +17,21 @@ pub fn SiteHeader() -> impl IntoView {
} }
}) })
}); });
let (_, write_theme, _) = use_local_storage::<String, FromToStringCodec>("theme"); // let (_, write_theme, _) = use_local_storage::<String, FromToStringCodec>("theme");
let change_theme = Callback::new(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());
write_theme.set("light".to_string()); // write_theme.set("light".to_string());
} else { } else {
theme.set(Theme::dark()); theme.set(Theme::dark());
write_theme.set("dark".to_string()); // write_theme.set("dark".to_string());
} }
}); });
let search_value = create_rw_signal(String::new()); let search_value = RwSignal::new(String::new());
let search_all_options = store_value(gen_search_all_options()); let search_all_options = StoredValue::new(gen_search_all_options());
let search_options = create_memo(move |_| { let search_options = Memo::new(move |_| {
let search_value = search_value.get(); let search_value = search_value.get();
if search_value.is_empty() { if search_value.is_empty() {
return vec![]; return vec![];
@ -69,7 +69,7 @@ pub fn SiteHeader() -> impl IntoView {
let navigate = use_navigate(); let navigate = use_navigate();
navigate(&path, Default::default()); navigate(&path, Default::default());
}; };
let auto_complete_ref = create_component_ref::<AutoCompleteRef>(); let auto_complete_ref = ComponentRef::<AutoCompleteRef>::new();
let handle = window_event_listener(ev::keydown, move |event| { let handle = window_event_listener(ev::keydown, move |event| {
let key = event.key(); let key = event.key();
if key == *"/" { if key == *"/" {
@ -165,7 +165,7 @@ pub fn SiteHeader() -> impl IntoView {
<Button <Button
appearance=ButtonAppearance::Subtle appearance=ButtonAppearance::Subtle
icon=icondata::AiUnorderedListOutlined icon=icondata::AiUnorderedListOutlined
style="font-size: 22px; padding: 0px 6px;" attr:style="font-size: 22px; padding: 0px 6px;"
/> />
</PopoverTrigger> </PopoverTrigger>
<div style="height: 70vh; overflow: auto;">// <Menu value=menu_value> <div style="height: 70vh; overflow: auto;">// <Menu value=menu_value>
@ -192,7 +192,7 @@ pub fn SiteHeader() -> impl IntoView {
<Button <Button
appearance=ButtonAppearance::Subtle appearance=ButtonAppearance::Subtle
icon=icondata::BiDiscordAlt icon=icondata::BiDiscordAlt
style="font-size: 22px; padding: 0px 6px;" attr:style="font-size: 22px; padding: 0px 6px;"
on_click=move |_| { on_click=move |_| {
_ = window().open_with_url("https://discord.gg/YPxuprzu6M"); _ = window().open_with_url("https://discord.gg/YPxuprzu6M");
} }
@ -201,7 +201,7 @@ pub fn SiteHeader() -> impl IntoView {
<Button <Button
appearance=ButtonAppearance::Subtle appearance=ButtonAppearance::Subtle
icon=icondata::AiGithubOutlined icon=icondata::AiGithubOutlined
style="font-size: 22px; padding: 0px 6px;" attr:style="font-size: 22px; padding: 0px 6px;"
on_click=move |_| { on_click=move |_| {
_ = window().open_with_url("http://github.com/thaw-ui/thaw"); _ = window().open_with_url("http://github.com/thaw-ui/thaw");
} }

View file

@ -1,4 +1,4 @@
use leptos::*; use leptos::prelude::*;
use thaw::*; use thaw::*;
#[component] #[component]

View file

@ -1,5 +1,5 @@
mod app; mod app;
mod components; // mod components;
mod pages; mod pages;
pub use app::App; pub use app::App;

View file

@ -1,12 +1,10 @@
mod app; mod app;
mod components; // mod components;
mod pages; mod pages;
use app::App; use app::App;
use leptos::*; use leptos::prelude::*;
fn main() { fn main() {
#[cfg(feature = "tracing")]
leptos_devtools::devtools!();
mount_to_body(App) mount_to_body(App)
} }

View file

@ -1,7 +1,10 @@
use crate::components::SiteHeader; use crate::components::SiteHeader;
use leptos::*; use leptos::prelude::*;
use leptos_meta::Style; use leptos_meta::Style;
use leptos_router::{use_location, use_navigate, Outlet}; use leptos_router::{
components::Outlet,
hooks::{use_location, use_navigate},
};
use thaw::*; use thaw::*;
#[component] #[component]
@ -9,7 +12,7 @@ pub fn ComponentsPage() -> impl IntoView {
let navigate = use_navigate(); let navigate = use_navigate();
let loaction = use_location(); let loaction = use_location();
let select_name = create_rw_signal(String::new()); let select_name = RwSignal::new(String::new());
Effect::new(move |_| { Effect::new(move |_| {
select_name.set(loaction.pathname.get()); select_name.set(loaction.pathname.get());
}); });
@ -51,12 +54,27 @@ pub fn ComponentsPage() -> impl IntoView {
</Style> </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 attr:style="top: 64px;">
<div class="demo-components__sider"> <div class="demo-components__sider">
<NavDrawer selected_value=select_name> <NavDrawer selected_value=select_name>
{
{gen_menu_data().into_view()} gen_menu_data().into_iter().map(|data| {
let MenuGroupOption { label, children } = data;
view! {
<Caption1Strong attr:style="margin-inline-start: 10px; margin-top: 10px; display: inline-block">
{label}
</Caption1Strong>
{
children.into_iter().map(|item| {
let MenuItemOption { label, value } = item;
view! {
<NavItem value>{label}</NavItem>
}
}).collect_view()
}
}
}).collect_view()
}
</NavDrawer> </NavDrawer>
</div> </div>
<Layout content_style="padding: 8px 12px 28px; display: flex;" class="doc-content"> <Layout content_style="padding: 8px 12px 28px; display: flex;" class="doc-content">
@ -72,31 +90,11 @@ pub(crate) struct MenuGroupOption {
pub children: Vec<MenuItemOption>, pub children: Vec<MenuItemOption>,
} }
impl IntoView for MenuGroupOption {
fn into_view(self) -> View {
let Self { label, children } = self;
view! {
<Caption1Strong style="margin-inline-start: 10px; margin-top: 10px; display: inline-block">
{label}
</Caption1Strong>
{children.into_iter().map(|v| v.into_view()).collect_view()}
}
.into_view()
}
}
pub(crate) struct MenuItemOption { pub(crate) struct MenuItemOption {
pub label: String, pub label: String,
pub value: String, pub value: String,
} }
impl IntoView for MenuItemOption {
fn into_view(self) -> View {
let Self { label, value } = self;
view! { <NavItem value>{label}</NavItem> }
}
}
pub(crate) fn gen_menu_data() -> Vec<MenuGroupOption> { pub(crate) fn gen_menu_data() -> Vec<MenuGroupOption> {
vec![ vec![
MenuGroupOption { MenuGroupOption {

View file

@ -1,5 +1,6 @@
use leptos::*; use leptos::prelude::*;
use leptos_router::{use_navigate, use_query_map}; use leptos_router::hooks::{use_navigate, use_query_map};
// use leptos_router::{use_navigate, use_query_map};
use thaw::*; use thaw::*;
#[component] #[component]
@ -8,7 +9,7 @@ pub fn Home() -> impl IntoView {
// mobile page // mobile page
if let Some(path) = query_map.get("path") { if let Some(path) = query_map.get("path") {
let navigate = use_navigate(); let navigate = use_navigate();
navigate(path, Default::default()); navigate(&path, Default::default());
} }
view! { view! {
<Layout <Layout

View file

@ -1,5 +1,5 @@
use crate::components::{Demo, DemoCode}; use crate::components::{Demo, DemoCode};
use leptos::*; use leptos::prelude::*;
use thaw::*; use thaw::*;
demo_markdown::include_md! {} demo_markdown::include_md! {}

View file

@ -1,14 +1,14 @@
mod components; // mod components;
mod home; mod home;
mod markdown; // mod markdown;
// mod mobile; // mod mobile;
// mod nav_bar; // mod nav_bar;
// mod tabbar; // mod tabbar;
// mod toast; // mod toast;
pub use components::*; // pub use components::*;
pub use home::*; pub use home::*;
pub use markdown::*; // pub use markdown::*;
// pub use mobile::*; // pub use mobile::*;
// pub use nav_bar::*; // pub use nav_bar::*;
// pub use tabbar::*; // pub use tabbar::*;

View file

@ -26,7 +26,7 @@ view! {
### Icon ### Icon
```rust demo ```rust demo
let icon = create_rw_signal(Some(icondata::AiCloseOutlined)); let icon = RwSignal::new(Some(icondata::AiCloseOutlined));
let on_click = move |_| { let on_click = move |_| {
icon.update(|icon| { icon.update(|icon| {

View file

@ -2,7 +2,7 @@
```rust demo ```rust demo
use chrono::prelude::*; use chrono::prelude::*;
let value = create_rw_signal(Some(Local::now().date_naive())); let value = RwSignal::new(Some(Local::now().date_naive()));
view! { view! {
<Calendar value /> <Calendar value />

View file

@ -3,7 +3,7 @@
```rust demo ```rust demo
use palette::Srgb; use palette::Srgb;
let value = create_rw_signal(Color::from(Srgb::new(0.0, 0.0, 0.0))); let value = RwSignal::new(Color::from(Srgb::new(0.0, 0.0, 0.0)));
view! { view! {
<ColorPicker value/> <ColorPicker value/>
@ -17,9 +17,9 @@ Encoding formats, support RGB, HSV, HSL.
```rust demo ```rust demo
use palette::{Hsl, Hsv, Srgb}; use palette::{Hsl, Hsv, Srgb};
let rgb = create_rw_signal(Color::from(Srgb::new(0.0, 0.0, 0.0))); let rgb = RwSignal::new(Color::from(Srgb::new(0.0, 0.0, 0.0)));
let hsv = create_rw_signal(Color::from(Hsv::new(0.0, 0.0, 0.0))); let hsv = RwSignal::new(Color::from(Hsv::new(0.0, 0.0, 0.0)));
let hsl = create_rw_signal(Color::from(Hsl::new(0.0, 0.0, 0.0))); let hsl = RwSignal::new(Color::from(Hsl::new(0.0, 0.0, 0.0)));
view! { view! {
<Space vertical=true> <Space vertical=true>

View file

@ -2,7 +2,7 @@
```rust demo ```rust demo
use chrono::prelude::*; use chrono::prelude::*;
let value = create_rw_signal(Some(Local::now().date_naive())); let value = RwSignal::new(Some(Local::now().date_naive()));
view! { view! {
<DatePicker value/> <DatePicker value/>

View file

@ -59,7 +59,7 @@ view! {
### Invalid ### Invalid
```rust demo ```rust demo
let value = create_rw_signal(String::from("o")); let value = RwSignal::new(String::from("o"));
view! { view! {
<Space vertical=true> <Space vertical=true>
@ -71,8 +71,8 @@ view! {
### Imperative handle ### Imperative handle
```rust demo ```rust demo
let value = create_rw_signal(String::from("o")); let value = RwSignal::new(String::from("o"));
let input_ref = create_component_ref::<InputRef>(); let input_ref = ComponentRef::<InputRef>::new();
let focus = Callback::new(move |_| { let focus = Callback::new(move |_| {
input_ref.get_untracked().unwrap().focus() input_ref.get_untracked().unwrap().focus()

View file

@ -3,10 +3,10 @@
```rust demo ```rust demo
view! { view! {
<Layout> <Layout>
<LayoutHeader style="background-color: #0078ffaa; padding: 20px;"> <LayoutHeader attr:style="background-color: #0078ffaa; padding: 20px;">
"Header" "Header"
</LayoutHeader> </LayoutHeader>
<Layout style="background-color: #0078ff88; padding: 20px;">"Content"</Layout> <Layout attr:style="background-color: #0078ff88; padding: 20px;">"Content"</Layout>
</Layout> </Layout>
} }
``` ```
@ -16,14 +16,14 @@ view! {
```rust demo ```rust demo
view! { view! {
<Layout has_sider=true> <Layout has_sider=true>
<LayoutSider style="background-color: #0078ff99; padding: 20px;"> <LayoutSider attr:style="background-color: #0078ff99; padding: 20px;">
"Sider" "Sider"
</LayoutSider> </LayoutSider>
<Layout> <Layout>
<LayoutHeader style="background-color: #0078ffaa; padding: 20px;"> <LayoutHeader attr:style="background-color: #0078ffaa; padding: 20px;">
"Header" "Header"
</LayoutHeader> </LayoutHeader>
<Layout style="background-color: #0078ff88; padding: 20px;"> <Layout attr:style="background-color: #0078ff88; padding: 20px;">
"Content" "Content"
</Layout> </Layout>
</Layout> </Layout>

View file

@ -1,7 +1,7 @@
# Select # Select
```rust demo ```rust demo
let value = create_rw_signal(None::<String>); let value = RwSignal::new(None::<String>);
let options = vec![ let options = vec![
SelectOption::new("RwSignal", String::from("rw_signal")), SelectOption::new("RwSignal", String::from("rw_signal")),
@ -16,7 +16,7 @@ view! {
# Multiple Select # Multiple Select
```rust demo ```rust demo
let value = create_rw_signal(vec![ let value = RwSignal::new(vec![
"rust".to_string(), "rust".to_string(),
"javascript".to_string(), "javascript".to_string(),
"zig".to_string(), "zig".to_string(),

View file

@ -3,7 +3,7 @@
```rust demo ```rust demo
use chrono::prelude::*; use chrono::prelude::*;
let value = create_rw_signal(Some(Local::now().time())); let value = RwSignal::new(Some(Local::now().time()));
view! { view! {
<TimePicker value /> <TimePicker value />

View file

@ -2,7 +2,7 @@
```rust demo ```rust demo
let message = use_message(); let message = use_message();
let custom_request = move |file_list: FileList| { let custom_request = move |file_list| {
message.create( message.create(
format!("Number of uploaded files: {}", file_list.length()), format!("Number of uploaded files: {}", file_list.length()),
MessageVariant::Success, MessageVariant::Success,
@ -23,7 +23,7 @@ view!{
```rust demo ```rust demo
let message = use_message(); let message = use_message();
let custom_request = move |file_list: FileList| { let custom_request = move |file_list| {
message.create( message.create(
format!("Number of uploaded files: {}", file_list.length()), format!("Number of uploaded files: {}", file_list.length()),
MessageVariant::Success, MessageVariant::Success,

View file

@ -28,8 +28,7 @@ pub fn to_tokens(code_block: &NodeCodeBlock, demos: &mut Vec<String>) -> TokenSt
quote! { quote! {
<Demo> <Demo>
<#demo /> <#demo />
<DemoCode slot is_highlight=#is_highlight> <DemoCode slot is_highlight=#is_highlight text=#literal>
#literal
</DemoCode> </DemoCode>
</Demo> </Demo>
} }
@ -45,8 +44,7 @@ pub fn to_tokens(code_block: &NodeCodeBlock, demos: &mut Vec<String>) -> TokenSt
}); });
quote! { quote! {
<Demo> <Demo>
<DemoCode slot is_highlight=#is_highlight> <DemoCode slot is_highlight=#is_highlight text=#literal>
#literal
</DemoCode> </DemoCode>
</Demo> </Demo>
} }

View file

@ -4,13 +4,14 @@ pub use upload_dragger::UploadDragger;
pub use web_sys::FileList; pub use web_sys::FileList;
use leptos::{ev, html, prelude::*}; use leptos::{ev, html, prelude::*};
use send_wrapper::SendWrapper;
use thaw_utils::{add_event_listener, mount_style}; use thaw_utils::{add_event_listener, mount_style};
#[component] #[component]
pub fn Upload( pub fn Upload(
#[prop(optional, into)] accept: MaybeSignal<String>, #[prop(optional, into)] accept: MaybeSignal<String>,
#[prop(optional, into)] multiple: MaybeSignal<bool>, #[prop(optional, into)] multiple: MaybeSignal<bool>,
#[prop(optional, into)] custom_request: Option<Callback<FileList, ()>>, #[prop(optional, into)] custom_request: Option<Callback<SendWrapper<FileList>, ()>>,
children: Children, children: Children,
) -> impl IntoView { ) -> impl IntoView {
mount_style("upload", include_str!("./upload.css")); mount_style("upload", include_str!("./upload.css"));
@ -34,7 +35,7 @@ pub fn Upload(
let on_file_addition = move |files: FileList| { let on_file_addition = move |files: FileList| {
if let Some(custom_request) = custom_request { if let Some(custom_request) = custom_request {
custom_request.call(files); custom_request.call(SendWrapper::new(files));
} }
}; };

View file

@ -1,5 +1,5 @@
use cfg_if::cfg_if; use cfg_if::cfg_if;
use leptos::prelude::*; use leptos::{children, prelude::*};
use tachys::view::any_view::AnyView; use tachys::view::any_view::AnyView;
/// https://github.com/solidjs/solid/blob/main/packages/solid/web/src/index.ts#L56 /// https://github.com/solidjs/solid/blob/main/packages/solid/web/src/index.ts#L56
@ -10,58 +10,67 @@ pub fn Teleport(
#[prop(optional, into)] element: Option<AnyView<Dom>>, #[prop(optional, into)] element: Option<AnyView<Dom>>,
#[prop(optional)] children: Option<Children>, #[prop(optional)] children: Option<Children>,
) -> impl IntoView { ) -> impl IntoView {
cfg_if! { if #[cfg(all(target_arch = "wasm32", any(feature = "csr", feature = "hydrate")))] { // cfg_if! { if #[cfg(all(target_arch = "wasm32", any(feature = "csr", feature = "hydrate")))] {
let mount_fn = StoredValue::new(None::<Box<dyn FnOnce() -> ()>>); let mount_fn = StoredValue::new(None::<Box<dyn FnOnce() + Send + Sync>>);
let mount = send_wrapper::SendWrapper::new(mount);
let element = send_wrapper::SendWrapper::new(element);
let children = send_wrapper::SendWrapper::new(children);
mount_fn.set_value(Some(Box::new(move || { mount_fn.set_value(Some(Box::new(move || {
let mount = mount.unwrap_or_else(|| { let mount = if let Some(el) = mount.take() {
el
} else {
use leptos::wasm_bindgen::JsCast; use leptos::wasm_bindgen::JsCast;
document() document()
.body() .body()
.expect("body element to exist") .expect("body element to exist")
.unchecked_into() .unchecked_into()
}); };
if let Some(element) = element { if let Some(element) = element.take() {
let render_root = element; let render_root = element;
let _ = mount.append_child(&render_root); let mut mountable = render_root.build();
on_cleanup(move || { mountable.mount(&mount, None);
let _ = mount.remove_child(&render_root); // TODO
}); // on_cleanup(move || {
} else if let Some(children) = children { // mountable.unmount();
// });
} else if let Some(children) = children.take() {
let container = document() let container = document()
.create_element("div") .create_element("div")
.expect("element creation to work"); .expect("element creation to work");
thaw_utils::with_hydration_off(|| { thaw_utils::with_hydration_off(|| {
use leptos::leptos_dom::Mountable; // use leptos::leptos_dom::Mountable;
let _ = container.append_child(&children().into_view().get_mountable_node()); // let _ = container.append_child(&children().into_view().get_mountable_node());
let view = children().into_view();
let mut mountable = view.build();
mountable.mount(&container, None);
}); });
let render_root = container; let render_root = container;
let _ = mount.append_child(&render_root); let _ = mount.append_child(&render_root);
on_cleanup(move || { // on_cleanup(move || {
let _ = mount.remove_child(&render_root); // let _ = mount.remove_child(&render_root);
}); // });
} }
}))); })));
let owner = Owner::current(); let owner = Owner::current().unwrap();
Effect::new(move |_| { Effect::new(move |_| {
if immediate.get() { if immediate.get() {
mount_fn.update_value(|mount_fn| { mount_fn.update_value(|mount_fn| {
if let Some(f) = mount_fn.take() { if let Some(f) = mount_fn.take() {
with_owner(owner.unwrap(), move || { owner.with(|| {
f(); f();
}); });
} }
}); });
} }
}); });
} else { // } else {
let _ = mount; // let _ = mount;
let _ = immediate; // let _ = immediate;
let _ = element; // let _ = element;
let _ = children; // let _ = children;
}} // }}
} }