diff --git a/src/auto_complete/mod.rs b/src/auto_complete/mod.rs index 8d6fa83..998d54d 100644 --- a/src/auto_complete/mod.rs +++ b/src/auto_complete/mod.rs @@ -1,7 +1,7 @@ mod theme; use crate::{ - components::{Binder, Follower, FollowerPlacement}, + components::{Binder, Follower, FollowerPlacement, FollowerWidth}, mount_style, use_theme, utils::StoredMaybeSignal, Input, Theme, @@ -61,7 +61,7 @@ pub fn AutoComplete( allow_value /> - +
) -> impl IntoVi let trigger_ref = create_node_ref::(); let popover_ref = create_node_ref::(); let show_popover = move |_| { - let rect = trigger_ref.get().unwrap().get_bounding_client_rect(); is_show_popover.set(true); - if let Some(popover_ref) = popover_ref.get() { - _ = popover_ref.style( - "transform", - format!( - "translateX({}px) translateY({}px)", - rect.x(), - rect.y() + rect.height() - ), - ); - } }; let timer = window_event_listener(ev::click, move |ev| { let el = ev.target(); @@ -96,28 +86,24 @@ pub fn ColorPicker(#[prop(optional, into)] value: RwSignal) -> impl IntoVi on_cleanup(move || timer.remove()); view! { -
-
- {move || label.get()} + +
+
+ {move || label.get()} +
-
- -
+ +
- - -
- + + +
+ + } } diff --git a/src/components/binder/get_placement_style.rs b/src/components/binder/get_placement_style.rs index 79ab2df..58554d4 100644 --- a/src/components/binder/get_placement_style.rs +++ b/src/components/binder/get_placement_style.rs @@ -32,19 +32,17 @@ pub fn get_follower_placement_style( let follower_height = follower_rect.height(); let target_y = target_rect.y(); let target_height = target_rect.height(); - let mut top = target_y + target_height; + let top = target_y + target_height; let Some(inner_height) = window_inner_height() else { return None; }; - if top + follower_height > inner_height { - if target_y - follower_height >= 0.0 { - top = target_y - follower_height - } + if top + follower_height > inner_height && target_y - follower_height >= 0.0 { + target_y - follower_height + } else { + top } - - top }; style.push_str(&format!( diff --git a/src/components/binder/mod.rs b/src/components/binder/mod.rs index 15990d9..56ba572 100644 --- a/src/components/binder/mod.rs +++ b/src/components/binder/mod.rs @@ -17,10 +17,20 @@ use leptos::{ pub struct Follower { #[prop(into)] show: MaybeSignal, + #[prop(optional)] + width: Option, placement: FollowerPlacement, children: Children, } +#[derive(Clone)] +pub enum FollowerWidth { + Target, + Px(u32), +} + +impl Copy for FollowerWidth {} + #[component] pub fn Binder( #[prop(into)] target_ref: NodeRef, @@ -30,6 +40,7 @@ pub fn Binder( mount_style("binder", include_str!("./binder.css")); let Follower { show: follower_show, + width: follower_width, placement: follower_placement, children: follower_children, } = follower; @@ -73,7 +84,7 @@ pub fn Binder( let remove_scroll_listener = move |_| { scrollable_element_handle_vec.update_value(|vec| { - vec.drain(..).into_iter().for_each(|handle| handle.remove()); + vec.drain(..).for_each(|handle| handle.remove()); }); scroll_listener.set_value(None); }; @@ -108,6 +119,7 @@ pub fn Binder( ( fn FollowerContainer( show: MaybeSignal, target_ref: NodeRef, + width: Option, placement: FollowerPlacement, #[prop(into)] add_scroll_listener: Callback>, #[prop(into)] remove_scroll_listener: Callback<()>, @@ -142,7 +155,13 @@ fn FollowerContainer( let target_rect = target_ref.get_bounding_client_rect(); let content_rect = content_ref.get_bounding_client_rect(); let mut style = String::new(); - style.push_str(&format!("width: {}px;", target_rect.width())); + if let Some(width) = width { + let width = match width { + FollowerWidth::Target => format!("width: {}px;", target_rect.width()), + FollowerWidth::Px(width) => format!("width: {width}px;"), + }; + style.push_str(&width); + } if let Some(placement_style) = get_follower_placement_style(placement, target_rect, content_rect) { diff --git a/src/select/mod.rs b/src/select/mod.rs index 4aa86df..e5f329c 100644 --- a/src/select/mod.rs +++ b/src/select/mod.rs @@ -1,6 +1,11 @@ mod theme; -use crate::{teleport::Teleport, theme::use_theme, utils::mount_style::mount_style, Theme}; +use crate::{ + components::{Binder, Follower, FollowerPlacement, FollowerWidth}, + theme::use_theme, + utils::mount_style::mount_style, + Theme, +}; use leptos::wasm_bindgen::__rt::IntoJsResult; use leptos::*; use std::hash::Hash; @@ -66,20 +71,7 @@ where let trigger_ref = create_node_ref::(); let menu_ref = create_node_ref::(); let show_menu = move |_| { - let rect = trigger_ref.get().unwrap().get_bounding_client_rect(); is_show_menu.set(true); - if let Some(menu_ref) = menu_ref.get() { - _ = menu_ref - .style("width", format!("{}px", rect.width())) - .style( - "transform", - format!( - "translateX({}px) translateY({}px) translateX(-50%)", - rect.x() + rect.width() / 2.0, - rect.y() + rect.height() - ), - ); - } }; let timer = window_event_listener(ev::click, move |ev| { let el = ev.target(); @@ -111,47 +103,46 @@ where None => String::new(), }); view! { -
+ +
- {move || select_option_label.get()} - -
- -
- - {item.get_value().label} -
- } - } - /> + {move || select_option_label.get()}
-
+ +
+ + {item.get_value().label} +
+ } + } + /> + +
+ + } } diff --git a/src/select/select.css b/src/select/select.css index ac69e62..702454f 100644 --- a/src/select/select.css +++ b/src/select/select.css @@ -21,16 +21,12 @@ background-color: var(--thaw-background-color); box-sizing: border-box; padding: 5px; - position: absolute; - top: 0; - left: 0; - right: 0; + width: 100%; max-height: 200px; border-radius: 3px; box-shadow: 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 9px 28px 8px rgba(0, 0, 0, 0.05); overflow: auto; - z-index: 1000; } .thaw-select-menu__item {