Primitives · a raise keeps its state under its owner's id

A raise inside another was namespaced by its place in the layer's
queue, so one that came before it moved its id path and rebuilt its
keyed state and focus: an open date popup would lose its month when a
tip appeared. raise now takes its owner's id and draws under it, and
float and float_height pass the owner's id on from every call site.
A test holds a focused box in a raise while another comes before it.
This commit is contained in:
ZacharyZhang-NY committed 2026-09-27 02:23:05 -04:00
1 parent 341420d1e4
commit 51ade29032
25 files changed
+188 -40

No files matched your search

+1
View File
@@ -265,6 +265,7 @@ impl RenderOnce for Cascader {
});
let close = state.clone();
float(
self.id.clone(),
anchor,
deepest,
surface((self.id.clone(), "columns"), cx)
+1
View File
@@ -228,6 +228,7 @@ fn period_picker(
};
let grid = period_grid(&key, build(shown), grid, window, cx);
float(
key.clone(),
anchor,
6,
surface((key.clone(), "popup"), cx)
+2
View File
@@ -246,6 +246,7 @@ impl RenderOnce for DatePicker {
}
let (escape, done) = (close.clone(), close.clone());
float(
id.clone(),
anchor,
CALENDAR_ROWS,
surface((id.clone(), "popup"), cx)
@@ -347,6 +348,7 @@ impl RenderOnce for DateRangePicker {
}
let (hover, pick, escape) = (state.clone(), state.clone(), close.clone());
float(
id.clone(),
anchor,
CALENDAR_ROWS,
surface((id.clone(), "popup"), cx)
+2
View File
@@ -256,6 +256,7 @@ impl RenderOnce for TimePicker {
let columns = time_columns(&id, time, step, commit.clone(), window, cx);
let out = close.clone();
float(
id.clone(),
anchor,
CALENDAR_ROWS,
surface((id.clone(), "popup"), cx)
@@ -368,6 +369,7 @@ impl RenderOnce for DateTimePicker {
);
let out = close.clone();
float(
id.clone(),
anchor,
CALENDAR_ROWS,
surface((id.clone(), "popup"), cx)
+1
View File
@@ -77,6 +77,7 @@ impl RenderOnce for WeekPicker {
}
let (escape, out, on_change) = (close.clone(), close.clone(), on_change.clone());
float(
id.clone(),
anchor,
CALENDAR_ROWS,
surface((id.clone(), "popup"), cx)
+8 -6
View File
@@ -166,8 +166,9 @@ pub(crate) fn surface(id: impl Into<ElementId>, cx: &App) -> Stateful<Div> {
.text_size(theme.text_size(TextSize::Sm))
}
/// Floats `content` of about `rows` rows under `anchor`, or over it when only above has room.
/// Floats `content` of about `rows` rows under `anchor`, or over it when only above has room; `id` is its owner's.
pub(crate) fn float(
id: impl Into<ElementId>,
anchor: Bounds<Pixels>,
rows: usize,
content: impl IntoElement,
@@ -178,7 +179,7 @@ pub(crate) fn float(
let rem = window.rem_size();
let row = theme.control_height(ControlSize::Md).to_pixels(rem);
let height = (row * (rows + 1) as f32).min(theme.list_max_height().to_pixels(rem));
float_height(anchor, height, content, window, cx)
float_height(id, anchor, height, content, window, cx)
}
/// Whether `height` goes over `anchor`: it does not fit below, and above has more room.
@@ -187,8 +188,9 @@ pub(crate) fn opens_up(anchor: Bounds<Pixels>, height: Pixels, viewport: Pixels)
height > below && anchor.top() > below
}
/// Floats `content` of a known `height` under `anchor`, or over it when only above has room.
/// Floats `content` of a known `height` under `anchor`, or over it when only above has room; `id` is its owner's.
pub(crate) fn float_height(
id: impl Into<ElementId>,
anchor: Bounds<Pixels>,
height: Pixels,
content: impl IntoElement,
@@ -220,7 +222,7 @@ pub(crate) fn float_height(
}),
)
};
raise(placed.snap_to_window())
raise(id, placed.snap_to_window())
.with_priority(1)
.into_any_element()
}
@@ -298,7 +300,7 @@ impl Popup<'_> {
})
})
});
let list = surface(self.id, cx)
let list = surface(self.id.clone(), cx)
.debug_selector(|| "option-list".into())
.min_w(theme.tooltip_max_width())
.when(anchor.size.width > Pixels::ZERO, |list| {
@@ -319,7 +321,7 @@ impl Popup<'_> {
self.scroll.zip(self.reveal),
|list, (handle, (ix, done))| list.child(revealer(handle, ix, done)),
);
float(anchor, self.rows.len(), list, window, cx)
float(self.id, anchor, self.rows.len(), list, window, cx)
}
}