mirror of
https://github.com/adoyle0/thaw.git
synced 2025-01-23 06:19:22 -05:00
feat(leptos-v0.7): error
This commit is contained in:
parent
4262493f61
commit
58b7eb35aa
8 changed files with 60 additions and 108 deletions
|
@ -4,9 +4,7 @@ pub use auto_complete_option::AutoCompleteOption;
|
||||||
|
|
||||||
use crate::{ComponentRef, ConfigInjection, Input, InputPrefix, InputRef, InputSuffix};
|
use crate::{ComponentRef, ConfigInjection, Input, InputPrefix, InputRef, InputSuffix};
|
||||||
use leptos::{context::Provider, either::Either, html, prelude::*};
|
use leptos::{context::Provider, either::Either, html, prelude::*};
|
||||||
use thaw_components::{
|
use thaw_components::{Binder, CSSTransition, Follower, FollowerPlacement, FollowerWidth};
|
||||||
Binder, CSSTransition, Follower, FollowerPlacement, FollowerWidth, OptionComp,
|
|
||||||
};
|
|
||||||
use thaw_utils::{class_list, mount_style, Model, OptionalProp};
|
use thaw_utils::{class_list, mount_style, Model, OptionalProp};
|
||||||
|
|
||||||
#[slot]
|
#[slot]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{ConfigInjection, Icon};
|
use crate::{ConfigInjection, Icon};
|
||||||
use leptos::{ev, html, prelude::*};
|
use leptos::{either::Either, ev, html, prelude::*};
|
||||||
use thaw_components::{CSSTransition, Fallback, OptionComp, Teleport};
|
use thaw_components::{CSSTransition, Teleport};
|
||||||
use thaw_utils::{
|
use thaw_utils::{
|
||||||
add_event_listener, class_list, get_scroll_parent, mount_style, EventListenerHandle,
|
add_event_listener, class_list, get_scroll_parent, mount_style, EventListenerHandle,
|
||||||
OptionalProp,
|
OptionalProp,
|
||||||
|
@ -93,12 +93,13 @@ pub fn BackTop(
|
||||||
}
|
}
|
||||||
on:click=on_click
|
on:click=on_click
|
||||||
>
|
>
|
||||||
<OptionComp value=children let:children>
|
{
|
||||||
<Fallback slot>
|
if let Some(children) = children {
|
||||||
<Icon icon=icondata_ai::AiVerticalAlignTopOutlined/>
|
Either::Left(children())
|
||||||
</Fallback>
|
} else {
|
||||||
{children()}
|
Either::Right(view!{<Icon icon=icondata_ai::AiVerticalAlignTopOutlined/>})
|
||||||
</OptionComp>
|
}
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</CSSTransition>
|
</CSSTransition>
|
||||||
</Teleport>
|
</Teleport>
|
||||||
|
|
|
@ -5,7 +5,6 @@ pub use button_group::ButtonGroup;
|
||||||
use crate::icon::Icon;
|
use crate::icon::Icon;
|
||||||
use leptos::{either::Either, ev, prelude::*};
|
use leptos::{either::Either, ev, prelude::*};
|
||||||
use send_wrapper::SendWrapper;
|
use send_wrapper::SendWrapper;
|
||||||
use thaw_components::OptionComp;
|
|
||||||
use thaw_utils::{class_list, mount_style, OptionalMaybeSignal, OptionalProp};
|
use thaw_utils::{class_list, mount_style, OptionalMaybeSignal, OptionalProp};
|
||||||
|
|
||||||
#[derive(Default, PartialEq, Clone, Copy)]
|
#[derive(Default, PartialEq, Clone, Copy)]
|
||||||
|
@ -115,10 +114,10 @@ pub fn Button(
|
||||||
|
|
||||||
move || {
|
move || {
|
||||||
let icon = icon.get();
|
let icon = icon.get();
|
||||||
view! {
|
if let Some(icon) = icon {
|
||||||
<OptionComp value=icon let:icon>
|
Either::Left(view!{<Icon icon=icon class="thaw-button__icon"/>})
|
||||||
<Icon icon=icon class="thaw-button__icon"/>
|
} else {
|
||||||
</OptionComp>
|
Either::Right(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,12 +7,12 @@ use leptos::leptos_dom::helpers::WindowListenerHandle;
|
||||||
use leptos::{ev, html, prelude::*};
|
use leptos::{ev, html, prelude::*};
|
||||||
use palette::{Hsv, IntoColor, Srgb};
|
use palette::{Hsv, IntoColor, Srgb};
|
||||||
use thaw_components::{Binder, CSSTransition, Follower, FollowerPlacement};
|
use thaw_components::{Binder, CSSTransition, Follower, FollowerPlacement};
|
||||||
use thaw_utils::{class_list, mount_style, Model, OptionalProp};
|
use thaw_utils::{class_list, mount_style, Model};
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn ColorPicker(
|
pub fn ColorPicker(
|
||||||
#[prop(optional, into)] value: Model<Color>,
|
#[prop(optional, into)] value: Model<Color>,
|
||||||
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>,
|
#[prop(optional, into)] class: MaybeProp<String>,
|
||||||
) -> impl IntoView {
|
) -> impl IntoView {
|
||||||
mount_style("color-picker", include_str!("./color-picker.css"));
|
mount_style("color-picker", include_str!("./color-picker.css"));
|
||||||
let config_provider = ConfigInjection::use_();
|
let config_provider = ConfigInjection::use_();
|
||||||
|
@ -106,6 +106,12 @@ pub fn ColorPicker(
|
||||||
{
|
{
|
||||||
use leptos::wasm_bindgen::__rt::IntoJsResult;
|
use leptos::wasm_bindgen::__rt::IntoJsResult;
|
||||||
let timer = window_event_listener(ev::click, move |ev| {
|
let timer = window_event_listener(ev::click, move |ev| {
|
||||||
|
let Some(popovel_el) = popover_ref.get_untracked() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let Some(trigger_el) = trigger_ref.get_untracked() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
let el = ev.target();
|
let el = ev.target();
|
||||||
let mut el: Option<web_sys::Element> =
|
let mut el: Option<web_sys::Element> =
|
||||||
el.into_js_result().map_or(None, |el| Some(el.into()));
|
el.into_js_result().map_or(None, |el| Some(el.into()));
|
||||||
|
@ -114,9 +120,7 @@ pub fn ColorPicker(
|
||||||
if current_el == *body {
|
if current_el == *body {
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
if current_el == **popover_ref.get().unwrap()
|
if current_el == **popovel_el || current_el == **trigger_el {
|
||||||
|| current_el == **trigger_ref.get().unwrap()
|
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
el = current_el.parent_element();
|
el = current_el.parent_element();
|
||||||
|
@ -129,7 +133,7 @@ pub fn ColorPicker(
|
||||||
view! {
|
view! {
|
||||||
<Binder target_ref=trigger_ref>
|
<Binder target_ref=trigger_ref>
|
||||||
<div
|
<div
|
||||||
class=class_list!["thaw-color-picker-trigger", class.map(| c | move || c.get())]
|
class=class_list!["thaw-color-picker-trigger", class]
|
||||||
on:click=show_popover
|
on:click=show_popover
|
||||||
node_ref=trigger_ref
|
node_ref=trigger_ref
|
||||||
>
|
>
|
||||||
|
|
|
@ -19,35 +19,16 @@ pub fn OverlayDrawer(
|
||||||
let config_provider = ConfigInjection::use_();
|
let config_provider = ConfigInjection::use_();
|
||||||
let drawer_ref = NodeRef::<html::Div>::new();
|
let drawer_ref = NodeRef::<html::Div>::new();
|
||||||
|
|
||||||
let is_css_transition = RwSignal::new(false);
|
|
||||||
let on_after_enter = move |_| {
|
|
||||||
is_css_transition.set(false);
|
|
||||||
};
|
|
||||||
let lazy_position = Memo::new(move |prev| {
|
|
||||||
let position = position.get().as_str();
|
|
||||||
let Some(prev) = prev else {
|
|
||||||
return position;
|
|
||||||
};
|
|
||||||
|
|
||||||
if is_css_transition.get() {
|
|
||||||
prev
|
|
||||||
} else {
|
|
||||||
position
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let is_lock = RwSignal::new(open.get_untracked());
|
let is_lock = RwSignal::new(open.get_untracked());
|
||||||
Effect::new(move |_| {
|
Effect::new(move |_| {
|
||||||
let is_open = open.get();
|
let is_open = open.get();
|
||||||
if is_open {
|
if is_open {
|
||||||
is_lock.set(true);
|
is_lock.set(true);
|
||||||
is_css_transition.set(true);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
use_lock_html_scroll(is_lock.into());
|
use_lock_html_scroll(is_lock.into());
|
||||||
let on_after_leave = move |_| {
|
let on_after_leave = move |_| {
|
||||||
is_lock.set(false);
|
is_lock.set(false);
|
||||||
is_css_transition.set(false);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mask_ref = NodeRef::<html::Div>::new();
|
let mask_ref = NodeRef::<html::Div>::new();
|
||||||
|
@ -83,17 +64,16 @@ pub fn OverlayDrawer(
|
||||||
appear=open.get_untracked()
|
appear=open.get_untracked()
|
||||||
show=open.signal()
|
show=open.signal()
|
||||||
name=Memo::new(move |_| {
|
name=Memo::new(move |_| {
|
||||||
format!("slide-in-from-{}-transition", lazy_position.get())
|
format!("slide-in-from-{}-transition", position.get().as_str())
|
||||||
})
|
})
|
||||||
|
|
||||||
on_after_enter
|
|
||||||
on_after_leave
|
on_after_leave
|
||||||
let:display
|
let:display
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class=class_list![
|
class=class_list![
|
||||||
"thaw-overlay-drawer",
|
"thaw-overlay-drawer",
|
||||||
move || format!("thaw-overlay-drawer--position-{}", lazy_position.get())
|
move || format!("thaw-overlay-drawer--position-{}", position.get().as_str())
|
||||||
]
|
]
|
||||||
|
|
||||||
style=move || {
|
style=move || {
|
||||||
|
|
|
@ -13,9 +13,7 @@ use leptos::{
|
||||||
leptos_dom::helpers::WindowListenerHandle,
|
leptos_dom::helpers::WindowListenerHandle,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
use thaw_utils::{
|
use thaw_utils::{add_event_listener, get_scroll_parent, mount_style, EventListenerHandle};
|
||||||
add_event_listener, get_scroll_parent, mount_style, with_hydration_off, EventListenerHandle,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[slot]
|
#[slot]
|
||||||
pub struct Follower {
|
pub struct Follower {
|
||||||
|
@ -193,19 +191,19 @@ where
|
||||||
remove_listener();
|
remove_listener();
|
||||||
});
|
});
|
||||||
|
|
||||||
let teleport_children = with_hydration_off(|| {
|
|
||||||
html::div().class("thaw-binder-follower-container").child(
|
|
||||||
html::div()
|
|
||||||
.class("thaw-binder-follower-content")
|
|
||||||
.attr("data-thaw-placement", move || placement_str.get())
|
|
||||||
.node_ref(content_ref)
|
|
||||||
.attr("style", move || content_style.get())
|
|
||||||
.child(follower_children()),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
{children()}
|
{children()}
|
||||||
<Teleport element=teleport_children.into_any() immediate=follower_show/>
|
<Teleport immediate=follower_show>
|
||||||
|
<div class="thaw-binder-follower-container">
|
||||||
|
<div
|
||||||
|
class="thaw-binder-follower-content"
|
||||||
|
data-thaw-placement=move || placement_str.get()
|
||||||
|
node_ref=content_ref
|
||||||
|
style=move || content_style.get()
|
||||||
|
>
|
||||||
|
{follower_children()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Teleport>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,5 +17,5 @@ where
|
||||||
(fallback.children)().into_any()
|
(fallback.children)().into_any()
|
||||||
} else {
|
} else {
|
||||||
().into_any()
|
().into_any()
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,74 +1,46 @@
|
||||||
|
use std::cell::Cell;
|
||||||
|
|
||||||
use cfg_if::cfg_if;
|
use cfg_if::cfg_if;
|
||||||
use leptos::{children, prelude::*};
|
use leptos::prelude::*;
|
||||||
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
|
||||||
#[component]
|
#[component]
|
||||||
pub fn Teleport(
|
pub fn Teleport(
|
||||||
#[prop(default = true.into(), into)] immediate: MaybeSignal<bool>,
|
#[prop(default = true.into(), into)] immediate: MaybeSignal<bool>,
|
||||||
#[prop(into, optional)] mount: Option<web_sys::Element>,
|
#[prop(into, optional)] mount: Option<web_sys::Element>,
|
||||||
#[prop(optional, into)] element: Option<AnyView<Dom>>,
|
children: 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() + Send + Sync>>);
|
let mount_fn: Cell<Option<Box<dyn FnOnce() -> ()>>> = Cell::new(Some(Box::new(move || {
|
||||||
let mount = send_wrapper::SendWrapper::new(mount);
|
let mount = if let Some(el) = mount.as_ref() {
|
||||||
let element = send_wrapper::SendWrapper::new(element);
|
|
||||||
let children = send_wrapper::SendWrapper::new(children);
|
|
||||||
mount_fn.set_value(Some(Box::new(move || {
|
|
||||||
let mount = if let Some(el) = mount.take() {
|
|
||||||
el
|
el
|
||||||
} else {
|
} 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.take() {
|
let mountable = {
|
||||||
let render_root = element;
|
|
||||||
let mut mountable = render_root.build();
|
|
||||||
mountable.mount(&mount, None);
|
|
||||||
on_cleanup({
|
|
||||||
let mut mountable = send_wrapper::SendWrapper::new(mountable);
|
|
||||||
move || {
|
|
||||||
mountable.unmount();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if let Some(children) = children.take() {
|
|
||||||
let container = document()
|
|
||||||
.create_element("div")
|
|
||||||
.expect("element creation to work");
|
|
||||||
|
|
||||||
let mountable = thaw_utils::with_hydration_off(|| {
|
|
||||||
let view = children().into_view();
|
let view = children().into_view();
|
||||||
let mut mountable = view.build();
|
let mut mountable = view.build();
|
||||||
mountable.mount(&container, None);
|
mountable.mount(mount, None);
|
||||||
mountable
|
mountable
|
||||||
});
|
};
|
||||||
|
|
||||||
let render_root = container;
|
|
||||||
let _ = mount.append_child(&render_root);
|
|
||||||
on_cleanup({
|
on_cleanup({
|
||||||
let mount = send_wrapper::SendWrapper::new(mount);
|
|
||||||
let render_root = send_wrapper::SendWrapper::new(render_root);
|
|
||||||
let mut mountable = send_wrapper::SendWrapper::new(mountable);
|
let mut mountable = send_wrapper::SendWrapper::new(mountable);
|
||||||
move || {
|
move || {
|
||||||
mountable.unmount();
|
mountable.unmount();
|
||||||
let _ = mount.remove_child(&render_root);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
})));
|
})));
|
||||||
|
|
||||||
let owner = Owner::current().unwrap();
|
let owner = Owner::current().unwrap();
|
||||||
Effect::new(move |_| {
|
Effect::new(move |_| {
|
||||||
if immediate.get() {
|
if immediate.get() {
|
||||||
let Some(f) = mount_fn
|
let Some(f) = mount_fn.take() else {
|
||||||
.try_update_value(|mount_fn| mount_fn.take())
|
|
||||||
.flatten()
|
|
||||||
else {
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue