EN · DE · RU · FR · ES

#2673: AdvancedPopper.jsx

projectforge-webapp/src/components/design/popper/AdvancedPopper.jsx React-Komponente, projectforge-webapp/src/components/design/popper/AdvancedPopper.jsx 159 Zeilen · 144 Code · 2 Kommentare · 13 leer
Zweck: React-Webapp: AdvancedPopper.jsx. AdvancedPopper.jsx ist Teil der Open-Source-Projektmanagement-Anwendung ProjectForge.

Quelltext (erste 100 Zeilen)

import classNames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';
import { useClickOutsideHandler } from '../../../utilities/hooks';
import style from './Popper.module.scss';

function AdvancedPopper(
    {
        actions,
        additionalClassName,
        basic,
        children,
        className,
        contentClassName,
        isOpen = false,
        onBlur,
        setIsOpen,
        withInput = false,
        ...props
    },
) {
    const reference = React.useRef(null);
    const basicReference = React.useRef(null);
    const [basicHeight, setBasicHeight] = React.useState(0);
    const [basicWidth, setBasicWidth] = React.useState(0);
    const [additionalHeight, setAdditionalHeight] = React.useState(0);
    const [additionalWidth, setAdditionalWidth] = React.useState(0);
    const [currentTimeout, setCurrentTimeout] = React.useState(-1);

    useClickOutsideHandler(reference, setIsOpen, isOpen);

    // Timeout beim Entfernen der Komponente löschen
    React.useEffect(() => () => {
        if (currentTimeout >= 0) {
            clearTimeout(currentTimeout);
        }
    }, []);

    React.useLayoutEffect(
        () => {
            if (basicReference.current) {
                setBasicWidth(basicReference.current.clientWidth);
                setBasicHeight(basicReference.current.clientHeight);
            }
        },
        [
            basicReference.current && basicReference.current.clientHeight,
            basicReference.current && basicReference.current.clientWidth,
        ],
    );
    React.useLayoutEffect(
        () => {
            if (reference.current) {
                const { top, left } = reference.current.getBoundingClientRect();

                setAdditionalHeight(document.body.clientHeight - top - 64);
                setAdditionalWidth(document.body.clientWidth - left - 16);
            }
        },
        [
            reference.current && Math.floor(reference.current.getBoundingClientRect().top),
            reference.current && Math.floor(reference.current.getBoundingClientRect().left),
        ],
    );

    const handleBlur = (event) => {
        if (reference.current) {
            if (currentTimeout) {
                clearTimeout(currentTimeout);
            }

            // Neues aktives Element nach Verlassen des Fokus abrufen
            setCurrentTimeout(
                setTimeout(() => {
                    if (reference.current && !reference.current.contains(document.activeElement)) {
                        setIsOpen(false);
                    }
                }, 1),
            );
        }

        if (onBlur) {
            onBlur(event);
        }
    };

    const handleClick = ({ target }) => {
        if (basicReference.current && basicReference.current.contains(target)) {
            setIsOpen(true);
        }
    };

    const additionalVisible = isOpen && children;

    return (
        <div
            ref={reference}
            className={classNames(
                style.advancedPopperContainer,
                { [style.isOpen]: additionalVisible },

Git-Verlauf

dda078e3e AdvancedPopper.jsx: Fehlerbehebung
3685edd6c Migration zu React 18 (Work-in-Progress)
918215de8 Korrektur der Breiten-/Höhenberechnung von AdvancedPopper
1bbd80660 Korrektur der AdvancedPopper-Abmessungen
f61b44dab Korrektur des Öffnens von AdvancedPopper bei Klick

dda078e3e

AdvancedPopper.jsx: Fehlerbehebung
dda078e3e7bb81b5b5656b8a634d5adbad9a638e
diff --git a/projectforge-webapp/src/components/design/popper/AdvancedPopper.jsx b/projectforge-webapp/src/components/design/popper/AdvancedPopper.jsx
index 2b3b66ea1..c65c6630b 100644
--- a/projectforge-webapp/src/components/design/popper/AdvancedPopper.jsx
+++ b/projectforge-webapp/src/components/design/popper/AdvancedPopper.jsx
@@ -72,7 +72,7 @@ function AdvancedPopper(
             // Neues aktives Element nach Verlassen des Fokus abrufen
             setCurrentTimeout(
                 setTimeout(() => {
-                    if (!reference.current.contains(document.activeElement)) {
+                    if (reference.current && !reference.current.contains(document.activeElement)) {
                         setIsOpen(false);
                     }
                 }, 1),

3685edd6c

Migration zu React 18 (Work-in-Progress)
3685edd6c9f0dfd4582dbeb01c05491c254ccb84
diff --git a/projectforge-webapp/src/components/design/popper/AdvancedPopper.jsx b/projectforge-webapp/src/components/design/popper/AdvancedPopper.jsx
index 9987f3259..2b3b66ea1 100644
--- a/projectforge-webapp/src/components/design/popper/AdvancedPopper.jsx
+++ b/projectforge-webapp/src/components/design/popper/AdvancedPopper.jsx
@@ -12,10 +12,10 @@ function AdvancedPopper(
         children,
         className,
         contentClassName,
-        isOpen,
+        isOpen = false,
         onBlur,
         setIsOpen,
-        withInput,
+        withInput = false,
         ...props
     },
 ) {
@@ -156,15 +156,4 @@ AdvancedPopper.propTypes = {
     withInput: PropTypes.bool,
 };
 
-AdvancedPopper.defaultProps = {
-    actions: undefined,
-    additionalClassName: undefined,
-    children: undefined,
-    className: undefined,
-    contentClassName: undefined,
-    isOpen: false,
-    onBlur: undefined,
-    withInput: false,
-};
-
 export default AdvancedPopper;

918215de8

Korrektur der Breiten-/Höhenberechnung von AdvancedPopper
918215de8bb987571818a7b183b659cc443ebdc0
diff --git a/projectforge-webapp/src/components/design/popper/AdvancedPopper.jsx b/projectforge-webapp/src/components/design/popper/AdvancedPopper.jsx
index 8548ef329..9987f3259 100644
--- a/projectforge-webapp/src/components/design/popper/AdvancedPopper.jsx
+++ b/projectforge-webapp/src/components/design/popper/AdvancedPopper.jsx
@@ -53,8 +53,8 @@ function AdvancedPopper(
             if (reference.current) {
                 const { top, left } = reference.current.getBoundingClientRect();
 
-                setAdditionalHeight(document.body.clientHeight - top - basicHeight - 64);
-                setAdditionalWidth(document.body.clientWidth - left - basicWidth - 16);
+                setAdditionalHeight(document.body.clientHeight - top - 64);
+                setAdditionalWidth(document.body.clientWidth - left - 16);
             }
         },
         [

1bbd80660

Korrektur der AdvancedPopper-Abmessungen
1bbd806609ed65469ca848259a8e1df399ab954a
diff --git a/projectforge-webapp/src/components/design/popper/AdvancedPopper.jsx b/projectforge-webapp/src/components/design/popper/AdvancedPopper.jsx
index fd1f00d5d..8548ef329 100644
--- a/projectforge-webapp/src/components/design/popper/AdvancedPopper.jsx
+++ b/projectforge-webapp/src/components/design/popper/AdvancedPopper.jsx
@@ -53,8 +53,8 @@ function AdvancedPopper(
             if (reference.current) {
                 const { top, left } = reference.current.getBoundingClientRect();
 
-                setAdditionalHeight(window.innerHeight - top - basicHeight - 64);
-                setAdditionalWidth(window.innerWidth - left - basicWidth - 16);
+                setAdditionalHeight(document.body.clientHeight - top - basicHeight - 64);
+                setAdditionalWidth(document.body.clientWidth - left - basicWidth - 16);
             }
         },
         [

f61b44dab

Korrektur des Öffnens von AdvancedPopper bei Klick
f61b44daba7f1cd26fca31f1c51518b4b5d094f6
diff --git a/projectforge-webapp/src/components/design/popper/AdvancedPopper.jsx b/projectforge-webapp/src/components/design/popper/AdvancedPopper.jsx
index f9c05f9a4..fd1f00d5d 100644
--- a/projectforge-webapp/src/components/design/popper/AdvancedPopper.jsx
+++ b/projectforge-webapp/src/components/design/popper/AdvancedPopper.jsx
@@ -84,6 +84,12 @@ function AdvancedPopper(
         }
     };
 
+    const handleClick = ({ target }) => {
+        if (basicReference.current && basicReference.current.contains(target)) {
+            setIsOpen(true);
+        }
+    };
+
     const additionalVisible = isOpen && children;
 
     return (
@@ -97,7 +103,7 @@ function AdvancedPopper(
             {...props}
             onBlur={handleBlur}
             role="menu"
-            onClick={() => setIsOpen(true)}
+            onClick={handleClick}
             onKeyDown={undefined}
             tabIndex={0}
         >