popover positioning relative to container

This commit is contained in:
zsviczian
2025-10-21 20:00:33 +00:00
parent dc4ebdbde7
commit 482f8132f2
3 changed files with 11 additions and 23 deletions

View File

@@ -8,7 +8,7 @@ import { atom, useAtom } from "../editor-jotai";
import { getLanguage, t } from "../i18n"; import { getLanguage, t } from "../i18n";
import Collapsible from "./Stats/Collapsible"; import Collapsible from "./Stats/Collapsible";
import { useDevice } from "./App"; import { useDevice, useExcalidrawContainer } from "./App";
import "./IconPicker.scss"; import "./IconPicker.scss";
@@ -39,6 +39,7 @@ function Picker<T>({
numberOfOptionsToAlwaysShow?: number; numberOfOptionsToAlwaysShow?: number;
}) { }) {
const device = useDevice(); const device = useDevice();
const { container } = useExcalidrawContainer();
const handleKeyDown = (event: React.KeyboardEvent) => { const handleKeyDown = (event: React.KeyboardEvent) => {
const pressedOption = options.find( const pressedOption = options.find(
@@ -161,6 +162,7 @@ function Picker<T>({
sideOffset={isMobile ? 8 : 12} sideOffset={isMobile ? 8 : 12}
style={{ zIndex: "var(--zIndex-ui-styles-popup)" }} style={{ zIndex: "var(--zIndex-ui-styles-popup)" }}
onKeyDown={handleKeyDown} onKeyDown={handleKeyDown}
collisionBoundary={container ?? undefined}
> >
<div <div
className={`picker`} className={`picker`}

View File

@@ -40,17 +40,8 @@ export const PropertiesPopover = React.forwardRef<
ref, ref,
) => { ) => {
const device = useDevice(); const device = useDevice();
const collisionPadding = container const isMobilePortrait =
? (() => { device.editor.isMobile && !device.viewport.isLandscape;
const rect = container.getBoundingClientRect();
return {
top: 8,
right: Math.max(8, window.innerWidth - rect.right),
bottom: Math.max(8, window.innerHeight - rect.bottom),
left: 8,
};
})()
: 8;
return ( return (
<Popover.Portal container={container}> <Popover.Portal container={container}>
@@ -58,20 +49,11 @@ export const PropertiesPopover = React.forwardRef<
ref={ref} ref={ref}
className={clsx("focus-visible-none", className)} className={clsx("focus-visible-none", className)}
data-prevent-outside-click data-prevent-outside-click
side={ side={isMobilePortrait ? "bottom" : "right"}
device.editor.isMobile && !device.viewport.isLandscape align={isMobilePortrait ? "center" : "start"}
? "bottom"
: "right"
}
align={
device.editor.isMobile && !device.viewport.isLandscape
? "center"
: "start"
}
alignOffset={-16} alignOffset={-16}
sideOffset={20} sideOffset={20}
collisionBoundary={container ?? undefined} collisionBoundary={container ?? undefined}
collisionPadding={collisionPadding}
style={{ style={{
zIndex: "var(--zIndex-ui-styles-popup)", zIndex: "var(--zIndex-ui-styles-popup)",
marginLeft: device.editor.isMobile ? "0.5rem" : undefined, marginLeft: device.editor.isMobile ? "0.5rem" : undefined,

View File

@@ -11,6 +11,8 @@ import { ToolButton } from "./ToolButton";
import "./ToolPopover.scss"; import "./ToolPopover.scss";
import { useExcalidrawContainer } from "./App";
import type { AppClassProperties } from "../types"; import type { AppClassProperties } from "../types";
type ToolOption = { type ToolOption = {
@@ -50,6 +52,7 @@ export const ToolPopover = ({
const currentType = activeTool.type; const currentType = activeTool.type;
const isActive = displayedOption.type === currentType; const isActive = displayedOption.type === currentType;
const SIDE_OFFSET = 32 / 2 + 10; const SIDE_OFFSET = 32 / 2 + 10;
const { container } = useExcalidrawContainer();
// if currentType is not in options, close popup // if currentType is not in options, close popup
if (!options.some((o) => o.type === currentType) && isPopupOpen) { if (!options.some((o) => o.type === currentType) && isPopupOpen) {
@@ -90,6 +93,7 @@ export const ToolPopover = ({
<Popover.Content <Popover.Content
className="tool-popover-content" className="tool-popover-content"
sideOffset={SIDE_OFFSET} sideOffset={SIDE_OFFSET}
collisionBoundary={container ?? undefined}
> >
{options.map(({ type, icon, title }) => ( {options.map(({ type, icon, title }) => (
<ToolButton <ToolButton