// 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 (
);
};
}