Răsfoiți Sursa

Add conditional computeStyle modifiers

https://youtrack.weseek.co.jp/issue/GW-7947
- Back to using reactstrap 8 instead of v9 due to differences in bootstrap versions
- Adjust props of DropdownMenu components
- Create conditional custom modifiers (Flickering only happened on right aligned DropdownMenu)
- Remove prevent scroll method
-  Add z-Index style to CopyDropdown component
Mudana-Grune 2 ani în urmă
părinte
comite
2ca728f875

+ 1 - 1
apps/app/package.json

@@ -162,7 +162,7 @@
     "react-syntax-highlighter": "^15.5.0",
     "react-toastify": "^9.1.1",
     "react-use-ripple": "^1.5.2",
-    "reactstrap": "^9.1.9",
+    "reactstrap": "^8.10.1",
     "reconnecting-websocket": "^4.4.0",
     "redis": "^3.0.2",
     "rehype-katex": "^6.0.2",

+ 1 - 1
apps/app/src/components/Admin/Users/UserMenu.tsx

@@ -95,7 +95,7 @@ const UserMenu = (props: UserMenuProps) => {
         {(user.status === USER_STATUS.INVITED && !isInvitationEmailSended)
         && <i className={`fa fa-circle text-danger grw-usermenu-notification-icon ${styles['grw-usermenu-notification-icon']}`} />}
       </DropdownToggle>
-      <DropdownMenu >
+      <DropdownMenu positionFixed>
         {renderEditMenu()}
         {user.status !== USER_STATUS.DELETED && renderStatusMenu()}
         {user.status === USER_STATUS.ACTIVE && renderAdminMenu()}

+ 41 - 29
apps/app/src/components/Common/Dropdown/PageItemControl.tsx

@@ -245,11 +245,51 @@ const PageItemControlDropdownMenu = React.memo((props: DropdownMenuProps): JSX.E
     );
   }
 
+  // Conditional modifiers
+  // To prevent flickering. only happened when `right` is true and persist props should be enabled
+  let modifiers = {};
+  if (alignRight) {
+    modifiers = {
+      applyStyle: {
+        enabled: true,
+      },
+      computeStyle: {
+        enabled: true,
+        fn: (data) => {
+          const popperRect = data.offsets.popper;
+          // Calculate transform styles
+          const newTransform = `translate3d(${popperRect.left - window.innerWidth + popperRect.width}px, ${popperRect.top}px, 0px)`;
+          const styles = {
+            transform: newTransform,
+            top: '0px',
+            right: '0px',
+            willChange: 'transform',
+          };
+          data.styles = styles;
+          return data;
+        },
+      },
+      preventOverflow: {
+        boundariesElement: 'viewport',
+      },
+    };
+  }
+  else {
+    modifiers = {
+      preventOverflow: {
+        boundariesElement: 'viewport',
+      },
+    };
+  }
+
+
   return (
     <DropdownMenu
       data-testid="page-item-control-menu"
-      end={alignRight}
+      right={alignRight}
+      modifiers={modifiers}
       container="body"
+      persist = { !!alignRight}
       style={{ zIndex: 1055 }} /* make it larger than $zindex-modal of bootstrap */
     >
       {contents}
@@ -279,34 +319,6 @@ export const PageItemControlSubstance = (props: PageItemControlSubstanceProps):
 
   const { data: fetchedPageInfo, mutate: mutatePageInfo } = useSWRxPageInfo(shouldFetch ? pageId : null);
 
-  // Efect for disable scroll if dropdown menu is opened
-  useEffect(() => {
-    // Get the current page scroll position
-    const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
-    const scrollHandler = () => {
-      window.scrollTo(0, scrollTop);
-    };
-    // Disable scroll
-    const disableScroll = () => {
-      if (isOpen && scrollTop >= 0) {
-        window.addEventListener('scroll', scrollHandler, { passive: false });
-      }
-    };
-    // Enable scroll
-    const enableScroll = () => {
-      window.removeEventListener('scroll', scrollHandler);
-    };
-
-    // Add event listeners
-    disableScroll();
-
-    // Clean up function
-    return () => {
-      enableScroll();
-    };
-  }, [isOpen]);
-
-
   // update shouldFetch (and will never be false)
   useEffect(() => {
     if (shouldFetch) {

+ 1 - 1
apps/app/src/components/InAppNotification/InAppNotificationDropdown.tsx

@@ -86,7 +86,7 @@ export const InAppNotificationDropdown = (): JSX.Element => {
       <DropdownToggle className="px-3 nav-link border-0 bg-transparent" innerRef={buttonRef}>
         <i className="icon-bell" /> {badge}
       </DropdownToggle>
-      <DropdownMenu end>
+      <DropdownMenu right>
         { inAppNotificationData != null && inAppNotificationData.docs.length === 0
           // no items
           ? <DropdownItem disabled>{t('in_app_notification.mark_all_as_read')}</DropdownItem>

+ 2 - 29
apps/app/src/components/Page/CopyDropdown.jsx

@@ -1,5 +1,5 @@
 import React, {
-  useState, useMemo, useCallback, useEffect,
+  useState, useMemo, useCallback,
 } from 'react';
 
 import { pagePathUtils } from '@growi/core';
@@ -98,33 +98,6 @@ const CopyDropdown = (props) => {
   }, []);
 
 
-  // Efect for disable scroll if dropdown menu is opened
-  useEffect(() => {
-    // Get the current page scroll position
-    const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
-    const scrollHandler = () => {
-      window.scrollTo(0, scrollTop);
-    };
-    // Disable scroll
-    const disableScroll = () => {
-      if (dropdownOpen && scrollTop >= 0) {
-        window.addEventListener('scroll', scrollHandler, { passive: false });
-      }
-    };
-    // Enable scroll
-    const enableScroll = () => {
-      window.removeEventListener('scroll', scrollHandler);
-    };
-
-    // Add event listeners
-    disableScroll();
-
-    // Clean up function
-    return () => {
-      enableScroll();
-    };
-  }, [dropdownOpen]);
-
   /*
    * render
    */
@@ -145,7 +118,7 @@ const CopyDropdown = (props) => {
           <span id={dropdownToggleId}>{children}</span>
         </DropdownToggle>
 
-        <DropdownMenu >
+        <DropdownMenu positionFixed modifiers={{ preventOverflow: { boundariesElement: 'viewport' } }} style={{ zIndex: 1055 }}>
 
           <div className="d-flex align-items-center justify-content-between">
             <DropdownItem header className="px-3">

+ 1 - 1
apps/app/src/components/RevisionComparer/RevisionComparer.tsx

@@ -76,7 +76,7 @@ export const RevisionComparer = (props: RevisionComparerProps): JSX.Element => {
           >
             <i className="ti ti-clipboard"></i>
           </DropdownToggle>
-          <DropdownMenu end >
+          <DropdownMenu positionFixed right modifiers={{ preventOverflow: { boundariesElement: undefined } }}>
             {/* Page path URL */}
             <CopyToClipboard text={generateURL(currentPagePath)}>
               <DropdownItem className="px-3">

+ 2 - 2
apps/app/src/components/SavePageControls.tsx

@@ -51,7 +51,7 @@ export const SavePageControls = (props: SavePageControlsProps): JSX.Element | nu
     mutateGrant(grantData);
   }, [mutateGrant]);
 
-  const save = useCallback(async (): Promise<void> => {
+  const save = useCallback(async(): Promise<void> => {
     // save
     globalEmitter.emit('saveAndReturnToView', { slackChannels });
   }, [slackChannels]);
@@ -107,7 +107,7 @@ export const SavePageControls = (props: SavePageControlsProps): JSX.Element | nu
           {labelSubmitButton}
         </Button>
         <DropdownToggle caret color="primary" disabled={isWaitingSaveProcessing} />
-        <DropdownMenu end>
+        <DropdownMenu right>
           <DropdownItem onClick={saveAndOverwriteScopesOfDescendants}>
             {labelOverwriteScopes}
           </DropdownItem>

+ 43 - 21
yarn.lock

@@ -1544,7 +1544,7 @@
   dependencies:
     regenerator-runtime "^0.13.4"
 
-"@babel/runtime@^7.20.13", "@babel/runtime@^7.20.6", "@babel/runtime@^7.5.5":
+"@babel/runtime@^7.20.13", "@babel/runtime@^7.20.6":
   version "7.21.0"
   resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673"
   integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==
@@ -2063,6 +2063,14 @@
   resolved "https://registry.yarnpkg.com/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz#98c23c950a3d9b6c8f0daed06da6c3af06981340"
   integrity sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==
 
+"@hypnosphi/create-react-context@^0.3.1":
+  version "0.3.1"
+  resolved "https://registry.yarnpkg.com/@hypnosphi/create-react-context/-/create-react-context-0.3.1.tgz#f8bfebdc7665f5d426cba3753e0e9c7d3154d7c6"
+  integrity sha512-V1klUed202XahrWJLLOT3EXNeCpFHCcJntdFGI15ntCwau+jfT386w7OFTMaCqOgXUH1fa0w/I1oZs+i/Rfr0A==
+  dependencies:
+    gud "^1.0.0"
+    warning "^4.0.3"
+
 "@icon/themify-icons@1.0.1-alpha.3":
   version "1.0.1-alpha.3"
   resolved "https://registry.yarnpkg.com/@icon/themify-icons/-/themify-icons-1.0.1-alpha.3.tgz#adb1652d37d4e58f507b1634785a3779f6829e0b"
@@ -2877,11 +2885,6 @@
   resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1"
   integrity sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==
 
-"@popperjs/core@^2.6.0":
-  version "2.11.7"
-  resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.7.tgz#ccab5c8f7dc557a52ca3288c10075c9ccd37fff7"
-  integrity sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw==
-
 "@popperjs/core@^2.8.6":
   version "2.11.4"
   resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.4.tgz#d8c7b8db9226d2d7664553a0741ad7d0397ee503"
@@ -7030,7 +7033,14 @@ dom-accessibility-api@^0.5.9:
   resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.10.tgz#caa6d08f60388d0bb4539dd75fe458a9a1d0014c"
   integrity sha512-Xu9mD0UjrJisTmv7lmVSDMagQcU9R5hwAbxsaAE/35XPnPLJobbuREfV/rraiSaEj/UOvgrzQs66zyTWTlyd+g==
 
-dom-helpers@^5.0.1, dom-helpers@^5.2.0:
+dom-helpers@^3.4.0:
+  version "3.4.0"
+  resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8"
+  integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==
+  dependencies:
+    "@babel/runtime" "^7.1.2"
+
+dom-helpers@^5.2.0:
   version "5.2.1"
   resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902"
   integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==
@@ -15040,7 +15050,20 @@ react-popper@^1.0.0:
     typed-styles "^0.0.7"
     warning "^4.0.2"
 
-react-popper@^2.2.4, react-popper@^2.2.5:
+react-popper@^1.3.6:
+  version "1.3.11"
+  resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-1.3.11.tgz#a2cc3f0a67b75b66cfa62d2c409f9dd1fcc71ffd"
+  integrity sha512-VSA/bS+pSndSF2fiasHK/PTEEAyOpX60+H5EPAjoArr8JGm+oihu4UbrqcEBpQibJxBVCpYyjAX7abJ+7DoYVg==
+  dependencies:
+    "@babel/runtime" "^7.1.2"
+    "@hypnosphi/create-react-context" "^0.3.1"
+    deep-equal "^1.1.1"
+    popper.js "^1.14.4"
+    prop-types "^15.6.1"
+    typed-styles "^0.0.7"
+    warning "^4.0.2"
+
+react-popper@^2.2.5:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-2.3.0.tgz#17891c620e1320dce318bad9fede46a5f71c70ba"
   integrity sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==
@@ -15079,15 +15102,15 @@ react-toastify@^9.1.1:
   dependencies:
     clsx "^1.1.1"
 
-react-transition-group@^4.4.2:
-  version "4.4.5"
-  resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1"
-  integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==
+react-transition-group@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-3.0.0.tgz#36efa4db970d5eec5e3028e0c458931163fa3b9b"
+  integrity sha512-A9ojB/LWECbFj58SNfjK1X9aaAU+1olLS0DFSikvrr2KfMaiBELemHDa5dKNvcTk2t3gUtDL/PJpFrBKDfMpLg==
   dependencies:
-    "@babel/runtime" "^7.5.5"
-    dom-helpers "^5.0.1"
+    dom-helpers "^3.4.0"
     loose-envify "^1.4.0"
     prop-types "^15.6.2"
+    react-lifecycles-compat "^3.0.4"
 
 react-use-ripple@^1.5.2:
   version "1.5.2"
@@ -15101,17 +15124,16 @@ react@^18.2.0:
   dependencies:
     loose-envify "^1.1.0"
 
-reactstrap@^9.1.9:
-  version "9.1.9"
-  resolved "https://registry.yarnpkg.com/reactstrap/-/reactstrap-9.1.9.tgz#25b7cadef92f09fcf4440d14c1df82df001d7c4a"
-  integrity sha512-kcXHdYLmPK7rXzLotum7RI9uwvDZJ01VtjchAwzfKL8SHFZEvi7+JVsnBojf1ZIswRaTX/s8poAgZFgE8oF0zQ==
+reactstrap@^8.10.1:
+  version "8.10.1"
+  resolved "https://registry.yarnpkg.com/reactstrap/-/reactstrap-8.10.1.tgz#43ea596c7f82f88997a9c8aae203417910262d3f"
+  integrity sha512-StjLADa/12yMNjafrSs+UD7sZAGtKpLO9fZp++2Dj0IzJinqY7eQhXlM3nFf0q40YsIcLvQdFc9pKF8PF4f0Qg==
   dependencies:
     "@babel/runtime" "^7.12.5"
-    "@popperjs/core" "^2.6.0"
     classnames "^2.2.3"
     prop-types "^15.5.8"
-    react-popper "^2.2.4"
-    react-transition-group "^4.4.2"
+    react-popper "^1.3.6"
+    react-transition-group "^3.0.0"
 
 read-pkg-up@^1.0.1:
   version "1.0.1"