Shift
Shifts the floating element to keep it in view.
This prevents the floating element from overflowing along its axis of alignment, thereby preserving the side it's placed on.
Type: Visibility Optimizer
Usage
use floating_ui_core::{compute_position, ComputePositionConfig, Shift, ShiftOptions};
compute_position(
reference_el,
floating_el,
ComputePositionConfig::new(platform)
.middleware(vec![
Box::new(Shift::new(ShiftOptions::default())),
]),
);
Options
These are the options you can pass to Shift
.
pub struct ShiftOptions<Element, Window> {
pub detect_overflow: Option<DetectOverflowOptions<Element>>,
pub main_axis: Option<bool>,
pub cross_axis: Option<bool>,
pub limiter: Option<Box<dyn Limiter<Element, Window>>>,
}
pub trait Limiter<Element, Window>: Clone + PartialEq {
fn compute(&self, state: MiddlewareState<Element, Window>) -> Coords;
}
main_axis
Default: true
This is the main axis in which shifting is applied.
x
-axis forTop
andBottom
placementsy
-axis forLeft
andRight
placements
Shift::new(ShiftOptions::default().main_axis(false))
cross_axis
Default: false
This is the cross axis in which shifting is applied, the opposite axis of main_axis
.
Enabling this can lead to the floating element overlapping the reference element, which may not be desired and is often replaced by the Flip
middleware.
Shift::new(ShiftOptions::default().cross_axis(true))
limiter
Default: no-op
This accepts a struct instance that limits the shifting done, in order to prevent detachment or “overly-eager” behavior. The behavior is to stop shifting once the opposite edges of the elements are aligned.
Shift::new(ShiftOptions::default().limiter(
Box::new(LimitShift::new(
LimitShiftOptions::default()
)),
))
This struct itself takes options.
pub struct LimitShiftOptions<'a, Element, Window> {
pub offset: Option<Derivable<'a, Element, Window, LimitShiftOffset>>,
pub main_axis: Option<bool>,
pub cross_axis: Option<bool>,
}
pub enum LimitShiftOffset {
Value(f64),
Values(LimitShiftOffsetValues),
}
pub struct LimitShiftOffsetValues {
pub main_axis: Option<f64>,
pub cross_axis: Option<f64>,
}
main_axis
Default: true
Whether to apply limiting on the main axis.
Shift::new(ShiftOptions::default().limiter(
Box::new(LimitShift::new(
LimitShiftOptions::default().main_axis(false)
)),
))
cross_axis
Default: true
Whether to apply limiting on the cross axis.
Shift::new(ShiftOptions::default().limiter(
Box::new(LimitShift::new(
LimitShiftOptions::default().cross_axis(false)
)),
))
offset
Default: 0.0
This will offset when the limiting starts. A positive number will start limiting earlier, while negative later.
Shift::new(ShiftOptions::default().limiter(
Box::new(LimitShift::new(
// Start limiting 5px earlier
LimitShiftOptions::default().offset(LimitShiftOffset::Value(5.0)),
)),
))
You may also pass a struct instance to configure both axes:
Shift::new(ShiftOptions::default().limiter(
Box::new(LimitShift::new(
LimitShiftOptions::default().offset(LimitShiftOffset::Values(
LimitShitOffsetValues::default()
.main_axis(10.0)
.cross_axis(5.0),
)),
)),
))
detect_overflow
All of detect_overflow
's options can be passed. For instance:
Shift::new(ShiftOptions::default().detect_overflow(
DetectOvverflowOptions::default().padding(Padding::All(5.0)),
))
Data
The following data is available in middleware_data
under the SHIFT_NAME
key:
middleware_data.get_as::<ShiftData>(SHIFT_NAME)
pub struct ShiftData {
pub x: f64,
pub y: f64,
}
x
and y
represent how much the floating element has been shifted along that axis. The values are offsets, and therefore can be negative.