// Copyright (C) 2021 Intel Corporation // // SPDX-License-Identifier: MIT /// import { SmallDashOutlined } from '@ant-design/icons'; import Popover from 'antd/lib/popover'; import React, { useEffect, useRef, useState } from 'react'; import ReactDOM from 'react-dom'; const extraControlsContentClassName = 'cvat-extra-controls-control-content'; let onUpdateChildren: Function | null = null; export function ExtraControlsControl(): JSX.Element { const [hasChildren, setHasChildren] = useState(false); const [initialized, setInitialized] = useState(false); useEffect(() => { if (!initialized) { setInitialized(true); } window.document.body.dispatchEvent(new MouseEvent('mousedown', { bubbles: true })); }, []); onUpdateChildren = () => { const contentElement = window.document.getElementsByClassName(extraControlsContentClassName)[0]; if (contentElement) { setHasChildren(contentElement.children.length > 0); } }; return ( } > ); } export default function ControlVisibilityObserver

( ControlComponent: React.FunctionComponent

, ): React.FunctionComponent

{ let visibilityHeightThreshold = 0; // minimum value of height when element can be pushed to main panel return (props: P): JSX.Element | null => { const ref = useRef(null); const [visible, setVisible] = useState(true); useEffect(() => { if (ref && ref.current) { const wrapper = ref.current; const parentElement = ref.current.parentElement as HTMLElement; const reservedHeight = 45; // for itself const observer = new ResizeObserver(() => { // when parent size was changed, check again can we put the control // into the side panel or not const availableHeight = parentElement.offsetHeight; setVisible(availableHeight - reservedHeight >= visibilityHeightThreshold); }); if (ref && ref.current) { const availableHeight = parentElement.offsetHeight; // when first mount, remember bottom coordinate which equal to minimum parent width // to put the control into side panel visibilityHeightThreshold = wrapper.offsetTop + wrapper.offsetHeight; // start observing parent size observer.observe(ref.current.parentElement as HTMLElement); // then put it to extra controls if parent height is not enought setVisible(availableHeight - reservedHeight >= visibilityHeightThreshold); } return () => { observer.disconnect(); }; } return () => {}; }, []); useEffect(() => { // when visibility changed, we notify extra content element because now its children changed if (onUpdateChildren) { onUpdateChildren(); } }, [visible]); if (!visible) { const extraControlsContent = window.document.getElementsByClassName(extraControlsContentClassName)[0]; if (extraControlsContent) { return ReactDOM.createPortal(, extraControlsContent); } return null; } // first mount always to side panel return (

); }; }