Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion packages/dom/src/platform/get_clipping_rect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
};

Expand Down Expand Up @@ -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![],
};

Expand Down
42 changes: 25 additions & 17 deletions packages/dom/src/platform/get_offset_parent.rs
Original file line number Diff line number Diff line change
@@ -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<dyn Fn(&HtmlElement) -> Option<Element>>;
Expand Down Expand Up @@ -40,31 +41,38 @@ 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::<Element>();
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;
}
}

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);
}
Expand Down
1 change: 1 addition & 0 deletions packages/dom/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
9 changes: 9 additions & 0 deletions packages/dom/src/utils/is_static_positioned.rs
Original file line number Diff line number Diff line change
@@ -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"
}
216 changes: 139 additions & 77 deletions packages/leptos/tests/visual/src/spec/arrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down Expand Up @@ -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,
Expand All @@ -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!{
<svg
class="arrow"
style:position="absolute"
style:top=move || match static_side() {
Side::Top => "-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!{
<div
class="arrow"
style:position="absolute"
style:top=move || match static_side() {
Side::Top => "-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! {
<div
_ref=floating_ref
style:position=move || floating_styles().style_position()
style:top=move || floating_styles().style_top()
style:left=move || floating_styles().style_left()
style:transform=move || floating_styles().style_transform()
style:will-change=move || floating_styles().style_will_change()
style:width=move || format!("{}px", floating_size())
style:height=move || format!("{}px", floating_size())
>
<div class="floating" style:position="relative" style:border="5px solid black">
{base}
</div>
</div>
},
false => view! {
<div
_ref=floating_ref
class="floating"
style:position=move || floating_styles().style_position()
style:top=move || floating_styles().style_top()
style:left=move || floating_styles().style_left()
style:transform=move || floating_styles().style_transform()
style:will-change=move || floating_styles().style_will_change()
style:width=move || format!("{}px", floating_size())
style:height=move || format!("{}px", floating_size())
>
{base}
</div>
},
}
};

view! {
<h1>Arrow</h1>
<p></p>
Expand All @@ -104,79 +208,7 @@ pub fn Arrow() -> impl IntoView {
>
Reference
</div>
<div
_ref=floating_ref
class="floating"
style:position=move || format!("{:?}", strategy()).to_lowercase()
style:top=move || format!("{}px", y())
style:left=move || format!("{}px", x())
style:width=move || format!("{}px", floating_size())
style:height=move || format!("{}px", floating_size())
>
{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!{
<svg
class="arrow"
style:position="absolute"
style:top=move || match static_side() {
Side::Top => "-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!{
<div
class="arrow"
style:position="absolute"
style:top=move || match static_side() {
Side::Top => "-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)
}}
</div>
{floating_view}
</div>
</div>

Expand Down Expand Up @@ -307,14 +339,44 @@ pub fn Arrow() -> impl IntoView {
each=|| [true, false]
key=|value| format!("{}", value)
children=move |value| {
let svg_update = svg_update.clone();
view! {
<button
data-testid=format!("svg-{}", value)
style:background-color=move || match svg() == value {
true => "black",
false => ""
}
on:click=move |_| set_svg(value)
on:click=move |_| {
set_svg(value);
svg_update();
}
>
{format!("{}", value)}
</button>
}
}
/>
</div>

<h2>Nested</h2>
<div class="controls">
<For
each=|| [true, false]
key=|value| format!("{}", value)
children=move |value| {
let nested_update = nested_update.clone();
view! {
<button
data-testid=format!("nested-{}", value)
style:background-color=move || match nested() == value {
true => "black",
false => ""
}
on:click=move |_| {
set_nested(value);
nested_update();
}
>
{format!("{}", value)}
</button>
Expand Down
4 changes: 4 additions & 0 deletions packages/utils/src/dom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ pub fn get_document_element(node_or_window: Option<DomNodeOrWindow>) -> Element
.expect("Document should have document element.")
}

pub fn is_element(node: &Node) -> bool {
node.is_instance_of::<Element>()
}

pub fn is_html_element(node: &Node) -> bool {
node.is_instance_of::<HtmlElement>()
}
Expand Down
2 changes: 1 addition & 1 deletion upstream.toml
Original file line number Diff line number Diff line change
@@ -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"