mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-11-14 09:45:27 +01:00
popover positioning relative to container
This commit is contained in:
@@ -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`}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user