@@ -16,6 +16,17 @@ use crate::{
1616/// Name of the [`Flip`] middleware.
1717pub const FLIP_NAME : & str = "flip" ;
1818
19+ /// Cross axis option used by [`Flip`] middleware.
20+ #[ derive( Copy , Clone , Debug , PartialEq ) ]
21+ pub enum CrossAxis {
22+ /// Whether to check cross axis overflow for both side and alignment flipping.
23+ True ,
24+ /// Whether to disable all cross axis overflow checking.
25+ False ,
26+ /// Whether to check cross axis overflow for alignment flipping only.
27+ Alignment ,
28+ }
29+
1930/// Fallback strategy used by [`Flip`] middleware.
2031#[ derive( Copy , Clone , Debug , Default , PartialEq ) ]
2132pub enum FallbackStrategy {
@@ -38,9 +49,12 @@ pub struct FlipOptions<Element: Clone> {
3849 pub main_axis : Option < bool > ,
3950
4051 /// The axis that runs along the alignment of the floating element. Determines whether overflow along this axis is checked to perform a flip.
52+ /// - [`CrossAxis::True`]: Whether to check cross axis overflow for both side and alignment flipping.
53+ /// - [`CrossAxis::False`]: Whether to disable all cross axis overflow checking.
54+ /// - [`CrossAxis::Alignment`]: Whether to check cross axis overflow for alignment flipping only.
4155 ///
4256 /// Defaults to `true`.
43- pub cross_axis : Option < bool > ,
57+ pub cross_axis : Option < CrossAxis > ,
4458
4559 /// Placements to try sequentially if the preferred `placement` does not fit.
4660 ///
@@ -77,7 +91,7 @@ impl<Element: Clone> FlipOptions<Element> {
7791 }
7892
7993 /// Set `cross_axis` option.
80- pub fn cross_axis ( mut self , value : bool ) -> Self {
94+ pub fn cross_axis ( mut self , value : CrossAxis ) -> Self {
8195 self . cross_axis = Some ( value) ;
8296 self
8397 }
@@ -203,7 +217,7 @@ impl<Element: Clone + PartialEq, Window: Clone + PartialEq> Middleware<Element,
203217 } ) ;
204218
205219 let check_main_axis = options. main_axis . unwrap_or ( true ) ;
206- let check_cross_axis = options. cross_axis . unwrap_or ( true ) ;
220+ let check_cross_axis = options. cross_axis . unwrap_or ( CrossAxis :: True ) ;
207221 let specified_fallback_placements = options. fallback_placements . clone ( ) ;
208222 let fallback_strategy = options. fallback_strategy . unwrap_or_default ( ) ;
209223 let fallback_axis_side_direction = options. fallback_axis_side_direction ;
@@ -264,7 +278,7 @@ impl<Element: Clone + PartialEq, Window: Clone + PartialEq> Middleware<Element,
264278 if check_main_axis {
265279 overflows. push ( overflow. side ( side) ) ;
266280 }
267- if check_cross_axis {
281+ if check_cross_axis == CrossAxis :: True || check_cross_axis == CrossAxis :: Alignment {
268282 let sides = get_alignment_sides ( placement, rects, rtl) ;
269283 overflows. push ( overflow. side ( sides. 0 ) ) ;
270284 overflows. push ( overflow. side ( sides. 1 ) ) ;
@@ -281,22 +295,34 @@ impl<Element: Clone + PartialEq, Window: Clone + PartialEq> Middleware<Element,
281295 let next_placement = placements. get ( next_index) ;
282296
283297 if let Some ( next_placement) = next_placement {
284- // Try next placement and re-run the lifecycle.
285- return MiddlewareReturn {
286- x : None ,
287- y : None ,
288- data : Some (
289- serde_json:: to_value ( FlipData {
290- index : next_index,
291- overflows : overflows_data,
292- } )
293- . expect ( "Data should be valid JSON." ) ,
294- ) ,
295- reset : Some ( Reset :: Value ( ResetValue {
296- placement : Some ( * next_placement) ,
297- rects : None ,
298- } ) ) ,
298+ let ignore_cross_axis_overflow = if check_cross_axis == CrossAxis :: Alignment {
299+ initial_side_axis != get_side_axis ( * next_placement)
300+ } else {
301+ false
299302 } ;
303+ let has_initial_main_axis_overflow = overflows_data
304+ . first ( )
305+ . and_then ( |overflow| overflow. overflows . first ( ) )
306+ . is_some_and ( |overflow| * overflow > 0.0 ) ;
307+
308+ if !ignore_cross_axis_overflow || has_initial_main_axis_overflow {
309+ // Try next placement and re-run the lifecycle.
310+ return MiddlewareReturn {
311+ x : None ,
312+ y : None ,
313+ data : Some (
314+ serde_json:: to_value ( FlipData {
315+ index : next_index,
316+ overflows : overflows_data,
317+ } )
318+ . expect ( "Data should be valid JSON." ) ,
319+ ) ,
320+ reset : Some ( Reset :: Value ( ResetValue {
321+ placement : Some ( * next_placement) ,
322+ rects : None ,
323+ } ) ) ,
324+ } ;
325+ }
300326 }
301327
302328 // First, find the candidates that fit on the main axis side of overflow, then find the placement that fits the best on the main cross axis side.
0 commit comments