From e3696704b927857c015b19ae5a683ff2b99df3fb Mon Sep 17 00:00:00 2001 From: "Christopher J. Tannum" Date: Thu, 3 Aug 2023 09:26:38 +0200 Subject: [PATCH] feat: add withSuppressRevealEvents HOC (#3545) * feat: add withSuppressRevealEvents HOC * chore: cleanup export in index.ts * fix: remove unused prop --------- Co-authored-by: cognite-bulldozer[bot] <51074376+cognite-bulldozer[bot]@users.noreply.github.com> --- .../RevealContainer/RevealContainer.tsx | 3 -- .../RevealToolbar/RevealToolbar.tsx | 11 ++++- .../withSuppressRevealEvents.tsx | 43 +++++++++++++++++++ react-components/src/index.ts | 29 ++++++++----- react-components/stories/Toolbar.stories.tsx | 10 ++++- 5 files changed, 80 insertions(+), 16 deletions(-) create mode 100644 react-components/src/higher-order-components/withSuppressRevealEvents.tsx diff --git a/react-components/src/components/RevealContainer/RevealContainer.tsx b/react-components/src/components/RevealContainer/RevealContainer.tsx index 12e5099c3e3..0d7f29b0b3d 100644 --- a/react-components/src/components/RevealContainer/RevealContainer.tsx +++ b/react-components/src/components/RevealContainer/RevealContainer.tsx @@ -13,7 +13,6 @@ import { QueryClientProvider, QueryClient } from '@tanstack/react-query'; type RevealContainerProps = { color?: Color; sdk: CogniteClient; - uiElements?: ReactNode; children?: ReactNode; viewerOptions?: Pick< Cognite3DViewerOptions, @@ -32,7 +31,6 @@ const queryClient = new QueryClient(); export function RevealContainer({ children, sdk, - uiElements, color, viewerOptions }: RevealContainerProps): ReactElement { @@ -52,7 +50,6 @@ export function RevealContainer({ ref={revealDomElementRef}> {mountChildren()} - {uiElements} ); diff --git a/react-components/src/components/RevealToolbar/RevealToolbar.tsx b/react-components/src/components/RevealToolbar/RevealToolbar.tsx index 6af87fe867b..93efc084bcf 100644 --- a/react-components/src/components/RevealToolbar/RevealToolbar.tsx +++ b/react-components/src/components/RevealToolbar/RevealToolbar.tsx @@ -7,6 +7,7 @@ import { Button, ToolBar, type ToolBarProps } from '@cognite/cogs.js'; import { FitModelsButton } from './FitModelsButton'; import { LayersButton } from './LayersButton'; import { SlicerButton } from './SlicerButton'; +import { withSuppressRevealEvents } from '../../higher-order-components/withSuppressRevealEvents'; const defaultStyle: ToolBarProps = { style: { @@ -35,7 +36,7 @@ const defaultContent = ( ); -export const RevealToolbar = ( +const RevealToolbarContainer = ( props: ToolBarProps & { toolBarContent?: JSX.Element } ): ReactElement => { if (props.className === undefined && props.style === undefined) { @@ -44,6 +45,14 @@ export const RevealToolbar = ( return {props.toolBarContent ?? defaultContent}; }; +export const RevealToolbar = withSuppressRevealEvents( + RevealToolbarContainer +) as typeof RevealToolbarContainer & { + FitModelsButton: typeof FitModelsButton; + SlicerButton: typeof SlicerButton; + LayersButton: typeof LayersButton; +}; + RevealToolbar.FitModelsButton = FitModelsButton; RevealToolbar.SlicerButton = SlicerButton; RevealToolbar.LayersButton = LayersButton; diff --git a/react-components/src/higher-order-components/withSuppressRevealEvents.tsx b/react-components/src/higher-order-components/withSuppressRevealEvents.tsx new file mode 100644 index 00000000000..48f44dfde6c --- /dev/null +++ b/react-components/src/higher-order-components/withSuppressRevealEvents.tsx @@ -0,0 +1,43 @@ +/*! + * Copyright 2023 Cognite AS + */ + +import { useRef, type ComponentType, type JSX, useEffect, type ReactElement } from 'react'; + +export function withSuppressRevealEvents( + Component: ComponentType +): ComponentType { + return function SuppressRevealEvents(props: T): ReactElement { + const divRef = useRef(null); + + const stopPropagation = (event: Event): void => { + event.stopPropagation(); + }; + + useEffect(() => { + const div = divRef.current; + + if (div === null) { + return; + } + + div.addEventListener('pointerdown', stopPropagation); + div.addEventListener('pointerup', stopPropagation); + div.addEventListener('pointermove', stopPropagation); + div.addEventListener('wheel', stopPropagation); + + return () => { + div.removeEventListener('pointerdown', stopPropagation); + div.removeEventListener('pointerup', stopPropagation); + div.removeEventListener('pointermove', stopPropagation); + div.removeEventListener('wheel', stopPropagation); + }; + }, []); + + return ( +
+ +
+ ); + }; +} diff --git a/react-components/src/index.ts b/react-components/src/index.ts index d3f559987c4..a897db6522d 100644 --- a/react-components/src/index.ts +++ b/react-components/src/index.ts @@ -2,29 +2,41 @@ * Copyright 2023 Cognite AS */ import '@cognite/cogs.js/dist/cogs.css'; + +// Components export { RevealContainer } from './components/RevealContainer/RevealContainer'; +export { Reveal3DResources } from './components/Reveal3DResources/Reveal3DResources'; +export { PointCloudContainer } from './components/PointCloudContainer/PointCloudContainer'; +export { CadModelContainer } from './components/CadModelContainer/CadModelContainer'; +export { Image360CollectionContainer } from './components/Image360CollectionContainer/Image360CollectionContainer'; +export { Image360HistoricalDetails } from './components/Image360HistoricalDetails/Image360HistoricalDetails'; +export { ViewerAnchor } from './components/ViewerAnchor/ViewerAnchor'; +export { CameraController } from './components/CameraController/CameraController'; +export { RevealToolbar } from './components/RevealToolbar/RevealToolbar'; + +// Hooks export { useReveal } from './components/RevealContainer/RevealContext'; +export { use3DModelName } from './hooks/use3DModelName'; +export { useFdmAssetMappings } from './hooks/useFdmAssetMappings'; + +// Higher order components +export { withSuppressRevealEvents } from './higher-order-components/withSuppressRevealEvents'; + +// Types export { - PointCloudContainer, type PointCloudModelStyling, type AnnotationIdStylingGroup } from './components/PointCloudContainer/PointCloudContainer'; export { - CadModelContainer, type CadModelStyling, type TreeIndexStylingGroup, type NodeStylingGroup } from './components/CadModelContainer/CadModelContainer'; -export { Image360CollectionContainer } from './components/Image360CollectionContainer/Image360CollectionContainer'; -export { Image360HistoricalDetails } from './components/Image360HistoricalDetails/Image360HistoricalDetails'; export { - Reveal3DResources, type Reveal3DResourcesProps, type Reveal3DResourcesStyling, type FdmAssetStylingGroup } from './components/Reveal3DResources/Reveal3DResources'; -export { ViewerAnchor } from './components/ViewerAnchor/ViewerAnchor'; -export { CameraController } from './components/CameraController/CameraController'; export type { AddImageCollection360Options, AddResourceOptions, @@ -32,7 +44,4 @@ export type { NodeDataResult } from './components/Reveal3DResources/types'; export type { Source } from './utilities/FdmSDK'; -export { RevealToolbar } from './components/RevealToolbar/RevealToolbar'; -export { useFdmAssetMappings } from './hooks/useFdmAssetMappings'; export { type FdmAssetMappingsConfig } from './hooks/types'; -export { use3DModelName } from './hooks/use3DModelName'; diff --git a/react-components/stories/Toolbar.stories.tsx b/react-components/stories/Toolbar.stories.tsx index 635f659dda1..038f7f195a1 100644 --- a/react-components/stories/Toolbar.stories.tsx +++ b/react-components/stories/Toolbar.stories.tsx @@ -3,7 +3,12 @@ */ import type { Meta, StoryObj } from '@storybook/react'; -import { CadModelContainer, RevealContainer, RevealToolbar } from '../src'; +import { + CadModelContainer, + RevealContainer, + RevealToolbar, + withSuppressRevealEvents +} from '../src'; import { CogniteClient } from '@cognite/sdk'; import { Color } from 'three'; import styled from 'styled-components'; @@ -26,7 +31,7 @@ const sdk = new CogniteClient({ getToken: async () => await Promise.resolve(token) }); -const MyCustomToolbar = styled(ToolBar)` +const MyCustomToolbar = styled(withSuppressRevealEvents(ToolBar))` position: absolute; right: 20px; top: 70px; @@ -55,6 +60,7 @@ export const Main: Story = { + )