diff --git a/crates/rustmotion-studio/src/components/color_picker/style.css b/crates/rustmotion-studio/src/components/color_picker/style.css index 2bb1fca..2566bf1 100644 --- a/crates/rustmotion-studio/src/components/color_picker/style.css +++ b/crates/rustmotion-studio/src/components/color_picker/style.css @@ -176,11 +176,18 @@ absolute popover under the trigger. Single divergence for our right-docked inspector: right-anchored (right:0) instead of upstream's left:0, so it opens leftward. Values themed to --rm-*. */ +/* Overlay escape (no measurement): `position:fixed` with `top:auto` keeps + the box at its STATIC position — vertically level with its trigger row — + while escaping every `overflow` ancestor (the scrollable inspector panel + clipped the absolute version). Horizontally `right: 308px` (300px panel + width constant + 8px gap) lays it just left of the panel, OVER the canvas, + always. No ancestor has transform/filter/perspective, so no containing + block hijacks the fixed positioning. */ .dx-color-picker-popover { - position: absolute; + position: fixed; z-index: 1000; - top: 100%; - right: 0; + top: auto; + right: 308px; left: auto; display: block; border-radius: 0.5rem; diff --git a/crates/rustmotion-studio/src/editor/inspector.rs b/crates/rustmotion-studio/src/editor/inspector.rs index a6a1e1c..a3128c2 100644 --- a/crates/rustmotion-studio/src/editor/inspector.rs +++ b/crates/rustmotion-studio/src/editor/inspector.rs @@ -611,11 +611,16 @@ pub fn InspectorPanel( // Provide the debounce handle so all child write helpers share one slot. use_context_provider(|| WriteDebounce(Rc::new(RefCell::new(None)))); // One expanded color picker at a time across the whole panel. - let open_picker = use_signal(|| None::); + let mut open_picker = use_signal(|| None::); use_context_provider(|| crate::components::color_picker::OpenPicker(open_picker)); let fam = family(&kind); rsx! { - div { style: "width:300px; flex:none; min-height:0; background:var(--rm-surface); border-left:1px solid var(--rm-border); box-sizing:border-box; display:flex; flex-direction:column; overflow:auto;", + div { + style: "width:300px; flex:none; min-height:0; background:var(--rm-surface); border-left:1px solid var(--rm-border); box-sizing:border-box; display:flex; flex-direction:column; overflow:auto;", + // The open picker popover is `position:fixed` at its trigger's + // static position: it doesn't follow the panel scroll, so close + // it when the panel scrolls (standard dropdown behavior). + onscroll: move |_| open_picker.set(None), div { style: "padding:14px; display:flex; justify-content:space-between; align-items:center;", div {