Shadow under resizable panels #674
-
|
B2 english ahead, you been warned I quickly learned that due to limitations (overflow: hidden) on So i tried to find a solution and came across shadow via overlay element in a portal approach that was mentioned in issue:#532, basically you create a separate element with dimensions and position of resizable panel, stuck few event listeners and observer so shadow not slip and put on pointerEvents: none and shadow itself, it's quite a bulky and probably far from optimal way to do shadow but it worked for me shadow component look like this:export default function ResizablePanelShadow({ targetRef }: { targetRef: RefObject<HTMLDivElement | null> }) {
const [rect, setRect] = useState<DOMRect | null>(null);
useLayoutEffect(() => {
if (!targetRef.current || targetRef.current === null) return;
const update = () => {
if (targetRef.current) {
setRect(targetRef.current.getBoundingClientRect());
}
};
update();
const ro = new ResizeObserver(update);
ro.observe(targetRef.current);
window.addEventListener("scroll", update, true);
window.addEventListener("resize", update);
return () => {
ro.disconnect();
window.removeEventListener("scroll", update, true);
window.removeEventListener("resize", update);
};
}, [targetRef]);
if (!rect) return null;
return createPortal(
<div
className="shadow-sm rounded-xl"
style={{
position: "fixed",
top: rect.top,
left: rect.left,
width: rect.width,
height: rect.height,
pointerEvents: "none",
zIndex: 0,
}}
/>,
document.body
);
}shadow here created with return createPortal(
<div
style={{
position: "fixed",
top: rect.top,
left: rect.left,
width: rect.width,
height: rect.height,
pointerEvents: "none",
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
borderRadius: "12px",
zIndex: 0,
}}
/>,
document.body
);important part: this is completely separate element so corner rounding of original use with panel:And to actually add shadow to it could be like this: export function ControlsExample() {
const mainPanelRef = useRef<HTMLDivElement>(null);
const secondaryPanelRef = useRef<HTMLDivElement>(null);
const panelClasses = "bg-content1 w-full rounded-xl p-2";
return (
<>
<Group orientation="horizontal" className="relative flex h-full w-full shrink-0 gap-2">
<Panel elementRef={mainPanelRef} defaultSize="80%" minSize="60%" className={panelClasses}>
any content
</Panel>
<Panel elementRef={secondaryPanelRef} defaultSize="20%" minSize="10%" className={panelClasses}>
any another content
</Panel>
</Group>
<ResizablePanelShadow targetRef={mainPanelRef} />
<ResizablePanelShadow targetRef={secondaryPanelRef} />
</>
);
}or this: export function ControlsExample() {
const mainPanelRef = useRef<HTMLDivElement>(null);
const secondaryPanelRef = useRef<HTMLDivElement>(null);
const panelClasses = "bg-content1 w-full rounded-xl p-2";
return (
<Group orientation="horizontal" className="relative flex h-full w-full shrink-0 gap-2">
<Panel elementRef={mainPanelRef} defaultSize="80%" minSize="60%" className={panelClasses}>
any content
</Panel>
<ResizablePanelShadow targetRef={mainPanelRef} />
<Panel elementRef={secondaryPanelRef} defaultSize="20%" minSize="10%" className={panelClasses}>
any another content
</Panel>
<ResizablePanelShadow targetRef={secondaryPanelRef} />
</Group>
);
}just pass the ref from I understand it can be kinda tricky to add functionality like this to base component due to variety of shadow creation ways and probably other limitation but if possible it would be great to see it build in Feel free to add any improvements in discussion bellow I don't really know if discussion is right place to post this kind of guide related stuff but i leave it here for anyone who had similar problem |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 2 replies
This comment has been hidden.
This comment has been hidden.
-
|
Hey @MarkuSSSann I spent more time thinking about this general topic and I have come up with a direction that I think will allow the library to support this sort of style out of the box. I've published a preview release of the library and would really appreciate if you could try it out and share feedback. Does it work for your use case? npm install react-resizable-panels@alphaHere is the related documentation: |
Beta Was this translation helpful? Give feedback.
-
|
This feature is now supported in the latest release: react-resizable-panels@4.7.1 Documentation is available here: https://react-resizable-panels.vercel.app/examples/overflow ❤️ → ☕ givebrian.coffee |
Beta Was this translation helpful? Give feedback.
This feature is now supported in the latest release: react-resizable-panels@4.7.1
Documentation is available here: https://react-resizable-panels.vercel.app/examples/overflow
❤️ → ☕ givebrian.coffee