diff --git a/src/CAREUI/display/PopupModal.tsx b/src/CAREUI/display/PopupModal.tsx index 37b5719d9bd..3b2ce314da0 100644 --- a/src/CAREUI/display/PopupModal.tsx +++ b/src/CAREUI/display/PopupModal.tsx @@ -9,10 +9,17 @@ type Props = { show: boolean; onHide: () => void; children: ReactNode; + anchorRef: React.RefObject; className?: string; onSubmit?: () => void; }; +type Position = + | { left: number; top: number } + | { right: number; bottom: number } + | { left: number; bottom: number } + | { right: number; top: number }; + export default function PopupModal(props: Props) { const { t } = useTranslation(); const isMobile = useBreakpoints({ default: true, lg: false }); @@ -43,7 +50,7 @@ export default function PopupModal(props: Props) { const DesktopView = (props: Props) => { const { t } = useTranslation(); - const [position, setPosition] = useState({ x: 0, y: 0 }); + const [position, setPosition] = useState({ left: 0, top: 0 }); const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 }); const modal = useRef(null); const [children, setChildren] = useState(props.children); @@ -68,25 +75,38 @@ const DesktopView = (props: Props) => { const currentMousePosition = mousePosition; const modalHeight = modal.current?.clientHeight || 0; const modalWidth = modal.current?.clientWidth || 0; - const xRelative = currentMousePosition.x; - const yRelative = currentMousePosition.y; - const containerHeight = window.innerHeight; - const containerWidth = window.innerWidth; - const top = - yRelative + modalHeight > containerHeight - ? yRelative - modalHeight - : yRelative; - const left = - xRelative + modalWidth > containerWidth - ? xRelative - modalWidth - : xRelative; - setPosition({ x: left, y: top }); + const clickX = currentMousePosition.x; + const clickY = currentMousePosition.y; + const windowHeight = window.innerHeight; + const windowWidth = window.innerWidth; + + const anchorPosition = props.anchorRef.current?.getBoundingClientRect(); + const anchorX = anchorPosition?.x || 0; + const anchorY = anchorPosition?.y || 0; + const verticalCenter = windowHeight / 2; + const horizontalCenter = windowWidth / 2; + const mountLeft = clickX - anchorX; + const mountTop = clickY - anchorY; + + let position; + if (clickX > horizontalCenter) { + position = { left: mountLeft - modalWidth }; + } else { + position = { left: mountLeft }; + } + if (clickY > verticalCenter) { + position = { ...position, top: mountTop - modalHeight }; + } else { + position = { ...position, top: mountTop }; + } + setPosition(position); } document.addEventListener("mousedown", handleOutsideClick); return () => { document.removeEventListener("mousedown", handleOutsideClick); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [props.show]); useEffect(() => { @@ -99,13 +119,17 @@ const DesktopView = (props: Props) => { }; }, []); + const positionAttributes = Object.entries(position).reduce( + (acc, [key, value]) => { + return { ...acc, [key]: `${value}px` }; + }, + {}, + ); + return (
{ const value = log.pressure_sore ?? []; + const containerRef = useRef(null); const [current, setCurrent] = useState(); const regionPushScore = (region: IPressureSore["region"]) => { @@ -33,11 +34,11 @@ const PressureSore = ({ log, onChange, readonly }: LogUpdateSectionProps) => { } }; - // TODO: wrap with a div with relative class so that the editor sticks on scroll. return ( - <> +
setCurrent(undefined)} onSave={ @@ -74,7 +75,7 @@ const PressureSore = ({ log, onChange, readonly }: LogUpdateSectionProps) => { } regionText={(r) => regionPushScore(r)?.toString() ?? ""} /> - +
); }; @@ -88,6 +89,7 @@ export default PressureSore; type RegionEditorProps = { show: boolean; value: IPressureSore; + anchorRef: React.RefObject; onCancel: () => void; onSave?: (value: IPressureSore) => void; }; @@ -106,6 +108,7 @@ const RegionEditor = (props: RegionEditorProps) => { (); + const containerRef = useRef(null); const valueDescription = (region: IPainScale["region"]) => { const scale = pain.find((obj) => obj.region === region)?.scale; @@ -24,10 +25,11 @@ export default function PainChart({ pain, onChange }: Props) { }; return ( - <> +
setCurrent(undefined)} onSave={ onChange @@ -60,13 +62,14 @@ export default function PainChart({ pain, onChange }: Props) { pain.find((p) => p.region === region)?.scale.toString() ?? "" } /> - +
); } type RegionEditorProps = { show: boolean; value: IPainScale; + anchorRef: React.RefObject; onCancel: () => void; onSave?: (value: IPainScale) => void; }; @@ -85,6 +88,7 @@ const RegionEditor = (props: RegionEditorProps) => {