From 231f3675f1640bec4cadba159cfd68bc9141e304 Mon Sep 17 00:00:00 2001
From: Pramod S <87521752+pramodcog@users.noreply.github.com>
Date: Mon, 14 Aug 2023 14:19:23 +0200
Subject: [PATCH] fix(react-components): 3D resources Submenu disappear in FDX
when hovered (#3570)
* fixed Submenu disappear issue occuring in FDX when mouse cursor is hovered on the menu items
* removed unused state in layerscontainer
* updated appending of 3D resource components to use context of Div element Ref
---------
Co-authored-by: cognite-bulldozer[bot] <51074376+cognite-bulldozer[bot]@users.noreply.github.com>
---
.../RevealContainer/RevealContainer.tsx | 20 +++++++++++-----
.../RevealContainerElementContext.ts | 17 +++++++++++++
.../components/RevealToolbar/LayersButton.tsx | 13 +++++++++-
.../CadModelLayersContainer.tsx | 24 ++++++++++++++++---
.../Image360LayersContainer.tsx | 22 ++++++++++++++---
.../PointCloudLayersContainer.tsx | 22 ++++++++++++++---
6 files changed, 102 insertions(+), 16 deletions(-)
create mode 100644 react-components/src/components/RevealContainer/RevealContainerElementContext.ts
diff --git a/react-components/src/components/RevealContainer/RevealContainer.tsx b/react-components/src/components/RevealContainer/RevealContainer.tsx
index c59ba344991..bf2401ee122 100644
--- a/react-components/src/components/RevealContainer/RevealContainer.tsx
+++ b/react-components/src/components/RevealContainer/RevealContainer.tsx
@@ -11,6 +11,7 @@ import { ModelsLoadingStateContext } from '../Reveal3DResources/ModelsLoadingCon
import { SDKProvider } from './SDKProvider';
import { QueryClientProvider, QueryClient } from '@tanstack/react-query';
import { useRevealKeepAlive } from '../RevealKeepAlive/RevealKeepAliveContext';
+import { RevealContainerElementContext } from './RevealContainerElementContext';
type RevealContainerProps = {
color?: Color;
@@ -67,14 +68,21 @@ export function RevealContainer({
);
function mountChildren(): ReactElement {
- if (viewer === undefined || viewerDomElement.current === null) return <>>;
+ if (
+ viewer === undefined ||
+ viewerDomElement.current === null ||
+ wrapperDomElement.current === null
+ )
+ return <>>;
return (
<>
-
-
- {createPortal(children, viewerDomElement.current)}
-
-
+
+
+
+ {createPortal(children, viewerDomElement.current)}
+
+
+
>
);
}
diff --git a/react-components/src/components/RevealContainer/RevealContainerElementContext.ts b/react-components/src/components/RevealContainer/RevealContainerElementContext.ts
new file mode 100644
index 00000000000..7f6ec5b4484
--- /dev/null
+++ b/react-components/src/components/RevealContainer/RevealContainerElementContext.ts
@@ -0,0 +1,17 @@
+/*!
+ * Copyright 2023 Cognite AS
+ */
+
+import { createContext, useContext } from 'react';
+
+export const RevealContainerElementContext = createContext(null);
+
+export const useRevealContainerElement = (): HTMLDivElement => {
+ const element = useContext(RevealContainerElementContext);
+ if (element === null) {
+ throw new Error(
+ 'useRevealContainerElement must be used within a RevealContainerElementContextProvider'
+ );
+ }
+ return element;
+};
diff --git a/react-components/src/components/RevealToolbar/LayersButton.tsx b/react-components/src/components/RevealToolbar/LayersButton.tsx
index 91e7449e764..0818674351e 100644
--- a/react-components/src/components/RevealToolbar/LayersButton.tsx
+++ b/react-components/src/components/RevealToolbar/LayersButton.tsx
@@ -15,10 +15,13 @@ import {
import { useReveal } from '../RevealContainer/RevealContext';
import { use3DModelName } from '../../hooks/use3DModelName';
import { isEqual } from 'lodash';
+import { useRevealContainerElement } from '../RevealContainer/RevealContainerElementContext';
export const LayersButton = (): ReactElement => {
const viewer = useReveal();
+ const revealContainerElement = useRevealContainerElement();
const [layersEnabled, setLayersEnabled] = useState(false);
+ const [visible, setVisible] = useState(false);
const [cadModelIds, setCadModelIds] = useState([]);
const [pointCloudModelIds, setPointCloudModelIds] = useState([]);
@@ -36,6 +39,7 @@ export const LayersButton = (): ReactElement => {
const showLayers = (): void => {
setLayersEnabled(!layersEnabled);
+ setVisible((prevState) => !prevState);
};
useEffect(() => {
@@ -146,9 +150,15 @@ export const LayersButton = (): ReactElement => {
setReveal3DResourcesLayerData(updated3DResourcesLayerData);
}, [updated3DResourcesLayerData]);
+ useEffect(() => {
+ viewer.on('click', () => {
+ setVisible(false);
+ });
+ }, [viewer]);
+
return (
{
}}
/>
}
+ visible={visible}
placement="auto">
diff --git a/react-components/src/components/RevealToolbar/LayersContainer/CadModelLayersContainer.tsx b/react-components/src/components/RevealToolbar/LayersContainer/CadModelLayersContainer.tsx
index f01490a13e2..ca89f9c64d1 100644
--- a/react-components/src/components/RevealToolbar/LayersContainer/CadModelLayersContainer.tsx
+++ b/react-components/src/components/RevealToolbar/LayersContainer/CadModelLayersContainer.tsx
@@ -2,13 +2,14 @@
* Copyright 2023 Cognite AS
*/
-import { type ReactElement } from 'react';
+import { useState, type ReactElement } from 'react';
import { useReveal } from '../../RevealContainer/RevealContext';
import { type CogniteCadModel } from '@cognite/reveal';
import { Checkbox, Flex, Menu } from '@cognite/cogs.js';
import { StyledChipCount, StyledLabel, StyledSubMenu } from './elements';
import { uniqueId } from 'lodash';
import { type Reveal3DResourcesLayersProps } from './types';
+import { useRevealContainerElement } from '../../RevealContainer/RevealContainerElementContext';
export const CadModelLayersContainer = ({
layerProps
@@ -16,6 +17,8 @@ export const CadModelLayersContainer = ({
layerProps: Reveal3DResourcesLayersProps;
}): ReactElement => {
const viewer = useReveal();
+ const revealContainerElement = useRevealContainerElement();
+ const [visible, setVisible] = useState(false);
const { cadLayerData } = layerProps.reveal3DResourcesLayerData;
@@ -63,6 +66,7 @@ export const CadModelLayersContainer = ({
{cadLayerData.map((data) => (
{cadLayerData.length > 0 && (
-
-
+ {
+ setVisible(false);
+ }}
+ content={cadModelContent()}
+ title="CAD models">
+ {
+ setVisible((prevState) => !prevState);
+ }}>
{
e.stopPropagation();
handleAllCadModelsVisibility(e.target.checked);
+ setVisible(true);
}}
/>
CAD models
diff --git a/react-components/src/components/RevealToolbar/LayersContainer/Image360LayersContainer.tsx b/react-components/src/components/RevealToolbar/LayersContainer/Image360LayersContainer.tsx
index 811b8a23c74..e490ccdb8d5 100644
--- a/react-components/src/components/RevealToolbar/LayersContainer/Image360LayersContainer.tsx
+++ b/react-components/src/components/RevealToolbar/LayersContainer/Image360LayersContainer.tsx
@@ -2,13 +2,14 @@
* Copyright 2023 Cognite AS
*/
-import { type ReactElement } from 'react';
+import { useState, type ReactElement } from 'react';
import { useReveal } from '../../RevealContainer/RevealContext';
import { Checkbox, Flex, Menu } from '@cognite/cogs.js';
import { StyledChipCount, StyledLabel, StyledSubMenu } from './elements';
import { type Image360Collection } from '@cognite/reveal';
import { uniqueId } from 'lodash';
import { type Reveal3DResourcesLayersProps } from './types';
+import { useRevealContainerElement } from '../../RevealContainer/RevealContainerElementContext';
export const Image360CollectionLayerContainer = ({
layerProps
@@ -16,6 +17,8 @@ export const Image360CollectionLayerContainer = ({
layerProps: Reveal3DResourcesLayersProps;
}): ReactElement => {
const viewer = useReveal();
+ const revealContainerElement = useRevealContainerElement();
+ const [visible, setVisible] = useState(false);
const { image360LayerData } = layerProps.reveal3DResourcesLayerData;
const count = image360LayerData.length.toString();
@@ -79,14 +82,27 @@ export const Image360CollectionLayerContainer = ({
return (
<>
{image360LayerData.length > 0 && (
-
-
+ {
+ setVisible(false);
+ }}
+ content={image360Content()}
+ title="360 images">
+ {
+ setVisible((prevState) => !prevState);
+ }}>
{
e.stopPropagation();
handleAll360ImagesVisibility(e.target.checked);
+ setVisible(true);
}}
/>
360 images
diff --git a/react-components/src/components/RevealToolbar/LayersContainer/PointCloudLayersContainer.tsx b/react-components/src/components/RevealToolbar/LayersContainer/PointCloudLayersContainer.tsx
index c997bed328c..2e4ce5f7949 100644
--- a/react-components/src/components/RevealToolbar/LayersContainer/PointCloudLayersContainer.tsx
+++ b/react-components/src/components/RevealToolbar/LayersContainer/PointCloudLayersContainer.tsx
@@ -2,7 +2,7 @@
* Copyright 2023 Cognite AS
*/
-import { type ReactElement } from 'react';
+import { useState, type ReactElement } from 'react';
import { useReveal } from '../../RevealContainer/RevealContext';
import { Checkbox, Flex, Menu } from '@cognite/cogs.js';
@@ -10,6 +10,7 @@ import { StyledChipCount, StyledLabel, StyledSubMenu } from './elements';
import { type CognitePointCloudModel } from '@cognite/reveal';
import { uniqueId } from 'lodash';
import { type Reveal3DResourcesLayersProps } from './types';
+import { useRevealContainerElement } from '../../RevealContainer/RevealContainerElementContext';
export const PointCloudLayersContainer = ({
layerProps
@@ -17,6 +18,8 @@ export const PointCloudLayersContainer = ({
layerProps: Reveal3DResourcesLayersProps;
}): ReactElement => {
const viewer = useReveal();
+ const revealContainerElement = useRevealContainerElement();
+ const [visible, setVisible] = useState(false);
const { pointCloudLayerData } = layerProps.reveal3DResourcesLayerData;
const count = pointCloudLayerData.length.toString();
const someModelVisible = !pointCloudLayerData.every((data) => !data.isToggled);
@@ -74,14 +77,27 @@ export const PointCloudLayersContainer = ({
return (
<>
{pointCloudLayerData.length > 0 && (
-
-
+ {
+ setVisible(false);
+ }}
+ content={pointCloudModelContent()}
+ title="Point clouds">
+ {
+ setVisible((prevState) => !prevState);
+ }}>
{
e.stopPropagation();
handleAllPointCloudModelsVisibility(e.target.checked);
+ setVisible(true);
}}
/>
Point clouds