This commit is contained in:
Ole
2026-05-31 20:25:41 +00:00
commit 0a07ab8593
275 changed files with 52660 additions and 0 deletions
@@ -0,0 +1,83 @@
import { useRef, useCallback, type ReactNode, useMemo } from 'react';
import type { InstanceStylingGroup } from '../types';
import {
InstanceStylingContext,
type InstanceStylingController,
} from './instanceStylingContext';
interface InstanceStylingProviderProps {
children: ReactNode;
}
/**
* Provider for centralized instance styling management.
* Components can register/unregister styling groups and listen for changes.
*/
export function InstanceStylingProvider({
children,
}: InstanceStylingProviderProps) {
const stylingGroupsRef = useRef<Map<string, InstanceStylingGroup>>(new Map());
const listenersRef = useRef<Set<() => void>>(new Set());
const nextIdRef = useRef(0);
const getStylingGroups = useCallback(() => {
return Array.from(stylingGroupsRef.current.values());
}, []);
const addEventListener = useCallback((callback: () => void): void => {
listenersRef.current.add(callback);
// Call once immediately to initialize with current state
callback();
}, []);
const removeEventListener = useCallback((callback: () => void): void => {
listenersRef.current.delete(callback);
}, []);
const notifyListeners = useCallback(() => {
listenersRef.current.forEach((listener) => listener());
}, []);
const registerStylingGroup = useCallback(
(group: InstanceStylingGroup): string => {
const id = `styling-group-${nextIdRef.current++}`;
stylingGroupsRef.current.set(id, group);
notifyListeners();
return id;
},
[notifyListeners]
);
const unregisterStylingGroup = useCallback(
(id: string): void => {
const deleted = stylingGroupsRef.current.delete(id);
if (deleted) {
notifyListeners();
}
},
[notifyListeners]
);
const controller: InstanceStylingController = useMemo(
() => ({
getStylingGroups,
addEventListener,
removeEventListener,
registerStylingGroup,
unregisterStylingGroup,
}),
[
getStylingGroups,
addEventListener,
removeEventListener,
registerStylingGroup,
unregisterStylingGroup,
]
);
return (
<InstanceStylingContext.Provider value={controller}>
{children}
</InstanceStylingContext.Provider>
);
}
@@ -0,0 +1,63 @@
import { useEffect, useRef, useState } from 'react';
import { Cognite3DViewer } from '@cognite/reveal';
import type { RevealContextProps } from '../types';
import { RevealContext } from './revealContext';
import { InstanceStylingProvider } from './InstanceStylingProvider';
import { useOptionalRevealKeepAlive } from '../components/RevealKeepAlive';
import { RevealSettingsController } from '../settings/RevealSettingsController';
export function RevealProvider({
children,
sdk,
color,
viewerOptions,
}: RevealContextProps) {
const keepAlive = useOptionalRevealKeepAlive();
const keepAliveRef = useRef(keepAlive);
keepAliveRef.current = keepAlive;
const [viewerData] = useState(() => {
const createViewer = () =>
new Cognite3DViewer({
sdk,
useFlexibleCameraManager: true,
...viewerOptions,
});
const viewer = keepAlive
? keepAlive.getOrCreateViewer(sdk, createViewer)
: createViewer();
if (color) {
viewer.setBackgroundColor({ color, alpha: 1 });
}
return { viewer, sdk };
});
useEffect(() => {
const controller = new RevealSettingsController('medium');
controller.applyToViewer(viewerData.viewer);
return () => controller.dispose();
}, [viewerData.viewer]);
useEffect(() => {
if (color) {
viewerData.viewer.setBackgroundColor({ color, alpha: 1 });
}
}, [color, viewerData.viewer]);
useEffect(() => {
return () => {
if (!keepAliveRef.current) {
viewerData.viewer.dispose();
}
};
}, []);
return (
<RevealContext.Provider value={viewerData}>
<InstanceStylingProvider>{children}</InstanceStylingProvider>
</RevealContext.Provider>
);
}
@@ -0,0 +1,14 @@
import { createContext } from 'react';
import type { InstanceStylingGroup } from '../types';
export interface InstanceStylingController {
getStylingGroups: () => InstanceStylingGroup[];
addEventListener: (callback: () => void) => void;
removeEventListener: (callback: () => void) => void;
registerStylingGroup: (group: InstanceStylingGroup) => string;
unregisterStylingGroup: (id: string) => void;
}
export const InstanceStylingContext = createContext<
InstanceStylingController | undefined
>(undefined);
@@ -0,0 +1,12 @@
import { createContext } from 'react';
import type { Cognite3DViewer } from '@cognite/reveal';
import type { CogniteClient } from '@cognite/sdk';
export interface RevealContextValue {
viewer: Cognite3DViewer;
sdk: CogniteClient;
}
export const RevealContext = createContext<RevealContextValue | undefined>(
undefined
);