pub fn use_placement<E, T>(
element_ref: E,
trigger_ref: T,
options: FloatingOptions,
) -> ReadSignal<FloatingResult>Expand description
Reactive hook for positioning a floating element relative to a trigger element (anchor).
This hook automatically finds the nearest ScrollableView context to handle scrolling and overflow boundary detection.
§Behavior
- It recalculates the position whenever the trigger, the element itself, or the parent’s scroll state changes.
- It uses a 1ms delay to ensure the browser has performed a Layout pass before measuring dimensions.
§Warning
This hook must be used within a ScrollableView component. If no context is found, it will log a warning and return default (zero) coordinates.
§Example
use dioxus::prelude::*;
use dioxus::html::geometry::PixelsVector2D;
use dioxus_floating::{use_placement, FloatingOptions};
fn MyElement() -> Element {
let mut element_ref = use_signal(|| None);
let mut trigger_ref = use_signal(|| None);
let mut is_opened = use_signal(|| false);
let placement = use_placement(element_ref, trigger_ref, FloatingOptions::default());
rsx! {
// The trigger element
button {
onmounted: move |e| trigger_ref.set(Some(e.data.clone())),
onclick: move |_| is_opened.toggle(),
"Toggle Dropdown"
}
// The floating element
if is_opened() {
div {
onmounted: move |e| element_ref.set(Some(e.data.clone())),
// Use is_ready to prevent the element from "jumping" into position
class: if placement().is_ready { "opacity-100" } else { "opacity-0" },
style: "position: fixed; transform: translate3d({placement().x}px, {placement().y}px, 0);",
"I am a dropdown content"
}
}
}
}§Example: Custom Style Generation
use dioxus::prelude::*;
use dioxus_floating::{use_placement, FloatingOptions};
#[component]
fn MyComponent() -> Element {
let el = use_signal(|| None);
let tr = use_signal(|| None);
let pos = use_placement(el, tr, FloatingOptions::default());
let style = use_memo(move || {
pos.with(|p| format!(
"position: fixed; transform: translate3d({}px, {}px, 0); opacity: {};",
p.x, p.y, if p.is_ready { 1 } else { 0 }
))
});
rsx!{}
}