Fix shared element state across component instances

This commit is contained in:
2026-11-09 14:04:25 +07:00
parent f022f08947
commit 73f7dc31d4
20 changed files with 489 additions and 136 deletions
+25 -39
View File
@@ -1,14 +1,13 @@
//! The command palette: a modal query field over the application's actions.
use std::cell::RefCell;
use std::rc::Rc;
use gpui::prelude::FluentBuilder as _;
use gpui::{
AnyElement, App, Bounds, Context, ElementId, Entity, InteractiveElement as _, IntoElement,
KeyBinding, MouseButton, MouseDownEvent, ParentElement as _, Pixels, Render, Role,
ScrollHandle, SharedString, StatefulInteractiveElement as _, Styled as _, Subscription, Window,
actions, canvas, div, px, relative,
AnyElement, App, Context, ElementId, Entity, InteractiveElement as _, IntoElement, KeyBinding,
MouseButton, ParentElement as _, Render, Role, ScrollHandle, SharedString,
StatefulInteractiveElement as _, Styled as _, Subscription, Window, actions, canvas, deferred,
div, px, relative,
};
use gpui_native_icons::{IconRole, icon};
use gpui_native_theme::{ActiveTheme as _, Size};
@@ -322,6 +321,7 @@ impl Render for CommandPaletteState {
let id = self.id.clone();
let state = cx.entity();
let query_focus = self.query.read(cx).focus_handle();
let rows: Vec<AnyElement> = self
.matches
@@ -406,9 +406,6 @@ impl Render for CommandPaletteState {
.into_any_element()
};
let panel_bounds: Rc<RefCell<Option<Bounds<Pixels>>>> = Rc::new(RefCell::new(None));
let query_focus = self.query.read(cx).focus_handle();
let panel = v_flex()
.id((id.clone(), "panel"))
.debug_selector({
@@ -460,20 +457,14 @@ impl Render for CommandPaletteState {
)
.child(rows)
.child(
canvas(
{
let cell = panel_bounds.clone();
move |bounds, _window, _cx| *cell.borrow_mut() = Some(bounds)
},
{
let focus = query_focus.clone();
move |_, _, window, cx| {
if !focus.contains_focused(window, cx) {
window.focus(&focus, cx);
}
canvas(|_, _, _| {}, {
let focus = query_focus.clone();
move |_, _, window, cx| {
if !focus.contains_focused(window, cx) {
window.focus(&focus, cx);
}
},
)
}
})
.absolute()
.inset_0(),
);
@@ -485,28 +476,23 @@ impl Render for CommandPaletteState {
.occlude()
.on_mouse_down(MouseButton::Left, {
let state = state.clone();
let panel_bounds = panel_bounds.clone();
move |event: &MouseDownEvent, _window, cx| {
let on_panel = panel_bounds
.borrow()
.is_some_and(|bounds| bounds.contains(&event.position));
if on_panel {
return;
}
move |_, _window, cx| {
state.update(cx, |state, cx| state.close(cx));
cx.stop_propagation();
}
});
div()
.absolute()
.inset_0()
.flex()
.justify_center()
.items_start()
.pt_10()
.child(scrim)
.child(panel)
.into_any_element()
deferred(
div()
.absolute()
.inset_0()
.flex()
.justify_center()
.items_start()
.pt_10()
.child(scrim)
.child(panel),
)
.into_any_element()
}
}