diff --git a/packages/dom/src/platform/get_clipping_rect.rs b/packages/dom/src/platform/get_clipping_rect.rs index 5a2afd6..c0f4fc0 100644 --- a/packages/dom/src/platform/get_clipping_rect.rs +++ b/packages/dom/src/platform/get_clipping_rect.rs @@ -15,6 +15,7 @@ use crate::{ utils::{ get_bounding_client_rect::get_bounding_client_rect, get_document_rect::get_document_rect, get_viewport_rect::get_viewport_rect, get_visual_offsets::get_visual_offsets, + is_top_layer::is_top_layer, }, }; @@ -172,7 +173,10 @@ pub fn get_clipping_rect( // TODO: cache let clipping_element_ancestors = match boundary { - floating_ui_core::Boundary::ClippingAncestors => get_clipping_element_ancestors(element), + floating_ui_core::Boundary::ClippingAncestors => match is_top_layer(element) { + true => vec![], + false => get_clipping_element_ancestors(element), + }, _ => vec![], }; diff --git a/packages/dom/src/platform/get_offset_parent.rs b/packages/dom/src/platform/get_offset_parent.rs index e45aaa3..e15255f 100644 --- a/packages/dom/src/platform/get_offset_parent.rs +++ b/packages/dom/src/platform/get_offset_parent.rs @@ -1,11 +1,12 @@ use floating_ui_utils::dom::{ - get_computed_style, get_containing_block, get_node_name, get_window, is_containing_block, - is_html_element, is_table_element, + get_computed_style, get_containing_block, get_parent_node, get_window, is_containing_block, + is_element, is_html_element, is_last_traversable_node, is_table_element, }; use floating_ui_utils::OwnedElementOrWindow; use web_sys::Window; use web_sys::{wasm_bindgen::JsCast, Element, HtmlElement}; +use crate::utils::is_static_positioned::is_static_positioned; use crate::utils::is_top_layer::is_top_layer; pub type Polyfill = Box Option>; @@ -40,15 +41,28 @@ pub fn get_offset_parent( return OwnedElementOrWindow::Window(window); } + if !is_html_element(element) { + let mut svg_offset_parent = Some(get_parent_node(element)); + while let Some(parent) = svg_offset_parent.as_ref() { + if is_last_traversable_node(parent) { + break; + } + + if is_element(parent) { + let element = parent.unchecked_ref::(); + if !is_static_positioned(element) { + return OwnedElementOrWindow::Element(element.clone()); + } + } + svg_offset_parent = Some(get_parent_node(parent)) + } + return OwnedElementOrWindow::Window(window); + } + let mut offset_parent = get_true_offset_parent(element, &polyfill); while let Some(parent) = offset_parent.as_ref() { - if is_table_element(parent) - && get_computed_style(parent) - .get_property_value("position") - .expect("Computed style should have position.") - == "static" - { + if is_table_element(parent) && is_static_positioned(parent) { offset_parent = get_true_offset_parent(parent, &polyfill); } else { break; @@ -56,15 +70,9 @@ pub fn get_offset_parent( } if let Some(parent) = offset_parent.as_ref() { - let node_name = get_node_name(parent.into()); - - if node_name == "html" - || node_name == "body" - && get_computed_style(parent) - .get_property_value("position") - .expect("Computed style should have position.") - == "static" - && !is_containing_block(parent) + if is_last_traversable_node(parent) + && is_static_positioned(parent) + && !is_containing_block(parent) { return OwnedElementOrWindow::Window(window); } diff --git a/packages/dom/src/utils.rs b/packages/dom/src/utils.rs index 7493d48..c94f43f 100644 --- a/packages/dom/src/utils.rs +++ b/packages/dom/src/utils.rs @@ -5,4 +5,5 @@ pub mod get_rect_relative_to_offset_parent; pub mod get_viewport_rect; pub mod get_visual_offsets; pub mod get_window_scroll_bar_x; +pub mod is_static_positioned; pub mod is_top_layer; diff --git a/packages/dom/src/utils/is_static_positioned.rs b/packages/dom/src/utils/is_static_positioned.rs new file mode 100644 index 0000000..7557080 --- /dev/null +++ b/packages/dom/src/utils/is_static_positioned.rs @@ -0,0 +1,9 @@ +use floating_ui_utils::dom::get_computed_style; +use web_sys::Element; + +pub fn is_static_positioned(element: &Element) -> bool { + get_computed_style(element) + .get_property_value("position") + .expect("Computed style should have position.") + == "static" +} diff --git a/packages/leptos/tests/visual/src/spec/arrow.rs b/packages/leptos/tests/visual/src/spec/arrow.rs index 741e3cc..0701e1e 100644 --- a/packages/leptos/tests/visual/src/spec/arrow.rs +++ b/packages/leptos/tests/visual/src/spec/arrow.rs @@ -27,14 +27,13 @@ pub fn Arrow() -> impl IntoView { let (svg, set_svg) = create_signal(false); let (center_offset, set_center_offset) = create_signal(false); let (add_offset, set_add_offset) = create_signal(false); + let (nested, set_nested) = create_signal(false); let UseFloatingReturn { - x, - y, - strategy, update, placement: resultant_placement, middleware_data, + floating_styles, .. } = use_floating( reference_ref.into_reference(), @@ -71,6 +70,9 @@ pub fn Arrow() -> impl IntoView { let arrow_y = move || arrow_data().and_then(|arrow_data| arrow_data.y); let center_offset_value = move || arrow_data().map(|arrow_data| arrow_data.center_offset); + let svg_update = update.clone(); + let nested_update = update.clone(); + let UseScrollReturn { scroll_ref, update_scroll, @@ -88,6 +90,108 @@ pub fn Arrow() -> impl IntoView { let add_offset_update_scroll = update_scroll.clone(); let center_offset_update_scroll = update_scroll.clone(); + let floating_view = move || { + let base = view! { + {move || match center_offset() { + true => center_offset_value().map_or("".into(), |center_offset_value| center_offset_value.to_string()), + false => "Floating".into() + }} + + {move || match svg() { + true => view!{ + "-15px".into(), + _ => match arrow_y() { + Some(arrow_y) => format!("{}px", arrow_y), + None => "".into() + } + } + style:right=move || match static_side() { + Side::Right => "-15px", + _ => "" + } + style:bottom=move || match static_side() { + Side::Bottom => "-15px", + _ => "" + } + style:left=move || match static_side() { + Side::Left => "-15px".into(), + _ => match arrow_x() { + Some(arrow_x) => format!("{}px", arrow_x), + None => "".into() + } + } + /> + }.into_any().node_ref(arrow_ref), + false => view!{ +
"-15px".into(), + _ => match arrow_y() { + Some(arrow_y) => format!("{}px", arrow_y), + None => "".into() + } + } + style:right=move || match static_side() { + Side::Right => "-15px", + _ => "" + } + style:bottom=move || match static_side() { + Side::Bottom => "-15px", + _ => "" + } + style:left=move || match static_side() { + Side::Left => "-15px".into(), + _ => match arrow_x() { + Some(arrow_x) => format!("{}px", arrow_x), + None => "".into() + } + } + /> + }.into_any().node_ref(arrow_ref) + }} + }; + + match nested() { + true => view! { +
+
+ {base} +
+
+ }, + false => view! { +
+ {base} +
+ }, + } + }; + view! {

Arrow

@@ -104,79 +208,7 @@ pub fn Arrow() -> impl IntoView { > Reference
-
- {move || match center_offset() { - true => center_offset_value().map_or("".into(), |center_offset_value| center_offset_value.to_string()), - false => "Floating".into() - }} - - {move || match svg() { - true => view!{ - "-15px".into(), - _ => match arrow_y() { - Some(arrow_y) => format!("{}px", arrow_y), - None => "".into() - } - } - style:right=move || match static_side() { - Side::Right => "-15px", - _ => "" - } - style:bottom=move || match static_side() { - Side::Bottom => "-15px", - _ => "" - } - style:left=move || match static_side() { - Side::Left => "-15px".into(), - _ => match arrow_x() { - Some(arrow_x) => format!("{}px", arrow_x), - None => "".into() - } - } - /> - }.into_any().node_ref(arrow_ref), - false => view!{ -
"-15px".into(), - _ => match arrow_y() { - Some(arrow_y) => format!("{}px", arrow_y), - None => "".into() - } - } - style:right=move || match static_side() { - Side::Right => "-15px", - _ => "" - } - style:bottom=move || match static_side() { - Side::Bottom => "-15px", - _ => "" - } - style:left=move || match static_side() { - Side::Left => "-15px".into(), - _ => match arrow_x() { - Some(arrow_x) => format!("{}px", arrow_x), - None => "".into() - } - } - /> - }.into_any().node_ref(arrow_ref) - }} -
+ {floating_view}
@@ -307,6 +339,7 @@ pub fn Arrow() -> impl IntoView { each=|| [true, false] key=|value| format!("{}", value) children=move |value| { + let svg_update = svg_update.clone(); view! { + } + } + /> + + +

Nested

+
+ "black", + false => "" + } + on:click=move |_| { + set_nested(value); + nested_update(); + } > {format!("{}", value)} diff --git a/packages/utils/src/dom.rs b/packages/utils/src/dom.rs index 933f6ec..e577068 100644 --- a/packages/utils/src/dom.rs +++ b/packages/utils/src/dom.rs @@ -125,6 +125,10 @@ pub fn get_document_element(node_or_window: Option) -> Element .expect("Document should have document element.") } +pub fn is_element(node: &Node) -> bool { + node.is_instance_of::() +} + pub fn is_html_element(node: &Node) -> bool { node.is_instance_of::() } diff --git a/upstream.toml b/upstream.toml index fd50862..00a89d7 100644 --- a/upstream.toml +++ b/upstream.toml @@ -1,5 +1,5 @@ [releases] core = "1.6.1" -dom = "1.6.4" +dom = "1.6.5" utils = "0.2.2" vue = "1.0.6"