Skip to content

Commit 6c15f9f

Browse files
feat(core): detect_overflow configurable via platform
1 parent 97a9517 commit 6c15f9f

9 files changed

Lines changed: 58 additions & 19 deletions

File tree

packages/core/src/compute_position.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ use crate::types::{
66
MiddlewareReturn, MiddlewareState, Reset, ResetRects,
77
};
88

9+
/// Maximum number of resets that can occur before bailing to avoid infinite reset loops.
10+
const MAX_RESET_COUNT: i32 = 50;
11+
912
/// Computes the `x` and `y` coordinates that will place the floating element next to a given reference element.
1013
///
1114
/// This export does not have any `platform` interface logic. You will need to write one for the platform you are using Floating UI with.
@@ -87,7 +90,7 @@ pub fn compute_position<Element: Clone, Window: Clone>(
8790
}
8891

8992
if let Some(reset) = reset
90-
&& reset_count <= 50
93+
&& reset_count < MAX_RESET_COUNT
9194
{
9295
reset_count += 1;
9396

packages/core/src/middleware/auto_placement.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use floating_ui_utils::{
55
use serde::{Deserialize, Serialize};
66

77
use crate::{
8-
detect_overflow::{DetectOverflowOptions, detect_overflow},
8+
detect_overflow::DetectOverflowOptions,
99
types::{
1010
Derivable, DerivableFn, Middleware, MiddlewareReturn, MiddlewareState,
1111
MiddlewareWithOptions, Reset, ResetValue,
@@ -236,7 +236,7 @@ impl<Element: Clone + PartialEq, Window: Clone + PartialEq> Middleware<Element,
236236
allowed_placements
237237
};
238238

239-
let overflow = detect_overflow(
239+
let overflow = platform.detect_overflow(
240240
MiddlewareState {
241241
elements: elements.clone(),
242242
..state

packages/core/src/middleware/flip.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use floating_ui_utils::{
55
use serde::{Deserialize, Serialize};
66

77
use crate::{
8-
detect_overflow::{DetectOverflowOptions, detect_overflow},
8+
detect_overflow::DetectOverflowOptions,
99
middleware::arrow::{ARROW_NAME, ArrowData},
1010
types::{
1111
Derivable, DerivableFn, Middleware, MiddlewareReturn, MiddlewareState,
@@ -264,7 +264,7 @@ impl<Element: Clone + PartialEq, Window: Clone + PartialEq> Middleware<Element,
264264

265265
placements.insert(0, initial_placement);
266266

267-
let overflow = detect_overflow(
267+
let overflow = platform.detect_overflow(
268268
MiddlewareState {
269269
elements: elements.clone(),
270270
..state

packages/core/src/middleware/hide.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use floating_ui_utils::{ALL_SIDES, Rect, SideObject};
22
use serde::{Deserialize, Serialize};
33

44
use crate::{
5-
detect_overflow::{DetectOverflowOptions, detect_overflow},
5+
detect_overflow::DetectOverflowOptions,
66
types::{
77
Derivable, DerivableFn, ElementContext, Middleware, MiddlewareReturn, MiddlewareState,
88
MiddlewareWithOptions,
@@ -132,14 +132,17 @@ impl<Element: Clone + PartialEq, Window: Clone + PartialEq> Middleware<Element,
132132
let options = self.options.evaluate(state.clone());
133133

134134
let MiddlewareState {
135-
elements, rects, ..
135+
elements,
136+
rects,
137+
platform,
138+
..
136139
} = state;
137140

138141
let strategy = options.strategy.unwrap_or_default();
139142

140143
match strategy {
141144
HideStrategy::ReferenceHidden => {
142-
let overflow = detect_overflow(
145+
let overflow = platform.detect_overflow(
143146
MiddlewareState {
144147
elements: elements.clone(),
145148
..state
@@ -168,7 +171,7 @@ impl<Element: Clone + PartialEq, Window: Clone + PartialEq> Middleware<Element,
168171
}
169172
}
170173
HideStrategy::Escaped => {
171-
let overflow = detect_overflow(
174+
let overflow = platform.detect_overflow(
172175
MiddlewareState {
173176
elements: elements.clone(),
174177
..state

packages/core/src/middleware/shift.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use floating_ui_utils::{Axis, Coords, Side, clamp, get_opposite_axis, get_side_a
55
use serde::{Deserialize, Serialize};
66

77
use crate::{
8-
detect_overflow::{DetectOverflowOptions, detect_overflow},
8+
detect_overflow::DetectOverflowOptions,
99
middleware::{OFFSET_NAME, OffsetData},
1010
types::{
1111
Derivable, DerivableFn, Middleware, MiddlewareReturn, MiddlewareState,
@@ -166,7 +166,11 @@ impl<Element: Clone + PartialEq + 'static, Window: Clone + PartialEq + 'static>
166166
let options = self.options.evaluate(state.clone());
167167

168168
let MiddlewareState {
169-
x, y, placement, ..
169+
x,
170+
y,
171+
placement,
172+
platform,
173+
..
170174
} = state;
171175

172176
let check_main_axis = options.main_axis.unwrap_or(true);
@@ -175,7 +179,7 @@ impl<Element: Clone + PartialEq + 'static, Window: Clone + PartialEq + 'static>
175179
let limiter = options.limiter.unwrap_or(Box::<DefaultLimiter>::default());
176180

177181
let coords = Coords { x, y };
178-
let overflow = detect_overflow(
182+
let overflow = platform.detect_overflow(
179183
MiddlewareState {
180184
elements: state.elements.clone(),
181185
..state

packages/core/src/middleware/size.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::ptr;
33
use floating_ui_utils::{Alignment, Axis, Rect, Side, get_side_axis};
44

55
use crate::{
6-
detect_overflow::{DetectOverflowOptions, detect_overflow},
6+
detect_overflow::DetectOverflowOptions,
77
middleware::shift::{SHIFT_NAME, ShiftData},
88
types::{
99
Derivable, DerivableFn, Middleware, MiddlewareReturn, MiddlewareState,
@@ -142,7 +142,7 @@ impl<Element: Clone + PartialEq, Window: Clone + PartialEq> Middleware<Element,
142142
..
143143
} = state;
144144

145-
let overflow = detect_overflow(
145+
let overflow = platform.detect_overflow(
146146
MiddlewareState {
147147
elements: elements.clone(),
148148
..state

packages/core/src/test_utils.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
use floating_ui_utils::{Dimensions, ElementRects, Rect};
1+
use floating_ui_utils::{Dimensions, ElementRects, Rect, SideObject};
22

3-
use crate::types::{GetClippingRectArgs, GetElementRectsArgs, Platform};
3+
use crate::{
4+
detect_overflow::{DetectOverflowOptions, detect_overflow},
5+
types::{GetClippingRectArgs, GetElementRectsArgs, MiddlewareState, Platform},
6+
};
47

58
#[derive(Clone, Debug)]
69
pub struct Element {}
@@ -49,6 +52,14 @@ impl Platform<Element, Window> for TestPlatform {
4952
height: 10.0,
5053
}
5154
}
55+
56+
fn detect_overflow(
57+
&self,
58+
state: MiddlewareState<Element, Window>,
59+
options: DetectOverflowOptions<Element>,
60+
) -> SideObject {
61+
detect_overflow(state, options)
62+
}
5263
}
5364

5465
pub const PLATFORM: TestPlatform = TestPlatform {};

packages/core/src/types.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ use serde::{Serialize, de::DeserializeOwned};
66

77
use floating_ui_utils::{
88
ClientRectObject, Coords, Dimensions, ElementOrVirtual, ElementOrWindow, ElementRects, Length,
9-
OwnedElementOrWindow, Placement, Rect, Strategy,
9+
OwnedElementOrWindow, Placement, Rect, SideObject, Strategy,
1010
};
1111

12+
use crate::detect_overflow::DetectOverflowOptions;
13+
1214
pub type DerivableFn<'a, Element, Window, T> = &'a dyn Fn(MiddlewareState<Element, Window>) -> T;
1315

1416
pub enum Derivable<'a, Element: Clone + 'static, Window: Clone, T: Clone> {
@@ -133,6 +135,12 @@ pub trait Platform<Element: Clone, Window: Clone>: Debug {
133135
fn get_client_length(&self, _element: &Element, _length: Length) -> Option<f64> {
134136
None
135137
}
138+
139+
fn detect_overflow(
140+
&self,
141+
state: MiddlewareState<Element, Window>,
142+
options: DetectOverflowOptions<Element>,
143+
) -> SideObject;
136144
}
137145

138146
/// Data stored by middleware.

packages/dom/src/platform.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@ pub mod get_scale;
99
pub mod is_rtl;
1010

1111
use floating_ui_core::{
12-
ConvertOffsetParentRelativeRectToViewportRelativeRectArgs, GetClippingRectArgs,
13-
GetElementRectsArgs, Platform as CorePlatform,
12+
ConvertOffsetParentRelativeRectToViewportRelativeRectArgs, DetectOverflowOptions,
13+
GetClippingRectArgs, GetElementRectsArgs, MiddlewareState, Platform as CorePlatform,
14+
detect_overflow,
1415
};
1516
use floating_ui_utils::dom::get_document_element;
1617
use floating_ui_utils::{
1718
ClientRectObject, Coords, Dimensions, ElementRects, Length, OwnedElementOrWindow, Rect,
19+
SideObject,
1820
};
1921
use web_sys::{Element, Window};
2022

@@ -79,4 +81,12 @@ impl CorePlatform<Element, Window> for Platform {
7981
fn get_client_length(&self, element: &Element, length: Length) -> Option<f64> {
8082
Some(get_client_length(element, length))
8183
}
84+
85+
fn detect_overflow(
86+
&self,
87+
state: MiddlewareState<Element, Window>,
88+
options: DetectOverflowOptions<Element>,
89+
) -> SideObject {
90+
detect_overflow(state, options)
91+
}
8292
}

0 commit comments

Comments
 (0)