From d2ca0028367f29eb6cd103e53f0c3fb02d1e795a Mon Sep 17 00:00:00 2001 From: "Christopher J. Tannum" Date: Tue, 4 Jul 2023 15:04:10 +0200 Subject: [PATCH] feat(react-components): add threed resource container (#3451) * feat: add container for CAD model * feat: add 360 image collection container * fix: add 3d resource container * feat: add CameraController component * fix: add missing import * feat: infer model type using Reveal's determineModelType * fix: from QA --------- Co-authored-by: cognite-bulldozer[bot] <51074376+cognite-bulldozer[bot]@users.noreply.github.com> --- react-components/.eslintrc.cjs | 5 +- .../CadModelContainer.tsx} | 20 +++- .../CameraController/CameraController.tsx | 43 ++++++++ .../Image360CollectionContainer.tsx | 38 +++++++ .../PointCloudContainer.tsx | 51 +++++++++ .../Reveal3DResources/ModelsLoadingContext.ts | 13 +++ .../Reveal3DResources/Reveal3DResources.tsx | 103 ++++++++++++++++++ .../src/components/Reveal3DResources/types.ts | 15 +++ .../RevealContainer/RevealContainer.tsx | 21 +++- react-components/src/components/index.ts | 7 -- react-components/src/index.ts | 17 ++- .../stories/CadModelContainer.stories.tsx | 34 ++++++ .../CogniteCadModelContainer.stories.tsx | 40 ------- .../Image360CollectionContainer.stories.tsx | 29 +++++ .../stories/PointCloudContainer.stories.tsx | 33 ++++++ .../stories/Reveal3DResources.stories.tsx | 52 +++++++++ .../stories/utilities/createSdkByUrlToken.ts | 19 ++++ react-components/tsconfig.json | 2 +- react-components/webpack.config.js | 2 +- 19 files changed, 479 insertions(+), 65 deletions(-) rename react-components/src/components/{CogniteCadModelContainer/CogniteCadModelContainer.tsx => CadModelContainer/CadModelContainer.tsx} (72%) create mode 100644 react-components/src/components/CameraController/CameraController.tsx create mode 100644 react-components/src/components/Image360CollectionContainer/Image360CollectionContainer.tsx create mode 100644 react-components/src/components/PointCloudContainer/PointCloudContainer.tsx create mode 100644 react-components/src/components/Reveal3DResources/ModelsLoadingContext.ts create mode 100644 react-components/src/components/Reveal3DResources/Reveal3DResources.tsx create mode 100644 react-components/src/components/Reveal3DResources/types.ts delete mode 100644 react-components/src/components/index.ts create mode 100644 react-components/stories/CadModelContainer.stories.tsx delete mode 100644 react-components/stories/CogniteCadModelContainer.stories.tsx create mode 100644 react-components/stories/Image360CollectionContainer.stories.tsx create mode 100644 react-components/stories/PointCloudContainer.stories.tsx create mode 100644 react-components/stories/Reveal3DResources.stories.tsx create mode 100644 react-components/stories/utilities/createSdkByUrlToken.ts diff --git a/react-components/.eslintrc.cjs b/react-components/.eslintrc.cjs index 15deb934592..5d1d664f654 100644 --- a/react-components/.eslintrc.cjs +++ b/react-components/.eslintrc.cjs @@ -1,5 +1,3 @@ -const path = require('path'); - module.exports = { env: { browser: true, @@ -14,7 +12,8 @@ module.exports = { parserOptions: { ecmaVersion: 'latest', sourceType: 'module', - project: [path.join(__dirname, 'tsconfig.json')] + project: './tsconfig.json', + tsconfigRootDir: __dirname }, plugins: ['react', 'prettier', 'header'], rules: { diff --git a/react-components/src/components/CogniteCadModelContainer/CogniteCadModelContainer.tsx b/react-components/src/components/CadModelContainer/CadModelContainer.tsx similarity index 72% rename from react-components/src/components/CogniteCadModelContainer/CogniteCadModelContainer.tsx rename to react-components/src/components/CadModelContainer/CadModelContainer.tsx index 8f3a5345378..5ecd063f8cd 100644 --- a/react-components/src/components/CogniteCadModelContainer/CogniteCadModelContainer.tsx +++ b/react-components/src/components/CadModelContainer/CadModelContainer.tsx @@ -9,20 +9,22 @@ import { type Matrix4 } from 'three'; type Cognite3dModelProps = { addModelOptions: AddModelOptions; transform?: Matrix4; + onLoad?: () => void; }; -export default function CogniteCadModelContainer({ +export function CadModelContainer({ addModelOptions, - transform + transform, + onLoad }: Cognite3dModelProps): ReactElement { const modelRef = useRef(); const viewer = useReveal(); - const { modelId, revisionId } = addModelOptions; + const { modelId, revisionId, geometryFilter } = addModelOptions; useEffect(() => { - addModel(modelId, revisionId, transform).catch(console.error); + addModel(modelId, revisionId, transform, onLoad).catch(console.error); return removeModel; - }, [addModelOptions]); + }, [modelId, revisionId, geometryFilter]); useEffect(() => { if (modelRef.current === undefined || transform === undefined) return; @@ -31,12 +33,18 @@ export default function CogniteCadModelContainer({ return <>; - async function addModel(modelId: number, revisionId: number, transform?: Matrix4): Promise { + async function addModel( + modelId: number, + revisionId: number, + transform?: Matrix4, + onLoad?: () => void + ): Promise { const cadModel = await viewer.addCadModel({ modelId, revisionId }); if (transform !== undefined) { cadModel.setModelTransformation(transform); } modelRef.current = cadModel; + onLoad?.(); } function removeModel(): void { diff --git a/react-components/src/components/CameraController/CameraController.tsx b/react-components/src/components/CameraController/CameraController.tsx new file mode 100644 index 00000000000..c06e0eea3c2 --- /dev/null +++ b/react-components/src/components/CameraController/CameraController.tsx @@ -0,0 +1,43 @@ +/*! + * Copyright 2023 Cognite AS + */ +import { type ReactElement, useEffect, useContext, useRef } from 'react'; +import { useReveal } from '../RevealContainer/RevealContext'; +import { ModelsLoadingStateContext } from '../Reveal3DResources/ModelsLoadingContext'; +import { type CameraState } from '@cognite/reveal'; + +export type CameraControllerProps = { + initialFitCamera?: FittingStrategy; +}; + +type FittingStrategy = + | { to: 'cameraState'; state: CameraState } + | { to: 'allModels' } + | { to: 'none' }; + +export function CameraController({ initialFitCamera }: CameraControllerProps): ReactElement { + const initialCameraSet = useRef(false); + const viewer = useReveal(); + const { modelsAdded } = useContext(ModelsLoadingStateContext); + + const fittingStrategy: Required = initialFitCamera ?? { to: 'allModels' }; + + useEffect(() => { + if (initialCameraSet.current) return; + if (fittingStrategy.to === 'none') { + initialCameraSet.current = true; + return; + } + if (fittingStrategy.to === 'cameraState') { + viewer.cameraManager.setCameraState(fittingStrategy.state); + initialCameraSet.current = true; + return; + } + if (fittingStrategy.to === 'allModels' && modelsAdded) { + viewer.fitCameraToModels(viewer.models, 0, true); + initialCameraSet.current = true; + } + }, [modelsAdded]); + + return <>; +} diff --git a/react-components/src/components/Image360CollectionContainer/Image360CollectionContainer.tsx b/react-components/src/components/Image360CollectionContainer/Image360CollectionContainer.tsx new file mode 100644 index 00000000000..d42d29b27bf --- /dev/null +++ b/react-components/src/components/Image360CollectionContainer/Image360CollectionContainer.tsx @@ -0,0 +1,38 @@ +/*! + * Copyright 2023 Cognite AS + */ +import { type ReactElement, useEffect, useRef } from 'react'; +import { useReveal } from '../RevealContainer/RevealContext'; +import { type Image360Collection } from '@cognite/reveal'; + +type Image360CollectionContainerProps = { + siteId: string; + onLoad?: () => void; +}; + +export function Image360CollectionContainer({ + siteId, + onLoad +}: Image360CollectionContainerProps): ReactElement { + const modelRef = useRef(); + const viewer = useReveal(); + + useEffect(() => { + add360Collection().catch(console.error); + return remove360Collection; + }, [siteId]); + + return <>; + + async function add360Collection(): Promise { + const image360Collection = await viewer.add360ImageSet('events', { site_id: siteId }); + modelRef.current = image360Collection; + onLoad?.(); + } + + function remove360Collection(): void { + if (modelRef.current === undefined) return; + viewer.remove360ImageSet(modelRef.current); + modelRef.current = undefined; + } +} diff --git a/react-components/src/components/PointCloudContainer/PointCloudContainer.tsx b/react-components/src/components/PointCloudContainer/PointCloudContainer.tsx new file mode 100644 index 00000000000..61142c8b753 --- /dev/null +++ b/react-components/src/components/PointCloudContainer/PointCloudContainer.tsx @@ -0,0 +1,51 @@ +/*! + * Copyright 2023 Cognite AS + */ + +import { type CognitePointCloudModel, type AddModelOptions } from '@cognite/reveal'; +import { useEffect, useRef, type ReactElement } from 'react'; +import { type Matrix4 } from 'three'; +import { useReveal } from '../RevealContainer/RevealContext'; + +type Cognite3dModelProps = { + addModelOptions: AddModelOptions; + transform?: Matrix4; + onLoad?: () => void; +}; + +export function PointCloudContainer({ + addModelOptions, + transform, + onLoad +}: Cognite3dModelProps): ReactElement { + const modelRef = useRef(); + const viewer = useReveal(); + const { modelId, revisionId } = addModelOptions; + + useEffect(() => { + addModel(modelId, revisionId, transform).catch(console.error); + return removeModel; + }, [modelId, revisionId]); + + useEffect(() => { + if (modelRef.current === undefined || transform === undefined) return; + modelRef.current.setModelTransformation(transform); + }, [transform]); + + return <>; + + async function addModel(modelId: number, revisionId: number, transform?: Matrix4): Promise { + const pointCloudModel = await viewer.addPointCloudModel({ modelId, revisionId }); + if (transform !== undefined) { + pointCloudModel.setModelTransformation(transform); + } + modelRef.current = pointCloudModel; + onLoad?.(); + } + + function removeModel(): void { + if (modelRef.current === undefined || !viewer.models.includes(modelRef.current)) return; + viewer.removeModel(modelRef.current); + modelRef.current = undefined; + } +} diff --git a/react-components/src/components/Reveal3DResources/ModelsLoadingContext.ts b/react-components/src/components/Reveal3DResources/ModelsLoadingContext.ts new file mode 100644 index 00000000000..6ee0a25325d --- /dev/null +++ b/react-components/src/components/Reveal3DResources/ModelsLoadingContext.ts @@ -0,0 +1,13 @@ +/*! + * Copyright 2023 Cognite AS + */ +import { createContext } from 'react'; + +export type ModelsLoadingState = { + modelsAdded: boolean; + setModelsAdded: (value: boolean) => void; +}; +export const ModelsLoadingStateContext = createContext({ + modelsAdded: false, + setModelsAdded: () => {} +}); diff --git a/react-components/src/components/Reveal3DResources/Reveal3DResources.tsx b/react-components/src/components/Reveal3DResources/Reveal3DResources.tsx new file mode 100644 index 00000000000..a81c2a55afc --- /dev/null +++ b/react-components/src/components/Reveal3DResources/Reveal3DResources.tsx @@ -0,0 +1,103 @@ +/*! + * Copyright 2023 Cognite AS + */ +import { useRef, type ReactElement, useContext, useState, useEffect } from 'react'; +import { type Cognite3DViewer } from '@cognite/reveal'; +import { ModelsLoadingStateContext } from './ModelsLoadingContext'; +import { CadModelContainer } from '../CadModelContainer/CadModelContainer'; +import { PointCloudContainer } from '../PointCloudContainer/PointCloudContainer'; +import { Image360CollectionContainer } from '../Image360CollectionContainer/Image360CollectionContainer'; +import { useReveal } from '../RevealContainer/RevealContext'; +import { + type AddReveal3DModelOptions, + type AddImageCollection360Options, + type TypedReveal3DModel, + type AddResourceOptions +} from './types'; + +export type Reveal3DResourcesProps = { + resources: AddResourceOptions[]; +}; + +export const Reveal3DResources = ({ resources }: Reveal3DResourcesProps): ReactElement => { + const [reveal3DModels, setReveal3DModels] = useState([]); + const { setModelsAdded } = useContext(ModelsLoadingStateContext); + const viewer = useReveal(); + const numModelsLoaded = useRef(0); + + useEffect(() => { + getTypedModels(resources, viewer).then(setReveal3DModels).catch(console.error); + }, [resources]); + + const image360CollectionAddOptions = resources.filter( + (resource): resource is AddImageCollection360Options => + (resource as AddImageCollection360Options).siteId !== undefined + ); + + const onModelLoaded = (): void => { + numModelsLoaded.current += 1; + if (numModelsLoaded.current === resources.length) { + setModelsAdded(true); + } + }; + + return ( + <> + {reveal3DModels + .filter(({ type }) => type === 'cad') + .map((addModelOption, index) => { + return ( + + ); + })} + {reveal3DModels + .filter(({ type }) => type === 'pointcloud') + .map((addModelOption, index) => { + return ( + + ); + })} + {image360CollectionAddOptions.map((addModelOption) => { + return ( + + ); + })} + + ); +}; + +async function getTypedModels( + resources: AddResourceOptions[], + viewer: Cognite3DViewer +): Promise { + return await Promise.all( + resources + .filter( + (resource): resource is AddReveal3DModelOptions => + (resource as AddReveal3DModelOptions).modelId !== undefined && + (resource as AddReveal3DModelOptions).revisionId !== undefined + ) + .map(async (addModelOptions) => { + const type = await viewer.determineModelType( + addModelOptions.modelId, + addModelOptions.revisionId + ); + const typedModel: TypedReveal3DModel = { ...addModelOptions, type }; + return typedModel; + }) + ); +} diff --git a/react-components/src/components/Reveal3DResources/types.ts b/react-components/src/components/Reveal3DResources/types.ts new file mode 100644 index 00000000000..87d0319ffc1 --- /dev/null +++ b/react-components/src/components/Reveal3DResources/types.ts @@ -0,0 +1,15 @@ +/*! + * Copyright 2023 Cognite AS + */ + +import { type AddModelOptions, type SupportedModelTypes } from '@cognite/reveal'; +import { type Matrix4 } from 'three'; + +export type AddImageCollection360Options = { + siteId: string; +}; + +export type AddResourceOptions = AddReveal3DModelOptions | AddImageCollection360Options; + +export type AddReveal3DModelOptions = AddModelOptions & { transform?: Matrix4 }; +export type TypedReveal3DModel = AddReveal3DModelOptions & { type: SupportedModelTypes | '' }; diff --git a/react-components/src/components/RevealContainer/RevealContainer.tsx b/react-components/src/components/RevealContainer/RevealContainer.tsx index a5e1d9fda19..fa09d21a33e 100644 --- a/react-components/src/components/RevealContainer/RevealContainer.tsx +++ b/react-components/src/components/RevealContainer/RevealContainer.tsx @@ -6,6 +6,7 @@ import { useEffect, useRef, type ReactNode, useState, type ReactElement } from ' import { Cognite3DViewer } from '@cognite/reveal'; import { RevealContext } from './RevealContext'; import { type Color } from 'three'; +import { ModelsLoadingStateContext } from '../Reveal3DResources/ModelsLoadingContext'; type RevealContainerProps = { color?: Color; @@ -13,11 +14,7 @@ type RevealContainerProps = { children?: ReactNode; }; -export default function RevealContainer({ - children, - sdk, - color -}: RevealContainerProps): ReactElement { +export function RevealContainer({ children, sdk, color }: RevealContainerProps): ReactElement { const [viewer, setViewer] = useState(); const revealDomElementRef = useRef(null); @@ -36,7 +33,9 @@ export default function RevealContainer({ if (viewer === undefined) return <>; return ( <> - {children} + + {children} + ); } @@ -57,3 +56,13 @@ export default function RevealContainer({ setViewer(undefined); } } + +function ModelsLoadingProvider({ children }: { children?: ReactNode }): ReactElement { + const [modelsLoading, setModelsLoading] = useState(false); + return ( + + {children} + + ); +} diff --git a/react-components/src/components/index.ts b/react-components/src/components/index.ts deleted file mode 100644 index eb0f43bf4b0..00000000000 --- a/react-components/src/components/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * Copyright 2023 Cognite AS - */ -import '@cognite/cogs.js/dist/cogs.css'; -export { default as RevealContainer } from './RevealContainer/RevealContainer'; -export { default as CogniteCadModelContainer } from './CogniteCadModelContainer/CogniteCadModelContainer'; -export { Image360HistoricalDetails } from './Image360HistoricalDetails/Image360HistoricalDetails'; diff --git a/react-components/src/index.ts b/react-components/src/index.ts index 17dbab7eb81..f749128f6a4 100644 --- a/react-components/src/index.ts +++ b/react-components/src/index.ts @@ -1,4 +1,19 @@ /*! * Copyright 2023 Cognite AS */ -export * from './components'; +import '@cognite/cogs.js/dist/cogs.css'; +export { RevealContainer } from './components/RevealContainer/RevealContainer'; +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 { + Reveal3DResources, + type Reveal3DResourcesProps +} from './components/Reveal3DResources/Reveal3DResources'; +export { CameraController } from './components/CameraController/CameraController'; +export type { + AddImageCollection360Options, + AddResourceOptions, + AddReveal3DModelOptions +} from './components/Reveal3DResources/types'; diff --git a/react-components/stories/CadModelContainer.stories.tsx b/react-components/stories/CadModelContainer.stories.tsx new file mode 100644 index 00000000000..e754fda543b --- /dev/null +++ b/react-components/stories/CadModelContainer.stories.tsx @@ -0,0 +1,34 @@ +/*! + * Copyright 2023 Cognite AS + */ +import type { Meta, StoryObj } from '@storybook/react'; +import { CadModelContainer, RevealContainer } from '../src'; +import { Color, Matrix4 } from 'three'; +import { createSdkByUrlToken } from './utilities/createSdkByUrlToken'; + +const meta = { + title: 'Example/PrimitiveWrappers/CadModelContainer', + component: CadModelContainer, + tags: ['autodocs'] +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +const sdk = createSdkByUrlToken(); + +export const Main: Story = { + args: { + addModelOptions: { + modelId: 1791160622840317, + revisionId: 498427137020189 + }, + transform: new Matrix4().makeTranslation(0, 10, 0) + }, + render: ({ addModelOptions, transform }) => ( + + + + + ) +}; diff --git a/react-components/stories/CogniteCadModelContainer.stories.tsx b/react-components/stories/CogniteCadModelContainer.stories.tsx deleted file mode 100644 index 5aabb207368..00000000000 --- a/react-components/stories/CogniteCadModelContainer.stories.tsx +++ /dev/null @@ -1,40 +0,0 @@ -/*! - * Copyright 2023 Cognite AS - */ -import type { Meta, StoryObj } from '@storybook/react'; -import { CogniteCadModelContainer, RevealContainer } from '../src'; -import { CogniteClient } from '@cognite/sdk'; -import { Color, Matrix4 } from 'three'; - -const meta = { - title: 'Example/CogniteCadModelContainer', - component: CogniteCadModelContainer, - tags: ['autodocs'] -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -const token = new URLSearchParams(window.location.search).get('token') ?? ''; -const sdk = new CogniteClient({ - appId: 'reveal.example', - baseUrl: 'https://greenfield.cognitedata.com', - project: '3d-test', - getToken: async () => await Promise.resolve(token) -}); - -export const Main: Story = { - args: { - addModelOptions: { - modelId: 1791160622840317, - revisionId: 498427137020189 - }, - transform: new Matrix4().makeTranslation(0, 10, 0) - }, - render: ({ addModelOptions, transform }) => ( - - - - - ) -}; diff --git a/react-components/stories/Image360CollectionContainer.stories.tsx b/react-components/stories/Image360CollectionContainer.stories.tsx new file mode 100644 index 00000000000..9eee3f71f99 --- /dev/null +++ b/react-components/stories/Image360CollectionContainer.stories.tsx @@ -0,0 +1,29 @@ +/*! + * Copyright 2023 Cognite AS + */ +import type { Meta, StoryObj } from '@storybook/react'; +import { Image360CollectionContainer, RevealContainer } from '../src'; +import { Color } from 'three'; +import { createSdkByUrlToken } from './utilities/createSdkByUrlToken'; + +const meta = { + title: 'Example/PrimitiveWrappers/Image360CollectionContainer', + component: Image360CollectionContainer, + tags: ['autodocs'] +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +const sdk = createSdkByUrlToken(); + +export const Main: Story = { + args: { + siteId: 'Hibernia_RS2' + }, + render: ({ siteId }) => ( + + + + ) +}; diff --git a/react-components/stories/PointCloudContainer.stories.tsx b/react-components/stories/PointCloudContainer.stories.tsx new file mode 100644 index 00000000000..b316f323d2f --- /dev/null +++ b/react-components/stories/PointCloudContainer.stories.tsx @@ -0,0 +1,33 @@ +/*! + * Copyright 2023 Cognite AS + */ +import type { Meta, StoryObj } from '@storybook/react'; +import { PointCloudContainer, RevealContainer } from '../src'; +import { Color, Matrix4 } from 'three'; +import { createSdkByUrlToken } from './utilities/createSdkByUrlToken'; + +const meta = { + title: 'Example/PrimitiveWrappers/PointCloudContainer', + component: PointCloudContainer, + tags: ['autodocs'] +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +const sdk = createSdkByUrlToken(); + +export const Main: Story = { + args: { + addModelOptions: { + modelId: 3865289545346058, + revisionId: 4160448151596909 + }, + transform: new Matrix4() + }, + render: ({ addModelOptions, transform }) => ( + + + + ) +}; diff --git a/react-components/stories/Reveal3DResources.stories.tsx b/react-components/stories/Reveal3DResources.stories.tsx new file mode 100644 index 00000000000..78552be355a --- /dev/null +++ b/react-components/stories/Reveal3DResources.stories.tsx @@ -0,0 +1,52 @@ +/*! + * Copyright 2023 Cognite AS + */ +import type { Meta, StoryObj } from '@storybook/react'; +import { Reveal3DResources, RevealContainer } from '../src'; +import { Color, Matrix4 } from 'three'; +import { CameraController } from '../src/'; +import { createSdkByUrlToken } from './utilities/createSdkByUrlToken'; + +const meta = { + title: 'Example/Reveal3DResources', + component: Reveal3DResources, + tags: ['autodocs'] +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +const sdk = createSdkByUrlToken(); + +export const Main: Story = { + args: { + resources: [ + { + modelId: 1791160622840317, + revisionId: 498427137020189 + }, + { + modelId: 1791160622840317, + revisionId: 498427137020189, + transform: new Matrix4().makeTranslation(0, 10, 0) + }, + { + siteId: 'c_RC_2' + }, + { + modelId: 3865289545346058, + revisionId: 4160448151596909 + } + ] + }, + render: ({ resources }) => ( + + + + + ) +}; diff --git a/react-components/stories/utilities/createSdkByUrlToken.ts b/react-components/stories/utilities/createSdkByUrlToken.ts new file mode 100644 index 00000000000..da563e98ece --- /dev/null +++ b/react-components/stories/utilities/createSdkByUrlToken.ts @@ -0,0 +1,19 @@ +/*! + * Copyright 2023 Cognite AS + */ +import { CogniteClient } from '@cognite/sdk'; + +export function createSdkByUrlToken(): CogniteClient { + const token = new URLSearchParams(window.location.search).get('token') ?? ''; + if (token === '') { + console.warn( + 'No token provided in URL. Please provide a token in the URL as a query parameter named "token".' + ); + } + return new CogniteClient({ + appId: 'reveal.example', + baseUrl: 'https://greenfield.cognitedata.com', + project: '3d-test', + getToken: async () => await Promise.resolve(token) + }); +} diff --git a/react-components/tsconfig.json b/react-components/tsconfig.json index 8cb3e155679..0d27756306b 100644 --- a/react-components/tsconfig.json +++ b/react-components/tsconfig.json @@ -14,5 +14,5 @@ "moduleResolution": "bundler", "allowSyntheticDefaultImports": true }, - "include": ["src/*", "stories/*"] + "include": ["src/**/*", "stories/**/*"] } diff --git a/react-components/webpack.config.js b/react-components/webpack.config.js index 57826127587..94ae0fa4841 100644 --- a/react-components/webpack.config.js +++ b/react-components/webpack.config.js @@ -14,7 +14,7 @@ export default (_, argv) => { output: { path: path.resolve(__dirname, 'dist'), filename: 'index.js', - clean: true, + clean: false, libraryTarget: 'module' }, module: {