diff --git a/client/package-lock.json b/client/package-lock.json index c8cc96e9..915cfd50 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -6,6 +6,7 @@ "": { "name": "planka-client", "dependencies": { + "@juggle/resize-observer": "^3.4.0", "classnames": "^2.3.1", "connected-react-router": "^6.9.3", "date-fns": "^2.29.1", @@ -3030,6 +3031,11 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@juggle/resize-observer": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz", + "integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==" + }, "node_modules/@leichtgewicht/ip-codec": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", @@ -27333,6 +27339,11 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "@juggle/resize-observer": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz", + "integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==" + }, "@leichtgewicht/ip-codec": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", diff --git a/client/package.json b/client/package.json index ec109f89..f4f05ae7 100755 --- a/client/package.json +++ b/client/package.json @@ -63,6 +63,7 @@ } }, "dependencies": { + "@juggle/resize-observer": "^3.4.0", "classnames": "^2.3.1", "connected-react-router": "^6.9.3", "date-fns": "^2.29.1", diff --git a/client/src/lib/popup/with-popup.jsx b/client/src/lib/popup/with-popup.jsx index a03f7a06..50c2302b 100755 --- a/client/src/lib/popup/with-popup.jsx +++ b/client/src/lib/popup/with-popup.jsx @@ -1,4 +1,5 @@ -import React, { useCallback, useState } from 'react'; +import { ResizeObserver } from '@juggle/resize-observer'; +import React, { useCallback, useRef, useState } from 'react'; import PropTypes from 'prop-types'; import { Button, Popup as SemanticUIPopup } from 'semantic-ui-react'; @@ -8,6 +9,9 @@ export default (WrappedComponent, defaultProps) => { const Popup = React.memo(({ children, ...props }) => { const [isOpened, setIsOpened] = useState(false); + const wrapper = useRef(null); + const resizeObserver = useRef(null); + const handleOpen = useCallback(() => { setIsOpened(true); }, []); @@ -37,6 +41,29 @@ export default (WrappedComponent, defaultProps) => { [children], ); + const handleContentRef = useCallback((element) => { + if (resizeObserver.current) { + resizeObserver.current.disconnect(); + } + + if (!element) { + resizeObserver.current = null; + return; + } + + resizeObserver.current = new ResizeObserver(() => { + if (resizeObserver.current.isInitial) { + resizeObserver.current.isInitial = false; + return; + } + + wrapper.current.positionUpdate(); + }); + + resizeObserver.current.isInitial = true; + resizeObserver.current.observe(element); + }, []); + const tigger = React.cloneElement(children, { onClick: handleTriggerClick, }); @@ -45,6 +72,7 @@ export default (WrappedComponent, defaultProps) => { { onClick={handleClick} {...defaultProps} // eslint-disable-line react/jsx-props-no-spreading > -